1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/univ/combobox.cpp
3 // Purpose: wxComboControl and wxComboBox implementation
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 2000 SciTech Software, Inc. (www.scitechsoft.com)
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 #include "wx/wxprec.h"
31 #include "wx/button.h"
32 #include "wx/combobox.h"
33 #include "wx/listbox.h"
34 #include "wx/textctrl.h"
35 #include "wx/bmpbuttn.h"
37 #include "wx/validate.h"
40 #include "wx/tooltip.h"
41 #include "wx/popupwin.h"
43 #include "wx/univ/renderer.h"
44 #include "wx/univ/inphand.h"
45 #include "wx/univ/theme.h"
48 The keyboard event flow:
50 1. they always come to the text ctrl
51 2. it forwards the ones it doesn't process to the wxComboControl
52 3. which passes them to the popup window if it is popped up
56 // ----------------------------------------------------------------------------
58 // the margin between the text control and the combo button
59 static const wxCoord g_comboMargin
= 2;
61 // ----------------------------------------------------------------------------
62 // wxComboButton is just a normal button except that it sends commands to the
63 // combobox and not its parent
64 // ----------------------------------------------------------------------------
66 class wxComboButton
: public wxBitmapButton
69 wxComboButton(wxComboControl
*combo
)
70 : wxBitmapButton(combo
->GetParent(), wxID_ANY
, wxNullBitmap
,
71 wxDefaultPosition
, wxDefaultSize
,
72 wxBORDER_NONE
| wxBU_EXACTFIT
)
76 wxBitmap bmpNormal
, bmpFocus
, bmpPressed
, bmpDisabled
;
78 GetRenderer()->GetComboBitmaps(&bmpNormal
,
83 SetBitmapLabel(bmpNormal
);
84 SetBitmapFocus(bmpFocus
.Ok() ? bmpFocus
: bmpNormal
);
85 SetBitmapSelected(bmpPressed
.Ok() ? bmpPressed
: bmpNormal
);
86 SetBitmapDisabled(bmpDisabled
.Ok() ? bmpDisabled
: bmpNormal
);
88 SetBestSize(wxDefaultSize
);
92 void OnButton(wxCommandEvent
& WXUNUSED(event
)) { m_combo
->ShowPopup(); }
94 virtual wxSize
DoGetBestClientSize() const
96 const wxBitmap
& bmp
= GetBitmapLabel();
98 return wxSize(bmp
.GetWidth(), bmp
.GetHeight());
103 wxComboControl
*m_combo
;
105 DECLARE_EVENT_TABLE()
108 // ----------------------------------------------------------------------------
109 // wxComboListBox is a listbox modified to be used as a popup window in a
111 // ----------------------------------------------------------------------------
113 class wxComboListBox
: public wxListBox
, public wxComboPopup
117 wxComboListBox(wxComboControl
*combo
, int style
= 0);
118 virtual ~wxComboListBox();
120 // implement wxComboPopup methods
121 virtual bool SetSelection(const wxString
& s
);
122 virtual wxControl
*GetControl() { return this; }
123 virtual void OnShow();
124 virtual wxCoord
GetBestWidth() const;
126 // fix virtual function hiding
127 virtual void SetSelection(int n
) { DoSetSelection(n
, true); }
128 void SetSelection(int n
, bool select
) { DoSetSelection(n
, select
); }
131 // we shouldn't return height too big from here
132 virtual wxSize
DoGetBestClientSize() const;
134 // filter mouse move events happening outside the list box
135 void OnMouseMove(wxMouseEvent
& event
);
137 // set m_clicked value from here
138 void OnLeftUp(wxMouseEvent
& event
);
140 // called whenever the user selects or activates a listbox item
141 void OnSelect(wxCommandEvent
& event
);
143 // used to process wxUniv actions
144 bool PerformAction(const wxControlAction
& action
,
146 const wxString
& strArg
);
149 // has the mouse been released on this control?
152 DECLARE_EVENT_TABLE()
155 // ----------------------------------------------------------------------------
156 // wxComboTextCtrl is a simple text ctrl which forwards
157 // wxEVT_COMMAND_TEXT_UPDATED events and all key events to the combobox
158 // ----------------------------------------------------------------------------
160 class wxComboTextCtrl
: public wxTextCtrl
163 wxComboTextCtrl(wxComboControl
*combo
,
164 const wxString
& value
,
166 const wxValidator
& validator
);
169 void OnKey(wxKeyEvent
& event
);
170 void OnText(wxCommandEvent
& event
);
173 wxComboControl
*m_combo
;
175 DECLARE_EVENT_TABLE()
178 // ----------------------------------------------------------------------------
179 // event tables and such
180 // ----------------------------------------------------------------------------
182 BEGIN_EVENT_TABLE(wxComboButton
, wxButton
)
183 EVT_BUTTON(wxID_ANY
, wxComboButton::OnButton
)
186 BEGIN_EVENT_TABLE(wxComboListBox
, wxListBox
)
187 EVT_LISTBOX(wxID_ANY
, wxComboListBox::OnSelect
)
188 EVT_LISTBOX_DCLICK(wxID_ANY
, wxComboListBox::OnSelect
)
189 EVT_MOTION(wxComboListBox::OnMouseMove
)
190 EVT_LEFT_UP(wxComboListBox::OnLeftUp
)
193 BEGIN_EVENT_TABLE(wxComboControl
, wxControl
)
194 EVT_KEY_DOWN(wxComboControl::OnKey
)
195 EVT_KEY_UP(wxComboControl::OnKey
)
198 BEGIN_EVENT_TABLE(wxComboTextCtrl
, wxTextCtrl
)
199 EVT_KEY_DOWN(wxComboTextCtrl::OnKey
)
200 EVT_KEY_UP(wxComboTextCtrl::OnKey
)
201 EVT_TEXT(wxID_ANY
, wxComboTextCtrl::OnText
)
204 IMPLEMENT_DYNAMIC_CLASS(wxComboBox
, wxControl
)
206 // ============================================================================
208 // ============================================================================
210 // ----------------------------------------------------------------------------
211 // wxComboControl creation
212 // ----------------------------------------------------------------------------
214 void wxComboControl::Init()
216 m_popup
= (wxComboPopup
*)NULL
;
217 m_winPopup
= (wxPopupComboWindow
*)NULL
;
218 m_isPopupShown
= false;
223 bool wxComboControl::Create(wxWindow
*parent
,
225 const wxString
& value
,
229 const wxValidator
& validator
,
230 const wxString
& name
)
232 // first create our own window, i.e. the one which will contain all
234 style
&= ~wxBORDER_NONE
;
235 style
|= wxBORDER_SUNKEN
;
236 if ( !wxControl::Create(parent
, id
, pos
, size
, style
, validator
, name
) )
239 // create the text control and the button as our siblings (*not* children),
240 // don't care about size/position here - they will be set in DoMoveWindow()
241 m_btn
= new wxComboButton(this);
242 m_text
= new wxComboTextCtrl(this,
244 style
& wxCB_READONLY
? wxTE_READONLY
: 0,
247 // for compatibility with the other ports, the height specified is the
248 // combined height of the combobox itself and the popup
249 if ( size
.y
== wxDefaultCoord
)
251 // ok, use default height for popup too
252 m_heightPopup
= wxDefaultCoord
;
256 m_heightPopup
= size
.y
- DoGetBestSize().y
;
262 // create the popup window immediately here to allow creating the controls
263 // with parent == GetPopupWindow() from the derived class ctor
264 m_winPopup
= new wxPopupComboWindow(this);
266 // have to disable this window to avoid interfering it with message
267 // processing to the text and the button... but pretend it is enabled to
268 // make IsEnabled() return true
269 wxControl::Enable(false); // don't use non virtual Disable() here!
272 CreateInputHandler(wxINP_HANDLER_COMBOBOX
);
277 wxComboControl::~wxComboControl()
279 // as the button and the text control are the parent's children and not
280 // ours, we have to delete them manually - they are not deleted
281 // automatically by wxWidgets when we're deleted
288 // ----------------------------------------------------------------------------
290 // ----------------------------------------------------------------------------
292 void wxComboControl::DoSetSize(int x
, int y
,
293 int width
, int WXUNUSED(height
),
296 // combo height is always fixed
297 wxControl::DoSetSize(x
, y
, width
, DoGetBestSize().y
, sizeFlags
);
300 wxSize
wxComboControl::DoGetBestClientSize() const
302 wxSize sizeBtn
= m_btn
->GetBestSize(),
303 sizeText
= m_text
->GetBestSize();
304 wxCoord widthPopup
= 0;
308 widthPopup
= m_popup
->GetBestWidth();
311 return wxSize(wxMax(sizeText
.x
+ g_comboMargin
+ sizeBtn
.x
, widthPopup
),
312 wxMax(sizeBtn
.y
, sizeText
.y
));
315 void wxComboControl::DoMoveWindow(int x
, int y
, int width
, int height
)
317 wxControl::DoMoveWindow(x
, y
, width
, height
);
319 // position the subcontrols inside the client area
320 wxRect rectBorders
= GetRenderer()->GetBorderDimensions(GetBorder());
323 width
-= rectBorders
.x
+ rectBorders
.width
;
324 height
-= rectBorders
.y
+ rectBorders
.height
;
326 wxSize sizeBtn
= m_btn
->GetBestSize();
328 wxCoord wText
= width
- sizeBtn
.x
;
329 wxPoint p
= GetParent() ? GetParent()->GetClientAreaOrigin() : wxPoint(0,0);
330 m_text
->SetSize(x
- p
.x
, y
- p
.y
, wText
, height
);
331 m_btn
->SetSize(x
- p
.x
+ wText
, y
- p
.y
, sizeBtn
.x
, height
);
334 // ----------------------------------------------------------------------------
336 // ----------------------------------------------------------------------------
338 bool wxComboControl::Enable(bool enable
)
340 if ( !wxControl::Enable(enable
) )
343 m_btn
->Enable(enable
);
344 m_text
->Enable(enable
);
349 bool wxComboControl::Show(bool show
)
351 if ( !wxControl::Show(show
) )
364 void wxComboControl::DoSetToolTip(wxToolTip
*tooltip
)
366 wxControl::DoSetToolTip(tooltip
);
368 // Set tool tip for button and text box
373 const wxString
&tip
= tooltip
->GetTip();
374 m_text
->SetToolTip(tip
);
375 m_btn
->SetToolTip(tip
);
379 m_text
->SetToolTip(NULL
);
380 m_btn
->SetToolTip(NULL
);
384 #endif // wxUSE_TOOLTIPS
386 // ----------------------------------------------------------------------------
387 // popup window handling
388 // ----------------------------------------------------------------------------
390 void wxComboControl::SetPopupControl(wxComboPopup
*popup
)
395 void wxComboControl::ShowPopup()
397 wxCHECK_RET( m_popup
, _T("no popup to show in wxComboControl") );
398 wxCHECK_RET( !IsPopupShown(), _T("popup window already shown") );
400 wxControl
*control
= m_popup
->GetControl();
402 // size and position the popup window correctly
403 m_winPopup
->SetSize(GetSize().x
,
404 m_heightPopup
== wxDefaultCoord
? control
->GetBestSize().y
406 wxSize sizePopup
= m_winPopup
->GetClientSize();
407 control
->SetSize(0, 0, sizePopup
.x
, sizePopup
.y
);
409 // some controls don't accept the size we give then: e.g. a listbox may
410 // require more space to show its last row
411 wxSize sizeReal
= control
->GetSize();
412 if ( sizeReal
!= sizePopup
)
414 m_winPopup
->SetClientSize(sizeReal
);
417 m_winPopup
->PositionNearCombo();
421 m_winPopup
->Popup(m_text
);
423 m_popup
->SetSelection(m_text
->GetValue());
425 m_isPopupShown
= true;
428 void wxComboControl::HidePopup()
430 wxCHECK_RET( m_popup
, _T("no popup to hide in wxComboControl") );
431 wxCHECK_RET( IsPopupShown(), _T("popup window not shown") );
433 m_winPopup
->Dismiss();
435 m_isPopupShown
= false;
438 void wxComboControl::OnSelect(const wxString
& value
)
440 m_text
->SetValue(value
);
446 void wxComboControl::OnDismiss()
452 // ----------------------------------------------------------------------------
454 // ----------------------------------------------------------------------------
456 wxComboTextCtrl::wxComboTextCtrl(wxComboControl
*combo
,
457 const wxString
& value
,
459 const wxValidator
& validator
)
460 : wxTextCtrl(combo
->GetParent(), wxID_ANY
, value
,
461 wxDefaultPosition
, wxDefaultSize
,
462 wxBORDER_NONE
| style
,
468 void wxComboTextCtrl::OnText(wxCommandEvent
& event
)
470 if ( m_combo
->IsPopupShown() )
472 m_combo
->GetPopupControl()->SetSelection(GetValue());
475 // we need to make a copy of the event to have the correct originating
477 wxCommandEvent event2
= event
;
478 event2
.SetEventObject(m_combo
);
479 event2
.SetId(m_combo
->GetId());
481 // there is a small incompatibility with wxMSW here: the combobox gets the
482 // event before the text control in our case which corresponds to SMW
483 // CBN_EDITUPDATE notification and not CBN_EDITCHANGE one wxMSW currently
486 // if this is really a problem, we can play games with the event handlers
487 // to circumvent this
488 (void)m_combo
->ProcessEvent(event2
);
493 // pass the keys we don't process to the combo first
494 void wxComboTextCtrl::OnKey(wxKeyEvent
& event
)
496 switch ( event
.GetKeyCode() )
499 // the popup control gets it first but only if it is shown
500 if ( !m_combo
->IsPopupShown() )
511 (void)m_combo
->ProcessEvent(event
);
518 // ----------------------------------------------------------------------------
520 // ----------------------------------------------------------------------------
522 wxComboListBox::wxComboListBox(wxComboControl
*combo
, int style
)
523 : wxListBox(combo
->GetPopupWindow(), wxID_ANY
,
524 wxDefaultPosition
, wxDefaultSize
,
526 wxBORDER_SIMPLE
| wxLB_INT_HEIGHT
| style
),
529 // we don't react to the mouse events outside the window at all
533 wxComboListBox::~wxComboListBox()
537 bool wxComboListBox::SetSelection(const wxString
& value
)
539 // FindItem() would just find the current item for an empty string (it
540 // always matches), but we want to show the first one in such case
545 wxListBox::SetSelection(0);
547 //else: empty listbox - nothing to do
549 else if ( !FindItem(value
) )
558 void wxComboListBox::OnSelect(wxCommandEvent
& event
)
562 // first update the combo and close the listbox
563 m_combo
->OnSelect(event
.GetString());
565 // next let the user code have the event
567 // all fields are already filled by the listbox, just change the event
568 // type and send it to the combo
569 wxCommandEvent event2
= event
;
570 event2
.SetEventType(wxEVT_COMMAND_COMBOBOX_SELECTED
);
571 event2
.SetEventObject(m_combo
);
572 event2
.SetId(m_combo
->GetId());
573 m_combo
->ProcessEvent(event2
);
575 //else: ignore the events resulting from just moving the mouse initially
578 void wxComboListBox::OnShow()
580 // nobody clicked us yet
584 bool wxComboListBox::PerformAction(const wxControlAction
& action
,
586 const wxString
& strArg
)
589 if ( action
== wxACTION_LISTBOX_FIND
)
591 // we don't let the listbox handle this as instead of just using the
592 // single key presses, as usual, we use the text ctrl value as prefix
593 // and this is done by wxComboControl itself
597 return wxListBox::PerformAction(action
, numArg
, strArg
);
600 void wxComboListBox::OnLeftUp(wxMouseEvent
& event
)
602 // we should dismiss the combo now
608 void wxComboListBox::OnMouseMove(wxMouseEvent
& event
)
610 // while a wxComboListBox is shown, it always has capture, so if it doesn't
611 // we're about to go away anyhow (normally this shouldn't happen at all,
612 // but I don't put assert here as it just might do on other platforms and
613 // it doesn't break anything anyhow)
614 if ( this == wxWindow::GetCapture() )
616 if ( HitTest(event
.GetPosition()) == wxHT_WINDOW_INSIDE
)
620 //else: popup shouldn't react to the mouse motions outside it, it only
621 // captures the mouse to be able to detect when it must be
622 // dismissed, so don't call Skip()
626 wxCoord
wxComboListBox::GetBestWidth() const
628 wxSize size
= wxListBox::GetBestSize();
632 wxSize
wxComboListBox::DoGetBestClientSize() const
634 // don't return size too big or we risk to not fit on the screen
635 wxSize size
= wxListBox::DoGetBestClientSize();
636 wxCoord hChar
= GetCharHeight();
638 int nLines
= size
.y
/ hChar
;
640 // 10 is the same limit as used by wxMSW
649 // ----------------------------------------------------------------------------
651 // ----------------------------------------------------------------------------
653 void wxComboBox::Init()
655 m_lbox
= (wxListBox
*)NULL
;
658 wxComboBox::wxComboBox(wxWindow
*parent
,
660 const wxString
& value
,
663 const wxArrayString
& choices
,
665 const wxValidator
& validator
,
666 const wxString
& name
)
670 Create(parent
, id
, value
, pos
, size
, choices
, style
, validator
, name
);
673 bool wxComboBox::Create(wxWindow
*parent
,
675 const wxString
& value
,
678 const wxArrayString
& choices
,
680 const wxValidator
& validator
,
681 const wxString
& name
)
683 wxCArrayString
chs(choices
);
685 return Create(parent
, id
, value
, pos
, size
, chs
.GetCount(),
686 chs
.GetStrings(), style
, validator
, name
);
689 bool wxComboBox::Create(wxWindow
*parent
,
691 const wxString
& value
,
695 const wxString choices
[],
697 const wxValidator
& validator
,
698 const wxString
& name
)
700 if ( !wxComboControl::Create(parent
, id
, value
, pos
, size
, style
,
706 wxComboListBox
*combolbox
=
707 new wxComboListBox(this, style
& wxCB_SORT
? wxLB_SORT
: 0);
709 m_lbox
->Set(n
, choices
);
711 SetPopupControl(combolbox
);
716 wxComboBox::~wxComboBox()
720 // ----------------------------------------------------------------------------
721 // wxComboBox methods forwarded to wxTextCtrl
722 // ----------------------------------------------------------------------------
724 wxString
wxComboBox::GetValue() const
726 return GetText()->GetValue();
729 void wxComboBox::SetValue(const wxString
& value
)
731 GetText()->SetValue(value
);
734 void wxComboBox::Copy()
739 void wxComboBox::Cut()
744 void wxComboBox::Paste()
749 void wxComboBox::SetInsertionPoint(long pos
)
751 GetText()->SetInsertionPoint(pos
);
754 void wxComboBox::SetInsertionPointEnd()
756 GetText()->SetInsertionPointEnd();
759 long wxComboBox::GetInsertionPoint() const
761 return GetText()->GetInsertionPoint();
764 wxTextPos
wxComboBox::GetLastPosition() const
766 return GetText()->GetLastPosition();
769 void wxComboBox::Replace(long from
, long to
, const wxString
& value
)
771 GetText()->Replace(from
, to
, value
);
774 void wxComboBox::Remove(long from
, long to
)
776 GetText()->Remove(from
, to
);
779 void wxComboBox::SetSelection(long from
, long to
)
781 GetText()->SetSelection(from
, to
);
784 void wxComboBox::SetEditable(bool editable
)
786 GetText()->SetEditable(editable
);
789 // ----------------------------------------------------------------------------
790 // wxComboBox methods forwarded to wxListBox
791 // ----------------------------------------------------------------------------
793 void wxComboBox::Clear()
796 GetText()->SetValue(wxEmptyString
);
799 void wxComboBox::Delete(int n
)
801 wxCHECK_RET( (n
>= 0) && (n
< GetCount()), _T("invalid index in wxComboBox::Delete") );
803 if (GetSelection() == n
)
804 GetText()->SetValue(wxEmptyString
);
806 GetLBox()->Delete(n
);
809 int wxComboBox::GetCount() const
811 return GetLBox()->GetCount();
814 wxString
wxComboBox::GetString(int n
) const
816 wxCHECK_MSG( (n
>= 0) && (n
< GetCount()), wxEmptyString
, _T("invalid index in wxComboBox::GetString") );
818 return GetLBox()->GetString(n
);
821 void wxComboBox::SetString(int n
, const wxString
& s
)
823 wxCHECK_RET( (n
>= 0) && (n
< GetCount()), _T("invalid index in wxComboBox::SetString") );
825 GetLBox()->SetString(n
, s
);
828 int wxComboBox::FindString(const wxString
& s
, bool bCase
) const
830 return GetLBox()->FindString(s
, bCase
);
833 void wxComboBox::SetSelection(int n
)
835 wxCHECK_RET( (n
>= 0) && (n
< GetCount()), _T("invalid index in wxComboBox::Select") );
837 GetLBox()->SetSelection(n
);
838 GetText()->SetValue(GetLBox()->GetString(n
));
841 int wxComboBox::GetSelection() const
843 #if 1 // FIXME:: What is the correct behavior?
844 // if the current value isn't one of the listbox strings, return -1
845 return GetLBox()->GetSelection();
847 // Why oh why is this done this way?
848 // It is not because the value displayed in the text can be found
849 // in the list that it is the item that is selected!
850 return FindString(GetText()->GetValue());
854 int wxComboBox::DoAppend(const wxString
& item
)
856 return GetLBox()->Append(item
);
859 int wxComboBox::DoInsert(const wxString
& item
, int pos
)
861 wxCHECK_MSG(!(GetWindowStyle() & wxCB_SORT
), -1, wxT("can't insert into sorted list"));
862 wxCHECK_MSG((pos
>=0) && (pos
<=GetCount()), -1, wxT("invalid index"));
864 if (pos
== GetCount())
865 return DoAppend(item
);
867 GetLBox()->Insert(item
, pos
);
871 void wxComboBox::DoSetItemClientData(int n
, void* clientData
)
873 GetLBox()->SetClientData(n
, clientData
);
876 void *wxComboBox::DoGetItemClientData(int n
) const
878 return GetLBox()->GetClientData(n
);
881 void wxComboBox::DoSetItemClientObject(int n
, wxClientData
* clientData
)
883 GetLBox()->SetClientObject(n
, clientData
);
886 wxClientData
* wxComboBox::DoGetItemClientObject(int n
) const
888 return GetLBox()->GetClientObject(n
);
891 bool wxComboBox::IsEditable() const
893 return GetText() != NULL
&& (!HasFlag(wxCB_READONLY
) || GetText()->IsEditable());
896 void wxComboBox::Undo()
902 void wxComboBox::Redo()
908 void wxComboBox::SelectAll()
910 GetText()->SelectAll();
913 bool wxComboBox::CanCopy() const
915 if (GetText() != NULL
)
916 return GetText()->CanCopy();
921 bool wxComboBox::CanCut() const
923 if (GetText() != NULL
)
924 return GetText()->CanCut();
929 bool wxComboBox::CanPaste() const
932 return GetText()->CanPaste();
937 bool wxComboBox::CanUndo() const
940 return GetText()->CanUndo();
945 bool wxComboBox::CanRedo() const
948 return GetText()->CanRedo();
954 // ----------------------------------------------------------------------------
956 // ----------------------------------------------------------------------------
958 void wxComboControl::OnKey(wxKeyEvent
& event
)
960 if ( m_isPopupShown
)
962 // pass it to the popped up control
963 (void)m_popup
->GetControl()->ProcessEvent(event
);
971 bool wxComboControl::PerformAction(const wxControlAction
& action
,
973 const wxString
& strArg
)
975 bool processed
= false;
976 if ( action
== wxACTION_COMBOBOX_POPUP
)
978 if ( !m_isPopupShown
)
985 else if ( action
== wxACTION_COMBOBOX_DISMISS
)
987 if ( m_isPopupShown
)
998 return wxControl::PerformAction(action
, numArg
, strArg
);
1004 // ----------------------------------------------------------------------------
1005 // wxStdComboBoxInputHandler
1006 // ----------------------------------------------------------------------------
1008 wxStdComboBoxInputHandler::wxStdComboBoxInputHandler(wxInputHandler
*inphand
)
1009 : wxStdInputHandler(inphand
)
1013 bool wxStdComboBoxInputHandler::HandleKey(wxInputConsumer
*consumer
,
1014 const wxKeyEvent
& event
,
1019 wxControlAction action
;
1020 switch ( event
.GetKeyCode() )
1023 action
= wxACTION_COMBOBOX_POPUP
;
1027 action
= wxACTION_COMBOBOX_DISMISS
;
1031 if ( !action
.IsEmpty() )
1033 consumer
->PerformAction(action
);
1039 return wxStdInputHandler::HandleKey(consumer
, event
, pressed
);
1042 #endif // wxUSE_COMBOBOX