Window 关闭字体对话框时失去焦点
Window loses focus when closing font dialog
#include <windows.h>
#include <tchar.h>
LRESULT CALLBACK SecondWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_RBUTTONUP:
{
HFONT hFont;
LOGFONT lf;
CHOOSEFONT cf = {0};
hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
GetObject(hFont, sizeof(LOGFONT), &lf);
cf.Flags = CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
cf.hwndOwner = hwnd;
cf.lpLogFont = &lf;
cf.lStructSize = sizeof(CHOOSEFONT);
if(ChooseFont(&cf))
{
}
}
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
LRESULT CALLBACK FirstWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nShowCmd)
{
WNDCLASSEX wcFirst = {0}, wcSecond = {0};
HWND hwndFirst, hwndSecond;
MSG msg;
wcFirst.cbSize = sizeof(WNDCLASSEX);
wcFirst.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
wcFirst.hCursor = LoadCursor(0, IDC_ARROW);
wcFirst.hIcon = LoadIcon(0, IDI_APPLICATION);
wcFirst.hInstance = hInstance;
wcFirst.lpfnWndProc = FirstWndProc;
wcFirst.lpszClassName = TEXT("FirstClass");
wcSecond.cbSize = sizeof(WNDCLASSEX);
wcSecond.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
wcSecond.hCursor = LoadCursor(0, IDC_ARROW);
wcSecond.hIcon = LoadIcon(0, IDI_APPLICATION);
wcSecond.hInstance = hInstance;
wcSecond.lpfnWndProc = SecondWndProc;
wcSecond.lpszClassName = TEXT("SecondClass");
if(!RegisterClassEx(&wcFirst))
return 0;
if(!RegisterClassEx(&wcSecond))
return 0;
hwndFirst = CreateWindowEx(0, TEXT("FirstClass"), TEXT("First Window"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
700, 400, 0, 0, hInstance, 0);
if(!hwndFirst)
return 0;
hwndSecond = CreateWindowEx(0, TEXT("SecondClass"), TEXT("Second Window"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
700, 400, hwndFirst, 0, hInstance, 0);
if(!hwndSecond)
return 0;
ShowWindow(hwndFirst, nShowCmd);
ShowWindow(hwndSecond, nShowCmd);
while(GetMessage(&msg, 0, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
在我关闭字体对话框和第二个 window 后,第一个 window 失去焦点并转到底部。来自另一个应用程序的 window 显示在顶部。只有当我关闭字体对话框,然后关闭第二个 window 时才会发生这种情况。如果只显示第一个 window 和第二个 window,并且我关闭第二个 window,第一个 window 不会失去焦点。如果您想对此进行测试,请确保在测试之前,此应用下方还有另一个来自其他应用的 window。为什么第一个 window 失去焦点?
您可以使用 MessageBox 重现相同的问题。任何时候第二个 window 是 disabled/enabled(而父 window 一直启用)并且第二个 windows 关闭,第一个 window 可能不会恢复正常。 WS_POPUP
会解决这个问题。
当第二个 window 最小化而第一个 window 保留在顶部时,会出现另一个问题。您在第二个 window 中删除 WS_MINIMIZEBOX
以阻止它。您还可以使用 SetFocus(GetWindow(hwnd, GW_OWNER))
重置焦点
LRESULT CALLBACK SecondWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_RBUTTONUP:
MessageBox(hwnd, TEXT("Test"), 0, 0);
break;
case WM_CLOSE:
SetFocus(GetWindow(hwnd, GW_OWNER));//force parent window to restore
DestroyWindow(hwnd);
break;
//...
hwndSecond = CreateWindowEx(WS_EX_CONTROLPARENT, TEXT("SecondClass"), TEXT("Second Window"),
WS_POPUP | WS_SYSMENU | WS_CAPTION | WS_THICKFRAME | WS_MAXIMIZEBOX,
CW_USEDEFAULT, CW_USEDEFAULT, 700, 400, hwndFirst, 0, hInstance, 0);
#include <windows.h>
#include <tchar.h>
LRESULT CALLBACK SecondWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_RBUTTONUP:
{
HFONT hFont;
LOGFONT lf;
CHOOSEFONT cf = {0};
hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
GetObject(hFont, sizeof(LOGFONT), &lf);
cf.Flags = CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
cf.hwndOwner = hwnd;
cf.lpLogFont = &lf;
cf.lStructSize = sizeof(CHOOSEFONT);
if(ChooseFont(&cf))
{
}
}
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
LRESULT CALLBACK FirstWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nShowCmd)
{
WNDCLASSEX wcFirst = {0}, wcSecond = {0};
HWND hwndFirst, hwndSecond;
MSG msg;
wcFirst.cbSize = sizeof(WNDCLASSEX);
wcFirst.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
wcFirst.hCursor = LoadCursor(0, IDC_ARROW);
wcFirst.hIcon = LoadIcon(0, IDI_APPLICATION);
wcFirst.hInstance = hInstance;
wcFirst.lpfnWndProc = FirstWndProc;
wcFirst.lpszClassName = TEXT("FirstClass");
wcSecond.cbSize = sizeof(WNDCLASSEX);
wcSecond.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
wcSecond.hCursor = LoadCursor(0, IDC_ARROW);
wcSecond.hIcon = LoadIcon(0, IDI_APPLICATION);
wcSecond.hInstance = hInstance;
wcSecond.lpfnWndProc = SecondWndProc;
wcSecond.lpszClassName = TEXT("SecondClass");
if(!RegisterClassEx(&wcFirst))
return 0;
if(!RegisterClassEx(&wcSecond))
return 0;
hwndFirst = CreateWindowEx(0, TEXT("FirstClass"), TEXT("First Window"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
700, 400, 0, 0, hInstance, 0);
if(!hwndFirst)
return 0;
hwndSecond = CreateWindowEx(0, TEXT("SecondClass"), TEXT("Second Window"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
700, 400, hwndFirst, 0, hInstance, 0);
if(!hwndSecond)
return 0;
ShowWindow(hwndFirst, nShowCmd);
ShowWindow(hwndSecond, nShowCmd);
while(GetMessage(&msg, 0, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
在我关闭字体对话框和第二个 window 后,第一个 window 失去焦点并转到底部。来自另一个应用程序的 window 显示在顶部。只有当我关闭字体对话框,然后关闭第二个 window 时才会发生这种情况。如果只显示第一个 window 和第二个 window,并且我关闭第二个 window,第一个 window 不会失去焦点。如果您想对此进行测试,请确保在测试之前,此应用下方还有另一个来自其他应用的 window。为什么第一个 window 失去焦点?
您可以使用 MessageBox 重现相同的问题。任何时候第二个 window 是 disabled/enabled(而父 window 一直启用)并且第二个 windows 关闭,第一个 window 可能不会恢复正常。 WS_POPUP
会解决这个问题。
当第二个 window 最小化而第一个 window 保留在顶部时,会出现另一个问题。您在第二个 window 中删除 WS_MINIMIZEBOX
以阻止它。您还可以使用 SetFocus(GetWindow(hwnd, GW_OWNER))
重置焦点
LRESULT CALLBACK SecondWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_RBUTTONUP:
MessageBox(hwnd, TEXT("Test"), 0, 0);
break;
case WM_CLOSE:
SetFocus(GetWindow(hwnd, GW_OWNER));//force parent window to restore
DestroyWindow(hwnd);
break;
//...
hwndSecond = CreateWindowEx(WS_EX_CONTROLPARENT, TEXT("SecondClass"), TEXT("Second Window"),
WS_POPUP | WS_SYSMENU | WS_CAPTION | WS_THICKFRAME | WS_MAXIMIZEBOX,
CW_USEDEFAULT, CW_USEDEFAULT, 700, 400, hwndFirst, 0, hInstance, 0);