某些环境下(如WIN PE)windows自带的选择文件夹api不能使用或者体验不佳。现在利用GetOpenFileName的回掉参数实现了选择文件夹选择功能。

#include <Windows.h>
#include <CommCtrl.h>
#include <locale.h>
#include <shlwapi.h>
LONG g_lOriWndProc = NULL;
#define ID_COMBO_ADDR 0x47c
#define ID_LEFT_TOOBAR 0x4A0
LRESULT static __stdcall _WndProc ( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
switch(uMsg)
{
case WM_COMMAND:
{
if( wParam == IDOK )
{
wchar_t wcDirPath[MAX_PATH] = {};
HWND hComboAddr = GetDlgItem(hwnd, ID_COMBO_ADDR);
if (hComboAddr != NULL)
{
GetWindowText(hComboAddr, wcDirPath, MAX_PATH);
}
if (!wcslen(wcDirPath))
{
break;
}
DWORD dwAttr = GetFileAttributes(wcDirPath);
if(dwAttr != - && (FILE_ATTRIBUTE_DIRECTORY & dwAttr))
{
LPOPENFILENAMEW oFn = (LPOPENFILENAME)GetProp(hwnd, L"OPENFILENAME");
if (oFn)
{
int size = oFn->nMaxFile > MAX_PATH?MAX_PATH: oFn->nMaxFile;
memcpy(oFn->lpstrFile, wcDirPath, size * sizeof(wchar_t));
RemoveProp(hwnd, L"OPENFILENAME");
EndDialog(hwnd, );
}
else
{
EndDialog(hwnd, );
}
}
break;
}
//////////////////////////////////////////////////////////////////////////
//如果是左边toolbar发出的WM_COMMOND消息(即点击左边的toolbar), 则清空OK按钮旁的组合框。
HWND hCtrl = (HWND)lParam;
if (hCtrl == NULL)
{
break;
}
int ctrlId = GetDlgCtrlID(hCtrl);
if (ctrlId == ID_LEFT_TOOBAR)
{
HWND hComboAddr = GetDlgItem(hwnd, ID_COMBO_ADDR);
if (hComboAddr != NULL)
{
SetWindowTextW(hComboAddr, L"");
}
}
}
break;
}
int i = CallWindowProc( (WNDPROC) g_lOriWndProc , hwnd, uMsg, wParam ,lParam );
return i;
}
UINT_PTR static __stdcall MyFolderProc( HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam )
{
//参考reactos可知,hdlg 是一个隐藏的对话框,其父窗口为打开文件对话框, OK,CANCEL按钮等控件的消息在父窗口处理。
if(uiMsg == WM_NOTIFY)
{
LPOFNOTIFY lpOfNotify = (LPOFNOTIFY)lParam;
if (lpOfNotify->hdr.code == CDN_INITDONE )
{
SetPropW(GetParent(hdlg), L"OPENFILENAME", (HANDLE)(lpOfNotify->lpOFN));
g_lOriWndProc = ::SetWindowLongW( ::GetParent( hdlg ), GWL_WNDPROC , (LONG)_WndProc );
}
if (lpOfNotify->hdr.code == CDN_SELCHANGE)
{
wchar_t wcDirPath[MAX_PATH] = {};
CommDlg_OpenSave_GetFilePathW(GetParent( hdlg ), wcDirPath, sizeof(wcDirPath));
HWND hComboAddr = GetDlgItem(GetParent(hdlg), ID_COMBO_ADDR);
if (hComboAddr != NULL)
{
if (wcslen(wcDirPath))
{
//去掉文件夹快捷方式的后缀名。
int pathSize = wcslen(wcDirPath);
if (pathSize >= )
{
wchar_t* wcExtension = PathFindExtensionW(wcDirPath);
if (wcslen(wcExtension))
{
wcExtension = CharLowerW(wcExtension);
if(!wcscmp(wcExtension, L".lnk"))
{
wcDirPath[pathSize - ] = L'\0';
}
}
} SetWindowTextW(hComboAddr, wcDirPath);
}
else
{
SetWindowTextW(hComboAddr, L"");
}
}
}
}
return ;
} int _tmain(int argc, _TCHAR* argv[])
{
setlocale(LC_ALL,"chs");
OPENFILENAMEW openFile;
memset(&openFile, , sizeof(openFile));
openFile.lStructSize = sizeof(openFile); wchar_t szFileName[MAX_PATH]={};
OPENFILENAME openFileName = {};
openFile.lStructSize = sizeof(OPENFILENAME);
openFile.nMaxFile = MAX_PATH;
openFile.lpstrFilter = L"文件夹\0..\0\0";
openFile.lpstrFile = szFileName;
openFile.nFilterIndex = ;
openFile.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST |OFN_ENABLEHOOK | OFN_HIDEREADONLY;
openFile.hInstance = (HMODULE)GetCurrentProcess();
openFile.lpfnHook = MyFolderProc;
BOOL b = GetOpenFileNameW(&openFile);
wprintf(L"%d %s\n", b,szFileName);
system("pause");
return ;
}

参考:http://blog.csdn.net/norsd/article/details/3476606

GetOpenFileName 选择文件夹的解决方法的更多相关文章

  1. python listdir() 中文路径 中文文件夹 乱码 解决方法

    python listdir() 中文路径 中文文件夹 乱码 解决方法 listdir(path)返回的结果的编码似乎和我们提供的 path 参数的编码有关: path = 'd:/test' try ...

  2. pyhton 27 pip命令无法使用 没有Scripts文件夹 的解决方法

    1 安装了setuptools http://jingyan.baidu.com/article/fb48e8be52f3166e622e1400.html 2 用ez_setup.py安装了setu ...

  3. C# WINFORM 编程中,选择**文件夹**而不是文件的方法(转)

    我们选择文件可以用 OpenFileDialog ,但是文件夹有两种方法. 法一: 用C#的FolderNameEditor类的子类FolderBrowser类来实现获取浏览文件夹对话框的功能.下面来 ...

  4. WPF中选择文件和选择文件夹的方法

    最近从winform转WPF,遇到了各种各样的问题.然而网上的关于WPF的资料少之又少,甚至连基本的文件选择操作,百度搜索的首页都没有一个比较好的方法.所以,踩了几个坑之后,我把我得到的方法分享给大家 ...

  5. 琐碎--选择文件夹(路径)+生产txt格式的log+数据库操作方式

    记录日常工作常用到的一些方法: 1 选择文件操作,并将文件的路径记录下来: OpenFileDialog ofd = new OpenFileDialog(); ofd.Multiselect = f ...

  6. win10 uwp 保存用户选择文件夹

    如果我们每次把临时处理的文件保存,都要让用户选择一次,用户会不会觉得uwp垃圾?如果我们每次打开应用,都从某个文件读取,而这个文件不在应用目录和已知的目录,那么每次都需要用户选择,用户会不会觉得uwp ...

  7. 无法打开文件“freeglut.lib”解决方法:

    资源: 链接:https://pan.baidu.com/s/1eSctT5K 密码:174s VS2010问题: 无法打开文件"freeglut.lib"解决方法: (1)下载f ...

  8. Unable to find ‘struts.multipart.saveDir’ Struts2上传文件错误的解决方法

    Unable to find ‘struts.multipart.saveDir’ Struts2上传文件错误的解决方法 在使用struts2的项目中上传文件的时候出现了一个这样的错误: 2011-7 ...

  9. java 弹出选择目录框(选择文件夹),获取选择的文件夹路径

    java 弹出选择目录框(选择文件夹),获取选择的文件夹路径 java 弹出选择目录框(选择文件夹),获取选择的文件夹路径:int result = 0;File file = null;String ...

随机推荐

  1. php+redis实现高并发模拟下单、秒杀、抢购操作

    对于高并发下的场景,一般都是采用redis缓存机制来处理. 当然也不是只有redis可以处理.还有利用mysql事务操作锁住操作的行.文件锁. 不过这些方式都没有redis缓存高效.可靠. 模拟的过程 ...

  2. FZU - 2109 Mountain Number 数位dp

    Mountain Number One integer number x is called "Mountain Number" if: (1) x>0 and x is a ...

  3. webbrowser 控件实现WinForm与WebForm交互

    WebBrowser 控件可以让你装载Windows Form 应用程序中的 Web 网页和其它采用浏览器的文件.可以使用webbrowser 控件将现有的web框架控制项加入至 Windows Fo ...

  4. JavaScript巩固篇(一)——数据类型与全局变量、局部变量、垃圾回收机制、存储方式、生命周期

    知识要点 数据类型 存储方式 全局变量与局部变量 变量的生命周期 垃圾回收机制 知识概览 数据类型 JavaScript的数据类型分为:基本类型.引用类型 本质区别: 基本数据类型的变量实际值存储在栈 ...

  5. C#中的结构体要使用new来实例化吗?

    声明结构的默认(无参数)构造函数是错误的.总是提供默认构造函数以将结构成员初始化为它们的默认值.在结构中初始化实例字段也是错误的. 如果使用 new 运算符创建结构对象,则会创建该结构对象,并调用适当 ...

  6. 洛谷P3405 [USACO16DEC]Cities and States省市

    P3405 [USACO16DEC]Cities and States省市 题目描述 To keep his cows intellectually stimulated, Farmer John h ...

  7. jquery 插件的实现和优化

    1.menus 实现: $.fn.menu=function(options){ var $this=$(this); var cross='<div class="zhiniu_cr ...

  8. for循环,递归,函数封装作业

    /******求100以内,所有的奇数和,求100以内,所有的偶数积*******/ // for循环方法   var sum=0; var sum1=1; for(var i=1;i<=100 ...

  9. IOS 打包提示 No iTunes Connect access for the team

    1.可以在提示页直接点击 Manage Accounts按钮,进去页面后,选择开发者账号点减号删除:(或者在Xcode中直接按command+键进入,选择accounts,选中账号按-键删除) 2.完 ...

  10. [題解](函數下整點個數?)luogu_P4132_BZOJ_2659_算不出的等式

    兩個都是一次函數,下取整就是整點個數,兩個函數k剛好成倒數,所以最後發現會組合成一個矩形 (為啥要考慮重複與否的問題???) 然而這樣會不會重複計算點數呢 我們發現因為取的是圖像下的整數點 所以要想重 ...