0

私はずっと投稿を読んで、さまざまなアプローチを試してきましたが、これを機能させることはできません。

ユーザーがアプリケーションをクリックする前に、最後のウィンドウを追跡できるようにしたい。このようにして、それを前面に表示し、コピーコマンドを送信して、ユーザーが選択したものをすべて取得できます。

フックを使用してアクティブ化されたウィンドウの通知を受信することを考えましたが、期待どおりに機能していません。HSHELL_WINDOWACTIVATEDグローバルフックを使用して、現在および最後のアクティブなウィンドウを追跡していますが、アプリケーションを指すように、常に両方のハンドルが同じになるようにしています。

コードは次のようになります。

#pragma data_seg("ASEG")  
  HWND lastWindow = 0;
  HWND currentWindow = 0;
#pragma data_seg()  
#pragma comment(linker, "/section:ASEG,RWS") 

HINSTANCE dllHandle;  

BOOL APIENTRY DllMain(    
         HINSTANCE hinstDLL,  
         DWORD fdwReason,  
         PVOID lpReserved )  
{ 
    switch( fdwReason )  
    {  
    case DLL_PROCESS_ATTACH:    
        dllHandle = hinstDLL;    
        return TRUE;  
        break;  
    }  
}  

LRESULT CALLBACK ShellHookProc(int nCode, WPARAM wParam, LPARAM lParam)   
{  
    if (nCode > 0)
    {
        switch (nCode)
        {
        case HSHELL_WINDOWACTIVATED: lastWindow = currentWindow;
                         currentWindow = (HWND)wParam;
                         break;
        }
    }

    return ::CallNextHookEx(NULL, nCode,wParam,lParam);
}

extern "C" {

__declspec(dllexport) void Init()
{   
    SetWindowsHookEx(WH_SHELL, ShellHookProc, dllHandle, 0);    
}

}

後で、lastWindowを使用してそのウィンドウを前面に表示し、Ctrl+Cコマンドを送信します。

ハンドルごとにGetWindowTextA(..)を呼び出すと、最初に別のウィンドウをアクティブにしてアプリケーションに戻ると、lastWindowは空白とcurrentWindowのアプリケーション名を取得します。連続してアクティブ化すると、lastWindowとcurrentWindowの両方のアプリケーションの名前が常に取得されます。なぜこれが起こっているのかよくわかりません。何か案は?

ありがとう!

4

1 に答える 1

1

SetWinEventHookを使用できると思います。このフックを使用すると、EVENT_SYSTEM_FOREGROUNDメッセージをキャプチャできるため、ウィンドウが前面に表示されるたびに、ウィンドウハンドルをキャプチャできます。次に、アプリウィンドウがアクティブになったら、最後にキャプチャした値を確認します。

これを参照してください:https ://stackoverflow.com/a/4407715/1502289

また、独自のコードでは、ウィンドウハンドルが独自のウィンドウへのハンドルであるかどうかを確認するために、単純に比較を行うことができます。そうでない場合は、ハンドルを保存します。

例:

...
case HSHELL_WINDOWACTIVATED: 
if (lastWindow != [your own window's handle])
{
    lastWindow = (HWND)wParam;
}
break;
...
于 2012-10-31T18:46:37.767 に答える