c++ - WS_EX_TOOLWINDOW 在窗口销毁时跳转到背景

标签 c++ winapi sdk

奇怪的问题:

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

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

回答问题:

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

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

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

感谢您的帮助!

澄清示例代码:

// 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);

最佳答案

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

你的工具窗口没有跳下来;而是记事本正在跳跃。

您关闭了激活的窗口。系统将激活 z 顺序中下一个最高的顶级窗口。在这方面,您的工具窗口不算作顶级窗口(这是工具窗口的一部分)。因此,记事本被激活,并出现在顶部。

如果您想让工具窗口被激活,您可能真的不需要工具窗口。

关于c++ - WS_EX_TOOLWINDOW 在窗口销毁时跳转到背景,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/175738/

相关文章:

iphone - 从 iPhone 上的 Facebook Connect 应用程序开始

Android SDK 源标记

java - 如何使用最新的 SDK 启动 Azure VM 异步

c++ - 如何返回 vector 的2个索引?

c++ - 对于 Windows XP,有任何使用用户 token 的 SHGetKnownFolderPath 的替代方案吗?

c++ - 运行 meep C++ 基础知识

c - 单链表(如何正确删除/释放实体?)

winapi - Windows SDK 许可证

c++ - Qt3D 2.0广告牌改造

C++如何从字符串中读取两行以分隔字符串?