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