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