c++ - VC++ 2010: Show open dialog hangs -
hi i've converted vc++6 project vc++ 2010 , keep encountering error while displaying modal open file dialog.
it shows bottom part of dialog top missing, filter not populated.
header has public members storing file information:
cstring m_strfilepathname; cstring m_strfileextname; my code show dialog:
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 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 line: if(fd.domodal() != idok) return; diagnostic returns: first-chance exception @ 0x006c69cc in alieditor.exe: 0xc0000005: access violation reading location 0x00000020.
breaking while in hanging mode call stack returns information:
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() line 748 + 0x26 bytes c++ alieditor.exe!cmainframe::onfileopen() line 195 + 0xb bytes c++ alieditor.exe!_afxdispatchcmdmsg(ccmdtarget * ptarget, unsigned int nid, int ncode, void (void)* pfn, void * pextra, unsigned int nsig, afx_cmdhandlerinfo * phandlerinfo) line 82 c++ alieditor.exe!ccmdtarget::oncmdmsg(unsigned int nid, int ncode, void * pextra, afx_cmdhandlerinfo * phandlerinfo) line 381 + 0x27 bytes c++ alieditor.exe!cframewnd::oncmdmsg(unsigned int nid, int ncode, void * pextra, afx_cmdhandlerinfo * phandlerinfo) line 973 + 0x18 bytes c++ alieditor.exe!cwnd::oncommand(unsigned int wparam, long lparam) line 2729 c++ alieditor.exe!cframewnd::oncommand(unsigned int wparam, long lparam) line 371 c++ alieditor.exe!cwnd::onwndmsg(unsigned int message, unsigned int wparam, long lparam, long * presult) line 2101 + 0x1e bytes c++ alieditor.exe!cwnd::windowproc(unsigned int message, unsigned int wparam, long lparam) line 2087 + 0x20 bytes c++ alieditor.exe!afxcallwndproc(cwnd * pwnd, hwnd__ * hwnd, unsigned int nmsg, unsigned int wparam, long lparam) line 257 + 0x1c bytes c++ alieditor.exe!afxwndproc(hwnd__ * hwnd, unsigned int nmsg, unsigned int wparam, long lparam) line 420 c++
declarations of guess (i not c++ developer) overriding (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() file "dlgfile.cpp" big, top part:
// part of microsoft foundation classes c++ library. // copyright (c) microsoft corporation // rights reserved. // // source code intended supplement // microsoft foundation classes reference , related // electronic documentation provided library. // see these sources detailed information regarding // microsoft foundation classes product. #include "stdafx.h" #include <dlgs.h> // standard control ids 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 0 if (dwsize == 0) { dwsize = sizeof(openfilename); } // size of openfilename must @ least version 5 assert(dwsize >= sizeof(openfilename)); // allocate memory 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 0/null m_szfilename[0] = '\0'; m_szfiletitle[0] = '\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 commdlg format (lots of \0) if (lpszfilter != null) { m_strfilter = lpszfilter; lptstr pch = m_strfilter.getbuffer(0); // modify buffer in place // mfc delimits '|' not '\0' while ((pch = _tcschr(pch, '|')) != null) *pch++ = '\0'; m_ofn.lpstrfilter = m_strfilter; // not call releasebuffer() since string contains '\0' characters } if (m_bvistastyle == true) { if (succeeded(coinitializeex(null, coinit_apartmentthreaded))) { // multi-threaded 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; } going step step point in same ("dlgfile.cpp") file:
int_ptr cfiledialog::domodal() { assert_valid(this); assert(m_ofn.flags & ofn_enablehook); assert(m_ofn.lpfnhook != null); // can still user hook // 0 out file buffer 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)); // special case file open/save dialog, // pumps while coming before has // disabled 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 , 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 file open/save dialog. if (benableparent) ::enablewindow(m_ofn.hwndowner, true); if (::iswindow(hwndfocus)) ::setfocus(hwndfocus); postmodal(); return nresult ? nresult : idcancel; } could me?
[update] no 1 can me @ stage, i've uploaded project public place here. can download , tell me what's wrong when click open file?
the problem can see filter string looks incorrect. looks code based on 1 of msdn samples. , according sample szfilter should this:
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||"); fyi used http://msdn.microsoft.com/en-us/library/wh5hz49d(v=vs.100).aspx reference.
[update]
i created small mfc app , pasted in code. there typo in code sample. class cfiledialog, not cfiledlg. fixed it, applied change described above fix szfilter string. works me. file dialog displays, enter data , dismiss file dialog. no access violation, no assert. think need elsewhere in code track down problem.
[update 2]
ignore said. original access violation around line 174 of fileexportdialog.cpp
void cfileexportdialog::ontypechange() { // current filename cwnd *filenamebox = getparent()->getdlgitem(edt1); assert_valid(filenamebox); cstring filename; filenamebox->getwindowtext(filename); // current extension cwnd *typenamebox = getparent()->getdlgitem(cmb1); assert_valid(typenamebox); cstring typename; typenamebox->getwindowtext(typename); ... the real call stack is:
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 incorrect and/or missing, no symbols loaded 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++ ... the program crashing @ cwnd::getdlgitem because cwnd "this" pointer 0. because first line of cfileexportdialog::ontypechange getparent() null because dialog has no parent.
the class cfileexportdialog not part of visual studio appears based on public domain code written in 1999 http://www.codeguru.com/cpp/w-d/dislog/commondialogs/article.php/c1863/cfileexportdialog-class.htm. , looks implementation of ontypechange based on original developer reverse engineering details of microsoft cfiledialog class implemented in 1999. i'm guessing internals have changed in vs 2010 class not longer useful.
next time run program, set breakpoint @ line 177 of fileexportdialog.cpp. when hit breakpoint, single-step through code , watch crashes , asserts obsolete code attempts things should never have been doing in first place.
recommend dump cfileexportdialog class , rewrite program using standard mfc cfiledialog class.
Comments
Post a Comment