1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/msw/tabctrl.cpp 
   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" 
  26 #include "wx/msw/private.h" 
  28 // include <commctrl.h> "properly" 
  29 #include "wx/msw/wrapcctl.h" 
  31 #include "wx/tabctrl.h" 
  32 #include "wx/msw/imaglist.h" 
  34 IMPLEMENT_DYNAMIC_CLASS(wxTabCtrl
, wxControl
) 
  35 IMPLEMENT_DYNAMIC_CLASS(wxTabEvent
, wxNotifyEvent
) 
  37 DEFINE_EVENT_TYPE(wxEVT_COMMAND_TAB_SEL_CHANGED
) 
  38 DEFINE_EVENT_TYPE(wxEVT_COMMAND_TAB_SEL_CHANGING
) 
  40 BEGIN_EVENT_TABLE(wxTabCtrl
, wxControl
) 
  41     EVT_SYS_COLOUR_CHANGED(wxTabCtrl::OnSysColourChanged
) 
  44 wxTabCtrl::wxTabCtrl() 
  49 bool wxTabCtrl::Create(wxWindow 
*parent
, wxWindowID id
, const wxPoint
& pos
, const wxSize
& size
, 
  50             long style
, const wxString
& name
) 
  54   m_backgroundColour 
= wxColour(GetRValue(GetSysColor(COLOR_BTNFACE
)), 
  55       GetGValue(GetSysColor(COLOR_BTNFACE
)), GetBValue(GetSysColor(COLOR_BTNFACE
))); 
  56   m_foregroundColour 
= *wxBLACK 
; 
  65   m_windowStyle 
= style
; 
  78   m_windowId 
= (id 
< 0 ? NewControlId() : id
); 
  80   long tabStyle 
= WS_CHILD 
| WS_VISIBLE
; 
  81   if (m_windowStyle 
& wxTC_MULTILINE
) 
  82     tabStyle 
|= TCS_MULTILINE
; 
  83   if (m_windowStyle 
& wxTC_RIGHTJUSTIFY
) 
  84     tabStyle 
|= TCS_RIGHTJUSTIFY
; 
  85   if (m_windowStyle 
& wxTC_FIXEDWIDTH
) 
  86     tabStyle 
|= TCS_FIXEDWIDTH
; 
  87   if (m_windowStyle 
& wxTC_OWNERDRAW
) 
  88     tabStyle 
|= TCS_OWNERDRAWFIXED
; 
  89   if (m_windowStyle 
& wxBORDER
) 
  90     tabStyle 
|= WS_BORDER
; 
  93   tabStyle 
|= TCS_TOOLTIPS
; 
  96   // Create the toolbar control. 
  97   HWND hWndTabCtrl 
= CreateWindowEx(0L,     // No extended styles. 
  98     WC_TABCONTROL
,                          // Class name for the tab control 
  99     wxEmptyString
,                          // No default text. 
 100     tabStyle
,    // Styles and defaults. 
 101     x
, y
, width
, height
,                    // Standard size and position. 
 102     (HWND
) parent
->GetHWND(),               // Parent window 
 103     (HMENU
)m_windowId
,                      // ID. 
 104     wxGetInstance(),                        // Current instance. 
 105     NULL 
);                                 // No class data. 
 107   m_hWnd 
= (WXHWND
) hWndTabCtrl
; 
 108   if (parent
) parent
->AddChild(this); 
 110   SubclassWin((WXHWND
) hWndTabCtrl
); 
 112   SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
)); 
 117 wxTabCtrl::~wxTabCtrl() 
 122 bool wxTabCtrl::MSWOnNotify(int idCtrl
, WXLPARAM lParam
, WXLPARAM 
*result
) 
 124     wxTabEvent 
event(wxEVT_NULL
, m_windowId
); 
 125     wxEventType eventType 
wxDUMMY_INITIALIZE(wxEVT_NULL
); 
 126     NMHDR
* hdr1 
= (NMHDR
*) lParam
; 
 127     switch ( hdr1
->code 
) 
 130             eventType 
= wxEVT_COMMAND_TAB_SEL_CHANGED
; 
 133         case TCN_SELCHANGING
: 
 134             eventType 
= wxEVT_COMMAND_TAB_SEL_CHANGING
; 
 141 //            if (!tool->m_shortHelpString.empty()) 
 142 //                ttText->lpszText = (char *) (const char *)tool->m_shortHelpString; 
 146             return wxControl::MSWOnNotify(idCtrl
, lParam
, result
); 
 149     event
.SetEventObject( this ); 
 150     event
.SetEventType(eventType
); 
 151     event
.SetInt(idCtrl
) ; 
 152     event
.SetSelection(idCtrl
); 
 154     return ProcessEvent(event
); 
 157 // Responds to colour changes, and passes event on to children. 
 158 void wxTabCtrl::OnSysColourChanged(wxSysColourChangedEvent
& event
) 
 160     m_backgroundColour 
= wxColour(GetRValue(GetSysColor(COLOR_BTNFACE
)), 
 161                                   GetGValue(GetSysColor(COLOR_BTNFACE
)), 
 162                                   GetBValue(GetSysColor(COLOR_BTNFACE
))); 
 166     // Propagate the event to the non-top-level children 
 167     wxWindow::OnSysColourChanged(event
); 
 171 bool wxTabCtrl::DeleteAllItems() 
 173     return ( TabCtrl_DeleteAllItems( (HWND
) GetHWND() ) != FALSE 
); 
 177 bool wxTabCtrl::DeleteItem(int item
) 
 179     return ( TabCtrl_DeleteItem( (HWND
) GetHWND(), item
) != FALSE 
); 
 183 int wxTabCtrl::GetSelection() const 
 185     return (int) TabCtrl_GetCurSel( (HWND
) GetHWND() ); 
 188 // Get the tab with the current keyboard focus 
 189 int wxTabCtrl::GetCurFocus() const 
 191     return (int) TabCtrl_GetCurFocus( (HWND
) GetHWND() ); 
 194 // Get the associated image list 
 195 wxImageList
* wxTabCtrl::GetImageList() const 
 200 // Get the number of items 
 201 int wxTabCtrl::GetItemCount() const 
 203     return (int) TabCtrl_GetItemCount( (HWND
) GetHWND() ); 
 206 // Get the rect corresponding to the tab 
 207 bool wxTabCtrl::GetItemRect(int item
, wxRect
& wxrect
) const 
 210     if ( !TabCtrl_GetItemRect( (HWND
) GetHWND(), item
, & rect
) ) 
 214         wxrect
.x 
= rect
.left
; wxrect
.y 
= rect
.top
; 
 215         wxrect
.width 
= rect
.right 
- rect
.left
; 
 216         wxrect
.height 
= rect
.bottom 
- rect
.top
; 
 221 // Get the number of rows 
 222 int wxTabCtrl::GetRowCount() const 
 224     return (int) TabCtrl_GetRowCount( (HWND
) GetHWND() ); 
 228 wxString 
wxTabCtrl::GetItemText(int item
) const 
 231     wxString 
str(wxEmptyString
); 
 233     tcItem
.mask 
= TCIF_TEXT
; 
 234     tcItem
.pszText 
= buf
; 
 235     tcItem
.cchTextMax 
= 256; 
 237     if (TabCtrl_GetItem( (HWND
) GetHWND(), item
, & tcItem
) ) 
 238         str 
= tcItem
.pszText
; 
 243 // Get the item image 
 244 int wxTabCtrl::GetItemImage(int item
) const 
 247     tcItem
.mask 
= TCIF_IMAGE
; 
 249     if (TabCtrl_GetItem( (HWND
) GetHWND(), item
, & tcItem
) ) 
 250         return tcItem
.iImage
; 
 256 void* wxTabCtrl::GetItemData(int item
) const 
 259     tcItem
.mask 
= TCIF_PARAM
; 
 261     if (TabCtrl_GetItem( (HWND
) GetHWND(), item
, & tcItem
) ) 
 262         return (void*) tcItem
.lParam
; 
 268 int wxTabCtrl::HitTest(const wxPoint
& pt
, long& flags
) 
 270     TC_HITTESTINFO hitTestInfo
; 
 271     hitTestInfo
.pt
.x 
= pt
.x
; 
 272     hitTestInfo
.pt
.y 
= pt
.y
; 
 273     int item 
= TabCtrl_HitTest( (HWND
) GetHWND(), & hitTestInfo 
) ; 
 276     if ((hitTestInfo
.flags 
& TCHT_NOWHERE
) == TCHT_NOWHERE
) 
 277         flags 
|= wxTAB_HITTEST_NOWHERE
; 
 278     if ((hitTestInfo
.flags 
& TCHT_ONITEMICON
) == TCHT_ONITEMICON
) 
 279         flags 
|= wxTAB_HITTEST_ONICON
; 
 280     if ((hitTestInfo
.flags 
& TCHT_ONITEMLABEL
) == TCHT_ONITEMLABEL
) 
 281         flags 
|= wxTAB_HITTEST_ONLABEL
; 
 287 bool wxTabCtrl::InsertItem(int item
, const wxString
& text
, int imageId
, void* data
) 
 291     tcItem
.mask 
= TCIF_PARAM
; 
 292     tcItem
.lParam 
= (long) data
; 
 295         tcItem
.mask 
|= TCIF_TEXT
; 
 296         wxStrcpy(buf
, (const wxChar
*) text
); 
 297         tcItem
.pszText 
= buf
; 
 298         tcItem
.cchTextMax 
= 256; 
 302         tcItem
.mask 
|= TCIF_IMAGE
; 
 303         tcItem
.iImage 
= imageId
; 
 306     return (TabCtrl_InsertItem( (HWND
) GetHWND(), item
, & tcItem
) != -1); 
 310 int wxTabCtrl::SetSelection(int item
) 
 312     return (int) TabCtrl_SetCurSel( (HWND
) GetHWND(), item 
); 
 315 // Set the image list 
 316 void wxTabCtrl::SetImageList(wxImageList
* imageList
) 
 318     m_imageList 
= imageList
; 
 319     (void) TabCtrl_SetImageList( (HWND
) GetHWND(), (HIMAGELIST
) imageList
->GetHIMAGELIST() ); 
 322 // Set the text for an item 
 323 bool wxTabCtrl::SetItemText(int item
, const wxString
& text
) 
 327     tcItem
.mask 
= TCIF_TEXT
; 
 328     wxStrcpy(buf
, (const wxChar
*) text
); 
 329     tcItem
.pszText 
= buf
; 
 330     tcItem
.cchTextMax 
= 256; 
 332     return ( TabCtrl_SetItem( (HWND
) GetHWND(), item
, & tcItem
) != 0 ); 
 335 // Set the image for an item 
 336 bool wxTabCtrl::SetItemImage(int item
, int image
) 
 339     tcItem
.mask 
= TCIF_IMAGE
; 
 340     tcItem
.iImage 
= image
; 
 342     return ( TabCtrl_SetItem( (HWND
) GetHWND(), item
, & tcItem
) != 0 ); 
 345 // Set the data for an item 
 346 bool wxTabCtrl::SetItemData(int item
, void* data
) 
 349     tcItem
.mask 
= TCIF_PARAM
; 
 350     tcItem
.lParam 
= (long) data
; 
 352     return ( TabCtrl_SetItem( (HWND
) GetHWND(), item
, & tcItem
) != 0 ); 
 355 // Set the size for a fixed-width tab control 
 356 void wxTabCtrl::SetItemSize(const wxSize
& size
) 
 358     TabCtrl_SetItemSize( (HWND
) GetHWND(), size
.x
, size
.y 
); 
 361 // Set the padding between tabs 
 362 void wxTabCtrl::SetPadding(const wxSize
& padding
) 
 364     TabCtrl_SetPadding( (HWND
) GetHWND(), padding
.x
, padding
.y 
); 
 368 // These are the default colors used to map the bitmap colors 
 369 // to the current system colors 
 371 #define BGR_BUTTONTEXT      (RGB(000,000,000))  // black 
 372 #define BGR_BUTTONSHADOW    (RGB(128,128,128))  // dark grey 
 373 #define BGR_BUTTONFACE      (RGB(192,192,192))  // bright grey 
 374 #define BGR_BUTTONHILIGHT   (RGB(255,255,255))  // white 
 375 #define BGR_BACKGROUNDSEL   (RGB(255,000,000))  // blue 
 376 #define BGR_BACKGROUND      (RGB(255,000,255))  // magenta 
 378 void wxMapBitmap(HBITMAP hBitmap
, int width
, int height
) 
 380   COLORMAP ColorMap
[] = { 
 381     {BGR_BUTTONTEXT
,    COLOR_BTNTEXT
},     // black 
 382     {BGR_BUTTONSHADOW
,  COLOR_BTNSHADOW
},   // dark grey 
 383     {BGR_BUTTONFACE
,    COLOR_BTNFACE
},     // bright grey 
 384     {BGR_BUTTONHILIGHT
, COLOR_BTNHIGHLIGHT
},// white 
 385     {BGR_BACKGROUNDSEL
, COLOR_HIGHLIGHT
},   // blue 
 386     {BGR_BACKGROUND
,    COLOR_WINDOW
}       // magenta 
 389   int NUM_MAPS 
= (sizeof(ColorMap
)/sizeof(COLORMAP
)); 
 391   for ( n 
= 0; n 
< NUM_MAPS
; n
++) 
 393     ColorMap
[n
].to 
= ::GetSysColor(ColorMap
[n
].to
); 
 397   HDC hdcMem 
= CreateCompatibleDC(NULL
); 
 401     hbmOld 
= SelectObject(hdcMem
, hBitmap
); 
 404     for ( i 
= 0; i 
< width
; i
++) 
 406         for ( j 
= 0; j 
< height
; j
++) 
 408             COLORREF pixel 
= ::GetPixel(hdcMem
, i
, j
); 
 410             BYTE red = GetRValue(pixel); 
 411             BYTE green = GetGValue(pixel); 
 412             BYTE blue = GetBValue(pixel); 
 415             for ( k 
= 0; k 
< NUM_MAPS
; k 
++) 
 417                 if ( ColorMap
[k
].from 
== pixel 
) 
 419                     /* COLORREF actualPixel = */ ::SetPixel(hdcMem
, i
, j
, ColorMap
[k
].to
); 
 427     SelectObject(hdcMem
, hbmOld
); 
 428     DeleteObject(hdcMem
); 
 434 #endif // wxUSE_TAB_DIALOG