]>
git.saurik.com Git - wxWidgets.git/blob - src/msw/bmpbuttn.cpp
   1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/msw/bmpbuttn.cpp 
   3 // Purpose:     wxBitmapButton 
   4 // Author:      Julian Smart 
   8 // Copyright:   (c) Julian Smart 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // For compilers that support precompilation, includes "wx.h". 
  13 #include "wx/wxprec.h" 
  22     #include "wx/bmpbuttn.h" 
  24     #include "wx/dcmemory.h" 
  27 #include "wx/msw/private.h" 
  30 // ---------------------------------------------------------------------------- 
  32 // ---------------------------------------------------------------------------- 
  34 #if wxUSE_EXTENDED_RTTI 
  36 WX_DEFINE_FLAGS( wxBitmapButtonStyle 
) 
  38 wxBEGIN_FLAGS( wxBitmapButtonStyle 
) 
  39     // new style border flags, we put them first to 
  40     // use them for streaming out 
  41     wxFLAGS_MEMBER(wxBORDER_SIMPLE
) 
  42     wxFLAGS_MEMBER(wxBORDER_SUNKEN
) 
  43     wxFLAGS_MEMBER(wxBORDER_DOUBLE
) 
  44     wxFLAGS_MEMBER(wxBORDER_RAISED
) 
  45     wxFLAGS_MEMBER(wxBORDER_STATIC
) 
  46     wxFLAGS_MEMBER(wxBORDER_NONE
) 
  48     // old style border flags 
  49     wxFLAGS_MEMBER(wxSIMPLE_BORDER
) 
  50     wxFLAGS_MEMBER(wxSUNKEN_BORDER
) 
  51     wxFLAGS_MEMBER(wxDOUBLE_BORDER
) 
  52     wxFLAGS_MEMBER(wxRAISED_BORDER
) 
  53     wxFLAGS_MEMBER(wxSTATIC_BORDER
) 
  54     wxFLAGS_MEMBER(wxBORDER
) 
  56     // standard window styles 
  57     wxFLAGS_MEMBER(wxTAB_TRAVERSAL
) 
  58     wxFLAGS_MEMBER(wxCLIP_CHILDREN
) 
  59     wxFLAGS_MEMBER(wxTRANSPARENT_WINDOW
) 
  60     wxFLAGS_MEMBER(wxWANTS_CHARS
) 
  61     wxFLAGS_MEMBER(wxFULL_REPAINT_ON_RESIZE
) 
  62     wxFLAGS_MEMBER(wxALWAYS_SHOW_SB 
) 
  63     wxFLAGS_MEMBER(wxVSCROLL
) 
  64     wxFLAGS_MEMBER(wxHSCROLL
) 
  66     wxFLAGS_MEMBER(wxBU_AUTODRAW
) 
  67     wxFLAGS_MEMBER(wxBU_LEFT
) 
  68     wxFLAGS_MEMBER(wxBU_RIGHT
) 
  69     wxFLAGS_MEMBER(wxBU_TOP
) 
  70     wxFLAGS_MEMBER(wxBU_BOTTOM
) 
  71 wxEND_FLAGS( wxBitmapButtonStyle 
) 
  73 IMPLEMENT_DYNAMIC_CLASS_XTI(wxBitmapButton
, wxButton
,"wx/bmpbuttn.h") 
  75 wxBEGIN_PROPERTIES_TABLE(wxBitmapButton
) 
  76     wxPROPERTY_FLAGS( WindowStyle 
, wxBitmapButtonStyle 
, long , SetWindowStyleFlag 
, GetWindowStyleFlag 
, EMPTY_MACROVALUE
, 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style 
  77 wxEND_PROPERTIES_TABLE() 
  79 wxBEGIN_HANDLERS_TABLE(wxBitmapButton
) 
  80 wxEND_HANDLERS_TABLE() 
  82 wxCONSTRUCTOR_5( wxBitmapButton 
, wxWindow
* , Parent 
, wxWindowID 
, Id 
, wxBitmap 
, Bitmap 
, wxPoint 
, Position 
, wxSize 
, Size 
) 
  85 IMPLEMENT_DYNAMIC_CLASS(wxBitmapButton
, wxButton
) 
  88 BEGIN_EVENT_TABLE(wxBitmapButton
, wxBitmapButtonBase
) 
  89     EVT_SYS_COLOUR_CHANGED(wxBitmapButton::OnSysColourChanged
) 
  95 long "style" , wxBU_AUTODRAW 
 102 bool wxBitmapButton::Create(wxWindow 
*parent
, wxWindowID id
, 
 103     const wxBitmap
& bitmap
, 
 105     const wxSize
& size
, long style
, 
 106     const wxValidator
& wxVALIDATOR_PARAM(validator
), 
 107     const wxString
& name
) 
 109     m_bmpNormal 
= bitmap
; 
 113     SetValidator(validator
); 
 114 #endif // wxUSE_VALIDATORS 
 116     parent
->AddChild(this); 
 118     m_backgroundColour 
= parent
->GetBackgroundColour(); 
 119     m_foregroundColour 
= parent
->GetForegroundColour(); 
 120     m_windowStyle 
= style
; 
 122     if ( style 
& wxBU_AUTODRAW 
) 
 124         m_marginX 
= wxDEFAULT_BUTTON_MARGIN
; 
 125         m_marginY 
= wxDEFAULT_BUTTON_MARGIN
; 
 129         m_windowId 
= NewControlId(); 
 133     long msStyle 
= WS_VISIBLE 
| WS_TABSTOP 
| WS_CHILD 
| BS_OWNERDRAW 
; 
 135     if ( m_windowStyle 
& wxCLIP_SIBLINGS 
) 
 136         msStyle 
|= WS_CLIPSIBLINGS
; 
 139     if(m_windowStyle 
& wxBU_LEFT
) 
 141     if(m_windowStyle 
& wxBU_RIGHT
) 
 143     if(m_windowStyle 
& wxBU_TOP
) 
 145     if(m_windowStyle 
& wxBU_BOTTOM
) 
 146         msStyle 
|= BS_BOTTOM
; 
 149     m_hWnd 
= (WXHWND
) CreateWindowEx( 
 161     // Subclass again for purposes of dialog editing mode 
 170 bool wxBitmapButton::SetBackgroundColour(const wxColour
& colour
) 
 172     if ( !wxBitmapButtonBase::SetBackgroundColour(colour
) ) 
 178     // invalidate the brush, it will be recreated the next time it's needed 
 179     m_brushDisabled 
= wxNullBrush
; 
 184 void wxBitmapButton::OnSysColourChanged(wxSysColourChangedEvent
& event
) 
 186     m_brushDisabled 
= wxNullBrush
; 
 190         // this change affects our current state 
 197 // VZ: should be at the very least less than wxDEFAULT_BUTTON_MARGIN 
 198 #define FOCUS_MARGIN 3 
 200 bool wxBitmapButton::MSWOnDraw(WXDRAWITEMSTRUCT 
*item
) 
 203     long style 
= GetWindowLong((HWND
) GetHWND(), GWL_STYLE
); 
 204     if (style 
& BS_BITMAP
) 
 206         // Let default procedure draw the bitmap, which is defined 
 207         // in the Windows resource. 
 212     LPDRAWITEMSTRUCT lpDIS 
= (LPDRAWITEMSTRUCT
) item
; 
 213     HDC hDC                
= lpDIS
->hDC
; 
 214     UINT state             
= lpDIS
->itemState
; 
 215     bool isSelected        
= (state 
& ODS_SELECTED
) != 0; 
 216     bool autoDraw          
= (GetWindowStyleFlag() & wxBU_AUTODRAW
) != 0; 
 219     // choose the bitmap to use depending on the button state 
 222     if ( isSelected 
&& m_bmpSelected
.Ok() ) 
 223         bitmap 
= &m_bmpSelected
; 
 224     else if ((state 
& ODS_FOCUS
) && m_bmpFocus
.Ok()) 
 225         bitmap 
= &m_bmpFocus
; 
 226     else if ((state 
& ODS_DISABLED
) && m_bmpDisabled
.Ok()) 
 227         bitmap 
= &m_bmpDisabled
; 
 229         bitmap 
= &m_bmpNormal
; 
 234     // centre the bitmap in the control area 
 235     int x      
= lpDIS
->rcItem
.left
; 
 236     int y      
= lpDIS
->rcItem
.top
; 
 237     int width  
= lpDIS
->rcItem
.right 
- x
; 
 238     int height 
= lpDIS
->rcItem
.bottom 
- y
; 
 239     int wBmp   
= bitmap
->GetWidth(); 
 240     int hBmp   
= bitmap
->GetHeight(); 
 244     if(m_windowStyle 
& wxBU_LEFT
) 
 245         x1 
= x 
+ (FOCUS_MARGIN
+1); 
 246     else if(m_windowStyle 
& wxBU_RIGHT
) 
 247         x1 
= x 
+ (width 
- wBmp
) - (FOCUS_MARGIN
+1); 
 249         x1 
= x 
+ (width 
- wBmp
) / 2; 
 251     if(m_windowStyle 
& wxBU_TOP
) 
 252         y1 
= y 
+ (FOCUS_MARGIN
+1); 
 253     else if(m_windowStyle 
& wxBU_BOTTOM
) 
 254         y1 
= y 
+ (height 
- hBmp
) - (FOCUS_MARGIN
+1); 
 256         y1 
= y 
+ (height 
- hBmp
) / 2; 
 258     if ( isSelected 
&& autoDraw 
) 
 264     // draw the face, if auto-drawing 
 267         DrawFace((WXHDC
) hDC
, 
 268                  lpDIS
->rcItem
.left
, lpDIS
->rcItem
.top
, 
 269                  lpDIS
->rcItem
.right
, lpDIS
->rcItem
.bottom
, 
 275     dst
.SetHDC((WXHDC
) hDC
, false); 
 276     dst
.DrawBitmap(*bitmap
, x1
, y1
, true); 
 278     // draw focus / disabled state, if auto-drawing 
 279     if ( (state 
& ODS_DISABLED
) && autoDraw 
) 
 281         DrawButtonDisable((WXHDC
) hDC
, 
 282                           lpDIS
->rcItem
.left
, lpDIS
->rcItem
.top
, 
 283                           lpDIS
->rcItem
.right
, lpDIS
->rcItem
.bottom
, 
 286     else if ( (state 
& ODS_FOCUS
) && autoDraw 
) 
 288         DrawButtonFocus((WXHDC
) hDC
, 
 292                         lpDIS
->rcItem
.bottom
, 
 299 // GRG Feb/2000, support for bmp buttons with Win95/98 standard LNF 
 301 #if defined(__WIN95__) 
 303 void wxBitmapButton::DrawFace( WXHDC dc
, int left
, int top
, 
 304     int right
, int bottom
, bool sel 
) 
 313     // create needed pens and brush 
 314     penHiLight  
= CreatePen(PS_SOLID
, 0, GetSysColor(COLOR_3DHILIGHT
)); 
 315     penLight    
= CreatePen(PS_SOLID
, 0, GetSysColor(COLOR_3DLIGHT
)); 
 316     penShadow   
= CreatePen(PS_SOLID
, 0, GetSysColor(COLOR_3DSHADOW
)); 
 317     penDkShadow 
= CreatePen(PS_SOLID
, 0, GetSysColor(COLOR_3DDKSHADOW
)); 
 318     // brushFace   = CreateSolidBrush(GetSysColor(COLOR_BTNFACE)); 
 319     // Taking the background colour fits in better with 
 320     // Windows XP themes. 
 321     brushFace   
= CreateSolidBrush(m_backgroundColour
.m_pixel
); 
 323     // draw the rectangle 
 328     rect
.bottom 
= bottom
; 
 329     FillRect((HDC
) dc
, &rect
, brushFace
); 
 332     oldp 
= (HPEN
) SelectObject( (HDC
) dc
, sel
? penDkShadow 
: penHiLight
); 
 334     wxDrawLine((HDC
) dc
, left
, top
, right
-1, top
); 
 335     wxDrawLine((HDC
) dc
, left
, top
+1, left
, bottom
-1); 
 337     SelectObject( (HDC
) dc
, sel
? penShadow 
: penLight
); 
 338     wxDrawLine((HDC
) dc
, left
+1, top
+1, right
-2, top
+1); 
 339     wxDrawLine((HDC
) dc
, left
+1, top
+2, left
+1, bottom
-2); 
 341     SelectObject( (HDC
) dc
, sel
? penLight 
: penShadow
); 
 342     wxDrawLine((HDC
) dc
, left
+1, bottom
-2, right
-1, bottom
-2); 
 343     wxDrawLine((HDC
) dc
, right
-2, bottom
-3, right
-2, top
); 
 345     SelectObject( (HDC
) dc
, sel
? penHiLight 
: penDkShadow
); 
 346     wxDrawLine((HDC
) dc
, left
, bottom
-1, right
+2, bottom
-1); 
 347     wxDrawLine((HDC
) dc
, right
-1, bottom
-2, right
-1, top
-1); 
 349     // delete allocated resources 
 350     SelectObject((HDC
) dc
,oldp
); 
 351     DeleteObject(penHiLight
); 
 352     DeleteObject(penLight
); 
 353     DeleteObject(penShadow
); 
 354     DeleteObject(penDkShadow
); 
 355     DeleteObject(brushFace
); 
 360 void wxBitmapButton::DrawFace( WXHDC dc
, int left
, int top
, 
 361     int right
, int bottom
, bool sel 
) 
 369     // create needed pens and brush 
 370     penBorder 
= CreatePen(PS_SOLID
, 0, GetSysColor(COLOR_WINDOWFRAME
)); 
 371     penShadow 
= CreatePen(PS_SOLID
, 0, GetSysColor(COLOR_BTNSHADOW
)); 
 372     penLight  
= CreatePen(PS_SOLID
, 0, GetSysColor(COLOR_BTNHIGHLIGHT
)); 
 373     brushFace 
= CreateSolidBrush(COLOR_BTNFACE
); 
 375     // draw the rectangle 
 380     rect
.bottom 
= bottom
; 
 381     FillRect((HDC
) dc
, &rect
, brushFace
); 
 384     oldp 
= (HPEN
) SelectObject( (HDC
) dc
, penBorder
); 
 385     MoveToEx((HDC
) dc
,left
+1,top
,NULL
);LineTo((HDC
) dc
,right
-1,top
); 
 386     MoveToEx((HDC
) dc
,left
,top
+1,NULL
);LineTo((HDC
) dc
,left
,bottom
-1); 
 387     MoveToEx((HDC
) dc
,left
+1,bottom
-1,NULL
);LineTo((HDC
) dc
,right
-1,bottom
-1); 
 388     MoveToEx((HDC
) dc
,right
-1,top
+1,NULL
);LineTo((HDC
) dc
,right
-1,bottom
-1); 
 390     SelectObject( (HDC
) dc
, penShadow
); 
 393         MoveToEx((HDC
) dc
,left
+1    ,bottom
-2   ,NULL
); 
 394         LineTo((HDC
) dc
,  left
+1    ,top
+1); 
 395         LineTo((HDC
) dc
,  right
-2   ,top
+1); 
 399         MoveToEx((HDC
) dc
,left
+1    ,bottom
-2   ,NULL
); 
 400         LineTo((HDC
) dc
,  right
-2   ,bottom
-2); 
 401         LineTo((HDC
) dc
,  right
-2   ,top
); 
 403         MoveToEx((HDC
) dc
,left
+2    ,bottom
-3   ,NULL
); 
 404         LineTo((HDC
) dc
,  right
-3   ,bottom
-3); 
 405         LineTo((HDC
) dc
,  right
-3   ,top
+1); 
 407         SelectObject( (HDC
) dc
, penLight
); 
 409         MoveToEx((HDC
) dc
,left
+1    ,bottom
-2   ,NULL
); 
 410         LineTo((HDC
) dc
,  left
+1    ,top
+1); 
 411         LineTo((HDC
) dc
,  right
-2   ,top
+1); 
 414     // delete allocated resources 
 415     SelectObject((HDC
) dc
,oldp
); 
 416     DeleteObject(penBorder
); 
 417     DeleteObject(penLight
); 
 418     DeleteObject(penShadow
); 
 419     DeleteObject(brushFace
); 
 422 #endif // defined(__WIN95__) 
 425 void wxBitmapButton::DrawButtonFocus( WXHDC dc
, int left
, int top
, int right
, 
 426     int bottom
, bool WXUNUSED(sel
) ) 
 432     rect
.bottom 
= bottom
; 
 433     InflateRect( &rect
, - FOCUS_MARGIN
, - FOCUS_MARGIN 
); 
 435     // GRG: the focus rectangle should not move when the button is pushed! 
 438         OffsetRect( &rect, 1, 1 ); 
 441     DrawFocusRect( (HDC
) dc
, &rect 
); 
 445 wxBitmapButton::DrawButtonDisable( WXHDC dc
, 
 446                                    int left
, int top
, int right
, int bottom
, 
 449     if ( !m_brushDisabled
.Ok() ) 
 451         // draw a bitmap with two black and two background colour pixels 
 454         dc
.SelectObject(bmp
); 
 455         dc
.SetPen(*wxBLACK_PEN
); 
 458         dc
.SetPen(GetBackgroundColour()); 
 462         m_brushDisabled 
= wxBrush(bmp
); 
 465     SelectInHDC 
selectBrush((HDC
)dc
, GetHbrushOf(m_brushDisabled
)); 
 467     // ROP for "dest |= pattern" operation -- as it doesn't have a standard 
 468     // name, give it our own 
 469     static const DWORD PATTERNPAINT 
= 0xFA0089UL
; 
 475         right 
-= 2 * m_marginX
; 
 476         bottom 
-= 2 * m_marginY
; 
 479     ::PatBlt( (HDC
) dc
, left
, top
, right
, bottom
, PATTERNPAINT
); 
 482 void wxBitmapButton::SetDefault() 
 484     wxButton::SetDefault(); 
 487 wxSize 
wxBitmapButton::DoGetBestSize() const 
 489     if ( m_bmpNormal
.Ok() ) 
 491         wxSize 
best(m_bmpNormal
.GetWidth() + 2*m_marginX
, 
 492                       m_bmpNormal
.GetHeight() + 2*m_marginY
); 
 497     // no idea what our best size should be, defer to the base class 
 498     return wxBitmapButtonBase::DoGetBestSize(); 
 501 #endif // wxUSE_BMPBUTTON