C/C++/Win32APIはまだまだ初心者です。
こちらのサイトのソースコードを確認・変更しながらダブルバッファリングの処理を勉強しているのですが、
以下の2点がどうしてもうまくいきません。
- 子ウィンドウ(ボタンなど)も一緒にダブルバッファリングの処理する
- BitBlt関数でコピー先長方形の領域を可変にする
どうしたらいいでしょうか……?
#include <windows.h>
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow) {
WNDCLASSEX wcx;
MSG msg;
HWND hWnd, hButton;
LPCSTR szTitle = TEXT("Sample");
LPCSTR szWindowClass = TEXT("SAMPLE");
ZeroMemory(&wcx, sizeof(wcx));
wcx.cbSize = sizeof(WNDCLASSEX);
wcx.style = 0;
wcx.lpfnWndProc = WndProc;
wcx.cbClsExtra = 0;
wcx.cbWndExtra = 0;
wcx.hInstance = hInstance;
wcx.hIcon = 0;
wcx.hIconSm = 0;
wcx.hCursor = LoadCursor(NULL, IDC_ARROW);
wcx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wcx.lpszMenuName = NULL;
wcx.lpszClassName = szWindowClass;
if (!RegisterClassEx(&wcx)) { return 0; }
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW | WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, HWND_DESKTOP, NULL, hInstance, NULL);
hButton = CreateWindow(TEXT("BUTTON"), TEXT("BUTTON"), WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,
100, 100, 100, 25, hWnd, NULL, hInstance, NULL);
if (!hWnd) { return 0; }
while (GetMessage(&msg, NULL, 0, 0) != 0) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam) {
static BITMAPINFO bmpInfo; // ビットマップ情報
static LPDWORD lpPixel; // ピクセル配列
static HBITMAP hBitmap; // ビットマップ
static HDC hMemDC; // オフスクリーン
WINDOWINFO winInfo;
GetWindowInfo(hWnd, &winInfo);
switch (uMessage) {
case WM_CREATE:
{
HDC hDC;
// DIB構造体の初期化
bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfo.bmiHeader.biWidth = winInfo.rcClient.right - winInfo.rcClient.left;
bmpInfo.bmiHeader.biHeight = winInfo.rcClient.bottom - winInfo.rcClient.top;
bmpInfo.bmiHeader.biPlanes = 1;
bmpInfo.bmiHeader.biBitCount = 32;
bmpInfo.bmiHeader.biCompression = BI_RGB;
// DIBセクションの作成
hDC = GetDC(hWnd);
hMemDC = CreateCompatibleDC(hDC);
hBitmap = CreateDIBSection(NULL, &bmpInfo, DIB_RGB_COLORS, (LPVOID*)&lpPixel, NULL, 0);
SelectObject(hMemDC, hBitmap);
SelectObject(hMemDC, GetStockObject(DC_PEN));
SelectObject(hMemDC, GetStockObject(DC_BRUSH));
ReleaseDC(hWnd, hDC);
}
break;
case WM_SHOWWINDOW:
SetTimer(hWnd, 1, 10, NULL);
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hDC;
// DIBセクションの描画
hDC = BeginPaint(hWnd, &ps);
SelectObject(hMemDC, GetStockObject(GRAY_BRUSH));
Rectangle(hMemDC, 0, 0, bmpInfo.bmiHeader.biWidth, bmpInfo.bmiHeader.biHeight);
BitBlt(hDC, 0, 0, bmpInfo.bmiHeader.biWidth, bmpInfo.bmiHeader.biHeight, hMemDC, 0, 0, SRCCOPY);
EndPaint(hWnd, &ps);
}
break;
case WM_ERASEBKGND:
// 何も処理しない⇒塗り潰した
return 1;
case WM_SIZING:
case WM_MDIMAXIMIZE:
bmpInfo.bmiHeader.biWidth = winInfo.rcClient.right - winInfo.rcClient.left;
bmpInfo.bmiHeader.biHeight = winInfo.rcClient.bottom - winInfo.rcClient.top;
hBitmap = CreateDIBSection(NULL, &bmpInfo, DIB_RGB_COLORS, (LPVOID*)&lpPixel, NULL, 0);
InvalidateRect(hWnd, NULL, TRUE);
break;
case WM_TIMER:
//ダブルバッファリングの動作を確認する為のタイマー
InvalidateRect(hWnd, NULL, TRUE);
break;
case WM_CLOSE:
// DIBセクションの破棄
DeleteDC(hMemDC);
DeleteObject(hBitmap);
DestroyWindow(hWnd);
break;
case WM_DESTROY:
KillTimer(hWnd, 1);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMessage, wParam, lParam);
}
return 0;
}