2009-07-14 14 views
6

, ponieważ nie mogłem znaleźć odpowiedzi na pytanie this zbadałem trochę dalej do MSDN i znalazłem isChild(). To może dać mi odpowiedź na to inne pytanie.uzyskiwanie HWND dla mojej własnej aplikacji w C

Teraz, aby użyć metody isChild(), muszę przekazać HWND aplikacji nadrzędnej, którą chcę sprawdzić, w tym przypadku moją własną aplikację. Jak uzyskać HWND z mojej aplikacji?

Nie znam tytułu, ponieważ stale się zmienia, więc nie mogę użyć FindWindow().

Dzięki

Edit:

Ponieważ nie jest jasne, dodam więcej informacji: ja nie tworząc okno. Nie mam dostępu do tworzenia okna. Mój kod to fragment kodu, który jest kompilowany razem z aplikacją, którą programuje inny programista i nie mam dostępu do tego, jak tworzone jest okno, tytułu lub jakiejkolwiek innej informacji. Jak zatem uzyskać HWND do "OKNA" uruchomionej aplikacji?

Odpowiedz

6

Skorzystaj z funkcji GetTopWindow() i GetNextWindow(), aby poruszać się po kliencie z-order.

Jednak nie sądzę, że jest to konieczne, ale można użyć GetCurrentProcessId() i GetWindowThreadProcessId() może być coś podobnego po pomoże Ci:

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

GetTopWindow() zawsze zwraca 0. To samo z GetActiveWindow() – wonderer

+0

Dzięki za powtórkę, ale GetTopWindow(), jeśli zostanie wywołana z NULL, może zwrócić górne okno innego programu (jak dowiedziałem się na poprzednim pytaniu) i ja jako ja w tym pytaniu i w tym szukam informacji o mojej aplikacji i oknie. – wonderer

+0

Znajdujesz więc najwyższe okno - a następnie iterujesz przez okna w porządku z-Z przy użyciu GetNextWindow i porównujesz każde okno ze swoim. Najpierw dopasowany jest to, czego potrzebujesz. Pomyślałem, że można to zrobić tak ... –

1

Nie możesz po prostu przytrzymać klamki zwróconej z CreateWindow? Jeśli nie, dlaczego nie?

+0

ponieważ nie jestem tworzenie okna. Mój mój to moduł, który jest skompilowany z czyimś kodem. Dlatego nie mam dostępu do tworzenia okna. Teraz, wiedząc o tym, jak mogę uzyskać HWND dla okna aplikacji, w której pracuję? – wonderer

+0

Więc nie masz nawet dostępu do pompy komunikatów okna, którą zakładam? Jedyne, co mogę wymyślić, to EnumWindows, a następnie wywołanie GetWindowLong za pomocą parametru GWL_HINSTANCE i porównanie HINSTANCE zwróconego do zwróconego z GetModuleHandle. – Goz

+0

Warto zauważyć, że odzyskasz KAŻDEGO HWND powiązanego ze swoim HINSTANCE chociaż ... – Goz

0

To jest dla mnie stare, ale IIRC powinieneś otrzymać HWND jako parametr w procedurze okna. Możesz zapisać go w zmiennej globalnej gdzieś na początku.

+1

Właściwie zamiast przechowywać ją jako globalną, można ją przekazać lub wskaźnik do innej struktury jako ostatni parametr the CreateWindowEX. Wskaźnik ten będzie wówczas dostępny w procedurze systemu Windows podczas komunikatu WM_CREATE. –

9

Twoja aplikacja nie ma pliku HWND. Okno ma. Aplikacja może nie mieć okien lub może mieć wiele, więc nie ma ogólnej funkcji "Pobierz HWND aplikacji".

Oczywistym rozwiązaniem jest po prostu przytrzymanie klamki, gdy ją otrzymasz. Podczas tworzenia okna zwracana jest nazwa HWND. Przechowuj to.

+0

OK przepraszam za brak poprawności. – wonderer

0

Co z nazwą klasy systemu Windows? Czy zawsze jest inaczej przy tworzeniu okna? Jeśli nie, nadal możesz znaleźć FindWindow().

1

Jak inni już wspomniano

  • Zasadniczo aplikacja może mieć zero lub wiele okien najwyższego poziomu.
  • Jeśli sam tworzysz okno, możesz po prostu zapamiętać gdzieś HWND.

Ale może twój kod znajduje się w bibliotece DLL, więc nie utworzyłeś sam okna najwyższego poziomu. Więc co robić?

Proponuję następujące:

  • Zastosowanie EnumWindows wyliczyć wszystkich okien najwyższego poziomu.
  • Użyj GetWindowLongPtr, aby uzyskać HINSTANCE dla każdego okna najwyższego poziomu. Porównaj to z HINSTANCE aplikacji, którą można uzyskać za pomocą GetModuleHandle(NULL). Jeśli są identyczne, znalazłeś swoje główne okno.

Edytuj: Oto kod. Okazuje się, że musisz także użyć IsWindowVisible, ponieważ wydaje się, że jest całkiem sporo niewidocznych okien "pomocnika".

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

Następnie w miejscu, gdzie chcemy się znaleźć okno:

hwndMain=NULL; 
EnumWindows(EnumWindowProc, 0); 

I po tym, hwndMain powinno zawierać uchwyt okna lub NULL jeśli żaden nie istnieje.

Korzystanie EnumWindows jest nieco uciążliwe, ale jest zalecany przez wywołanie GetWindow w pętli, ponieważ, jak zauważa MSDN: „Aplikacja nazywa GetWindow Aby wykonać tę zagrożenia zadanie przyłapania w nieskończonej pętli lub przedstawieniu uchwyt do okna, które został zniszczony. "

+0

Dzięki. Wygląda na to, że jest dużo kodu, aby uzyskać coś tak prostego. Czy masz próbkę? – wonderer

1

Prawdopodobnie kod jest wywoływany przez główny kod aplikacji, w przeciwnym razie, jaki jest to użytek? W takim przypadku nie widzę powodu, dla którego API twojego kodu nie może w jakiś sposób informować cię o uchwycie głównego okna aplikacji.

+0

Ponieważ nie ma w dokumencie projektowym. To wszystko. – wonderer

+1

Następnie zmień projekt! –

+0

Moje myśli dokładnie. To wszystko, co konieczne. – kurige

Powiązane problemy