关闭字体对话框时窗口失去焦点

Posted

技术标签:

【中文标题】关闭字体对话框时窗口失去焦点【英文标题】:Window loses focus when closing font dialog 【发布时间】:2015-04-11 23:16:54 【问题描述】:
#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;

关闭字体对话框和第二个窗口后,第一个窗口失去焦点并进入底部。另一个应用程序的窗口显示在顶部。这只发生在我关闭字体对话框,然后关闭第二个窗口时。如果只显示第一个窗口和第二个窗口,并且我关闭了第二个窗口,则第一个窗口不会失去焦点。如果您想对此进行测试,请确保在测试之前,该应用程序下方有另一个应用程序的另一个窗口。为什么第一个窗口失去焦点?

【问题讨论】:

这与第二个窗口是一个拥有的窗口有关。其他主要错误的地方是对话框不是第一个窗口的模式,可能是相关的。戳了一会儿,没找到破绽。 【参考方案1】:

您可以使用 MessageBox 重现相同的问题。任何时候第二个窗口被禁用/启用(而父窗口始终处于启用状态)并且第二个窗口关闭,第一个窗口可能无法正确恢复。 WS_POPUP 会解决这个问题。

当第二个窗口最小化而第一个窗口保持在顶部时,会出现另一个问题。您在第二个窗口中删除 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);

【讨论】:

以上是关于关闭字体对话框时窗口失去焦点的主要内容,如果未能解决你的问题,请参考以下文章

失去焦点时自动关闭 ExtJS 窗口

关于窗口失去焦点的问题,出高分求高手帮忙解决!

窗口/舞台失去焦点时的事件

失去焦点后无法取消对话框?

当我失去焦点时选项卡不起作用

qt对话框失去焦点透明