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" 
  22     #include "wx/msw/wrapcctl.h" // include <commctrl.h> "properly" 
  27 #include "wx/msw/private.h" 
  29 #include "wx/tabctrl.h" 
  30 #include "wx/msw/imaglist.h" 
  32 IMPLEMENT_DYNAMIC_CLASS(wxTabCtrl
, wxControl
) 
  33 IMPLEMENT_DYNAMIC_CLASS(wxTabEvent
, wxNotifyEvent
) 
  35 DEFINE_EVENT_TYPE(wxEVT_COMMAND_TAB_SEL_CHANGED
) 
  36 DEFINE_EVENT_TYPE(wxEVT_COMMAND_TAB_SEL_CHANGING
) 
  38 BEGIN_EVENT_TABLE(wxTabCtrl
, wxControl
) 
  39     EVT_SYS_COLOUR_CHANGED(wxTabCtrl::OnSysColourChanged
) 
  42 wxTabCtrl::wxTabCtrl() 
  47 bool wxTabCtrl::Create(wxWindow 
*parent
, wxWindowID id
, const wxPoint
& pos
, const wxSize
& size
, 
  48             long style
, const wxString
& name
) 
  52   m_backgroundColour 
= wxColour(GetRValue(GetSysColor(COLOR_BTNFACE
)), 
  53       GetGValue(GetSysColor(COLOR_BTNFACE
)), GetBValue(GetSysColor(COLOR_BTNFACE
))); 
  54   m_foregroundColour 
= *wxBLACK 
; 
  63   m_windowStyle 
= style
; 
  76   m_windowId 
= (id 
< 0 ? NewControlId() : id
); 
  78   long tabStyle 
= WS_CHILD 
| WS_VISIBLE
; 
  79   if (m_windowStyle 
& wxTC_MULTILINE
) 
  80     tabStyle 
|= TCS_MULTILINE
; 
  81   if (m_windowStyle 
& wxTC_RIGHTJUSTIFY
) 
  82     tabStyle 
|= TCS_RIGHTJUSTIFY
; 
  83   if (m_windowStyle 
& wxTC_FIXEDWIDTH
) 
  84     tabStyle 
|= TCS_FIXEDWIDTH
; 
  85   if (m_windowStyle 
& wxTC_OWNERDRAW
) 
  86     tabStyle 
|= TCS_OWNERDRAWFIXED
; 
  87   if (m_windowStyle 
& wxBORDER
) 
  88     tabStyle 
|= WS_BORDER
; 
  91   tabStyle 
|= TCS_TOOLTIPS
; 
  94   // Create the toolbar control. 
  95   HWND hWndTabCtrl 
= CreateWindowEx(0L,     // No extended styles. 
  96     WC_TABCONTROL
,                          // Class name for the tab control 
  97     wxEmptyString
,                          // No default text. 
  98     tabStyle
,    // Styles and defaults. 
  99     x
, y
, width
, height
,                    // Standard size and position. 
 100     (HWND
) parent
->GetHWND(),               // Parent window 
 101     (HMENU
)m_windowId
,                      // ID. 
 102     wxGetInstance(),                        // Current instance. 
 103     NULL 
);                                 // No class data. 
 105   m_hWnd 
= (WXHWND
) hWndTabCtrl
; 
 106   if (parent
) parent
->AddChild(this); 
 108   SubclassWin((WXHWND
) hWndTabCtrl
); 
 110   SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
)); 
 115 wxTabCtrl::~wxTabCtrl() 
 120 bool wxTabCtrl::MSWOnNotify(int idCtrl
, WXLPARAM lParam
, WXLPARAM 
*result
) 
 122     wxTabEvent 
event(wxEVT_NULL
, m_windowId
); 
 123     wxEventType eventType 
wxDUMMY_INITIALIZE(wxEVT_NULL
); 
 124     NMHDR
* hdr1 
= (NMHDR
*) lParam
; 
 125     switch ( hdr1
->code 
) 
 128             eventType 
= wxEVT_COMMAND_TAB_SEL_CHANGED
; 
 131         case TCN_SELCHANGING
: 
 132             eventType 
= wxEVT_COMMAND_TAB_SEL_CHANGING
; 
 139 //            if (!tool->m_shortHelpString.empty()) 
 140 //                ttText->lpszText = (char *) (const char *)tool->m_shortHelpString; 
 144             return wxControl::MSWOnNotify(idCtrl
, lParam
, result
); 
 147     event
.SetEventObject( this ); 
 148     event
.SetEventType(eventType
); 
 149     event
.SetInt(idCtrl
) ; 
 150     event
.SetSelection(idCtrl
); 
 152     return ProcessEvent(event
); 
 155 // Responds to colour changes, and passes event on to children. 
 156 void wxTabCtrl::OnSysColourChanged(wxSysColourChangedEvent
& event
) 
 158     m_backgroundColour 
= wxColour(GetRValue(GetSysColor(COLOR_BTNFACE
)), 
 159                                   GetGValue(GetSysColor(COLOR_BTNFACE
)), 
 160                                   GetBValue(GetSysColor(COLOR_BTNFACE
))); 
 164     // Propagate the event to the non-top-level children 
 165     wxWindow::OnSysColourChanged(event
); 
 169 bool wxTabCtrl::DeleteAllItems() 
 171     return ( TabCtrl_DeleteAllItems( (HWND
) GetHWND() ) != FALSE 
); 
 175 bool wxTabCtrl::DeleteItem(int item
) 
 177     return ( TabCtrl_DeleteItem( (HWND
) GetHWND(), item
) != FALSE 
); 
 181 int wxTabCtrl::GetSelection() const 
 183     return (int) TabCtrl_GetCurSel( (HWND
) GetHWND() ); 
 186 // Get the tab with the current keyboard focus 
 187 int wxTabCtrl::GetCurFocus() const 
 189     return (int) TabCtrl_GetCurFocus( (HWND
) GetHWND() ); 
 192 // Get the associated image list 
 193 wxImageList
* wxTabCtrl::GetImageList() const 
 198 // Get the number of items 
 199 int wxTabCtrl::GetItemCount() const 
 201     return (int) TabCtrl_GetItemCount( (HWND
) GetHWND() ); 
 204 // Get the rect corresponding to the tab 
 205 bool wxTabCtrl::GetItemRect(int item
, wxRect
& wxrect
) const 
 208     if ( !TabCtrl_GetItemRect( (HWND
) GetHWND(), item
, & rect
) ) 
 212         wxrect
.x 
= rect
.left
; wxrect
.y 
= rect
.top
; 
 213         wxrect
.width 
= rect
.right 
- rect
.left
; 
 214         wxrect
.height 
= rect
.bottom 
- rect
.top
; 
 219 // Get the number of rows 
 220 int wxTabCtrl::GetRowCount() const 
 222     return (int) TabCtrl_GetRowCount( (HWND
) GetHWND() ); 
 226 wxString 
wxTabCtrl::GetItemText(int item
) const 
 229     wxString 
str(wxEmptyString
); 
 231     tcItem
.mask 
= TCIF_TEXT
; 
 232     tcItem
.pszText 
= buf
; 
 233     tcItem
.cchTextMax 
= 256; 
 235     if (TabCtrl_GetItem( (HWND
) GetHWND(), item
, & tcItem
) ) 
 236         str 
= tcItem
.pszText
; 
 241 // Get the item image 
 242 int wxTabCtrl::GetItemImage(int item
) const 
 245     tcItem
.mask 
= TCIF_IMAGE
; 
 247     if (TabCtrl_GetItem( (HWND
) GetHWND(), item
, & tcItem
) ) 
 248         return tcItem
.iImage
; 
 254 void* wxTabCtrl::GetItemData(int item
) const 
 257     tcItem
.mask 
= TCIF_PARAM
; 
 259     if (TabCtrl_GetItem( (HWND
) GetHWND(), item
, & tcItem
) ) 
 260         return (void*) tcItem
.lParam
; 
 266 int wxTabCtrl::HitTest(const wxPoint
& pt
, long& flags
) 
 268     TC_HITTESTINFO hitTestInfo
; 
 269     hitTestInfo
.pt
.x 
= pt
.x
; 
 270     hitTestInfo
.pt
.y 
= pt
.y
; 
 271     int item 
= TabCtrl_HitTest( (HWND
) GetHWND(), & hitTestInfo 
) ; 
 274     if ((hitTestInfo
.flags 
& TCHT_NOWHERE
) == TCHT_NOWHERE
) 
 275         flags 
|= wxTAB_HITTEST_NOWHERE
; 
 276     if ((hitTestInfo
.flags 
& TCHT_ONITEMICON
) == TCHT_ONITEMICON
) 
 277         flags 
|= wxTAB_HITTEST_ONICON
; 
 278     if ((hitTestInfo
.flags 
& TCHT_ONITEMLABEL
) == TCHT_ONITEMLABEL
) 
 279         flags 
|= wxTAB_HITTEST_ONLABEL
; 
 285 bool wxTabCtrl::InsertItem(int item
, const wxString
& text
, int imageId
, void* data
) 
 289     tcItem
.mask 
= TCIF_PARAM
; 
 290     tcItem
.lParam 
= (long) data
; 
 293         tcItem
.mask 
|= TCIF_TEXT
; 
 294         wxStrcpy(buf
, (const wxChar
*) text
); 
 295         tcItem
.pszText 
= buf
; 
 296         tcItem
.cchTextMax 
= 256; 
 300         tcItem
.mask 
|= TCIF_IMAGE
; 
 301         tcItem
.iImage 
= imageId
; 
 304     return (TabCtrl_InsertItem( (HWND
) GetHWND(), item
, & tcItem
) != -1); 
 308 int wxTabCtrl::SetSelection(int item
) 
 310     return (int) TabCtrl_SetCurSel( (HWND
) GetHWND(), item 
); 
 313 // Set the image list 
 314 void wxTabCtrl::SetImageList(wxImageList
* imageList
) 
 316     m_imageList 
= imageList
; 
 317     (void) TabCtrl_SetImageList( (HWND
) GetHWND(), (HIMAGELIST
) imageList
->GetHIMAGELIST() ); 
 320 // Set the text for an item 
 321 bool wxTabCtrl::SetItemText(int item
, const wxString
& text
) 
 325     tcItem
.mask 
= TCIF_TEXT
; 
 326     wxStrcpy(buf
, (const wxChar
*) text
); 
 327     tcItem
.pszText 
= buf
; 
 328     tcItem
.cchTextMax 
= 256; 
 330     return ( TabCtrl_SetItem( (HWND
) GetHWND(), item
, & tcItem
) != 0 ); 
 333 // Set the image for an item 
 334 bool wxTabCtrl::SetItemImage(int item
, int image
) 
 337     tcItem
.mask 
= TCIF_IMAGE
; 
 338     tcItem
.iImage 
= image
; 
 340     return ( TabCtrl_SetItem( (HWND
) GetHWND(), item
, & tcItem
) != 0 ); 
 343 // Set the data for an item 
 344 bool wxTabCtrl::SetItemData(int item
, void* data
) 
 347     tcItem
.mask 
= TCIF_PARAM
; 
 348     tcItem
.lParam 
= (long) data
; 
 350     return ( TabCtrl_SetItem( (HWND
) GetHWND(), item
, & tcItem
) != 0 ); 
 353 // Set the size for a fixed-width tab control 
 354 void wxTabCtrl::SetItemSize(const wxSize
& size
) 
 356     TabCtrl_SetItemSize( (HWND
) GetHWND(), size
.x
, size
.y 
); 
 359 // Set the padding between tabs 
 360 void wxTabCtrl::SetPadding(const wxSize
& padding
) 
 362     TabCtrl_SetPadding( (HWND
) GetHWND(), padding
.x
, padding
.y 
); 
 366 // These are the default colors used to map the bitmap colors 
 367 // to the current system colors 
 369 #define BGR_BUTTONTEXT      (RGB(000,000,000))  // black 
 370 #define BGR_BUTTONSHADOW    (RGB(128,128,128))  // dark grey 
 371 #define BGR_BUTTONFACE      (RGB(192,192,192))  // bright grey 
 372 #define BGR_BUTTONHILIGHT   (RGB(255,255,255))  // white 
 373 #define BGR_BACKGROUNDSEL   (RGB(255,000,000))  // blue 
 374 #define BGR_BACKGROUND      (RGB(255,000,255))  // magenta 
 376 void wxMapBitmap(HBITMAP hBitmap
, int width
, int height
) 
 378   COLORMAP ColorMap
[] = { 
 379     {BGR_BUTTONTEXT
,    COLOR_BTNTEXT
},     // black 
 380     {BGR_BUTTONSHADOW
,  COLOR_BTNSHADOW
},   // dark grey 
 381     {BGR_BUTTONFACE
,    COLOR_BTNFACE
},     // bright grey 
 382     {BGR_BUTTONHILIGHT
, COLOR_BTNHIGHLIGHT
},// white 
 383     {BGR_BACKGROUNDSEL
, COLOR_HIGHLIGHT
},   // blue 
 384     {BGR_BACKGROUND
,    COLOR_WINDOW
}       // magenta 
 387   int NUM_MAPS 
= (sizeof(ColorMap
)/sizeof(COLORMAP
)); 
 389   for ( n 
= 0; n 
< NUM_MAPS
; n
++) 
 391     ColorMap
[n
].to 
= ::GetSysColor(ColorMap
[n
].to
); 
 395   HDC hdcMem 
= CreateCompatibleDC(NULL
); 
 399     hbmOld 
= SelectObject(hdcMem
, hBitmap
); 
 402     for ( i 
= 0; i 
< width
; i
++) 
 404         for ( j 
= 0; j 
< height
; j
++) 
 406             COLORREF pixel 
= ::GetPixel(hdcMem
, i
, j
); 
 408             BYTE red = GetRValue(pixel); 
 409             BYTE green = GetGValue(pixel); 
 410             BYTE blue = GetBValue(pixel); 
 413             for ( k 
= 0; k 
< NUM_MAPS
; k 
++) 
 415                 if ( ColorMap
[k
].from 
== pixel 
) 
 417                     /* COLORREF actualPixel = */ ::SetPixel(hdcMem
, i
, j
, ColorMap
[k
].to
); 
 425     SelectObject(hdcMem
, hbmOld
); 
 426     DeleteObject(hdcMem
); 
 432 #endif // wxUSE_TAB_DIALOG