получить HWND для моего собственного приложения в C - PullRequest
6 голосов
/ 14 июля 2009

, поскольку я не смог найти ответ на этот вопрос, я немного углубился в MSDN и нашел isChild (). Это может дать мне ответ на этот другой вопрос.

Теперь, чтобы использовать isChild (), мне нужно передать HWND родительского приложения, которое я хочу проверить, в данном случае мое собственное приложение. Как мне получить HWND моего собственного приложения?

Я не знаю заголовок, так как он постоянно меняется, поэтому я не могу использовать FindWindow ().

Спасибо

Edit:

Поскольку неясно, я добавлю больше информации: Я не создаю окно. У меня нет доступа к созданию окна. Мой код - это кусок кода, который компилируется вместе с любым приложением, которое кодирует другой программист, и у меня нет доступа к тому, как создается окно, к заголовку или любой другой информации. Итак, как мне получить HWND для «ОКНА» приложения, которое я запускаю?

Ответы [ 8 ]

9 голосов
/ 14 июля 2009

Ваше приложение не имеет HWND. Окно делает. В приложении может не быть окон или их может быть много, поэтому нет общей функции «Получить HWND приложения».

Очевидное решение - просто держать ручку, когда вы ее получаете. Когда вы создаете окно, HWND возвращается. Сохраните это.

6 голосов
/ 14 июля 2009

Используйте GetTopWindow () и GetNextWindow () для обхода z-порядка окон.

Однако, не думайте, что это необходимо, но вы можете использовать GetCurrentProcessId () и GetWindowThreadProcessId (), может быть что-то вроде следующего поможет вам:

HWND FindMyTopMostWindow()
{
    DWORD dwProcID = GetCurrentProcessId();
    HWND hWnd = GetTopWindow(GetDesktopWindow());
    while(hWnd)
    {
        DWORD dwWndProcID = 0;
        GetWindowThreadProcessId(hWnd, &dwWndProcID);
        if(dwWndProcID == dwProcID)
            return hWnd;            
        hWnd = GetNextWindow(hWnd, GW_HWNDNEXT);
    }
    return NULL;
 }
1 голос
/ 31 июля 2009

Вы можете внедрить DLL в поток, который обращается к user32.dll http://msdn.microsoft.com/en-us/library/ms821625.aspx

1 голос
/ 14 июля 2009

Предположительно, ваш код вызывается основным кодом приложения, в противном случае, что это за использование? В этом случае я не понимаю, почему API вашего кода не может каким-либо образом информировать вас о дескрипторе главного окна приложения.

1 голос
/ 14 июля 2009

Как уже отмечали другие

  • В общем случае приложение может иметь ноль или несколько окон верхнего уровня.
  • Если вы создаете окно самостоятельно, вы можете просто вспомнить HWND где-нибудь.

Но, возможно, ваш код находится в DLL, поэтому вы на самом деле не создавали окно верхнего уровня самостоятельно. Так что же делать?

Я бы предложил следующее:

  • Используйте EnumWindows для перечисления всех окон верхнего уровня.
  • Используйте GetWindowLongPtr, чтобы получить HINSTANCE для каждого окна верхнего уровня. Сравните это с HINSTANCE приложения, которое вы можете получить, используя GetModuleHandle(NULL). Если они идентичны, вы нашли свое главное окно.

Редактировать: вот код. Оказывается, вы также должны использовать IsWindowVisible, потому что кажется, что существует довольно много невидимых «вспомогательных» окон.

HWND hwndMain;

BOOL CALLBACK EnumWindowProc(HWND hwnd, LPARAM lParam)
{
    HINSTANCE hinst=(HINSTANCE)GetModuleHandle(NULL);

    if((HINSTANCE)GetWindowLongPtr(hwnd, GWL_HINSTANCE)==hinst &&
        IsWindowVisible(hwnd))
    {
        hwndMain=hwnd;
        return FALSE;
    }
    else
        return TRUE;
}

Тогда в том месте, где вы хотите найти окно:

hwndMain=NULL;
EnumWindows(EnumWindowProc, 0);

И после этого hwndMain должен содержать дескриптор окна, или NULL, если ничего не существует.

Использование EnumWindows немного обременительно, но рекомендуется при вызове GetWindow в цикле, потому что, как отмечает MSDN: «Приложение, вызывающее GetWindow для выполнения этой задачи, рискует оказаться в бесконечном цикле или сослаться на дескриптор окно, которое было разрушено. "

1 голос
/ 14 июля 2009

Разве вы не можете просто удерживать дескриптор, возвращенный из CreateWindow? Если нет, то почему нет?

0 голосов
/ 14 июля 2009

А как насчет вашего имени класса Windows? Всегда ли это отличается при создании окна? Если нет, вы все равно можете найти FindWindow ().

0 голосов
/ 14 июля 2009

Это старо для меня, но IIRC вы должны получить HWND в качестве параметра в процедуре окна. Вы можете сохранить его в глобальной переменной где-то в начале.

...