X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/c10c791ba99839bd5fb5216cbf8dc8e8bd3f1fb3..404b319a85dadd7decf7a5a5331020520031a41c:/src/msw/filedlg.cpp?ds=inline diff --git a/src/msw/filedlg.cpp b/src/msw/filedlg.cpp index c553328fb4..27dfd888e5 100644 --- a/src/msw/filedlg.cpp +++ b/src/msw/filedlg.cpp @@ -43,8 +43,11 @@ #include #include +#include "wx/dynlib.h" #include "wx/filename.h" +#include "wx/scopeguard.h" #include "wx/tokenzr.h" +#include "wx/testing.h" // ---------------------------------------------------------------------------- // constants @@ -65,7 +68,7 @@ // ---------------------------------------------------------------------------- // standard dialog size for the old Windows systems where the dialog wasn't -// resizeable +// resizable static wxRect gs_rectDialog(0, 0, 428, 266); // ============================================================================ @@ -74,6 +77,78 @@ static wxRect gs_rectDialog(0, 0, 428, 266); IMPLEMENT_CLASS(wxFileDialog, wxFileDialogBase) +// ---------------------------------------------------------------------------- + +namespace +{ + +#if wxUSE_DYNLIB_CLASS + +typedef BOOL (WINAPI *GetProcessUserModeExceptionPolicy_t)(LPDWORD); +typedef BOOL (WINAPI *SetProcessUserModeExceptionPolicy_t)(DWORD); + +GetProcessUserModeExceptionPolicy_t gs_pfnGetProcessUserModeExceptionPolicy + = (GetProcessUserModeExceptionPolicy_t) -1; + +SetProcessUserModeExceptionPolicy_t gs_pfnSetProcessUserModeExceptionPolicy + = (SetProcessUserModeExceptionPolicy_t) -1; + +DWORD gs_oldExceptionPolicyFlags = 0; + +bool gs_changedPolicy = false; + +#endif // #if wxUSE_DYNLIB_CLASS + +/* +Since Windows 7 by default (callback) exceptions aren't swallowed anymore +with native x64 applications. Exceptions can occur in a file dialog when +using the hook procedure in combination with third-party utilities. +Since Windows 7 SP1 the swallowing of exceptions can be enabled again +by using SetProcessUserModeExceptionPolicy. +*/ +void ChangeExceptionPolicy() +{ +#if wxUSE_DYNLIB_CLASS + gs_changedPolicy = false; + + wxLoadedDLL dllKernel32(wxT("kernel32.dll")); + + if ( gs_pfnGetProcessUserModeExceptionPolicy + == (GetProcessUserModeExceptionPolicy_t) -1) + { + wxDL_INIT_FUNC(gs_pfn, GetProcessUserModeExceptionPolicy, dllKernel32); + wxDL_INIT_FUNC(gs_pfn, SetProcessUserModeExceptionPolicy, dllKernel32); + } + + if ( !gs_pfnGetProcessUserModeExceptionPolicy + || !gs_pfnSetProcessUserModeExceptionPolicy + || !gs_pfnGetProcessUserModeExceptionPolicy(&gs_oldExceptionPolicyFlags) ) + { + return; + } + + if ( gs_pfnSetProcessUserModeExceptionPolicy(gs_oldExceptionPolicyFlags + | 0x1 /* PROCESS_CALLBACK_FILTER_ENABLED */ ) ) + { + gs_changedPolicy = true; + } + +#endif // wxUSE_DYNLIB_CLASS +} + +void RestoreExceptionPolicy() +{ +#if wxUSE_DYNLIB_CLASS + if (gs_changedPolicy) + { + gs_changedPolicy = false; + (void) gs_pfnSetProcessUserModeExceptionPolicy(gs_oldExceptionPolicyFlags); + } +#endif // wxUSE_DYNLIB_CLASS +} + +} // unnamed namespace + // ---------------------------------------------------------------------------- // hook function for moving the dialog // ---------------------------------------------------------------------------- @@ -156,8 +231,8 @@ void wxFileDialog::GetPaths(wxArrayString& paths) const paths.Empty(); wxString dir(m_dir); - if ( m_dir.Last() != _T('\\') ) - dir += _T('\\'); + if ( m_dir.empty() || m_dir.Last() != wxT('\\') ) + dir += wxT('\\'); size_t count = m_fileNames.GetCount(); for ( size_t n = 0; n < count; n++ ) @@ -174,14 +249,6 @@ void wxFileDialog::GetFilenames(wxArrayString& files) const files = m_fileNames; } -void wxFileDialog::SetPath(const wxString& path) -{ - wxString ext; - wxFileName::SplitPath(path, &m_dir, &m_fileName, &ext); - if ( !ext.empty() ) - m_fileName << _T('.') << ext; -} - void wxFileDialog::DoGetPosition(int *x, int *y) const { if ( x ) @@ -233,7 +300,7 @@ void wxFileDialog::DoCentre(int dir) void wxFileDialog::MSWOnInitDone(WXHWND hDlg) { - // note the the dialog is the parent window: hDlg is a child of it when + // note the dialog is the parent window: hDlg is a child of it when // OFN_EXPLORER is used HWND hFileDlg = ::GetParent((HWND)hDlg); @@ -351,7 +418,7 @@ static bool ShowCommFileDialog(OPENFILENAME *of, long style) { // this can happen if the default file name is invalid, try without it // now - of->lpstrFile[0] = _T('\0'); + of->lpstrFile[0] = wxT('\0'); success = DoShowCommFileDialog(of, style, &errCode); } @@ -383,6 +450,8 @@ void wxFileDialog::MSWOnInitDialogHook(WXHWND hwnd) int wxFileDialog::ShowModal() { + WX_TESTING_SHOW_MODAL_HOOK(); + HWND hWnd = 0; if (m_parent) hWnd = (HWND) m_parent->GetHWND(); if (!hWnd && wxTheApp->GetTopWindow()) @@ -408,12 +477,15 @@ int wxFileDialog::ShowModal() */ if (m_bMovedWindow || HasExtraControlCreator()) // we need these flags. { + ChangeExceptionPolicy(); msw_flags |= OFN_EXPLORER|OFN_ENABLEHOOK; #ifndef __WXWINCE__ msw_flags |= OFN_ENABLESIZING; #endif } + wxON_BLOCK_EXIT0(RestoreExceptionPolicy); + if ( HasFdFlag(wxFD_MULTIPLE) ) { // OFN_EXPLORER must always be specified with OFN_ALLOWMULTISELECT @@ -438,7 +510,7 @@ int wxFileDialog::ShowModal() of.lStructSize = gs_ofStructSize; of.hwndOwner = hWnd; - of.lpstrTitle = m_message.wx_str(); + of.lpstrTitle = m_message.t_str(); of.lpstrFileTitle = titleBuffer; of.nMaxFileTitle = wxMAXFILE + 1 + wxMAXEXT; @@ -484,17 +556,17 @@ int wxFileDialog::ShowModal() wxChar ch = m_dir[i]; switch ( ch ) { - case _T('/'): + case wxT('/'): // convert to backslash - ch = _T('\\'); + ch = wxT('\\'); // fall through - case _T('\\'): + case wxT('\\'): while ( i < len - 1 ) { wxChar chNext = m_dir[i + 1]; - if ( chNext != _T('\\') && chNext != _T('/') ) + if ( chNext != wxT('\\') && chNext != wxT('/') ) break; // ignore the next one, unless it is at the start of a UNC path @@ -521,7 +593,7 @@ int wxFileDialog::ShowModal() size_t items = wxParseCommonDialogsFilter(m_wildCard, wildDescriptions, wildFilters); - wxASSERT_MSG( items > 0 , _T("empty wildcard list") ); + wxASSERT_MSG( items > 0 , wxT("empty wildcard list") ); wxString filterBuffer; @@ -540,7 +612,7 @@ int wxFileDialog::ShowModal() } } - of.lpstrFilter = (LPTSTR)filterBuffer.wx_str(); + of.lpstrFilter = filterBuffer.t_str(); of.nFilterIndex = m_filterIndex + 1; //=== Setting defaultFileName >>========================================= @@ -557,7 +629,7 @@ int wxFileDialog::ShowModal() wxString defextBuffer; // we need it to be alive until GetSaveFileName()! if (HasFdFlag(wxFD_SAVE)) { - const wxChar* extension = filterBuffer.wx_str(); + const wxChar* extension = filterBuffer.t_str(); int maxFilter = (int)(of.nFilterIndex*2L) - 1; for( int i = 0; i < maxFilter; i++ ) // get extension @@ -613,7 +685,7 @@ int wxFileDialog::ShowModal() i += wxStrlen(&fileNameBuffer[i]) + 1; } #else - wxStringTokenizer toke(fileNameBuffer, _T(" \t\r\n")); + wxStringTokenizer toke(fileNameBuffer, wxT(" \t\r\n")); m_dir = toke.GetNextToken(); m_fileName = toke.GetNextToken(); m_fileNames.Add(m_fileName); @@ -623,8 +695,8 @@ int wxFileDialog::ShowModal() #endif // OFN_EXPLORER wxString dir(m_dir); - if ( m_dir.Last() != _T('\\') ) - dir += _T('\\'); + if ( m_dir.Last() != wxT('\\') ) + dir += wxT('\\'); m_path = dir + m_fileName; m_filterIndex = (int)of.nFilterIndex - 1; @@ -639,7 +711,7 @@ int wxFileDialog::ShowModal() (of.nFileExtension && fileNameBuffer[of.nFileExtension] == wxT('\0')) ) { // User has typed a filename without an extension: - const wxChar* extension = filterBuffer.wx_str(); + const wxChar* extension = filterBuffer.t_str(); int maxFilter = (int)(of.nFilterIndex*2L) - 1; for( int i = 0; i < maxFilter; i++ ) // get extension