Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用RedrawWindow或SendMessage(WM_PAINT)重新绘制后出现窗口故障 我用标准的Windows API编写C++中的应用程序。它使用按钮进行一些简单的注册表修改。按下按钮时,会更改底部显示的标签。要更改它,我需要重新绘制窗口,该窗口会根据需要自动更改标签。但当我重新绘制窗口时,它开始出现故障。静态标签开始闪烁,按钮完全丢失,但在移动窗口后停止。下面是它发生的GIF:_C++_Winapi_Wm Paint - Fatal编程技术网

使用RedrawWindow或SendMessage(WM_PAINT)重新绘制后出现窗口故障 我用标准的Windows API编写C++中的应用程序。它使用按钮进行一些简单的注册表修改。按下按钮时,会更改底部显示的标签。要更改它,我需要重新绘制窗口,该窗口会根据需要自动更改标签。但当我重新绘制窗口时,它开始出现故障。静态标签开始闪烁,按钮完全丢失,但在移动窗口后停止。下面是它发生的GIF:

使用RedrawWindow或SendMessage(WM_PAINT)重新绘制后出现窗口故障 我用标准的Windows API编写C++中的应用程序。它使用按钮进行一些简单的注册表修改。按下按钮时,会更改底部显示的标签。要更改它,我需要重新绘制窗口,该窗口会根据需要自动更改标签。但当我重新绘制窗口时,它开始出现故障。静态标签开始闪烁,按钮完全丢失,但在移动窗口后停止。下面是它发生的GIF:,c++,winapi,wm-paint,C++,Winapi,Wm Paint,以下是我的WndProc函数: LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { static HFONT s_hFont = NULL; HWND drive; switch (message) { case WM_COMMAND: { int wmId = LOWORD(wPa

以下是我的WndProc函数:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
    static HFONT s_hFont = NULL;
    HWND drive;
    switch (message)
    {
        case WM_COMMAND:
            {
                int wmId = LOWORD(wParam);
                // Parse the menu selections:
                switch (wmId)
                {
                    case IDM_ABOUT:
                        DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
                        break;
                    case IDM_EXIT:
                        DestroyWindow(hWnd);
                        break;
                    case APPLY_BUTTON:
                        SetRegistryValues(hWnd);
                        break;
                    case CDRIVE_BUTTON:
                        newDriveSelection = 0;
                        RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE); // tried both this...
                        break;
                    case DDRIVE_BUTTON:
                        newDriveSelection = 1;
                        InvalidateRect(hWnd, hWndSize, NULL); // ...and this
                        break;
                    default:
                        return DefWindowProc(hWnd, message, wParam, lParam);
                }
            }
            break;
    case WM_CREATE:
        {
        const TCHAR* fontName = _T("Tahoma");
        const long nFontSize = 10;

        HDC hdc = GetDC(hWnd);

        LOGFONT logFont = {0};
        logFont.lfHeight = -MulDiv(nFontSize, GetDeviceCaps(hdc, LOGPIXELSY), 72);
        logFont.lfWeight = FW_MEDIUM;
        _tcscpy_s(logFont.lfFaceName, fontName);

        s_hFont = CreateFontIndirect(&logFont);
        ReleaseDC(hWnd, hdc);
        //s_hFont = (HFONT)GetStockObject();
    }
    break;
    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);
            HWND CDrvButton = CreateWindow(
                L"BUTTON",  // Predefined class; Unicode assumed 
                L"Set to C: Drive",      // Button text 
                WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,  // Styles 
                20,         // x position 
                20,         // y position 
                156,        // Button width
                21,        // Button height
                hWnd,     // Parent window
                (HMENU)CDRIVE_BUTTON,       // No menu.
                (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE),
                NULL);
            HWND DDrvButton = CreateWindow(
                L"BUTTON",  // Predefined class; Unicode assumed 
                L"Set to D: Drive",      // Button text 
                WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,  // Styles 
                20,         // x position 
                53,         // y position 
                156,        // Button width
                21,        // Button height
                hWnd,     // Parent window
                (HMENU)DDRIVE_BUTTON,       // No menu.
                (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE),
                NULL);
            HWND quit = CreateWindow(
                L"BUTTON",  // Predefined class; Unicode assumed 
                L"Quit",      // Button text 
                WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,  // Styles 
                20,         // x position 
                125,         // y position 
                54,        // Button width
                21,        // Button height
                hWnd,     // Parent window
                (HMENU)IDM_EXIT,       // No menu.
                (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE),
                NULL);
            HWND apply = CreateWindow(
                L"BUTTON",  // Predefined class; Unicode assumed 
                L"Apply",      // Button text 
                WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,  // Styles 
                220,         // x position 
                125,         // y position 
                63,        // Button width
                21,        // Button height
                hWnd,     // Parent window
                (HMENU)APPLY_BUTTON,       // No menu.
                (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE),
                NULL);
            HWND the = CreateWindow(
                L"static", 
                L"ST_U",
                WS_CHILD | WS_VISIBLE | WS_TABSTOP,
                35, 
                82, 
                28, 
                17,
                hWnd, 
                (HMENU)(501),
                (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE), 
                NULL);
            drive = CreateWindow(
                L"static",
                L"ST_U",
                WS_CHILD | WS_VISIBLE | WS_TABSTOP,
                66,
                82,
                18,
                17,
                hWnd,
                (HMENU)(501),
                (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE),
                NULL);
            HWND selected = CreateWindow(
                L"static",
                L"ST_U",
                WS_CHILD | WS_VISIBLE | WS_TABSTOP,
                87,
                82,
                196,
                17,
                hWnd,
                (HMENU)(501),
                (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE),
                NULL);
            HWND newdrv = CreateWindow(
                L"static",
                L"ST_U",
                WS_CHILD | WS_VISIBLE | WS_TABSTOP,
                25,
                99,
                276,
                23,
                hWnd,
                (HMENU)(501),
                (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE),
                NULL);
            SetWindowText(the, L"The");
            SetWindowText(drive, GetDriveLetter());
            SetWindowText(selected, L"drive is set as the current drive.");
            switch (newDriveSelection) {
                case 0:
                    SetWindowText(newdrv, L"The C: drive will be when you click Apply.");
                    break;
                case 1:
                    SetWindowText(newdrv, L"The D: drive will be when you click Apply.");
                    break;
                default:
                    SetWindowText(newdrv, L"");
                    break;
            }
            SendMessage(CDrvButton, WM_SETFONT, (WPARAM)s_hFont, (LPARAM)MAKELONG(TRUE, 0));
            SendMessage(DDrvButton, WM_SETFONT, (WPARAM)s_hFont, (LPARAM)MAKELONG(TRUE, 0));
            SendMessage(apply, WM_SETFONT, (WPARAM)s_hFont, (LPARAM)MAKELONG(TRUE, 0));
            SendMessage(quit, WM_SETFONT, (WPARAM)s_hFont, (LPARAM)MAKELONG(TRUE, 0));
            SendMessage(the, WM_SETFONT, (WPARAM)s_hFont, (LPARAM)MAKELONG(TRUE, 0));
            SendMessage(drive, WM_SETFONT, (WPARAM)s_hFont, (LPARAM)MAKELONG(TRUE, 0));
            SendMessage(selected, WM_SETFONT, (WPARAM)s_hFont, (LPARAM)MAKELONG(TRUE, 0));
            SendMessage(newdrv, WM_SETFONT, (WPARAM)s_hFont, (LPARAM)MAKELONG(TRUE, 0));
            EndPaint(hWnd, &ps);
        }
        break;
    case WM_DESTROY:
        DeleteObject(s_hFont);
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

是什么导致我的代码出现问题?我认为这是WM_PAINT处理程序的问题,因为在取消最小化程序时有时也会发生这种情况。

每次应用程序重新绘制-处理消息时,您都在创建组件,这就是为什么会出现闪烁的原因。从以下位置移动所有内容:

HDC hdc = BeginPaint(hWnd, &ps);
// move everything in here to WM_CREATE message handling section
EndPaint(hWnd, &ps);
块到该部分。paint事件用于绘制,而不是创建windows组件、发送消息或处理输入。声明如下:

switch (newDriveSelection)

更适合于消息处理部分。

为什么要在WM_PAINT上创建窗口?除此之外,这里不需要调用重画窗口,失效可能更干净。而且你绝对不能发送WM_PAINT。你需要养成阅读文档的习惯。它相当简洁。如果这还不够,请提供更多信息。