winapi/gdi: FillRect(COLOR_BTNFACE) fills with strange grid-like brush on Windows 7 and wine; solid black on Windows XP

ε祈祈猫儿з 提交于 2019-12-08 06:45:13

问题


I'm trying to fill an off-screen bitmap/device context on Windows with the standard COLOR_BTNFACE solid color with FillRect(). However, on wine, I get this from the program below. Windows 7 shows this and Windows XP shows... this. I'm lost as to what I'm doing wrong, but I'm sure whatever that weird pattern is isn't right, and I know that black isn't the button face color, as the window looks right without the custom paint.

I tried all of the following; they show the same thing:

FillRect(rdc, &rrect, (HBRUSH) (COLOR_BTNFACE + 1));
FillRect(rdc, &rrect, GetSystemColorBrush(COLOR_BTNFACE));
FillRect(rdc, &rrect, GetSolidBrush(GetSysColor(COLOR_BTNFACE)));

GetDeviceCaps(BITSPIXEL) for both the BeginPaint() and off-screen device contexts returns 32; COLORRES returns 24.

Possibly related? Here's the output from the actual program I'm running, which adds another picture to this DC with AlphaBlend(); this caused someone else to suggest I was accidentally using a monochrome DC? hence the information in the previous paragraph

What am I doing wrong here? Thanks.

Program:

// pietro gagliardi - 11-12 april 2014
#define _UNICODE
#define UNICODE
#include <stdio.h>
#include <windows.h>

// this test program doesn't check drawing errors; I have done so in the actual program and there are none
void paintwin(HWND hwnd)
{   
    PAINTSTRUCT ps;

    HDC hdc = BeginPaint(hwnd, &ps);
    RECT updaterect = ps.rcPaint;

    // this is the DC that will be drawn to hdc
    HDC rdc = CreateCompatibleDC(hdc);
    HBITMAP rbitmap = CreateCompatibleBitmap(rdc,
            updaterect.right - updaterect.left,
            updaterect.bottom - updaterect.top);
    HBITMAP prevrbitmap = SelectObject(rdc, rbitmap);
    RECT rrect = { 0, 0, updaterect.right - updaterect.left, updaterect.bottom - updaterect.top };
    FillRect(rdc, &rrect, (HBRUSH) (COLOR_BTNFACE + 1));

    BitBlt(hdc, updaterect.left, updaterect.top,
        updaterect.right - updaterect.left,
        updaterect.bottom - updaterect.top,
        rdc, 0, 0, SRCCOPY);

    SelectObject(rdc, prevrbitmap);
    DeleteObject(rbitmap);
    DeleteDC(rdc);

    EndPaint(hwnd, &ps);
}

LRESULT CALLBACK wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
    switch (msg) {
    case WM_PAINT:
        paintwin(hwnd);
        return 0;
    case  WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd, msg, wparam, lparam);
}

int getnCmdShow()
{
    STARTUPINFO si;

    GetStartupInfo(&si);
    if ((si.dwFlags & STARTF_USESHOWWINDOW) != 0)
        return si.wShowWindow;
    return SW_SHOWDEFAULT;
}

int main(int argc, char *argv[])
{
    WNDCLASS cls;
    MSG msg;
    HWND mainwin;

    HINSTANCE hInstance = GetModuleHandle(NULL);
    int nCmdShow = getnCmdShow();

    ZeroMemory(&cls, sizeof (WNDCLASS));
    cls.lpszClassName = L"mainwin";
    cls.lpfnWndProc = wndproc;
    cls.hInstance = hInstance;
    cls.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    cls.hCursor = LoadCursor(NULL, IDC_ARROW);
    cls.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
    if (RegisterClass(&cls) == 0) {
        fprintf(stderr, "registering window class failed: %lu\n", GetLastError());
        return 1;
    }

    mainwin = CreateWindowEx(0,
        L"mainwin", L"mainwin",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT,
        CW_USEDEFAULT, CW_USEDEFAULT,
        NULL, NULL, hInstance, NULL);
    if (mainwin == NULL) {
        fprintf(stderr, "opening main window failed: %lu", GetLastError());
        return 1;
    }
    ShowWindow(mainwin, nCmdShow);
    UpdateWindow(mainwin);

    while (GetMessage(&msg, NULL, 0, 0) > 0) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return 0;
}

回答1:


The error is indeed that you are using a monochrome bitmap.

CreateCompatibleBitmap(rdc, ...);

The problem is that rdc has the default 1x1 monochrome bitmap selected into it. Instead you need

CreateCompatibleBitmap(hdc, ...);


来源:https://stackoverflow.com/questions/23033636/winapi-gdi-fillrectcolor-btnface-fills-with-strange-grid-like-brush-on-window

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!