WinAPI-GDI:DrawText()和ExtTextOut()丑陋(启用AA)

WinAPI-GDI:DrawText()和ExtTextOut()丑陋(启用AA),winapi,Winapi,我正在尝试使用所描述的方法(而不是MFC)为一个丰富的编辑控件进行行编号。虽然效果很好,但与rich edit相比,行号的渲染非常糟糕 我制作了一个小程序来重现这个问题:(很抱歉,我复制了粘贴,但找不到正常的文件托管服务-。-): #包括 LRESULT WINAPI WndProc(HWND HWND、UINT msg、WPARAM WPARAM、LPARAM LPARAM) { 开关(msg) { 案例WM_结束: 显示窗口(hWnd、SW_隐藏); 窗口(hWnd); 打破 案例WM_油漆

我正在尝试使用所描述的方法(而不是MFC)为一个丰富的编辑控件进行行编号。虽然效果很好,但与rich edit相比,行号的渲染非常糟糕

我制作了一个小程序来重现这个问题:(很抱歉,我复制了粘贴,但找不到正常的文件托管服务-。-):

#包括
LRESULT WINAPI WndProc(HWND HWND、UINT msg、WPARAM WPARAM、LPARAM LPARAM)
{
开关(msg)
{
案例WM_结束:
显示窗口(hWnd、SW_隐藏);
窗口(hWnd);
打破
案例WM_油漆:
{
HDC HDC=GetDC(hWnd);
HDC bdc=CreateCompatibleDC(HDC);
HBITMAP bitmap=CreateCompatibleBitmap(hdc,400100);
int height=-MulDiv(10,GetDeviceCaps(hdc,LOGPIXELSY),72);
HFONT font=CreateFont(
高度,0,0,0,FW_DONTCARE,假,假,假,
默认字符集、输出默认精度、剪辑默认精度、,
抗锯齿质量,FF_DONTCARE,“控制台”);
hgdobj oldbm=选择对象(bdc,位图);
hgdobj oldft=选择对象(bdc,字体);
RECT rc={0,0200,20};
FillRect(bdc,&rc,(HBRUSH)GetStockObject(WHITE_-BRUSH));
DrawText(bdc,“123456789”,19和rc,DT|U左| DT|U编辑控制);
BitBlt(hdc,20,20,rc.right-rc.left,rc.bottom-rc.top,bdc,0,0,srcopy);
选择对象(bdc、oldbm);
选择对象(bdc、oldft);
删除对象(位图);
删除对象(字体);
DeleteDC(bdc);
}
返回1;
案例WM_销毁:
PostQuitMessage(0);
返回0;
案例WM_KEYUP:
交换机(wParam)
{
案件VK_逃逸:
发送消息(hWnd,WM_CLOSE,0,0);
打破
}
打破
违约:
打破
}
返回DefWindowProc(hWnd、msg、wParam、lParam);
}
INT-WINAPI WinMain(HINSTANCE-hInst、HINSTANCE-hPrevInst、LPSTR-lpCmdLine、INT-nShowCmd)
{
HWND-HWND=0;
WNDCLASSEX wc=
{
sizeof(WNDCLASSEX),
政务司司长,
(WNDPROC)WNDPROC,
0升,0升,
欣斯特,
空,空,空,空,
“TestClass”,空
};
注册类别(&wc);
int w=GetSystemMetrics(0);
int h=GetSystemMetrics(1);
DWORD style=WS|u CLIPCHILDREN | WS|u CLIPSIBLINGS | WS|u SYSMENU | WS|u BORDER | WS|u CAPTION;
hwnd=CreateWindowA(“TestClass”,“Winapi1”,样式,
(w-400)/2,(h-200)/2400200,
NULL,NULL,wc.hInstance,NULL);
如果(!hwnd)
{
MessageBoxA(NULL,“无法创建窗口!”,“错误!”,MB_OK);
后藤端;
}
显示窗口(hwnd、SW_显示默认值);
更新窗口(hwnd);
味精;
零内存(&msg,sizeof(msg));
while(msg.message!=WM_退出)
{
while(peek消息(&msg,NULL,0U,0U,PM_删除))
{
翻译信息(&msg);
发送消息(&msg);
}
}
_完:
取消注册类(“TestClass”,wc.hInstance);
返回0;
}
将结果与在rich edit中键入文本进行比较:

(…无法发布图像-。-…)

当我放大图像时,差异是“细微的”,但它表明rich edit使用了某种颜色

我试过以下方法:

  • 使用ExtexOut
  • 将位图保存到文件,以查看其是否也很丑(确实如此)
  • 直接绘制到hdc(也很难看,加上它会闪烁,但现在这不是问题)

我遗漏了什么?

改用CLEARTYPE_QUALITY,这是唯一能让Console看起来不错的设置。天哪,谢谢:)我现在觉得自己太傻了…:/
#include <Windows.h>

LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch( msg )
    {
    case WM_CLOSE:
        ShowWindow(hWnd, SW_HIDE);
        DestroyWindow(hWnd);
        break;

    case WM_PAINT:
        {
            HDC hdc = GetDC(hWnd);
            HDC bdc = CreateCompatibleDC(hdc);
            HBITMAP bitmap = CreateCompatibleBitmap(hdc, 400, 100);

            int height = -MulDiv(10, GetDeviceCaps(hdc, LOGPIXELSY), 72);

            HFONT font = CreateFont(
                height, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE,
                DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
                ANTIALIASED_QUALITY, FF_DONTCARE, "Consolas");

            HGDIOBJ oldbm = SelectObject(bdc, bitmap);
            HGDIOBJ oldft = SelectObject(bdc, font);

            RECT rc = { 0, 0, 200, 20 };

            FillRect(bdc, &rc, (HBRUSH)GetStockObject(WHITE_BRUSH));

            DrawText(bdc, " 1 2 3 4 5 6 7 8 9", 19, &rc, DT_LEFT|DT_EDITCONTROL);
            BitBlt(hdc, 20, 20, rc.right - rc.left, rc.bottom - rc.top, bdc, 0, 0, SRCCOPY);

            SelectObject(bdc, oldbm);
            SelectObject(bdc, oldft);

            DeleteObject(bitmap);
            DeleteObject(font);
            DeleteDC(bdc);
        }
        return 1;

    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;

    case WM_KEYUP:
        switch(wParam)
        {
        case VK_ESCAPE:
            SendMessage(hWnd, WM_CLOSE, 0, 0);
            break;
        }
        break;

    default:
        break;
    }

    return DefWindowProc(hWnd, msg, wParam, lParam);
}

INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nShowCmd)
{
    HWND hwnd = 0;

    WNDCLASSEX wc =
    {
        sizeof(WNDCLASSEX),
        CS_CLASSDC,
        (WNDPROC)WndProc,
        0L, 0L,
        hInst,
        NULL, NULL, NULL, NULL,
        "TestClass", NULL
    };

    RegisterClassEx(&wc);

    int w = GetSystemMetrics(0);
    int h = GetSystemMetrics(1);

    DWORD style = WS_CLIPCHILDREN|WS_CLIPSIBLINGS|WS_SYSMENU|WS_BORDER|WS_CAPTION;

    hwnd = CreateWindowA("TestClass", "Winapi1", style,
        (w - 400) / 2, (h - 200) / 2, 400, 200,
        NULL, NULL, wc.hInstance, NULL);

    if( !hwnd )
    {
        MessageBoxA(NULL, "Could not create window!", "Error!", MB_OK);
        goto _end;
    }

    ShowWindow(hwnd, SW_SHOWDEFAULT);
    UpdateWindow(hwnd);

    MSG msg;
    ZeroMemory(&msg, sizeof(msg));

    while( msg.message != WM_QUIT )
    {
        while( PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE) )
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

_end:
    UnregisterClass("TestClass", wc.hInstance);
    return 0;
}