使用组合框和列表框时问题的解决方案

介绍 MSDN的2006年8月期提出了两个关于组合框的好问题。以下是文章在MSDN中的链接。 为了清楚起见,让我重复一下这个问题。 我有一个对话框和一个组合框。如果我按下取消按钮,对话框立即关闭,尽管焦点在组合框上。但是,如果我通过键入字母或打开下拉列表开始自动完成,然后按下Cancel按钮,下拉列表关闭,但对话框不关闭。这对用户来说有些讨厌。在Microsoft®Word中,file open菜单可以关闭下拉列表并取消对话框。如果我打开下拉列表并按取消,文件对话框关闭。我如何使取消立即关闭我的对话框? Tahir Helvaci 我试着按Ctrl+A选择列表框中的所有项目。我怎样才能做到这一点? 马克·福勒 像往常一样,Paul DiLascia在解决这些问题上做得很好。实际上,它促使我思考是否有任何方法可以在不使用钩子的情况下完成同样的任务。请记住,他使用了三个钩子来完成上述任务,即一个WH_GETMESSAGE、一个WH_MOUSE和一个WH_CALLWNDPROC。正如他自己所告诫的那样,钩子编写者必须非常小心,比如非常迅速地在钩子子程中执行任何想要执行的操作,然后离开。 我在这里提供的解决方案没有钩子,而且我还进一步提供了MS Word中没有的一个简单特性。不存在的特性是:当一个组合框的下拉菜单可见时,在非客户端区域上的鼠标左键按下按钮只会拉出组合框的下拉菜单部分,禁用窗口的拖拽功能。如果用户希望拖动对话框,他应该再次在非客户端区域使用鼠标左键。当组合框展开时,如果单击关闭按钮,则窗口不会关闭。在下面的代码片段中,我也解决了这个问题。 组合框有三种样式,一种带有编辑框,另一种没有编辑框,还有一种简单类型总是可以看到下拉菜单。整个逻辑在对话框应用程序的PreTranslateMessage(…)中处理。首先,进行如下所示的检查:复制Code

if(pMsg->message == WM_LBUTTONDOWN ) 
{
   -------------- 
}

因此,如果消息是WM_LBUTTONDOWN,另一个检查,看看是否消息是在组合框内生成完成。如果是这样,只需调用基类PreTranslateMessage(…)并返回。如果不是,那么使用GetFocus(..)获取焦点所在的当前窗口及其父窗口(如果它是没有编辑框的组合框)或其父窗口(如果它是有编辑框的组合框)的句柄。然后,使用ChildWindowFromPoint(…)API,检查如果下下来的消息不是在组合框,如果是下下来是在组合框以外的一个窗口,所以调用基类PreTranslateMessage(…)(这实际上拉下拉组合框的一部分),并使用调用的子窗口有ChildWindowFromPoint(…)API, WM_LBUTTONDOWN消息发布子窗口。这足以让子窗口从这里接管。由于此消息只需要发布一次,因此将使用一个静态变量s来实现此目的。在对话框的PreTranslateMessage(…)中的WM_LBUTTONUP消息中,这个变量被重置为0。 接下来,对于拖放和关闭特性,我覆盖了对话框的OnNcMouseMove(…)消息。 而下拉组合框是可见的,当鼠标消息产生的非客户区对话框中,代码跳到如果PreTranslateMessage (! wndChild)条件(…),所以我就将nHap变量设置为TRUE,其余是OnNcMouseMove处理(…)消息。 注意:由于上面提到的技巧,一个免费的礼物是,对话框也会自动响应最小化,最大化和调整消息大小。 现在来回答第二个问题。令人惊讶的是,答案比预期的更简单。如上所述,我覆盖了PreTranslateMessage(…)。首先,检查是否按下了控制键。如果是,则将标志设置为true。然后,如果按下字符' a ',如果焦点在一个列表框上,如果nFlag被设置,调用SetSel(-1)将选择所有元素。 注意:上面提到的技术只适用于多选择选项启用的列表框。 本文转载于:http://www.diyabc.com/frontweb/news375.html

原文地址:https://www.cnblogs.com/Dincat/p/13443933.html