]>
git.saurik.com Git - wxWidgets.git/blob - src/msw/pen.cpp
fd70094b2530ff3ac7ac04280c09697168a6daf1
   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 
; 
  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
); 
  71     wxThePenList
->AddPen(this); 
  77         wxThePenList
->RemovePen(this); 
  80 // Should implement Create 
  81 wxPen::wxPen(const wxColour
& col
, int Width
, int Style
) 
  83   m_refData 
= new wxPenRefData
; 
  85   M_PENDATA
->m_colour 
= col
; 
  86 //  M_PENDATA->m_stipple = NULL; 
  87   M_PENDATA
->m_width 
= Width
; 
  88   M_PENDATA
->m_style 
= Style
; 
  89   M_PENDATA
->m_join 
= wxJOIN_ROUND 
; 
  90   M_PENDATA
->m_cap 
= wxCAP_ROUND 
; 
  91   M_PENDATA
->m_nbDash 
= 0 ; 
  92   M_PENDATA
->m_dash 
= 0 ; 
  93   M_PENDATA
->m_hPen 
= 0 ; 
  96   // In Windows, only a pen of width = 1 can be dotted or dashed! 
  97   if ((Style 
== wxDOT
) || (Style 
== wxLONG_DASH
) || 
  98       (Style 
== wxSHORT_DASH
) || (Style 
== wxDOT_DASH
) || 
  99       (Style 
== wxUSER_DASH
)) 
 100     M_PENDATA
->m_width 
= 1; 
 103   DWORD vers = GetVersion() ; 
 104   WORD  high = HIWORD(vers) ; // high bit=0 for NT, 1 for Win32s 
 105   // Win32s doesn't support wide dashed pens 
 107   if ((high&0x8000)!=0) 
 109   if (wxGetOsVersion()==wxWIN32S
) 
 111     // In Windows, only a pen of width = 1 can be dotted or dashed! 
 112     if ((Style 
== wxDOT
) || (Style 
== wxLONG_DASH
) || 
 113         (Style 
== wxSHORT_DASH
) || (Style 
== wxDOT_DASH
) || 
 114         (Style 
== wxUSER_DASH
)) 
 115       M_PENDATA
->m_width 
= 1; 
 121     wxThePenList
->AddPen(this); 
 124 wxPen::wxPen(const wxBitmap
& stipple
, int Width
) 
 126     m_refData 
= new wxPenRefData
; 
 128 //  M_PENDATA->m_colour = col; 
 129     M_PENDATA
->m_stipple 
= stipple
; 
 130     M_PENDATA
->m_width 
= Width
; 
 131     M_PENDATA
->m_style 
= wxSTIPPLE
; 
 132     M_PENDATA
->m_join 
= wxJOIN_ROUND 
; 
 133     M_PENDATA
->m_cap 
= wxCAP_ROUND 
; 
 134     M_PENDATA
->m_nbDash 
= 0 ; 
 135     M_PENDATA
->m_dash 
= 0 ; 
 136     M_PENDATA
->m_hPen 
= 0 ; 
 141        wxThePenList
->AddPen(this); 
 144 bool wxPen::RealizeResource() 
 146    if (M_PENDATA 
&& (M_PENDATA
->m_hPen 
== 0)) 
 148        if (M_PENDATA
->m_style
==wxTRANSPARENT
) 
 150            M_PENDATA
->m_hPen 
= (WXHPEN
) ::GetStockObject(NULL_PEN
); 
 154        COLORREF ms_colour 
= 0; 
 155        ms_colour 
= M_PENDATA
->m_colour
.GetPixel(); 
 157        // Join style, Cap style, Pen Stippling only on Win32. 
 158        // Currently no time to find equivalent on Win3.1, sorry 
 159        // [if such equiv exist!!] 
 161        if (M_PENDATA
->m_join
==wxJOIN_ROUND        
&& 
 162            M_PENDATA
->m_cap
==wxCAP_ROUND          
&& 
 163            M_PENDATA
->m_style
!=wxUSER_DASH        
&& 
 164            M_PENDATA
->m_style
!=wxSTIPPLE          
&& 
 165            M_PENDATA
->m_width 
<= 1) 
 168              (WXHPEN
) CreatePen( wx2msPenStyle(M_PENDATA
->m_style
), 
 174            DWORD ms_style 
= PS_GEOMETRIC 
| wx2msPenStyle(M_PENDATA
->m_style
); 
 176            switch(M_PENDATA
->m_join
) 
 178                case wxJOIN_BEVEL
: ms_style 
|= PS_JOIN_BEVEL
; break; 
 179                case wxJOIN_MITER
: ms_style 
|= PS_JOIN_MITER
; break; 
 181                case wxJOIN_ROUND
: ms_style 
|= PS_JOIN_ROUND
; break; 
 184            switch(M_PENDATA
->m_cap
) 
 186                case wxCAP_PROJECTING
: ms_style 
|= PS_ENDCAP_SQUARE
;  break; 
 187                case wxCAP_BUTT
:       ms_style 
|= PS_ENDCAP_FLAT
;    break; 
 189                case wxCAP_ROUND
:      ms_style 
|= PS_ENDCAP_ROUND
;   break; 
 194            switch(M_PENDATA
->m_style
) 
 197                    logb
.lbStyle 
= BS_PATTERN 
; 
 198                    if (M_PENDATA
->m_stipple
.Ok()) 
 199                        logb
.lbHatch 
= (LONG
)M_PENDATA
->m_stipple
.GetHBITMAP(); 
 201                        logb
.lbHatch 
= (LONG
)0; 
 203                case wxBDIAGONAL_HATCH
: 
 204                    logb
.lbStyle 
= BS_HATCHED
; 
 205                    logb
.lbHatch 
= HS_BDIAGONAL
; 
 207                case wxCROSSDIAG_HATCH
: 
 208                    logb
.lbStyle 
= BS_HATCHED
; 
 209                    logb
.lbHatch 
= HS_DIAGCROSS
; 
 211                case wxFDIAGONAL_HATCH
: 
 212                    logb
.lbStyle 
= BS_HATCHED
; 
 213                    logb
.lbHatch 
= HS_FDIAGONAL
; 
 216                    logb
.lbStyle 
= BS_HATCHED
; 
 217                    logb
.lbHatch 
= HS_CROSS
; 
 219                case wxHORIZONTAL_HATCH
: 
 220                    logb
.lbStyle 
= BS_HATCHED
; 
 221                    logb
.lbHatch 
= HS_HORIZONTAL
; 
 223                case wxVERTICAL_HATCH
: 
 224                    logb
.lbStyle 
= BS_HATCHED
; 
 225                    logb
.lbHatch 
= HS_VERTICAL
; 
 228                    logb
.lbStyle 
= BS_SOLID
; 
 230                    // this should be unnecessary (it's unused) but suppresses the Purigy 
 231                    // messages about uninitialized memory read 
 237            logb
.lbColor 
= ms_colour
; 
 240            if (M_PENDATA
->m_style
==wxUSER_DASH 
&& M_PENDATA
->m_nbDash 
&& M_PENDATA
->m_dash
) 
 242                real_dash 
= new wxDash
[M_PENDATA
->m_nbDash
]; 
 244                for (i
=0; i
<M_PENDATA
->m_nbDash
; i
++) 
 245                real_dash
[i
] = M_PENDATA
->m_dash
[i
] * M_PENDATA
->m_width
; 
 252            // Win32s doesn't have ExtCreatePen function... 
 253            if (wxGetOsVersion()==wxWINDOWS_NT 
|| wxGetOsVersion()==wxWIN95
) 
 256                  (WXHPEN
) ExtCreatePen( ms_style
, 
 259                                         M_PENDATA
->m_style
==wxUSER_DASH
 
 260                                           ? M_PENDATA
->m_nbDash
 
 262                                         (const DWORD
*)real_dash 
); 
 267                   (WXHPEN
) CreatePen( wx2msPenStyle(M_PENDATA
->m_style
), 
 277          (WXHPEN
) CreatePen( wx2msPenStyle(M_PENDATA
->m_style
), 
 281 #ifdef WXDEBUG_CREATE 
 282        if (M_PENDATA
->m_hPen
==0) 
 283            wxError("Cannot create pen","Internal error") ; 
 290 WXHANDLE 
wxPen::GetResourceHandle() 
 295                 return (WXHANDLE
)M_PENDATA
->m_hPen
; 
 298 bool wxPen::FreeResource(bool force
) 
 300   if (M_PENDATA 
&& (M_PENDATA
->m_hPen 
!= 0)) 
 302     DeleteObject((HPEN
) M_PENDATA
->m_hPen
); 
 303     M_PENDATA
->m_hPen 
= 0; 
 309 bool wxPen::IsFree() const 
 311   return (M_PENDATA 
&& M_PENDATA
->m_hPen 
== 0); 
 314 void wxPen::Unshare() 
 316         // Don't change shared data 
 319                 m_refData 
= new wxPenRefData(); 
 323                 wxPenRefData
* ref 
= new wxPenRefData(*(wxPenRefData
*)m_refData
); 
 329 void wxPen::SetColour(const wxColour
& col
) 
 333     M_PENDATA
->m_colour 
= col
; 
 338 void wxPen::SetColour(unsigned char r
, unsigned char g
, unsigned char b
) 
 342     M_PENDATA
->m_colour
.Set(r
, g
, b
); 
 347 void wxPen::SetWidth(int Width
) 
 351     M_PENDATA
->m_width 
= Width
; 
 356 void wxPen::SetStyle(int Style
) 
 360     M_PENDATA
->m_style 
= Style
; 
 365 void wxPen::SetStipple(const wxBitmap
& Stipple
) 
 369     M_PENDATA
->m_stipple 
= Stipple
; 
 370     M_PENDATA
->m_style 
= wxSTIPPLE
; 
 375 void wxPen::SetDashes(int nb_dashes
, const wxDash 
*Dash
) 
 379     M_PENDATA
->m_nbDash 
= nb_dashes
; 
 380     M_PENDATA
->m_dash 
= (wxDash 
*)Dash
; 
 385 void wxPen::SetJoin(int Join
) 
 389     M_PENDATA
->m_join 
= Join
; 
 394 void wxPen::SetCap(int Cap
) 
 398     M_PENDATA
->m_cap 
= Cap
; 
 403 int wx2msPenStyle(int wx_style
) 
 427            // Win32s doesn't have PS_USERSTYLE 
 428            if (wxGetOsVersion()==wxWINDOWS_NT 
|| wxGetOsVersion()==wxWIN95
) 
 429                cstyle 
= PS_USERSTYLE
; 
 431                cstyle 
= PS_DOT
; // We must make a choice... This is mine!