c++ - 设置我的应用程序 api 感知并防止系统使其模糊和错误定位

标签 c++ winapi dpi-aware

我有一个带有父窗口和 4 个子窗口的简单应用程序。 Windows xp 上看起来不错和 Windows 7125%显示设置。

然而,在 Windows 7超过125%Windows 10 125%本身,窗口,菜单,文本和消息框变得模糊,子窗口溢出。

我想修复它们,使它们看起来很好,所以我尝试根据 dpi 用更新的尺寸替换它们的尺寸:

//Get resoulation 
int resX=GetSystemMetrics(SM_CXVIRTUALSCREEN) , resY=GetSystemMetrics(SM_CYVIRTUALSCREEN);
//Get current dpi
HDC screen = GetDC(0);
int dpiX = GetDeviceCaps(screen, LOGPIXELSX);
int dpiY = GetDeviceCaps(screen, LOGPIXELSY);
//Do some calculations about the resoulation 
if( resX <= 800 ){
        winWidth=resX/1.45;
        winHeight=resY/1.3;
    }
//...

//Update width and height of the main window according to the current dpi
int updatedWinWidth=(winWidth * dpiX) / 96 , updatedWinHeight=(winHeight * dpiY) / 96 ;
//Creating parent window with updated width and height
hwnd=CreateWindowEx( WS_EX_CLIENTEDGE , myClassName , L"Compressor Reporter" ,  WS_OVERLAPPED  | WS_MINIMIZEBOX | WS_SYSMENU ,CW_USEDEFAULT, CW_USEDEFAULT,  updatedWinWidth , updatedWinHeight, NULL , NULL , hInstance , NULL );

//Updating width and height for child window, width and height variables are the dafault width and height for the child 
int updatedWidth = ( width * dpiX) / 96 , updatedHeight= (height * dpiY) / 96;
//Creating the child window
hwndList1 = CreateWindow(WC_LISTVIEW , L"" ,  WS_VISIBLE | WS_CHILD | LVS_REPORT | WS_BORDER  | WS_VSCROLL | LVS_OWNERDRAWFIXED, middle-(10+updatedWidth) , middleH-(10+updatedHeight) , updatedWidth , updatedHeight, hwnd, NULL, GetModuleHandle(NULL), 0); 



//Font settings
HDC hdc=GetDC( hHeader1);
int points=0;
switch(GetDeviceCaps( hdc , LOGPIXELSY)){
    case 96:
        points=11;
        break;
    default:
        points=10.5;
}

int fonth=-MulDiv(points, GetDeviceCaps( hdc , LOGPIXELSY) , 72 );

ReleaseDC(hHeader1 , hdc);

hF2=CreateFont(fonth, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, L"Tahoma");

SendMessage(hHeader1,WM_SETFONT,(WPARAM)hF2,MAKELPARAM(TRUE,0));

但是,结果是一样的。

我还更改了Compressor Reporter.exe.embed.manifest并添加 application在其中标记如下。但是当我重建我的应用程序时,我添加的内容没有出现,我看到没有 application标签。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<application xmlns="urn:schemas-microsoft-com:asm.v3">
 <windowsSettings>
        <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
        <dpiAware>true</dpiAware>
    </windowsSettings>
</application>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
  <security>
   <requestedPrivileges>
        <requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel>
      </requestedPrivileges>
    </security>
</trustInfo>
</assembly>

我做错了什么,如何修复模糊的窗口、文本、菜单和消息框并使子窗口正确定位?

谢谢

最佳答案

您可能错过了 this document

Desktop applications using older Windows programming technologies (raw Win32 programming, Windows Forms, Windows Presentation Framework (WPF), etc.) are unable to automatically handle DPI scaling without additional developer work. Without such work, applications will appear blurry or incorrectly-sized in many common usage scenarios.



为了更新现有桌面应用程序以正确处理 DPI 缩放,需要对其进行更新,以便至少更新其 UI 的重要部分以响应 DPI 更改。

大多数桌面应用程序在系统 DPI 感知模式下运行。系统 DPI 感知应用程序通常会缩放到主显示器的 DPI(Windows session 启动时系统托盘所在的显示器)。当 DPI 发生变化时,Windows 会位图拉伸(stretch)这些应用程序的 UI,这通常会导致它们变得模糊。当更新系统 DPI 感知应用程序以成为每个监视器 DPI 感知时,需要更新处理 UI 布局的代码,以便它不仅在应用程序初始化期间执行,而且在 DPI 更改通知时执行(在这种情况下为 WM_DPICHANGED Win32) 被接收。这通常涉及重新审视代码中的任何假设,即 UI 只需要缩放一次。

您可以在 example 的帮助下了解它是如何工作的。

不要忘记添加 SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE),它会在应用程序运行时更改 DPI 感知。

案例可能有用:
  • High-DPI Scaling Improvements for Desktop Applications in the Windows 10 Creators Update (1703)
  • Per-window DPI Awareness Sample
  • 关于c++ - 设置我的应用程序 api 感知并防止系统使其模糊和错误定位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59650136/

    相关文章:

    c++ - 非静态数据成员初始化

    c++ - 在没有智能指针的情况下返回指向堆对象的指针

    c - 如何在 64 位 Windows 中将 wchar_t 数组打印到文件

    c++ - 无法编译旧的 WIN32 WINAPI 程序

    c# - DPI 感知和 Rect

    c++ - 如何在 C++ 应用程序中重现 "Stack smashing detected"

    c++ - Visual Studio 2010 Qt 插件 Cmake 项目

    c++ - 如何限制进程创建新进程?

    c# - DPI 意识 - 在一个版本中没有意识到,在另一个版本中有系统意识

    winforms - 每个显示器 DPI 感知的 Windows 系统镜像列表