gpt4 book ai didi

c++ - 使用 RedrawWindow 或 SendMessage(WM_PAINT) 重绘后窗口出现故障

转载 作者:太空宇宙 更新时间:2023-11-04 15:00:42 25 4
gpt4 key购买 nike

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

Glitching window

这是我的 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 处理程序的问题,因为有时在取消最小化程序时也会发生这种情况。

最佳答案

每次应用程序重绘时您都在创建组件 - 处理 WM_PAINT消息,这就是为什么会出现闪烁。将所有内容从:

HDC hdc = BeginPaint(hWnd, &ps);
// move everything in here to WM_CREATE message handling section
EndPaint(hWnd, &ps);

block 到 WM_CREATE部分。 paint 事件用于绘画,而不是用于创建窗口(组件)、发送消息或处理输入。声明:

switch (newDriveSelection)

更适合 WM_COMMAND消息处理部分。

关于c++ - 使用 RedrawWindow 或 SendMessage(WM_PAINT) 重绘后窗口出现故障,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45776329/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com