1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     wxComboBox class 
   4 // Author:      Julian Smart 
   8 // Copyright:   (c) Julian Smart and Markus Holzem 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  13 #pragma implementation "combobox.h" 
  16 // For compilers that support precompilation, includes "wx.h". 
  17 #include "wx/wxprec.h" 
  29 #include "wx/combobox.h" 
  30 #include "wx/clipbrd.h" 
  31 #include "wx/msw/private.h" 
  33 #if !USE_SHARED_LIBRARY 
  34 IMPLEMENT_DYNAMIC_CLASS(wxComboBox
, wxControl
) 
  37 bool wxComboBox::MSWCommand(WXUINT param
, WXWORD 
WXUNUSED(id
)) 
  39   if (param 
== CBN_SELCHANGE
) 
  41     wxCommandEvent 
event(wxEVENT_TYPE_COMBOBOX_COMMAND
, m_windowId
); 
  42     event
.SetInt(GetSelection()); 
  43     event
.SetEventObject(this); 
  44     event
.SetString(copystring(GetStringSelection())); 
  45     ProcessCommand(event
); 
  46     delete[] event
.GetString(); 
  52 bool wxComboBox::Create(wxWindow 
*parent
, wxWindowID id
, 
  53            const wxString
& value
, 
  56                    int n
, const wxString choices
[], 
  58            const wxValidator
& validator
, 
  62   SetValidator(validator
); 
  63   if (parent
) parent
->AddChild(this); 
  64   SetBackgroundColour(parent
->GetDefaultBackgroundColour()) ; 
  65   SetForegroundColour(parent
->GetDefaultForegroundColour()) ; 
  68   m_windowStyle 
= style
; 
  71         m_windowId 
= (int)NewControlId(); 
  80   long msStyle 
= WS_CHILD 
| WS_HSCROLL 
| WS_VSCROLL
 
  81                      | WS_TABSTOP 
| WS_VISIBLE 
| CBS_NOINTEGRALHEIGHT
; 
  82   if (m_windowStyle 
& wxCB_READONLY
) 
  83     msStyle 
|= CBS_DROPDOWNLIST
; 
  84   else if (m_windowStyle 
& wxCB_SIMPLE
) // A list (shown always) and edit control 
  85     msStyle 
|= CBS_SIMPLE
; 
  87     msStyle 
|= CBS_DROPDOWN
; 
  89   if (m_windowStyle 
& wxCB_SORT
) 
  93   WXDWORD exStyle 
= Determine3DEffects(WS_EX_CLIENTEDGE
, &want3D
) ; 
  95   // Even with extended styles, need to combine with WS_BORDER 
  96   // for them to look right. 
  97   if (want3D 
|| (m_windowStyle 
& wxSIMPLE_BORDER
) || (m_windowStyle 
& wxRAISED_BORDER
) || 
  98        (m_windowStyle 
& wxSUNKEN_BORDER
) || (m_windowStyle 
& wxDOUBLE_BORDER
)) 
 101   HWND wx_combo 
= CreateWindowEx(exStyle
, "COMBOBOX", NULL
, 
 103                    0, 0, 0, 0, (HWND
) parent
->GetHWND(), (HMENU
)m_windowId
, 
 104                    wxGetInstance(), NULL
); 
 109     Ctl3dSubclassCtl(wx_combo); 
 115   m_hWnd 
= (WXHWND
)wx_combo
; 
 117   // Subclass again for purposes of dialog editing mode 
 118   SubclassWin((WXHWND
)wx_combo
); 
 120   SetFont(* parent
->GetFont()); 
 122   for (i 
= 0; i 
< n
; i
++) 
 123     SendMessage(wx_combo
, CB_INSERTSTRING
, i
, (LONG
)(const char *)choices
[i
]); 
 124   SendMessage(wx_combo
, CB_SETCURSEL
, i
, 0); 
 126   SetSize(x
, y
, width
, height
); 
 128     SetWindowText(wx_combo
, (const char *)value
); 
 133 wxString 
wxComboBox::GetValue(void) const 
 135   GetWindowText((HWND
) GetHWND(), wxBuffer
, 500); 
 136   return wxString(wxBuffer
); 
 139 void wxComboBox::SetValue(const wxString
& value
) 
 141   // If newlines are denoted by just 10, must stick 13 in front. 
 143   int len 
= value
.Length(); 
 145   for (i 
= 0; i 
< len
; i 
++) 
 147     if ((i 
> 0) && (value
[i
] == 10) && (value
[i
-1] != 13)) 
 152     char *tmp 
= new char[len 
+ singletons 
+ 1]; 
 154     for (i 
= 0; i 
< len
; i 
++) 
 156       if ((i 
> 0) && (value
[i
] == 10) && (value
[i
-1] != 13)) 
 165     SetWindowText((HWND
) GetHWND(), tmp
); 
 169     SetWindowText((HWND
) GetHWND(), (const char *)value
); 
 172 // Clipboard operations 
 173 void wxComboBox::Copy(void) 
 175   HWND hWnd 
= (HWND
) GetHWND(); 
 176   SendMessage(hWnd
, WM_COPY
, 0, 0L); 
 179 void wxComboBox::Cut(void) 
 181   HWND hWnd 
= (HWND
) GetHWND(); 
 182   SendMessage(hWnd
, WM_CUT
, 0, 0L); 
 185 void wxComboBox::Paste(void) 
 187   HWND hWnd 
= (HWND
) GetHWND(); 
 188   SendMessage(hWnd
, WM_PASTE
, 0, 0L); 
 191 void wxComboBox::SetEditable(bool editable
) 
 193   // Can't implement in MSW? 
 194 //  HWND hWnd = (HWND) GetHWND(); 
 195 //  SendMessage(hWnd, EM_SETREADONLY, (WPARAM)!editable, (LPARAM)0L); 
 198 void wxComboBox::SetInsertionPoint(long pos
) 
 201   HWND hWnd = (HWND) GetHWND(); 
 203   SendMessage(hWnd, EM_SETSEL, pos, pos); 
 204   SendMessage(hWnd, EM_SCROLLCARET, (WPARAM)0, (LPARAM)0); 
 206   SendMessage(hWnd, EM_SETSEL, 0, MAKELPARAM(pos, pos)); 
 209   SendMessage(hWnd, EM_REPLACESEL, 0, (LPARAM)nothing); 
 213 void wxComboBox::SetInsertionPointEnd(void) 
 216   long pos = GetLastPosition(); 
 217   SetInsertionPoint(pos); 
 221 long wxComboBox::GetInsertionPoint(void) const 
 224   DWORD Pos=(DWORD)SendMessage((HWND) GetHWND(), EM_GETSEL, 0, 0L); 
 230 long wxComboBox::GetLastPosition(void) const 
 233     HWND hWnd = (HWND) GetHWND(); 
 235     // Will always return a number > 0 (according to docs) 
 236     int noLines = (int)SendMessage(hWnd, EM_GETLINECOUNT, (WPARAM)0, (LPARAM)0L); 
 238     // This gets the char index for the _beginning_ of the last line 
 239     int charIndex = (int)SendMessage(hWnd, EM_LINEINDEX, (WPARAM)(noLines-1), (LPARAM)0L); 
 241     // Get number of characters in the last line. We'll add this to the character 
 242     // index for the last line, 1st position. 
 243     int lineLength = (int)SendMessage(hWnd, EM_LINELENGTH, (WPARAM)charIndex, (LPARAM)0L); 
 245     return (long)(charIndex + lineLength); 
 250 void wxComboBox::Replace(long from
, long to
, const wxString
& value
) 
 253     HWND hWnd 
= (HWND
) GetHWND(); 
 254     long fromChar 
= from
; 
 257     // Set selection and remove it 
 259     SendMessage(hWnd
, CB_SETEDITSEL
, fromChar
, toChar
); 
 261     SendMessage(hWnd
, CB_SETEDITSEL
, (WPARAM
)0, (LPARAM
)MAKELONG(fromChar
, toChar
)); 
 263     SendMessage(hWnd
, WM_CUT
, (WPARAM
)0, (LPARAM
)0); 
 265     // Now replace with 'value', by pasting. 
 266     wxSetClipboardData(wxDF_TEXT
, (wxObject 
*)(const char *)value
, 0, 0); 
 268     // Paste into edit control 
 269     SendMessage(hWnd
, WM_PASTE
, (WPARAM
)0, (LPARAM
)0L); 
 273 void wxComboBox::Remove(long from
, long to
) 
 275     HWND hWnd 
= (HWND
) GetHWND(); 
 276     long fromChar 
= from
; 
 279     // Cut all selected text 
 281     SendMessage(hWnd
, CB_SETEDITSEL
, fromChar
, toChar
); 
 283     SendMessage(hWnd
, CB_SETEDITSEL
, (WPARAM
)0, (LPARAM
)MAKELONG(fromChar
, toChar
)); 
 285     SendMessage(hWnd
, WM_CUT
, (WPARAM
)0, (LPARAM
)0); 
 288 void wxComboBox::SetSelection(long from
, long to
) 
 290     HWND hWnd 
= (HWND
) GetHWND(); 
 291     long fromChar 
= from
; 
 293     // if from and to are both -1, it means 
 294     // (in wxWindows) that all text should be selected. 
 295     // This translates into Windows convention 
 296     if ((from 
== -1) && (to 
== -1)) 
 303     SendMessage(hWnd
, CB_SETEDITSEL
, (WPARAM
)fromChar
, (LPARAM
)toChar
); 
 304 //    SendMessage(hWnd, EM_SCROLLCARET, (WPARAM)0, (LPARAM)0); 
 306     // WPARAM is 0: selection is scrolled into view 
 307     SendMessage(hWnd
, CB_SETEDITSEL
, (WPARAM
)0, (LPARAM
)MAKELONG(fromChar
, toChar
));