学习windows编程 day5 之 区域裁剪

时间:2021-12-08 20:31:24

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