2009-11-16 13 views
7

Przywykłem do myślenia, że ​​WM_CREATE jest pierwszą wiadomością, którą otrzymuje okno. Jednak podczas testowania tego założenia na oknie najwyższego poziomu okazuje się, że jest to fałsz. W moim teście WM_MINMAXINFO pojawiła się jako pierwsza wiadomość.Windows API: Jaka jest pierwsza wiadomość, którą gwarantuje otrzymanie okna?

Jaka jest pierwsza wiadomość, którą gwarantuje otrzymanie okna?

+1

To pytanie nie ma sensu. Jak zauważyłeś, pierwsze wiadomości nie zawsze są takie same. W zależności od tego, czy okno zostanie utworzone, czy nie, cała masa wiadomości może przyjść do WindowPRoc, zanim CreateWindow kiedykolwiek powróci. które wiadomości i ich kolejność zmieniły się między wersjami okien. Gwarantujemy tylko, że WM_CREATE - a teraz WM_NCREATE - zostanie wysłane przed powrotem do CreateWindow (Zakładając pomyślne utworzenie okna). –

+3

Chris, dlaczego komentarz zamiast odpowiedzi? Czy to nie ma sensu? Założę się, że 90% programistów Win32 przysięgnie, że WM_CREATE jest pierwszym odebranym msg (i byłem jednym z nich do 30 sekund temu). W końcu to wszystko czytamy w naszych podręcznikach. –

+0

Zgadzam się, Serge Wautier, Myślałem o tym, dopóki nie zrobiłem małego testu. To jest kolejność wszystkich moich wiadomości WM do WM_CREATE: WM_GETMINMAXINFO, WM_NCCREATE, WM_NCCALCSIZE, WM_CREATE. – Kit10

Odpowiedz

6

Odpowiedziałeś na własne pytanie. Również widzę WM_GETMINMAXINFO, na Windows XP SP3, a następnie WM_NCCREATE, WM_NCCALCSIZE, a na końcu WM_CREATE zanim CreateWindowEx() zwrócił uchwyt do tworzonego okna. Co za garabage "

Ogólna odpowiedź brzmi, że Microsoft nie jest niekompetentny, jeśli chodzi o uporządkowane tworzenie i niszczenie obiektów. Robią to źle z Windows, z COM i ze sterownikami urządzeń. Zawsze jest jakiś haczyk-22, w którym obiekt jest w połowie stworzony lub w połowie zniszczony, który wymaga jakiegoś okrężnego, zawiłego rozwiązania, aby wytworzyć niezawodny produkt.

+0

WM_GETMINMAXINFO to pierwsza wiadomość dla okna najwyższego poziomu. W przypadku innych okien wygląda to na WM_NCCREATE. –

13

WM_NCCREATE to właściwie very first message your window will receive, który pojawi się przed WM_CREATE. Jest to związane z tworzeniem obszaru poza obszarem klienta (np. Pasek tytułu, menu systemowe itp.), Stąd prefiks NC.

WM_GETMINMAXINFO jest wysyłany before the window size/position is changed i może pojawić się przed WM_CREATE (patrz poniżej więcej).

Wiadomość jest wysyłana przed CreateWindow() wiadomością zwrotną, więc można zagwarantować, że inicjalizacja okna została wykonana przez ten punkt. Twój proces okna otrzyma WM_CREATE po utworzeniu okna, ale zanim okno stanie się widoczne (WM_SHOWWINDOW).

W dokumentacji MSDN występuje interesująca niekonsekwencja - komunikaty o tworzeniu wydają się zależeć od tego, czy wywoływana jest nazwa CreateWindow() lub CreateWindowEx(), jednak nie określa ona, że ​​komunikaty muszą być wymienione w kolejności wysyłania.

  • CreateWindow(): WM_CREATE, WM_GETMINMAXINFO i WM_NCCREATE
  • CreateWindowEx(): WM_NCCREATE, WM_NCCALCSIZE i WM_CREATE

I podejrzewam, że kolejność komunikat opisany w CreateWindow() powinien mieć WM_NCCREATE pierwszy, a regularne WM_CREATE ostatni , co jest zgodne z dokumentacją powiadamiania i numerem referencyjnym CreateWindowEx() (a także zgodnie z tym, co opisać).

Raymond Chen ma również kilka interesujących information on window creation/destruction.

Po prostu pokazuje, nawet pozornie proste rzeczy mogą się skomplikować, im więcej na nie patrzysz.

+0

Ciekawe, że WM_NCCREATE zostało wprowadzone w Win95, co wyjaśnia, dlaczego nie zostało udokumentowane w "Programming Windows" Petzolda, kiedy po raz pierwszy przeczytałem go w 1997 roku. –

+2

WM_NCCREATE istnieje od wersji 1.0. Jest wiele rzeczy, których Petzold nigdy nie próbował ukryć. –

+1

Mnóstwo użytecznych informacji tutaj i przykro mi złożyć skargę. Jednak WM_NCCREATE jest pierwszą wiadomością tylko dla okien najwyższego poziomu. –

1

Możesz użyć spy ++, który jest dostarczany z visual studio, aby zobaczyć, jakie komunikaty są generowane podczas uruchamiania aplikacji lub okna.

2

Wyniki eksperymentowania są lepsze niż zaufanie do źródła, zwłaszcza, że ​​źródło jest skomponowane przez legion programistów i żaden nie zna całego kodu.Powiedział:

Najpierw otrzymam wiadomość o adresie 0x24 (WM_GETMINMAXINFO).

Czy mogę założyć, że zawsze będzie to pierwsza wiadomość? Nie, ponieważ kod zmienia się między wersjami Windows, a Microsoft nie udokumentował wiadomości gwarantowanej jako pierwsza otrzymana.

Podsumowanie: Nie zakładaj, że WM_CREATE został wywołany przed inną wiadomością.

+1

Nie, eksperymentowanie nigdy nie jest dobrym pomysłem. Te rzeczy są nieudokumentowane z jakiegoś powodu. Nie ma gwarancji, że 'WM_GETMINMAXINFO' będzie * zawsze * być pierwszą wysłaną wiadomością, bez względu na to, która wersja systemu Windows i konfiguracja komputera użytkownika. Każda aplikacja, która polega na otrzymywaniu wiadomości w takiej kolejności jak ta, jest zasadniczo zepsuta. Dokumentacja mówi, że należy przyjąć, że 'WM_NCCREATE' jest pierwszą odebraną wiadomością. Powinieneś tam wykonać całą swoją inicjalizację: będzie działać za każdym razem, bez względu na system, na którym działa twoja aplikacja. Nie odtwarzaj wstecz systemu Windows. –

Powiązane problemy