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