X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/82922a02d831317ca846f5d741863c676dc30c13..cb73e6001f891ae46b12a1e4ca39b93649cb6099:/src/msw/dc.cpp diff --git a/src/msw/dc.cpp b/src/msw/dc.cpp index 190526870a..2f2d0e54a5 100644 --- a/src/msw/dc.cpp +++ b/src/msw/dc.cpp @@ -17,7 +17,7 @@ // headers // --------------------------------------------------------------------------- -#ifdef __GNUG__ +#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) #pragma implementation "dc.h" #endif @@ -40,6 +40,8 @@ #include "wx/icon.h" #endif +#include "wx/msw/private.h" // needs to be before #include + #include "wx/sysopt.h" #include "wx/dcprint.h" #include "wx/module.h" @@ -52,8 +54,6 @@ #include #include -#include "wx/msw/private.h" // needs to be before #include - #if wxUSE_COMMON_DIALOGS && !defined(__WXMICROWIN__) #include #endif @@ -158,6 +158,8 @@ private: COLORREF m_colFgOld, m_colBgOld; bool m_changed; + + DECLARE_NO_COPY_CLASS(wxColourChanger) }; // this class saves the old stretch blit mode during its life time @@ -167,21 +169,27 @@ public: StretchBltModeChanger(HDC hdc, int mode) : m_hdc(hdc) { +#ifndef __WXWINCE__ m_modeOld = ::SetStretchBltMode(m_hdc, mode); if ( !m_modeOld ) wxLogLastError(_T("SetStretchBltMode")); +#endif } ~StretchBltModeChanger() { +#ifndef __WXWINCE__ if ( !::SetStretchBltMode(m_hdc, m_modeOld) ) wxLogLastError(_T("SetStretchBltMode")); +#endif } private: const HDC m_hdc; int m_modeOld; + + DECLARE_NO_COPY_CLASS(StretchBltModeChanger) }; // =========================================================================== @@ -374,7 +382,7 @@ void wxDC::SetClippingHrgn(WXHRGN hrgn) // note that we combine the new clipping region with the existing one: this // is compatible with what the other ports do and is the documented // behaviour now (starting with 2.3.3) -#ifdef __WIN16__ +#if defined(__WIN16__) || defined(__WXWINCE__) RECT rectClip; if ( !::GetClipBox(GetHdc(), &rectClip) ) return; @@ -510,7 +518,9 @@ void wxDC::Clear() rect.bottom = m_selectedBitmap.GetHeight(); } +#ifndef __WXWINCE__ (void) ::SetMapMode(GetHdc(), MM_TEXT); +#endif DWORD colour = ::GetBkColor(GetHdc()); HBRUSH brush = ::CreateSolidBrush(colour); @@ -520,15 +530,22 @@ void wxDC::Clear() int width = DeviceToLogicalXRel(VIEWPORT_EXTENT)*m_signX, height = DeviceToLogicalYRel(VIEWPORT_EXTENT)*m_signY; +#ifndef __WXWINCE__ ::SetMapMode(GetHdc(), MM_ANISOTROPIC); + ::SetViewportExtEx(GetHdc(), VIEWPORT_EXTENT, VIEWPORT_EXTENT, NULL); ::SetWindowExtEx(GetHdc(), width, height, NULL); ::SetViewportOrgEx(GetHdc(), (int)m_deviceOriginX, (int)m_deviceOriginY, NULL); ::SetWindowOrgEx(GetHdc(), (int)m_logicalOriginX, (int)m_logicalOriginY, NULL); +#endif } bool wxDC::DoFloodFill(wxCoord x, wxCoord y, const wxColour& col, int style) { +#ifdef __WXWINCE__ + return FALSE; +#else + #ifdef __WXMICROWIN__ if (!GetHDC()) return FALSE; #endif @@ -557,6 +574,7 @@ bool wxDC::DoFloodFill(wxCoord x, wxCoord y, const wxColour& col, int style) CalcBoundingBox(x, y); return success; +#endif } bool wxDC::DoGetPixel(wxCoord x, wxCoord y, wxColour *col) const @@ -586,11 +604,8 @@ void wxDC::DoCrossHair(wxCoord x, wxCoord y) wxCoord x2 = x+VIEWPORT_EXTENT; wxCoord y2 = y+VIEWPORT_EXTENT; - (void)MoveToEx(GetHdc(), XLOG2DEV(x1), YLOG2DEV(y), NULL); - (void)LineTo(GetHdc(), XLOG2DEV(x2), YLOG2DEV(y)); - - (void)MoveToEx(GetHdc(), XLOG2DEV(x), YLOG2DEV(y1), NULL); - (void)LineTo(GetHdc(), XLOG2DEV(x), YLOG2DEV(y2)); + wxDrawLine(GetHdc(), XLOG2DEV(x1), YLOG2DEV(y), XLOG2DEV(x2), YLOG2DEV(y)); + wxDrawLine(GetHdc(), XLOG2DEV(x), YLOG2DEV(y1), XLOG2DEV(x), YLOG2DEV(y2)); CalcBoundingBox(x1, y1); CalcBoundingBox(x2, y2); @@ -602,8 +617,7 @@ void wxDC::DoDrawLine(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2) if (!GetHDC()) return; #endif - (void)MoveToEx(GetHdc(), XLOG2DEV(x1), YLOG2DEV(y1), NULL); - (void)LineTo(GetHdc(), XLOG2DEV(x2), YLOG2DEV(y2)); + wxDrawLine(GetHdc(), XLOG2DEV(x1), YLOG2DEV(y1), XLOG2DEV(x2), YLOG2DEV(y2)); CalcBoundingBox(x1, y1); CalcBoundingBox(x2, y2); @@ -615,6 +629,15 @@ void wxDC::DoDrawArc(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2, wxCoord xc, wxCoord yc) { +#ifdef __WXWINCE__ + // Slower emulation since WinCE doesn't support Pie and Arc + double r = sqrt( (x1-xc)*(x1-xc) + (y1-yc)*(y1-yc) ); + double sa = acos((x1-xc)/r)/M_PI*180; // between 0 and 180 + if( y1>yc ) sa = -sa; // below center + double ea = atan2(yc-y2, x2-xc)/M_PI*180; + DoDrawEllipticArcRot( xc-r, yc-r, 2*r, 2*r, sa, ea ); +#else + #ifdef __WXMICROWIN__ if (!GetHDC()) return; #endif @@ -662,6 +685,7 @@ void wxDC::DoDrawArc(wxCoord x1, wxCoord y1, CalcBoundingBox(xc - r, yc - r); CalcBoundingBox(xc + r, yc + r); +#endif } void wxDC::DoDrawCheckMark(wxCoord x1, wxCoord y1, @@ -681,7 +705,11 @@ void wxDC::DoDrawCheckMark(wxCoord x1, wxCoord y1, rect.right = x2; rect.bottom = y2; +#ifdef __WXWINCE__ + DrawFrameControl(GetHdc(), &rect, DFC_BUTTON, DFCS_BUTTONCHECK); +#else DrawFrameControl(GetHdc(), &rect, DFC_MENU, DFCS_MENUCHECK); +#endif #else // Win16 // In WIN16, draw a cross HPEN blackPen = ::CreatePen(PS_SOLID, 1, RGB(0, 0, 0)); @@ -740,9 +768,13 @@ void wxDC::DoDrawPolygon(int n, wxPoint points[], wxCoord xoffset, wxCoord yoffs CalcBoundingBox(cpoints[i].x, cpoints[i].y); } +#ifndef __WXWINCE__ int prev = SetPolyFillMode(GetHdc(),fillStyle==wxODDEVEN_RULE?ALTERNATE:WINDING); +#endif (void)Polygon(GetHdc(), cpoints, n); +#ifndef __WXWINCE__ SetPolyFillMode(GetHdc(),prev); +#endif delete[] cpoints; } else @@ -751,9 +783,13 @@ void wxDC::DoDrawPolygon(int n, wxPoint points[], wxCoord xoffset, wxCoord yoffs for (i = 0; i < n; i++) CalcBoundingBox(points[i].x, points[i].y); +#ifndef __WXWINCE__ int prev = SetPolyFillMode(GetHdc(),fillStyle==wxODDEVEN_RULE?ALTERNATE:WINDING); +#endif (void)Polygon(GetHdc(), (POINT*) points, n); +#ifndef __WXWINCE__ SetPolyFillMode(GetHdc(),prev); +#endif } } @@ -889,6 +925,10 @@ void wxDC::DoDrawEllipse(wxCoord x, wxCoord y, wxCoord width, wxCoord height) // Chris Breeze 20/5/98: first implementation of DrawEllipticArc on Windows void wxDC::DoDrawEllipticArc(wxCoord x,wxCoord y,wxCoord w,wxCoord h,double sa,double ea) { +#ifdef __WXWINCE__ + DoDrawEllipticArcRot( x, y, w, h, sa, ea ); +#else + #ifdef __WXMICROWIN__ if (!GetHDC()) return; #endif @@ -932,6 +972,7 @@ void wxDC::DoDrawEllipticArc(wxCoord x,wxCoord y,wxCoord w,wxCoord h,double sa,d CalcBoundingBox(x, y); CalcBoundingBox(x2, y2); +#endif } void wxDC::DoDrawIcon(const wxIcon& icon, wxCoord x, wxCoord y) @@ -1122,11 +1163,19 @@ void wxDC::DrawAnyText(const wxString& text, wxCoord x, wxCoord y) SetBkMode(GetHdc(), m_backgroundMode == wxTRANSPARENT ? TRANSPARENT : OPAQUE); +#ifdef __WXWINCE__ + if ( ::ExtTextOut(GetHdc(), XLOG2DEV(x), YLOG2DEV(y), 0, NULL, + text.c_str(), text.length(), NULL) == 0 ) + { + wxLogLastError(wxT("TextOut")); + } +#else if ( ::TextOut(GetHdc(), XLOG2DEV(x), YLOG2DEV(y), text.c_str(), text.length()) == 0 ) { wxLogLastError(wxT("TextOut")); } +#endif // restore the old parameters (text foreground colour may be left because // it never is set to anything else, but background should remain @@ -1399,40 +1448,9 @@ void wxDC::SetBackground(const wxBrush& brush) m_backgroundBrush = brush; - if (!m_backgroundBrush.Ok()) - return; - - if (m_canvas) - { - bool customColours = TRUE; - // If we haven't specified wxUSER_COLOURS, don't allow the panel/dialog box to - // change background colours from the control-panel specified colours. - if (m_canvas->IsKindOf(CLASSINFO(wxWindow)) && ((m_canvas->GetWindowStyleFlag() & wxUSER_COLOURS) != wxUSER_COLOURS)) - customColours = FALSE; - - if (customColours) - { - if (m_backgroundBrush.GetStyle()==wxTRANSPARENT) - { - m_canvas->SetTransparent(TRUE); - } - else - { - // New behaviour, 10/2/99: setting the background brush of a DC - // doesn't affect the window background colour. However, - // I'm leaving in the transparency setting because it's needed by - // various controls (e.g. wxStaticText) to determine whether to draw - // transparently or not. TODO: maybe this should be a new function - // wxWindow::SetTransparency(). Should that apply to the child itself, or the - // parent? - // m_canvas->SetBackgroundColour(m_backgroundBrush.GetColour()); - m_canvas->SetTransparent(FALSE); - } - } - } - COLORREF new_color = m_backgroundBrush.GetColour().GetPixel(); + if ( m_backgroundBrush.Ok() ) { - (void)SetBkColor(GetHdc(), new_color); + (void)SetBkColor(GetHdc(), m_backgroundBrush.GetColour().GetPixel()); } } @@ -1648,6 +1666,7 @@ void wxDC::SetMapMode(int mode) // VZ: it seems very wasteful to always use MM_ANISOTROPIC when in 99% of // cases we could do with MM_TEXT and in the remaining 0.9% with // MM_ISOTROPIC (TODO!) +#ifndef __WXWINCE__ ::SetMapMode(GetHdc(), MM_ANISOTROPIC); int width = DeviceToLogicalXRel(VIEWPORT_EXTENT)*m_signX, @@ -1658,6 +1677,7 @@ void wxDC::SetMapMode(int mode) ::SetViewportOrgEx(GetHdc(), m_deviceOriginX, m_deviceOriginY, NULL); ::SetWindowOrgEx(GetHdc(), m_logicalOriginX, m_logicalOriginY, NULL); +#endif } void wxDC::SetUserScale(double x, double y) @@ -1666,6 +1686,7 @@ void wxDC::SetUserScale(double x, double y) if (!GetHDC()) return; #endif +#ifndef __WXWINCE__ if ( x == m_userScaleX && y == m_userScaleY ) return; @@ -1673,6 +1694,7 @@ void wxDC::SetUserScale(double x, double y) m_userScaleY = y; SetMapMode(m_mappingMode); +#endif } void wxDC::SetAxisOrientation(bool xLeftRight, bool yBottomUp) @@ -1681,6 +1703,7 @@ void wxDC::SetAxisOrientation(bool xLeftRight, bool yBottomUp) if (!GetHDC()) return; #endif +#ifndef __WXWINCE__ int signX = xLeftRight ? 1 : -1, signY = yBottomUp ? -1 : 1; @@ -1691,6 +1714,7 @@ void wxDC::SetAxisOrientation(bool xLeftRight, bool yBottomUp) SetMapMode(m_mappingMode); } +#endif } void wxDC::SetSystemScale(double x, double y) @@ -1699,6 +1723,7 @@ void wxDC::SetSystemScale(double x, double y) if (!GetHDC()) return; #endif +#ifndef __WXWINCE__ if ( x == m_scaleX && y == m_scaleY ) return; @@ -1706,6 +1731,7 @@ void wxDC::SetSystemScale(double x, double y) m_scaleY = y; SetMapMode(m_mappingMode); +#endif } void wxDC::SetLogicalOrigin(wxCoord x, wxCoord y) @@ -1714,6 +1740,7 @@ void wxDC::SetLogicalOrigin(wxCoord x, wxCoord y) if (!GetHDC()) return; #endif +#ifndef __WXWINCE__ if ( x == m_logicalOriginX && y == m_logicalOriginY ) return; @@ -1721,6 +1748,7 @@ void wxDC::SetLogicalOrigin(wxCoord x, wxCoord y) m_logicalOriginY = y; ::SetWindowOrgEx(GetHdc(), (int)m_logicalOriginX, (int)m_logicalOriginY, NULL); +#endif } void wxDC::SetDeviceOrigin(wxCoord x, wxCoord y) @@ -1729,6 +1757,7 @@ void wxDC::SetDeviceOrigin(wxCoord x, wxCoord y) if (!GetHDC()) return; #endif +#ifndef __WXWINCE__ if ( x == m_deviceOriginX && y == m_deviceOriginY ) return; @@ -1736,6 +1765,7 @@ void wxDC::SetDeviceOrigin(wxCoord x, wxCoord y) m_deviceOriginY = y; ::SetViewportOrgEx(GetHdc(), (int)m_deviceOriginX, (int)m_deviceOriginY, NULL); +#endif } // --------------------------------------------------------------------------- @@ -1981,6 +2011,9 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest, { // if we already have a DIB, draw it using StretchDIBits(), otherwise // use StretchBlt() if available and finally fall back to BitBlt() + + // FIXME: use appropriate WinCE functions +#ifndef __WXWINCE__ const int caps = ::GetDeviceCaps(GetHdc(), RASTERCAPS); if ( bmpSrc.Ok() && (caps & RC_STRETCHDIB) ) { @@ -2053,6 +2086,8 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest, success = TRUE; } } +#endif + // __WXWINCE__ } ::SetTextColor(GetHdc(), old_textground); @@ -2170,7 +2205,7 @@ wxDCCacheEntry::~wxDCCacheEntry() wxDCCacheEntry* wxDC::FindBitmapInCache(WXHDC dc, int w, int h) { int depth = ::GetDeviceCaps((HDC) dc, PLANES) * ::GetDeviceCaps((HDC) dc, BITSPIXEL); - wxNode* node = sm_bitmapCache.GetFirst(); + wxList::compatibility_iterator node = sm_bitmapCache.GetFirst(); while (node) { wxDCCacheEntry* entry = (wxDCCacheEntry*) node->GetData(); @@ -2206,7 +2241,7 @@ wxDCCacheEntry* wxDC::FindBitmapInCache(WXHDC dc, int w, int h) wxDCCacheEntry* wxDC::FindDCInCache(wxDCCacheEntry* notThis, WXHDC dc) { int depth = ::GetDeviceCaps((HDC) dc, PLANES) * ::GetDeviceCaps((HDC) dc, BITSPIXEL); - wxNode* node = sm_dcCache.GetFirst(); + wxList::compatibility_iterator node = sm_dcCache.GetFirst(); while (node) { wxDCCacheEntry* entry = (wxDCCacheEntry*) node->GetData(); @@ -2244,12 +2279,8 @@ void wxDC::AddToDCCache(wxDCCacheEntry* entry) void wxDC::ClearCache() { - sm_dcCache.DeleteContents(TRUE); - sm_dcCache.Clear(); - sm_dcCache.DeleteContents(FALSE); - sm_bitmapCache.DeleteContents(TRUE); - sm_bitmapCache.Clear(); - sm_bitmapCache.DeleteContents(FALSE); + WX_CLEAR_LIST(wxList, sm_dcCache); + WX_CLEAR_LIST(wxList, sm_bitmapCache); } // Clean up cache at app exit @@ -2280,7 +2311,7 @@ static bool AlphaBlt(HDC hdcDst, wxASSERT_MSG( hdcDst && hdcSrc, _T("AlphaBlt(): invalid HDC") ); // do we have AlphaBlend() and company in the headers? -#ifdef AC_SRC_OVER +#if defined(AC_SRC_OVER) && wxUSE_DYNLIB_CLASS // yes, now try to see if we have it during run-time typedef BOOL (WINAPI *AlphaBlend_t)(HDC,int,int,int,int, HDC,int,int,int,int,