关于WTL中CFileDialogImpl的DoModal的问题(也许是个bug)??

sumos 2012-08-20 02:59:27
打开atldlgs.h

INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow())
{
ATLASSERT((m_ofn.Flags & OFN_ENABLEHOOK) != 0);
ATLASSERT(m_ofn.lpfnHook != NULL); // can still be a user hook

ATLASSERT((m_ofn.Flags & OFN_EXPLORER) != 0);

if(m_ofn.hwndOwner == NULL) // set only if not specified before
m_ofn.hwndOwner = hWndParent;

ATLASSERT(m_hWnd == NULL); //此处为何是NULL???
ModuleHelper::AddCreateWndData(&m_thunk.cd, (ATL::CDialogImplBase*)this);

BOOL bRet;
if(m_bOpenFileDialog)
#if defined(__AYGSHELL_H__) && (_WIN32_WCE >= 0x0501)
bRet = ::GetOpenFileNameEx(&m_ofn);
else
bRet = ::GetSaveFileName((LPOPENFILENAME)&m_ofn);
#else
bRet = ::GetOpenFileName(&m_ofn);
else
bRet = ::GetSaveFileName(&m_ofn);
#endif

m_hWnd = NULL;//此处为何设置为NULL???
//太坑了,好多Get开头的函数都有断言ATLASSERT(::IsWindow(m_hWnd));

return bRet ? IDOK : IDCANCEL;
}

DoModal()调用之后可以显示,但是调用GetFilePath()时断言错误

int GetFilePath(LPTSTR lpstrFilePath, int nLength) const
{
ATLASSERT(::IsWindow(m_hWnd)); //断言m_hWnd = 0
ATLASSERT((m_ofn.Flags & OFN_EXPLORER) != 0);

return (int)GetFileDialogWindow().SendMessage(CDM_GETFILEPATH, nLength, (LPARAM)lpstrFilePath);
}

但是断点进去GetFilePath函数,查看ofn结构,里面的lpstrFile是正确的。
运行环境:vs2010+wtl8.1+debug+dialog
请求解答???
...全文
279 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
sumos 2012-08-21
  • 打赏
  • 举报
回复
看来了解WTL的人甚少。好吧,结贴。问题的解决方法就是直接用ofn成员变量。
如果是MFC的话,那个Get函数还是可以用的。
Tishion 2012-08-20
  • 打赏
  • 举报
回复
骚年 这不是BUG

FileDialog的用法是通过OPENFILENAME这个结构体来获取最终选择的结果的。

GetFilePath这个方法的用处是,在你没有点击确定或者取消之前,你可能会选中一个文件,这个方法就是用来获取你选中的文件袋路径的。

另外,WTL是推崇模版的,所以这些带impl结尾的类不能拿来直接用,至少你用这些模版类实例化一个类在用。
hurryboylqs 2012-08-20
  • 打赏
  • 举报
回复
代码你可以看到的,直接用成员变量获取即可
dlg.m_szFileName

那种Get函数是要窗口有效才行的,窗口销毁就取不到了
sumos 2012-08-20
  • 打赏
  • 举报
回复
我来分析一下:
是在DoModal()之前还是之后??
之前肯定不行,因为还未选择。
之后,m_hWnd已经为NULL,再调用就断言。
so 怎么在派生类中调用??
[Quote=引用 5 楼 的回复:]
CFileDialogImpl类可以派生啊,派生就类中能调用 GetFilePath
[/Quote]
Occam's_Razor 2012-08-20
  • 打赏
  • 举报
回复
CFileDialogImpl类可以派生啊,派生就类中能调用 GetFilePath
sumos 2012-08-20
  • 打赏
  • 举报
回复
你这个代码是MFC中的吧,GetPathName没有这个函数。
[Quote=引用 2 楼 的回复:]
这个估计是WTL特有的吧。

C/C++ code

CFileDialog dlg(TRUE);
if(dlg.DoModal() == IDOK)
{
m_strGSMFilePath= dlg.GetPathName();
SetDlgItemText(IDC_EDIT_GSMFILE,m_strGSMFilePath)……
[/Quote]
sumos 2012-08-20
  • 打赏
  • 举报
回复
但是MFC中是可以的。 目前只能通过dlg.m_ofn.lpstrFile获取。
如果说窗口已经销毁,那么GetFilePath这个函数不就没用了??那么为什么要提供这个函数??
[Quote=引用 1 楼 的回复:]
用 dlg.m_ofn.lpstrFile 得到你的路径

GetFilePath 是在 CFileDialog 派生类里面调用的

执行完DoModal 之后窗口已经销毁 就不能调用GetFilePath了
[/Quote]
傻X 2012-08-20
  • 打赏
  • 举报
回复
这个估计是WTL特有的吧。

CFileDialog dlg(TRUE);
if(dlg.DoModal() == IDOK)
{
m_strGSMFilePath= dlg.GetPathName();
SetDlgItemText(IDC_EDIT_GSMFILE,m_strGSMFilePath);
}

没问题
Occam's_Razor 2012-08-20
  • 打赏
  • 举报
回复
用 dlg.m_ofn.lpstrFile 得到你的路径

GetFilePath 是在 CFileDialog 派生类里面调用的

执行完DoModal 之后窗口已经销毁 就不能调用GetFilePath了

15,980

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧