WM_NEXTDLGCTL可以与非对话窗口一起使用吗?

Can WM_NEXTDLGCTL be used with non-dialog windows?

本文关键字:一起 窗口 对话 NEXTDLGCTL WM      更新时间:2023-10-16

WM_NEXTDLGCTL的文档说明,此消息将用于对话框:

发送到对话框过程,用于将键盘焦点设置为对话框中的另一个控件。

如果此消息不能与非对话控件父控件一起使用,那么以通用方式子类化控件将是非常繁琐的(如本问题所示),因为窗口过程必须调用SetFocus或发送WM_NEXTDLGCTL消息,以确定上下文。

由于其他特定于对话框的api可以与非对话框窗口一起使用(例如IsDialogMessage),因此能够在此设置中使用WM_NEXTDLGCTL也会感觉很自然。

问题: WM_NEXTDLGCTL可以与非对话框控制父级一起使用吗?

WM_NEXTDLGCTL可以与非对话框控件父级一起使用吗?

我不认为你可以在非对话框父窗口中使用它(至少没有更改父窗口),原因是它是在DefDlgProc内实现的。因此,您的其他非对话框窗口必须调用它才能使此消息工作。

这是我在中发现的引用:旧的新事物:贯穿Windows进化的实际开发: DefDlgProc内部发生了什么?

正如WM_NEXTDLGCTL消息的注释所观察到的,DefDlgProc函数通过更新所有内部对话管理器簿记来处理WM_NEXTDLGCTL消息,决定哪个按钮应该是默认的,所有这些好东西。

它是唯一对话框消息的另一个原因是它(引用自msdn for WM_NEXTDLGCTL):

设置默认的控件标识符

必须发送DM_SETDEFID,定义为:

#define DM_SETDEFID         (WM_USER+1)

所以它是WM_USER,因此它可能在非对话框窗口上用于其他目的(这一事实也在Raymond chen的书中提到)。有趣的是,根据这本书,IsDialogMessage也发送DM_SETDEFID/DM_GETDEFID到您的窗口。因此,如果你想在你的非对话框窗口中使用标签导航(使用对话框代码),你必须遵守一些规则,你可以在上面的书中阅读它们:What happens inside IsDialogMessage?。这意味着使用以下消息循环:

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

所以如果你不想对你的父窗口代码做大的改变,那么恐怕你就不走运了。