可以将WM_NEXTDLGCTL用于非对话窗口吗? [英] Can WM_NEXTDLGCTL be used with non-dialog windows?

查看:171
本文介绍了可以将WM_NEXTDLGCTL用于非对话窗口吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

WM_NEXTDLGCTL 的文档说明要使用此邮件与对话框:


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


如果这个消息不能用于非对话控制父对象,那么以通用方式子类化控件是非常乏味的(如这个问题),因为窗口过程将必须调用 SetFocus 或发送 WM_NEXTDLGCTL 消息,基于不太容易确定上下文。 >

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



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

解决方案

可以将WM_NEXTDLGCTL用于非对话控制父项吗?



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



这是我在中找到的报价旧的新事物:实用在Windows的进化过程中的发展: DefDlgProc中发生了什么?


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


另一个为什么是dialog only消息的原因是它(从WM_NEXTDLGCTL的msdn引用):


默认控制标识符


,它必须发送DM_SETDEFID,定义如下:

  #define DM_SETDEFID(WM_USER + 1)

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

  while(GetMessage(& msg,NULL,0,0)){ 
if(IsDialogMessage(hwnd,& msg)){
/ *已经由对话管理器处理* /
} else {
TranslateMessage(& msg);
DispatchMessage(& msg);
}
}

所以如果你不想对你的父窗口代码,那么我恐怕你失去了运气。


The documentation for WM_NEXTDLGCTL states, that this message is to be used with dialogs:

Sent to a dialog box procedure to set the keyboard focus to a different control in the dialog box.

If this message cannot be used with non-dialog control parents, it would be very tedious to subclass controls in a generic way (as illustrated in this question), since the window procedure would have to call either SetFocus or send a WM_NEXTDLGCTL message, based on not quite trivial to determine context.

Since other dialog-specific APIs can be used with non-dialog windows (e.g. IsDialogMessage), it would feel natural to be able to use WM_NEXTDLGCTL in this setup as well.

Question: Can WM_NEXTDLGCTL be used with non-dialog control parents?

解决方案

Can WM_NEXTDLGCTL be used with non-dialog control parents?

I dont think you can use it in non dialog parent windows (at least with no changes to parent window), the cause is that it is implemented inside DefDlgProc. So your other non-dialog windows would have to call it to make this message work.

This is the quote I have found in The Old New Thing: Practical Development Throughout the Evolution of Windows: What happens inside DefDlgProc?

As the remarks for the WM_NEXTDLGCTL message observe, the DefDlgProc function handles the WM_NEXTDLGCTL message by updating all the internal dialog manager bookkeeping, deciding which button should be the default, all that good stuff.

Another reason why it is dialog only message is the fact that it (quote from msdn for WM_NEXTDLGCTL):

sets the default control identifier

to do it it must send DM_SETDEFID, which is defined as:

#define DM_SETDEFID         (WM_USER+1)

so it is WM_USER, and as such it might be used for some other purpose on non dialog window (this fact is also mentioned in Raymond Chens book). The interesting thing is that according to this book IsDialogMessage also sends DM_SETDEFID/DM_GETDEFID to your window. So if you want to use TAB like navigation inside you non dialog window (using dialog code), you must adhere to some rules, you can read on them inside: What happens inside IsDialogMessage? of above book. This means among others to use following message loop:

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

so if you dont want to do major changes to your parent windows code, then I am afraid you are out of luck.

这篇关于可以将WM_NEXTDLGCTL用于非对话窗口吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆