Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
W tym omówieniu omówiono funkcje okien, takie jak typy okien, stany, rozmiar i położenie.
- Typy okien
- Relacje między oknami
- Okno Pokaż stan
- Rozmiar i położenie okna
- Animacja okna
- Układ i dublowanie okien
- Niszczenie okien
Typy okien
Ta sekcja zawiera następujące tematy, które opisują typy okien.
Nakładające się okna
Nakładające się okno to okno najwyższego poziomu (okno inne niż podrzędne), które ma pasek tytułu, obramowanie i obszar klienta; ma służyć jako główne okno aplikacji. Może również mieć menu okna, przyciski minimalizacji i maksymalizacji oraz paski przewijania. Nakładające się okno używane jako główne okno zwykle zawiera wszystkie te składniki.
Określając styl WS_OVERLAPPED lub WS_OVERLAPPEDWINDOW w funkcji CreateWindowEx , aplikacja tworzy nakładające się okno. Jeśli używasz stylu WS_OVERLAPPED , okno ma pasek tytułu i obramowanie. Jeśli używasz stylu WS_OVERLAPPEDWINDOW, okno ma pasek tytułu, obramowanie zmieniające rozmiar, menu okna i przyciski minimalizacji i maksymalizacji.
Wyskakujące okienka
Okno podręczne jest specjalnym typem nakładanego okna używanego w oknach dialogowych, oknach komunikatów i innych oknach tymczasowych, które pojawiają się poza głównym oknem aplikacji. Paski tytułu są opcjonalne dla okien podręcznych; w przeciwnym razie okna podręczne są takie same jak nakładające się okna WS_OVERLAPPED stylu.
Okno podręczne można utworzyć, określając styl WS_POPUP w funkcji CreateWindowEx. Aby dołączyć pasek tytułu, określ styl WS_CAPTION . Użyj stylu WS_POPUPWINDOW aby utworzyć okno podręczne z obramowaniem i menu okna. Styl WS_CAPTION musi być połączony ze stylem WS_POPUPWINDOW , aby menu okna było widoczne.
Okna potomne
Okno podrzędne ma styl WS_CHILD i jest ograniczone do obszaru klienta okna nadrzędnego. Aplikacja zazwyczaj używa okien podrzędnych do dzielenia obszaru roboczego okna nadrzędnego na obszary funkcjonalne. Okno podrzędne można utworzyć, określając styl WS_CHILD w funkcji CreateWindowEx .
Okno podrzędne musi mieć okno nadrzędne. Okno nadrzędne może być nakładanym oknem, oknem podręcznym, a nawet innym oknem podrzędnym. Podczas wywoływania polecenia CreateWindowEx należy określić okno nadrzędne. Jeśli określisz styl WS_CHILD w oknie CreateWindowEx , ale nie określisz okna nadrzędnego, system nie utworzy okna.
Okno podrzędne ma obszar klienta, ale nie ma żadnych innych funkcji, chyba że są jawnie żądane. Aplikacja może zażądać paska tytułu, menu okna, zminimalizować i zmaksymalizować przyciski, obramowanie i paski przewijania dla okna podrzędnego, ale okno podrzędne nie może mieć menu. Jeśli aplikacja określa uchwyt menu, gdy rejestruje klasę okna podrzędnego lub tworzy okno podrzędne, uchwyt menu jest ignorowany. Jeśli nie określono żadnego stylu obramowania, system tworzy okno bez obramowania. Aplikacja może używać okien podrzędnych bez granic, aby podzielić obszar klienta okna nadrzędnego, zachowując jednocześnie niewidoczne dla użytkownika podziały.
W tej sekcji omówiono następujące aspekty dziecięcych okien:
Pozycjonowanie
System zawsze umieszcza okno podrzędne względem lewego górnego rogu obszaru roboczego okna nadrzędnego. Żadna część okna podrzędnego nigdy nie pojawia się poza granicami okna nadrzędnego. Jeśli aplikacja tworzy okno podrzędne większe niż okno nadrzędne lub umieszcza okno podrzędne tak, aby niektóre lub wszystkie okno podrzędne wykraczały poza granice okna nadrzędnego, system przycina okno podrzędne; oznacza to, że część poza obszarem klienta okna nadrzędnego nie jest wyświetlana. Akcje wpływające na okno nadrzędne mogą również mieć wpływ na okno podrzędne w następujący sposób.
| Okno nadrzędne | Okno podrzędne |
|---|---|
| Zniszczone | Zniszczone zanim okno nadrzędne zostanie zniszczone. |
| Ukryty | Ukrywane przed ukryciem okna nadrzędnego. Okno podrzędne jest widoczne tylko wtedy, gdy okno nadrzędne jest widoczne. |
| Przeniesiony | Przemieszczono razem z obszarem klienta okna nadrzędnego. Okno podrzędne jest odpowiedzialne za malowanie obszaru klienta po przeniesieniu. |
| Pokazano | Wyświetlane po wyświetleniu okna nadrzędnego. |
Przycinanie
System nie przycina automatycznie okna podrzędnego z obszaru klienta okna nadrzędnego. Oznacza to, że okno nadrzędne rysuje nad oknem podrzędnym, jeśli rysuje w tym samym miejscu, co okno podrzędne. System wycina okno podrzędne z obszaru klienta okna nadrzędnego, jeśli okno nadrzędne ma styl WS_CLIPCHILDREN. Jeśli okno podrzędne zostanie obcięte, okno nadrzędne nie może narysować go.
Okno podrzędne może nakładać się na inne okna podrzędne w tym samym obszarze klienta. Okno podrzędne, które dzieli okno nadrzędne z jednym lub więcej innymi oknami podrzędnymi, jest nazywane oknem równorzędnym. Okna równorzędne mogą rysować się w obszarze klienta, chyba że jedno z okien podrzędnych ma styl WS_CLIPSIBLINGS . Jeśli okno podrzędne ma ten styl, każda część równorzędnego okna, która znajduje się w oknie podrzędnym, zostanie przycięta.
Jeśli okno ma styl WS_CLIPCHILDREN lub WS_CLIPSIBLINGS , występuje niewielka utrata wydajności. Każde okno zajmuje zasoby systemowe, dlatego aplikacja nie powinna używać okien podrzędnych bezkrytycznie. Aby uzyskać najlepszą wydajność, aplikacja, która musi logicznie podzielić swoje główne okno, powinna to zrobić w procedurze okna głównego, a nie przy użyciu okien podrzędnych.
Relacja z oknem nadrzędnym
Aplikacja może zmienić okno nadrzędne istniejącego okna podrzędnego, wywołując funkcję SetParent . W takim przypadku system usuwa okno podrzędne z obszaru klienta starego okna nadrzędnego i przenosi je do obszaru klienta nowego okna nadrzędnego. Jeśli funkcja SetParent określa uchwyt jako NULL, to okno pulpitu staje się nowym oknem nadrzędnym. W takim przypadku okno podrzędne jest rysowane na pulpicie, poza granicami dowolnego innego okna. Funkcja GetParent pobiera uchwyt do okna nadrzędnego dla okna podrzędnego.
Okno nadrzędne rezygnuje z części obszaru klienta na rzecz okna podrzędnego, a okno podrzędne odbiera wszystkie sygnały wejściowe z tego obszaru. Klasa okna nie musi być taka sama dla każdego z okien podrzędnych względem okna nadrzędnego. Oznacza to, że aplikacja może wypełniać okno nadrzędne oknami podrzędnymi, które różnią się wyglądem i wykonują różne zadania. Na przykład okno dialogowe może zawierać wiele typów kontrolek, z których każde jest oknem podrzędnym, które akceptuje różne typy danych od użytkownika.
Okno podrzędne ma tylko jedno okno nadrzędne, ale okno nadrzędne może mieć dowolną liczbę okien podrzędnych. Każde okno podrzędne z kolei może mieć okna podrzędne. W tym łańcuchu okien każde okno podrzędne jest nazywane potomkiem pierwotnego okna nadrzędnego. Aplikacja używa funkcji IsChild , aby sprawdzić, czy dane okno jest oknem podrzędnym, czy oknem potomnym danego okna nadrzędnego.
Funkcja EnumChildWindows wylicza okna podrzędne okna nadrzędnego. Następnie EnumChildWindows przekazuje dojście do każdego okna podrzędnego do funkcji wywołania zwrotnego zdefiniowanej przez aplikację. Wyliczone są również okna podrzędne danego okna nadrzędnego.
Messages
System przekazuje komunikaty wejściowe okna podrzędnego bezpośrednio do okna podrzędnego; komunikaty nie są przekazywane przez okno nadrzędne. Jedynym wyjątkiem jest to, że okno podrzędne zostało wyłączone przez funkcję EnableWindow . W takim przypadku system przekazuje wszystkie komunikaty wejściowe, które zamiast tego trafiłyby do okna podrzędnego do okna nadrzędnego. Dzięki temu okno nadrzędne pozwala na sprawdzenie komunikatów wejściowych i włączanie okna podrzędnego w razie potrzeby.
Okno podrzędne może mieć unikalny identyfikator całkowity. Identyfikatory okien podrzędnych są ważne podczas pracy z oknami sterowania. Aplikacja kieruje działaniem kontrolki, wysyłając do niej komunikaty. Aplikacja używa identyfikatora okna podrzędnego elementu sterującego do kierowania wiadomości do elementu sterującego. Ponadto kontrolka wysyła komunikaty powiadomień do okna nadrzędnego. Wiadomość powiadomienia zawiera identyfikator podrzędnego okna kontrolki, którego używa element nadrzędny do określenia, która kontrolka wysłała komunikat. Aplikacja określa identyfikator okna podrzędnego dla innych typów okien podrzędnych, ustawiając parametr hMenu funkcji CreateWindowEx na wartość, a nie uchwyt menu.
Okna warstwowe
Użycie okna warstwowego może znacznie poprawić wydajność i efekty wizualne dla okna, które ma złożony kształt, animuje jego kształt lub chce używać efektów mieszania alfa. System automatycznie komponuje i przemaluje warstwowe okna i okna bazowych aplikacji. W rezultacie okna warstwowe są renderowane płynnie, bez migotania typowego dla złożonych regionów okien. Ponadto okna warstwowe mogą być częściowo przezroczyste, czyli alfa-blended.
Aby utworzyć okno warstwowe, określ styl okna rozszerzonego WS_EX_LAYERED podczas wywoływania funkcji CreateWindowEx lub wywołaj funkcję SetWindowLong , aby ustawić WS_EX_LAYERED po utworzeniu okna. Po wywołaniu createWindowEx okno warstwowe nie będzie widoczne, dopóki nie zostanie wywołana funkcja SetLayeredWindowAttributes lub UpdateLayeredWindow .
Uwaga / Notatka
Począwszy od systemu Windows 8, WS_EX_LAYERED można używać z oknami podrzędnymi i oknami najwyższego poziomu. Poprzednie wersje systemu Windows obsługują WS_EX_LAYERED tylko w przypadku okien najwyższego poziomu.
Aby ustawić poziom nieprzezroczystości lub klucz koloru transparentności dla danego okna warstwowego, wywołaj SetLayeredWindowAttributes. Po wywołaniu system może nadal prosić o malowanie okna po wyświetleniu lub zmianie rozmiaru okna. Jednak ze względu na to, że system przechowuje obraz okna warstwowego, system nie będzie zlecać oknu rysowania, jeśli części okna zostają ujawnione w wyniku relatywnych ruchów okna na pulpicie. Starsze aplikacje nie muszą restrukturyzować kodu malowania, jeśli chcą dodać efekty przezroczystości lub przejrzystości dla okna, ponieważ system przekierowuje malowanie okien, które wywołały SetLayeredWindowAttributes, do pamięci poza ekranem i rekonstruuje je w celu osiągnięcia pożądanego efektu.
Aby szybciej i wydajniej przeprowadzić animację lub jeśli wymagana jest alfa na piksel, wywołaj metodę UpdateLayeredWindow. UpdateLayeredWindow należy używać głównie wtedy, gdy aplikacja musi bezpośrednio podać kształt i zawartość okna warstwowego bez korzystania z mechanizmu przekierowania, który system udostępnia za pośrednictwem elementu SetLayeredWindowAttributes. Ponadto użycie elementu UpdateLayeredWindow bezpośrednio korzysta z pamięci wydajniej, ponieważ system nie potrzebuje dodatkowej pamięci wymaganej do przechowywania obrazu przekierowanego okna. Aby uzyskać maksymalną wydajność w animowaniu okien, wywołaj metodę UpdateLayeredWindow , aby zmienić położenie i rozmiar okna warstwowego. Pamiętaj, że po wywołaniu SetLayeredWindowAttributes, kolejne wywołania UpdateLayeredWindow zakończą się niepowodzeniem, dopóki bit stylu warstwy nie zostanie ponownie wyczyszczony i ustawiony.
Testowanie trafień okna warstwowego opiera się na kształcie i przezroczystości okna. Oznacza to, że obszary okna, które są oznaczone kolorami kluczowymi lub których wartość alfa wynosi zero, pozwolą na przejście wiadomości dot. myszy. Jeśli jednak okno warstwowe ma WS_EX_TRANSPARENT rozszerzony styl okna, kształt okna warstwowego zostanie zignorowany, a zdarzenia myszy zostaną przekazane do innych okien poniżej okna warstwowego.
Okna tylko do wiadomości
Okno tylko do wiadomości umożliwia wysyłanie i odbieranie komunikatów. Nie jest widoczny, nie ma kolejności wyświetlania, nie można enumerować i nie odbiera komunikatów rozgłaszania. Okno po prostu wysyła komunikaty.
Aby utworzyć okno tylko do komunikatów, określ stałą HWND_MESSAGE w parametrze hWndParent funkcji CreateWindowEx. Istniejące okno można również zmienić na okno tylko dla komunikatów, określając HWND_MESSAGE w parametrze hWndNewParent funkcji SetParent .
Aby znaleźć okna tylko dla komunikatów, określ HWND_MESSAGE w parametrze hwndParent funkcji FindWindowEx . Ponadto funkcja FindWindowEx wyszukuje okna tylko dla komunikatów, a także okna najwyższego poziomu, jeśli parametry hwndParent i hwndChildAfter mają wartość NULL.
Relacje okien
Istnieje wiele sposobów, na które okno może odnosić się do użytkownika lub innego okna. Okno może być oknem należącym do użytkownika, oknem pierwszego planu lub oknem tła. Okno ma również kolejność względem innych okien. Aby uzyskać więcej informacji, zobacz następujące tematy:
Okna pierwszego planu i tła
Każdy proces może mieć wiele wątków wykonywania, a każdy wątek może tworzyć okna. Wątek, który utworzył okno, z którym użytkownik aktualnie pracuje, jest nazywany wątkiem pierwszego planu, a okno jest nazywane oknem pierwszego planu. Wszystkie inne wątki są wątkami tła, a okna utworzone przez wątki w tle są nazywane oknami tła.
Każdy wątek ma poziom priorytetu, który określa ilość czasu CPU otrzymywanego przez wątek. Mimo że aplikacja może ustawić poziom priorytetu wątków, zwykle wątek pierwszego planu ma nieco wyższy poziom priorytetu niż wątki w tle. Ponieważ ma wyższy priorytet, wątek pierwszego planu otrzymuje więcej czasu procesora NIŻ wątki w tle. Wątek pierwszego planu ma normalny priorytet podstawowy 9; wątek w tle ma normalny priorytet podstawowy 7.
Użytkownik ustawia okno pierwszego planu, klikając okno lub używając kombinacji klawiszy ALT+TAB lub ALT+ESC. Aby pobrać uchwyt do okna pierwszego planu, użyj funkcji GetForegroundWindow. Aby sprawdzić, czy okno aplikacji jest oknem pierwszego planu, porównaj dojście zwrócone przez polecenie GetForegroundWindow do okna aplikacji.
Aplikacja ustawia okno pierwszego planu przy użyciu funkcji SetForegroundWindow .
System ogranicza, które procesy mogą ustawić okno pierwszego planu. Proces może ustawić okno pierwszego planu tylko wtedy, gdy:
- Wszystkie następujące warunki są spełnione:
- Proces wywołujący SetForegroundWindow należy do aplikacji desktopowej, a nie aplikacji UWP ani aplikacji ze Sklepu Windows przeznaczonej dla systemu Windows 8 lub 8.1.
- Proces pierwszego planu nie zablokował wywołań funkcji SetForegroundWindow przez wcześniejsze wywołanie funkcji LockSetForegroundWindow.
- Upłynął limit czasu blokady pierwszego planu (zobacz SPI_GETFOREGROUNDLOCKTIMEOUT w temacie SystemParametersInfo).
- Żadne menu nie są aktywne.
- Ponadto co najmniej jeden z następujących warunków jest spełniony:
- Proces wywoływania jest procesem pierwszego planu.
- Proces inicjujący został uruchomiony przez proces pierwszoplanowy.
- Obecnie nie ma okna na pierwszym planie, a zatem nie ma procesu działającego na pierwszym planie.
- Proces wywołujący odebrał ostatnie zdarzenie wejściowe.
- Proces działający na pierwszym planie lub proces wywołujący jest debugowany.
Możliwe jest odmówienie procesowi możliwości ustawienia okna pierwszego planu, nawet jeśli spełnia te warunki.
Proces, który może ustawić okno pierwszego planu, może umożliwić inny proces ustawiania okna pierwszego planu przez wywołanie funkcji AllowSetForegroundWindow lub wywołanie funkcji BroadcastSystemMessage z flagą BSF_ALLOWSFW . Proces pierwszego planu może wyłączyć wywołania funkcji SetForegroundWindow poprzez wywołanie funkcji LockSetForegroundWindow.
Należące do systemu Windows
Nakładające się lub wyskakujące okno może być własnością innego nakładanego lub wyskakującego okna. Posiadanie narzuca kilka ograniczeń na okno.
- Okno będące własnością jest zawsze powyżej właściciela w kolejności z.
- System automatycznie niszczy okno własności, gdy jego właściciel zostanie zniszczony.
- Okno należące do użytkownika jest ukryte, gdy jego właściciel jest zminimalizowany.
Tylko nakładające się lub wyskakujące okno może być oknem właściciela; okno podrzędne nie może być oknem właściciela. Aplikacja tworzy okno podrzędne, określając uchwyt okna właściciela jako parametr hwndParent w funkcji CreateWindowEx podczas tworzenia okna ze stylem WS_OVERLAPPED lub WS_POPUP. Parametr hwndParent musi zidentyfikować nakładające się okno lub wyskakujące okienko. Jeśli hwndParent identyfikuje okno podrzędne, system przypisuje własność do okna nadrzędnego najwyższego poziomu okna podrzędnego. Po utworzeniu okna należącego do użytkownika aplikacja nie może przenieść własności okna do innego okna.
Okna dialogowe i okna komunikatów są domyślnie oknami podrzędnymi. Aplikacja określa okno właściciela podczas wywoływania funkcji, która tworzy okno dialogowe lub okno komunikatu.
Aplikacja może użyć funkcji GetWindow z flagą GW_OWNER, aby uzyskać uchwyt właściciela okna.
Z-Order
Z-order okna wskazuje jego położenie w stosie nakładających się okien. Ten stos okien jest zorientowany na oś wyimaginowaną, oś z, rozciągającą się na zewnątrz z ekranu. Okno w górnej części kolejności z nakłada się na wszystkie inne okna. Okno w dolnej części z-rzędu jest zasłonięte przez wszystkie inne okna.
System utrzymuje z-order na jednej liście. Dodaje okna do kolejności z-etapowej na podstawie tego, czy są to okna najwyższego poziomu, okna nadrzędne, czy okna podrzędne. Okno najwyższego poziomu nakłada się na wszystkie inne okna nienajwyższego poziomu, niezależnie od tego, czy jest to okno aktywne, czy okno pierwszoplanowe. Najbardziej górne okno ma styl WS_EX_TOPMOST . Wszystkie okna najwyższego poziomu są wyświetlane w z-order zanim dowolnymi oknami nienależącymi do najwyższego poziomu. Okno podrzędne jest grupowane z oknem nadrzędnym w porządku z.
Gdy aplikacja tworzy okno, system umieszcza je na szczycie kolejności Z dla okien tego samego typu. Możesz użyć funkcji BringWindowToTop, aby przenieść okno na górę kolejności Z dla okien tego samego typu. Możesz zmienić kolejność z (z-order) za pomocą funkcji SetWindowPos i DeferWindowPos.
Użytkownik zmienia kolejność okien, aktywując inne okno. System umieszcza aktywne okno w górnej części kolejności z dla okien tego samego typu. Gdy okno pojawia się na szczycie kolejności wyświetlania, jego okna podrzędne również są tam przesuwane. Za pomocą funkcji GetTopWindow można przeszukiwać wszystkie okna podrzędne danego okna nadrzędnego i zwracać uchwyt do okna podrzędnego, które jest najwyżej w kolejności Z. Funkcja GetNextWindow pobiera uchwyt do następnego lub poprzedniego okna w kolejności Z.
Okno Pokaż stan
W dowolnym momencie okno może być aktywne lub nieaktywne; ukryte lub widoczne; i zminimalizowane, zmaksymalizowane lub przywrócone. Te cechy są określane zbiorczo jako stan wyświetlania okna. W poniższych tematach omówiono stan wyświetlania okna:
- Aktywne okno
- Wyłączony system Windows
- Widoczność okna
- Zminimalizowane, zmaksymalizowane i przywrócone okna
Aktywne okno
Aktywne okno to okno najwyższego poziomu aplikacji, z którym użytkownik aktualnie pracuje. Aby umożliwić użytkownikowi łatwe zidentyfikowanie aktywnego okna, system umieszcza go w górnej części kolejności z i zmienia kolor paska tytułu i obramowania na zdefiniowane przez system kolory aktywnych okien. Tylko okno najwyższego poziomu może być aktywnym oknem. Gdy użytkownik pracuje z oknem podrzędnym, system aktywuje okno nadrzędne najwyższego poziomu skojarzone z oknem podrzędnym.
Tylko jedno okno najwyższego poziomu w systemie jest aktywne w danym momencie. Użytkownik aktywuje okno najwyższego poziomu, klikając go (lub jedno z jego okien podrzędnych) lub używając kombinacji klawiszy ALT+ESC lub ALT+TAB. Aplikacja aktywuje okno najwyższego poziomu, wywołując funkcję SetActiveWindow . Inne funkcje mogą spowodować, że system aktywuje inne okno najwyższego poziomu, w tym SetWindowPos, DeferWindowPos, SetWindowPlacement i DestroyWindow. Mimo że aplikacja może aktywować inne okno najwyższego poziomu w dowolnym momencie, aby uniknąć mylenia użytkownika, powinna to zrobić tylko w odpowiedzi na działanie użytkownika. Aplikacja używa funkcji GetActiveWindow, aby pobrać uchwyt do aktywnego okna.
Gdy aktywacja zmieni się z okna najwyższego poziomu jednej aplikacji do okna najwyższego poziomu innego, system wysyła komunikat WM_ACTIVATEAPP do obu aplikacji, powiadamiając ich o zmianie. Kiedy aktywacja zmienia się na inne okno najwyższego poziomu w tej samej aplikacji, system wysyła komunikat WM_ACTIVATE do obu okien.
Wyłączony system Windows
Okno można wyłączyć. Wyłączone okno nie odbiera od użytkownika żadnych danych wejściowych klawiatury ani myszy, ale może odbierać komunikaty z innych okien, z innych aplikacji i z systemu. Aplikacja zazwyczaj wyłącza okno, aby uniemożliwić użytkownikowi korzystanie z okna. Na przykład aplikacja może wyłączyć przycisk wypychania w oknie dialogowym, aby uniemożliwić użytkownikowi wybranie go. Aplikacja może w dowolnym momencie włączyć wyłączone okno; włączenie okna przywraca normalne dane wejściowe.
Domyślnie okno jest włączone podczas tworzenia. Aplikacja może jednak określić styl WS_DISABLED , aby wyłączyć nowe okno. Aplikacja włącza lub wyłącza istniejące okno przy użyciu funkcji EnableWindow . System wysyła komunikat WM_ENABLE do okna, gdy jego stan włączony zostanie zmieniony. Aplikacja może określić, czy okno jest włączone przy użyciu funkcji IsWindowEnabled .
Gdy okno podrzędne jest wyłączone, system przekazuje komunikaty wejściowe myszy do okna nadrzędnego. Element nadrzędny używa komunikatów, aby określić, czy włączyć okno podrzędne. Aby uzyskać więcej informacji, zobacz Wprowadzanie myszy.
Tylko jedno okno jednocześnie może odbierać dane wejściowe klawiatury; mówi się, że okno ma fokus klawiatury. Jeśli aplikacja używa funkcji EnableWindow do wyłączenia okna z focusem klawiatury, okno traci fokus klawiatury oraz staje się wyłączone. WłączWindow następnie ustawia fokus klawiatury na wartość NULL, co oznacza, że żadne okno nie ma fokusu. Jeśli okno podrzędne lub inne okno elementów potomnych ma fokus klawiatury, okno elementu potomnego traci fokus, gdy okno nadrzędne jest wyłączone. Aby uzyskać więcej informacji, zobacz Wprowadzanie klawiatury.
Widoczność okna
Okno może być widoczne lub ukryte. System wyświetla widoczne okno na ekranie. Ukrywa ukryte okno , nie rysując go. Jeśli okno jest widoczne, użytkownik może podać dane wejściowe do okna i wyświetlić dane wyjściowe okna. Jeśli okno jest ukryte, jest skutecznie wyłączone. Ukryte okno może przetwarzać komunikaty z systemu lub z innych okien, ale nie może przetwarzać danych wejściowych od użytkownika ani wyświetlać danych wyjściowych. Aplikacja ustawia stan widoczności okna podczas tworzenia okna. Później aplikacja może zmienić stan widoczności.
Okno jest widoczne po ustawieniu stylu WS_VISIBLE dla okna. Domyślnie funkcja CreateWindowEx tworzy ukryte okno, chyba że aplikacja określa styl WS_VISIBLE . Zazwyczaj aplikacja ustawia styl WS_VISIBLE po utworzeniu okna, aby zachować szczegóły procesu tworzenia ukryte przed użytkownikiem. Na przykład aplikacja może zachować nowe okno ukryte podczas dostosowywania wyglądu okna. Jeśli styl WS_VISIBLE jest określony w oknie CreateWindowEx, system wysyła komunikat WM_SHOWWINDOW do okna po utworzeniu okna, ale przed jego wyświetleniem.
Aplikacja może określić, czy okno jest widoczne przy użyciu funkcji IsWindowVisible . Aplikacja może wyświetlać (uwidocznić) lub ukryć okno przy użyciu funkcji ShowWindow, SetWindowPos, DeferWindowPos lub SetWindowPlacement lub SetWindowLong . Te funkcje pokazują lub ukrywają okno, ustawiając lub usuwając styl WS_VISIBLE okna. Wysyłają również wiadomość WM_SHOWWINDOW do okna przed wyświetleniem lub ukryciem go.
Gdy okno właściciela zostanie zminimalizowane, system automatycznie ukrywa skojarzone okna należące do użytkownika. Podobnie, gdy okno właściciela zostanie przywrócone, system automatycznie wyświetla powiązane okna zależne. W obu przypadkach system wysyła komunikat WM_SHOWWINDOW do okna należącego do użytkownika przed ich ukryciem lub wyświetleniem. Czasami aplikacja może wymagać ukrycia posiadanych okien bez konieczności minimalizowania lub ukrywania właściciela. W tym przypadku aplikacja używa funkcji ShowOwnedPopups . Ta funkcja ustawia lub usuwa styl WS_VISIBLE dla wszystkich okien należących do użytkownika i wysyła komunikat WM_SHOWWINDOW do okna należącego do użytkownika przed ich ukryciem lub wyświetleniem. Ukrywanie okna właściciela nie ma wpływu na stan widoczności okien należących do użytkownika.
Kiedy okno nadrzędne jest widoczne, również jego powiązane okna podrzędne są widoczne. Podobnie, gdy okno nadrzędne jest ukryte, jego okna podrzędne również są ukryte. Minimalizacja okna nadrzędnego nie ma wpływu na stan widoczności okien podrzędnych; oznacza to, że okna podrzędne są zminimalizowane wraz z elementem nadrzędnym, ale styl WS_VISIBLE nie jest zmieniany.
Nawet jeśli okno ma styl WS_VISIBLE , użytkownik może nie być w stanie wyświetlić okna na ekranie; inne okna mogą się całkowicie nakładać lub mogły zostać przeniesione poza krawędź ekranu. Ponadto widoczne okno podrzędne podlega regułom wycinania ustalonym na mocy relacji nadrzędno-podrzędnej. Jeśli okno nadrzędne nie jest widoczne, również nie będzie widoczne. Jeśli okno nadrzędne wychodzi poza krawędź ekranu, okno podrzędne również się przesuwa, ponieważ jest pozycjonowane względem lewego górnego rogu okna nadrzędnego. Na przykład użytkownik może przenieść okno nadrzędne zawierające okno podrzędne tak daleko poza krawędź ekranu, że nie będzie mógł dostrzec okna podrzędnego, mimo że okno podrzędne i jego okno nadrzędne mają styl WS_VISIBLE.
Zminimalizowane, zmaksymalizowane i przywrócone okna
Zmaksymalizowane okno to okno, które ma styl WS_MAXIMIZE. Domyślnie system powiększa zmaksymalizowane okno, tak aby wypełniało ekran lub, w przypadku okna podrzędnego, obszar klienta okna nadrzędnego. Chociaż rozmiar okna można ustawić na taki sam rozmiar zmaksymalizowanego okna, zmaksymalizowane okno jest nieco inne. System automatycznie przenosi pasek tytułu okna do górnej części ekranu lub do górnej części obszaru klienta okna nadrzędnego. Ponadto system wyłącza obramowanie do zmiany rozmiaru okna i możliwość zmiany położenia okna za pomocą paska tytułu (dzięki czemu użytkownik nie może przenieść okna, przeciągając pasek tytułu).
Zminimalizowane okno to okno, które ma styl WS_MINIMIZE. Domyślnie system zmniejsza zminimalizowane okno do rozmiaru przycisku paska zadań i przenosi zminimalizowane okno na pasek zadań. Przywrócone okno to okno, które zostało zwrócone do poprzedniego rozmiaru i położenia, czyli rozmiaru, który był wcześniej zminimalizowany lub zmaksymalizowany.
Jeśli aplikacja określa styl WS_MAXIMIZE lub WS_MINIMIZE w funkcji CreateWindowEx , okno jest początkowo zmaksymalizowane lub zminimalizowane. Po utworzeniu okna aplikacja może użyć funkcji CloseWindow , aby zminimalizować okno. Funkcja ArrangeIconicWindows rozmieszcza ikony na pulpicie lub rozmieszcza zminimalizowane okna podrzędne okna nadrzędnego w oknie nadrzędnym. Funkcja OpenIcon przywraca zminimalizowane okno do poprzedniego rozmiaru i położenia.
Funkcja ShowWindow może zminimalizować, zmaksymalizować lub przywrócić okno. Może również ustawić stan widoczności i aktywacji okna. Funkcja SetWindowPlacement zawiera takie same funkcje jak ShowWindow, ale może zastąpić domyślne zminimalizowane, zmaksymalizowane i przywrócone pozycje okna.
Funkcje IsZoomed i IsIconic określają, czy dane okno jest odpowiednio zmaksymalizowane, czy zminimalizowane. Funkcja GetWindowPlacement pobiera zminimalizowane, zmaksymalizowane i przywrócone pozycje dla okna, a także określa stan wyświetlania okna.
Gdy system otrzymuje polecenie w celu zmaksymalizowania lub przywrócenia zminimalizowanego okna, wysyła w oknie komunikat WM_QUERYOPEN . Jeśli procedura okna zwraca wartość FALSE, system ignoruje polecenie maksymalizowania lub przywracania.
System automatycznie ustawia rozmiar i położenie zmaksymalizowanego okna na wartości domyślne zdefiniowane przez system dla zmaksymalizowanego okna. Aby zastąpić te wartości domyślne, aplikacja może wywołać funkcję SetWindowPlacement lub przetworzyć komunikat WM_GETMINMAXINFO odbierany przez okno, gdy system ma zmaksymalizować okno. WM_GETMINMAXINFO zawiera wskaźnik do struktury MINMAXINFO zawierającej wartości używane przez system do ustawiania zmaksymalizowanego rozmiaru i położenia. Zastąpienie tych wartości zastępuje wartości domyślne.
Rozmiar i położenie okna
Rozmiar i położenie okna są wyrażane jako prostokąt obwiedni, podawany we współrzędnych względem ekranu lub okna nadrzędnego. Współrzędne okna najwyższego poziomu są względem lewego górnego rogu ekranu; współrzędne okna podrzędnego są względem lewego górnego rogu okna nadrzędnego. Aplikacja określa początkowy rozmiar i położenie okna podczas tworzenia okna, ale może zmienić rozmiar i położenie okna w dowolnym momencie. Aby uzyskać więcej informacji, zobacz Wypełnione kształty.
Ta sekcja zawiera następujące tematy:
- Domyślny rozmiar i położenie
- Rozmiar śledzenia
- Polecenia systemowe
- Funkcje rozmiaru i położenia
- Komunikaty o rozmiarze i położeniu
Domyślny rozmiar i położenie
Aplikacja może zezwolić systemowi na obliczenie początkowego rozmiaru lub położenia okna najwyższego poziomu, określając CW_USEDEFAULT w obszarze CreateWindowEx. Jeśli aplikacja ustawia współrzędne okna na CW_USEDEFAULT i nie utworzyła żadnych innych okien najwyższego poziomu, system ustawia położenie nowego okna względem lewego górnego rogu ekranu; W przeciwnym razie ustawia położenie względem pozycji okna najwyższego poziomu, które aplikacja utworzyła ostatnio. Jeśli parametry szerokości i wysokości są ustawione na CW_USEDEFAULT, system oblicza rozmiar nowego okna. Jeśli aplikacja utworzyła inne okna najwyższego poziomu, system opiera rozmiar nowego okna na rozmiarze ostatnio utworzonego okna najwyższego poziomu aplikacji. Określenie CW_USEDEFAULT podczas tworzenia okna podrzędnego lub wyskakującego powoduje, że system ustawi rozmiar okna na domyślny minimalny rozmiar okna.
Rozmiar śledzenia
System utrzymuje minimalny i maksymalny rozmiar śledzenia dla okna w stylu WS_THICKFRAME; okno z tym stylem ma ramkę zmiany rozmiaru. Minimalny rozmiar śledzenia to najmniejszy rozmiar okna, jaki można utworzyć, przesuwając ramkę rozmiaru okna. Podobnie maksymalny rozmiar okna to największy rozmiar okna, jaki można osiągnąć, przeciągając krawędź okna.
Minimalne i maksymalne rozmiary śledzenia okna są ustawiane na wartości domyślne zdefiniowane przez system podczas tworzenia okna. Aplikacja może odnaleźć wartości domyślne i zastąpić je, przetwarzając komunikat WM_GETMINMAXINFO . Aby uzyskać więcej informacji, zobacz Size and Position Messages (Komunikaty dotyczące rozmiaru i położenia).
Polecenia systemowe
Aplikacja z menu okna może zmienić rozmiar i położenie tego okna, wysyłając polecenia systemowe. Polecenia systemowe są generowane, gdy użytkownik wybiera polecenia z menu okna. Aplikacja może emulować akcję użytkownika, wysyłając komunikat WM_SYSCOMMAND do okna. Następujące polecenia systemowe wpływają na rozmiar i położenie okna.
| Command | Opis |
|---|---|
| SC_CLOSE | Zamyka okno. To polecenie wysyła komunikat WM_CLOSE do okna. Okno wykonuje wszelkie kroki niezbędne do oczyszczenia i zniszczenia. |
| SC_MAXIMIZE | Maksymalizuje okno. |
| SC_MINIMIZE | Minimalizuje okno. |
| SC_MOVE | Przenosi okno. |
| SC_RESTORE | Przywraca zminimalizowane lub zmaksymalizowane okno do poprzedniego rozmiaru i położenia. |
| SC_SIZE | Uruchamia polecenie dotyczące rozmiaru. Aby zmienić rozmiar okna, użyj myszy lub klawiatury. |
Funkcje rozmiaru i położenia
Po utworzeniu okna aplikacja może ustawić rozmiar lub położenie okna, wywołując jedną z kilku różnych funkcji, w tym SetWindowPlacement, MoveWindow, SetWindowPos i DeferWindowPos. SetWindowPlacement ustawia zminimalizowaną pozycję okna, zmaksymalizowaną pozycję, przywrócony rozmiar i położenie oraz stan wyświetlania. Funkcje MoveWindow i SetWindowPos są podobne; oba ustawienia rozmiaru lub położenia pojedynczego okna aplikacji. Funkcja SetWindowPos zawiera zestaw flag, które wpływają na stan wyświetlania okna; Funkcja MoveWindow nie zawiera tych flag. Użyj funkcji BeginDeferWindowPos, DeferWindowPos i EndDeferWindowPos , aby jednocześnie ustawić położenie wielu okien, w tym rozmiar, położenie, pozycję w kolejności z i pokaż stan.
Aplikacja może pobrać współrzędne prostokąta ograniczenia okna przy użyciu funkcji GetWindowRect . GetWindowRect wypełnia strukturę RECT współrzędnymi lewego i dolnego rogu okna. Współrzędne są względne względem lewego górnego rogu ekranu, nawet w przypadku okna podrzędnego. Funkcja ScreenToClient lub MapWindowPoints mapuje współrzędne ekranu prostokąta obramowania okna podrzędnego na współrzędne względem obszaru klienta okna nadrzędnego.
Funkcja GetClientRect pobiera współrzędne obszaru klienta okna. GetClientRect wypełnia strukturę RECT współrzędnymi lewego górnego i prawego dolnego rogu obszaru klienta, ale współrzędne są względem samego obszaru klienta. Oznacza to, że współrzędne lewego górnego rogu obszaru klienta są zawsze (0,0), a współrzędne prawego dolnego rogu to szerokość i wysokość obszaru klienta.
Funkcja CascadeWindows układa okna na pulpicie w sposób kaskadowy lub układa okna podrzędne określonego okna nadrzędnego w układzie kaskadowym. Funkcja TileWindows kafelkuje okna na pulpicie lub okna podrzędne określonego okna nadrzędnego.
Komunikaty dotyczące rozmiaru i położenia
System wysyła komunikat WM_GETMINMAXINFO do okna, którego rozmiar lub pozycja ma ulec zmianie. Na przykład komunikat jest wysyłany, gdy użytkownik kliknie pozycję Przenieś lub Zmień rozmiar w menu okna lub kliknie obręb lub pasek tytułu; komunikat jest również wysyłany, gdy aplikacja wywołuje funkcję SetWindowPos w celu przeniesienia lub zmiany rozmiaru okna. WM_GETMINMAXINFO zawiera wskaźnik do struktury MINMAXINFO zawierającej domyślny maksymalny rozmiar i położenie okna, a także domyślne minimalne i maksymalne rozmiary śledzenia. Aplikacja może nadpisać wartości domyślne, przetwarzając WM_GETMINMAXINFO i ustawiając odpowiednich członków struktury MINMAXINFO. Aby otrzymywać WM_GETMINMAXINFO, okno musi mieć styl WS_THICKFRAME lub WS_CAPTION. Okno ze stylem WS_THICKFRAME odbiera ten komunikat podczas procesu tworzenia okna, a także podczas przenoszenia lub rozmiaru.
System wysyła komunikat WM_WINDOWPOSCHANGING do okna, którego rozmiar, położenie, pozycja w kolejności Z lub stan wyświetlania ma ulec zmianie. Ten komunikat zawiera wskaźnik do struktury WINDOWPOS, która określa nowy rozmiar okna, położenie, położenie w kolejności Z oraz stan widoczności. Ustawiając członków WINDOWPOS, aplikacja może wpłynąć na nowy rozmiar, położenie i wygląd okna.
Po zmianie rozmiaru, położenia okna, położenia na osi Z lub stanu wyświetlania, system wysyła komunikat WM_WINDOWPOSCHANGED do okna. Ten komunikat zawiera wskaźnik do WINDOWPOS, który informuje okno o jego nowym rozmiarze, pozycji, pozycji w z-porządku oraz trybie wyświetlania. Ustawienie członków struktury WINDOWPOS, która jest przekazywana z WM_WINDOWPOSCHANGED, nie ma wpływu na okno. Okno, które musi przetwarzać komunikaty WM_SIZE i WM_MOVE , musi przekazać WM_WINDOWPOSCHANGED do funkcji DefWindowProc ; w przeciwnym razie system nie wysyła WM_SIZE i WM_MOVE komunikatów do okna.
System wysyła komunikat WM_NCCALCSIZE do okna po utworzeniu lub rozmiarze okna. System używa danego komunikatu do obliczenia rozmiaru obszaru klienta okna oraz położenia tego obszaru względem lewego górnego rogu okna. Okno zazwyczaj przekazuje ten komunikat do domyślnej procedury okna; jednak ten komunikat może być przydatny w aplikacjach, które dostosowują obszar niekliencki okna lub zachowują części obszaru klienta, gdy zmienia się rozmiar okna. Aby uzyskać więcej informacji, zobacz Malowanie i Rysowanie.
Animacja okna
Efekty specjalne można tworzyć podczas wyświetlania lub ukrywania okien przy użyciu funkcji AnimowanieWindow . Gdy okno jest animowane w ten sposób, system będzie zwijać, przesuwać lub zanikać okno, w zależności od flag podanych w wywołaniu AnimateWindow.
Domyślnie system używa animacji rzutowania. Dzięki temu efektowi okno wydaje się rozwijać (pokazując okno) lub zwijać (gdy okno jest ukrywane). Możesz użyć parametru dwFlags, aby określić, czy okno porusza się poziomo, pionowo lub po przekątnej.
Po określeniu flagi AW_SLIDE system używa animacji slajdów. Dzięki temu efektowi okno wydaje się przesuwać na ekran (ukazując okno) lub przesuwać się poza ekran (ukrywając okno). Możesz użyć parametru dwFlags , aby określić, czy okno przesuwa się w poziomie, w pionie lub po przekątnej.
Po określeniu flagi AW_BLEND, system używa zanikania z użyciem alfa.
Możesz również użyć flagi AW_CENTER, aby okno zwijało się do wewnątrz lub rozwijało na zewnątrz.
Układ i odbicie okien
Układ okna definiuje sposób, w jaki obiekty tekstowe i obiekty interfejsu urządzenia graficznego systemu Windows (GDI) są rozmieszczone w kontekście okna lub urządzenia (DC). Niektóre języki, takie jak angielski, francuski i niemiecki, wymagają układu od lewej do prawej (LTR). Inne języki, takie jak arabski i hebrajski, wymagają układu od prawej do lewej (RTL). Układ okna ma zastosowanie do tekstu, ale także wpływa na inne elementy GDI okna, w tym obrazy bitmapowe, ikony, położenie punktu początkowego, przyciski, rozsuwane kontrolki drzewa i to, czy współrzędna pozioma zwiększa się, gdy przesuwasz się w prawo. Na przykład po ustawieniu układu RTL przez aplikację źródło jest umieszczone na prawej krawędzi okna lub urządzenia, a liczba reprezentująca współrzędną poziomą zwiększa się w miarę przechodzenia w lewo. Jednak nie wszystkie obiekty mają wpływ na układ okna. Na przykład układ okien dialogowych, pól komunikatów i kontekstów urządzeń, które nie są skojarzone z oknem, takich jak metaplik i konteksty urządzenia drukarki, musi być obsługiwany oddzielnie. Szczegółowe informacje o tych zagadnieniach zostały wymienione w dalszej części tego tematu.
Funkcje okna umożliwiają określenie lub zmianę układu okna w arabskich i hebrajskich wersjach systemu Windows. Należy pamiętać, że zmiana na układ RTL (znany również jako dublowanie) nie jest obsługiwana w przypadku okien, które mają styl CS_OWNDC lub kontrolera domeny z trybem graficznym GM_ADVANCED.
Domyślnie układ okna jest od lewej do prawej (LTR). Aby ustawić układ okna RTL, wywołaj metodę CreateWindowEx ze stylem WS_EX_LAYOUTRTL. Domyślnie okno podrzędne (czyli utworzone przy użyciu stylu WS_CHILD i z prawidłowym parametrem hWnd jako rodzicem w wywołaniu funkcji CreateWindow lub CreateWindowEx) ma taki sam układ jak jego rodzic. Aby wyłączyć dziedziczenie dublowania we wszystkich oknach podrzędnych, określ WS_EX_NOINHERITLAYOUT w wywołaniu metody CreateWindowEx. Należy pamiętać, że dublowanie nie jest dziedziczone przez okna należące do użytkownika (utworzone bez stylu WS_CHILD ) lub utworzone z nadrzędnym parametrem hWnd w funkcji CreateWindowEx ustawionym na wartość NULL. Aby wyłączyć dziedziczenie odbijania dla pojedynczego okna, przetwórz komunikat WM_NCCREATE za pomocą GetWindowLong i SetWindowLong, aby wyłączyć flagę WS_EX_LAYOUTRTL. To przetwarzanie jest dodatkiem do jakiegokolwiek innego wymaganego przetwarzania. Poniższy fragment kodu pokazuje, jak to zrobić.
SetWindowLong (hWnd,
GWL_EXSTYLE,
GetWindowLong(hWnd,GWL_EXSTYLE) & ~WS_EX_LAYOUTRTL))
Domyślny układ można ustawić na wartość RTL, wywołując funkcję SetProcessDefaultLayout(LAYOUT_RTL). Wszystkie okna utworzone po wywołaniu zostaną zdublowane, ale nie ma to wpływu na istniejące okna. Aby wyłączyć domyślne dublowanie, wywołaj metodę SetProcessDefaultLayout(0).
Uwaga, SetProcessDefaultLayout odzwierciedla konteksty urządzeń tylko dla lustrzanych okien. Aby zdublować dowolny kontroler domeny, wywołaj metodę SetLayout(hdc, LAYOUT_RTL). Aby uzyskać więcej informacji, zobacz dyskusję na temat odwzorowania kontekstów urządzeń, które nie są skojarzone z oknami, przedstawioną w dalszej części tego tematu.
Bitmapy i ikony w lustrzanych oknach są domyślnie również lustrzane. Jednak nie wszystkie z nich powinny być odwzorowane. Na przykład elementy z tekstem, logo firmowym lub zegarem analogowym nie powinny być odzwierciedlane. Aby wyłączyć odbijanie map bitowych, wywołaj metodę SetLayout z ustawionym bitem LAYOUT_BITMAPORIENTATIONPRESERVED w dwLayout. Aby wyłączyć dublowanie w kontrolerze domeny, wywołaj metodę SetLayout(hdc, 0).
Aby wysłać zapytanie do bieżącego układu domyślnego, wywołaj metodę GetProcessDefaultLayout. Po pomyślnym powrocie pdwDefaultLayout zawiera LAYOUT_RTL lub 0. Aby wysłać zapytanie dotyczące ustawień układu kontekstu urządzenia, wywołaj metodę GetLayout. Po pomyślnym zakończeniu funkcja GetLayout zwraca DWORD, który wskazuje ustawienia układu zgodnie z ustawieniami bitów LAYOUT_RTL i LAYOUT_BITMAPORIENTATIONPRESERVED.
Po utworzeniu okna zmieniasz układ przy użyciu funkcji SetWindowLong . Na przykład jest to konieczne, gdy użytkownik zmieni język interfejsu użytkownika istniejącego okna z arabskiego lub hebrajskiego na niemiecki. Jednak podczas zmiany układu istniejącego okna należy unieważnić i zaktualizować okno, aby upewnić się, że zawartość okna jest rysowana w tym samym układzie. Poniższy przykład kodu pochodzi z przykładowego kodu, który zmienia układ okna zgodnie z potrzebami:
// Using ANSI versions of GetWindowLong and SetWindowLong because Unicode
// is not needed for these calls
lExStyles = GetWindowLongA(hWnd, GWL_EXSTYLE);
// Check whether new layout is opposite the current layout
if (!!(pLState -> IsRTLLayout) != !!(lExStyles & WS_EX_LAYOUTRTL))
{
// the following lines will update the window layout
lExStyles ^= WS_EX_LAYOUTRTL; // toggle layout
SetWindowLongA(hWnd, GWL_EXSTYLE, lExStyles);
InvalidateRect(hWnd, NULL, TRUE); // to update layout in the client area
}
W lustrzanym odbiciu warto myśleć w kategoriach "blisko" i "daleko" zamiast "lewej" i "prawej". Niepodejmowanie tych działań może powodować problemy. Jedną z typowych praktyk kodowania, która powoduje problemy w zwierciadlanych oknach, pojawia się podczas mapowania między współrzędnymi ekranu i współrzędnymi klienta. Na przykład aplikacje często używają kodu podobnego do poniższego, aby umieścić kontrolkę w oknie:
// DO NOT USE THIS IF APPLICATION MIRRORS THE WINDOW
// get coordinates of the window in screen coordinates
GetWindowRect(hControl, (LPRECT) &rControlRect);
// map screen coordinates to client coordinates in dialog
ScreenToClient(hDialog, (LPPOINT) &rControlRect.left);
ScreenToClient(hDialog, (LPPOINT) &rControlRect.right);
Powoduje to problemy z odbiciem lustrzanym, ponieważ lewa krawędź prostokąta staje się prawą krawędzią w lustrzanym odbiciu okna i odwrotnie. Aby uniknąć tego problemu, zastąp wywołania ScreenToClient wywołaniem mapWindowPoints w następujący sposób:
// USE THIS FOR MIRRORING
GetWindowRect(hControl, (LPRECT) &rControlRect);
MapWindowPoints(NULL, hDialog, (LPPOINT) &rControlRect, 2)
Ten kod działa, ponieważ na platformach, które obsługują odbijanie, MapWindowPoints jest modyfikowane w celu zamiany współrzędnych lewego i prawego punktu, gdy okno klienta jest odbijane. Aby uzyskać więcej informacji, zobacz sekcję 'Uwagi' w dokumentacji MapWindowPoints.
Inną typową praktyką, która może powodować problemy w lustrzanych oknach, jest pozycjonowanie obiektów w oknie klienta przy użyciu offsetów współrzędnych ekranu zamiast współrzędnych klienta. Na przykład poniższy kod używa różnicy współrzędnych ekranu jako pozycji x we współrzędnych klienta, aby umieścić kontrolkę w oknie dialogowym.
// OK if LTR layout and mapping mode of client is MM_TEXT,
// but WRONG for a mirrored dialog
RECT rdDialog;
RECT rcControl;
HWND hControl = GetDlgItem(hDlg, IDD_CONTROL);
GetWindowRect(hDlg, &rcDialog); // gets rect in screen coordinates
GetWindowRect(hControl, &rcControl);
MoveWindow(hControl,
rcControl.left - rcDialog.left, // uses x position in client coords
rcControl.top - rcDialog.top,
nWidth,
nHeight,
FALSE);
Ten kod jest w porządku, gdy okno dialogowe ma układ od lewej do prawej (LTR), a tryb mapowania klienta jest MM_TEXT, ponieważ nowa pozycja x we współrzędnych klienta odpowiada różnicy w lewych krawędziach kontrolki i okna dialogowego we współrzędnych ekranu. Jednak w oknie dialogowym odbitym lustrzanie, lewo i prawo są odwrócone, więc zamiast tego należy użyć MapWindowPoints w następujący sposób:
RECT rcDialog;
RECT rcControl;
HWND hControl - GetDlgItem(hDlg, IDD_CONTROL);
GetWindowRect(hControl, &rcControl);
// MapWindowPoints works correctly in both mirrored and non-mirrored windows.
MapWindowPoints(NULL, hDlg, (LPPOINT) &rcControl, 2);
// Now rcControl is in client coordinates.
MoveWindow(hControl, rcControl.left, rcControl.top, nWidth, nHeight, FALSE)
Dublowanie okien dialogowych i okien komunikatów
Okna dialogowe i pola komunikatów nie dziedziczą układu, dlatego należy jawnie ustawić układ. Aby zdublować okno komunikatu, wywołaj metodę MessageBox lub MessageBoxEx z opcją MB_RTLREADING . Aby układać okno dialogowe od prawej do lewej, użyj rozszerzonego stylu WS_EX_LAYOUTRTL w strukturze szablonu okna dialogowego DLGTEMPLATEEX. Arkusze właściwości są specjalnym przypadkiem okien dialogowych. Każda karta jest traktowana jako osobne okno dialogowe, dlatego należy uwzględnić styl WS_EX_LAYOUTRTL na każdej karcie, która ma zostać zdublowana.
Dublowanie kontekstów urządzeń, które nie są skojarzone z oknem
Kontrolery domeny, które nie są skojarzone z oknem, takim jak metaplik lub kontrolery domeny drukarki, nie dziedziczą układu, dlatego należy jawnie ustawić układ. Aby zmienić układ kontekstu urządzenia, użyj funkcji SetLayout .
Funkcja SetLayout jest rzadko używana w oknach. Zazwyczaj okna otrzymują skojarzony kontekst urządzenia tylko podczas przetwarzania komunikatu WM_PAINT. Czasami program tworzy kontroler domeny dla okna, wywołując polecenie GetDC. Tak czy siak, początkowy układ DC jest ustawiany przez BeginPaint lub GetDC zgodnie z flagą okna WS_EX_LAYOUTRTL.
Wartości zwracane przez polecenia GetWindowOrgEx, GetWindowExtEx, GetViewportOrgEx i GetViewportExtEx nie mają wpływu na wywołanie metody SetLayout.
Gdy układ ma wartość RTL, funkcja GetMapMode zwróci MM_ANISOTROPIC zamiast MM_TEXT. Wywoływanie metody SetMapMode za pomocą MM_TEXT będzie działać poprawnie; Dotyczy to tylko zwracanej wartości z polecenia GetMapMode . Podobnie wywołanie metody SetLayout(hdc, LAYOUT_RTL), gdy tryb mapowania jest MM_TEXT powoduje zmianę zgłaszanego trybu mapowania na MM_ANISOTROPIC.
Niszczenie okien
Ogólnie rzecz biorąc, aplikacja musi zniszczyć wszystkie utworzone okna. Robi to za pomocą funkcji DestroyWindow . Gdy okno zostanie zniszczone, system ukrywa okno, jeśli jest widoczne, a następnie usuwa wszelkie dane wewnętrzne skojarzone z oknem. Spowoduje to unieważnienie uchwytu okna, który nie może być już używany przez aplikację.
Aplikacja niszczy wiele okien tworzonych wkrótce po ich utworzeniu. Na przykład aplikacja zwykle niszczy okno dialogowe, gdy tylko aplikacja ma wystarczające dane wejściowe od użytkownika, aby kontynuować swoje zadanie. Aplikacja ostatecznie niszczy główne okno aplikacji (przed zakończeniem).
Przed zniszczeniem okna aplikacja powinna zapisać lub usunąć wszystkie dane skojarzone z oknem i zwolnić wszystkie zasoby systemowe przydzielone do okna. Jeśli aplikacja nie zwolni zasobów, system zwolni wszystkie zasoby, które nie zostaną zwolnione przez aplikację.
Zniszczenie okna nie ma wpływu na klasę okna, z której zostanie utworzone okno. Nowe okna można nadal tworzyć przy użyciu tej klasy, a wszystkie istniejące okna tej klasy nadal działają. Zniszczenie okna niszczy również jego okna podrzędne. Funkcja DestroyWindow wysyła najpierw komunikat WM_DESTROY do okna, a następnie do jego podrzędnych okien i okien potomnych. W ten sposób wszystkie okna potomne niszczonego okna są również usuwane.
Okno z menu okna odbiera komunikat WM_CLOSE, gdy użytkownik kliknie Zamknij. Przetwarzając ten komunikat, aplikacja może monitować użytkownika o potwierdzenie przed zniszczeniem okna. Jeśli użytkownik potwierdzi, że okno powinno zostać zniszczone, aplikacja może wywołać funkcję DestroyWindow , aby zniszczyć okno.
Jeśli zniszczone okno jest aktywnym oknem, zarówno aktywne, jak i stany fokusu są przenoszone do innego okna. Okno, które staje się aktywnym oknem, jest następnym oknem określonym przez kombinację klawiszy ALT+ESC. Nowe aktywne okno określa, które okno odbiera fokus klawiatury.