1 /////////////////////////////////////////////////////////////////////////////
2 // Name: 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 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
21 #pragma implementation "univcombobox.h"
24 #include "wx/wxprec.h"
35 #include "wx/button.h"
36 #include "wx/combobox.h"
37 #include "wx/listbox.h"
38 #include "wx/textctrl.h"
39 #include "wx/bmpbuttn.h"
41 #include "wx/validate.h"
44 #include "wx/tooltip.h"
45 #include "wx/popupwin.h"
47 #include "wx/univ/renderer.h"
48 #include "wx/univ/inphand.h"
49 #include "wx/univ/theme.h"
52 The keyboard event flow:
54 1. they always come to the text ctrl
55 2. it forwards the ones it doesn't process to the wxComboControl
56 3. which passes them to the popup window if it is popped up
60 // ----------------------------------------------------------------------------
62 // the margin between the text control and the combo button
63 static const wxCoord g_comboMargin
= 2;
65 // ----------------------------------------------------------------------------
66 // wxComboButton is just a normal button except that it sends commands to the
67 // combobox and not its parent
68 // ----------------------------------------------------------------------------
70 class wxComboButton
: public wxBitmapButton
73 wxComboButton(wxComboControl
*combo
)
74 : wxBitmapButton(combo
->GetParent(), wxID_ANY
, wxNullBitmap
,
75 wxDefaultPosition
, wxDefaultSize
,
76 wxBORDER_NONE
| wxBU_EXACTFIT
)
80 wxBitmap bmpNormal
, bmpFocus
, bmpPressed
, bmpDisabled
;
82 GetRenderer()->GetComboBitmaps(&bmpNormal
,
87 SetBitmapLabel(bmpNormal
);
88 SetBitmapFocus(bmpFocus
.Ok() ? bmpFocus
: bmpNormal
);
89 SetBitmapSelected(bmpPressed
.Ok() ? bmpPressed
: bmpNormal
);
90 SetBitmapDisabled(bmpDisabled
.Ok() ? bmpDisabled
: bmpNormal
);
92 SetBestSize(wxDefaultSize
);
96 void OnButton(wxCommandEvent
& WXUNUSED(event
)) { m_combo
->ShowPopup(); }
98 virtual wxSize
DoGetBestClientSize() const
100 const wxBitmap
& bmp
= GetBitmapLabel();
102 return wxSize(bmp
.GetWidth(), bmp
.GetHeight());
107 wxComboControl
*m_combo
;
109 DECLARE_EVENT_TABLE()
112 // ----------------------------------------------------------------------------
113 // wxComboListBox is a listbox modified to be used as a popup window in a
115 // ----------------------------------------------------------------------------
117 class wxComboListBox
: public wxListBox
, public wxComboPopup
121 wxComboListBox(wxComboControl
*combo
, int style
= 0);
122 virtual ~wxComboListBox();
124 // implement wxComboPopup methods
125 virtual bool SetSelection(const wxString
& s
);
126 virtual wxControl
*GetControl() { return this; }
127 virtual void OnShow();
128 virtual wxCoord
GetBestWidth() const;
130 // fix virtual function hiding
131 virtual void SetSelection(int n
) { DoSetSelection(n
, true); }
132 void SetSelection(int n
, bool select
) { DoSetSelection(n
, select
); }
135 // we shouldn't return height too big from here
136 virtual wxSize
DoGetBestClientSize() const;
138 // filter mouse move events happening outside the list box
139 void OnMouseMove(wxMouseEvent
& event
);
141 // set m_clicked value from here
142 void OnLeftUp(wxMouseEvent
& event
);
144 // called whenever the user selects or activates a listbox item
145 void OnSelect(wxCommandEvent
& event
);
147 // used to process wxUniv actions
148 bool PerformAction(const wxControlAction
& action
,
150 const wxString
& strArg
);
153 // has the mouse been released on this control?
156 DECLARE_EVENT_TABLE()
159 // ----------------------------------------------------------------------------
160 // wxComboTextCtrl is a simple text ctrl which forwards
161 // wxEVT_COMMAND_TEXT_UPDATED events and all key events to the combobox
162 // ----------------------------------------------------------------------------
164 class wxComboTextCtrl
: public wxTextCtrl
167 wxComboTextCtrl(wxComboControl
*combo
,
168 const wxString
& value
,
170 const wxValidator
& validator
);
173 void OnKey(wxKeyEvent
& event
);
174 void OnText(wxCommandEvent
& event
);
177 wxComboControl
*m_combo
;
179 DECLARE_EVENT_TABLE()
182 // ----------------------------------------------------------------------------
183 // event tables and such
184 // ----------------------------------------------------------------------------
186 BEGIN_EVENT_TABLE(wxComboButton
, wxButton
)
187 EVT_BUTTON(wxID_ANY
, wxComboButton::OnButton
)
190 BEGIN_EVENT_TABLE(wxComboListBox
, wxListBox
)
191 EVT_LISTBOX(wxID_ANY
, wxComboListBox::OnSelect
)
192 EVT_LISTBOX_DCLICK(wxID_ANY
, wxComboListBox::OnSelect
)
193 EVT_MOTION(wxComboListBox::OnMouseMove
)
194 EVT_LEFT_UP(wxComboListBox::OnLeftUp
)
197 BEGIN_EVENT_TABLE(wxComboControl
, wxControl
)
198 EVT_KEY_DOWN(wxComboControl::OnKey
)
199 EVT_KEY_UP(wxComboControl::OnKey
)
202 BEGIN_EVENT_TABLE(wxComboTextCtrl
, wxTextCtrl
)
203 EVT_KEY_DOWN(wxComboTextCtrl::OnKey
)
204 EVT_KEY_UP(wxComboTextCtrl::OnKey
)
205 EVT_TEXT(wxID_ANY
, wxComboTextCtrl::OnText
)
208 IMPLEMENT_DYNAMIC_CLASS(wxComboBox
, wxControl
)
210 // ============================================================================
212 // ============================================================================
214 // ----------------------------------------------------------------------------
215 // wxComboControl creation
216 // ----------------------------------------------------------------------------
218 void wxComboControl::Init()
220 m_popup
= (wxComboPopup
*)NULL
;
221 m_winPopup
= (wxPopupComboWindow
*)NULL
;
222 m_isPopupShown
= false;
227 bool wxComboControl::Create(wxWindow
*parent
,
229 const wxString
& value
,
233 const wxValidator
& validator
,
234 const wxString
& name
)
236 // first create our own window, i.e. the one which will contain all
238 style
&= ~wxBORDER_NONE
;
239 style
|= wxBORDER_SUNKEN
;
240 if ( !wxControl::Create(parent
, id
, pos
, size
, style
, validator
, name
) )
243 // create the text control and the button as our siblings (*not* children),
244 // don't care about size/position here - they will be set in DoMoveWindow()
245 m_btn
= new wxComboButton(this);
246 m_text
= new wxComboTextCtrl(this,
248 style
& wxCB_READONLY
? wxTE_READONLY
: 0,
251 // for compatibility with the other ports, the height specified is the
252 // combined height of the combobox itself and the popup
253 if ( size
.y
== wxDefaultCoord
)
255 // ok, use default height for popup too
256 m_heightPopup
= wxDefaultCoord
;
260 m_heightPopup
= size
.y
- DoGetBestSize().y
;
266 // create the popup window immediately here to allow creating the controls
267 // with parent == GetPopupWindow() from the derived class ctor
268 m_winPopup
= new wxPopupComboWindow(this);
270 // have to disable this window to avoid interfering it with message
271 // processing to the text and the button... but pretend it is enabled to
272 // make IsEnabled() return true
273 wxControl::Enable(false); // don't use non virtual Disable() here!
276 CreateInputHandler(wxINP_HANDLER_COMBOBOX
);
281 wxComboControl::~wxComboControl()
283 // as the button and the text control are the parent's children and not
284 // ours, we have to delete them manually - they are not deleted
285 // automatically by wxWidgets when we're deleted
292 // ----------------------------------------------------------------------------
294 // ----------------------------------------------------------------------------
296 void wxComboControl::DoSetSize(int x
, int y
,
297 int width
, int WXUNUSED(height
),
300 // combo height is always fixed
301 wxControl::DoSetSize(x
, y
, width
, DoGetBestSize().y
, sizeFlags
);
304 wxSize
wxComboControl::DoGetBestClientSize() const
306 wxSize sizeBtn
= m_btn
->GetBestSize(),
307 sizeText
= m_text
->GetBestSize();
308 wxCoord widthPopup
= 0;
312 widthPopup
= m_popup
->GetBestWidth();
315 return wxSize(wxMax(sizeText
.x
+ g_comboMargin
+ sizeBtn
.x
, widthPopup
),
316 wxMax(sizeBtn
.y
, sizeText
.y
));
319 void wxComboControl::DoMoveWindow(int x
, int y
, int width
, int height
)
321 wxControl::DoMoveWindow(x
, y
, width
, height
);
323 // position the subcontrols inside the client area
324 wxRect rectBorders
= GetRenderer()->GetBorderDimensions(GetBorder());
327 width
-= rectBorders
.x
+ rectBorders
.width
;
328 height
-= rectBorders
.y
+ rectBorders
.height
;
330 wxSize sizeBtn
= m_btn
->GetBestSize();
332 wxCoord wText
= width
- sizeBtn
.x
;
333 wxPoint p
= GetParent() ? GetParent()->GetClientAreaOrigin() : wxPoint(0,0);
334 m_text
->SetSize(x
- p
.x
, y
- p
.y
, wText
, height
);
335 m_btn
->SetSize(x
- p
.x
+ wText
, y
- p
.y
, sizeBtn
.x
, height
);
338 // ----------------------------------------------------------------------------
340 // ----------------------------------------------------------------------------
342 bool wxComboControl::Enable(bool enable
)
344 if ( !wxControl::Enable(enable
) )
347 m_btn
->Enable(enable
);
348 m_text
->Enable(enable
);
353 bool wxComboControl::Show(bool show
)
355 if ( !wxControl::Show(show
) )
368 void wxComboControl::DoSetToolTip(wxToolTip
*tooltip
)
370 wxControl::DoSetToolTip(tooltip
);
372 // Set tool tip for button and text box
377 const wxString
&tip
= tooltip
->GetTip();
378 m_text
->SetToolTip(tip
);
379 m_btn
->SetToolTip(tip
);
383 m_text
->SetToolTip(NULL
);
384 m_btn
->SetToolTip(NULL
);
388 #endif // wxUSE_TOOLTIPS
390 // ----------------------------------------------------------------------------
391 // popup window handling
392 // ----------------------------------------------------------------------------
394 void wxComboControl::SetPopupControl(wxComboPopup
*popup
)
399 void wxComboControl::ShowPopup()
401 wxCHECK_RET( m_popup
, _T("no popup to show in wxComboControl") );
402 wxCHECK_RET( !IsPopupShown(), _T("popup window already shown") );
404 wxControl
*control
= m_popup
->GetControl();
406 // size and position the popup window correctly
407 m_winPopup
->SetSize(GetSize().x
,
408 m_heightPopup
== wxDefaultCoord
? control
->GetBestSize().y
410 wxSize sizePopup
= m_winPopup
->GetClientSize();
411 control
->SetSize(0, 0, sizePopup
.x
, sizePopup
.y
);
413 // some controls don't accept the size we give then: e.g. a listbox may
414 // require more space to show its last row
415 wxSize sizeReal
= control
->GetSize();
416 if ( sizeReal
!= sizePopup
)
418 m_winPopup
->SetClientSize(sizeReal
);
421 m_winPopup
->PositionNearCombo();
425 m_winPopup
->Popup(m_text
);
427 m_popup
->SetSelection(m_text
->GetValue());
429 m_isPopupShown
= true;
432 void wxComboControl::HidePopup()
434 wxCHECK_RET( m_popup
, _T("no popup to hide in wxComboControl") );
435 wxCHECK_RET( IsPopupShown(), _T("popup window not shown") );
437 m_winPopup
->Dismiss();
439 m_isPopupShown
= false;
442 void wxComboControl::OnSelect(const wxString
& value
)
444 m_text
->SetValue(value
);
450 void wxComboControl::OnDismiss()
456 // ----------------------------------------------------------------------------
458 // ----------------------------------------------------------------------------
460 wxComboTextCtrl::wxComboTextCtrl(wxComboControl
*combo
,
461 const wxString
& value
,
463 const wxValidator
& validator
)
464 : wxTextCtrl(combo
->GetParent(), wxID_ANY
, value
,
465 wxDefaultPosition
, wxDefaultSize
,
466 wxBORDER_NONE
| style
,
472 void wxComboTextCtrl::OnText(wxCommandEvent
& event
)
474 if ( m_combo
->IsPopupShown() )
476 m_combo
->GetPopupControl()->SetSelection(GetValue());
479 // we need to make a copy of the event to have the correct originating
481 wxCommandEvent event2
= event
;
482 event2
.SetEventObject(m_combo
);
483 event2
.SetId(m_combo
->GetId());
485 // there is a small incompatibility with wxMSW here: the combobox gets the
486 // event before the text control in our case which corresponds to SMW
487 // CBN_EDITUPDATE notification and not CBN_EDITCHANGE one wxMSW currently
490 // if this is really a problem, we can play games with the event handlers
491 // to circumvent this
492 (void)m_combo
->ProcessEvent(event2
);
497 // pass the keys we don't process to the combo first
498 void wxComboTextCtrl::OnKey(wxKeyEvent
& event
)
500 switch ( event
.GetKeyCode() )
503 // the popup control gets it first but only if it is shown
504 if ( !m_combo
->IsPopupShown() )
515 (void)m_combo
->ProcessEvent(event
);
522 // ----------------------------------------------------------------------------
524 // ----------------------------------------------------------------------------
526 wxComboListBox::wxComboListBox(wxComboControl
*combo
, int style
)
527 : wxListBox(combo
->GetPopupWindow(), wxID_ANY
,
528 wxDefaultPosition
, wxDefaultSize
,
530 wxBORDER_SIMPLE
| wxLB_INT_HEIGHT
| style
),
533 // we don't react to the mouse events outside the window at all
537 wxComboListBox::~wxComboListBox()
541 bool wxComboListBox::SetSelection(const wxString
& value
)
543 // FindItem() would just find the current item for an empty string (it
544 // always matches), but we want to show the first one in such case
549 wxListBox::SetSelection(0);
551 //else: empty listbox - nothing to do
553 else if ( !FindItem(value
) )
562 void wxComboListBox::OnSelect(wxCommandEvent
& event
)
566 // first update the combo and close the listbox
567 m_combo
->OnSelect(event
.GetString());
569 // next let the user code have the event
571 // all fields are already filled by the listbox, just change the event
572 // type and send it to the combo
573 wxCommandEvent event2
= event
;
574 event2
.SetEventType(wxEVT_COMMAND_COMBOBOX_SELECTED
);
575 event2
.SetEventObject(m_combo
);
576 event2
.SetId(m_combo
->GetId());
577 m_combo
->ProcessEvent(event2
);
579 //else: ignore the events resulting from just moving the mouse initially
582 void wxComboListBox::OnShow()
584 // nobody clicked us yet
588 bool wxComboListBox::PerformAction(const wxControlAction
& action
,
590 const wxString
& strArg
)
593 if ( action
== wxACTION_LISTBOX_FIND
)
595 // we don't let the listbox handle this as instead of just using the
596 // single key presses, as usual, we use the text ctrl value as prefix
597 // and this is done by wxComboControl itself
601 return wxListBox::PerformAction(action
, numArg
, strArg
);
604 void wxComboListBox::OnLeftUp(wxMouseEvent
& event
)
606 // we should dismiss the combo now
612 void wxComboListBox::OnMouseMove(wxMouseEvent
& event
)
614 // while a wxComboListBox is shown, it always has capture, so if it doesn't
615 // we're about to go away anyhow (normally this shouldn't happen at all,
616 // but I don't put assert here as it just might do on other platforms and
617 // it doesn't break anything anyhow)
618 if ( this == wxWindow::GetCapture() )
620 if ( HitTest(event
.GetPosition()) == wxHT_WINDOW_INSIDE
)
624 //else: popup shouldn't react to the mouse motions outside it, it only
625 // captures the mouse to be able to detect when it must be
626 // dismissed, so don't call Skip()
630 wxCoord
wxComboListBox::GetBestWidth() const
632 wxSize size
= wxListBox::GetBestSize();
636 wxSize
wxComboListBox::DoGetBestClientSize() const
638 // don't return size too big or we risk to not fit on the screen
639 wxSize size
= wxListBox::DoGetBestClientSize();
640 wxCoord hChar
= GetCharHeight();
642 int nLines
= size
.y
/ hChar
;
644 // 10 is the same limit as used by wxMSW
653 // ----------------------------------------------------------------------------
655 // ----------------------------------------------------------------------------
657 void wxComboBox::Init()
659 m_lbox
= (wxListBox
*)NULL
;
662 wxComboBox::wxComboBox(wxWindow
*parent
,
664 const wxString
& value
,
667 const wxArrayString
& choices
,
669 const wxValidator
& validator
,
670 const wxString
& name
)
674 Create(parent
, id
, value
, pos
, size
, choices
, style
, validator
, name
);
677 bool wxComboBox::Create(wxWindow
*parent
,
679 const wxString
& value
,
682 const wxArrayString
& choices
,
684 const wxValidator
& validator
,
685 const wxString
& name
)
687 wxCArrayString
chs(choices
);
689 return Create(parent
, id
, value
, pos
, size
, chs
.GetCount(),
690 chs
.GetStrings(), style
, validator
, name
);
693 bool wxComboBox::Create(wxWindow
*parent
,
695 const wxString
& value
,
699 const wxString choices
[],
701 const wxValidator
& validator
,
702 const wxString
& name
)
704 if ( !wxComboControl::Create(parent
, id
, value
, pos
, size
, style
,
710 wxComboListBox
*combolbox
=
711 new wxComboListBox(this, style
& wxCB_SORT
? wxLB_SORT
: 0);
713 m_lbox
->Set(n
, choices
);
715 SetPopupControl(combolbox
);
720 wxComboBox::~wxComboBox()
724 // ----------------------------------------------------------------------------
725 // wxComboBox methods forwarded to wxTextCtrl
726 // ----------------------------------------------------------------------------
728 wxString
wxComboBox::GetValue() const
730 return GetText()->GetValue();
733 void wxComboBox::SetValue(const wxString
& value
)
735 GetText()->SetValue(value
);
738 void wxComboBox::Copy()
743 void wxComboBox::Cut()
748 void wxComboBox::Paste()
753 void wxComboBox::SetInsertionPoint(long pos
)
755 GetText()->SetInsertionPoint(pos
);
758 void wxComboBox::SetInsertionPointEnd()
760 GetText()->SetInsertionPointEnd();
763 long wxComboBox::GetInsertionPoint() const
765 return GetText()->GetInsertionPoint();
768 wxTextPos
wxComboBox::GetLastPosition() const
770 return GetText()->GetLastPosition();
773 void wxComboBox::Replace(long from
, long to
, const wxString
& value
)
775 GetText()->Replace(from
, to
, value
);
778 void wxComboBox::Remove(long from
, long to
)
780 GetText()->Remove(from
, to
);
783 void wxComboBox::SetSelection(long from
, long to
)
785 GetText()->SetSelection(from
, to
);
788 void wxComboBox::SetEditable(bool editable
)
790 GetText()->SetEditable(editable
);
793 // ----------------------------------------------------------------------------
794 // wxComboBox methods forwarded to wxListBox
795 // ----------------------------------------------------------------------------
797 void wxComboBox::Clear()
800 GetText()->SetValue(wxEmptyString
);
803 void wxComboBox::Delete(int n
)
805 wxCHECK_RET( (n
>= 0) && (n
< GetCount()), _T("invalid index in wxComboBox::Delete") );
807 if (GetSelection() == n
)
808 GetText()->SetValue(wxEmptyString
);
810 GetLBox()->Delete(n
);
813 int wxComboBox::GetCount() const
815 return GetLBox()->GetCount();
818 wxString
wxComboBox::GetString(int n
) const
820 wxCHECK_MSG( (n
>= 0) && (n
< GetCount()), wxEmptyString
, _T("invalid index in wxComboBox::GetString") );
822 return GetLBox()->GetString(n
);
825 void wxComboBox::SetString(int n
, const wxString
& s
)
827 wxCHECK_RET( (n
>= 0) && (n
< GetCount()), _T("invalid index in wxComboBox::SetString") );
829 GetLBox()->SetString(n
, s
);
832 int wxComboBox::FindString(const wxString
& s
) const
834 return GetLBox()->FindString(s
);
837 void wxComboBox::SetSelection(int n
)
839 wxCHECK_RET( (n
>= 0) && (n
< GetCount()), _T("invalid index in wxComboBox::Select") );
841 GetLBox()->SetSelection(n
);
842 GetText()->SetValue(GetLBox()->GetString(n
));
845 int wxComboBox::GetSelection() const
847 #if 1 // FIXME:: What is the correct behavior?
848 // if the current value isn't one of the listbox strings, return -1
849 return GetLBox()->GetSelection();
851 // Why oh why is this done this way?
852 // It is not because the value displayed in the text can be found
853 // in the list that it is the item that is selected!
854 return FindString(GetText()->GetValue());
858 int wxComboBox::DoAppend(const wxString
& item
)
860 return GetLBox()->Append(item
);
863 int wxComboBox::DoInsert(const wxString
& item
, int pos
)
865 wxCHECK_MSG(!(GetWindowStyle() & wxCB_SORT
), -1, wxT("can't insert into sorted list"));
866 wxCHECK_MSG((pos
>=0) && (pos
<=GetCount()), -1, wxT("invalid index"));
868 if (pos
== GetCount())
869 return DoAppend(item
);
871 GetLBox()->Insert(item
, pos
);
875 void wxComboBox::DoSetItemClientData(int n
, void* clientData
)
877 GetLBox()->SetClientData(n
, clientData
);
880 void *wxComboBox::DoGetItemClientData(int n
) const
882 return GetLBox()->GetClientData(n
);
885 void wxComboBox::DoSetItemClientObject(int n
, wxClientData
* clientData
)
887 GetLBox()->SetClientObject(n
, clientData
);
890 wxClientData
* wxComboBox::DoGetItemClientObject(int n
) const
892 return GetLBox()->GetClientObject(n
);
895 bool wxComboBox::IsEditable() const
897 return GetText() != NULL
&& (!HasFlag(wxCB_READONLY
) || GetText()->IsEditable());
900 void wxComboBox::Undo()
906 void wxComboBox::Redo()
912 void wxComboBox::SelectAll()
914 GetText()->SelectAll();
917 bool wxComboBox::CanCopy() const
919 if (GetText() != NULL
)
920 return GetText()->CanCopy();
925 bool wxComboBox::CanCut() const
927 if (GetText() != NULL
)
928 return GetText()->CanCut();
933 bool wxComboBox::CanPaste() const
936 return GetText()->CanPaste();
941 bool wxComboBox::CanUndo() const
944 return GetText()->CanUndo();
949 bool wxComboBox::CanRedo() const
952 return GetText()->CanRedo();
958 // ----------------------------------------------------------------------------
960 // ----------------------------------------------------------------------------
962 void wxComboControl::OnKey(wxKeyEvent
& event
)
964 if ( m_isPopupShown
)
966 // pass it to the popped up control
967 (void)m_popup
->GetControl()->ProcessEvent(event
);
975 bool wxComboControl::PerformAction(const wxControlAction
& action
,
977 const wxString
& strArg
)
979 bool processed
= false;
980 if ( action
== wxACTION_COMBOBOX_POPUP
)
982 if ( !m_isPopupShown
)
989 else if ( action
== wxACTION_COMBOBOX_DISMISS
)
991 if ( m_isPopupShown
)
1002 return wxControl::PerformAction(action
, numArg
, strArg
);
1008 // ----------------------------------------------------------------------------
1009 // wxStdComboBoxInputHandler
1010 // ----------------------------------------------------------------------------
1012 wxStdComboBoxInputHandler::wxStdComboBoxInputHandler(wxInputHandler
*inphand
)
1013 : wxStdInputHandler(inphand
)
1017 bool wxStdComboBoxInputHandler::HandleKey(wxInputConsumer
*consumer
,
1018 const wxKeyEvent
& event
,
1023 wxControlAction action
;
1024 switch ( event
.GetKeyCode() )
1027 action
= wxACTION_COMBOBOX_POPUP
;
1031 action
= wxACTION_COMBOBOX_DISMISS
;
1035 if ( !action
.IsEmpty() )
1037 consumer
->PerformAction(action
);
1043 return wxStdInputHandler::HandleKey(consumer
, event
, pressed
);
1046 #endif // wxUSE_COMBOBOX