最好的策略是使用 GDI 绘制一个用作缓冲区的 HBITMAP,每次更改颜色时重新创建该位图。然后在 WM_PAINT 控件的形状 WndProc 中绘制它:
case WM_PAINT:
PAINTSTRUCT ps;
HDC hdc;
BITMAP bitmap;
HDC hdcMem;
HGDIOBJ oldBitmap;
hdc = BeginPaint(hWnd, &ps);
hdcMem = CreateCompatibleDC(hdc);
oldBitmap = SelectObject(hdcMem, hBitmap);
GetObject(hBitmap, sizeof(bitmap), &bitmap);
BitBlt(hdc, 0, 0, bitmap.bmWidth, bitmap.bmHeight, hdcMem, 0, 0, SRCCOPY);
SelectObject(hdcMem, oldBitmap);
DeleteDC(hdcMem);
EndPaint(hWnd, &ps);
break;
为了所需绘图的简单性(圆圈内的圆圈),您可以在 WM_PAINT 中全部绘制,但是按照建议创建缓冲区是一个很好的做法,它更快并且可以避免闪烁,还可以让您绘制零件而不是整个图像。要创建缓冲区,请使用:CreateCompatibleBitmap 创建内存 DC:
HDC hDC;
int width = 16;
int height= 16;
HDC hMemDC = ::CreateCompatibleDC(NULL);
HBITMAP hBmp = ::CreateCompatibleBitmap(hDC, width, height);
::SelectObject(hMemDC, hBmp);
并使用WINAPI绘图,看看Win32 GDI Drawing a circle
如果要从资源中绘制,请在 WM_CREATE 中加载位图:
HBITMAP g_hbmBall = NULL;
case WM_CREATE:
g_hbmBall = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_BALL));
if(g_hbmBall == NULL)
MessageBox(hwnd, "Could not load IDB_BALL!", "Error", MB_OK | MB_ICONEXCLAMATION);
break;
然后在 WM_PAINT 上绘制:
case WM_PAINT:
{
BITMAP bm;
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
HDC hdcMem = CreateCompatibleDC(hdc);
HBITMAP hbmOld = SelectObject(hdcMem, g_hbmBall);
GetObject(g_hbmBall, sizeof(bm), &bm);
BitBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);
SelectObject(hdcMem, hbmOld);
DeleteDC(hdcMem);
EndPaint(hwnd, &ps);
}
break;
仅仅因为它是一个小图标,您可以在窗口的 WndProc 的 WM_PAINT 上进行所有绘图...但只是为了避免创建另一个控件并且因为它是一个小位图。
希望对你有帮助!
编辑
如果您打算使用 GDI+(我虽然您对此不感兴趣......我很抱歉)。当然,您可以使用 GDI+ 绘制位图。所有的东西都改变了绘制你只需要创建一个图形并制作图纸。此外,您可以加载位图并使用“DrawImage”进行绘制,示例取自 MSDN:
Image image(L"Grapes.jpg");
graphics.DrawImage(&image, 60, 10);
当您在 WinProc 上时,您可以从 hDC 创建一个图形,然后进行绘制。记住要处理 Graphics,不要调用 base WinProc。
MSDN Reference