Может ли WM_NEXTDLGCTL использоваться без диалоговых окон?

В документации для WM_NEXTDLGCTL указано, что это сообщение должно использоваться с диалогами:

Отправлен в процедуру диалогового windows, чтобы настроить фокус клавиатуры на другой элемент управления в диалоговом окне.

Если это сообщение не может использоваться с родителями без диалога, было бы очень утомительно подclassифицировать элементы управления общим способом (как показано в этом вопросе ), поскольку оконная процедура должна была бы вызвать SetFocus или отправить сообщение WM_NEXTDLGCTL основе не совсем тривиально определить контекст.

Поскольку другие диалоговые API-интерфейсы могут использоваться с не-диалоговыми windowsми (например, IsDialogMessage ), было бы естественно использовать WM_NEXTDLGCTL в этой настройке.

Вопрос: Может ли WM_NEXTDLGCTL использоваться с родителями без диалога?

Может ли WM_NEXTDLGCTL использоваться с родителями без диалога?

Я не думаю, что вы можете использовать его в родительских windowsх без диалога (по крайней мере, без изменений в родительском окне), причина в том, что он реализован внутри DefDlgProc . Поэтому ваши другие недиалоговые windows должны были бы вызвать его, чтобы это сообщение работало.

Это цитата, которую я нашел в «Старой новой вещи: практическое развитие на протяжении всей эволюции Windows : что происходит внутри DefDlgProc?

Как замечают комментарии WM_NEXTDLGCTL, функция DefDlgProc обрабатывает сообщение WM_NEXTDLGCTL, обновляя всю внутреннюю учетную запись менеджера диалога, определяя, какая кнопка должна быть по умолчанию, все, что хорошо.

Другой причиной, по которой это сообщение является только диалоговое, является тот факт, что он (цитата из msdn для WM_NEXTDLGCTL):

устанавливает идентификатор элемента управления по умолчанию

для этого он должен отправить DM_SETDEFID, который определяется как:

 #define DM_SETDEFID (WM_USER+1) 

так что это WM_USER, и как таковой он может использоваться для какой-либо другой цели в недиалоговом окне (этот факт также упоминается в книге Раймонда Ченна). Интересно то, что согласно этой книге IsDialogMessage также отправляет DM_SETDEFID / DM_GETDEFID в ваше окно. Поэтому, если вы хотите использовать TAB как навигацию внутри вашего диалогового windows (используя код диалога), вы должны придерживаться некоторых правил, вы можете прочитать их внутри: What happens inside IsDialogMessage? выше книги. Это означает, среди прочего, использование следующего цикла сообщений:

 while (GetMessage(&msg, NULL, 0, 0)) { if (IsDialogMessage(hwnd, &msg)) { /* Already handled by dialog manager */ } else { TranslateMessage(&msg); DispatchMessage(&msg); } } 

поэтому, если вы не хотите делать серьезные изменения в своем родительском коде Windows, я боюсь, что вам не повезло.