]>
git.saurik.com Git - wxWidgets.git/blob - src/msw/pen.cpp
   1 ///////////////////////////////////////////////////////////////////////////// 
   4 // Author:      Julian Smart 
   8 // Copyright:   (c) Julian Smart and Markus Holzem 
   9 // Licence:     wxWindows license 
  10 ///////////////////////////////////////////////////////////////////////////// 
  13 #pragma implementation "pen.h" 
  16 // For compilers that support precompilation, includes "wx.h". 
  17 #include "wx/wxprec.h" 
  32 #include "wx/msw/private.h" 
  35 IMPLEMENT_DYNAMIC_CLASS(wxPen
, wxGDIObject
) 
  37 wxPenRefData::wxPenRefData() 
  41   m_join 
= wxJOIN_ROUND 
; 
  44   m_dash 
= (wxDash
*)NULL
; 
  48 wxPenRefData::wxPenRefData(const wxPenRefData
& data
) 
  50     m_style 
= data
.m_style
; 
  51     m_width 
= data
.m_width
; 
  54     m_nbDash 
= data
.m_nbDash
; 
  56     m_colour 
= data
.m_colour
; 
  60 wxPenRefData::~wxPenRefData() 
  63                 ::DeleteObject((HPEN
) m_hPen
); 
  76 // Should implement Create 
  77 wxPen::wxPen(const wxColour
& col
, int Width
, int Style
) 
  79   m_refData 
= new wxPenRefData
; 
  81   M_PENDATA
->m_colour 
= col
; 
  82 //  M_PENDATA->m_stipple = NULL; 
  83   M_PENDATA
->m_width 
= Width
; 
  84   M_PENDATA
->m_style 
= Style
; 
  85   M_PENDATA
->m_join 
= wxJOIN_ROUND 
; 
  86   M_PENDATA
->m_cap 
= wxCAP_ROUND 
; 
  87   M_PENDATA
->m_nbDash 
= 0 ; 
  88   M_PENDATA
->m_dash 
= (wxDash
*)NULL
; 
  89   M_PENDATA
->m_hPen 
= 0 ; 
  92   // In Windows, only a pen of width = 1 can be dotted or dashed! 
  93   if ((Style 
== wxDOT
) || (Style 
== wxLONG_DASH
) || 
  94       (Style 
== wxSHORT_DASH
) || (Style 
== wxDOT_DASH
) || 
  95       (Style 
== wxUSER_DASH
)) 
  96     M_PENDATA
->m_width 
= 1; 
  99   DWORD vers = GetVersion() ; 
 100   WORD  high = HIWORD(vers) ; // high bit=0 for NT, 1 for Win32s 
 101   // Win32s doesn't support wide dashed pens 
 103   if ((high&0x8000)!=0) 
 105   if (wxGetOsVersion()==wxWIN32S
) 
 107     // In Windows, only a pen of width = 1 can be dotted or dashed! 
 108     if ((Style 
== wxDOT
) || (Style 
== wxLONG_DASH
) || 
 109         (Style 
== wxSHORT_DASH
) || (Style 
== wxDOT_DASH
) || 
 110         (Style 
== wxUSER_DASH
)) 
 111       M_PENDATA
->m_width 
= 1; 
 118 wxPen::wxPen(const wxBitmap
& stipple
, int Width
) 
 120     m_refData 
= new wxPenRefData
; 
 122 //  M_PENDATA->m_colour = col; 
 123     M_PENDATA
->m_stipple 
= stipple
; 
 124     M_PENDATA
->m_width 
= Width
; 
 125     M_PENDATA
->m_style 
= wxSTIPPLE
; 
 126     M_PENDATA
->m_join 
= wxJOIN_ROUND 
; 
 127     M_PENDATA
->m_cap 
= wxCAP_ROUND 
; 
 128     M_PENDATA
->m_nbDash 
= 0 ; 
 129     M_PENDATA
->m_dash 
= (wxDash
*)NULL
; 
 130     M_PENDATA
->m_hPen 
= 0 ; 
 136 bool wxPen::RealizeResource() 
 138    if (M_PENDATA 
&& (M_PENDATA
->m_hPen 
== 0)) 
 140        if (M_PENDATA
->m_style
==wxTRANSPARENT
) 
 142            M_PENDATA
->m_hPen 
= (WXHPEN
) ::GetStockObject(NULL_PEN
); 
 146        COLORREF ms_colour 
= 0; 
 147        ms_colour 
= M_PENDATA
->m_colour
.GetPixel(); 
 149        // Join style, Cap style, Pen Stippling only on Win32. 
 150        // Currently no time to find equivalent on Win3.1, sorry 
 151        // [if such equiv exist!!] 
 152 #if defined(__WIN32__) && !defined(__WXMICROWIN__) 
 153        if (M_PENDATA
->m_join
==wxJOIN_ROUND        
&& 
 154            M_PENDATA
->m_cap
==wxCAP_ROUND          
&& 
 155            M_PENDATA
->m_style
!=wxUSER_DASH        
&& 
 156            M_PENDATA
->m_style
!=wxSTIPPLE          
&& 
 157            M_PENDATA
->m_width 
<= 1) 
 160              (WXHPEN
) CreatePen( wx2msPenStyle(M_PENDATA
->m_style
), 
 166            DWORD ms_style 
= PS_GEOMETRIC 
| wx2msPenStyle(M_PENDATA
->m_style
); 
 168            switch(M_PENDATA
->m_join
) 
 170                case wxJOIN_BEVEL
: ms_style 
|= PS_JOIN_BEVEL
; break; 
 171                case wxJOIN_MITER
: ms_style 
|= PS_JOIN_MITER
; break; 
 173                case wxJOIN_ROUND
: ms_style 
|= PS_JOIN_ROUND
; break; 
 176            switch(M_PENDATA
->m_cap
) 
 178                case wxCAP_PROJECTING
: ms_style 
|= PS_ENDCAP_SQUARE
;  break; 
 179                case wxCAP_BUTT
:       ms_style 
|= PS_ENDCAP_FLAT
;    break; 
 181                case wxCAP_ROUND
:      ms_style 
|= PS_ENDCAP_ROUND
;   break; 
 186            switch(M_PENDATA
->m_style
) 
 189                    logb
.lbStyle 
= BS_PATTERN 
; 
 190                    if (M_PENDATA
->m_stipple
.Ok()) 
 191                        logb
.lbHatch 
= (LONG
)M_PENDATA
->m_stipple
.GetHBITMAP(); 
 193                        logb
.lbHatch 
= (LONG
)0; 
 195                case wxBDIAGONAL_HATCH
: 
 196                    logb
.lbStyle 
= BS_HATCHED
; 
 197                    logb
.lbHatch 
= HS_BDIAGONAL
; 
 199                case wxCROSSDIAG_HATCH
: 
 200                    logb
.lbStyle 
= BS_HATCHED
; 
 201                    logb
.lbHatch 
= HS_DIAGCROSS
; 
 203                case wxFDIAGONAL_HATCH
: 
 204                    logb
.lbStyle 
= BS_HATCHED
; 
 205                    logb
.lbHatch 
= HS_FDIAGONAL
; 
 208                    logb
.lbStyle 
= BS_HATCHED
; 
 209                    logb
.lbHatch 
= HS_CROSS
; 
 211                case wxHORIZONTAL_HATCH
: 
 212                    logb
.lbStyle 
= BS_HATCHED
; 
 213                    logb
.lbHatch 
= HS_HORIZONTAL
; 
 215                case wxVERTICAL_HATCH
: 
 216                    logb
.lbStyle 
= BS_HATCHED
; 
 217                    logb
.lbHatch 
= HS_VERTICAL
; 
 220                    logb
.lbStyle 
= BS_SOLID
; 
 222                    // this should be unnecessary (it's unused) but suppresses the Purigy 
 223                    // messages about uninitialized memory read 
 229            logb
.lbColor 
= ms_colour
; 
 231            wxMSWDash 
*real_dash
; 
 232            if (M_PENDATA
->m_style
==wxUSER_DASH 
&& M_PENDATA
->m_nbDash 
&& M_PENDATA
->m_dash
) 
 234                real_dash 
= new wxMSWDash
[M_PENDATA
->m_nbDash
]; 
 235                for ( int i 
= 0; i 
< M_PENDATA
->m_nbDash
; i
++ ) 
 236                    real_dash
[i
] = M_PENDATA
->m_dash
[i
] * M_PENDATA
->m_width
; 
 240                real_dash 
= (wxMSWDash
*)NULL
; 
 243            // Win32s doesn't have ExtCreatePen function... 
 244            if (wxGetOsVersion()==wxWINDOWS_NT 
|| wxGetOsVersion()==wxWIN95
) 
 247                  (WXHPEN
) ExtCreatePen( ms_style
, 
 250                                         M_PENDATA
->m_style 
== wxUSER_DASH
 
 251                                           ? M_PENDATA
->m_nbDash
 
 253                                         (LPDWORD
)real_dash 
); 
 258                   (WXHPEN
) CreatePen( wx2msPenStyle(M_PENDATA
->m_style
), 
 268          (WXHPEN
) CreatePen( wx2msPenStyle(M_PENDATA
->m_style
), 
 272 #ifdef WXDEBUG_CREATE 
 273        if (M_PENDATA
->m_hPen
==0) 
 274            wxError("Cannot create pen","Internal error") ; 
 281 WXHANDLE 
wxPen::GetResourceHandle() 
 286                 return (WXHANDLE
)M_PENDATA
->m_hPen
; 
 289 bool wxPen::FreeResource(bool WXUNUSED(force
)) 
 291   if (M_PENDATA 
&& (M_PENDATA
->m_hPen 
!= 0)) 
 293     DeleteObject((HPEN
) M_PENDATA
->m_hPen
); 
 294     M_PENDATA
->m_hPen 
= 0; 
 300 bool wxPen::IsFree() const 
 302   return (M_PENDATA 
&& M_PENDATA
->m_hPen 
== 0); 
 305 void wxPen::Unshare() 
 307         // Don't change shared data 
 310                 m_refData 
= new wxPenRefData(); 
 314                 wxPenRefData
* ref 
= new wxPenRefData(*(wxPenRefData
*)m_refData
); 
 320 void wxPen::SetColour(const wxColour
& col
) 
 324     M_PENDATA
->m_colour 
= col
; 
 329 void wxPen::SetColour(unsigned char r
, unsigned char g
, unsigned char b
) 
 333     M_PENDATA
->m_colour
.Set(r
, g
, b
); 
 338 void wxPen::SetWidth(int Width
) 
 342     M_PENDATA
->m_width 
= Width
; 
 347 void wxPen::SetStyle(int Style
) 
 351     M_PENDATA
->m_style 
= Style
; 
 356 void wxPen::SetStipple(const wxBitmap
& Stipple
) 
 360     M_PENDATA
->m_stipple 
= Stipple
; 
 361     M_PENDATA
->m_style 
= wxSTIPPLE
; 
 366 void wxPen::SetDashes(int nb_dashes
, const wxDash 
*Dash
) 
 370     M_PENDATA
->m_nbDash 
= nb_dashes
; 
 371     M_PENDATA
->m_dash 
= (wxDash 
*)Dash
; 
 376 void wxPen::SetJoin(int Join
) 
 380     M_PENDATA
->m_join 
= Join
; 
 385 void wxPen::SetCap(int Cap
) 
 389     M_PENDATA
->m_cap 
= Cap
; 
 394 int wx2msPenStyle(int wx_style
) 
 399 #if !defined(__WXMICROWIN__) 
 419 #if !defined(__WXMICROWIN__) 
 421            // Win32s doesn't have PS_USERSTYLE 
 422            if (wxGetOsVersion()==wxWINDOWS_NT 
|| wxGetOsVersion()==wxWIN95
) 
 423                cstyle 
= PS_USERSTYLE
; 
 425                cstyle 
= PS_DOT
; // We must make a choice... This is mine!