2

編集:私は言及するのを忘れました、私はウィンドウを作成するDLLのソースコードを持っていないので、HWNDを返すように関数を実際に変更することはできません。

Win32アプリケーションを作成していて、エクスポートされた関数 "void X();"の1つを介してウィンドウを作成するDLLを使用しています。WinMain()でX()を呼び出します。

それは私のためのウィンドウを作成します。X()がvoidを返すため、このエクスポートされたライブラリ関数によって作成されたウィンドウのHWNDを取得したいので、他のAPI呼び出しに使用できます。誰かがHWNDを入手するのが最も簡単だと言うことができますか?

私はここで検索して質問に答えましたが、どういうわけか正確で適切な解決策を見つけることができません。EnumWIndows()を試し、プロセスIDを取得して、現在のスレッドプロセスIDと比較しました。しかし、HWNDを取得するには、はるかに効率的で簡単な方法があるはずです。結局のところ、私は最初にこのウィンドウを作成したプロセスのWinMainにいます。

私がここに書くのを逃したことを説明する必要があるならば、私に知らせてください。

これは非常に基本的なことであり、ここで露骨に何かが欠けていると確信しています。ごめん。ありがとうございます。それでは、お元気で!

4

2 に答える 2

2

これを行う最も簡単な方法は、関数を使用することSetWindowsHookEx(WH_CBT, fun, NULL, GetCurrentThreadId())です。次に、fun多数のイベントが発生すると、ユーザーが定義したコールバック関数が呼び出されます。必要なのはですHCBT_CREATEWND

そのように考えてください(完全にテストされていません):

HWND hDllHandle = NULL;
LRESULT CALLBACK X_CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (nCode == HCBT_CREATEWND)
        hDllHandle = (HWND)wParam;
    return CallNextHookEx(NULL, nCode, wParam, lParam); //The first parameter is useless
}

HWND CallXAndGetHWND()
{
    HHOOK hDllHook = SetWindowsHookEx(WH_CBT, X_CBTProc, NULL, GetCurrentThreadId());
    X();
    UnhookWindowsHookEx(hDllHook);
    //hDllHandle is a global variable, so will be now you window!
    return hDllHandle;
}

この関数はスレッド対応ではありませんが、コードの先頭で1回だけ呼び出す可能性が高いため、問題ではないことに注意してください。

そして注意してください!Win32 API関数でさえ、多くの関数が非表示のウィンドウを作成します。このコードはそれらすべてをフックし、最後に作成されたものを返します。他のものを返すように変更するか、必要に応じてそれらのリストを返すように変更するのは簡単です。

于 2013-01-19T08:42:46.927 に答える
2

Spy ++やWinspectorなどのツールを使用してHWND、アプリによって作成されたすべての、特にクラス名とウィンドウタイトルを確認します。次に、これらの値をコードにコピーしFindWindow()、DLLがウィンドウを作成した後にを1回呼び出すことができます。例:

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    // ...
    X();
    HWND hWnd = FindWindow("ClassNameHere", "TitleHere");
    // ...
    return 0;
}
于 2013-01-19T16:50:32.573 に答える