]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/dc.cpp
don't keep dangling m_prevRadio pointer (2nd part of patch 1836644)
[wxWidgets.git] / src / msw / dc.cpp
index 6e0ea3100b992fc5b1eacd4ba1827a86dd5516ed..0801815ebf277f650057f3f17b53980ab2ad7374 100644 (file)
@@ -205,6 +205,8 @@ private:
     DECLARE_NO_COPY_CLASS(StretchBltModeChanger)
 };
 
+#if wxUSE_DYNLIB_CLASS
+
 // helper class to cache dynamically loaded libraries and not attempt reloading
 // them if it fails
 class wxOnceOnlyDLLLoader
@@ -236,14 +238,39 @@ public:
         return m_dll.IsLoaded() ? m_dll.GetSymbol(name) : NULL;
     }
 
+    void Unload()
+    {
+        if ( m_dll.IsLoaded() )
+        {
+            m_dll.Unload();
+        }
+    }
+
 private:
     wxDynamicLibrary m_dll;
     const wxChar *m_dllName;
 };
 
-static wxOnceOnlyDLLLoader wxGDI32DLL(_T("gdi32"));
 static wxOnceOnlyDLLLoader wxMSIMG32DLL(_T("msimg32"));
 
+// we must ensure that DLLs are unloaded before the static objects cleanup time
+// because we may hit the notorious DllMain() dead lock in this case if wx is
+// used as a DLL (attempting to unload another DLL from inside DllMain() hangs
+// under Windows because it tries to reacquire the same lock)
+class wxGDIDLLsCleanupModule : public wxModule
+{
+public:
+    virtual bool OnInit() { return true; }
+    virtual void OnExit() { wxMSIMG32DLL.Unload(); }
+
+private:
+    DECLARE_DYNAMIC_CLASS(wxGDIDLLsCleanupModule)
+};
+
+IMPLEMENT_DYNAMIC_CLASS(wxGDIDLLsCleanupModule, wxModule)
+
+#endif // wxUSE_DYNLIB_CLASS
+
 // ===========================================================================
 // implementation
 // ===========================================================================
@@ -993,7 +1020,7 @@ void wxDC::DoDrawEllipse(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
 }
 
 #if wxUSE_SPLINES
-void wxDC::DoDrawSpline(wxList *points)
+void wxDC::DoDrawSpline(const wxPointList *points)
 {
 #ifdef  __WXWINCE__
     // WinCE does not support ::PolyBezier so use generic version
@@ -1025,8 +1052,8 @@ void wxDC::DoDrawSpline(wxList *points)
     size_t bezier_pos = 0;
     wxCoord x1, y1, x2, y2, cx1, cy1, cx4, cy4;
 
-    wxList::compatibility_iterator node = points->GetFirst();
-    wxPoint *p = (wxPoint *)node->GetData();
+    wxPointList::compatibility_iterator node = points->GetFirst();
+    wxPoint *p = node->GetData();
     lppt[ bezier_pos ].x = x1 = p->x;
     lppt[ bezier_pos ].y = y1 = p->y;
     bezier_pos++;
@@ -1034,7 +1061,7 @@ void wxDC::DoDrawSpline(wxList *points)
     bezier_pos++;
 
     node = node->GetNext();
-    p = (wxPoint *)node->GetData();
+    p = node->GetData();
 
     x2 = p->x;
     y2 = p->y;
@@ -1118,6 +1145,17 @@ void wxDC::DoDrawEllipticArc(wxCoord x,wxCoord y,wxCoord w,wxCoord h,double sa,d
     rx2 += (int)(100.0 * abs(w) * cos(ea));
     ry2 -= (int)(100.0 * abs(h) * m_signY * sin(ea));
 
+    // Swap start and end positions if the end angle is less than the start angle.
+    if (ea < sa) {
+       int temp;
+       temp = rx2;
+       rx2 = rx1;
+       rx1 = temp;
+       temp = ry2;
+       ry2 = ry1;
+       ry1 = temp;
+    }
+
     // draw pie with NULL_PEN first and then outline otherwise a line is
     // drawn from the start and end points to the centre
     HPEN hpenOld = (HPEN) ::SelectObject(GetHdc(), (HPEN) ::GetStockObject(NULL_PEN));
@@ -2673,13 +2711,15 @@ void wxDC::DoGradientFillLinear (const wxRect& rect,
     wxDCBase::DoGradientFillLinear(rect, initialColour, destColour, nDirection);
 }
 
+#if wxUSE_DYNLIB_CLASS
+
 static DWORD wxGetDCLayout(HDC hdc)
 {
     typedef DWORD (WINAPI *GetLayout_t)(HDC);
     static GetLayout_t
-        pfnGetLayout = (GetLayout_t)wxGDI32DLL.GetSymbol(_T("GetLayout"));
+        wxDL_INIT_FUNC(s_pfn, GetLayout, wxDynamicLibrary(_T("gdi32.dll")));
 
-    return pfnGetLayout ? pfnGetLayout(hdc) : (DWORD)-1;
+    return s_pfnGetLayout ? s_pfnGetLayout(hdc) : (DWORD)-1;
 }
 
 wxLayoutDirection wxDC::GetLayoutDirection() const
@@ -2696,8 +2736,8 @@ void wxDC::SetLayoutDirection(wxLayoutDirection dir)
 {
     typedef DWORD (WINAPI *SetLayout_t)(HDC, DWORD);
     static SetLayout_t
-        pfnSetLayout = (SetLayout_t)wxGDI32DLL.GetSymbol(_T("SetLayout"));
-    if ( !pfnSetLayout )
+        wxDL_INIT_FUNC(s_pfn, SetLayout, wxDynamicLibrary(_T("gdi32.dll")));
+    if ( !s_pfnSetLayout )
         return;
 
     if ( dir == wxLayout_Default )
@@ -2713,5 +2753,19 @@ void wxDC::SetLayoutDirection(wxLayoutDirection dir)
     else
         layout &= ~LAYOUT_RTL;
 
-    pfnSetLayout(GetHdc(), layout);
+    s_pfnSetLayout(GetHdc(), layout);
+}
+
+#else // !wxUSE_DYNLIB_CLASS
+
+// we can't provide RTL support without dynamic loading, so stub it out
+wxLayoutDirection wxDC::GetLayoutDirection() const
+{
+    return wxLayout_Default;
 }
+
+void wxDC::SetLayoutDirection(wxLayoutDirection WXUNUSED(dir))
+{
+}
+
+#endif // wxUSE_DYNLIB_CLASS/!wxUSE_DYNLIB_CLASS