【问题标题】:WS_EX_TOOLWINDOW jumping to background on window destroyWS_EX_TOOLWINDOW 在窗口销毁时跳转到背景
【发布时间】:2023-03-20 05:39:01
【问题描述】:

奇怪的问题:

  1. 打开一个大记事本窗口
  2. 创建工具窗口(样式 WS_EX_TOOLWINDOW)
  3. 再创建 2 个窗口(正常重叠)(WS_OVERLAPPED)
  4. 关闭这 2 个重叠的窗口(桌面或工具窗口的子窗口)
  5. 工具窗口跳到记事本窗口后面

有人知道为什么会这样吗?或者我可能做错了什么?我会说“Windows 中的错误”,但这种情况很少见。

回答问题:

它不是一个对话窗口,而是一个完整的窗口。如果我让它有正确的孩子(即:不是桌面的孩子),孩子的任务栏条目不会出现(可能很容易修复),但无论哪种方式,错误仍然会发生。

我已包含显示问题的示例代码。我希望我只是创建错误的窗口或需要回复我没有回复的消息。

在此示例中,将打开一个工具窗口(没有任务栏条目,这是想要的)。然后单击该窗口,将打开一个子窗口。您单击子窗口,将打开另一个窗口。然后关闭新的子窗口和原始窗口,而不是获得焦点,而是立即跳转到其他窗口(记事本等)的后面。

感谢您的帮助!

澄清示例代码:

// WindowToback.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "WindowToback.h"

// Global Variables:
HINSTANCE g_instance;
HWND g_mainWnd = NULL;

wchar_t *szWindowClass = L"WindowToBackSub";
wchar_t *szWindowClass2 = L"WindowToBackSub2";

ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK    WndProc2(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);

int APIENTRY _tWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    MSG msg;

    MyRegisterClass(hInstance);

// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
    return FALSE;
}

// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}

return (int) msg.wParam;
}


ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;

wcex.cbSize = sizeof(WNDCLASSEX);

wcex.style          = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc    = WndProc;
wcex.cbClsExtra     = 0;
wcex.cbWndExtra     = 0;
wcex.hInstance      = hInstance;
wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINDOWTOBACK));
wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName   = MAKEINTRESOURCE(IDC_WINDOWTOBACK);
wcex.lpszClassName  = szWindowClass;
wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

RegisterClassEx(&wcex);

wcex.lpfnWndProc    = WndProc2;
wcex.lpszClassName  = szWindowClass2;

return RegisterClassEx(&wcex);
}

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   g_instance = hInstance; 
   g_mainWnd = CreateWindowEx(WS_EX_TOOLWINDOW,szWindowClass, szWindowClass,WS_OVERLAPPED,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

   if (!g_mainWnd) return FALSE;

   ShowWindow(g_mainWnd, nCmdShow);
   UpdateWindow(g_mainWnd);

   return TRUE;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
    case WM_LBUTTONDOWN:
    {
        HWND l_hwnd = CreateWindow(szWindowClass2, szWindowClass2, WS_VISIBLE | WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, g_instance, NULL);
        ShowWindow(l_hwnd,SW_SHOW);
        break;
    }

    case WM_DESTROY:
    {
        PostQuitMessage(0);
        return 0;
    }
}

return DefWindowProc(hWnd, message, wParam, lParam);
}

LRESULT CALLBACK WndProc2(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
    case WM_LBUTTONDOWN:
    {
        HWND l_hwnd = CreateWindow(szWindowClass2, szWindowClass2, WS_VISIBLE | WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, g_instance, NULL);
        ShowWindow(l_hwnd,SW_SHOW);
    }
    break;
}

return DefWindowProc(hWnd, message, wParam, lParam);

}

【问题讨论】:

    标签: c++ winapi sdk


    【解决方案1】:

    这并不奇怪。事实上,这正是我所期望的行为。

    你的工具窗口没有往下跳;而是记事本跳起来了。

    您关闭了已激活的窗口。系统将激活 z 顺序中的下一个最高顶级窗口。在这方面,您的工具窗口不算作顶级窗口(这是工具窗口的一部分)。所以记事本被激活,它来到了顶部。

    如果您希望激活您的工具窗口,那么您可能并不真正想要一个工具窗口。

    【讨论】:

      【解决方案2】:

      这三个窗口是另一个主窗口的对话框还是它们自己的应用程序?

      如果它们是对话框窗口,那么我会检查它们的父窗口是否被正确分配。

      如果它们是应用程序窗口,那么我会检查它们是否出现在任务栏中。

      如果没有关于问题的更多信息,很难给出更有意义的答案。

      【讨论】:

      • 我已更新问题以包含更多信息。感谢您到目前为止的回复!
      猜你喜欢
      • 2020-02-22
      • 2011-01-18
      • 2010-10-31
      • 2016-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多