2009-05-01 4 views
12

W systemie Windows można ustawić okno A tak, aby zawsze znajdowało się ono nad oknem B, a jednocześnie pozwolić innym oknom na normalne działanie i pojawiać się nad nimi, gdy są aktywne.Czy okno może znajdować się zawsze tylko na jednym innym oknie?

Innymi słowy, chcę relacji rodzic-dziecko między dwoma oknami. Czy można to zrobić bez uczynienia okna A dzieckiem okna B, stylu MDI? Okno B nie jest moje (Internet Explorer) i wkręca moją grafikę dialogową A, gdy próbuję to osiągnąć za pomocą SetParent.

Myślałem, że popękane go z tego pomysłu z MSDN forum post, ale niestety nadal okien A jest zawsze na domiar wszystkiego, nie tylko okno B.

// Place window A on top 
SetWindowPos(hWndWindow, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); 
// Place window B underneath it 
SetWindowPos(hWndParent, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE); 

Czy to możliwe?

+0

Niestety, nie sądzę, że istnieje sposób, aby to zrobić. – Charlie

Odpowiedz

0

Czy można uzyskać dostęp do kolejności Z okien?

nie mogę sobie przypomnieć domyślnej kolejności z okien, ale myślę, że to 1. Możesz być w stanie ustawić IE do -1 i aplikacji na 0.

0

Spróbuj:

// Place window A on top of window B 
SetWindowPos(hWndA, hWndB, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); 

Drugi parametr uchwytu okna określa kolejne okno w kolejności Z.

Uwaga: to nie zmienia relacji okno nadrzędny-podrzędny - ale można go symulować.

+0

To robi to raz (ale potem robi to raz bez tego). Kliknięcie na IE przenosi go przed moje okno :( – Mat

3

Po zmianie kolejności okien (lub rozmiaru lub pozycji) w oknie powinien on otrzymać komunikat WM_WINDOWPOSCHANGING. Jeśli przetwarzasz tę wiadomość, masz możliwość zmodyfikowania ostatecznej kolejności Z (lub rozmiaru lub pozycji), do której przeniesione jest okno.

Dla zilustrowania, w procedurze okna hWndA to:

case WM_WINDOWPOSCHANGING: 
    DefWindowProc(hWnd, msg, wParam, lParam); 
    WINDOWPOS *p = (WINDOWPOS*)lParam; 
    p->hwndInsertAfter = hWndB; 
    p->flags &= ~SWP_NOZORDER; 
    return 0; 

należy wstawić hWndA po hWndB w kolejności z dowolnym czasie zmiany pozycji hWndA'S.

+0

Mat nie jest właścicielem okna nadrzędnego, więc nie może zmienić wartości zmiennej "A", ale może jakiś typ haka rodzica zadziałałby? – Aardvark

+0

Właściwie , mówi, że posiada A i chce sprawić, by wyglądało na dziecko B, które nie jest jego (Internet Explorer) .Myślę, że A otrzyma powiadomienie, że kolejność Z zmienia się, jeśli B zostanie przesunięte z przodu. –

+0

Tak! ! zrobiłeś mi dzień mam co chcę przez obsługę 'ON_WM_WINDOWPOSCHANGING()' 'i wtedy robi void CMyFrame :: OnWindowPosChanging (WINDOWPOS * lpwndpos) { \t __super :: OnWindowPosChanging (lpwndpos) \t CMainFrame * pMainFrame = dynamic_cast (AfxGetMainWnd()); \t if (pMainFrame) \t { \t \t lpwndpos-> hwndInsertAfter = pMainFrame-> GetSafeHwnd(); \t} } ' – sergiol

2

Do Visty jednym ze sposobów było użycie SetWindowsHookEx i podpięcie haka WH_CBT lub WH_CALLWNDPROC, a następnie podjęcie odpowiednich działań po wykryciu zmiany Z. Jednak to nie działa z Vistą (o ile mogę powiedzieć z google).

Jedyne inne rozwiązanie, jakie mogę sobie wyobrazić, to ustawienie czasomierza na uruchamianie co kilka sekund, a kiedy otrzymasz WM_TIMER, przesłuchasz system, używając GetNextWindow, aby dowiedzieć się, które okno znajduje się za twoim. Jeśli to nie jest IE, to zadzwoń pod numer SetWindowPos, aby ustawić swoje okno powyżej IE (zakładam, że masz okno HWND dla wybranego okna IE - pamiętaj, że może istnieć wiele okien IE).

Spowoduje to problemy, jeśli ludzie będą próbować doprowadzić okno do przodu - odwróci się ono do poziomu znajdującego się tuż nad IE. W tym przypadku w swoim kodzie możesz obsłużyć numer WM_ACTIVATE i spróbować zmienić kolejność Z okna IE, tak aby znajdował się pod twoim oknem (wywołaj SetWindowPos, aby przenieść okno IE, aby znalazł się nad oknem, które znajduje się pod twoim oknem). To rozwiązanie może być obarczone problemami, ponieważ system Windows może próbować uniemożliwić korzystanie z okien innego procesu, ze względów bezpieczeństwa. Z drugiej strony, dokumenty MSDN dla SetWindowPos nie są jawnie wspomnieć, że nie można manipulować oknami innego procesu.Mogą jednak istnieć niejasne ograniczenia.

Nawet z tego czasomierza siekać, masz zamiar skutecznie mieć pętlę zajęty-oczekujących w aplikacji (z częstych komunikatów WM_TIMER) i jest to ogólnie złe rzeczą do zrobienia, szczególnie dla żywotności baterii laptopów itp. (ponieważ uniemożliwiasz CPU przejście w stan uśpienia itd.).

Powiedziałbym, że nie ma dobrego sposobu na zrobienie tego, a wszystko, co prawdopodobnie będzie działać, będzie kruche i spowoduje problemy. Gorąco polecam, nie próbując tego robić. Czy można zamiast tego zrobić program w jakiejś wtyczce lub pasku narzędzi dla IE?

NB Bądź szczególnie świadomi, że SetWindowsHookEx nakłada karę wydajności na poziomie całego systemu, jeśli podążać tą drogą.

12

Czy tworzenie relacji własności nie wystarczy?

SetWindowLong(hwndChild, GWL_HWNDPARENT, hwndOwner) 

Okna mogą mieć różne procesy i można je wywołać z dowolnego procesu. Zapewni to, że okno podrzędne będzie zawsze nad oknem właściciela. To różni się od SetParent, który w rzeczywistości tworzy relację Parent/Child. Read through this article (z 1993 r., Ale nadal w większości poprawne), aby zobaczyć rozróżnienie między własnością a rodzicielstwem.

+0

To działa bez zarzutu. – Sebastian

+1

Łącze "Treść usunięta" –

+0

[łącze do archiwum w sieci] (https://web.archive.org/web/20100318062734/http://msdn.microsoft.com/en-us/library/ms997562.aspx) –

1

Odpowiedź Maurice'a jest najlepsza z tego, co tu jest, ale brakuje ważnego kroku. Gdy wywołujesz pokaz w oknie, który ma być nakładką, musisz wywołać metodę show, która ma parametr. Musisz zdefiniować klasę, która implementuje interfejs IWin32Window i po prostu utworzyć nową instancję tego. Jedyną rzeczą, o którą troszczy się interfejs, jest to, że Handle po prostu ustawia to na klamce okna IE i powinno działać całkiem dobrze

0

Jeśli relacja rodzic-dziecko jest tworzona przez ciebie z funkcją SetWindowPos(), twoje pragnienie można wdrożyć.

Powiązane problemy