VC++2010:显示打开的对话框挂起
VC++ 2010: Show open dialog hangs
嗨,我已经将VC++6项目转换为VC++2010,在显示模式"打开文件"对话框时一直遇到错误。
它显示对话框的底部,但顶部缺失,过滤器也未填充。
标头具有用于存储文件信息的公共成员:
CString m_strFilePathName;
CString m_strFileExtName;
我要显示的对话框代码:
static TCHAR BASED_CODE szFilter[] = _T("Open Bin File(*.abs)|")
_T("Default DataBase File(*.ddf)|")
_T("SatCodex File(*.sdx)|")
_T("Format Text File(*.txt)");
// TODO: Add your command handler code here
CFileDlg fd(TRUE, NULL, "", OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter);
//"Open Bin File(*.abs)|Default DataBase File(*.ddf)|SatCodex File(*.sdx)|Format Text File(*.txt)");
const int c_cMaxFiles = 1;
const int c_cbBuffSize = (c_cMaxFiles * (MAX_PATH + 1)) + 1;
fd.GetOFN().lpstrFile = m_strFilePathName.GetBuffer(c_cbBuffSize);
fd.GetOFN().nMaxFile = c_cbBuffSize;
// Dialog hangs on this line:
if(fd.DoModal() != IDOK) return;
诊断返回:AliEditor.exe中0x006c69cc处的首次机会异常:0xC0000005:读取位置0x00000020的访问冲突。
挂起模式下的中断调用堆栈返回以下信息:
user32.dll!_NtUserWaitMessage@0() + 0x15 bytes <-STOPPED HERE
user32.dll!_NtUserWaitMessage@0() + 0x15 bytes
user32.dll!_DialogBox2@16() + 0x109 bytes
user32.dll!_InternalDialogBox@24() + 0xc9 bytes
user32.dll!_DialogBoxIndirectParamAorW@24() + 0x36 bytes
user32.dll!_DialogBoxIndirectParamW@20() + 0x1b bytes
comdlg32.dll!CFileOpenSave::Show() + 0x146 bytes
AliEditor.exe!CFileDialog::DoModal()行748+0x26字节C++AliEditor.exe!CMainFrame::OnFileOpen()行195+0xb字节C++AliEditor.exe_AfxDispatchCmdMsg(CCmdTarget*pTarget,unsigned int nID,int nCode,void(void)*pfn,void*pExtra,unsignedint nSig,AFX_CMDHANDLERINFO*pHandlerInfo)第82行C++AliEditor.exe!CCmdTarget::OnCmdMsg(unsigned int nID,int nCode,void*pExtra,AFX_CMDHANDLERINFO*pHandlerInfo)行381+0x27字节C++AliEditor.exe!CFrameWnd::OnCmdMsg(无符号int nID,int nCode,void*pExtra,AFX_CMDHANDLERINFO*pHandlerInfo)行973+0x18字节C++AliEditor.exe!CWnd::OnCommand(无符号int wParam,长lParam)行2729 C++AliEditor.exe!CFrameWnd::OnCommand(无符号int wParam,长lParam)第371行C++AliEditor.exe!CWnd::OnWndMsg(无符号int消息,无符号int wParam,长lParam,长*pResult)行2101+0x1e字节C++AliEditor.exe!CWnd::WindowProc(无符号int消息,无符号int wParam,长lParam)行2087+0x20字节C++AliEditor.exe!AfxCallWndProc(CWnd*pWnd,HWND__*HWND,无符号int nMsg,无符号整数wParam,长lParam)行257+0x1c字节C++AliEditor.exe!AfxWndProc(HWND__*HWND,无符号int nMsg,无符号整数wParam,长lParam)第420行C++
我猜(我不是C++开发人员)重写(fileDlg.cpp)的声明:
#include "stdafx.h"
#include "AliEditor.h"
#include "FileDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CFileDlg
IMPLEMENT_DYNAMIC(CFileDlg, CFileDialog)
CFileDlg::CFileDlg(BOOL bOpenFileDialog, LPCTSTR lpszDefExt, LPCTSTR lpszFileName,
DWORD dwFlags, LPCTSTR lpszFilter, CWnd* pParentWnd) :
CFileExportDialog(bOpenFileDialog, lpszDefExt, lpszFileName, dwFlags, lpszFilter, pParentWnd)
{
}
BEGIN_MESSAGE_MAP(CFileDlg, CFileExportDialog)
//{{AFX_MSG_MAP(CFileDlg)
ON_WM_CLOSE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
文件"dlgfile.cpp"很大,但这只是最重要的部分:
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.
#include "stdafx.h"
#include <dlgs.h> // for standard control IDs for commdlg
#include "afxglobals.h"
#define new DEBUG_NEW
////////////////////////////////////////////////////////////////////////////
// FileOpen/FileSaveAs common dialog helper
CFileDialog::CFileDialog(BOOL bOpenFileDialog,
LPCTSTR lpszDefExt, LPCTSTR lpszFileName, DWORD dwFlags,
LPCTSTR lpszFilter, CWnd* pParentWnd, DWORD dwSize, BOOL bVistaStyle)
: CCommonDialog(pParentWnd)
{
OSVERSIONINFO vi;
ZeroMemory(&vi, sizeof(OSVERSIONINFO));
vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
::GetVersionEx(&vi);
// if running under Vista
if (vi.dwMajorVersion >= 6)
{
m_bVistaStyle = bVistaStyle;
}
else
{
m_bVistaStyle = FALSE;
}
m_bPickFoldersMode = FALSE;
// determine size of OPENFILENAME struct if dwSize is zero
if (dwSize == 0)
{
dwSize = sizeof(OPENFILENAME);
}
// size of OPENFILENAME must be at least version 5
ASSERT(dwSize >= sizeof(OPENFILENAME));
// allocate memory for OPENFILENAME struct based on size passed in
m_pOFN = static_cast<LPOPENFILENAME>(malloc(dwSize));
ASSERT(m_pOFN != NULL);
if (m_pOFN == NULL)
AfxThrowMemoryException();
memset(&m_ofn, 0, dwSize); // initialize structure to 0/NULL
m_szFileName[0] = ' ';
m_szFileTitle[0] = ' ';
m_pofnTemp = NULL;
m_bOpenFileDialog = bOpenFileDialog;
m_nIDHelp = bOpenFileDialog ? AFX_IDD_FILEOPEN : AFX_IDD_FILESAVE;
m_ofn.lStructSize = dwSize;
m_ofn.lpstrFile = m_szFileName;
m_ofn.nMaxFile = _countof(m_szFileName);
m_ofn.lpstrDefExt = lpszDefExt;
m_ofn.lpstrFileTitle = (LPTSTR)m_szFileTitle;
m_ofn.nMaxFileTitle = _countof(m_szFileTitle);
m_ofn.Flags |= dwFlags | OFN_ENABLEHOOK | OFN_EXPLORER;
if(dwFlags & OFN_ENABLETEMPLATE)
m_ofn.Flags &= ~OFN_ENABLESIZING;
m_ofn.hInstance = AfxGetResourceHandle();
m_ofn.lpfnHook = (COMMDLGPROC)_AfxCommDlgProc;
// setup initial file name
if (lpszFileName != NULL)
Checked::tcsncpy_s(m_szFileName, _countof(m_szFileName), lpszFileName, _TRUNCATE);
// Translate filter into commdlg format (lots of )
if (lpszFilter != NULL)
{
m_strFilter = lpszFilter;
LPTSTR pch = m_strFilter.GetBuffer(0); // modify the buffer in place
// MFC delimits with '|' not ' '
while ((pch = _tcschr(pch, '|')) != NULL)
*pch++ = ' ';
m_ofn.lpstrFilter = m_strFilter;
// do not call ReleaseBuffer() since the string contains ' ' characters
}
if (m_bVistaStyle == TRUE)
{
if (SUCCEEDED(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)))
{ // multi-threaded is not supported
IFileDialog* pIFileDialog;
IFileDialogCustomize* pIFileDialogCustomize;
HRESULT hr;
USE_INTERFACE_PART_STD(FileDialogEvents);
USE_INTERFACE_PART_STD(FileDialogControlEvents);
if (m_bOpenFileDialog)
{
hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&pIFileDialog));
}
else
{
hr = CoCreateInstance(CLSID_FileSaveDialog, NULL, CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&pIFileDialog));
}
if (FAILED(hr))
{
m_bVistaStyle = FALSE;
return;
}
hr = pIFileDialog->QueryInterface(IID_PPV_ARGS(&pIFileDialogCustomize));
ENSURE(SUCCEEDED(hr));
hr = pIFileDialog->Advise(reinterpret_cast<IFileDialogEvents*>(&m_xFileDialogEvents), &m_dwCookie);
ENSURE(SUCCEEDED(hr));
m_pIFileDialog = static_cast<void*>(pIFileDialog);
m_pIFileDialogCustomize = static_cast<void*>(pIFileDialogCustomize);
}
else
{
m_bVistaStyle = FALSE;
}
}
}
CFileDialog::~CFileDialog()
{
free(m_pOFN);
if (m_bVistaStyle == TRUE)
{
HRESULT hr;
hr = (static_cast<IFileDialog*>(m_pIFileDialog))->Unadvise(m_dwCookie);
ENSURE(SUCCEEDED(hr));
(static_cast<IFileDialogCustomize*>(m_pIFileDialogCustomize))->Release();
(static_cast<IFileDialog*>(m_pIFileDialog))->Release();
CoUninitialize();
}
}
const OPENFILENAME& CFileDialog::GetOFN() const
{
return *m_pOFN;
}
OPENFILENAME& CFileDialog::GetOFN()
{
return *m_pOFN;
}
一步一步地,我在同一个("dlgfile.cpp")文件中到达了这一点:
INT_PTR CFileDialog::DoModal()
{
ASSERT_VALID(this);
ASSERT(m_ofn.Flags & OFN_ENABLEHOOK);
ASSERT(m_ofn.lpfnHook != NULL); // can still be a user hook
// zero out the file buffer for consistent parsing later
ASSERT(AfxIsValidAddress(m_ofn.lpstrFile, m_ofn.nMaxFile));
DWORD nOffset = lstrlen(m_ofn.lpstrFile)+1;
ASSERT(nOffset <= m_ofn.nMaxFile);
memset(m_ofn.lpstrFile+nOffset, 0, (m_ofn.nMaxFile-nOffset)*sizeof(TCHAR));
// This is a special case for the file open/save dialog,
// which sometimes pumps while it is coming up but before it has
// disabled the main window.
HWND hWndFocus = ::GetFocus();
BOOL bEnableParent = FALSE;
m_ofn.hwndOwner = PreModal();
AfxUnhookWindowCreate();
if (m_ofn.hwndOwner != NULL && ::IsWindowEnabled(m_ofn.hwndOwner))
{
bEnableParent = TRUE;
::EnableWindow(m_ofn.hwndOwner, FALSE);
}
_AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
ASSERT(pThreadState->m_pAlternateWndInit == NULL);
if (m_bVistaStyle == TRUE)
{
AfxHookWindowCreate(this);
}
else if (m_ofn.Flags & OFN_EXPLORER)
pThreadState->m_pAlternateWndInit = this;
else
AfxHookWindowCreate(this);
INT_PTR nResult = 0;
if (m_bVistaStyle == TRUE)
{
ApplyOFNToShellDialog();
// HERE CALLS **OPENFILENAME& CFileDialog::GetOFN()** method and then hangs
HRESULT hr = (static_cast<IFileDialog*>(m_pIFileDialog))->Show(m_ofn.hwndOwner);
nResult = (hr == S_OK) ? IDOK : IDCANCEL;
}
else if (m_bOpenFileDialog)
nResult = ::AfxCtxGetOpenFileName(&m_ofn);
else
nResult = ::AfxCtxGetSaveFileName(&m_ofn);
if (nResult)
ASSERT(pThreadState->m_pAlternateWndInit == NULL);
pThreadState->m_pAlternateWndInit = NULL;
// Second part of special case for file open/save dialog.
if (bEnableParent)
::EnableWindow(m_ofn.hwndOwner, TRUE);
if (::IsWindow(hWndFocus))
::SetFocus(hWndFocus);
PostModal();
return nResult ? nResult : IDCANCEL;
}
有人能帮我吗?
[更新]由于现阶段并没有人能够帮助我,我已经将项目上传到了这里的公共场所。当我点击打开文件时,有人能下载并告诉我出了什么问题吗?
我能看到的唯一问题是你的过滤器字符串看起来不正确。看起来您的代码是基于MSDN示例之一的。根据这个样本,你的szFilter应该是这样的:
static TCHAR BASED_CODE szFilter[] = _T("Open Bin File(*.abs)|*.abs|")
_T("Default DataBase File(*.ddf)|*.ddf|")
_T("SatCodex File(*.sdx)|*.sdx|")
_T("Format Text File(*.txt)|*.txt||");
仅供参考我用过http://msdn.microsoft.com/en-US/library/wh5hz49d(v=vs.100).aspx作为参考。
[更新]
我创建了一个小型MFC应用程序并粘贴到您的代码中。您的代码示例中存在拼写错误。类是CFileDialog,而不是CFileDlg。我修复了它,然后应用上面描述的更改来修复szFilter字符串。它对我有用。显示文件对话框,我输入一些数据并关闭文件对话框。没有访问冲突,没有断言。我认为您需要在代码的其他地方查找问题。
[更新2]
忽略我之前说的一切。您最初的访问违规发生在FileExportDialog.cpp 的第174行附近
void CFileExportDialog::OnTypeChange()
{
// get current filename
CWnd *fileNameBox = GetParent()->GetDlgItem(edt1);
ASSERT_VALID(fileNameBox);
CString fileName; fileNameBox->GetWindowText(fileName);
// get current extension
CWnd *typeNameBox = GetParent()->GetDlgItem(cmb1);
ASSERT_VALID(typeNameBox);
CString typeName; typeNameBox->GetWindowText(typeName);
...
真正的调用堆栈是:
AliEditor.exe!CWnd::GetDlgItem(int nID) Line 92 + 0x3 bytes C++
AliEditor.exe!CFileExportDialog::OnTypeChange() Line 177 + 0x14 bytes C++
AliEditor.exe!CFileDialog::XFileDialogEvents::OnTypeChange(IFileDialog * __formal) Line 619 C++
comdlg32.dll!76138057()
[Frames below may be incorrect and/or missing, no symbols loaded for comdlg32.dll]
comctl32.dll!731c7613()
comdlg32.dll!7612bdda()
comdlg32.dll!7612c5a0()
KernelBase.dll!76096055()
comctl32.dll!7458b575()
user32.dll!767281c8()
user32.dll!76728326()
user32.dll!76728347()
user32.dll!76730d27()
user32.dll!7673794a()
AliEditor.exe!_AfxActivationWndProc(HWND__ * hWnd, unsigned int nMsg, unsigned int wParam, long lParam) Line 456 + 0x1a bytes C++
user32.dll!767262fa()
user32.dll!76726d3a()
user32.dll!76726ce9()
user32.dll!7672965e()
user32.dll!7675206f()
user32.dll!7674cf4b()
user32.dll!7674ce8a()
user32.dll!7674cc0e()
comdlg32.dll!7612597b()
AliEditor.exe!CFileDialog::DoModal() Line 748 + 0x26 bytes C++
...
程序在CWnd::GetDlgItem处崩溃,因为CWnd"this"指针为0。这是因为CFileExportDialog::OnTypeChange的第一行是GetParent(),它为NULL,因为此对话框没有父级。
类CFileExportDialog不是Visual Studio的一部分,它似乎是基于1999年编写的一些公共域代码http://www.codeguru.com/cpp/w-d/dislog/commondialogs/article.php/c1863/CFileExportDialog-Class.htm.OnTypeChange的实现似乎是基于最初的开发人员对1999年实现的Microsoft CFileDialog类的细节进行反向工程。我猜VS 2010中的内部结构已经发生了变化,所以该类不再有用。
下次运行程序时,请在FileExportDialog.cpp的第177行设置一个断点。当您遇到断点时,单步执行代码,并观察崩溃和断言,因为过时的代码试图做它本来不应该做的事情。
建议您转储CFileExportDialog类,并使用标准MFC CFileDialog类重写程序。
- 挂起和取消挂起一个文件DLL
- 如何防止C++遗留代码中的挂起指针
- 如何在Qbutton的帮助下更改Q对话框的宽度
- 为什么所有C++编译器都会崩溃或挂起此代码
- 当对话框被接受时,如何用参数调用槽
- WinAPI 在单击第一个对话框上的按钮控件并销毁第一个对话框后创建第二个对话框
- 我编写了代码将十进制分数转换为其二进制等效数.它编译得很好,但在执行时挂起
- 如何多次询问来自QML对话框的输入?
- 选择文件对话框错误
- 构建挂起,即使是适度的文件大小
- 循环挂起迭代的 std::擦除 on std::list
- Poco::Net::FTPClientSession 在 open() 方法上挂起 129 秒,如果 ftp 主机不存
- 自定义对话框(源自QDialog)不会关闭(Android)
- MFC C对话框::在x64上创建挂起
- VC++2010:显示打开的对话框挂起
- 在自定义组合框下拉列表控件上等待超过5秒会导致win32 C++应用程序在Windows7中挂起
- 如何查找 win32 对话框绘图挂起的原因
- 在C++的窗口中打开文件对话框>过滤器不起作用
- 使用运行时创建的模板的对话框在 XP 32 位上不起作用
- 特定对话框控件的MFC SetFont不起作用