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);
}