+
+void wxMSWDCImpl::DoGradientFillLinear (const wxRect& rect,
+ const wxColour& initialColour,
+ const wxColour& destColour,
+ wxDirection nDirection)
+{
+ // use native function if we have compile-time support it and can load it
+ // during run-time (linking to it statically would make the program
+ // unusable on earlier Windows versions)
+#if defined(GRADIENT_FILL_RECT_H) && wxUSE_DYNLIB_CLASS
+ typedef BOOL
+ (WINAPI *GradientFill_t)(HDC, PTRIVERTEX, ULONG, PVOID, ULONG, ULONG);
+ static GradientFill_t pfnGradientFill =
+ (GradientFill_t)wxMSIMG32DLL.GetSymbol(_T("GradientFill"));
+
+ if ( pfnGradientFill )
+ {
+ GRADIENT_RECT grect;
+ grect.UpperLeft = 0;
+ grect.LowerRight = 1;
+
+ // invert colours direction if not filling from left-to-right or
+ // top-to-bottom
+ int firstVertex = nDirection == wxNORTH || nDirection == wxWEST ? 1 : 0;
+
+ // one vertex for upper left and one for upper-right
+ TRIVERTEX vertices[2];
+
+ vertices[0].x = rect.GetLeft();
+ vertices[0].y = rect.GetTop();
+ vertices[1].x = rect.GetRight()+1;
+ vertices[1].y = rect.GetBottom()+1;
+
+ vertices[firstVertex].Red = (COLOR16)(initialColour.Red() << 8);
+ vertices[firstVertex].Green = (COLOR16)(initialColour.Green() << 8);
+ vertices[firstVertex].Blue = (COLOR16)(initialColour.Blue() << 8);
+ vertices[firstVertex].Alpha = 0;
+ vertices[1 - firstVertex].Red = (COLOR16)(destColour.Red() << 8);
+ vertices[1 - firstVertex].Green = (COLOR16)(destColour.Green() << 8);
+ vertices[1 - firstVertex].Blue = (COLOR16)(destColour.Blue() << 8);
+ vertices[1 - firstVertex].Alpha = 0;
+
+ if ( (*pfnGradientFill)
+ (
+ GetHdc(),
+ vertices,
+ WXSIZEOF(vertices),
+ &grect,
+ 1,
+ nDirection == wxWEST || nDirection == wxEAST
+ ? GRADIENT_FILL_RECT_H
+ : GRADIENT_FILL_RECT_V
+ ) )
+ {
+ // skip call of the base class version below
+ return;
+ }
+
+ wxLogLastError(_T("GradientFill"));
+ }
+#endif // wxUSE_DYNLIB_CLASS
+
+ wxDCImpl::DoGradientFillLinear(rect, initialColour, destColour, nDirection);
+}
+
+#if wxUSE_DYNLIB_CLASS
+
+static DWORD wxGetDCLayout(HDC hdc)
+{
+ typedef DWORD (WINAPI *GetLayout_t)(HDC);
+ static GetLayout_t
+ wxDL_INIT_FUNC(s_pfn, GetLayout, wxDynamicLibrary(_T("gdi32.dll")));
+
+ return s_pfnGetLayout ? s_pfnGetLayout(hdc) : (DWORD)-1;
+}
+
+wxLayoutDirection wxMSWDCImpl::GetLayoutDirection() const
+{
+ DWORD layout = wxGetDCLayout(GetHdc());
+
+ if ( layout == (DWORD)-1 )
+ return wxLayout_Default;
+
+ return layout & LAYOUT_RTL ? wxLayout_RightToLeft : wxLayout_LeftToRight;
+}
+
+void wxMSWDCImpl::SetLayoutDirection(wxLayoutDirection dir)
+{
+ typedef DWORD (WINAPI *SetLayout_t)(HDC, DWORD);
+ static SetLayout_t
+ wxDL_INIT_FUNC(s_pfn, SetLayout, wxDynamicLibrary(_T("gdi32.dll")));
+ if ( !s_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;
+
+ s_pfnSetLayout(GetHdc(), layout);
+}
+
+#else // !wxUSE_DYNLIB_CLASS
+
+// we can't provide RTL support without dynamic loading, so stub it out
+wxLayoutDirection wxMSWDCImpl::GetLayoutDirection() const
+{
+ return wxLayout_Default;
+}
+
+void wxMSWDCImpl::SetLayoutDirection(wxLayoutDirection WXUNUSED(dir))
+{
+}
+
+#endif // wxUSE_DYNLIB_CLASS/!wxUSE_DYNLIB_CLASS