Ответ 1
Может ли WM_NEXTDLGCTL использоваться с родителями без диалога?
Я не думаю, что вы можете использовать его в родительских окнах без диалога (по крайней мере, без изменений в родительском окне), причина в том, что он реализован внутри DefDlgProc
. Поэтому ваши другие недиалоговые окна должны были бы вызвать его, чтобы это сообщение работало.
Это цитата, которую я нашел в "Старой новой вещи: практическое развитие на всей эволюции 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 как навигацию внутри вашего диалогового окна (используя код диалога), вы должны придерживаться некоторых правил, вы можете прочитать их внутри: 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, я боюсь, что вам не повезло.