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