1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        src/os2/combobox.cpp
3 // Purpose:     wxComboBox class
4 // Author:      David Webster
5 // Modified by:
6 // Created:     10/13/99
7 // Copyright:   (c) David Webster
8 // Licence:     wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10 
11 // For compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
13 
14 #if wxUSE_COMBOBOX
15 
16 #include "wx/combobox.h"
17 
18 #ifndef WX_PRECOMP
19     #include "wx/settings.h"
20 #endif
21 
22 #include "wx/clipbrd.h"
23 #include "wx/os2/private.h"
24 
25 #define OWNER_DRAWN_LISTBOX_EXTRA_SPACE    (1)
26 
27 MRESULT EXPENTRY wxComboEditWndProc( HWND   hWnd
28                                     ,UINT   uMessage
29                                     ,MPARAM wParam
30                                     ,MPARAM lParam
31                                    );
32 //
33 // The pointer to standard wnd proc
34 //
35 static WXFARPROC gfnWndprocEdit     = (WXFARPROC)NULL;
36 
OS2Command(WXUINT uParam,WXWORD WXUNUSED (wId))37 bool wxComboBox::OS2Command( WXUINT uParam, WXWORD WXUNUSED(wId) )
38 {
39     long lSel = GetSelection();
40     wxString sValue;
41 
42     switch (uParam)
43     {
44         case CBN_LBSELECT:
45             if (lSel > -1)
46             {
47                 wxCommandEvent vEvent( wxEVT_COMBOBOX, GetId() );
48 
49                 vEvent.SetInt(lSel);
50                 vEvent.SetEventObject(this);
51                 vEvent.SetString(GetStringSelection());
52 
53                 ProcessCommand(vEvent);
54             }
55             break;
56 
57         case CBN_EFCHANGE:
58             {
59                 wxCommandEvent vEvent( wxEVT_TEXT, GetId() );
60 
61                 if (lSel == -1L)
62                     sValue = GetValue();
63                 else
64                     sValue = GetStringSelection();
65                 vEvent.SetString(sValue);
66                 vEvent.SetEventObject(this);
67                 ProcessCommand(vEvent);
68             }
69             break;
70     }
71     //
72     // There is no return value for the CBN_ notifications, so always return
73     // false from here to pass the message to DefWindowProc()
74     //
75     return false;
76 } // end of wxComboBox::OS2Command
77 
Create(wxWindow * pParent,wxWindowID vId,const wxString & rsValue,const wxPoint & rPos,const wxSize & rSize,const wxArrayString & asChoices,long lStyle,const wxValidator & rValidator,const wxString & rsName)78 bool wxComboBox::Create(
79   wxWindow*                         pParent
80 , wxWindowID                        vId
81 , const wxString&                   rsValue
82 , const wxPoint&                    rPos
83 , const wxSize&                     rSize
84 , const wxArrayString&              asChoices
85 , long                              lStyle
86 , const wxValidator&                rValidator
87 , const wxString&                   rsName
88 )
89 {
90     wxCArrayString chs(asChoices);
91 
92     return Create(pParent, vId, rsValue, rPos, rSize, chs.GetCount(),
93                   chs.GetStrings(), lStyle, rValidator, rsName);
94 }
95 
Create(wxWindow * pParent,wxWindowID vId,const wxString & rsValue,const wxPoint & rPos,const wxSize & rSize,int n,const wxString asChoices[],long lStyle,const wxValidator & rValidator,const wxString & rsName)96 bool wxComboBox::Create(
97   wxWindow*                         pParent
98 , wxWindowID                        vId
99 , const wxString&                   rsValue
100 , const wxPoint&                    rPos
101 , const wxSize&                     rSize
102 , int                               n
103 , const wxString                    asChoices[]
104 , long                              lStyle
105 , const wxValidator&                rValidator
106 , const wxString&                   rsName
107 )
108 {
109     m_isShown = false;
110 
111     if (!CreateControl( pParent
112                        ,vId
113                        ,rPos
114                        ,rSize
115                        ,lStyle
116                        ,rValidator
117                        ,rsName
118                       ))
119         return false;
120 
121     //
122     // Get the right style
123     //
124     long                            lSstyle = 0L;
125 
126     lSstyle = WS_TABSTOP   |
127               WS_VISIBLE;
128 
129     // clipping siblings does not yet work
130     // if (lStyle & wxCLIP_SIBLINGS )
131     //     lSstyle |= WS_CLIPSIBLINGS;
132     if (lStyle & wxCB_READONLY)
133         lSstyle |= CBS_DROPDOWNLIST;
134     else if (lStyle & wxCB_SIMPLE)
135         lSstyle |= CBS_SIMPLE; // A list (shown always) and edit control
136     else
137         lSstyle |= CBS_DROPDOWN;
138 
139 
140     if (!OS2CreateControl( wxT("COMBOBOX")
141                           ,lSstyle
142                          ))
143         return false;
144 
145     //
146     // A choice/combobox normally has a white background (or other, depending
147     // on global settings) rather than inheriting the parent's background colour.
148     //
149     SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
150 
151     for (int i = 0; i < n; i++)
152     {
153         Append(asChoices[i]);
154     }
155 
156     SetSize( rPos.x
157             ,rPos.y
158             ,rSize.x
159             ,rSize.y
160            );
161 
162     // Set height to use with sizers i.e. without the dropdown listbox
163     wxFont vFont = GetFont();
164     int nEditHeight;
165     wxGetCharSize( GetHWND(), NULL, &nEditHeight, &vFont );
166     nEditHeight = EDIT_HEIGHT_FROM_CHAR_HEIGHT(nEditHeight);
167     SetInitialSize(wxSize(-1,nEditHeight+4));   // +2x2 for the border
168 
169     if (!rsValue.empty())
170     {
171         SetValue(rsValue);
172     }
173     gfnWndprocEdit = (WXFARPROC)::WinSubclassWindow( (HWND)GetHwnd()
174                                                     ,(PFNWP)wxComboEditWndProc
175                                                    );
176     ::WinSetWindowULong(GetHwnd(), QWL_USER, (ULONG)this);
177     Show(true);
178     return true;
179 } // end of wxComboBox::Create
180 
GetValue() const181 wxString wxComboBox::GetValue() const
182 {
183     return HasFlag(wxCB_READONLY) ? GetStringSelection()
184                                   : wxTextEntry::GetValue();
185 }
186 
SetValue(const wxString & value)187 void wxComboBox::SetValue(const wxString& value)
188 {
189     if ( HasFlag(wxCB_READONLY) )
190         SetStringSelection(value);
191     else
192         wxTextEntry::SetValue(value);
193 }
194 
Clear()195 void wxComboBox::Clear()
196 {
197     wxChoice::Clear();
198     if ( !HasFlag(wxCB_READONLY) )
199         wxTextEntry::Clear();
200 }
201 
IsEditable() const202 bool wxComboBox::IsEditable() const
203 {
204     return !HasFlag(wxCB_READONLY) && wxTextEntry::IsEditable();
205 }
206 
ProcessEditMsg(WXUINT uMsg,WXWPARAM wParam,WXLPARAM lParam)207 bool wxComboBox::ProcessEditMsg(
208   WXUINT                            uMsg
209 , WXWPARAM                          wParam
210 , WXLPARAM                          lParam)
211 {
212     SHORT                           vFlag;
213     switch (uMsg)
214     {
215         case WM_CHAR:
216             vFlag = SHORT1FROMMP(wParam);
217             switch(vFlag)
218             {
219                 case KC_CHAR:
220                     return (HandleChar( wParam
221                                        ,lParam
222                                        ,true /* isASCII */
223                                       ));
224 
225                 case KC_PREVDOWN:
226                     return (HandleKeyDown( wParam
227                                           ,lParam
228                                          ));
229 
230                 case KC_KEYUP:
231                     return (HandleKeyUp( wParam
232                                         ,lParam
233                                        ));
234             }
235             break;
236 
237         case WM_SETFOCUS:
238             if (SHORT1FROMMP((MPARAM)lParam) == TRUE)
239                 return(HandleSetFocus((WXHWND)(HWND)wParam));
240             else
241                 return(HandleKillFocus((WXHWND)(HWND)wParam));
242     }
243     return false;
244 } // end of wxComboBox::ProcessEditMsg
245 
wxComboEditWndProc(HWND hWnd,UINT uMessage,MPARAM wParam,MPARAM lParam)246 MRESULT EXPENTRY wxComboEditWndProc(
247   HWND                              hWnd
248 , UINT                              uMessage
249 , MPARAM                            wParam
250 , MPARAM                            lParam
251 )
252 {
253     switch (uMessage)
254     {
255         //
256         // Forward some messages to the combobox
257         //
258         case WM_SETFOCUS:
259         case WM_CHAR:
260             {
261                 wxComboBox* pCombo = (wxComboBox *)::WinQueryWindowULong( hWnd
262                                                                          ,QWL_USER
263                                                                         );
264 
265                 if (pCombo->ProcessEditMsg( uMessage
266                                            ,wParam
267                                            ,lParam
268                                           ))
269                     return ((MRESULT)0);
270             }
271             break;
272 
273         //
274         // TODO: Deal with tooltips here
275         //
276     }
277     return (gfnWndprocEdit(hWnd, (ULONG)uMessage, (MPARAM)wParam, (MPARAM)lParam));
278 } // end of wxComboEditWndProc
279 
280 #endif
281  // wxUSE_COMBOBOX
282