]> git.saurik.com Git - wxWidgets.git/blob - src/msw/nonownedwnd.cpp
Correct erasing of background behind controls in a toolbar in wxMSW.
[wxWidgets.git] / src / msw / nonownedwnd.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/nonownedwnd.cpp
3 // Purpose: wxNonOwnedWindow implementation for MSW.
4 // Author: Vadim Zeitlin
5 // Created: 2011-10-09 (extracted from src/msw/toplevel.cpp)
6 // Copyright: (c) 2011 Vadim Zeitlin <vadim@wxwidgets.org>
7 // Licence: wxWindows licence
8 ///////////////////////////////////////////////////////////////////////////////
9
10 // ============================================================================
11 // declarations
12 // ============================================================================
13
14 // ----------------------------------------------------------------------------
15 // headers
16 // ----------------------------------------------------------------------------
17
18 // for compilers that support precompilation, includes "wx.h".
19 #include "wx/wxprec.h"
20
21 #ifdef __BORLANDC__
22 #pragma hdrstop
23 #endif
24
25 // This class can't be implemented and hence is not used under Win CE.
26 #ifndef __WXWINCE__
27
28 #ifndef WX_PRECOMP
29 #include "wx/dcclient.h"
30 #include "wx/frame.h" // Only for wxFRAME_SHAPED.
31 #include "wx/region.h"
32 #include "wx/msw/private.h"
33 #endif // WX_PRECOMP
34
35 #include "wx/nonownedwnd.h"
36
37 #if wxUSE_GRAPHICS_CONTEXT
38 #include "wx/msw/wrapgdip.h"
39 #include "wx/graphics.h"
40 #endif // wxUSE_GRAPHICS_CONTEXT
41
42 #include "wx/scopedptr.h"
43
44 // ============================================================================
45 // wxNonOwnedWindow implementation
46 // ============================================================================
47
48 bool wxNonOwnedWindow::DoClearShape()
49 {
50 if (::SetWindowRgn(GetHwnd(), NULL, TRUE) == 0)
51 {
52 wxLogLastError(wxT("SetWindowRgn"));
53 return false;
54 }
55
56 return true;
57 }
58
59 bool wxNonOwnedWindow::DoSetRegionShape(const wxRegion& region)
60 {
61 // Windows takes ownership of the region, so
62 // we'll have to make a copy of the region to give to it.
63 DWORD noBytes = ::GetRegionData(GetHrgnOf(region), 0, NULL);
64 RGNDATA *rgnData = (RGNDATA*) new char[noBytes];
65 ::GetRegionData(GetHrgnOf(region), noBytes, rgnData);
66 HRGN hrgn = ::ExtCreateRegion(NULL, noBytes, rgnData);
67 delete[] (char*) rgnData;
68
69 // SetWindowRgn expects the region to be in coordinates
70 // relative to the window, not the client area.
71 const wxPoint clientOrigin = GetClientAreaOrigin();
72 ::OffsetRgn(hrgn, -clientOrigin.x, -clientOrigin.y);
73
74 // Now call the shape API with the new region.
75 if (::SetWindowRgn(GetHwnd(), hrgn, TRUE) == 0)
76 {
77 wxLogLastError(wxT("SetWindowRgn"));
78 return false;
79 }
80 return true;
81 }
82
83 #if wxUSE_GRAPHICS_CONTEXT
84
85 #include "wx/msw/wrapgdip.h"
86
87 // This class contains data used only when SetPath(wxGraphicsPath) is called.
88 //
89 // Notice that it derives from wxEvtHandler solely to allow Connect()-ing its
90 // OnPaint() method to the window, we could get rid of this inheritance once
91 // Bind() can be used in wx sources.
92 class wxNonOwnedWindowShapeImpl : public wxEvtHandler
93 {
94 public:
95 wxNonOwnedWindowShapeImpl(wxNonOwnedWindow* win, const wxGraphicsPath& path) :
96 m_win(win),
97 m_path(path)
98 {
99 // Create the region corresponding to this path and set it as windows
100 // shape.
101 wxScopedPtr<wxGraphicsContext> context(wxGraphicsContext::Create(win));
102 Region gr(static_cast<GraphicsPath*>(m_path.GetNativePath()));
103 win->SetShape(
104 wxRegion(
105 gr.GetHRGN(static_cast<Graphics*>(context->GetNativeContext()))
106 )
107 );
108
109
110 // Connect to the paint event to draw the border.
111 //
112 // TODO: Do this only optionally?
113 m_win->Connect
114 (
115 wxEVT_PAINT,
116 wxPaintEventHandler(wxNonOwnedWindowShapeImpl::OnPaint),
117 NULL,
118 this
119 );
120 }
121
122 virtual ~wxNonOwnedWindowShapeImpl()
123 {
124 m_win->Disconnect
125 (
126 wxEVT_PAINT,
127 wxPaintEventHandler(wxNonOwnedWindowShapeImpl::OnPaint),
128 NULL,
129 this
130 );
131 }
132
133 private:
134 void OnPaint(wxPaintEvent& event)
135 {
136 event.Skip();
137
138 wxPaintDC dc(m_win);
139 wxScopedPtr<wxGraphicsContext> context(wxGraphicsContext::Create(dc));
140 context->SetPen(wxPen(*wxLIGHT_GREY, 2));
141 context->StrokePath(m_path);
142 }
143
144 wxNonOwnedWindow* const m_win;
145 wxGraphicsPath m_path;
146
147 wxDECLARE_NO_COPY_CLASS(wxNonOwnedWindowShapeImpl);
148 };
149
150 wxNonOwnedWindow::wxNonOwnedWindow()
151 {
152 m_shapeImpl = NULL;
153 }
154
155 wxNonOwnedWindow::~wxNonOwnedWindow()
156 {
157 delete m_shapeImpl;
158 }
159
160 bool wxNonOwnedWindow::DoSetPathShape(const wxGraphicsPath& path)
161 {
162 delete m_shapeImpl;
163 m_shapeImpl = new wxNonOwnedWindowShapeImpl(this, path);
164
165 return true;
166 }
167
168 #else // !wxUSE_GRAPHICS_CONTEXT
169
170 // Trivial ctor and dtor as we don't have anything to do when wxGraphicsContext
171 // is not used but still define them here to avoid adding even more #if checks
172 // to the header, it it doesn't do any harm even though it's not needed.
173 wxNonOwnedWindow::wxNonOwnedWindow()
174 {
175 }
176
177 wxNonOwnedWindow::~wxNonOwnedWindow()
178 {
179 }
180
181 #endif // wxUSE_GRAPHICS_CONTEXT/!wxUSE_GRAPHICS_CONTEXT
182
183 #endif // !__WXWINCE__