Какие сообщения обрабатываются DefWindowProc? - PullRequest
3 голосов
/ 04 июня 2010

Есть ли документация, какие сообщения обрабатываются DefWindowProc и как?

Недавно я наткнулся на то, что WM_SETFONT / WM_GETFONT не обрабатывается, я не уверен, есть ли ошибка в моем коде, или это ожидаемое поведение, поэтому я попробовал следующий WinMain:


   WNDCLASSEX wcx =
   {
      sizeof(WNDCLASSEX),
      CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS, 
      DefWindowProc,
      0, 0,  // class/wnd extra bytes
      hInstance, 
      0,  
      LoadCursor(0, IDC_ARROW),
      0, 
      0,
      _T("some class"),
      0
   };

   ATOM a = RegisterClassEx(&wcx);
   _ASSERTE(a != 0);

   HWND wnd = CreateWindowEx(0, wcx.lpszClassName, NULL, 
                   WS_POPUP, 0,0,0,0, GetDesktopWindow(), 0, hInstance, 0);
   _ASSERTE(wnd != 0);

   HFONT font = (HFONT) GetStockObject(ANSI_VAR_FONT);
   _ASSERTE(font != 0);

   SendMessage(wnd, WM_SETFONT, (WPARAM) font, 0);
   HFONT font2 = (HFONT) SendMessage(wnd, WM_GETFONT, 0, 0);

   _ASSERTE(font2 == font);  // **FAILS**, font2 is 0

1 Ответ

5 голосов
/ 04 июня 2010

Насколько я знаю - нет. Каждое оконное сообщение - это редкая и уникальная вещь, которая может отличаться во многих отношениях. Ожидается, что некоторые сообщения будут опубликованы, другие отправлены.

Некоторые сообщения являются уведомлениями для окна пользователя proc, другие являются командами для обработчика (ов) DefXXXWindowProc - DefWindowProc, DefDlgProc, DefMDIChildProc и т. Д.

Некоторые обрабатываются одинаково в диалоговых и оконных процессах, некоторые должны обрабатываться по-разному.

WM_SETTEXT и WM_SETREDRAW фактически являются командами, которые DefWindowProc использует для изменения внутренних структур данных в структуре WND.

WM_SIZE - это просто уведомление - отправленное BY DefWindowProc в собственное окно - в ответ на WM_WINDOWPOSCHANGED.

Сообщения WM_MOUSExxx НЕОБХОДИМО публиковать, никогда не отправлять, поскольку окна часто входят в модальные состояния, когда сообщения читаются с помощью GetMessage / PeekMessage и обрабатываются напрямую, а НЕ публикуются.

Многие сообщения выглядят как уведомления, но ДОЛЖНЫ всегда передаваться в DefWindowProc, потому что они "тайно" используются для реализации оконного менеджера. (WM_ACTIVATE и друзья).

Большинство сообщений можно обработать в диалоговом процессе, возвращая FALSE (или ИСТИНА), некоторые с существенными результатами должны использовать SetDlgResult, другие автоматически обрабатываются (WM_CTLCOLOR *), поскольку диалоговое окно proc знает , ненулевой результат от DialogProc соответствует LRESULT для возврата.

Некоторые (WM_SYSCOMMAND) на самом деле вообще не являются сообщениями в окно, а просто обрабатываются DefWindowProc для выполнения задач типа менеджера окон (мозаика рабочего стола и т. Д.)

В официальной документации нет реальной попытки классифицировать эти различия.


Чтобы конкретно решить проблему WM_SET/GETFONT, WM_SETFONT, хотя и определенное сообщение, не обрабатывается DefwindowProc и, следовательно, не обрабатывается классами окна, которые явно его не поддерживают. Элементы управления (EDIT, STATIC и т. Д.) И диалоги поддерживают WM_SETFONT и WM_GETFONT. Для поддержки этого в зарегистрированном классе приложения потребуется предоставить фактический пользовательский WindowProc и обработать сообщение там.

...