学习windows编程 day5 之 区域裁剪
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; RECT rect; static int cxClient, cyClient; HRGN hRgn[6]; static HRGN hTotRgn; double fAngle, fRadius; HCURSOR hCursor; switch (message) { case WM_SIZE: cxClient = LOWORD(lParam); cyClient = HIWORD(lParam); hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT)); ShowCursor(TRUE); //创建四个区域 //先左右两个 hRgn[0]=CreateEllipticRgn(0, cyClient / 3, cxClient / 2, cyClient * 2 / 3); hRgn[1] = CreateEllipticRgn(cxClient, cyClient / 3, cxClient / 2, cyClient * 2 / 3); //后上下两个 hRgn[2] = CreateEllipticRgn(cxClient / 3, 0, cxClient * 2 / 3, cyClient / 2); hRgn[3] = CreateEllipticRgn(cxClient / 3, cyClient/2, cxClient * 2 / 3, cyClient); //其余的先设为一个较小的区域(空) hRgn[4] = CreateEllipticRgn(0, 0, 1, 1); hRgn[5] = CreateEllipticRgn(0, 0, 1, 1); hTotRgn = CreateEllipticRgn(0, 0, 1, 1); //调用combinRgn后原来这些区域会被销毁 //先合并左右 CombineRgn(hRgn[4], hRgn[0], hRgn[1], RGN_OR); CombineRgn(hRgn[5], hRgn[2], hRgn[3], RGN_OR); //合并为一个总区域句柄 CombineRgn(hTotRgn, hRgn[4], hRgn[5], RGN_XOR); for (int i = 0; i < 6; i++) DeleteObject(hRgn[i]); SetCursor(hCursor); ShowCursor(TRUE); break; case WM_PAINT: hdc = BeginPaint(hwnd, &ps); GetClientRect(hwnd, &rect); SetViewportOrgEx(hdc, cxClient / 2, cyClient / 2, NULL); //选中剪切区域后,会在这个区域作图 SelectClipRgn(hdc, hTotRgn); FrameRgn(hdc, hTotRgn, (HBRUSH)GetStockObject(BLACK_BRUSH),1,1); //内部画阴影 fRadius = _hypot(cxClient / 2, cyClient / 2);//直角三角形斜边 for (fAngle = 0.0; fAngle < PI * 2;fAngle += PI*2/360) { MoveToEx(hdc, 0, 0, NULL); LineTo(hdc, (int)(fRadius*cos(fAngle) + 0.5), (int)(-fRadius*sin(fAngle) + 0.5)); } EndPaint(hwnd, &ps); break; case WM_DESTROY: DeleteObject(hTotRgn); PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, message, wParam, lParam); }