-bool wxComboBox::Create(wxWindow *parent, wxWindowID id,
- const wxString& value,
- const wxPoint& pos,
- const wxSize& size,
- int n, const wxString choices[],
- long style,
- const wxValidator& validator,
- const wxString& name)
-{
- SetName(name);
- SetValidator(validator);
- if (parent) parent->AddChild(this);
- SetBackgroundColour(parent->GetDefaultBackgroundColour()) ;
- SetForegroundColour(parent->GetDefaultForegroundColour()) ;
- m_noStrings = n;
-
- m_windowStyle = style;
-
- if ( id == -1 )
- m_windowId = (int)NewControlId();
- else
- m_windowId = id;
-
- int x = pos.x;
- int y = pos.y;
- int width = size.x;
- int height = size.y;
-
- long msStyle = WS_CHILD | WS_HSCROLL | WS_VSCROLL
- | WS_TABSTOP | WS_VISIBLE | CBS_NOINTEGRALHEIGHT;
- if (m_windowStyle & wxCB_READONLY)
- msStyle |= CBS_DROPDOWNLIST;
- else if (m_windowStyle & wxCB_SIMPLE) // A list (shown always) and edit control
- msStyle |= CBS_SIMPLE;
- else
- msStyle |= CBS_DROPDOWN;
-
- if (m_windowStyle & wxCB_SORT)
- msStyle |= CBS_SORT;
-
- bool want3D;
- WXDWORD exStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &want3D) ;
-
- // Even with extended styles, need to combine with WS_BORDER
- // for them to look right.
- if (want3D || (m_windowStyle & wxSIMPLE_BORDER) || (m_windowStyle & wxRAISED_BORDER) ||
- (m_windowStyle & wxSUNKEN_BORDER) || (m_windowStyle & wxDOUBLE_BORDER))
- msStyle |= WS_BORDER;
-
- HWND wx_combo = CreateWindowEx(exStyle, "COMBOBOX", NULL,
- msStyle,
- 0, 0, 0, 0, (HWND) parent->GetHWND(), (HMENU)m_windowId,
- wxGetInstance(), NULL);
-/*
-#if CTL3D
- if (want3D)
- {
- Ctl3dSubclassCtl(wx_combo);
- m_useCtl3D = TRUE;
- }
+// ----------------------------------------------------------------------------
+// wxComboBox callbacks
+// ----------------------------------------------------------------------------
+
+WXLRESULT wxComboBox::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
+{
+ // TODO: handle WM_CTLCOLOR messages from our EDIT control to be able to
+ // set its colour correctly (to be the same as our own one)
+
+ switch ( nMsg )
+ {
+ case WM_SIZE:
+ // wxStaticBox can generate this message, when modifying the control's style.
+ // This causes the content of the combobox to be selected, for some reason.
+ case WM_STYLECHANGED:
+ {
+ // combobox selection sometimes spontaneously changes when its
+ // size changes, restore it to the old value if necessary
+ if ( !GetEditHWNDIfAvailable() )
+ break;
+
+ long fromOld, toOld;
+ GetSelection(&fromOld, &toOld);
+
+ // if an editable combobox has a not empty text not from the
+ // list, it tries to autocomplete it from the list when it is
+ // resized, but we don't want this to happen as it doesn't seem
+ // to make any sense, so we forcefully restore the old text
+ wxString textOld;
+ if ( !HasFlag(wxCB_READONLY) && GetCurrentSelection() == -1 )
+ textOld = GetValue();
+
+ // eliminate flickering during following hacks
+ wxWindowUpdateLocker lock(this);
+
+ WXLRESULT result = wxChoice::MSWWindowProc(nMsg, wParam, lParam);
+
+ if ( !textOld.empty() && GetValue() != textOld )
+ SetLabel(textOld);
+
+ long fromNew, toNew;
+ GetSelection(&fromNew, &toNew);
+
+ if ( fromOld != fromNew || toOld != toNew )
+ {
+ SetSelection(fromOld, toOld);
+ }
+
+ return result;
+ }
+ }
+
+ return wxChoice::MSWWindowProc(nMsg, wParam, lParam);
+}
+
+bool wxComboBox::MSWProcessEditMsg(WXUINT msg, WXWPARAM wParam, WXLPARAM lParam)
+{
+ switch ( msg )
+ {
+ case WM_CHAR:
+ // for compatibility with wxTextCtrl, generate a special message
+ // when Enter is pressed
+ if ( wParam == VK_RETURN )
+ {
+ if (SendMessage(GetHwnd(), CB_GETDROPPEDSTATE, 0, 0))
+ return false;
+
+ wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER, m_windowId);
+
+ const int sel = GetSelection();
+ event.SetInt(sel);
+ event.SetString(GetValue());
+ InitCommandEventWithItems(event, sel);
+
+ if ( ProcessCommand(event) )
+ {
+ // don't let the event through to the native control
+ // because it doesn't need it and may generate an annoying
+ // beep if it gets it
+ return true;
+ }
+ }
+ // fall through
+
+ case WM_SYSCHAR:
+ return HandleChar(wParam, lParam);
+
+ case WM_SYSKEYDOWN:
+ case WM_KEYDOWN:
+ return HandleKeyDown(wParam, lParam);
+
+ case WM_SYSKEYUP:
+ case WM_KEYUP:
+ return HandleKeyUp(wParam, lParam);
+
+ case WM_SETFOCUS:
+ return HandleSetFocus((WXHWND)wParam);
+
+ case WM_KILLFOCUS:
+ return HandleKillFocus((WXHWND)wParam);
+
+ case WM_CUT:
+ case WM_COPY:
+ case WM_PASTE:
+ return HandleClipboardEvent(msg);
+ }
+
+ return false;
+}
+
+bool wxComboBox::MSWCommand(WXUINT param, WXWORD id)
+{
+ int sel = -1;
+ wxString value;
+
+ switch ( param )
+ {
+ case CBN_DROPDOWN:
+ // remember the last selection, just as wxChoice does
+ m_lastAcceptedSelection = GetCurrentSelection();
+ if ( m_lastAcceptedSelection == -1 )
+ {
+ // but unlike with wxChoice we may have no selection but still
+ // have some text and we should avoid erasing it if the drop
+ // down is cancelled (see #8474)
+ m_lastAcceptedSelection = wxID_NONE;
+ }
+ {
+ wxCommandEvent event(wxEVT_COMMAND_COMBOBOX_DROPDOWN, GetId());
+ event.SetEventObject(this);
+ ProcessCommand(event);
+ }
+ break;
+ case CBN_CLOSEUP:
+ {
+ wxCommandEvent event(wxEVT_COMMAND_COMBOBOX_CLOSEUP, GetId());
+ event.SetEventObject(this);
+ ProcessCommand(event);
+ }
+ break;
+ case CBN_SELENDOK:
+#ifndef __SMARTPHONE__
+ // we need to reset this to prevent the selection from being undone
+ // by wxChoice, see wxChoice::MSWCommand() and comments there
+ m_lastAcceptedSelection = wxID_NONE;