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

时间:2015-05-18 08:33:43

标签: c++ c user-interface winapi

WM_NEXTDLGCTL状态的文档,此消息将与对话框一起使用:

  

发送到对话框程序,将键盘焦点设置为对话框中的其他控件。

如果此消息不能与非对话框控件父项一起使用,则以通用方式对控件进行子类化非常繁琐(如this question所示),因为窗口过程必须调用{{ 3}}或发送WM_NEXTDLGCTL消息,基于不太重要的确定上下文。

由于其他特定于对话框的API可用于非对话窗口(例如SetFocus),因此在此设置中使用WM_NEXTDLGCTL也很自然。

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

1 个答案:

答案 0 :(得分:11)

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 Chens书中提到过)。有趣的是,根据本书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);
    }
}

所以,如果你不想对你的父窗口代码进行重大更改,那么我恐怕你运气不好。