// Handler for drawing
void OnDraw(HWND hWnd)
{
PAINTSTRUCT ps;
HDC hdc, hdcMem, hdcNew;
HBITMAP hBmp;
HBRUSH hBr;
int dstX, dstY, i, offset;
RECT rt, rtmp;
hdc = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rt);
// First draw the colored bars in the upper part of the window that serve as
// the starting bitmap to rotate
offset = (rt.right - rt.left - 200) / 2;
rtmp.left = offset;
rtmp.right = offset + 1;
rtmp.top = 0;
rtmp.bottom = 200;
for (i = 0; i < 200; i++) {
hBr = CreateSolidBrush(RGB(i * 8 % 255, i * 5 % 255, i * 2 % 255));
FillRect(hdc, &rtmp, hBr);
DeleteObject(hBr);
rtmp.left++;
rtmp.right++;
}
// BitBlt the starting Bitmap into a memory HDC
hdcNew = CreateCompatibleDC(hdc);
hBmp = CreateCompatibleBitmap(hdc, 200,200);
SelectObject(hdcNew, hBmp);
BitBlt(hdcNew, 0, 0, 200, 200, hdc, (rt.right - rt.left - 200) / 2, 0, SRCCOPY);
// Rotate that memory HDC
RotateMemoryDC(hBmp, hdcNew, 200, 200, g_angle, hdcMem, dstX, dstY);
DeleteObject(hBmp);
DeleteDC(hdcNew);
// Create the output HDC
hdcNew = CreateCompatibleDC(hdc);
hBmp = CreateCompatibleBitmap(hdc, 400,400);
SelectObject(hdcNew, hBmp);
rtmp.left = rtmp.top = 0;
rtmp.right = rtmp.bottom = 400;
// Fill the output HDC with the window background color and BitBlt the rotated bitmap into it
FillRect(hdcNew, &rtmp, GetSysColorBrush(COLOR_WINDOW));
BitBlt(hdcNew, (400 - dstX) / 2, (400-dstY) / 2, dstX, dstY, hdcMem, 0, 0, SRCCOPY);
DeleteDC(hdcMem);
BitBlt(hdc, (rt.left + rt.right - 400) / 2, rt.bottom - 400, 400, 400, hdcNew, 0, 0, SRCCOPY);
DeleteObject(hBmp);
DeleteDC(hdcNew);
EndPaint(hWnd, &ps);
}
//
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
switch (message)
{
case WM_TIMER:
// Handle the redraw with the timer
g_angle = g_angle + .05f;
RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
OnDraw(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
复制代码