Reputation: 313
From my understanding, BeginPaint
and EndPaint
helps paint the screen and validates the rectangle that it paints, this also prevents WM_PAINT
messages from being spammed since there will be no more invalid regions in the window.
With my understanding, I thought that theoretically speaking, if I were to use BitBlt()
to paint the window in WM_CREATE
, then use ValidateRect
to Validate the entire client region, the code would work. However, I tried it and it doesn't, suggesting that there could be something possibly wrong with my understanding, or code. Could someone please explain to me where I went wrong?
Here is the code that I used, IDB_BITMAP1
can be replaced with any appropriate Bitmap. Do note the comment in WM_PAINT
to reproduce the issue. Thanks for reading!
#include <windows.h>
#include "resource.h"
HBITMAP hBitMap = NULL;
LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CREATE:
{
BITMAP infoBM;
hBitMap = LoadBitmap(GetModuleHandle(NULL), IDB_BITMAP1);
if (hBitMap == NULL)
{
MessageBoxA(NULL, "COULD NOT LOAD CAT BITMAP", "ERROR", MB_OK);
}
HDC winDC = GetDC(hwnd);
HDC hMem = CreateCompatibleDC(winDC);
GetObject(hBitMap, sizeof(infoBM), &infoBM);
HBITMAP hMemOld = SelectObject(hMem, hBitMap);
BitBlt(winDC, 0, 0, infoBM.bmWidth, infoBM.bmHeight, hMem, 0, 0, SRCCOPY);
SelectObject(hMem, hMemOld);
DeleteDC(hMem);
ReleaseDC(hwnd,winDC);
break;
}
case WM_PAINT: //<<<--------- I replaced the entire segment here with ValidateRect(hwnd,NULL);break; And the whole window doesnt show anymore, why is that so?
{
BITMAP infoBM;
PAINTSTRUCT ps;
HDC winDC = BeginPaint(hwnd, &ps);
GetObject(hBitMap, sizeof(infoBM), &infoBM);
HDC hMem = CreateCompatibleDC(winDC);
HBITMAP hOldMem = SelectObject(hMem, hBitMap);
BitBlt(winDC, 0, 0, infoBM.bmWidth, infoBM.bmHeight, hMem, 0, 0, SRCCOPY);
SelectObject(hMem, hOldMem);
DeleteObject(hMem);
EndPaint(hwnd, &ps);
break;
}
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:return DefWindowProcA(hwnd, msg, wParam, lParam);
}
return 0;
}
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevIstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc = { sizeof(WNDCLASSEX),0,WindowProc,0,0,hInstance,NULL,LoadCursor(NULL,IDC_ARROW),(HBRUSH)(COLOR_WINDOW+1),NULL,"WindowClass",LoadIcon(NULL,IDI_APPLICATION)};
if (!RegisterClassEx(&wc))
{
MessageBoxA(NULL, "WINDOW REGISTRATION FAILED", "ERROR", MB_OK);
}
HWND hwnd = CreateWindowEx(WS_EX_LAYERED, "WindowClass", "Title", WS_POPUP, 200, 200, 300, 300, NULL, NULL, hInstance, NULL);
if (!hwnd)
{
MessageBoxA(NULL, "WINDOW CREATION FAILED", "ERROR", MB_OK);
}
ShowWindow(hwnd, SW_SHOW);
UpdateWindow(hwnd);
if (!SetLayeredWindowAttributes(hwnd, RGB(0, 0, 0), 255, LWA_ALPHA))
{
MessageBoxA(NULL, "WINDOW LAYERED ATTRIBUTES FAILED", "ERROR", MB_OK);
}
MSG msg;
while (GetMessage(&msg, hwnd, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
Upvotes: 2
Views: 183
Reputation: 2130
Typically,
And if you'd like, you can ValidateRect the entire client area instead of real painting when a WM_PAINT message is processing.
The following code is adapted from the thread.
LRESULT CALLBACK MyWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static int i = 0;
switch (message)
{
case WM_PAINT:
{
if (i++ < 100)
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
RECT rect;
GetClientRect(hWnd, &rect);
COLORREF clrbak = SetBkColor(hdc, RGB(255, 0, 0));
ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
int x = (rect.right - rect.left) / 8;
int y = (rect.bottom - rect.top) / 8;
rect.left += x; rect.right -= x;
rect.top += y; rect.bottom -= y;
SetBkColor(hdc, RGB(0, 255, 0));
ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
rect.left += x; rect.right -= x;
rect.top += y; rect.bottom -= y;
SetBkColor(hdc, RGB(0, 0, 255));
ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
rect.left += x; rect.right -= x;
rect.top += y; rect.bottom -= y;
SetBkColor(hdc, RGB(0, 0, 0));
ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
SetBkColor(hdc, clrbak);
EndPaint(hWnd, &ps);
}
else
{
ValidateRect(hWnd,NULL);
}
}
break;
case WM_ERASEBKGND:
return 1;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
Upvotes: 1