Ich schreibe eine Anwendung in C++ mit der Standard-Windows-API. Es macht einige einfache Änderungen der Registrierung mit Schaltflächen. Wenn eine Taste gedrückt wird, ändert sich die Beschriftung unten. Um es zu ändern, muss ich das Fenster neu streichen (das Etikett wird bei Bedarf automatisch geändert). Aber wenn ich das Fenster neu zeichne, fängt es an zu glitchen. Die statischen Beschriftungen beginnen zu flackern, und die Schaltflächen fehlen vollständig, aber nach dem Verschieben des Fensters bleibt sie stehen. Hier ist ein GIF es passiert:Fensterfehler nach dem Redrawing mit RedrawWindow oder SendMessage (WM_PAINT)
hier meine WndProc
Funktion ist:
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;
}
Was das Problem mit meinem Code verursachen könnte? Ich denke, es ist ein Problem mit dem WM_PAINT-Handler, da dies manchmal auch passiert, wenn das Programm nicht minimiert wird.
Warum erstellen Sie Windows auf 'WM_PAINT'? – VTT
Darüber hinaus ist der Aufruf von RedrawWindow hier unnötig, die Ungültigkeit ist wahrscheinlich sauberer. Und Sie dürfen WM_PAINT niemals senden. –
Sie müssen sich angewöhnen, die Dokumentation zu lesen. [WM_PAINT] (https://msdn.microsoft.com/en-us/library/windows/desktop/dd145213.aspx) ist ziemlich prägnant. Wenn das nicht genug ist, bietet [The WM_PAINT Message] (https://msdn.microsoft.com/en-us/library/dd145137.aspx) weitere Informationen. – IInspectable