none
一个LineTo函数画出两条线段 RRS feed

  • 问题

  • 经典的《windows程序设计》第五版第五章“Rectangles, Regions, Clipping”, 有一个演示Clipping的例子程序 clover.c。这个程序运行出现奇怪问题。 下面是我对该例子稍加改动后的程序。很明显, 一条LineTo函数调用出现了两条线段(窗口最大化后最明显)。 关闭win7 “桌面组合”后, 这个问题消失, 打开“桌面组合” 问题出现。 这是不是一个bug? 

    #include<windows.h>
    #include<math.h>
    #define TWO_PI (2.0 * 3.14159)
    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    {
        static TCHAR szAppName[] = TEXT("Clover");
        static TCHAR szWndName[] = TEXT("Draw a clover");
        BOOL bRet;
        MSG msg;
        HWND hwnd;
        WNDCLASS wndclass;
        wndclass.style = CS_HREDRAW | CS_VREDRAW;
        wndclass.lpfnWndProc = WndProc;
        wndclass.cbClsExtra = 0;
        wndclass.cbWndExtra = 0;
        wndclass.hInstance = hInstance;
        wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
        wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
        wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
        wndclass.lpszMenuName = NULL;
        wndclass.lpszClassName = szAppName;
        if (!RegisterClass(&wndclass)) {
            MessageBox(NULL, TEXT("Program requires Windows NT!"), szAppName, MB_ICONERROR);
            return FALSE;
        }
        hwnd = CreateWindow(szAppName, szWndName, WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
        if (!hwnd) {
            MessageBox(NULL, TEXT("Can not create window!"), szAppName, MB_ICONERROR);
            return FALSE;
        }
        ShowWindow(hwnd, nCmdShow);
        UpdateWindow(hwnd);
        while (bRet = GetMessage(&msg, NULL, 0, 0)) {
            if (bRet == -1 ) {
                MessageBox(NULL, TEXT("Can not get message!"), szAppName, MB_ICONERROR);
                return FALSE;
            }               
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        return msg.wParam;
    }
    LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
    {
        static HRGN hRgnClip;
        static int cxClient, cyClient;
        double fAngle, fRadius;
        HCURSOR hCursor;
        HDC hdc;
        HRGN hRgnTemp[6];
        int i;
        PAINTSTRUCT ps;
        HBRUSH hbr;
        static TCHAR szBuffer [50];
        switch (iMsg) {
        case WM_SIZE:
            cxClient = LOWORD(lParam);
            cyClient = HIWORD(lParam);
            hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
            ShowCursor(TRUE);
            if (hRgnClip)
                DeleteObject(hRgnClip);
            
            hRgnTemp[0] = CreateEllipticRgn(0, cyClient / 3, cxClient / 2, 2 * cyClient / 3);
            hRgnTemp[1] = CreateEllipticRgn(cxClient / 2, cyClient / 3, cxClient, 2 * cyClient / 3);
            hRgnTemp[2] = CreateEllipticRgn(cxClient / 3, 0, 2 * cxClient / 3, cyClient / 2);
            hRgnTemp[3] = CreateEllipticRgn(cxClient / 3, cyClient / 2, 2 * cxClient / 3, cyClient);
            hRgnTemp[4] = CreateRectRgn(0, 0, 1, 1);
            hRgnTemp[5] = CreateRectRgn(0, 0, 1, 1);
            hRgnClip = CreateRectRgn(0, 0, 1, 1);
            CombineRgn(hRgnTemp[4], hRgnTemp[0], hRgnTemp[1], RGN_OR);
            CombineRgn(hRgnTemp[5], hRgnTemp[2], hRgnTemp[3], RGN_OR);
            CombineRgn(hRgnClip, hRgnTemp[4], hRgnTemp[5], RGN_XOR);
            for (i = 0; i < 6; i++)
                DeleteObject(hRgnTemp[i]);
            SetCursor(hCursor);
            ShowCursor(FALSE);
            return 0;
        case WM_PAINT:
            hdc = BeginPaint(hwnd, &ps);
            hbr = GetStockObject(GRAY_BRUSH);
            FillRgn(hdc, hRgnClip, hbr);
            DeleteObject(hbr);
            SetViewportOrgEx(hdc, cxClient / 2, cyClient / 2, NULL);
            SelectClipRgn(hdc, hRgnClip);
            fRadius = hypot(cxClient / 2.0, cyClient / 2.0);
            fAngle = 3 * TWO_PI / 16;
            //for (fAngle = 0.0; fAngle < TWO_PI; fAngle += TWO_PI / 360) {
                MoveToEx(hdc, 0, 0, NULL);
    //          LineTo(hdc,(int) (fRadius * cos(fAngle) + 0.5) / 3, (int) (-fRadius * sin(fAngle) + 0.5) / 3);
                LineTo(hdc, (int) (fRadius * cos(fAngle) + 0.5), (int) (-fRadius * sin(fAngle) + 0.5));
    //          LineTo(hdc, 0, 0);
                //TextOut(hdc, 200, 0, szBuffer, wsprintf(szBuffer, TEXT("x = %d, y = %d"),
                //  (int) (fRadius * cos(fAngle) + 0.5), (int) (-fRadius * sin(fAngle) + 0.5) ));
            //  }
            EndPaint(hwnd, &ps);
            return 0;
        case WM_DESTROY:
            DeleteObject(hRgnClip);
            PostQuitMessage(0);
            return 0;
        }
        return DefWindowProc(hwnd, iMsg, wParam, lParam);
    }

    2018年4月16日 0:59