3

次の方法でクラスを登録しています。

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;
    }
}

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


}

現在、他のアプリケーションでウィンドウを見つけて、一番上に表示しようとしています:

以下のコードで新しく作成されたウィンドウを編集できます

 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();
                        }

pWndPrev NULL ではないため、ウィンドウを見つけることができますが、アプリケーションが前面に表示されません。CNDSClientDlg の代わりに他のクラスを登録する必要がありますか? MFC アプリケーションを一番上に表示したいと考えています。

4

4 に答える 4

14

見るべきいくつかのこと...

1) BringWindowToTop() の代わりに SetForegroundWindow() を試してください。Win32 プログラミングを行ってからしばらく経ちましたが、BringWindowToTop() にはいくつかの制限があることを思い出したようです (特に、異なるプロセスでウィンドウを操作する場合)。

2) Microsoft が Windows 2000 以降の SetForegroundWindow() に関して導入したいくつかのルールがあります。短いバージョンでは、最前面のアプリケーションのみがフォアグラウンド ウィンドウを変更できます。これは、最前面にないアプリケーションは、アクティブなアプリケーションの「前にジャンプ」できないという考え方です。バックグラウンド アプリケーションが SetForegroundWindow() を呼び出すと、Windows はアプリのタスク バー ボタンを点滅させますが、実際にはアプリを前面に表示しません。ユーザーはそれを行う必要があります。ルールを単純化しすぎていますが、特定のシナリオによっては、これを確認する必要がある場合があります。

于 2010-11-17T07:14:27.213 に答える
6

BringWindowToTop()は、呼び出しプロセスがフォアグラウンド プロセスであるか、最後の入力イベントを受け取った場合にのみ機能します。

代わりにCWnd::SetForegroundWindow()を呼び出してください。

于 2010-11-17T07:17:56.280 に答える
2

SetForegroundWindow を呼び出す前に、「他の」アプリケーションでAllowSetForegroundWindowを呼び出す必要がある場合があります。

これは、他のアプリケーションがフォアグラウンド アプリであり、そのフォアグラウンド ステータスをウィンドウを持つアプリケーションに渡そうとしていることを前提としています。

どちらのアプリもフォアグラウンド アプリではない場合、ウィンドウを前面に表示することはできませんが、それを行う方法はあります (偶然にも意図的にも)

于 2010-11-17T08:09:51.017 に答える
0
SetWindowPos(&wndTopMost, -1, -1, -1, -1,  SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
SetForegroundWindow();
于 2012-09-18T13:49:11.797 に答える