1 ///////////////////////////////////////////////////////////////////////////// 
   4 // Author:      Julian Smart 
   8 // Copyright:   (c) Julian Smart and Markus Holzem 
   9 // Licence:     wxWindows license 
  10 ///////////////////////////////////////////////////////////////////////////// 
  13 #pragma implementation "choice.h" 
  16 // For compilers that support precompilation, includes "wx.h". 
  17 #include "wx/wxprec.h" 
  24 #include "wx/choice.h" 
  28 #include "wx/msw/private.h" 
  30 #if !USE_SHARED_LIBRARY 
  31 IMPLEMENT_DYNAMIC_CLASS(wxChoice
, wxControl
) 
  34 bool wxChoice::MSWCommand(WXUINT param
, WXWORD 
WXUNUSED(id
)) 
  36   if (param 
== CBN_SELCHANGE
) 
  38     wxCommandEvent 
event(wxEVT_COMMAND_CHOICE_SELECTED
, m_windowId
); 
  39     event
.SetInt(GetSelection()); 
  40     event
.SetEventObject(this); 
  41     event
.SetString(GetStringSelection()); 
  42     ProcessCommand(event
); 
  50 bool wxChoice::Create(wxWindow 
*parent
, wxWindowID id
, 
  53        int n
, const wxString choices
[], 
  55            const wxValidator
& validator
, 
  59   SetValidator(validator
); 
  60   if (parent
) parent
->AddChild(this); 
  61   SetBackgroundColour(parent
->GetBackgroundColour()) ; 
  62   SetForegroundColour(parent
->GetForegroundColour()) ; 
  65   m_windowStyle 
= style
; 
  68     m_windowId 
= (int)NewControlId(); 
  77   long msStyle 
= WS_CHILD 
| CBS_DROPDOWNLIST 
| WS_HSCROLL 
| WS_VSCROLL
 
  78                    | WS_TABSTOP 
| WS_VISIBLE
; 
  79   if (m_windowStyle 
& wxCB_SORT
) 
  83   WXDWORD exStyle 
= Determine3DEffects(WS_EX_CLIENTEDGE
, &want3D
) ; 
  85   // Even with extended styles, need to combine with WS_BORDER 
  86   // for them to look right. 
  87   if ( want3D 
|| wxStyleHasBorder(m_windowStyle
) ) 
  90   m_hWnd 
= (WXHWND
)::CreateWindowEx(exStyle
, _T("COMBOBOX"), NULL
, 
  92                    0, 0, 0, 0, (HWND
) parent
->GetHWND(), (HMENU
)m_windowId
, 
  93                    wxGetInstance(), NULL
); 
  95   wxCHECK_MSG( m_hWnd
, FALSE
, _T("Failed to create combobox") ); 
 102     Ctl3dSubclassCtl(wx_combo); // Does CTL3D affect the combobox? I think not. 
 107   // Subclass again for purposes of dialog editing mode 
 110   SetFont(parent
->GetFont()); 
 113   for (i 
= 0; i 
< n
; i
++) 
 119   SetSize(x
, y
, width
, height
); 
 124 void wxChoice::Append(const wxString
& item
) 
 126   SendMessage((HWND
) GetHWND(), CB_ADDSTRING
, 0, (LONG
)(const wxChar 
*)item
); 
 131 void wxChoice::Delete(int n
) 
 133   m_noStrings 
= (int)SendMessage((HWND
) GetHWND(), CB_DELETESTRING
, n
, 0); 
 136 void wxChoice::Clear(void) 
 138   SendMessage((HWND
) GetHWND(), CB_RESETCONTENT
, 0, 0); 
 144 int wxChoice::GetSelection(void) const 
 146   return (int)SendMessage((HWND
) GetHWND(), CB_GETCURSEL
, 0, 0); 
 149 void wxChoice::SetSelection(int n
) 
 151   SendMessage((HWND
) GetHWND(), CB_SETCURSEL
, n
, 0); 
 154 int wxChoice::FindString(const wxString
& s
) const 
 156 #if defined(__WATCOMC__) && defined(__WIN386__) 
 157   // For some reason, Watcom in WIN386 mode crashes in the CB_FINDSTRINGEXACT message. 
 158   // Do it the long way instead. 
 160   for (int i 
= 0; i 
< Number(); i
++) 
 162     int len 
= (int)SendMessage((HWND
) GetHWND(), CB_GETLBTEXT
, i
, (LPARAM
)(LPSTR
)buf
); 
 164     if (strcmp(buf
, (const char *)s
) == 0) 
 169  int pos 
= (int)SendMessage((HWND
) GetHWND(), CB_FINDSTRINGEXACT
, (WPARAM
)-1, (LPARAM
)(LPSTR
)(const wxChar 
*)s
); 
 177 wxString 
wxChoice::GetString(int n
) const 
 179   int len 
= (int)SendMessage((HWND
) GetHWND(), CB_GETLBTEXT
, n
, (long)wxBuffer
); 
 181   return wxString(wxBuffer
); 
 184 void wxChoice::DoSetSize(int x
, int y
, int width
, int height
, int sizeFlags
) 
 186   int currentX
, currentY
; 
 187   GetPosition(¤tX
, ¤tY
); 
 194   if (x 
== -1 || (sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
)) 
 196   if (y 
== -1 || (sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
)) 
 199   AdjustForParentClientOrigin(x1
, y1
, sizeFlags
); 
 201   // If we're prepared to use the existing size, then... 
 202   if (width 
== -1 && height 
== -1 && ((sizeFlags 
& wxSIZE_AUTO
) != wxSIZE_AUTO
)) 
 207   int cx
; // button font dimensions 
 209   wxGetCharSize(GetHWND(), &cx
, &cy
, & this->GetFont()); 
 211   int control_width
, control_height
; 
 213   // Ignore height parameter because height doesn't 
 214   // mean 'initially displayed' height, it refers to the 
 215   // drop-down menu as well. The wxWindows interpretation 
 216   // is different; also, getting the size returns the 
 217   // _displayed_ size (NOT the drop down menu size) 
 218   // so setting-getting-setting size would not work. 
 221   // Deal with default size (using -1 values) 
 224     // Find the longest string 
 225     if (m_noStrings 
== 0) 
 234       for (i 
= 0; i 
< m_noStrings
; i
++) 
 236         wxString 
str(GetString(i
)); 
 237         GetTextExtent(str
, &len
, &ht
, NULL
, NULL
, & this->GetFont()); 
 242       control_width 
= longest 
+ cx
*5; 
 247     // If non-default width... 
 252   // Choice drop-down list depends on number of items (limited to 10) 
 255     if (m_noStrings 
== 0) 
 256         h1 
= EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy
)*10; 
 258         h1 
= EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy
)*(wxMin(10, m_noStrings
) + 1); 
 263   // Calculations may have made text size too small 
 264   if (control_height 
<= 0) 
 265     control_height 
= EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy
); 
 267   if (control_width 
<= 0) 
 270   MoveWindow((HWND
)GetHWND(), x1
, y1
, 
 271              control_width
, control_height
, TRUE
); 
 274 WXHBRUSH 
wxChoice::OnCtlColor(WXHDC pDC
, WXHWND pWnd
, WXUINT nCtlColor
, 
 275       WXUINT message
, WXWPARAM wParam
, WXLPARAM lParam
) 
 280 long wxChoice::MSWWindowProc(WXUINT nMsg
, WXWPARAM wParam
, WXLPARAM lParam
) 
 287         if (GetWindowStyleFlag() & wxPROCESS_ENTER) 
 288           return DLGC_WANTALLKEYS; 
 293       case WM_CHAR: // Always an ASCII character 
 295         if (wParam == VK_RETURN) 
 297           wxCommandEvent event(wxEVENT_TYPE_TEXT_ENTER_COMMAND); 
 298           event.commandString = ((wxTextCtrl *)item)->GetValue(); 
 299           event.eventObject = item; 
 300           item->ProcessCommand(event); 
 308         int x 
= (int)LOWORD(lParam
); 
 309         int y 
= (int)HIWORD(lParam
); 
 311        // Ok, this is truly weird, but if a panel with a wxChoice loses the 
 312        // focus, then you get a *fake* WM_LBUTTONUP message 
 313        // with x = 65535 and y = 65535. 
 314        // Filter out this nonsense. 
 315        if (x 
== 65535 && y 
== 65535) 
 321   return wxWindow::MSWWindowProc(nMsg
, wParam
, lParam
); 
 324 wxString 
wxChoice::GetStringSelection (void) const 
 326   int sel 
= GetSelection (); 
 328     return wxString(this->GetString (sel
)); 
 330     return wxString(_T("")); 
 333 bool wxChoice::SetStringSelection (const wxString
& s
) 
 335   int sel 
= FindString (s
); 
 345 void wxChoice::Command(wxCommandEvent 
& event
) 
 347   SetSelection (event
.GetInt()); 
 348   ProcessCommand (event
);