windows 即使我获得了类窗口的句柄,BringWindowToTop 也不起作用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4201728/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 15:37:05  来源:igfitidea点击:

BringWindowToTop is Not working even if I get the handle to Class Window

c++windowsmfccreatewindowregisterclass

提问by Simsons

I am registering my Class in the following method:

我正在使用以下方法注册我的班级:

BOOL CNDSClientDlg::InitInstance()
{
    //Register Window Updated on 16th Nov 2010, @Subhen
    // Register our unique class name that we wish to use
    WNDCLASS wndcls;
    memset(&wndcls, 0, sizeof(WNDCLASS));

    wndcls.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
    wndcls.lpfnWndProc  =  ::DefWindowProc; 
    wndcls.hInstance = AfxGetInstanceHandle();
    wndcls.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wndcls.lpszMenuName = NULL;

    //Class name for using FindWindow later
    wndcls.lpszClassName = _T("CNDSClientDlg");
    // Register new class and exit if it fails

    if(!AfxRegisterClass(&wndcls)) // [C]

    {
        return FALSE;
    }
}

and then calling the InitInstance method and creating the window in constructor of the Class:

然后调用 InitInstance 方法并在类的构造函数中创建窗口:

CNDSClientDlg::CNDSClientDlg(CWnd* pParent /*=NULL*/)
    : CDialog(CNDSClientDlg::IDD, pParent)

{
InitInstance();

    HWND hWnd;
    hInst = AfxGetInstanceHandle(); // Store instance handle in our global variable
    hWnd = CreateWindow(_T("CNDSClientDlg"), "NDS", WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInst, NULL);


}

Now in my other application I am finding the window and trying to bring to top:

现在在我的另一个应用程序中,我找到了窗口并尝试将其置于顶部:

EditAble to bring newlyCreated Windows with below code

编辑能够使用以下代码带来新创建的 Windows

 CWnd *pWndPrev = NULL;
                    CWnd *FirstChildhWnd = NULL;
                    pWndPrev = CWnd::FindWindow(_T("CNDSClientDlg"),NULL);
                    if(pWndPrev != NULL)
                    {
                        //pWndPrev->BringWindowToTop();
                        WINDOWPLACEMENT wndplacement;
                        pWndPrev->GetWindowPlacement(&wndplacement);
                        wndplacement.showCmd = SW_RESTORE;
                        pWndPrev->SetWindowPlacement(&wndplacement);
                        pWndPrev->SetForegroundWindow();

                        FirstChildhWnd = pWndPrev->GetLastActivePopup();
                        if (pWndPrev != FirstChildhWnd)
                        {
                            // a pop-up window is active, bring it to the top too
                            FirstChildhWnd->GetWindowPlacement(&wndplacement);
                            wndplacement.showCmd = SW_RESTORE;
                            FirstChildhWnd->SetWindowPlacement(&wndplacement);
                            FirstChildhWnd->SetForegroundWindow();
                        }

I am able to find the window as pWndPrevis not NULL , but It is not bringing up my application to front. Do I need to register any other class Instead of CNDSClientDlg. I want to bring my MFC application to top.

我能够找到pWndPrev不是 NULL的窗口,但它没有将我的应用程序调到最前面。我是否需要注册任何其他类而不是 CNDSClientDlg。我想把我的 MFC 应用程序放在首位。

回答by cbranch

A few things to look at...

有几件事要看...

1) Try SetForegroundWindow() instead of BringWindowToTop(). It's been awhile since I've done Win32 programming, but I seem to recall that BringWindowToTop() has some limitations (especially when working with windows in different processes).

1) 尝试使用 SetForegroundWindow() 而不是BringWindowToTop()。我已经有一段时间没有完成 Win32 编程了,但我似乎记得BringWindowToTop() 有一些限制(尤其是在不同进程中使用Windows 时)。

2) There are some rules that Microsoft put in place regarding SetForegroundWindow() starting with Windows 2000. The short version is that only the front-most application can change the foreground window. The idea is that an application that is not front-most cannot "jump in front of" the active application. If a background application calls SetForegroundWindow(), Windows will flash the taskbar button for the app, but will not actually bring the app to the front. The user must do that. I'm oversimplifying the rules, but this may be something to look at depending on your specific scenario.

2) 从 Windows 2000 开始,Microsoft 就 SetForegroundWindow() 制定了一些规则。简短的版本是只有最前面的应用程序可以更改前景窗口。这个想法是,不是最前面的应用程序不能“跳到”活动应用程序的前面。如果后台应用程序调用 SetForegroundWindow(),Windows 将闪​​烁应用程序的任务栏按钮,但实际上不会将应用程序带到前面。用户必须这样做。我过于简化了规则,但这可能需要根据您的具体情况来查看。

回答by Leo Davidson

You may need to call AllowSetForegroundWindowin your "other" application before calling SetForegroundWindow.

在调用 SetForegroundWindow 之前,您可能需要在“其他”应用程序中调用AllowSetForegroundWindow

That is assuming your other application is the foreground app and is trying to pass on its foreground status to the application with the window.

那是假设您的另一个应用程序是前台应用程序,并试图将其前台状态传递给带有窗口的应用程序。

If neither app is the foreground app then you're not supposedto be able to bring a window to the front, although there are ways to do it (both accidentally and on purpose).

如果这两个应用程序都不是前台应用程序,那么您不应该将窗口放在前面,尽管有办法做到这一点(无论是偶然还是故意)。

回答by Goldorak

SetWindowPos(&wndTopMost, -1, -1, -1, -1,  SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
SetForegroundWindow();