Release 940804
[wine/gsoc-2012-control.git] / controls / combo.c
blobd05917607625d392a08184cbcb0ac85d338e6357
1 /*
2 * Interface code to COMBOBOX widget
4 * Copyright Martin Ayotte, 1993
6 */
8 #define DEBUG_COMBO
9 /*
10 #define DEBUG_COMBO
13 static char Copyright[] = "Copyright Martin Ayotte, 1993";
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <sys/types.h>
18 #include <sys/stat.h>
20 #include "windows.h"
21 #include "combo.h"
22 #include "heap.h"
23 #include "win.h"
24 #include "prototypes.h"
26 HBITMAP hComboBit = 0;
28 LPHEADCOMBO ComboGetStorageHeader(HWND hwnd);
29 int CreateComboStruct(HWND hwnd);
32 /***********************************************************************
33 * ComboWndProc
35 LONG ComboBoxWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam )
37 WORD wRet;
38 RECT rect;
39 int y, count;
40 int width, height;
41 int AltState;
42 WND *wndPtr;
43 LPHEADCOMBO lphc;
44 HDC hDC, hMemDC;
45 BITMAP bm;
46 char str[128];
47 PAINTSTRUCT paintstruct;
48 static RECT rectsel;
49 switch(message)
51 case WM_CREATE:
52 wndPtr = WIN_FindWndPtr(hwnd);
53 if (wndPtr == NULL) return 0;
54 #ifdef DEBUG_COMBO
55 printf("Combo WM_CREATE %lX !\n", lphc);
56 #endif
57 if (hComboBit == (HBITMAP)NULL)
58 hComboBit = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_COMBO));
59 GetObject(hComboBit, sizeof(BITMAP), (LPSTR)&bm);
60 wndPtr->dwStyle &= 0xFFFFFFFFL ^ (WS_VSCROLL | WS_HSCROLL);
61 GetWindowRect(hwnd, &rect);
62 width = rect.right - rect.left;
63 height = rect.bottom - rect.top;
64 SetWindowPos(hwnd, 0, 0, 0, width + bm.bmHeight, bm.bmHeight,
65 SWP_NOMOVE | SWP_NOZORDER);
66 CreateComboStruct(hwnd);
67 lphc = ComboGetStorageHeader(hwnd);
68 if (lphc == NULL) return 0;
69 if (wndPtr->dwStyle & CBS_SIMPLE)
70 /* lphc->hWndEdit = CreateWindow("EDIT", "", */
71 lphc->hWndEdit = CreateWindow("STATIC", "",
72 WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | SS_LEFT,
73 0, 0, width - bm.bmHeight, bm.bmHeight,
74 hwnd, 1, wndPtr->hInstance, 0L);
75 else
76 lphc->hWndEdit = CreateWindow("STATIC", "",
77 WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | SS_LEFT,
78 0, 0, width - bm.bmHeight, bm.bmHeight,
79 hwnd, 1, wndPtr->hInstance, 0L);
80 lphc->hWndLBox = CreateWindow("LISTBOX", "",
81 WS_POPUP | WS_BORDER | WS_VSCROLL | LBS_NOTIFY,
82 rect.left, rect.top + bm.bmHeight,
83 width, height, wndPtr->hwndParent, 0,
84 wndPtr->hInstance, (LPSTR)MAKELONG(0, hwnd));
85 ShowWindow(lphc->hWndLBox, SW_HIDE);
86 #ifdef DEBUG_COMBO
87 printf("Combo Creation LBox=%X!\n", lphc->hWndLBox);
88 #endif
89 return 0;
90 case WM_DESTROY:
91 lphc = ComboGetStorageHeader(hwnd);
92 if (lphc == 0) return 0;
94 DestroyWindow(lphc->hWndEdit);
96 DestroyWindow(lphc->hWndLBox);
97 free(lphc);
99 *((LPHEADCOMBO *)&wndPtr->wExtra[1]) = 0;
100 printf("Combo WM_DESTROY after clearing wExtra !\n");
102 #ifdef DEBUG_COMBO
103 printf("Combo WM_DESTROY %lX !\n", lphc);
104 #endif
105 return DefWindowProc( hwnd, message, wParam, lParam );
106 case WM_SHOWWINDOW:
107 #ifdef DEBUG_COMBO
108 printf("ComboBox WM_SHOWWINDOW hWnd=%04X !\n", hwnd);
109 #endif
110 if (!(wParam == 0 && lParam == 0L)) {
111 InvalidateRect(hwnd, NULL, TRUE);
113 break;
115 case WM_COMMAND:
116 wndPtr = WIN_FindWndPtr(hwnd);
117 lphc = ComboGetStorageHeader(hwnd);
118 if (lphc == NULL) return 0;
119 if (LOWORD(lParam) == lphc->hWndLBox) {
120 switch(HIWORD(lParam)) {
121 case LBN_SELCHANGE:
122 lphc->dwState = lphc->dwState & (CB_SHOWDROPDOWN ^ 0xFFFFFFFFL);
123 ShowWindow(lphc->hWndLBox, SW_HIDE);
124 y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L);
125 if (y != LB_ERR) {
126 SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, (LPARAM)str);
127 SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, (LPARAM)str);
129 SendMessage(GetParent(hwnd), WM_COMMAND, wndPtr->wIDmenu,
130 MAKELONG(hwnd, CBN_SELCHANGE));
131 break;
132 case LBN_DBLCLK:
133 SendMessage(GetParent(hwnd), WM_COMMAND, wndPtr->wIDmenu,
134 MAKELONG(hwnd, CBN_DBLCLK));
135 break;
138 break;
139 case WM_LBUTTONDOWN:
140 printf("Combo WM_LBUTTONDOWN wParam=%x lParam=%lX !\n", wParam, lParam);
141 GetClientRect(hwnd, &rect);
142 rect.left = rect.right - (rect.bottom - rect.top);
143 hDC = GetDC(hwnd);
144 InflateRect(&rect, -1, -1);
145 DrawReliefRect(hDC, rect, 1, 1);
146 ReleaseDC(hwnd, hDC);
147 wndPtr = WIN_FindWndPtr(hwnd);
148 lphc = ComboGetStorageHeader(hwnd);
149 if (lphc == NULL) return 0;
150 lphc->dwState = lphc->dwState ^ CB_SHOWDROPDOWN;
151 if ((lphc->dwState & CB_SHOWDROPDOWN) == CB_SHOWDROPDOWN) {
152 ShowWindow(lphc->hWndLBox, SW_SHOW);
153 SetFocus(lphc->hWndLBox);
155 else {
156 printf("before Combo Restore Focus !\n");
157 SetFocus(lphc->hWndEdit);
158 printf("before Combo List Hide !\n");
159 ShowWindow(lphc->hWndLBox, SW_HIDE);
160 printf("before Combo List GetCurSel !\n");
161 y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L);
162 if (y != LB_ERR) {
163 printf("before Combo List GetText !\n");
164 SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, (LPARAM)str);
165 SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, (LPARAM)str);
167 printf("End of Combo List Hide !\n");
169 break;
170 case WM_LBUTTONUP:
171 printf("Combo WM_LBUTTONUP wParam=%x lParam=%lX !\n", wParam, lParam);
172 GetClientRect(hwnd, &rect);
173 rect.left = rect.right - (rect.bottom - rect.top);
174 hDC = GetDC(hwnd);
175 InflateRect(&rect, -1, -1);
176 DrawReliefRect(hDC, rect, 1, 0);
177 ReleaseDC(hwnd, hDC);
178 break;
179 case WM_KEYDOWN:
180 wndPtr = WIN_FindWndPtr(hwnd);
181 lphc = ComboGetStorageHeader(hwnd);
182 if (lphc == NULL) return 0;
183 y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L);
184 count = SendMessage(lphc->hWndLBox, LB_GETCOUNT, 0, 0L);
185 printf("COMBOBOX // GetKeyState(VK_MENU)=%d\n", GetKeyState(VK_MENU));
186 if (GetKeyState(VK_MENU) < 0) {
187 lphc->dwState = lphc->dwState ^ CB_SHOWDROPDOWN;
188 if ((lphc->dwState & CB_SHOWDROPDOWN) == CB_SHOWDROPDOWN) {
189 ShowWindow(lphc->hWndLBox, SW_SHOW);
190 SetFocus(lphc->hWndLBox);
192 else {
193 ShowWindow(lphc->hWndLBox, SW_HIDE);
194 y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L);
195 if (y != LB_ERR) {
196 SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, (LPARAM)str);
197 SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, (LPARAM)str);
201 else {
202 switch(wParam) {
203 case VK_HOME:
204 y = 0;
205 break;
206 case VK_END:
207 y = count - 1;
208 break;
209 case VK_UP:
210 y--;
211 break;
212 case VK_DOWN:
213 y++;
214 break;
216 if (y < 0) y = 0;
217 if (y >= count) y = count - 1;
218 SendMessage(lphc->hWndLBox, LB_SETCURSEL, y, 0L);
219 SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, (LPARAM)str);
220 SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, (LPARAM)str);
221 SendMessage(GetParent(hwnd), WM_COMMAND, wndPtr->wIDmenu,
222 MAKELONG(hwnd, CBN_SELCHANGE));
224 break;
225 case WM_MEASUREITEM:
226 printf("ComboBoxWndProc WM_MEASUREITEM !\n");
227 return(SendMessage(GetParent(hwnd), WM_MEASUREITEM, wParam, lParam));
228 case WM_CTLCOLOR:
229 return(SendMessage(GetParent(hwnd), WM_CTLCOLOR, wParam, lParam));
230 case WM_PAINT:
231 GetClientRect(hwnd, &rect);
232 hDC = BeginPaint(hwnd, &paintstruct);
233 hMemDC = CreateCompatibleDC(hDC);
234 if (hMemDC != 0 && hComboBit != 0) {
235 GetObject(hComboBit, sizeof(BITMAP), (LPSTR)&bm);
236 SelectObject(hMemDC, hComboBit);
237 BitBlt(hDC, rect.right - bm.bmWidth, 0,
238 bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
240 DeleteDC(hMemDC);
241 EndPaint(hwnd, &paintstruct);
242 lphc = ComboGetStorageHeader(hwnd);
243 if (lphc == NULL) return 0;
244 InvalidateRect(lphc->hWndEdit, NULL, TRUE);
245 UpdateWindow(lphc->hWndEdit);
246 if ((lphc->dwState & CB_SHOWDROPDOWN) == CB_SHOWDROPDOWN) {
247 InvalidateRect(lphc->hWndLBox, NULL, TRUE);
248 UpdateWindow(lphc->hWndLBox);
250 break;
251 case WM_SETFOCUS:
252 lphc = ComboGetStorageHeader(hwnd);
253 if (lphc == NULL) return 0;
254 SetFocus(lphc->hWndEdit);
255 break;
256 case WM_KILLFOCUS:
257 lphc = ComboGetStorageHeader(hwnd);
258 if (lphc == NULL) return 0;
259 ShowWindow(lphc->hWndLBox, SW_HIDE);
260 y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L);
261 if (y != LB_ERR) {
262 SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, (LPARAM)str);
263 SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, (LPARAM)str);
265 break;
266 case CB_ADDSTRING:
267 #ifdef DEBUG_COMBO
268 printf("CB_ADDSTRING '%s' !\n", (LPSTR)lParam);
269 #endif
270 lphc = ComboGetStorageHeader(hwnd);
271 if (lphc == NULL) return 0;
272 return(SendMessage(lphc->hWndLBox, LB_ADDSTRING, wParam, lParam));
273 case CB_GETLBTEXT:
274 #ifdef DEBUG_COMBO
275 printf("CB_GETLBTEXT #%u !\n", wParam);
276 #endif
277 lphc = ComboGetStorageHeader(hwnd);
278 if (lphc == NULL) return 0;
279 return(SendMessage(lphc->hWndLBox, LB_GETTEXT, wParam, lParam));
280 case CB_GETLBTEXTLEN:
281 printf("CB_GETLBTEXTLEN !\n");
282 lphc = ComboGetStorageHeader(hwnd);
283 if (lphc == NULL) return 0;
284 return(SendMessage(lphc->hWndLBox, LB_GETTEXTLEN, wParam, lParam));
285 case CB_INSERTSTRING:
286 printf("CB_INSERTSTRING '%s' !\n", (LPSTR)lParam);
287 lphc = ComboGetStorageHeader(hwnd);
288 if (lphc == NULL) return 0;
289 return(SendMessage(lphc->hWndLBox, LB_INSERTSTRING, wParam, lParam));
290 case CB_DELETESTRING:
291 printf("CB_DELETESTRING #%u !\n", wParam);
292 lphc = ComboGetStorageHeader(hwnd);
293 if (lphc == NULL) return 0;
294 return(SendMessage(lphc->hWndLBox, LB_DELETESTRING, wParam, 0L));
295 case CB_RESETCONTENT:
296 printf("CB_RESETCONTENT !\n");
297 lphc = ComboGetStorageHeader(hwnd);
298 if (lphc == NULL) return 0;
299 return(SendMessage(lphc->hWndLBox, LB_RESETCONTENT, 0, 0L));
300 case CB_DIR:
301 printf("ComboBox CB_DIR !\n");
302 lphc = ComboGetStorageHeader(hwnd);
303 if (lphc == NULL) return 0;
304 return(SendMessage(lphc->hWndLBox, LB_DIR, wParam, lParam));
305 case CB_FINDSTRING:
306 lphc = ComboGetStorageHeader(hwnd);
307 return(SendMessage(lphc->hWndLBox, LB_FINDSTRING, wParam, lParam));
308 case CB_GETCOUNT:
309 lphc = ComboGetStorageHeader(hwnd);
310 if (lphc == NULL) return 0;
311 return(SendMessage(lphc->hWndLBox, LB_GETCOUNT, 0, 0L));
312 case CB_GETCURSEL:
313 printf("ComboBox CB_GETCURSEL !\n");
314 lphc = ComboGetStorageHeader(hwnd);
315 if (lphc == NULL) return 0;
316 return(SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L));
317 case CB_SETCURSEL:
318 printf("ComboBox CB_SETCURSEL wParam=%X !\n", wParam);
319 lphc = ComboGetStorageHeader(hwnd);
320 if (lphc == NULL) return 0;
321 return(SendMessage(lphc->hWndLBox, LB_SETCURSEL, wParam, 0L));
322 case CB_GETEDITSEL:
323 printf("ComboBox CB_GETEDITSEL !\n");
324 lphc = ComboGetStorageHeader(hwnd);
325 if (lphc == NULL) return 0;
326 /* return(SendMessage(lphc->hWndEdit, EM_GETSEL, 0, 0L)); */
327 break;
328 case CB_SETEDITSEL:
329 printf("ComboBox CB_SETEDITSEL lParam=%lX !\n", lParam);
330 lphc = ComboGetStorageHeader(hwnd);
331 if (lphc == NULL) return 0;
332 /* return(SendMessage(lphc->hWndEdit, EM_SETSEL, 0, lParam)); */
333 break;
334 case CB_SELECTSTRING:
335 printf("ComboBox CB_SELECTSTRING !\n");
336 lphc = ComboGetStorageHeader(hwnd);
337 if (lphc == NULL) return 0;
338 break;
339 case CB_SHOWDROPDOWN:
340 printf("ComboBox CB_SHOWDROPDOWN !\n");
341 lphc = ComboGetStorageHeader(hwnd);
342 if (lphc == NULL) return 0;
343 lphc->dwState = lphc->dwState | CB_SHOWDROPDOWN;
344 if (wParam != 0) {
345 ShowWindow(lphc->hWndLBox, SW_SHOW);
347 else {
348 lphc->dwState = lphc->dwState ^ CB_SHOWDROPDOWN;
349 ShowWindow(lphc->hWndLBox, SW_HIDE);
350 SendMessage(GetParent(hwnd), WM_COMMAND, wndPtr->wIDmenu,
351 MAKELONG(hwnd, CBN_DROPDOWN));
353 break;
354 case CB_GETITEMDATA:
355 printf("ComboBox CB_GETITEMDATA wParam=%X !\n", wParam);
356 lphc = ComboGetStorageHeader(hwnd);
357 if (lphc == NULL) return 0;
358 return(SendMessage(lphc->hWndLBox, LB_GETITEMDATA, wParam, 0L));
359 break;
360 case CB_SETITEMDATA:
361 printf("ComboBox CB_SETITEMDATA wParam=%X lParam=%lX !\n", wParam, lParam);
362 lphc = ComboGetStorageHeader(hwnd);
363 if (lphc == NULL) return 0;
364 return(SendMessage(lphc->hWndLBox, LB_SETITEMDATA, wParam, lParam));
365 break;
366 case CB_LIMITTEXT:
367 printf("ComboBox CB_LIMITTEXT !\n");
368 lphc = ComboGetStorageHeader(hwnd);
369 if (lphc == NULL) return 0;
370 /* return(SendMessage(lphc->hWndEdit, EM_LIMITTEXT, wParam, 0L)); */
371 break;
373 default:
374 return DefWindowProc( hwnd, message, wParam, lParam );
376 return 0;
381 LPHEADCOMBO ComboGetStorageHeader(HWND hwnd)
383 WND *wndPtr;
384 LPHEADCOMBO lphc;
385 wndPtr = WIN_FindWndPtr(hwnd);
386 if (wndPtr == 0) {
387 printf("Bad Window handle on ComboBox !\n");
388 return 0;
390 lphc = *((LPHEADCOMBO *)&wndPtr->wExtra[1]);
391 return lphc;
396 int CreateComboStruct(HWND hwnd)
398 WND *wndPtr;
399 LPHEADCOMBO lphc;
400 wndPtr = WIN_FindWndPtr(hwnd);
401 if (wndPtr == 0) {
402 printf("Bad Window handle on ComboBox !\n");
403 return 0;
405 lphc = (LPHEADCOMBO)malloc(sizeof(HEADCOMBO));
406 *((LPHEADCOMBO *)&wndPtr->wExtra[1]) = lphc;
407 lphc->dwState = 0;
408 return TRUE;
413 /************************************************************************
414 * DlgDirSelectComboBox [USER.194]
416 BOOL DlgDirSelectComboBox(HWND hDlg, LPSTR lpStr, int nIDLBox)
418 printf("DlgDirSelectComboBox(%04X, '%s', %d) \n", hDlg, lpStr, nIDLBox);
422 /************************************************************************
423 * DlgDirListComboBox [USER.195]
425 int DlgDirListComboBox(HWND hDlg, LPSTR lpPathSpec,
426 int nIDLBox, int nIDStat, WORD wType)
428 HWND hWnd;
429 LPHEADCOMBO lphc;
430 printf("DlgDirListComboBox(%04X, '%s', %d, %d, %04X) \n",
431 hDlg, lpPathSpec, nIDLBox, nIDStat, wType);
432 hWnd = GetDlgItem(hDlg, nIDLBox);
433 lphc = ComboGetStorageHeader(hWnd);
434 if (lphc == NULL) return 0;
435 SendMessage(lphc->hWndLBox, LB_RESETCONTENT, 0, 0L);
436 return SendMessage(lphc->hWndLBox, LB_DIR, wType, (DWORD)lpPathSpec);