我有一个Windows程序,其中有两个2个窗口:

hwnd (main interface)

hwnd2 (toplevel window, no parent, created by hwnd)

当我双击hwnd时,我需要hwnd2弹出并显示一些数据,因此我使用此函数将hwnd2置于顶部:
BringWindowToTop(hwnd2);

hwnd2登顶,但有一件奇怪的事。当我再次单击hwnd2时,hwnd(主界面)会自动再次弹出。
我试图使用以下函数来解决此问题,但是它们都不起作用。
SetWindowPos(hwnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
                                                                  //doesn't work

BringWindowToTop(hwnd2);    //This is the function brings hwnd2 to top

SetForegroundWindow(hwnd2); //doesn't work

SetWindowPos(hwnd2, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
                                                                  //doesn't work

SetWindowPos(hwnd2, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
                                       // hwnd2 "always" on top, not what I want

SetActiveWindow(hwnd2); // doesn't work too (for replying to Magnus Skog, thanks)

SwitchToThisWindow(hwnd2, TRUE);// got the same problem with BringWindowToTop function
SwitchToThisWindow(hwnd2, FALSE);

我该如何解决这个问题?
提前致谢。

(为了回复aJ,hwnd2没有父级,因为它必须是顶层窗口,因此它可以位于其他窗口的前面/后面)

(hwnd2是一种媒体播放器,它由几个窗口组成,其中一个窗口用于视频显示,另外两个跟踪栏控件用于进度条和音量栏,一个工具栏控件用于控制面板。)

(有一个方法可能会有所帮助,无论我单击hwnd2的哪个窗口,hwnd都会自动弹出,就像“鼠标在Zwnd上位于hwnd的顶部”一样,包括菜单栏和非工作区,等等。)

(此媒体播放器是在Direct Show中编写的。我使用IVideoWindow::put_Owner将视频窗口作为视频所有者,Direct Show在内部创建了一个子视频窗口作为该视频窗口的子级。除了该子视频窗口之外,我看不到源代码,我看不到hwnd2中有任何可疑的东西。)

我找到了原因,这是因为Direct Show。我使用多线程执行它,然后问题解决了。但为什么??

通过使用PostMessage(而不是SendMessage)可以解决此问题。

最佳答案

试试这个,据说是来自M $

    HWND hCurWnd = ::GetForegroundWindow();
    DWORD dwMyID = ::GetCurrentThreadId();
    DWORD dwCurID = ::GetWindowThreadProcessId(hCurWnd, NULL);
    ::AttachThreadInput(dwCurID, dwMyID, TRUE);
    ::SetWindowPos(m_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
    ::SetWindowPos(m_hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE);
    ::SetForegroundWindow(m_hWnd);
    ::SetFocus(m_hWnd);
    ::SetActiveWindow(m_hWnd);
    ::AttachThreadInput(dwCurID, dwMyID, FALSE);

为了使窗口顶部,您应该获取窗口句柄,线程句柄,处于前台的Windows线程句柄

然后将线程附加到前景窗口线程,并通过AttachThreadInput获取输入,然后设置窗口的z顺序
到最顶部,然后将其z顺序恢复为正常,请调用SetForegroundWindow,SetFocus,SetActiveWindow以确保我们的窗口位于顶部并处于 Activity 状态并具有焦点

然后从旧的前台窗口线程断开输入队列,使我们的线程成为唯一捕获输入事件的线程

那么为什么要调用AttachThreadInput,这是因为



AttachThreadInput是做什么的?



我们使用SetWindowPos将窗口置于最高位置,并通过使用SWP_HIDEWINDOW显示该窗口是否隐藏



如果您的问题是窗口也已最小化,则应在最后添加一行代码
ShowWindow(m_hWnd, SW_RESTORE);

关于c++ - Win32 : Bring a window to top,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/916259/

10-11 16:23