问题
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