Like the AUTORADIOBUTTON, the parent of a RADIOBUTTON style button
[wine] / dlls / comctl32 / comboex.c
1 /*
2  * ComboBoxEx control
3  *
4  * Copyright 1998, 1999 Eric Kohl
5  *
6  * NOTES
7  *   This is just a dummy control. An author is needed! Any volunteers?
8  *   I will only improve this control once in a while.
9  *     Eric <ekohl@abo.rhein-zeitung.de>
10  *
11  * TODO:
12  *   - All messages.
13  *   - All notifications.
14  *
15  * FIXME:
16  *   - should include "combo.h" 
17  */
18
19 #include "winbase.h"
20 #include "commctrl.h"
21 #include "comboex.h"
22 #include "debugtools.h"
23
24 DEFAULT_DEBUG_CHANNEL(comboex)
25
26 #define ID_CB_EDIT    1001
27
28 #define COMBOEX_GetInfoPtr(wndPtr) ((COMBOEX_INFO *)GetWindowLongA (hwnd, 0))
29
30
31 /* << COMBOEX_DeleteItem >> */
32
33
34 inline static LRESULT
35 COMBOEX_GetComboControl (HWND hwnd, WPARAM wParam, LPARAM lParam)
36 {
37     COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
38
39     TRACE("\n");
40
41     return (LRESULT)infoPtr->hwndCombo;
42 }
43
44
45 inline static LRESULT
46 COMBOEX_GetEditControl (HWND hwnd, WPARAM wParam, LPARAM lParam)
47 {
48     COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
49
50     if ((GetWindowLongA (hwnd, GWL_STYLE) & CBS_DROPDOWNLIST) != CBS_DROPDOWN)
51         return 0;
52
53     TRACE("-- 0x%x\n", GetDlgItem (infoPtr->hwndCombo, ID_CB_EDIT));
54
55     return (LRESULT)GetDlgItem (infoPtr->hwndCombo, ID_CB_EDIT);
56 }
57
58
59 inline static LRESULT
60 COMBOEX_GetExtendedStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
61 {
62     COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
63
64     return (LRESULT)infoPtr->dwExtStyle;
65 }
66
67
68 inline static LRESULT
69 COMBOEX_GetImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
70 {
71     COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
72
73     TRACE("(0x%08x 0x%08lx)\n", wParam, lParam);
74
75     return (LRESULT)infoPtr->himl;
76 }
77
78
79
80
81 static LRESULT
82 COMBOEX_InsertItemA (HWND hwnd, WPARAM wParam, LPARAM lParam)
83 {
84     /* COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd); */
85
86     FIXME("(0x%08x 0x%08lx)\n", wParam, lParam);
87
88     return -1;
89 }
90
91
92
93 static LRESULT
94 COMBOEX_SetExtendedStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
95 {
96     COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
97     DWORD dwTemp;
98
99     TRACE("(0x%08x 0x%08lx)\n", wParam, lParam);
100
101     dwTemp = infoPtr->dwExtStyle;
102
103     if ((DWORD)wParam) {
104         infoPtr->dwExtStyle = (infoPtr->dwExtStyle & ~(DWORD)wParam) | (DWORD)lParam;
105     }
106     else
107         infoPtr->dwExtStyle = (DWORD)lParam;
108
109     /* FIXME: repaint?? */
110
111     return (LRESULT)dwTemp;
112 }
113
114
115 inline static LRESULT
116 COMBOEX_SetImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
117 {
118     COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
119     HIMAGELIST himlTemp;
120
121     TRACE("(0x%08x 0x%08lx)\n", wParam, lParam);
122
123     himlTemp = infoPtr->himl;
124     infoPtr->himl = (HIMAGELIST)lParam;
125
126     return (LRESULT)himlTemp;
127 }
128
129
130 static LRESULT
131 COMBOEX_SetItemA (HWND hwnd, WPARAM wParam, LPARAM lParam)
132 {
133     /* COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd); */
134
135     FIXME("(%p): stub\n", (LPVOID)lParam);
136
137     return TRUE;
138 }
139
140
141 /* << COMBOEX_SetItem32W >> */
142
143
144 inline static LRESULT
145 COMBOEX_Forward (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
146 {
147     COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
148
149     FIXME("(0x%x 0x%x 0x%lx): stub\n", uMsg, wParam, lParam);
150
151     if (infoPtr->hwndCombo)    
152         return SendMessageA (infoPtr->hwndCombo, uMsg, wParam, lParam);
153
154     return 0;
155 }
156
157
158 static LRESULT
159 COMBOEX_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
160 {
161     COMBOEX_INFO *infoPtr;
162     DWORD dwComboStyle;
163
164     /* allocate memory for info structure */
165     infoPtr = (COMBOEX_INFO *)COMCTL32_Alloc (sizeof(COMBOEX_INFO));
166     if (infoPtr == NULL) {
167         ERR("could not allocate info memory!\n");
168         return 0;
169     }
170
171     SetWindowLongA (hwnd, 0, (DWORD)infoPtr);
172
173
174     /* initialize info structure */
175
176
177     /* create combo box */
178     dwComboStyle = GetWindowLongA (hwnd, GWL_STYLE) &
179                         (CBS_SIMPLE|CBS_DROPDOWN|CBS_DROPDOWNLIST|WS_CHILD);
180
181     infoPtr->hwndCombo = CreateWindowA ("ComboBox", "",
182                          WS_CHILD | WS_VISIBLE | CBS_OWNERDRAWFIXED | dwComboStyle,
183                         0, 0, 0, 0, hwnd, (HMENU)1,
184                         GetWindowLongA (hwnd, GWL_HINSTANCE), NULL);
185
186     return 0;
187 }
188
189
190 static LRESULT
191 COMBOEX_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
192 {
193     COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
194
195
196     if (infoPtr->hwndCombo)
197         DestroyWindow (infoPtr->hwndCombo);
198
199
200
201
202     /* free comboex info data */
203     COMCTL32_Free (infoPtr);
204     SetWindowLongA (hwnd, 0, 0);
205     return 0;
206 }
207
208
209 static LRESULT
210 COMBOEX_Size (HWND hwnd, WPARAM wParam, LPARAM lParam)
211 {
212     COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
213     RECT rect;
214
215     GetClientRect (hwnd, &rect);
216
217     MoveWindow (infoPtr->hwndCombo, 0, 0, rect.right -rect.left,
218                   rect.bottom - rect.top, TRUE);
219
220     return 0;
221 }
222
223
224 static LRESULT WINAPI
225 COMBOEX_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
226 {
227     TRACE("hwnd=%x msg=%x wparam=%x lParam=%lx\n", hwnd, uMsg, wParam, lParam);
228     if (!COMBOEX_GetInfoPtr (hwnd) && (uMsg != WM_CREATE))
229         return DefWindowProcA (hwnd, uMsg, wParam, lParam);
230
231     switch (uMsg)
232     {
233 /*      case CBEM_DELETEITEM: */
234
235         case CBEM_GETCOMBOCONTROL:
236             return COMBOEX_GetComboControl (hwnd, wParam, lParam);
237
238         case CBEM_GETEDITCONTROL:
239             return COMBOEX_GetEditControl (hwnd, wParam, lParam);
240
241         case CBEM_GETEXTENDEDSTYLE:
242             return COMBOEX_GetExtendedStyle (hwnd, wParam, lParam);
243
244         case CBEM_GETIMAGELIST:
245             return COMBOEX_GetImageList (hwnd, wParam, lParam);
246
247 /*      case CBEM_GETITEM32A:
248         case CBEM_GETITEM32W:
249         case CBEM_GETUNICODEFORMAT:
250         case CBEM_HASEDITCHANGED:
251 */
252
253         case CBEM_INSERTITEMA:
254             return COMBOEX_InsertItemA (hwnd, wParam, lParam);
255
256 /*      case CBEM_INSERTITEM32W: */
257
258         case CBEM_SETEXTENDEDSTYLE:
259             return COMBOEX_SetExtendedStyle (hwnd, wParam, lParam);
260
261         case CBEM_SETIMAGELIST:
262             return COMBOEX_SetImageList (hwnd, wParam, lParam);
263
264         case CBEM_SETITEMA:
265             return COMBOEX_SetItemA (hwnd, wParam, lParam);
266
267 /*      case CBEM_SETITEM32W:
268         case CBEM_SETUNICODEFORMAT:
269 */
270
271         case CB_DELETESTRING:
272         case CB_FINDSTRINGEXACT:
273         case CB_GETCOUNT:
274         case CB_GETCURSEL:
275         case CB_GETDROPPEDCONTROLRECT:
276         case CB_GETDROPPEDSTATE:
277         case CB_GETITEMDATA:
278         case CB_GETITEMHEIGHT:
279         case CB_GETLBTEXT:
280         case CB_GETLBTEXTLEN:
281         case CB_GETEXTENDEDUI:
282         case CB_LIMITTEXT:
283         case CB_RESETCONTENT:
284         case CB_SELECTSTRING:
285         case CB_SETCURSEL:
286         case CB_SETDROPPEDWIDTH:
287         case CB_SETEXTENDEDUI:
288         case CB_SETITEMDATA:
289         case CB_SETITEMHEIGHT:
290         case CB_SHOWDROPDOWN:
291             return COMBOEX_Forward (hwnd, uMsg, wParam, lParam);
292
293
294         case WM_CREATE:
295             return COMBOEX_Create (hwnd, wParam, lParam);
296
297         case WM_DESTROY:
298             return COMBOEX_Destroy (hwnd, wParam, lParam);
299
300         case WM_SIZE:
301             return COMBOEX_Size (hwnd, wParam, lParam);
302
303         default:
304             if (uMsg >= WM_USER)
305                 ERR("unknown msg %04x wp=%08x lp=%08lx\n",
306                      uMsg, wParam, lParam);
307             return DefWindowProcA (hwnd, uMsg, wParam, lParam);
308     }
309     return 0;
310 }
311
312
313 VOID
314 COMBOEX_Register (void)
315 {
316     WNDCLASSA wndClass;
317
318     ZeroMemory (&wndClass, sizeof(WNDCLASSA));
319     wndClass.style         = CS_GLOBALCLASS;
320     wndClass.lpfnWndProc   = (WNDPROC)COMBOEX_WindowProc;
321     wndClass.cbClsExtra    = 0;
322     wndClass.cbWndExtra    = sizeof(COMBOEX_INFO *);
323     wndClass.hCursor       = LoadCursorA (0, IDC_ARROWA);
324     wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
325     wndClass.lpszClassName = WC_COMBOBOXEXA;
326  
327     RegisterClassA (&wndClass);
328 }
329
330
331 VOID
332 COMBOEX_Unregister (void)
333 {
334     UnregisterClassA (WC_COMBOBOXEXA, (HINSTANCE)NULL);
335 }
336