MFC CFileDialog的问题...

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MFC CFileDialog的问题...相关的知识,希望对你有一定的参考价值。

CFileDialog fd(true);
if(fd.DoModal()==IDOK)

hFile=fopen(fd.GetPathName(), "rb");

编译会提示:error C2664: 'fopen' : cannot convert parameter 1 from 'CString' to 'const char *'

应该怎么转换类型? 强制貌似不行。。。

第二个问题是,CFileDialog 在打开时候,默认的目录,能指定吗?

你这个是因为你的程序选择了Unicode编码,在Unicode编码下,系统默认的字符为wchar_t,一个字符两字节,这时候CString也默认转换成一个字符两字节的wchar_t。而fopen是个ANSI字符的函数,不能接受宽字符(wchar_t)所以编译器就报错了。解决方法有两个

1. 使用Unicode函数,基本所有的ANSI函数都带有一个Unicode版本的,fopen则为_wfopen

2. 使用USES_CONVERSION类型转换
A2T可以把ANSI编码转换成Unicode编码,T2A则相反。使用前先要定义USES_CONVERSION


USES_CONVERSION;
fopen(T2A(fd.GetPathName()), "rb")...
即可。

不过强烈推荐全部使用Unicode编码的函数,适合多语言和国际化的需要。

另外,微软增加了一种TCHAR的变量类型,其中T就是指的是当编译器设置了Unicode,那么全部按照wchar来处理,如果编译器设定了ANSI字符,则全部按照char处理。

也就是相当于(事实上要更复杂一些)
#ifdef _UNICODE
#define TCHAR wchar_t
#else
#define TCHAR char
#endif

Windows定义的字符串指针类型
LPCTSTR
LPTSTR
这里面的T就是TCHAR的意思,令注,C是const的意思,LP是指针的意思,STR是字符

LPCTSTR被定义为 const TCHAR*,根据Unicode选项为const char*或者const wchar_t*
LPTSTR则为TCHAR*,根据Unicode选项为char*或者wchar_t*

所有的函数都带TCHAR版本,自动适应ANSI和Unicode设置的需要,
比如
_tprintf
_tscanf
_tfopen
等,这些函数都可以在msdn查到。

另外,Windows API以及MFC函数都是以TCHAR编写的。

在定义字符串常量的时候,一律要用宏_T()包括定义的字符串,比如
CString str = _T("test");
在Unicode激活的时候,变成L"test"的Unicode字符串,未激活Unicode则是普通的"test"。
参考技术A 第一个问题,一般都是将文件名再输出到一个char变量数组的,我一直都是如此做的。
第二个问题参见下面的代码,比如设置为C根目录:
CFileDialog FileDlg(TRUE,"*.exe",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,"Exe files(*.exe)|*.exe|All files (*.*)|*.*||");
FileDlg.m_ofn.lpstrInitialDir="C:\\";

if(FileDlg.DoModal()==IDOK)
参考技术B 默认目录可以指定。
CFileDialog fd(true,NULL,"C:\\windows\\*.*")

关于类型转换的问题,可以用LPCTSTR。
hFile=fopen((LPCTSTR)(fd.GetPathName()), "rb");
正常情况下,这个转换时可以自动进行的。
参考技术C 为什么不用fd.GetPathName().GetBuffer();
CString 和char*确实是无法强制转化的,因为他们的存储结构不匹配。
CString 类型在内存中存放的前几个字节是int型(这个记不得清楚了,也可能是short,long)的字符串长度。即使能够强制转化通过,转化出来的也是错的,所以编译器报错倒是件好事。
你做个程序,对CString类型测试一下吧。
参考技术D 楼上的基本上说的很清楚了,续貂一下:LPCTSTR是CString类提供的重载操作符,所以可以直接利用。

在 CFileDialog (MFC) 中设置文件夹视图

【中文标题】在 CFileDialog (MFC) 中设置文件夹视图【英文标题】:Setting the folder view in a CFileDialog (MFC) 【发布时间】:2011-10-25 08:02:35 【问题描述】:

是否有一种标准方法可以在 CFileDialog 中设置文件夹视图(启用 Vista 样式)?我正在尝试让它显示详细信息视图和一些自定义列。

我已经实现了一个 Windows 7 列处理程序,它显示由我的应用程序创建的文件的特定于应用程序的信息。但是,为了在资源管理器窗口或公用文件对话框中查看这些自定义列,我必须手动将文件夹视图设置为详细信息,然后选择我想要的特定列。

这很好用,但目标是让应用程序中的文件选择器自动在详细信息视图中显示这些列,除非用户更改视图样式。

我已经研究了各种方法来做到这一点,但没有找到可行的解决方案。 shell 属性包似乎存储了列类型和宽度以及视图样式,但其中大部分是二进制的,并且没有明显记录。如果我复制包属性,我可以切换视图设置,但这似乎很脆弱。

任何指针或其他帮助将不胜感激。

【问题讨论】:

【参考方案1】:

我认为 Explorer 不会在 Vista/Windows 7 中加载列处理程序。

在 vista 文件对话框中更改视图设置:

Check OS version (needs Vista or higher)    
Not sure which event is raised on startup, OnFolderChange maybe?
assuming OnFolderChange is raised, override CFileDialog::OnFolderChange:
call GetIFileSaveDialog/GetIFileOpenDialog to get IFileDialog
//begin undocumented behavior 
QI for IServiceProvider from IFileDialog
QS for SID_SFolderView with IID_IFolderView2
call IFolderView2::SetViewModeAndIconSize
//end undocumented behavior
clean up COM interfaces

您也可以尝试未记录的方法 #2

//begin undocumented behavior 
QI for IServiceProvider from IFileDialog
QS for SID_STopLevelBrowser with IID_IShellBrowser
call IShellBrowser::QueryActiveShellView to get IShellView
QI IFolderView2 from IShellView
call IFolderView2::SetViewModeAndIconSize
//end undocumented behavior
clean up COM interfaces

【讨论】:

我称它为列处理程序,但它使用属性系统 COM 接口来处理显示自定义列和进入其中的数据。这在 Vista 和 7 中运行良好(在 XP 上,我需要实现之前的 IColumnProvider,但这是另一回事)。谢谢,我会调查这种方法。 我希望我有足够的业力来支持你。最终结果使用 IFileDialog -> IServiceProvider 中的 IFolderView2 将视图更改为详细信息模式。然后使用 IServiceProvider -> IShellBrowser -> IShellView 中的 IColumnManager 我能够使用我的自定义列的属性存储道具键设置列。非常感谢。

以上是关于MFC CFileDialog的问题...的主要内容,如果未能解决你的问题,请参考以下文章

mfc CFileDialog类

MFC中CFileDialog使用方法

在 CFileDialog (MFC) 中设置文件夹视图

如何在 MFC 中使用 CfileDialog 选择特定文件

MFC CFileDialog 只打开选择文件

关于MFC的CFileDialog类的问题