]> git.saurik.com Git - wxWidgets.git/blame - src/univ/combobox.cpp
added wxUSE_POPUPWIN
[wxWidgets.git] / src / univ / combobox.cpp
CommitLineData
1e6feb95
VZ
1/////////////////////////////////////////////////////////////////////////////
2// Name: univ/combobox.cpp
3// Purpose: wxComboControl and wxComboBox implementation
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 15.12.00
7// RCS-ID: $Id$
442b35b5 8// Copyright: (c) 2000 SciTech Software, Inc. (www.scitechsoft.com)
1e6feb95
VZ
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12/*
13 TODO:
14
15 +1. typing in the text should select the string in listbox
16 +2. scrollbars in listbox are unusable
17 +3. the initially selected item is not selected
18 ?4. kbd interface (what does GTK do?)
19 5. there is still autoscrolling without scrollbars - but is it bad?
20 */
21
22// ============================================================================
23// declarations
24// ============================================================================
25
26// ----------------------------------------------------------------------------
27// headers
28// ----------------------------------------------------------------------------
29
30#ifdef __GNUG__
a3870b2f 31 #pragma implementation "univcombobox.h"
1e6feb95
VZ
32#endif
33
34#include "wx/wxprec.h"
35
36#ifdef __BORLANDC__
37 #pragma hdrstop
38#endif
39
40#if wxUSE_COMBOBOX
41
42#ifndef WX_PRECOMP
43 #include "wx/log.h"
44
45 #include "wx/button.h"
46 #include "wx/combobox.h"
47 #include "wx/listbox.h"
48 #include "wx/textctrl.h"
8cb172b4 49 #include "wx/bmpbuttn.h"
1e6feb95
VZ
50
51 #include "wx/validate.h"
52#endif
53
54#include "wx/popupwin.h"
55
56#include "wx/univ/renderer.h"
57#include "wx/univ/inphand.h"
58#include "wx/univ/theme.h"
59
60/*
61 The keyboard event flow:
62
63 1. they always come to the text ctrl
64 2. it forwards the ones it doesn't process to the wxComboControl
65 3. which passes them to the popup window if it is popped up
66 */
67
68// ----------------------------------------------------------------------------
69// wxComboButton is just a normal button except that it sends commands to the
70// combobox and not its parent
71// ----------------------------------------------------------------------------
72
73class wxComboButton : public wxBitmapButton
74{
75public:
76 wxComboButton(wxComboControl *combo)
77 : wxBitmapButton(combo->GetParent(), -1, wxNullBitmap,
78 wxDefaultPosition, wxDefaultSize,
79 wxBORDER_NONE)
80 {
81 m_combo = combo;
82
83 wxBitmap bmpNormal, bmpPressed, bmpDisabled;
84
85 GetRenderer()->GetComboBitmaps(&bmpNormal, &bmpPressed, &bmpDisabled);
86 SetBitmapLabel(bmpNormal);
87 SetBitmapFocus(bmpNormal);
88 SetBitmapSelected(bmpPressed);
89 SetBitmapDisabled(bmpDisabled);
90
1629fb3b 91// SetSize(bmpNormal.GetWidth(), bmpNormal.GetHeight());
1e6feb95
VZ
92 }
93
94protected:
95 void OnButton(wxCommandEvent& event) { m_combo->ShowPopup(); }
96
97 virtual wxSize DoGetBestSize() const { return GetSize(); }
98
99private:
100 wxComboControl *m_combo;
101
102 DECLARE_EVENT_TABLE()
103};
104
105// ----------------------------------------------------------------------------
106// wxComboListBox is a listbox modified to be used as a popup window in a
107// combobox
108// ----------------------------------------------------------------------------
109
110class wxComboListBox : public wxListBox, public wxComboPopup
111{
112public:
113 // ctor and dtor
114 wxComboListBox(wxComboControl *combo, int style = 0);
115 virtual ~wxComboListBox();
116
117 // implement wxComboPopup methods
118 virtual bool SetSelection(const wxString& value);
119 virtual wxControl *GetControl() { return this; }
120 virtual void OnShow();
121
122protected:
123 // we shouldn't return height too big from here
124 virtual wxSize DoGetBestClientSize() const;
125
126 // filter mouse move events happening outside the list box
127 void OnMouseMove(wxMouseEvent& event);
128
129 // called whenever the user selects or activates a listbox item
130 void OnSelect(wxCommandEvent& event);
131
132 // used to process wxUniv actions
133 bool PerformAction(const wxControlAction& action,
134 long numArg,
135 const wxString& strArg);
136
137private:
138 DECLARE_EVENT_TABLE()
139};
140
141// ----------------------------------------------------------------------------
142// wxComboTextCtrl is a simple text ctrl which forwards
143// wxEVT_COMMAND_TEXT_UPDATED events and all key events to the combobox
144// ----------------------------------------------------------------------------
145
146class wxComboTextCtrl : public wxTextCtrl
147{
148public:
149 wxComboTextCtrl(wxComboControl *combo,
150 const wxString& value,
151 long style,
152 const wxValidator& validator);
153
154protected:
155 void OnKey(wxKeyEvent& event);
156 void OnText(wxCommandEvent& event);
157
158private:
159 wxComboControl *m_combo;
160
161 DECLARE_EVENT_TABLE()
162};
163
164// ----------------------------------------------------------------------------
165// event tables and such
166// ----------------------------------------------------------------------------
167
168BEGIN_EVENT_TABLE(wxComboButton, wxButton)
169 EVT_BUTTON(-1, wxComboButton::OnButton)
170END_EVENT_TABLE()
171
172BEGIN_EVENT_TABLE(wxComboListBox, wxListBox)
173 EVT_LISTBOX(-1, wxComboListBox::OnSelect)
174 EVT_LISTBOX_DCLICK(-1, wxComboListBox::OnSelect)
175 EVT_MOTION(wxComboListBox::OnMouseMove)
176END_EVENT_TABLE()
177
178BEGIN_EVENT_TABLE(wxComboControl, wxControl)
179 EVT_KEY_DOWN(wxComboControl::OnKey)
180 EVT_KEY_UP(wxComboControl::OnKey)
181END_EVENT_TABLE()
182
183BEGIN_EVENT_TABLE(wxComboTextCtrl, wxTextCtrl)
184 EVT_KEY_DOWN(wxComboTextCtrl::OnKey)
185 EVT_KEY_UP(wxComboTextCtrl::OnKey)
186 EVT_TEXT(-1, wxComboTextCtrl::OnText)
187END_EVENT_TABLE()
188
189IMPLEMENT_DYNAMIC_CLASS(wxComboBox, wxControl);
190
191// ============================================================================
192// implementation
193// ============================================================================
194
195// ----------------------------------------------------------------------------
196// wxComboControl creation
197// ----------------------------------------------------------------------------
198
199void wxComboControl::Init()
200{
201 m_popup = (wxComboPopup *)NULL;
202 m_winPopup = (wxPopupComboWindow *)NULL;
203 m_isPopupShown = FALSE;
9f41d601
RR
204 m_btn = NULL;
205 m_text = NULL;
1e6feb95
VZ
206}
207
208bool wxComboControl::Create(wxWindow *parent,
209 wxWindowID id,
210 const wxString& value,
211 const wxPoint& pos,
212 const wxSize& size,
213 long style,
214 const wxValidator& validator,
215 const wxString& name)
216{
217 // first create our own window, i.e. the one which will contain all
218 // subcontrols
219 style &= ~wxBORDER_NONE;
220 style |= wxBORDER_SUNKEN;
221 if ( !wxControl::Create(parent, id, pos, size, style, validator, name) )
222 return FALSE;
223
224 // create the text control and the button as our siblings (*not* children),
225 // don't care about size/position here - they will be set in DoMoveWindow()
226 m_btn = new wxComboButton(this);
227 m_text = new wxComboTextCtrl(this,
228 value,
229 style & wxCB_READONLY ? wxTE_READONLY : 0,
230 validator);
231
232 // for compatibility with the other ports, the height specified is the
233 // combined height of the combobox itself and the popup
234 if ( size.y == -1 )
235 {
236 // ok, use default height for popup too
237 m_heightPopup = -1;
238 }
239 else
240 {
241 m_heightPopup = size.y - DoGetBestSize().y;
242 }
243
244 DoSetSize(pos.x, pos.y, size.x, size.y);
245
246 // create the popup window immediately here to allow creating the controls
247 // with parent == GetPopupWindow() from the derived class ctor
248 m_winPopup = new wxPopupComboWindow(this);
249
250 // have to disable this window to avoid interfering it with message
251 // processing to the text and the button... but pretend it is enabled to
252 // make IsEnabled() return TRUE
253 wxControl::Enable(FALSE); // don't use non virtual Disable() here!
254 m_isEnabled = TRUE;
255
256 CreateInputHandler(wxINP_HANDLER_COMBOBOX);
257
258 return TRUE;
259}
260
261wxComboControl::~wxComboControl()
262{
263 // as the button and the text control are the parent's children and not
264 // ours, we have to delete them manually - they are not deleted
265 // automatically by wxWindows when we're deleted
266 delete m_btn;
267 delete m_text;
268
269 delete m_winPopup;
270}
271
272// ----------------------------------------------------------------------------
273// geometry stuff
274// ----------------------------------------------------------------------------
275
276void wxComboControl::DoSetSize(int x, int y,
277 int width, int height,
278 int sizeFlags)
279{
280 // combo height is always fixed
281 wxControl::DoSetSize(x, y, width, DoGetBestSize().y, sizeFlags);
282}
283
284wxSize wxComboControl::DoGetBestClientSize() const
285{
286 wxSize sizeBtn = m_btn->GetBestSize(),
287 sizeText = m_text->GetBestSize();
288
289 return wxSize(sizeBtn.x + sizeText.x, wxMax(sizeBtn.y, sizeText.y));
290}
291
292void wxComboControl::DoMoveWindow(int x, int y, int width, int height)
293{
294 wxControl::DoMoveWindow(x, y, width, height);
295
296 // position the subcontrols inside the client area
297 wxRect rectBorders = GetRenderer()->GetBorderDimensions(GetBorder());
298 x += rectBorders.x;
299 y += rectBorders.y;
300 width -= rectBorders.x + rectBorders.width;
301 height -= rectBorders.y + rectBorders.height;
302
303 wxSize sizeBtn = m_btn->GetSize(),
304 sizeText = m_text->GetSize();
305
306 wxCoord wText = width - sizeBtn.x;
307 m_text->SetSize(x, y, wText, height);
308 m_btn->SetSize(x + wText, y, -1, height);
309}
310
311// ----------------------------------------------------------------------------
312// operations
313// ----------------------------------------------------------------------------
314
315bool wxComboControl::Enable(bool enable)
316{
317 if ( !wxControl::Enable(enable) )
318 return FALSE;
319
320 m_btn->Enable(enable);
321 m_text->Enable(enable);
322
323 return TRUE;
324}
325
326bool wxComboControl::Show(bool show)
327{
328 if ( !wxControl::Show(show) )
329 return FALSE;
330
9f41d601
RR
331 if (m_btn)
332 m_btn->Show(show);
333
334 if (m_text)
335 m_text->Show(show);
1e6feb95
VZ
336
337 return TRUE;
338}
339
340// ----------------------------------------------------------------------------
341// popup window handling
342// ----------------------------------------------------------------------------
343
344void wxComboControl::SetPopupControl(wxComboPopup *popup)
345{
346 m_popup = popup;
347}
348
349void wxComboControl::ShowPopup()
350{
351 wxCHECK_RET( m_popup, _T("no popup to show in wxComboControl") );
352 wxCHECK_RET( !IsPopupShown(), _T("popup window already shown") );
353
354 wxControl *control = m_popup->GetControl();
355
356 // size and position the popup window correctly
357 m_winPopup->SetSize(GetSize().x,
358 m_heightPopup == -1 ? control->GetBestSize().y
359 : m_heightPopup);
360 wxSize sizePopup = m_winPopup->GetClientSize();
361 control->SetSize(0, 0, sizePopup.x, sizePopup.y);
362
363 // some controls don't accept the size we give then: e.g. a listbox may
364 // require more space to show its last row
365 wxSize sizeReal = control->GetSize();
366 if ( sizeReal != sizePopup )
367 {
368 m_winPopup->SetClientSize(sizeReal);
369 }
370
371 m_winPopup->PositionNearCombo();
372
373 // show it
374 m_winPopup->Popup(m_text);
375 m_text->SelectAll();
376 m_popup->SetSelection(m_text->GetValue());
377
378 m_isPopupShown = TRUE;
379}
380
381void wxComboControl::HidePopup()
382{
383 wxCHECK_RET( m_popup, _T("no popup to hide in wxComboControl") );
384 wxCHECK_RET( IsPopupShown(), _T("popup window not shown") );
385
386 m_winPopup->Dismiss();
387
388 m_isPopupShown = FALSE;
389}
390
391void wxComboControl::OnSelect(const wxString& value)
392{
393 m_text->SetValue(value);
394 m_text->SelectAll();
395
396 OnDismiss();
397}
398
399void wxComboControl::OnDismiss()
400{
401 HidePopup();
402 m_text->SetFocus();
403}
404
405// ----------------------------------------------------------------------------
406// wxComboTextCtrl
407// ----------------------------------------------------------------------------
408
409wxComboTextCtrl::wxComboTextCtrl(wxComboControl *combo,
410 const wxString& value,
411 long style,
412 const wxValidator& validator)
413 : wxTextCtrl(combo->GetParent(), -1, value,
414 wxDefaultPosition, wxDefaultSize,
415 wxBORDER_NONE | style,
416 validator)
417{
418 m_combo = combo;
419}
420
421void wxComboTextCtrl::OnText(wxCommandEvent& event)
422{
423 if ( m_combo->IsPopupShown() )
424 {
425 m_combo->GetPopupControl()->SetSelection(GetValue());
426 }
427
428 // we need to make a copy of the event to have the correct originating
429 // object and id
430 wxCommandEvent event2 = event;
431 event2.SetEventObject(m_combo);
432 event2.SetId(m_combo->GetId());
433
434 // there is a small incompatibility with wxMSW here: the combobox gets the
435 // event before the text control in our case which corresponds to SMW
436 // CBN_EDITUPDATE notification and not CBN_EDITCHANGE one wxMSW currently
437 // uses
438 //
439 // if this is really a problem, we can play games with the event handlers
440 // to circumvent this
441 (void)m_combo->ProcessEvent(event2);
442
443 event.Skip();
444}
445
446// pass the keys we don't process to the combo first
447void wxComboTextCtrl::OnKey(wxKeyEvent& event)
448{
449 switch ( event.GetKeyCode() )
450 {
451 case WXK_RETURN:
452 // the popup control gets it first but only if it is shown
453 if ( !m_combo->IsPopupShown() )
454 break;
455 //else: fall through
456
457 case WXK_UP:
458 case WXK_DOWN:
459 case WXK_ESCAPE:
460 case WXK_PAGEDOWN:
461 case WXK_PAGEUP:
462 case WXK_PRIOR:
463 case WXK_NEXT:
464 (void)m_combo->ProcessEvent(event);
465 return;
466 }
467
468 event.Skip();
469}
470
471// ----------------------------------------------------------------------------
472// wxComboListBox
473// ----------------------------------------------------------------------------
474
475wxComboListBox::wxComboListBox(wxComboControl *combo, int style)
476 : wxListBox(combo->GetPopupWindow(), -1,
477 wxDefaultPosition, wxDefaultSize,
478 0, NULL,
479 wxBORDER_SIMPLE | wxLB_INT_HEIGHT | style),
480 wxComboPopup(combo)
481{
482 // we don't react to the mouse events outside the window at all
483 StopAutoScrolling();
484}
485
486wxComboListBox::~wxComboListBox()
487{
488}
489
490bool wxComboListBox::SetSelection(const wxString& value)
491{
492 // FindItem() would just find the current item for an empty string (it
493 // always matches), but we want to show the first one in such case
494 if ( value.empty() )
495 {
496 if ( GetCount() )
497 {
498 wxListBox::SetSelection(0);
499 }
500 //else: empty listbox - nothing to do
501 }
502 else if ( !FindItem(value) )
503 {
504 // no match att all
505 return FALSE;
506 }
507
508 return TRUE;
509}
510
511void wxComboListBox::OnSelect(wxCommandEvent& event)
512{
513 // first let the user code have the event
514
515 // all fields are already filled by the listbox, just change the event
516 // type and send it to the combo
517 wxCommandEvent event2 = event;
518 event2.SetEventType(wxEVT_COMMAND_COMBOBOX_SELECTED);
519 event2.SetEventObject(m_combo);
520 event2.SetId(m_combo->GetId());
521 m_combo->ProcessEvent(event2);
522
523 // next update the combo and close the listbox
524 m_combo->OnSelect(event.GetString());
525}
526
527void wxComboListBox::OnShow()
528{
529}
530
531bool wxComboListBox::PerformAction(const wxControlAction& action,
532 long numArg,
533 const wxString& strArg)
534
535{
536 if ( action == wxACTION_LISTBOX_FIND )
537 {
538 // we don't let the listbox handle this as instead of just using the
539 // single key presses, as usual, we use the text ctrl value as prefix
540 // and this is done by wxComboControl itself
541 return TRUE;
542 }
543
544 return wxListBox::PerformAction(action, numArg, strArg);
545}
546
547void wxComboListBox::OnMouseMove(wxMouseEvent& event)
548{
549 // while a wxComboListBox is shown, it always has capture, so if it doesn't
550 // we're about to go away anyhow (normally this shouldn't happen at all,
551 // but I don't put assert here as it just might do on other platforms and
552 // it doesn't break anythign anyhow)
553 if ( this == wxWindow::GetCapture() )
554 {
555 if ( HitTest(event.GetPosition()) == wxHT_WINDOW_INSIDE )
556 {
557 event.Skip();
558 }
559 //else: popup shouldn't react to the mouse motions outside it, it only
560 // captures the mouse to be able to detect when it must be
561 // dismissed, so don't call Skip()
562 }
563}
564
565wxSize wxComboListBox::DoGetBestClientSize() const
566{
567 // don't return size too big or we risk to not fit on the screen
568 wxSize size = wxListBox::DoGetBestClientSize();
569 wxCoord hChar = GetCharHeight();
570
571 int nLines = size.y / hChar;
572
573 // 10 is the same limit as used by wxMSW
574 if ( nLines > 10 )
575 {
576 size.y = 10*hChar;
577 }
578
579 return size;
580}
581
582// ----------------------------------------------------------------------------
583// wxComboBox
584// ----------------------------------------------------------------------------
585
586void wxComboBox::Init()
587{
588 m_lbox = (wxListBox *)NULL;
589}
590
591bool wxComboBox::Create(wxWindow *parent,
592 wxWindowID id,
593 const wxString& value,
594 const wxPoint& pos,
595 const wxSize& size,
596 int n,
597 const wxString *choices,
598 long style,
599 const wxValidator& validator,
600 const wxString& name)
601{
602 if ( !wxComboControl::Create(parent, id, value, pos, size, style,
603 validator, name) )
604 {
605 return FALSE;
606 }
607
608 wxComboListBox *combolbox =
609 new wxComboListBox(this, style & wxCB_SORT ? wxLB_SORT : 0);
610 m_lbox = combolbox;
611 m_lbox->Set(n, choices);
612
613 SetPopupControl(combolbox);
614
615 return TRUE;
616}
617
618wxComboBox::~wxComboBox()
619{
620}
621
622// ----------------------------------------------------------------------------
623// wxComboBox methods forwarded to wxTextCtrl
624// ----------------------------------------------------------------------------
625
626wxString wxComboBox::GetValue() const
627{
628 return GetText()->GetValue();
629}
630
631void wxComboBox::SetValue(const wxString& value)
632{
633 GetText()->SetValue(value);
634}
635
636void wxComboBox::Copy()
637{
638 GetText()->Copy();
639}
640
641void wxComboBox::Cut()
642{
643 GetText()->Cut();
644}
645
646void wxComboBox::Paste()
647{
648 GetText()->Paste();
649}
650
651void wxComboBox::SetInsertionPoint(long pos)
652{
653 GetText()->SetInsertionPoint(pos);
654}
655
656void wxComboBox::SetInsertionPointEnd()
657{
658 GetText()->SetInsertionPointEnd();
659}
660
661long wxComboBox::GetInsertionPoint() const
662{
663 return GetText()->GetInsertionPoint();
664}
665
666long wxComboBox::GetLastPosition() const
667{
668 return GetText()->GetLastPosition();
669}
670
671void wxComboBox::Replace(long from, long to, const wxString& value)
672{
673 GetText()->Replace(from, to, value);
674}
675
676void wxComboBox::Remove(long from, long to)
677{
678 GetText()->Remove(from, to);
679}
680
681void wxComboBox::SetSelection(long from, long to)
682{
683 GetText()->SetSelection(from, to);
684}
685
686void wxComboBox::SetEditable(bool editable)
687{
688 GetText()->SetEditable(editable);
689}
690
691// ----------------------------------------------------------------------------
692// wxComboBox methods forwarded to wxListBox
693// ----------------------------------------------------------------------------
694
695void wxComboBox::Clear()
696{
697 GetLBox()->Clear();
698}
699
700void wxComboBox::Delete(int n)
701{
702 GetLBox()->Delete(n);
703}
704
705int wxComboBox::GetCount() const
706{
707 return GetLBox()->GetCount();
708}
709
710wxString wxComboBox::GetString(int n) const
711{
712 return GetLBox()->GetString(n);
713}
714
715void wxComboBox::SetString(int n, const wxString& s)
716{
717 GetLBox()->SetString(n, s);
718}
719
720int wxComboBox::FindString(const wxString& s) const
721{
722 return GetLBox()->FindString(s);
723}
724
725void wxComboBox::Select(int n)
726{
727 wxCHECK_RET( (n >= 0) && (n < GetCount()), _T("invalid combobox index") );
728
729 GetLBox()->SetSelection(n);
730 GetText()->SetValue(GetLBox()->GetString(n));
731}
732
733int wxComboBox::GetSelection() const
734{
735 // if the current value isn't one of the listbox strings, return -1
736 return FindString(GetText()->GetValue());
737}
738
739int wxComboBox::DoAppend(const wxString& item)
740{
741 return GetLBox()->Append(item);
742}
743
744void wxComboBox::DoSetItemClientData(int n, void* clientData)
745{
746 GetLBox()->SetClientData(n, clientData);
747}
748
749void *wxComboBox::DoGetItemClientData(int n) const
750{
751 return GetLBox()->GetClientData(n);
752}
753
754void wxComboBox::DoSetItemClientObject(int n, wxClientData* clientData)
755{
756 GetLBox()->SetClientObject(n, clientData);
757}
758
759wxClientData* wxComboBox::DoGetItemClientObject(int n) const
760{
761 return GetLBox()->GetClientObject(n);
762}
763
764// ----------------------------------------------------------------------------
765// input handling
766// ----------------------------------------------------------------------------
767
768void wxComboControl::OnKey(wxCommandEvent& event)
769{
770 if ( m_isPopupShown )
771 {
772 // pass it to the popped up control
773 (void)m_popup->GetControl()->ProcessEvent(event);
774 }
775 else // no popup
776 {
777 event.Skip();
778 }
779}
780
781bool wxComboControl::PerformAction(const wxControlAction& action,
782 long numArg,
783 const wxString& strArg)
784{
785 bool processed = FALSE;
786 if ( action == wxACTION_COMBOBOX_POPUP )
787 {
788 if ( !m_isPopupShown )
789 {
790 ShowPopup();
791
792 processed = TRUE;
793 }
794 }
795 else if ( action == wxACTION_COMBOBOX_DISMISS )
796 {
797 if ( m_isPopupShown )
798 {
799 HidePopup();
800
801 processed = TRUE;
802 }
803 }
804
805 if ( !processed )
806 {
807 // pass along
808 return wxControl::PerformAction(action, numArg, strArg);
809 }
810
811 return TRUE;
812}
813
814// ----------------------------------------------------------------------------
815// wxStdComboBoxInputHandler
816// ----------------------------------------------------------------------------
817
818wxStdComboBoxInputHandler::wxStdComboBoxInputHandler(wxInputHandler *inphand)
819 : wxStdInputHandler(inphand)
820{
821}
822
823bool wxStdComboBoxInputHandler::HandleKey(wxControl *control,
824 const wxKeyEvent& event,
825 bool pressed)
826{
827 if ( pressed )
828 {
829 wxControlAction action;
830 switch ( event.GetKeyCode() )
831 {
832 case WXK_DOWN:
833 action = wxACTION_COMBOBOX_POPUP;
834 break;
835
836 case WXK_ESCAPE:
837 action = wxACTION_COMBOBOX_DISMISS;
838 break;
839 }
840
841 if ( !!action )
842 {
843 control->PerformAction(action);
844
845 return TRUE;
846 }
847 }
848
849 return wxStdInputHandler::HandleKey(control, event, pressed);
850}
851
852#endif // wxUSE_COMBOBOX