MFC:为什么Edit控件收不到WM_DROPFILES消息,OnDropFiles不调用或调用无法响应?

MFC的Edit控件响应拖拽文件的事件,可能无法响应的几种情况:

    1. 可能是系统权限问题。用户界面特权隔离(User Interface Privilege Isolation,UIPI),限制低特权进程向高特权进程发送消息,以此增强系统的安全性。为此,可以添加代码 ChangeWindowMessageFilter(WM_DROPFILES, MSGFLT_ADD); ,使得窗口能够接收原本被 UIPI 阻止的特定消息。
    2. 控件或窗口可能没设置DragAcceptFiles(TRUE); , 也可以在控件或窗口的属性中设置“接受文件”为TRUE。
    3. 存在其他高层级的控件,拦截了消息。这方面还没好的方法去判断。这里给出简单的思路:

由于高层级的控件可能接受拦截了WM_DROPFILES消息,因此,控件的子类化方式去处理接收拖拽文件,是肯定不行了,因为收不到消息通知。因此可以在顶层窗口中处理WM_DROPFILES消息,但要判断是哪个控件收到了拖拽消息。因此,可以使用RealChildWindowFromPoint函数。

注意,不要使用ChildWindowFromPoint!因为有控件叠加的情况下,ChildWindowFromPoint可能获取的还是另外的控件。“RealChildWindowFromPoint 以不同于控件其他区域的方式处理标准控件的 HTTRANSPARENT 区域;它返回控件透明部分后面的子窗口。 相比之下, ChildWindowFromPoint 对待控件的 HTTRANSPARENT 区域与其他区域相同。 例如,如果该点位于组框的透明区域中, 则 RealChildWindowFromPoint 返回组框后面的子窗口,而 ChildWindowFromPoint 返回组框。 但是,这两个 API 都返回静态字段,即使它也返回 HTTRANSPARENT。”

此外,叠加的其他控件,应该设置为“透明”属性,也就是Transparent为TRUE,这样,RealChildWindowFromPoint 才会越过透明控件。

比如,一个GroupBox控件上放一个Edit控件,此时,Edit控件将无法响应WM_DROPFILES消息。我们可以在顶层父窗口加上WM_DROPFILES消息的处理函数,并在OnDropFiles中:

		// 获取拖放目标控件
		CPoint pt;
		DragQueryPoint(hDropInfo, &pt);
		HWND hWnd = ::RealChildWindowFromPoint(m_hWnd, pt);
		DWORD id = hWnd != NULL ? ::GetDlgCtrlID(hWnd) : 0;

由此获得控件id,根据控件id即可判断是否是edit控件,再做后续处理,即可。

 

 

很久没用MFC写代码,现在再写,感觉MFC很不方便。

 

 

 

 

转载请注明来源,谢谢。

有偿解决C++编程问题,承接项目定制开发;寻一份全职或兼职Windows C++开发工作。联系邮箱:[email protected]


老刀的技术日志 » MFC:为什么Edit控件收不到WM_DROPFILES消息,OnDropFiles不调用或调用无法响应?

发表评论