Witaj na Zine.net online Zaloguj się | Rejestracja | Pomoc

Jak wyświetlić okno aby okno obecnie posiadające focus nie straciło go?

Zadanie (Windows Forms):
Z pierwszego okna otwórz drugie okno, które ma się pojawić nad pierwszym oknem, ale tak, żeby focus pozostał w pierwszym oknie.

Ostatnio spotkałem się właśnie z takim problemem. Chciałem zaprogramować coś a'la ToolTip, który będzie mi się pokazywał nad moim polem tekstowym i w którym będę mógł umieszczać swoje informacje. Okazało się, że sprawa nie jest tak oczywista jak mogłoby się wydawać. Oczywiście zacząłem od ustawienia drugiej formatki jako TopMost, żeby zawsze pojawiała się na wierzchu. Największy problem polegał na zabraniu (albo najlepiej nie daniu) otwieranemu oknu focusa.

Pierwsze znalezisko - ale niestety nie rozwiązuje problemu do końca.
Dowiedziałem się, że implementując formatkę (dziedzicząc po Form) można nadpisać właściwość ShowWithoutActivation.

protected override bool ShowWithoutActivation
{
    get { return true; }
}


Jeżeli to zrobmy i zwrócimy true to okno będzie otwierało się bez focusa. Fajnie, już myślałem, że sprawa załatwiona. Niestety okazuje się, że opcja ta nie działa jeżeli okno ma ustawioną właściwość TopMost na true :(. W komentarzu na MSDN znalazłem, że aby podobny efekt uzyskać z oknem TopMost to należy skorzystać bezpośrednio z API Windowsa.

Druga wersja - tym razem rozwiązująca zadanie.
Po kolejnych kulku minutach na Googlach znalazłem to czego szukałem.

[DllImport("User32.dll")]
public extern static int ShowWindow(System.IntPtr hWnd, short cmdShow);


Wywołanie tej metody z uchwytem do pokazywanego okna i z parametrem cmdShow = 4 (SW_SHOWNOACTIVATE) załatwia sprawę. Okienko ładnie się pokazuje i nie dostaje focusa. Great! :)

W załączniku umieściłem przykładową aplikację, która pokazuje omówione tu techniki. Symuluje ona edycję tekstu w polu tekstowym oraz wyświetlanie okien pomocniczych. Wciskając kombinacje klawiszy CTRL + [Z, X, C] otwierać będą się kolejno: okno z TopMost = true przy użyciu standardowej metody Show, okno z ustawionym TopMost = true, ale za pomocą metody ShowWindow oraz okno z TopMost = false z nadpisaną właściwością ShowWithoutActivation zwracającą true.

Jeżeli jesteście ciekawi to zerknijcie sobie.
Opublikowane 4 października 2007 10:43 przez nuwanda
Attachment(s): WindowWithoutFocus.zip

Powiadamianie o komentarzach

Jeżeli chciałbyś otrzymywać email gdy ta wypowiedź zostanie zaktualizowana, to zarejestruj się tutaj

Subskrybuj komentarze za pomocą RSS

Komentarze:

# re: Jak wyświetlić okno aby okno obecnie posiadające focus nie straciło go?

4 października 2007 12:34 by Wojciech Gebczyk

ciekawy trick :-)

problem ze reczne przywolanie okienka nie odpala wszystkich zdarzen (np: OnActivated)

v

# re: Jak wyświetlić okno aby okno obecnie posiadające focus nie straciło go?

4 października 2007 12:42 by nuwanda

To prawda (niestety). Akurat w tym rozwiązaniu nie potrzebowałem tych zdarzeń, ale w innych przypadkach to może być problematyczne.

Co o tym myślisz?

(wymagane) 
wymagane 
(wymagane) 

  
Wprowadź kod: (wymagane)