]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/dc.cpp
docking hint bug fix
[wxWidgets.git] / src / msw / dc.cpp
index 03375ff1083a7e81509d36956401417ffd14df68..8c7a50a98264b557e9f914cb1659746fef2249a4 100644 (file)
 #endif
 
 #ifndef AC_SRC_ALPHA
-#define AC_SRC_ALPHA 1
+    #define AC_SRC_ALPHA 1
+#endif
+
+#ifndef LAYOUT_RTL
+    #define LAYOUT_RTL 1
 #endif
 
 /* Quaternary raster codes */
@@ -196,36 +200,44 @@ private:
     DECLARE_NO_COPY_CLASS(StretchBltModeChanger)
 };
 
-// support for dynamic loading of msimg32.dll which we use for some functions
-class wxMSImg32DLL
+// helper class to cache dynamically loaded libraries and not attempt reloading
+// them if it fails
+class wxOnceOnlyDLLLoader
 {
 public:
-    // return the symbol with the given name if the DLL not loaded or symbol
-    // not present
-    static void *GetSymbol(const wxChar *name)
+    // ctor argument must be a literal string as we don't make a copy of it!
+    wxOnceOnlyDLLLoader(const wxChar *dllName)
+        : m_dllName(dllName)
     {
+    };
+
+
+    // return the symbol with the given name or NULL if the DLL not loaded
+    // or symbol not present
+    void *GetSymbol(const wxChar *name)
+    {
+        // we're prepared to handle errors here
         wxLogNull noLog;
 
-        if ( !ms_triedToLoad )
+        if ( m_dllName )
         {
-            ms_triedToLoad = true;
-            ms_dll.Load(_T("msimg32"));
+            m_dll.Load(m_dllName);
+
+            // reset the name whether we succeeded or failed so that we don't
+            // try again the next time
+            m_dllName = NULL;
         }
 
-        return ms_dll.IsLoaded() ? ms_dll.GetSymbol(name) : NULL;
+        return m_dll.IsLoaded() ? m_dll.GetSymbol(name) : NULL;
     }
 
 private:
-    static wxDynamicLibrary ms_dll;
-    static bool ms_triedToLoad;
+    wxDynamicLibrary m_dll;
+    const wxChar *m_dllName;
 };
 
-wxDynamicLibrary wxMSImg32DLL::ms_dll;
-bool wxMSImg32DLL::ms_triedToLoad = false;
-
-// helper macro for getting the symbols from msimg32.dll: it supposes that a
-// type "name_t" is defined and casts the returned symbol to it automatically
-#define wxMSIMG32_SYMBOL(name) (name ## _t)wxMSImg32DLL::GetSymbol(_T(#name))
+static wxOnceOnlyDLLLoader wxGDI32DLL(_T("gdi32"));
+static wxOnceOnlyDLLLoader wxMSIMG32DLL(_T("msimg32"));
 
 // ===========================================================================
 // implementation
@@ -918,7 +930,7 @@ void wxDC::DoDrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
         // transparent pen) one pixel smaller in both directions and we want them
         // to have the same size regardless of which pen is used - adjust
 
-        // I wonder if this shouldnยดt be done after the LOG2DEV() conversions. RR.
+        // I wonder if this shouldnt be done after the LOG2DEV() conversions. RR.
         if ( m_pen.GetStyle() == wxTRANSPARENT )
         {
             // Apparently not needed for WinCE (see e.g. Life! demo)
@@ -1233,7 +1245,8 @@ void wxDC::DoDrawBitmap( const wxBitmap &bmp, wxCoord x, wxCoord y, bool useMask
             // Rather than reproduce wxDC::Blit, let's do it at the wxWin API
             // level
             wxMemoryDC memDC;
-            memDC.SelectObject(bmp);
+
+            memDC.SelectObjectAsSource(bmp);
 
             Blit(x, y, width, height, &memDC, 0, 0, wxCOPY, useMask);
 
@@ -2541,7 +2554,8 @@ static bool AlphaBlt(HDC hdcDst,
                                         HDC,int,int,int,int,
                                         BLENDFUNCTION);
 
-    static AlphaBlend_t pfnAlphaBlend = wxMSIMG32_SYMBOL(AlphaBlend);
+    static AlphaBlend_t
+        pfnAlphaBlend = (AlphaBlend_t)wxMSIMG32DLL.GetSymbol(_T("AlphaBlend"));
     if ( pfnAlphaBlend )
     {
         BLENDFUNCTION bf;
@@ -2654,7 +2668,8 @@ void wxDC::DoGradientFillLinear (const wxRect& rect,
 #if defined(GRADIENT_FILL_RECT_H) && wxUSE_DYNLIB_CLASS
     typedef BOOL
         (WINAPI *GradientFill_t)(HDC, PTRIVERTEX, ULONG, PVOID, ULONG, ULONG);
-    static GradientFill_t pfnGradientFill = wxMSIMG32_SYMBOL(GradientFill);
+    static GradientFill_t pfnGradientFill =
+        (GradientFill_t)wxMSIMG32DLL.GetSymbol(_T("GradientFill"));
 
     if ( pfnGradientFill )
     {
@@ -2705,3 +2720,46 @@ void wxDC::DoGradientFillLinear (const wxRect& rect,
 
     wxDCBase::DoGradientFillLinear(rect, initialColour, destColour, nDirection);
 }
+
+static DWORD wxGetDCLayout(HDC hdc)
+{
+    typedef DWORD (WINAPI *GetLayout_t)(HDC);
+    static GetLayout_t
+        pfnGetLayout = (GetLayout_t)wxGDI32DLL.GetSymbol(_T("GetLayout"));
+
+    return pfnGetLayout ? pfnGetLayout(hdc) : (DWORD)-1;
+}
+
+wxLayoutDirection wxDC::GetLayoutDirection() const
+{
+    DWORD layout = wxGetDCLayout(GetHdc());
+
+    if ( layout == (DWORD)-1 )
+        return wxLayout_Default;
+
+    return layout & LAYOUT_RTL ? wxLayout_RightToLeft : wxLayout_LeftToRight;
+}
+
+void wxDC::SetLayoutDirection(wxLayoutDirection dir)
+{
+    typedef DWORD (WINAPI *SetLayout_t)(HDC, DWORD);
+    static SetLayout_t
+        pfnSetLayout = (SetLayout_t)wxGDI32DLL.GetSymbol(_T("SetLayout"));
+    if ( !pfnSetLayout )
+        return;
+
+    if ( dir == wxLayout_Default )
+    {
+        dir = wxTheApp->GetLayoutDirection();
+        if ( dir == wxLayout_Default )
+            return;
+    }
+
+    DWORD layout = wxGetDCLayout(GetHdc());
+    if ( dir == wxLayout_RightToLeft )
+        layout |= LAYOUT_RTL;
+    else
+        layout &= ~LAYOUT_RTL;
+
+    pfnSetLayout(GetHdc(), layout);
+}