GetOpenFileName 选择文件夹的解决方法
某些环境下(如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 选择文件夹的解决方法的更多相关文章
- python listdir() 中文路径 中文文件夹 乱码 解决方法
python listdir() 中文路径 中文文件夹 乱码 解决方法 listdir(path)返回的结果的编码似乎和我们提供的 path 参数的编码有关: path = 'd:/test' try ...
- pyhton 27 pip命令无法使用 没有Scripts文件夹 的解决方法
1 安装了setuptools http://jingyan.baidu.com/article/fb48e8be52f3166e622e1400.html 2 用ez_setup.py安装了setu ...
- C# WINFORM 编程中,选择**文件夹**而不是文件的方法(转)
我们选择文件可以用 OpenFileDialog ,但是文件夹有两种方法. 法一: 用C#的FolderNameEditor类的子类FolderBrowser类来实现获取浏览文件夹对话框的功能.下面来 ...
- WPF中选择文件和选择文件夹的方法
最近从winform转WPF,遇到了各种各样的问题.然而网上的关于WPF的资料少之又少,甚至连基本的文件选择操作,百度搜索的首页都没有一个比较好的方法.所以,踩了几个坑之后,我把我得到的方法分享给大家 ...
- 琐碎--选择文件夹(路径)+生产txt格式的log+数据库操作方式
记录日常工作常用到的一些方法: 1 选择文件操作,并将文件的路径记录下来: OpenFileDialog ofd = new OpenFileDialog(); ofd.Multiselect = f ...
- win10 uwp 保存用户选择文件夹
如果我们每次把临时处理的文件保存,都要让用户选择一次,用户会不会觉得uwp垃圾?如果我们每次打开应用,都从某个文件读取,而这个文件不在应用目录和已知的目录,那么每次都需要用户选择,用户会不会觉得uwp ...
- 无法打开文件“freeglut.lib”解决方法:
资源: 链接:https://pan.baidu.com/s/1eSctT5K 密码:174s VS2010问题: 无法打开文件"freeglut.lib"解决方法: (1)下载f ...
- Unable to find ‘struts.multipart.saveDir’ Struts2上传文件错误的解决方法
Unable to find ‘struts.multipart.saveDir’ Struts2上传文件错误的解决方法 在使用struts2的项目中上传文件的时候出现了一个这样的错误: 2011-7 ...
- java 弹出选择目录框(选择文件夹),获取选择的文件夹路径
java 弹出选择目录框(选择文件夹),获取选择的文件夹路径 java 弹出选择目录框(选择文件夹),获取选择的文件夹路径:int result = 0;File file = null;String ...
随机推荐
- 极客时间_Vue开发实战_汇总贴
视频地址: https://time.geekbang.org/course/intro/163 https://github.com/tangjinzhou/geektime-vue-1 电脑dem ...
- Linux/Unix中的命令提示符prompt
用惯了DOS的伙计刚用Unix时最想干的事情就是想把Unix搞得像DOS一些, 其中的一条就是把Unix的提示符设置成$p$g那样的.下面就说一说做的方法. 不同的SHELL设置的方法不同,比较方便的 ...
- Django 开发拓展 auth 模块,注册用户时发生 ValueError: The given username must be set
原因 使用局部钩子函数 _clean_fields() 对 username.email 字段进行验证时,未返回,具体请参考 _clean_fields() 函数源码. def clean_usern ...
- 安装coreseek 编译错误
Ubuntu下 编译csft 报错fatal error python.h no such file or directory 执行apt-get install python-dev即可
- SPOJ IAPCR2F 【并查集】
思路: 利用并查集/DFS都可以处理连通问题. PS:注意Find()查找值和pre[]值的区别. #include<bits/stdc++.h> using namespace std; ...
- es6常用方法
一.let 和 constlet 声明变量,只在所在的块区有效,不存在变量提升:var 存在变 量提升const 声明常量,只在所在块区有效 二.变量的解构赋值1.数组的解构赋值let [a, b, ...
- Node.js 内置模块crypto加密模块(3) HMAC
HMAC:哈希消息认证码 ( Hash-based Message Authentication Code ) HMAC是密钥相关的哈希算法 使用 HMAC 进行加密的Node实现的一种方法: &qu ...
- SpringMVC之WebMVC介绍
一.MVC是什么 二.常用的MVC框架 三.MVC模式的优缺点 四.SpringMVC简介
- ADO.NET 学习链接
在博客园上,这个系列的文章对ADO.NET 总结的很好. ADO.NET 系列文章
- JS高级学习历程-3
JS-作用域链及作用 [作用域链] 1 什么事作用域链 一个变量,在当前环境可以使用,当前环境的内部环境也可以使用,内部的深层环境...也可以使用,变量在不同环境都可以使用的现象想成了一个链条,称为“ ...