1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     wxComboBox class 
   4 // Author:      David Webster 
   8 // Copyright:   (c) David Webster 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 #include "wx/combobox.h" 
  14 // For compilers that support precompilation, includes "wx.h". 
  15 #include "wx/wxprec.h" 
  23 #include "wx/combobox.h" 
  24 #include "wx/clipbrd.h" 
  25 #include "wx/os2/private.h" 
  27 #define OWNER_DRAWN_LISTBOX_EXTRA_SPACE    (1) 
  29 MRESULT EXPENTRY 
wxComboEditWndProc( HWND   hWnd
 
  35 // The pointer to standard wnd proc 
  37 static WXFARPROC gfnWndprocEdit     
= (WXFARPROC
)NULL
; 
  39 IMPLEMENT_DYNAMIC_CLASS(wxComboBox
, wxControl
) 
  41 bool wxComboBox::OS2Command( 
  43 , WXWORD                            
WXUNUSED(wId
) 
  52             if (GetSelection() > -1) 
  54                 wxCommandEvent      
vEvent( wxEVT_COMMAND_COMBOBOX_SELECTED
 
  58                 vEvent
.SetInt(GetSelection()); 
  59                 vEvent
.SetEventObject(this); 
  60                 vEvent
.SetString((char*)GetStringSelection().c_str()); 
  61                 ProcessCommand(vEvent
); 
  67                 wxCommandEvent      
vEvent( wxEVT_COMMAND_TEXT_UPDATED
 
  75                 vEvent
.SetString((char*)GetValue().c_str()); 
  76                 vEvent
.SetEventObject(this); 
  77                 ProcessCommand(vEvent
); 
  82     // There is no return value for the CBN_ notifications, so always return 
  83     // FALSE from here to pass the message to DefWindowProc() 
  86 } // end of wxComboBox::OS2Command 
  88 bool wxComboBox::Create( 
  91 , const wxString
&                   rsValue
 
  95 , const wxString                    asChoices
[] 
  98 , const wxValidator
&                rValidator
 
 100 , const wxString
&                   rsName
 
 104     if (!OS2CreateControl( pParent
 
 117     // Get the right style 
 121     lSstyle 
= WS_TABSTOP   
| 
 124     if (lStyle 
& wxCLIP_SIBLINGS 
) 
 125         lSstyle 
|= WS_CLIPSIBLINGS
; 
 126     if (lStyle 
& wxCB_READONLY
) 
 127         lSstyle 
|= CBS_DROPDOWNLIST
; 
 128     else if (lStyle 
& wxCB_SIMPLE
) 
 129         lSstyle 
|= CBS_SIMPLE
; // A list (shown always) and edit control 
 131         lSstyle 
|= CBS_DROPDOWN
; 
 134     if (!OS2CreateControl( "COMBOBOX" 
 140     // A choice/combobox normally has a white background (or other, depending 
 141     // on global settings) rather than inheriting the parent's background colour. 
 143     SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW
)); 
 145     SetFont(pParent
->GetFont()); 
 149     for (i 
= 0; i 
< n
; i
++) 
 151         Append(asChoices
[i
]); 
 159     if (!rsValue
.IsEmpty()) 
 163     gfnWndprocEdit 
= (WXFARPROC
)::WinSubclassWindow( (HWND
)GetHwnd() 
 164                                                     ,(PFNWP
)wxComboEditWndProc
 
 166     ::WinSetWindowULong(GetHwnd(), QWL_USER
, (ULONG
)this); 
 168 } // end of wxComboBox::Create 
 170 void wxComboBox::SetValue( 
 171   const wxString
&                   rsValue
 
 175     // If newlines are denoted by just 10, must stick 13 in front. 
 178     int                             nLen 
= rsValue
.Length(); 
 181     for (i 
= 0; i 
< nLen
; i 
++) 
 183         if ((i 
> 0) && (rsValue
[i
] == 10) && (rsValue
[i 
- 1] != 13)) 
 188         wxChar
*                     zTmp 
= new wxChar
[nLen 
+ nSingletons 
+ 1]; 
 191         for (i 
= 0; i 
< nLen
; i 
++) 
 193             if ((i 
> 0) && (rsValue
[i
] == 10) && (rsValue
[i 
- 1] != 13)) 
 198             zTmp
[j
] = rsValue
[i
]; 
 202         ::WinSetWindowText(GetHwnd(), zTmp
); 
 206         ::WinSetWindowText(GetHwnd(), rsValue
.c_str()); 
 207 } // end of wxComboBox::SetValue 
 210 // Clipboard operations 
 212 void wxComboBox::Copy() 
 214     HWND                            hWnd 
= GetHwnd(); 
 216     ::WinSendMsg(hWnd
, EM_COPY
, (MPARAM
)0, (MPARAM
)0); 
 217 } // end of wxComboBox::Copy 
 219 void wxComboBox::Cut() 
 221     HWND                            hWnd 
= GetHwnd(); 
 223     ::WinSendMsg(hWnd
, EM_CUT
, (MPARAM
)0, (MPARAM
)0); 
 224 } // end of wxComboBox::Cut 
 226 void wxComboBox::Paste() 
 228     HWND                            hWnd 
= GetHwnd(); 
 230     ::WinSendMsg(hWnd
, EM_PASTE
, (MPARAM
)0, (MPARAM
)0); 
 231 } // end of wxComboBox::Paste 
 233 void wxComboBox::SetEditable( 
 237     HWND                            hWnd 
= GetHwnd(); 
 239     ::WinSendMsg(hWnd
, EM_SETREADONLY
, (MPARAM
)!bEditable
, (MPARAM
)0L); 
 240 } // end of wxComboBox::SetEditable 
 242 void wxComboBox::SetInsertionPoint( 
 246     HWND                            hWnd 
= GetHwnd(); 
 248     ::WinSendMsg(hWnd
, EM_SETFIRSTCHAR
, MPFROMLONG(lPos
), (MPARAM
)0); 
 249 } // end of wxComboBox::SetInsertionPoint 
 251 void wxComboBox::SetInsertionPointEnd() 
 253     long                            lPos 
= GetLastPosition(); 
 255     SetInsertionPoint(lPos
); 
 256 } // end of wxComboBox::SetInsertionPointEnd 
 258 long wxComboBox::GetInsertionPoint() const 
 260     long                            lPos 
= LONGFROMMR(::WinSendMsg( GetHwnd() 
 265    if (lPos 
== LIT_NONE
) 
 268 } // end of wxComboBox::GetInsertionPoint 
 270 long wxComboBox::GetLastPosition() const 
 272     HWND                            hEditWnd 
= GetHwnd(); 
 273     long                            lLineLength 
= 0L; 
 277     // Get number of characters in the last (only) line. We'll add this to the character 
 278     // index for the last line, 1st position. 
 282     vParams
.fsStatus 
= WPM_CCHTEXT
; 
 283     if (::WinSendMsg( GetHwnd() 
 284                      ,WM_QUERYWINDOWPARAMS
 
 289         lLineLength 
= (long)vParams
.cchText
; 
 294 } // end of wxComboBox::GetLastPosition 
 296 void wxComboBox::Replace( 
 299 , const wxString
&                   rsValue
 
 303     HWND                            hWnd 
= GetHwnd(); 
 304     long                            lFromChar 
= lFrom
; 
 308     // Set selection and remove it 
 310     ::WinSendMsg(hWnd
, EM_SETSEL
, MPFROM2SHORT((USHORT
)lFrom
, (USHORT
)lTo
), 0); 
 311     ::WinSendMsg(hWnd
, EM_CUT
, (MPARAM
)0, (MPARAM
)0); 
 314     // Now replace with 'value', by pasting. 
 316     wxSetClipboardData( wxDF_TEXT
 
 317                        ,(wxObject 
*)rsValue
.c_str() 
 323     // Paste into edit control 
 325     ::WinSendMsg(hWnd
, EM_PASTE
, (MPARAM
)0, (MPARAM
)0L); 
 327 } // end of wxComboBox::Replace 
 329 void wxComboBox::Remove( 
 335     HWND                            hWnd 
= GetHwnd(); 
 336     long                            lFromChar 
= lFrom
; 
 339     ::WinSendMsg(hWnd
, EM_SETSEL
, MPFROM2SHORT((USHORT
)lFrom
, (USHORT
)lTo
), 0); 
 340     ::WinSendMsg(hWnd
, EM_CUT
, (MPARAM
)0, (MPARAM
)0); 
 342 } // end of wxComboBox::Remove 
 344 void wxComboBox::SetSelection( 
 349     HWND                            hWnd 
= GetHwnd(); 
 350     long                            lFromChar 
= lFrom
; 
 354     // If from and to are both -1, it means 
 355     // (in wxWindows) that all text should be selected. 
 356     // This translates into Windows convention 
 358     if ((lFrom 
== -1L) && (lTo 
== -1L)) 
 366                  ,MPFROM2SHORT((USHORT
)lFromChar
, (USHORT
)lToChar
) 
 369 } // end of wxComboBox::SetSelection 
 371 void wxComboBox::DoSetSize( 
 379     wxControl::DoSetSize( nX
 
 385 } // end of wxComboBox::DoSetSize 
 387 bool wxComboBox::ProcessEditMsg( 
 396             vFlag 
= SHORT1FROMMP(wParam
); 
 400                     return (HandleChar( SHORT1FROMMP(wParam
) 
 406                     return (HandleKeyDown( SHORT1FROMMP(wParam
) 
 411                     return (HandleKeyUp( SHORT1FROMMP(wParam
) 
 418 } // end of WinGuiBase_CComboBox::ProcessEditMsg 
 420 MRESULT EXPENTRY 
wxComboEditWndProc( 
 428     wxWindow
*                       pWin 
= NULL
; 
 430     hWndCombo 
= ::WinQueryWindow(hWnd
, QW_PARENT
); 
 431     pWin 
= (wxWindow
*)wxFindWinFromHandle((WXHWND
)hWndCombo
); 
 435         // Forward some messages to the combobox 
 439                 wxComboBox
*         pCombo 
= wxDynamicCast( pWin
 
 443                 if (pCombo
->ProcessEditMsg( uMessage
 
 452         // TODO: Deal with tooltips here 
 455     return (gfnWndprocEdit(hWnd
, (ULONG
)uMessage
, (MPARAM
)wParam
, (MPARAM
)lParam
)); 
 456 } // end of wxComboEditWndProc