0

アクティブなウィンドウ/プログラムに基づいて異なる設定をロードする必要があるアプリケーションを構築しています(たとえば、Chromeを使用している場合は、Chromeに関連付けられている設定が読み込まれ、MS Wordに切り替えると、MSWordの設定が読み込まれます)。

現在、アクティブなウィンドウが変更されるたびにデータベースから正しい設定をフェッチするクラスに取り組んでいます。このクラスには、最後にフェッチされた設定に基づいて値を返す「LookUp」メソッドもあります。

私が擬似コードで実装しようとしていることを説明するには:

class RecipeBook{
   public:
       RecipeBook();
       HWINEVENTEVENTHOOK hEvent;
       string currentProgram;
       static VOID CALLBACK WindowCallback(HWINEVENTHOOK hWinEventHook, 
                                           DWORD dwEvent,
                                           HWND hwnd, LONG idObject, 
                                           LONG idChild, 
                                           DWORD dwEventThread, 
                                           DWORD dwmsEventTime); //Actual callback
       void messageCheck(void*);
 }

 RecipeBook::RecipeBook(){
      this->hEvent = SetWinEventHook(EVENT_SYSTEM_FOREGROUND, 
                                     EVENT_SYSTEM_FOREGROUND, 
                                     NULL,&WinEventProcCallback, 
                                     0, 0, 
                                     WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS);

      Start messageCheck(void*) in separate thread
 }

 void messageCheck(void*){
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
     TranslateMessage(&msg);
     DispatchMessage(&msg);
    }

 }

 VOID CALLBACK WindowCallback(HWINEVENTHOOK hWinEventHook, 
                                           DWORD dwEvent,
                                           HWND hwnd, LONG idObject, 
                                           LONG idChild, 
                                           DWORD dwEventThread, 
                                           DWORD dwmsEventTime){

       Get the name of the active program from the HWND handle //This is working
       Update RecipeBook->CurrentProgram
 }

私がこれで抱えている問題:

1)別のスレッドで実行するメッセージチェックを取得できません。コードを順番に実行すると、正常に機能します。スレッドでmessageCheckを生成しようとすると(

    AfxBeginThread(&messageCheck, &currentProgram, THREAD_PRIORITY_NORMAL, 0, 0,NULL) 

)。

他のスレッドが作成されているようには見えません。

2)コールバックからRecipeBookの値を変更する方法がわかりません。コールバックから名前を返すことを考えましたが、それを機能させることができませんでした。コールバック内から文字列を編集できればいいのですが。

3)LookUpメソッドが呼び出されるたびに現在アクティブなプログラムを要求することを考えましたが、アクティブなWindowsプロセスIDではなく、呼び出し元のプロセスIDを取得するメソッドしか見つかりませんでした。

大きな質問ですが、アドバイスをいただければ幸いです。

ありがとう!

4

1 に答える 1

0
GetForgroundWindow()

それが私が探していたものです!

http://msdn.microsoft.com/en-us/library/windows/desktop/ms633505(v=vs.85).aspx

なんらかの理由でGetActiveWindow()を使おうとしていて、何らかの理由でForgroundウィンドウを見たときはいつでも、背景ウィンドウを考えていました。おっと!

マルチタスクやCALLBACKの実行方法について誰かが適切な説明を提供できない限り、この関数を使用して、ルックアップが実行されるたびに現在のウィンドウにクエリを実行します。それほど頻繁ではないはずであり、このプロセスはそれほど長くはかかりません。

ウィンドウハンドルを使用してアクティブなウィンドウ/PIDからプロセスの名前を取得する方法に興味がある人のために、これは私がそれを行ってきた方法です:

DWORD processID;
LPTSTR processName = new TCHAR[MAX_PATH];
DWORD nameSize = MAX_PATH;
HWND activeWindowH = GetForegroundWindow();
DWORD threadID = GetWindowThreadProcessId(activeWindowH,&processID);
HANDLE processHandle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_QUERY_INFORMATION,FALSE,processID);
BOOL nameSuccess = QueryFullProcessImageName(processHandle,0,processName,&nameSize);

乾杯!

于 2013-03-27T04:23:31.947 に答える