]> git.saurik.com Git - wxWidgets.git/blob - src/os2/combobox.cpp
Warning fix.
[wxWidgets.git] / src / os2 / combobox.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        src/os2/combobox.cpp
3 // Purpose:     wxComboBox class
4 // Author:      David Webster
5 // Modified by:
6 // Created:     10/13/99
7 // RCS-ID:      $Id$
8 // Copyright:   (c) David Webster
9 // Licence:     wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14
15 #if wxUSE_COMBOBOX
16
17 #include "wx/combobox.h"
18
19 #ifndef WX_PRECOMP
20     #include "wx/settings.h"
21 #endif
22
23 #include "wx/clipbrd.h"
24 #include "wx/os2/private.h"
25
26 #define OWNER_DRAWN_LISTBOX_EXTRA_SPACE    (1)
27
28 MRESULT EXPENTRY wxComboEditWndProc( HWND   hWnd
29                                     ,UINT   uMessage
30                                     ,MPARAM wParam
31                                     ,MPARAM lParam
32                                    );
33 //
34 // The pointer to standard wnd proc
35 //
36 static WXFARPROC gfnWndprocEdit     = (WXFARPROC)NULL;
37
38 IMPLEMENT_DYNAMIC_CLASS(wxComboBox, wxControl)
39
40 bool wxComboBox::OS2Command( WXUINT uParam, WXWORD WXUNUSED(wId) )
41 {
42     long lSel = GetSelection();
43     wxString sValue;
44
45     switch (uParam)
46     {
47         case CBN_LBSELECT:
48             if (lSel > -1)
49             {
50                 wxCommandEvent vEvent( wxEVT_COMMAND_COMBOBOX_SELECTED, GetId() );
51
52                 vEvent.SetInt(lSel);
53                 vEvent.SetEventObject(this);
54                 vEvent.SetString(GetStringSelection());
55
56                 ProcessCommand(vEvent);
57             }
58             break;
59
60         case CBN_EFCHANGE:
61             {
62                 wxCommandEvent vEvent( wxEVT_COMMAND_TEXT_UPDATED, GetId() );
63
64                 if (lSel == -1L)
65                     sValue = GetValue();
66                 else
67                     sValue = GetStringSelection();
68                 vEvent.SetString(sValue);
69                 vEvent.SetEventObject(this);
70                 ProcessCommand(vEvent);
71             }
72             break;
73     }
74     //
75     // There is no return value for the CBN_ notifications, so always return
76     // false from here to pass the message to DefWindowProc()
77     //
78     return false;
79 } // end of wxComboBox::OS2Command
80
81 bool wxComboBox::Create(
82   wxWindow*                         pParent
83 , wxWindowID                        vId
84 , const wxString&                   rsValue
85 , const wxPoint&                    rPos
86 , const wxSize&                     rSize
87 , const wxArrayString&              asChoices
88 , long                              lStyle
89 , const wxValidator&                rValidator
90 , const wxString&                   rsName
91 )
92 {
93     wxCArrayString chs(asChoices);
94
95     return Create(pParent, vId, rsValue, rPos, rSize, chs.GetCount(),
96                   chs.GetStrings(), lStyle, rValidator, rsName);
97 }
98
99 bool wxComboBox::Create(
100   wxWindow*                         pParent
101 , wxWindowID                        vId
102 , const wxString&                   rsValue
103 , const wxPoint&                    rPos
104 , const wxSize&                     rSize
105 , int                               n
106 , const wxString                    asChoices[]
107 , long                              lStyle
108 , const wxValidator&                rValidator
109 , const wxString&                   rsName
110 )
111 {
112     m_isShown = false;
113
114     if (!CreateControl( pParent
115                        ,vId
116                        ,rPos
117                        ,rSize
118                        ,lStyle
119                        ,rValidator
120                        ,rsName
121                       ))
122         return false;
123
124     //
125     // Get the right style
126     //
127     long                            lSstyle = 0L;
128
129     lSstyle = WS_TABSTOP   |
130               WS_VISIBLE;
131
132     // clipping siblings does not yet work
133     // if (lStyle & wxCLIP_SIBLINGS )
134     //     lSstyle |= WS_CLIPSIBLINGS;
135     if (lStyle & wxCB_READONLY)
136         lSstyle |= CBS_DROPDOWNLIST;
137     else if (lStyle & wxCB_SIMPLE)
138         lSstyle |= CBS_SIMPLE; // A list (shown always) and edit control
139     else
140         lSstyle |= CBS_DROPDOWN;
141
142
143     if (!OS2CreateControl( _T("COMBOBOX")
144                           ,lSstyle
145                          ))
146         return false;
147
148     //
149     // A choice/combobox normally has a white background (or other, depending
150     // on global settings) rather than inheriting the parent's background colour.
151     //
152     SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
153
154     for (int i = 0; i < n; i++)
155     {
156         Append(asChoices[i]);
157     }
158
159     SetSize( rPos.x
160             ,rPos.y
161             ,rSize.x
162             ,rSize.y
163            );
164
165     // Set height to use with sizers i.e. without the dropdown listbox
166     wxFont vFont = GetFont();
167     int nEditHeight;
168     wxGetCharSize( GetHWND(), NULL, &nEditHeight, &vFont );
169     nEditHeight = EDIT_HEIGHT_FROM_CHAR_HEIGHT(nEditHeight);
170     SetBestFittingSize(wxSize(-1,nEditHeight+4));   // +2x2 for the border
171
172     if (!rsValue.empty())
173     {
174         SetValue(rsValue);
175     }
176     gfnWndprocEdit = (WXFARPROC)::WinSubclassWindow( (HWND)GetHwnd()
177                                                     ,(PFNWP)wxComboEditWndProc
178                                                    );
179     ::WinSetWindowULong(GetHwnd(), QWL_USER, (ULONG)this);
180     Show(true);
181     return true;
182 } // end of wxComboBox::Create
183
184 wxString wxComboBox::GetValue() const
185 {
186     return wxGetWindowText(GetHwnd());
187 }
188
189 void wxComboBox::SetValue(
190   const wxString&                   rsValue
191 )
192 {
193     if ( HasFlag(wxCB_READONLY) )
194         SetStringSelection(rsValue);
195     else
196         ::WinSetWindowText(GetHwnd(), (PSZ)rsValue.c_str());
197 } // end of wxComboBox::SetValue
198
199 //
200 // Clipboard operations
201 //
202 void wxComboBox::Copy()
203 {
204     HWND                            hWnd = GetHwnd();
205
206     ::WinSendMsg(hWnd, EM_COPY, (MPARAM)0, (MPARAM)0);
207 } // end of wxComboBox::Copy
208
209 void wxComboBox::Cut()
210 {
211     HWND                            hWnd = GetHwnd();
212
213     ::WinSendMsg(hWnd, EM_CUT, (MPARAM)0, (MPARAM)0);
214 } // end of wxComboBox::Cut
215
216 void wxComboBox::Paste()
217 {
218     HWND                            hWnd = GetHwnd();
219
220     ::WinSendMsg(hWnd, EM_PASTE, (MPARAM)0, (MPARAM)0);
221 } // end of wxComboBox::Paste
222
223 void wxComboBox::SetEditable(
224   bool                              bEditable
225 )
226 {
227     HWND                            hWnd = GetHwnd();
228
229     ::WinSendMsg(hWnd, EM_SETREADONLY, (MPARAM)!bEditable, (MPARAM)0L);
230 } // end of wxComboBox::SetEditable
231
232 void wxComboBox::SetInsertionPoint(
233   long                              lPos
234 )
235 {
236     HWND                            hWnd = GetHwnd();
237
238     ::WinSendMsg(hWnd, EM_SETFIRSTCHAR, MPFROMLONG(lPos), (MPARAM)0);
239 } // end of wxComboBox::SetInsertionPoint
240
241 void wxComboBox::SetInsertionPointEnd()
242 {
243     wxTextPos                       lPos = GetLastPosition();
244
245     SetInsertionPoint(lPos);
246 } // end of wxComboBox::SetInsertionPointEnd
247
248 long wxComboBox::GetInsertionPoint() const
249 {
250     long                            lPos = LONGFROMMR(::WinSendMsg( GetHwnd()
251                                                                    ,LM_QUERYSELECTION
252                                                                    ,(MPARAM)0
253                                                                    ,(MPARAM)0
254                                                                   ));
255    if (lPos == LIT_NONE)
256         return wxNOT_FOUND;
257    return lPos;
258 } // end of wxComboBox::GetInsertionPoint
259
260 wxTextPos wxComboBox::GetLastPosition() const
261 {
262     long                            lLineLength = 0L;
263     WNDPARAMS                       vParams;
264
265     //
266     // Get number of characters in the last (only) line. We'll add this to the character
267     // index for the last line, 1st position.
268     //
269
270
271     vParams.fsStatus = WPM_CCHTEXT;
272     if (::WinSendMsg( GetHwnd()
273                      ,WM_QUERYWINDOWPARAMS
274                      ,&vParams
275                      ,0
276                     ))
277     {
278         lLineLength = (long)vParams.cchText;
279     }
280     else
281         lLineLength = 0L;
282     return lLineLength;
283 } // end of wxComboBox::GetLastPosition
284
285 void wxComboBox::Replace( long lFrom,
286                           long lTo,
287                           const wxString& rsValue )
288 {
289 #if wxUSE_CLIPBOARD
290     HWND                            hWnd = GetHwnd();
291
292     //
293     // Set selection and remove it
294     //
295     ::WinSendMsg(hWnd, EM_SETSEL, MPFROM2SHORT((USHORT)lFrom, (USHORT)lTo), 0);
296     ::WinSendMsg(hWnd, EM_CUT, (MPARAM)0, (MPARAM)0);
297
298     //
299     // Now replace with 'value', by pasting.
300     //
301     wxSetClipboardData( wxDF_TEXT
302                        ,(wxObject *)rsValue.c_str()
303                        ,0
304                        ,0
305                       );
306
307     //
308     // Paste into edit control
309     //
310     ::WinSendMsg(hWnd, EM_PASTE, (MPARAM)0, (MPARAM)0L);
311 #else
312     wxUnusedVar(lFrom);
313     wxUnusedVar(lTo);
314     wxUnusedVar(rsValue);
315 #endif
316 } // end of wxComboBox::Replace
317
318 void wxComboBox::Remove( long lFrom, long lTo)
319 {
320 #if wxUSE_CLIPBOARD
321     HWND                            hWnd = GetHwnd();
322
323     ::WinSendMsg(hWnd, EM_SETSEL, MPFROM2SHORT((USHORT)lFrom, (USHORT)lTo), 0);
324     ::WinSendMsg(hWnd, EM_CUT, (MPARAM)0, (MPARAM)0);
325 #else
326     wxUnusedVar(lFrom);
327     wxUnusedVar(lTo);
328 #endif
329 } // end of wxComboBox::Remove
330
331 void wxComboBox::SetSelection( long lFrom, long lTo )
332 {
333     HWND hWnd = GetHwnd();
334     long lFromChar = 0;
335     long lToChar   = 0;
336
337     //
338     // If from and to are both -1, it means
339     // (in wxWidgets) that all text should be selected.
340     // This translates into Windows convention
341     //
342     if ((lFrom == -1L) && (lTo == -1L))
343     {
344         lFromChar = 0;
345         lToChar = -1;
346     }
347
348     ::WinSendMsg( hWnd
349                  ,EM_SETSEL
350                  ,MPFROM2SHORT((USHORT)lFromChar, (USHORT)lToChar)
351                  ,(MPARAM)0
352                 );
353 } // end of wxComboBox::SetSelection
354
355 bool wxComboBox::ProcessEditMsg(
356   WXUINT                            uMsg
357 , WXWPARAM                          wParam
358 , WXLPARAM                          lParam)
359 {
360     SHORT                           vFlag;
361     switch (uMsg)
362     {
363         case WM_CHAR:
364             vFlag = SHORT1FROMMP(wParam);
365             switch(vFlag)
366             {
367                 case KC_CHAR:
368                     return (HandleChar( wParam
369                                        ,lParam
370                                        ,true /* isASCII */
371                                       ));
372
373                 case KC_PREVDOWN:
374                     return (HandleKeyDown( wParam
375                                           ,lParam
376                                          ));
377
378                 case KC_KEYUP:
379                     return (HandleKeyUp( wParam
380                                         ,lParam
381                                        ));
382             }
383             break;
384
385         case WM_SETFOCUS:
386             if (SHORT1FROMMP((MPARAM)lParam) == TRUE)
387                 return(HandleSetFocus((WXHWND)(HWND)wParam));
388             else
389                 return(HandleKillFocus((WXHWND)(HWND)wParam));
390     }
391     return false;
392 } // end of wxComboBox::ProcessEditMsg
393
394 MRESULT EXPENTRY wxComboEditWndProc(
395   HWND                              hWnd
396 , UINT                              uMessage
397 , MPARAM                            wParam
398 , MPARAM                            lParam
399 )
400 {
401     switch (uMessage)
402     {
403         //
404         // Forward some messages to the combobox
405         //
406         case WM_SETFOCUS:
407         case WM_CHAR:
408             {
409                 wxComboBox* pCombo = (wxComboBox *)::WinQueryWindowULong( hWnd
410                                                                          ,QWL_USER
411                                                                         );
412
413                 if (pCombo->ProcessEditMsg( uMessage
414                                            ,wParam
415                                            ,lParam
416                                           ))
417                     return ((MRESULT)0);
418             }
419             break;
420
421         //
422         // TODO: Deal with tooltips here
423         //
424     }
425     return (gfnWndprocEdit(hWnd, (ULONG)uMessage, (MPARAM)wParam, (MPARAM)lParam));
426 } // end of wxComboEditWndProc
427
428 #endif
429  // wxUSE_COMBOBOX