X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/e0a050e347b1ece07ad5f165ba1b1d16edbeae77..4b601a59b5f303a8866a18c90fff90aff393c6b7:/src/msw/utilsgui.cpp diff --git a/src/msw/utilsgui.cpp b/src/msw/utilsgui.cpp index f01babae85..68ca45db20 100644 --- a/src/msw/utilsgui.cpp +++ b/src/msw/utilsgui.cpp @@ -33,6 +33,9 @@ #include "wx/dynlib.h" #include "wx/msw/private.h" // includes +#include "wx/msw/registry.h" +#include // needed for SHELLEXECUTEINFO + // ============================================================================ // implementation @@ -105,7 +108,7 @@ bool wxCheckForInterrupt(wxWindow *wnd) // Returns NULL or newly-allocated memory, so use delete[] to clean up. #ifndef __WXMICROWIN__ -wxChar *wxLoadUserResource(const wxString& resourceName, const wxString& resourceType) +char *wxLoadUserResource(const wxString& resourceName, const wxString& resourceType, int* pLen /* = NULL */) { HRSRC hResource = ::FindResource(wxGetInstance(), resourceName.wx_str(), @@ -117,16 +120,16 @@ wxChar *wxLoadUserResource(const wxString& resourceName, const wxString& resourc if ( hData == 0 ) return NULL; - wxChar *theText = (wxChar *)::LockResource(hData); + void *theText = ::LockResource(hData); if ( !theText ) return NULL; // Not all compilers put a zero at the end of the resource (e.g. BC++ doesn't). // so we need to find the length of the resource. int len = ::SizeofResource(wxGetInstance(), hResource); - wxChar *s = new wxChar[len+1]; - wxStrncpy(s,theText,len); - s[len]=0; + char *s = new char[len + 1]; + memcpy(s, theText, len); + s[len] = '\0'; // NUL-terminate in case the resource itself wasn't // Obsolete in WIN32 #ifndef __WIN32__ @@ -136,6 +139,9 @@ wxChar *wxLoadUserResource(const wxString& resourceName, const wxString& resourc // No need?? // GlobalFree(hData); + if (pLen) + *pLen = len; + return s; } #endif // __WXMICROWIN__ @@ -293,19 +299,17 @@ wxString WXDLLEXPORT wxGetWindowClass(WXHWND hWnd) return str; } -WXWORD WXDLLEXPORT wxGetWindowId(WXHWND hWnd) +int WXDLLEXPORT wxGetWindowId(WXHWND hWnd) { - return (WXWORD)GetWindowLong((HWND)hWnd, GWL_ID); + return ::GetWindowLong((HWND)hWnd, GWL_ID); } // ---------------------------------------------------------------------------- // Metafile helpers // ---------------------------------------------------------------------------- -extern void PixelToHIMETRIC(LONG *x, LONG *y) +void PixelToHIMETRIC(LONG *x, LONG *y, HDC hdcRef) { - ScreenHDC hdcRef; - int iWidthMM = GetDeviceCaps(hdcRef, HORZSIZE), iHeightMM = GetDeviceCaps(hdcRef, VERTSIZE), iWidthPels = GetDeviceCaps(hdcRef, HORZRES), @@ -317,10 +321,8 @@ extern void PixelToHIMETRIC(LONG *x, LONG *y) *y /= iHeightPels; } -extern void HIMETRICToPixel(LONG *x, LONG *y) +void HIMETRICToPixel(LONG *x, LONG *y, HDC hdcRef) { - ScreenHDC hdcRef; - int iWidthMM = GetDeviceCaps(hdcRef, HORZSIZE), iHeightMM = GetDeviceCaps(hdcRef, VERTSIZE), iWidthPels = GetDeviceCaps(hdcRef, HORZRES), @@ -332,6 +334,16 @@ extern void HIMETRICToPixel(LONG *x, LONG *y) *y /= (iHeightMM * 100); } +void HIMETRICToPixel(LONG *x, LONG *y) +{ + HIMETRICToPixel(x, y, ScreenHDC()); +} + +void PixelToHIMETRIC(LONG *x, LONG *y) +{ + PixelToHIMETRIC(x, y, ScreenHDC()); +} + void wxDrawLine(HDC hdc, int x1, int y1, int x2, int y2) { #ifdef __WXWINCE__ @@ -364,11 +376,11 @@ extern bool wxEnableFileNameAutoComplete(HWND hwnd) s_initialized = true; wxLogNull nolog; - wxDynamicLibrary dll(_T("shlwapi.dll")); + wxDynamicLibrary dll(wxT("shlwapi.dll")); if ( dll.IsLoaded() ) { s_pfnSHAutoComplete = - (SHAutoComplete_t)dll.GetSymbol(_T("SHAutoComplete")); + (SHAutoComplete_t)dll.GetSymbol(wxT("SHAutoComplete")); if ( s_pfnSHAutoComplete ) { // won't be unloaded until the process termination, no big deal @@ -383,7 +395,7 @@ extern bool wxEnableFileNameAutoComplete(HWND hwnd) HRESULT hr = s_pfnSHAutoComplete(hwnd, 0x10 /* SHACF_FILESYS_ONLY */); if ( FAILED(hr) ) { - wxLogApiError(_T("SHAutoComplete"), hr); + wxLogApiError(wxT("SHAutoComplete"), hr); return false; } @@ -394,3 +406,117 @@ extern bool wxEnableFileNameAutoComplete(HWND hwnd) #endif // wxUSE_DYNLIB_CLASS/!wxUSE_DYNLIB_CLASS } +// ---------------------------------------------------------------------------- +// Launch document with default app +// ---------------------------------------------------------------------------- + +bool wxLaunchDefaultApplication(const wxString& document, int flags) +{ + wxUnusedVar(flags); + + WinStruct sei; + sei.lpFile = document.wx_str(); + sei.lpVerb = wxT("open"); +#ifdef __WXWINCE__ + sei.nShow = SW_SHOWNORMAL; // SW_SHOWDEFAULT not defined under CE (#10216) +#else + sei.nShow = SW_SHOWDEFAULT; +#endif + + // avoid Windows message box in case of error for consistency with + // wxLaunchDefaultBrowser() even if don't show the error ourselves in this + // function + sei.fMask = SEE_MASK_FLAG_NO_UI; + + if ( ::ShellExecuteEx(&sei) ) + return true; + + return false; +} + +// ---------------------------------------------------------------------------- +// Launch default browser +// ---------------------------------------------------------------------------- + +bool wxDoLaunchDefaultBrowser(const wxString& url, const wxString& scheme, int flags) +{ + wxUnusedVar(flags); + +#if wxUSE_IPC + if ( flags & wxBROWSER_NEW_WINDOW ) + { + // ShellExecuteEx() opens the URL in an existing window by default so + // we can't use it if we need a new window + wxRegKey key(wxRegKey::HKCR, scheme + wxT("\\shell\\open")); + if ( !key.Exists() ) + { + // try the default browser, it must be registered at least for http URLs + key.SetName(wxRegKey::HKCR, wxT("http\\shell\\open")); + } + + if ( key.Exists() ) + { + wxRegKey keyDDE(key, wxT("DDEExec")); + if ( keyDDE.Exists() ) + { + // we only know the syntax of WWW_OpenURL DDE request for IE, + // optimistically assume that all other browsers are compatible + // with it + static const wxChar *TOPIC_OPEN_URL = wxT("WWW_OpenURL"); + wxString ddeCmd; + wxRegKey keyTopic(keyDDE, wxT("topic")); + bool ok = keyTopic.Exists() && + keyTopic.QueryDefaultValue() == TOPIC_OPEN_URL; + if ( ok ) + { + ddeCmd = keyDDE.QueryDefaultValue(); + ok = !ddeCmd.empty(); + } + + if ( ok ) + { + // for WWW_OpenURL, the index of the window to open the URL + // in is -1 (meaning "current") by default, replace it with + // 0 which means "new" (see KB article 160957) + ok = ddeCmd.Replace(wxT("-1"), wxT("0"), + false /* only first occurrence */) == 1; + } + + if ( ok ) + { + // and also replace the parameters: the topic should + // contain a placeholder for the URL + ok = ddeCmd.Replace(wxT("%1"), url, false) == 1; + } + + if ( ok ) + { + // try to send it the DDE request now but ignore the errors + wxLogNull noLog; + + const wxString ddeServer = wxRegKey(keyDDE, wxT("application")); + if ( wxExecuteDDE(ddeServer, TOPIC_OPEN_URL, ddeCmd) ) + return true; + + // this is not necessarily an error: maybe browser is + // simply not running, but no matter, in any case we're + // going to launch it using ShellExecuteEx() below now and + // we shouldn't try to open a new window if we open a new + // browser anyhow + } + } + } + } +#endif // wxUSE_IPC + + WinStruct sei; + sei.lpFile = url.c_str(); + sei.lpVerb = wxT("open"); + sei.nShow = SW_SHOWNORMAL; + sei.fMask = SEE_MASK_FLAG_NO_UI; // we give error message ourselves + + if ( ::ShellExecuteEx(&sei) ) + return true; + + return false; +}