]> git.saurik.com Git - wxWidgets.git/blame - src/msw/pen.cpp
Fix for bug #1422217. Menu items with the checked bitmap set need to
[wxWidgets.git] / src / msw / pen.cpp
CommitLineData
2bda0e17 1/////////////////////////////////////////////////////////////////////////////
46562151 2// Name: src/msw/pen.cpp
2bda0e17
KB
3// Purpose: wxPen
4// Author: Julian Smart
5// Modified by:
6// Created: 04/01/98
7// RCS-ID: $Id$
6c9a19aa 8// Copyright: (c) Julian Smart
65571936 9// Licence: wxWindows licence
2bda0e17
KB
10/////////////////////////////////////////////////////////////////////////////
11
2bda0e17
KB
12// For compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
14
15#ifdef __BORLANDC__
16#pragma hdrstop
17#endif
18
19#ifndef WX_PRECOMP
20#include <stdio.h>
2bda0e17
KB
21#include "wx/list.h"
22#include "wx/utils.h"
23#include "wx/app.h"
24#include "wx/pen.h"
25#endif
26
27#include "wx/msw/private.h"
2bda0e17 28
a6c81161 29static int wx2msPenStyle(int wx_style);
ef59847c 30
2bda0e17 31IMPLEMENT_DYNAMIC_CLASS(wxPen, wxGDIObject)
2bda0e17 32
e4a81a2e 33wxPenRefData::wxPenRefData()
2bda0e17 34{
2bda0e17
KB
35 m_style = wxSOLID;
36 m_width = 1;
37 m_join = wxJOIN_ROUND ;
38 m_cap = wxCAP_ROUND ;
39 m_nbDash = 0 ;
edd97174 40 m_dash = (wxDash*)NULL;
2bda0e17
KB
41 m_hPen = 0;
42}
43
b823f5a1 44wxPenRefData::wxPenRefData(const wxPenRefData& data)
04a18b0d 45 :wxGDIRefData()
b823f5a1
JS
46{
47 m_style = data.m_style;
48 m_width = data.m_width;
49 m_join = data.m_join;
50 m_cap = data.m_cap;
51 m_nbDash = data.m_nbDash;
52 m_dash = data.m_dash;
53 m_colour = data.m_colour;
54 m_hPen = 0;
55}
56
e4a81a2e 57wxPenRefData::~wxPenRefData()
2bda0e17 58{
8b0975a3
VZ
59 if ( m_hPen )
60 ::DeleteObject((HPEN) m_hPen);
2bda0e17
KB
61}
62
63// Pens
64
e4a81a2e 65wxPen::wxPen()
2bda0e17 66{
2bda0e17
KB
67}
68
69wxPen::~wxPen()
70{
2bda0e17
KB
71}
72
73// Should implement Create
debe6624 74wxPen::wxPen(const wxColour& col, int Width, int Style)
2bda0e17
KB
75{
76 m_refData = new wxPenRefData;
77
78 M_PENDATA->m_colour = col;
79// M_PENDATA->m_stipple = NULL;
80 M_PENDATA->m_width = Width;
81 M_PENDATA->m_style = Style;
82 M_PENDATA->m_join = wxJOIN_ROUND ;
83 M_PENDATA->m_cap = wxCAP_ROUND ;
84 M_PENDATA->m_nbDash = 0 ;
edd97174 85 M_PENDATA->m_dash = (wxDash*)NULL;
2bda0e17
KB
86 M_PENDATA->m_hPen = 0 ;
87
2bda0e17 88 RealizeResource();
2bda0e17
KB
89}
90
debe6624 91wxPen::wxPen(const wxBitmap& stipple, int Width)
2bda0e17 92{
c45a644e 93 m_refData = new wxPenRefData;
2bda0e17
KB
94
95// M_PENDATA->m_colour = col;
c45a644e
RR
96 M_PENDATA->m_stipple = stipple;
97 M_PENDATA->m_width = Width;
98 M_PENDATA->m_style = wxSTIPPLE;
99 M_PENDATA->m_join = wxJOIN_ROUND ;
100 M_PENDATA->m_cap = wxCAP_ROUND ;
101 M_PENDATA->m_nbDash = 0 ;
edd97174 102 M_PENDATA->m_dash = (wxDash*)NULL;
c45a644e 103 M_PENDATA->m_hPen = 0 ;
2bda0e17 104
c45a644e 105 RealizeResource();
2bda0e17
KB
106}
107
e4a81a2e 108bool wxPen::RealizeResource()
2bda0e17 109{
8b0975a3
VZ
110 if ( !M_PENDATA || M_PENDATA->m_hPen )
111 return false;
112
113 if (M_PENDATA->m_style==wxTRANSPARENT)
c45a644e 114 {
8b0975a3
VZ
115 M_PENDATA->m_hPen = (WXHPEN) ::GetStockObject(NULL_PEN);
116 return true;
117 }
118
119 static const int os = wxGetOsVersion();
120 COLORREF ms_colour = M_PENDATA->m_colour.GetPixel();
121
122 // Join style, Cap style, Pen Stippling
123#if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
124 // Only NT can display dashed or dotted lines with width > 1
125 if ( os != wxWINDOWS_NT &&
f3ebca94
VZ
126 (M_PENDATA->m_style == wxDOT ||
127 M_PENDATA->m_style == wxLONG_DASH ||
128 M_PENDATA->m_style == wxSHORT_DASH ||
129 M_PENDATA->m_style == wxDOT_DASH ||
130 M_PENDATA->m_style == wxUSER_DASH) &&
8b0975a3
VZ
131 M_PENDATA->m_width > 1 )
132 {
133 M_PENDATA->m_width = 1;
134 }
135
136 if (M_PENDATA->m_join==wxJOIN_ROUND &&
137 M_PENDATA->m_cap==wxCAP_ROUND &&
138 M_PENDATA->m_style!=wxUSER_DASH &&
139 M_PENDATA->m_style!=wxSTIPPLE &&
140 M_PENDATA->m_width <= 1)
141 {
142 M_PENDATA->m_hPen =
143 (WXHPEN) CreatePen( wx2msPenStyle(M_PENDATA->m_style),
144 M_PENDATA->m_width,
145 ms_colour );
146 }
147 else
148 {
149 DWORD ms_style = PS_GEOMETRIC | wx2msPenStyle(M_PENDATA->m_style);
150
151 switch(M_PENDATA->m_join)
c45a644e 152 {
8b0975a3
VZ
153 case wxJOIN_BEVEL: ms_style |= PS_JOIN_BEVEL; break;
154 case wxJOIN_MITER: ms_style |= PS_JOIN_MITER; break;
155 default:
156 case wxJOIN_ROUND: ms_style |= PS_JOIN_ROUND; break;
c45a644e
RR
157 }
158
8b0975a3 159 switch(M_PENDATA->m_cap)
c45a644e 160 {
8b0975a3
VZ
161 case wxCAP_PROJECTING: ms_style |= PS_ENDCAP_SQUARE; break;
162 case wxCAP_BUTT: ms_style |= PS_ENDCAP_FLAT; break;
163 default:
164 case wxCAP_ROUND: ms_style |= PS_ENDCAP_ROUND; break;
c45a644e 165 }
8b0975a3
VZ
166
167 LOGBRUSH logb;
168
169 switch(M_PENDATA->m_style)
c45a644e 170 {
8b0975a3
VZ
171 case wxSTIPPLE:
172 logb.lbStyle = BS_PATTERN ;
173 if (M_PENDATA->m_stipple.Ok())
174 logb.lbHatch = (LONG)M_PENDATA->m_stipple.GetHBITMAP();
175 else
176 logb.lbHatch = (LONG)0;
177 break;
178 case wxBDIAGONAL_HATCH:
179 logb.lbStyle = BS_HATCHED;
180 logb.lbHatch = HS_BDIAGONAL;
181 break;
182 case wxCROSSDIAG_HATCH:
183 logb.lbStyle = BS_HATCHED;
184 logb.lbHatch = HS_DIAGCROSS;
185 break;
186 case wxFDIAGONAL_HATCH:
187 logb.lbStyle = BS_HATCHED;
188 logb.lbHatch = HS_FDIAGONAL;
189 break;
190 case wxCROSS_HATCH:
191 logb.lbStyle = BS_HATCHED;
192 logb.lbHatch = HS_CROSS;
193 break;
194 case wxHORIZONTAL_HATCH:
195 logb.lbStyle = BS_HATCHED;
196 logb.lbHatch = HS_HORIZONTAL;
197 break;
198 case wxVERTICAL_HATCH:
199 logb.lbStyle = BS_HATCHED;
200 logb.lbHatch = HS_VERTICAL;
201 break;
202 default:
203 logb.lbStyle = BS_SOLID;
61ba49f2 204#ifdef __WXDEBUG__
8b0975a3
VZ
205 // this should be unnecessary (it's unused) but suppresses the Purify
206 // messages about uninitialized memory read
207 logb.lbHatch = 0;
61ba49f2 208#endif
8b0975a3 209 break;
c45a644e 210 }
8b0975a3
VZ
211
212 logb.lbColor = ms_colour;
213
214 wxMSWDash *real_dash;
215 if (M_PENDATA->m_style==wxUSER_DASH && M_PENDATA->m_nbDash && M_PENDATA->m_dash)
216 {
217 real_dash = new wxMSWDash[M_PENDATA->m_nbDash];
218 int rw = M_PENDATA->m_width > 1 ? M_PENDATA->m_width : 1;
219 for ( int i = 0; i < M_PENDATA->m_nbDash; i++ )
220 real_dash[i] = M_PENDATA->m_dash[i] * rw;
221 }
222 else
223 {
224 real_dash = (wxMSWDash*)NULL;
225 }
226
227 // Win32s doesn't have ExtCreatePen function...
228 if (os==wxWINDOWS_NT || os==wxWIN95)
229 {
230 M_PENDATA->m_hPen =
231 (WXHPEN) ExtCreatePen( ms_style,
232 M_PENDATA->m_width,
233 &logb,
234 M_PENDATA->m_style == wxUSER_DASH
235 ? M_PENDATA->m_nbDash
236 : 0,
237 (LPDWORD)real_dash );
238 }
239 else
240 {
241 M_PENDATA->m_hPen =
242 (WXHPEN) CreatePen( wx2msPenStyle(M_PENDATA->m_style),
243 M_PENDATA->m_width,
244 ms_colour );
245 }
246
247 delete [] real_dash;
248 }
249#else // WinCE
250 M_PENDATA->m_hPen =
251 (WXHPEN) CreatePen( wx2msPenStyle(M_PENDATA->m_style),
252 M_PENDATA->m_width,
253 ms_colour );
254#endif // !WinCE/WinCE
255
256 return true;
2bda0e17
KB
257}
258
2b5f62a0 259WXHANDLE wxPen::GetResourceHandle() const
2bda0e17 260{
92218ce6
WS
261 if ( !M_PENDATA )
262 return 0;
263 else
264 return (WXHANDLE)M_PENDATA->m_hPen;
2bda0e17
KB
265}
266
33ac7e6f 267bool wxPen::FreeResource(bool WXUNUSED(force))
2bda0e17 268{
92218ce6
WS
269 if (M_PENDATA && (M_PENDATA->m_hPen != 0))
270 {
271 DeleteObject((HPEN) M_PENDATA->m_hPen);
272 M_PENDATA->m_hPen = 0;
273 return true;
274 }
275 else return false;
2bda0e17
KB
276}
277
e4a81a2e 278bool wxPen::IsFree() const
2bda0e17 279{
92218ce6 280 return (M_PENDATA && M_PENDATA->m_hPen == 0);
2bda0e17 281}
2bda0e17 282
b823f5a1 283void wxPen::Unshare()
2bda0e17 284{
92218ce6
WS
285 // Don't change shared data
286 if (!m_refData)
b823f5a1 287 {
92218ce6
WS
288 m_refData = new wxPenRefData();
289 }
b823f5a1
JS
290 else
291 {
92218ce6
WS
292 wxPenRefData* ref = new wxPenRefData(*(wxPenRefData*)m_refData);
293 UnRef();
294 m_refData = ref;
295 }
2bda0e17
KB
296}
297
298void wxPen::SetColour(const wxColour& col)
299{
b823f5a1 300 Unshare();
2bda0e17 301
b823f5a1 302 M_PENDATA->m_colour = col;
bbd41262 303
2bda0e17
KB
304 RealizeResource();
305}
306
1a1498c0 307void wxPen::SetColour(unsigned char r, unsigned char g, unsigned char b)
2bda0e17 308{
b823f5a1 309 Unshare();
2bda0e17 310
b823f5a1 311 M_PENDATA->m_colour.Set(r, g, b);
bbd41262 312
2bda0e17
KB
313 RealizeResource();
314}
315
debe6624 316void wxPen::SetWidth(int Width)
2bda0e17 317{
b823f5a1 318 Unshare();
2bda0e17 319
b823f5a1 320 M_PENDATA->m_width = Width;
2bda0e17 321
2bda0e17
KB
322 RealizeResource();
323}
324
debe6624 325void wxPen::SetStyle(int Style)
2bda0e17 326{
b823f5a1 327 Unshare();
2bda0e17 328
b823f5a1 329 M_PENDATA->m_style = Style;
2bda0e17 330
2bda0e17
KB
331 RealizeResource();
332}
333
334void wxPen::SetStipple(const wxBitmap& Stipple)
335{
b823f5a1 336 Unshare();
2bda0e17 337
b823f5a1
JS
338 M_PENDATA->m_stipple = Stipple;
339 M_PENDATA->m_style = wxSTIPPLE;
bbd41262 340
2bda0e17
KB
341 RealizeResource();
342}
343
debe6624 344void wxPen::SetDashes(int nb_dashes, const wxDash *Dash)
2bda0e17 345{
b823f5a1 346 Unshare();
2bda0e17 347
b823f5a1 348 M_PENDATA->m_nbDash = nb_dashes;
edd97174 349 M_PENDATA->m_dash = (wxDash *)Dash;
bbd41262 350
2bda0e17
KB
351 RealizeResource();
352}
353
debe6624 354void wxPen::SetJoin(int Join)
2bda0e17 355{
b823f5a1 356 Unshare();
2bda0e17 357
b823f5a1 358 M_PENDATA->m_join = Join;
2bda0e17 359
2bda0e17
KB
360 RealizeResource();
361}
362
debe6624 363void wxPen::SetCap(int Cap)
2bda0e17 364{
b823f5a1 365 Unshare();
2bda0e17 366
b823f5a1 367 M_PENDATA->m_cap = Cap;
2bda0e17 368
2bda0e17
KB
369 RealizeResource();
370}
371
372int wx2msPenStyle(int wx_style)
373{
07505825 374#if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
c45a644e 375 switch (wx_style)
bbd41262 376 {
07505825
WS
377 case wxDOT:
378 return PS_DOT;
c45a644e 379
07505825
WS
380 case wxDOT_DASH:
381 return PS_DASHDOT;
382
383 case wxSHORT_DASH:
384 case wxLONG_DASH:
385 return PS_DASH;
386
387 case wxTRANSPARENT:
388 return PS_NULL;
389
390 case wxUSER_DASH:
391 // if (wxGetOsVersion()==wxWINDOWS_NT || wxGetOsVersion()==wxWIN95)
392 return PS_USERSTYLE;
393 }
2bda0e17 394#else
07505825 395 wxUnusedVar(wx_style);
2bda0e17 396#endif
07505825 397 return PS_SOLID;
2bda0e17 398}