]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/utilsgui.cpp
Fix best size computation for buttons without image and with empty label.
[wxWidgets.git] / src / msw / utilsgui.cpp
index f01babae85c64d8784aef0c9e0a858d3c914f0fa..68ca45db20cafbe0293087787bc83e2fe4c5238d 100644 (file)
@@ -33,6 +33,9 @@
 #include "wx/dynlib.h"
 
 #include "wx/msw/private.h"     // includes <windows.h>
+#include "wx/msw/registry.h"
+#include <shellapi.h> // 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<SHELLEXECUTEINFO> 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<SHELLEXECUTEINFO> 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;
+}