]> git.saurik.com Git - wxWidgets.git/blame - src/msw/tabctrl.cpp
process CBN_SELENDOK and not only CBN_SELCHANGE (patch 1083907)
[wxWidgets.git] / src / msw / tabctrl.cpp
CommitLineData
2bda0e17
KB
1/////////////////////////////////////////////////////////////////////////////
2// Name: tabctrl.cpp
3// Purpose: wxTabCtrl
4// Author: Julian Smart
5// Modified by:
6// Created: 04/01/98
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart
65571936 9// Licence: wxWindows licence
2bda0e17
KB
10/////////////////////////////////////////////////////////////////////////////
11
14f355c2 12#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
2bda0e17
KB
13#pragma implementation "tabctrl.h"
14#endif
15
16// For compilers that support precompilation, includes "wx.h".
17#include "wx/wxprec.h"
18
19#ifdef __BORLANDC__
20#pragma hdrstop
21#endif
22
23#ifndef WX_PRECOMP
2432b92d 24#include "wx/wx.h"
2bda0e17
KB
25#endif
26
27#if defined(__WIN95__)
28
4676948b 29#include "wx/msw/private.h"
2bda0e17 30
b39dbf34 31#if defined(__WIN95__) && !(defined(__GNUWIN32_OLD__) && !defined(__CYGWIN10__))
c42404a5
VZ
32 #include <commctrl.h>
33#else
34 #include "wx/msw/gnuwin32/extra.h"
65fd5cb0 35#endif
2bda0e17 36
186ef90c 37#include "wx/tabctrl.h"
2bda0e17 38#include "wx/app.h"
2bda0e17
KB
39#include "wx/msw/imaglist.h"
40
2bda0e17 41IMPLEMENT_DYNAMIC_CLASS(wxTabCtrl, wxControl)
2b5f62a0 42IMPLEMENT_DYNAMIC_CLASS(wxTabEvent, wxNotifyEvent)
2bda0e17 43
2e4df4bf
VZ
44DEFINE_EVENT_TYPE(wxEVT_COMMAND_TAB_SEL_CHANGED)
45DEFINE_EVENT_TYPE(wxEVT_COMMAND_TAB_SEL_CHANGING)
46
2bda0e17 47BEGIN_EVENT_TABLE(wxTabCtrl, wxControl)
2bda0e17
KB
48 EVT_SYS_COLOUR_CHANGED(wxTabCtrl::OnSysColourChanged)
49END_EVENT_TABLE()
2bda0e17 50
ee4f8c2a 51wxTabCtrl::wxTabCtrl()
2bda0e17
KB
52{
53 m_imageList = NULL;
54}
55
ee4f8c2a
JS
56bool wxTabCtrl::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
57 long style, const wxString& name)
2bda0e17
KB
58{
59 m_imageList = NULL;
60
61 m_backgroundColour = wxColour(GetRValue(GetSysColor(COLOR_BTNFACE)),
42e69d6b 62 GetGValue(GetSysColor(COLOR_BTNFACE)), GetBValue(GetSysColor(COLOR_BTNFACE)));
2bda0e17
KB
63 m_foregroundColour = *wxBLACK ;
64
2bda0e17
KB
65 SetName(name);
66
67 int x = pos.x;
68 int y = pos.y;
69 int width = size.x;
70 int height = size.y;
71
72 m_windowStyle = style;
73
2bda0e17
KB
74 SetParent(parent);
75
2bda0e17
KB
76 if (width <= 0)
77 width = 100;
78 if (height <= 0)
79 height = 30;
80 if (x < 0)
81 x = 0;
82 if (y < 0)
83 y = 0;
84
85 m_windowId = (id < 0 ? NewControlId() : id);
86
96df9ed9 87 long tabStyle = WS_CHILD | WS_VISIBLE;
2bda0e17
KB
88 if (m_windowStyle & wxTC_MULTILINE)
89 tabStyle |= TCS_MULTILINE;
90 if (m_windowStyle & wxTC_RIGHTJUSTIFY)
91 tabStyle |= TCS_RIGHTJUSTIFY;
92 if (m_windowStyle & wxTC_FIXEDWIDTH)
93 tabStyle |= TCS_FIXEDWIDTH;
94 if (m_windowStyle & wxTC_OWNERDRAW)
95 tabStyle |= TCS_OWNERDRAWFIXED;
2b5f62a0
VZ
96 if (m_windowStyle & wxBORDER)
97 tabStyle |= WS_BORDER;
2bda0e17 98
4676948b 99#ifndef __WXWINCE__
2bda0e17 100 tabStyle |= TCS_TOOLTIPS;
4676948b 101#endif
2bda0e17
KB
102
103 // Create the toolbar control.
104 HWND hWndTabCtrl = CreateWindowEx(0L, // No extended styles.
105 WC_TABCONTROL, // Class name for the tab control
fda7962d 106 wxEmptyString, // No default text.
2b5f62a0 107 tabStyle, // Styles and defaults.
2bda0e17
KB
108 x, y, width, height, // Standard size and position.
109 (HWND) parent->GetHWND(), // Parent window
110 (HMENU)m_windowId, // ID.
111 wxGetInstance(), // Current instance.
112 NULL ); // No class data.
113
114 m_hWnd = (WXHWND) hWndTabCtrl;
115 if (parent) parent->AddChild(this);
bfbb0b4c 116
2bda0e17
KB
117 SubclassWin((WXHWND) hWndTabCtrl);
118
2b5f62a0
VZ
119 SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
120
bfbb0b4c 121 return true;
2bda0e17
KB
122}
123
ee4f8c2a 124wxTabCtrl::~wxTabCtrl()
2bda0e17
KB
125{
126 UnsubclassWin();
127}
128
a23fd0e1 129bool wxTabCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
2bda0e17 130{
42e69d6b 131 wxTabEvent event(wxEVT_NULL, m_windowId);
5cb598ae 132 wxEventType eventType wxDUMMY_INITIALIZE(wxEVT_NULL);
42e69d6b
VZ
133 NMHDR* hdr1 = (NMHDR*) lParam;
134 switch ( hdr1->code )
135 {
136 case TCN_SELCHANGE:
137 eventType = wxEVT_COMMAND_TAB_SEL_CHANGED;
138 break;
139
140 case TCN_SELCHANGING:
141 eventType = wxEVT_COMMAND_TAB_SEL_CHANGING;
142 break;
fd3f686c 143
4676948b 144#ifndef __WXWINCE__
2bda0e17
KB
145 case TTN_NEEDTEXT:
146 {
147 // TODO
f31a4098 148// if (!tool->m_shortHelpString.empty())
2bda0e17 149// ttText->lpszText = (char *) (const char *)tool->m_shortHelpString;
2bda0e17 150 }
4676948b 151#endif
42e69d6b
VZ
152 default :
153 return wxControl::MSWOnNotify(idCtrl, lParam, result);
154 }
2bda0e17 155
42e69d6b
VZ
156 event.SetEventObject( this );
157 event.SetEventType(eventType);
158 event.SetInt(idCtrl) ;
2b5f62a0 159 event.SetSelection(idCtrl);
2bda0e17 160
42e69d6b 161 return ProcessEvent(event);
2bda0e17
KB
162}
163
164// Responds to colour changes, and passes event on to children.
165void wxTabCtrl::OnSysColourChanged(wxSysColourChangedEvent& event)
166{
167 m_backgroundColour = wxColour(GetRValue(GetSysColor(COLOR_BTNFACE)),
42e69d6b
VZ
168 GetGValue(GetSysColor(COLOR_BTNFACE)),
169 GetBValue(GetSysColor(COLOR_BTNFACE)));
2bda0e17
KB
170
171 Refresh();
172
173 // Propagate the event to the non-top-level children
174 wxWindow::OnSysColourChanged(event);
175}
176
177// Delete all items
ee4f8c2a 178bool wxTabCtrl::DeleteAllItems()
2bda0e17
KB
179{
180 return ( TabCtrl_DeleteAllItems( (HWND) GetHWND() ) != FALSE );
181}
182
183// Delete an item
ee4f8c2a 184bool wxTabCtrl::DeleteItem(int item)
2bda0e17
KB
185{
186 return ( TabCtrl_DeleteItem( (HWND) GetHWND(), item) != FALSE );
187}
188
189// Get the selection
ee4f8c2a 190int wxTabCtrl::GetSelection() const
2bda0e17
KB
191{
192 return (int) TabCtrl_GetCurSel( (HWND) GetHWND() );
193}
194
da87a1ca
JS
195// Get the tab with the current keyboard focus
196int wxTabCtrl::GetCurFocus() const
197{
198 return (int) TabCtrl_GetCurFocus( (HWND) GetHWND() );
199}
200
2bda0e17 201// Get the associated image list
ee4f8c2a 202wxImageList* wxTabCtrl::GetImageList() const
2bda0e17
KB
203{
204 return m_imageList;
205}
206
207// Get the number of items
ee4f8c2a 208int wxTabCtrl::GetItemCount() const
2bda0e17
KB
209{
210 return (int) TabCtrl_GetItemCount( (HWND) GetHWND() );
211}
212
213// Get the rect corresponding to the tab
ee4f8c2a 214bool wxTabCtrl::GetItemRect(int item, wxRect& wxrect) const
2bda0e17
KB
215{
216 RECT rect;
217 if ( !TabCtrl_GetItemRect( (HWND) GetHWND(), item, & rect) )
bfbb0b4c 218 return false;
2bda0e17
KB
219 else
220 {
221 wxrect.x = rect.left; wxrect.y = rect.top;
222 wxrect.width = rect.right - rect.left;
223 wxrect.height = rect.bottom - rect.top;
bfbb0b4c 224 return true;
2bda0e17
KB
225 }
226}
227
228// Get the number of rows
ee4f8c2a 229int wxTabCtrl::GetRowCount() const
2bda0e17
KB
230{
231 return (int) TabCtrl_GetRowCount( (HWND) GetHWND() );
232}
233
234// Get the item text
ee4f8c2a 235wxString wxTabCtrl::GetItemText(int item) const
2bda0e17 236{
837e5743 237 wxChar buf[256];
fda7962d 238 wxString str(wxEmptyString);
2bda0e17
KB
239 TC_ITEM tcItem;
240 tcItem.mask = TCIF_TEXT;
241 tcItem.pszText = buf;
242 tcItem.cchTextMax = 256;
243
244 if (TabCtrl_GetItem( (HWND) GetHWND(), item, & tcItem) )
245 str = tcItem.pszText;
246
247 return str;
248}
249
250// Get the item image
ee4f8c2a 251int wxTabCtrl::GetItemImage(int item) const
2bda0e17
KB
252{
253 TC_ITEM tcItem;
254 tcItem.mask = TCIF_IMAGE;
255
256 if (TabCtrl_GetItem( (HWND) GetHWND(), item, & tcItem) )
257 return tcItem.iImage;
258 else
259 return -1;
260}
261
262// Get the item data
ee4f8c2a 263void* wxTabCtrl::GetItemData(int item) const
2bda0e17
KB
264{
265 TC_ITEM tcItem;
266 tcItem.mask = TCIF_PARAM;
267
268 if (TabCtrl_GetItem( (HWND) GetHWND(), item, & tcItem) )
269 return (void*) tcItem.lParam;
270 else
271 return 0;
272}
273
274// Hit test
275int wxTabCtrl::HitTest(const wxPoint& pt, long& flags)
276{
277 TC_HITTESTINFO hitTestInfo;
278 hitTestInfo.pt.x = pt.x;
279 hitTestInfo.pt.y = pt.y;
280 int item = TabCtrl_HitTest( (HWND) GetHWND(), & hitTestInfo ) ;
281 flags = 0;
282
283 if ((hitTestInfo.flags & TCHT_NOWHERE) == TCHT_NOWHERE)
284 flags |= wxTAB_HITTEST_NOWHERE;
285 if ((hitTestInfo.flags & TCHT_ONITEMICON) == TCHT_ONITEMICON)
286 flags |= wxTAB_HITTEST_ONICON;
287 if ((hitTestInfo.flags & TCHT_ONITEMLABEL) == TCHT_ONITEMLABEL)
288 flags |= wxTAB_HITTEST_ONLABEL;
289
290 return item;
291}
292
293// Insert an item
ee4f8c2a 294bool wxTabCtrl::InsertItem(int item, const wxString& text, int imageId, void* data)
2bda0e17 295{
837e5743 296 wxChar buf[256];
2bda0e17
KB
297 TC_ITEM tcItem;
298 tcItem.mask = TCIF_PARAM;
299 tcItem.lParam = (long) data;
fda7962d 300 if (text != wxEmptyString)
2bda0e17
KB
301 {
302 tcItem.mask |= TCIF_TEXT;
837e5743 303 wxStrcpy(buf, (const wxChar*) text);
2bda0e17
KB
304 tcItem.pszText = buf;
305 tcItem.cchTextMax = 256;
306 }
307 if (imageId != -1)
308 {
309 tcItem.mask |= TCIF_IMAGE;
310 tcItem.iImage = imageId;
311 }
312
ee4f8c2a 313 return (TabCtrl_InsertItem( (HWND) GetHWND(), item, & tcItem) != -1);
2bda0e17
KB
314}
315
316// Set the selection
ee4f8c2a 317int wxTabCtrl::SetSelection(int item)
2bda0e17
KB
318{
319 return (int) TabCtrl_SetCurSel( (HWND) GetHWND(), item );
320}
321
322// Set the image list
323void wxTabCtrl::SetImageList(wxImageList* imageList)
324{
325 m_imageList = imageList;
326 TabCtrl_SetImageList( (HWND) GetHWND(), (HIMAGELIST) imageList->GetHIMAGELIST() );
327}
328
329// Set the text for an item
ee4f8c2a 330bool wxTabCtrl::SetItemText(int item, const wxString& text)
2bda0e17 331{
837e5743 332 wxChar buf[256];
2bda0e17
KB
333 TC_ITEM tcItem;
334 tcItem.mask = TCIF_TEXT;
837e5743 335 wxStrcpy(buf, (const wxChar*) text);
2bda0e17
KB
336 tcItem.pszText = buf;
337 tcItem.cchTextMax = 256;
338
339 return ( TabCtrl_SetItem( (HWND) GetHWND(), item, & tcItem) != 0 );
340}
341
342// Set the image for an item
ee4f8c2a 343bool wxTabCtrl::SetItemImage(int item, int image)
2bda0e17
KB
344{
345 TC_ITEM tcItem;
346 tcItem.mask = TCIF_IMAGE;
347 tcItem.iImage = image;
348
349 return ( TabCtrl_SetItem( (HWND) GetHWND(), item, & tcItem) != 0 );
350}
351
352// Set the data for an item
ee4f8c2a 353bool wxTabCtrl::SetItemData(int item, void* data)
2bda0e17
KB
354{
355 TC_ITEM tcItem;
356 tcItem.mask = TCIF_PARAM;
357 tcItem.lParam = (long) data;
358
359 return ( TabCtrl_SetItem( (HWND) GetHWND(), item, & tcItem) != 0 );
360}
361
362// Set the size for a fixed-width tab control
363void wxTabCtrl::SetItemSize(const wxSize& size)
364{
365 TabCtrl_SetItemSize( (HWND) GetHWND(), size.x, size.y );
366}
367
368// Set the padding between tabs
369void wxTabCtrl::SetPadding(const wxSize& padding)
370{
371 TabCtrl_SetPadding( (HWND) GetHWND(), padding.x, padding.y );
372}
373
374#if 0
375// These are the default colors used to map the bitmap colors
376// to the current system colors
377
378#define BGR_BUTTONTEXT (RGB(000,000,000)) // black
379#define BGR_BUTTONSHADOW (RGB(128,128,128)) // dark grey
380#define BGR_BUTTONFACE (RGB(192,192,192)) // bright grey
381#define BGR_BUTTONHILIGHT (RGB(255,255,255)) // white
382#define BGR_BACKGROUNDSEL (RGB(255,000,000)) // blue
383#define BGR_BACKGROUND (RGB(255,000,255)) // magenta
384
385void wxMapBitmap(HBITMAP hBitmap, int width, int height)
386{
387 COLORMAP ColorMap[] = {
388 {BGR_BUTTONTEXT, COLOR_BTNTEXT}, // black
389 {BGR_BUTTONSHADOW, COLOR_BTNSHADOW}, // dark grey
390 {BGR_BUTTONFACE, COLOR_BTNFACE}, // bright grey
391 {BGR_BUTTONHILIGHT, COLOR_BTNHIGHLIGHT},// white
392 {BGR_BACKGROUNDSEL, COLOR_HIGHLIGHT}, // blue
393 {BGR_BACKGROUND, COLOR_WINDOW} // magenta
394 };
395
396 int NUM_MAPS = (sizeof(ColorMap)/sizeof(COLORMAP));
397 int n;
398 for ( n = 0; n < NUM_MAPS; n++)
399 {
400 ColorMap[n].to = ::GetSysColor(ColorMap[n].to);
401 }
402
403 HBITMAP hbmOld;
404 HDC hdcMem = CreateCompatibleDC(NULL);
405
406 if (hdcMem)
407 {
408 hbmOld = SelectObject(hdcMem, hBitmap);
409
410 int i, j, k;
411 for ( i = 0; i < width; i++)
412 {
413 for ( j = 0; j < height; j++)
414 {
415 COLORREF pixel = ::GetPixel(hdcMem, i, j);
416/*
417 BYTE red = GetRValue(pixel);
418 BYTE green = GetGValue(pixel);
419 BYTE blue = GetBValue(pixel);
420*/
421
422 for ( k = 0; k < NUM_MAPS; k ++)
423 {
424 if ( ColorMap[k].from == pixel )
425 {
426 /* COLORREF actualPixel = */ ::SetPixel(hdcMem, i, j, ColorMap[k].to);
427 break;
428 }
429 }
430 }
431 }
432
433
434 SelectObject(hdcMem, hbmOld);
435 DeleteObject(hdcMem);
436 }
437
438}
439#endif
440
2bda0e17
KB
441#endif
442 // __WIN95__