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

 

posted @ 2018-03-06 21:49  山上有风景  阅读(332)  评论(0编辑  收藏  举报