非MFC,利用window api OPENFILENAME实现文件夹选择

利用OPENFILENAME 实现的打开文件对话框 只能对文件进行选择,如果选中文件夹 点击按钮的话会自动的进入到文件夹 目录去了。之前提到非MFC,利用window api OPENFILENAME实现定制打开文件对话框 可以通过设置钩子函数来截获打开文件对话框 的消息,响应这些消息实现特定的功能。然而,不管怎么做这个函数就是无法获得鼠标点击打开按钮的事件,我百思不得其解。为了这个问题,花了好几天时间,试了很多种方法,在网上搜了好多文章,最后才从这些文章中看出写星星点点的线索。最终解决了这个问题。


OPENFILENAME 对话框的钩子函数只能获得文件列表框这个子窗体里的消息,见上图,只有获得整个对话框的消息才能实现文件夹 的选择。还好windows提供了各种给力的api。LONG SetWindowLong(HWND hWnd, int nIndex, LONG dwNewLong); 利用这个api把父窗口,也就是整个打开文件对话框 的的消息响应函数hook到,就能获取按钮的点击事件了。

1
2
3
HWND hhwnd = ::GetParent(hWnd);
SetWindowLong(hWnd, DWL_USER, lParam); //保存lParam信息
g_wndProcUp=(WNDPROC)::SetWindowLong(hhwnd,GWL_WNDPROC,( LONG )OFNHookProc);

OFNHookProc是新的整个对话框的消息响应Hook函数。能够截获到鼠标点击打开按钮的事件,从而在当前选中文件夹的情况下,关闭对话框实 现文件夹选择。需要注意一点的是,在OFNHookProc函数结束之前要调用CallWindowProc。具体原因请见下面MSDN中的解释:

“Use the CallWindowProc function for window subclassing. Usually, all windows with the same class share one window procedure. A subclass is a window or set of windows with the same class whose messages are intercepted and processed by another window procedure (or procedures) before being passed to the window procedure of the class.

The SetWindowLong function creates the subclass by changing the window procedure associated with a particular window, causing the system to call the new window procedure instead of the previous one. An application must pass any messages not processed by the new window procedure to the previous window procedure by calling CallWindowProc. This allows the application to create a chain of window procedures.”

原创文章,转载请注明: 转载自 袖子的博客 >> 非MFC,利用window api OPENFILENAME实现文件夹选择
本文链接地址: http://www.ioxiu.com/2011/04/2656.html
订阅袖子的博客: http://www.ioxiu.com/feed

你可能感兴趣的:(非MFC,利用window api OPENFILENAME实现文件夹选择)