当使用Windows API调整屏幕大小时,DPI感知会扭曲文本 我用Win32 API编写C++应用程序。我首先注意到,使用DrawTextLayout()呈现的文本非常模糊,因此我添加了以下行: SetProcessDpiAwarenessContext(DPI\u感知\u上下文\u每个监视器\u感知\u V2);

当使用Windows API调整屏幕大小时,DPI感知会扭曲文本 我用Win32 API编写C++应用程序。我首先注意到,使用DrawTextLayout()呈现的文本非常模糊,因此我添加了以下行: SetProcessDpiAwarenessContext(DPI\u感知\u上下文\u每个监视器\u感知\u V2);,c++,windows,winapi,C++,Windows,Winapi,起初,这似乎起到了作用:文本看起来更清晰,更符合我对Windows应用程序的期望 但是,当我调整窗口大小时(通过拖动下角),我注意到我绘制的文本被扭曲了 如何保持使用DPI\u AWARE\u CONTEXT\u PER\u MONITOR\u AWARE\u V2的简洁性,同时避免文本被拉伸 #include "targetver.h" #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff

起初,这似乎起到了作用:文本看起来更清晰,更符合我对Windows应用程序的期望

但是,当我调整窗口大小时(通过拖动下角),我注意到我绘制的文本被扭曲了

如何保持使用
DPI\u AWARE\u CONTEXT\u PER\u MONITOR\u AWARE\u V2
的简洁性,同时避免文本被拉伸

#include "targetver.h"
#define WIN32_LEAN_AND_MEAN             // Exclude rarely-used stuff from Windows headers
// Windows Header Files
#include <windows.h>
// C RunTime Header Files
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
#include <dwrite.h>
#include <d2d1.h>
#define IDS_APP_TITLE           103
#define IDR_MAINFRAME           128
#define IDD_PRACTICE_DIALOG 102
#define IDD_ABOUTBOX            103
#define IDM_ABOUT               104
#define IDM_EXIT                105
#define IDI_PRACTICE            107
#define IDI_SMALL               108
#define IDC_PRACTICE            109
#define IDC_MYICON              2
#ifndef IDC_STATIC
#define IDC_STATIC              -1
#endif
#define MAX_LOADSTRING 100
// Global Variables:
HINSTANCE hInst;                                // current instance
WCHAR szTitle[MAX_LOADSTRING];                  // The title bar text
WCHAR szWindowClass[MAX_LOADSTRING];            // the main window class name
ID2D1Factory* m_pD2DFactory;
ID2D1HwndRenderTarget* m_pRenderTarget;
ID2D1SolidColorBrush* m_pBlackBrush;
IDWriteFactory* writeFactory;
IDWriteTextFormat* writeTextFormat;
IDWriteTextLayout* writeTextLayout;
RECT rc;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEXW wcex;
    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.style = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc = WndProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = hInstance;
    wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_PRACTICE));
    wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_PRACTICE);
    wcex.lpszClassName = szWindowClass;
    wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
    return RegisterClassExW(&wcex);
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
    hInst = hInstance; // Store instance handle in our global variable
    HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, nullptr, nullptr, hInstance, nullptr);
    //create device independent resources
    {
        SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
        // Create a Direct2D factory.
        D2D1CreateFactory(
            D2D1_FACTORY_TYPE_SINGLE_THREADED,
            &m_pD2DFactory
        );
        DWriteCreateFactory(
            DWRITE_FACTORY_TYPE_SHARED,
            __uuidof(IDWriteFactory),
            reinterpret_cast<IUnknown**>(&writeFactory)
        );
    }
    if (!hWnd)
    {
        return FALSE;
    }
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);
    return TRUE;
}
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
    _In_opt_ HINSTANCE hPrevInstance,
    _In_ LPWSTR    lpCmdLine,
    _In_ int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);
    // Initialize global strings
    LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    LoadStringW(hInstance, IDC_PRACTICE, szWindowClass, MAX_LOADSTRING);
    MyRegisterClass(hInstance);
    // Perform application initialization:
    if (!InitInstance(hInstance, nCmdShow))
    {
        return FALSE;
    }
    HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_PRACTICE));
    MSG msg;
    // Main message loop:
    while (GetMessage(&msg, nullptr, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    return (int)msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hWnd, &ps);
        //create device dependent resources
        {
            HRESULT hr = S_OK;
            if (!m_pRenderTarget) {
                GetClientRect(hWnd, &rc);
                D2D1_SIZE_U size = D2D1::SizeU(rc.right - rc.left, rc.bottom - rc.top);
                // Create a Direct2D render target 
                hr = m_pD2DFactory->CreateHwndRenderTarget(D2D1::RenderTargetProperties(), D2D1::HwndRenderTargetProperties(hWnd, size), &m_pRenderTarget);
                if (SUCCEEDED(hr))
                {
                    // Create a black brush
                    hr = m_pRenderTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Black), &m_pBlackBrush);
                }
            }
        }
        //render text
        {
            writeFactory->CreateTextFormat(
                L"Times New Roman",
                NULL,
                DWRITE_FONT_WEIGHT_NORMAL,
                DWRITE_FONT_STYLE_NORMAL,
                DWRITE_FONT_STRETCH_NORMAL,
                14.0f,
                L"EN-US",
                &writeTextFormat
            );
            writeFactory->CreateTextLayout(
                L"String",      // The string to be laid out and formatted.
                6,  // The length of the string.
                writeTextFormat,  // The text format to apply to the string (contains font information, etc).
                200,         // The length of the layout box.
                500,        // The width of the layout box.
                &writeTextLayout  // The IDWriteTextLayout interface pointer.
            );
        }
        m_pRenderTarget->BeginDraw();
        m_pRenderTarget->SetTransform(D2D1::IdentityMatrix());
        m_pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::White));
        m_pRenderTarget->DrawTextLayout(D2D1::Point2F(0, 0), writeTextLayout, m_pBlackBrush);
        m_pRenderTarget->EndDraw();
        EndPaint(hWnd, &ps);
    }
    break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}
#包括“targetver.h”
#定义WIN32_LEAN_和_MEAN//从Windows标题中排除很少使用的内容
//Windows头文件
#包括
//C运行时头文件
#包括
#包括
#包括
#包括
#包括
#包括
#定义ID\u应用程序\u标题103
#定义IDR_大型机128
#定义IDD_实践_对话框102
#定义IDD_关于框103
#定义IDM_约104
#定义IDM_出口105
#定义IDI_实践107
#定义IDI_小108
#定义IDC_实践109
#定义IDC_MYICON 2
#ifndef IDC_静态
#定义IDC_静态-1
#恩迪夫
#定义最大加载字符串100
//全局变量:
HINSTANCE hInst;//当前实例
WCHAR szTitle[MAX_LOADSTRING];//标题栏文本
WCHAR szWindowClass[最大加载字符串];//主窗口类名称
ID2D1工厂*m_PD2工厂;
ID2D1HwndRenderTarget*m_pRenderTarget;
ID2D1SOLIDCORBRUSH*m_pBlackBrush;
IDWriteFactory*writeFactory;
IDWriteTextFormat*writeTextFormat;
IDWriteTextLayout*writeTextLayout;
RECT-rc;
LRESULT回调WndProc(HWND HWND,UINT消息,WPARAM WPARAM,LPARAM LPARAM);
ATOM MyRegisterClass(HINSTANCE HINSTANCE)
{
WNDCLASSEXW wcex;
wcex.cbSize=sizeof(WNDCLASSEX);
wcex.style=CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc=WndProc;
wcex.cbClsExtra=0;
wcex.cbWndExtra=0;
wcex.hInstance=hInstance;
wcex.hIcon=LoadIcon(hInstance,MAKEINTRESOURCE(IDI_实践));
wcex.hCursor=LoadCursor(nullptr,IDC_箭头);
wcex.hbrBackground=(HBRUSH)(彩色窗口+1);
wcex.lpszMenuName=MAKEINTRESOURCEW(IDC_实践);
wcex.lpszClassName=szWindowClass;
wcex.hIconSm=LoadIcon(wcex.hInstance,MAKEINTRESOURCE(IDI_SMALL));
返回寄存器CLASSEXW(&wcex);
}
BOOL InitInstance(HINSTANCE HINSTANCE,int nCmdShow)
{
hInst=hInstance;//将实例句柄存储在全局变量中
HWND HWND=CreateWindowW(szWindowClass,szTitle,WS_OVERLAPPEDWINDOW,
CW_usefault、CW_usefault、CW_usefault、CW_usefault、nullptr、nullptr、hInstance、nullptr);
//创建独立于设备的资源
{
SetProcessDPIawarenesContext(DPI\U感知\U上下文每\U监视器\U感知\U V2);
//创建Direct2D工厂。
D2D1CreateFactory(
D2D1工厂型单螺纹,
&m_PD2D工厂
);
德怀特工厂(
数据写入工厂类型共享,
__uuidof(IDWriteFactory),
重新解释强制转换(&writeFactory)
);
}
如果(!hWnd)
{
返回FALSE;
}
显示窗口(hWnd、nCmdShow);
更新窗口(hWnd);
返回TRUE;
}
国际货币基金组织,
_在当前情况下,
_在LPWSTR lpCmdLine中,
_In_uuint(nCmdShow)
{
未引用的_参数(HPPreInstance);
未引用的_参数(lpCmdLine);
//初始化全局字符串
LoadStringW(hInstance、IDS\U APP\U TITLE、szTitle、MAX\U LOADSTRING);
LoadStringW(hInstance、IDC_PRACTICE、szWindowClass、MAX_LOADSTRING);
MyRegisterClass(hInstance);
//执行应用程序初始化:
如果(!InitInstance(hInstance,nCmdShow))
{
返回FALSE;
}
HACCEL hAccelTable=装载加速器(hInstance,MAKEINTRESOURCE(IDC_实践));
味精;
//主消息循环:
while(GetMessage(&msg,nullptr,0,0))
{
if(!TranslateAccelerator(msg.hwnd、hAccelTable和msg))
{
翻译信息(&msg);
发送消息(&msg);
}
}
返回(int)msg.wParam;
}
LRESULT回调WndProc(HWND HWND,UINT消息,WPARAM WPARAM,LPARAM LPARAM)
{
开关(信息)
{
案例WM_油漆:
{
PAINTSTRUCT-ps;
HDC HDC=开始喷漆(hWnd和ps);
//创建设备相关资源
{
HRESULT hr=S_正常;
如果(!m_pRenderTarget){
GetClientRect(hWnd和rc);
D2D1_SIZE_SIZE=D2D1::SizeU(rc.right-rc.left,rc.bottom-rc.top);
//创建Direct2D渲染目标
hr=m_pD2DFactory->CreateHwndRenderTarget(D2D1::renderargetproperties(),D2D1::HwndRenderTargetProperties(hWnd,size),&m_pRenderTarget);
如果(成功(hr))
{
//创建一个黑色笔刷
hr=m_pRenderTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Black)和m_pBlackBrush);
}
}
}
//渲染文本
{
writeFactory->CreateTextFormat(
“新罗马时代”,
无效的
数据写入字体重量正常,
DWRITE\u FONT\u STYLE\u NORMAL,
DWRITE\u FONT\u STRETCH\u NORMAL,
14.0f,
L“EN-US”,
&writeTextFormat
);
writeFactory->CreateTextLayout(
L“String”,//要布局和格式化的字符串。
6,//字符串的长度。
writeTextFormat,//应用于字符串的文本格式(包含字体信息等)。
200,//布局框的长度。
case WM_SIZE:
{
    if (m_pRenderTarget)
    {
        GetClientRect(hWnd, &rc);
        D2D1_SIZE_U size = D2D1::SizeU(rc.right - rc.left, rc.bottom - rc.top);
        m_pRenderTarget->Resize(size);
    }
    break;
}
case WM_SIZE:
{
    if (m_pRenderTarget)
    {
        m_pRenderTarget->Release();
        m_pRenderTarget = nullptr;
    }
    break;
}