Release 940524
[wine/testsucceed.git] / controls / combo.c
blob22a1b08fb5eb651e342cc2c4093e9886a0a0201d
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_CHILD | WS_CLIPCHILDREN | WS_BORDER | WS_VSCROLL | LBS_NOTIFY,
82 wndPtr->rectClient.left, wndPtr->rectClient.top + bm.bmHeight,
83 width, height, wndPtr->hwndParent, 1,
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 );
107 case WM_COMMAND:
108 wndPtr = WIN_FindWndPtr(hwnd);
109 lphc = ComboGetStorageHeader(hwnd);
110 if (lphc == NULL) return 0;
111 if (LOWORD(lParam) == lphc->hWndLBox) {
112 switch(HIWORD(lParam)) {
113 case LBN_SELCHANGE:
114 lphc->dwState = lphc->dwState & (CB_SHOWDROPDOWN ^ 0xFFFFFFFFL);
115 ShowWindow(lphc->hWndLBox, SW_HIDE);
116 y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L);
117 if (y != LB_ERR) {
118 SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, (LPARAM)str);
119 SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, (LPARAM)str);
121 SendMessage(GetParent(hwnd), WM_COMMAND, wndPtr->wIDmenu,
122 MAKELONG(hwnd, CBN_SELCHANGE));
123 break;
124 case LBN_DBLCLK:
125 SendMessage(GetParent(hwnd), WM_COMMAND, wndPtr->wIDmenu,
126 MAKELONG(hwnd, CBN_DBLCLK));
127 break;
130 break;
131 case WM_LBUTTONDOWN:
132 printf("Combo WM_LBUTTONDOWN wParam=%x lParam=%lX !\n", wParam, lParam);
133 GetClientRect(hwnd, &rect);
134 rect.left = rect.right - (rect.bottom - rect.top);
135 hDC = GetDC(hwnd);
136 InflateRect(&rect, -1, -1);
137 DrawReliefRect(hDC, rect, 1, 1);
138 ReleaseDC(hwnd, hDC);
139 wndPtr = WIN_FindWndPtr(hwnd);
140 lphc = ComboGetStorageHeader(hwnd);
141 if (lphc == NULL) return 0;
142 lphc->dwState = lphc->dwState ^ CB_SHOWDROPDOWN;
143 if ((lphc->dwState & CB_SHOWDROPDOWN) == CB_SHOWDROPDOWN) {
144 ShowWindow(lphc->hWndLBox, SW_SHOW);
145 SetFocus(lphc->hWndLBox);
147 else {
148 printf("before Combo Restore Focus !\n");
149 SetFocus(lphc->hWndEdit);
150 printf("before Combo List Hide !\n");
151 ShowWindow(lphc->hWndLBox, SW_HIDE);
152 printf("before Combo List GetCurSel !\n");
153 y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L);
154 if (y != LB_ERR) {
155 printf("before Combo List GetText !\n");
156 SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, (LPARAM)str);
157 SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, (LPARAM)str);
159 printf("End of Combo List Hide !\n");
161 break;
162 case WM_LBUTTONUP:
163 printf("Combo WM_LBUTTONUP wParam=%x lParam=%lX !\n", wParam, lParam);
164 GetClientRect(hwnd, &rect);
165 rect.left = rect.right - (rect.bottom - rect.top);
166 hDC = GetDC(hwnd);
167 InflateRect(&rect, -1, -1);
168 DrawReliefRect(hDC, rect, 1, 0);
169 ReleaseDC(hwnd, hDC);
170 break;
171 case WM_KEYDOWN:
172 wndPtr = WIN_FindWndPtr(hwnd);
173 lphc = ComboGetStorageHeader(hwnd);
174 if (lphc == NULL) return 0;
175 y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L);
176 count = SendMessage(lphc->hWndLBox, LB_GETCOUNT, 0, 0L);
177 printf("COMBOBOX // GetKeyState(VK_MENU)=%d\n", GetKeyState(VK_MENU));
178 if (GetKeyState(VK_MENU) < 0) {
179 lphc->dwState = lphc->dwState ^ CB_SHOWDROPDOWN;
180 if ((lphc->dwState & CB_SHOWDROPDOWN) == CB_SHOWDROPDOWN) {
181 ShowWindow(lphc->hWndLBox, SW_SHOW);
182 SetFocus(lphc->hWndLBox);
184 else {
185 ShowWindow(lphc->hWndLBox, SW_HIDE);
186 y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L);
187 if (y != LB_ERR) {
188 SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, (LPARAM)str);
189 SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, (LPARAM)str);
193 else {
194 switch(wParam) {
195 case VK_HOME:
196 y = 0;
197 break;
198 case VK_END:
199 y = count - 1;
200 break;
201 case VK_UP:
202 y--;
203 break;
204 case VK_DOWN:
205 y++;
206 break;
208 if (y < 0) y = 0;
209 if (y >= count) y = count - 1;
210 SendMessage(lphc->hWndLBox, LB_SETCURSEL, y, 0L);
211 SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, (LPARAM)str);
212 SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, (LPARAM)str);
213 SendMessage(GetParent(hwnd), WM_COMMAND, wndPtr->wIDmenu,
214 MAKELONG(hwnd, CBN_SELCHANGE));
216 break;
217 case WM_MEASUREITEM:
218 printf("ComboBoxWndProc WM_MEASUREITEM !\n");
219 return(SendMessage(GetParent(hwnd), WM_MEASUREITEM, wParam, lParam));
220 case WM_CTLCOLOR:
221 return(SendMessage(GetParent(hwnd), WM_CTLCOLOR, wParam, lParam));
222 case WM_PAINT:
223 GetClientRect(hwnd, &rect);
224 hDC = BeginPaint(hwnd, &paintstruct);
225 hMemDC = CreateCompatibleDC(hDC);
226 if (hMemDC != 0 && hComboBit != 0) {
227 GetObject(hComboBit, sizeof(BITMAP), (LPSTR)&bm);
228 SelectObject(hMemDC, hComboBit);
229 BitBlt(hDC, rect.right - bm.bmWidth, 0,
230 bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
232 DeleteDC(hMemDC);
233 EndPaint(hwnd, &paintstruct);
234 lphc = ComboGetStorageHeader(hwnd);
235 if (lphc == NULL) return 0;
236 InvalidateRect(lphc->hWndEdit, NULL, TRUE);
237 UpdateWindow(lphc->hWndEdit);
238 if ((lphc->dwState & CB_SHOWDROPDOWN) == CB_SHOWDROPDOWN) {
239 InvalidateRect(lphc->hWndLBox, NULL, TRUE);
240 UpdateWindow(lphc->hWndLBox);
242 break;
243 case WM_SETFOCUS:
244 lphc = ComboGetStorageHeader(hwnd);
245 if (lphc == NULL) return 0;
246 SetFocus(lphc->hWndEdit);
247 break;
248 case WM_KILLFOCUS:
249 lphc = ComboGetStorageHeader(hwnd);
250 if (lphc == NULL) return 0;
251 ShowWindow(lphc->hWndLBox, SW_HIDE);
252 y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L);
253 if (y != LB_ERR) {
254 SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, (LPARAM)str);
255 SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, (LPARAM)str);
257 break;
258 case CB_ADDSTRING:
259 #ifdef DEBUG_COMBO
260 printf("CB_ADDSTRING '%s' !\n", (LPSTR)lParam);
261 #endif
262 lphc = ComboGetStorageHeader(hwnd);
263 if (lphc == NULL) return 0;
264 return(SendMessage(lphc->hWndLBox, LB_ADDSTRING, wParam, lParam));
265 case CB_GETLBTEXT:
266 #ifdef DEBUG_COMBO
267 printf("CB_GETLBTEXT #%u !\n", wParam);
268 #endif
269 lphc = ComboGetStorageHeader(hwnd);
270 if (lphc == NULL) return 0;
271 return(SendMessage(lphc->hWndLBox, LB_GETTEXT, wParam, lParam));
272 case CB_GETLBTEXTLEN:
273 printf("CB_GETLBTEXTLEN !\n");
274 lphc = ComboGetStorageHeader(hwnd);
275 if (lphc == NULL) return 0;
276 return(SendMessage(lphc->hWndLBox, LB_GETTEXTLEN, wParam, lParam));
277 case CB_INSERTSTRING:
278 printf("CB_INSERTSTRING '%s' !\n", (LPSTR)lParam);
279 lphc = ComboGetStorageHeader(hwnd);
280 if (lphc == NULL) return 0;
281 return(SendMessage(lphc->hWndLBox, LB_INSERTSTRING, wParam, lParam));
282 case CB_DELETESTRING:
283 printf("CB_DELETESTRING #%u !\n", wParam);
284 lphc = ComboGetStorageHeader(hwnd);
285 if (lphc == NULL) return 0;
286 return(SendMessage(lphc->hWndLBox, LB_DELETESTRING, wParam, 0L));
287 case CB_RESETCONTENT:
288 printf("CB_RESETCONTENT !\n");
289 lphc = ComboGetStorageHeader(hwnd);
290 if (lphc == NULL) return 0;
291 return(SendMessage(lphc->hWndLBox, LB_RESETCONTENT, 0, 0L));
292 case CB_DIR:
293 printf("ComboBox CB_DIR !\n");
294 lphc = ComboGetStorageHeader(hwnd);
295 if (lphc == NULL) return 0;
296 return(SendMessage(lphc->hWndLBox, LB_DIR, wParam, lParam));
297 case CB_FINDSTRING:
298 lphc = ComboGetStorageHeader(hwnd);
299 return(SendMessage(lphc->hWndLBox, LB_FINDSTRING, wParam, lParam));
300 case CB_GETCOUNT:
301 lphc = ComboGetStorageHeader(hwnd);
302 if (lphc == NULL) return 0;
303 return(SendMessage(lphc->hWndLBox, LB_GETCOUNT, 0, 0L));
304 case CB_GETCURSEL:
305 printf("ComboBox CB_GETCURSEL !\n");
306 lphc = ComboGetStorageHeader(hwnd);
307 if (lphc == NULL) return 0;
308 return(SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L));
309 case CB_SETCURSEL:
310 printf("ComboBox CB_SETCURSEL wParam=%X !\n", wParam);
311 lphc = ComboGetStorageHeader(hwnd);
312 if (lphc == NULL) return 0;
313 return(SendMessage(lphc->hWndLBox, LB_SETCURSEL, wParam, 0L));
314 case CB_GETEDITSEL:
315 printf("ComboBox CB_GETEDITSEL !\n");
316 lphc = ComboGetStorageHeader(hwnd);
317 if (lphc == NULL) return 0;
318 /* return(SendMessage(lphc->hWndEdit, EM_GETSEL, 0, 0L)); */
319 break;
320 case CB_SETEDITSEL:
321 printf("ComboBox CB_SETEDITSEL lParam=%lX !\n", lParam);
322 lphc = ComboGetStorageHeader(hwnd);
323 if (lphc == NULL) return 0;
324 /* return(SendMessage(lphc->hWndEdit, EM_SETSEL, 0, lParam)); */
325 break;
326 case CB_SELECTSTRING:
327 printf("ComboBox CB_SELECTSTRING !\n");
328 lphc = ComboGetStorageHeader(hwnd);
329 if (lphc == NULL) return 0;
330 break;
331 case CB_SHOWDROPDOWN:
332 printf("ComboBox CB_SHOWDROPDOWN !\n");
333 lphc = ComboGetStorageHeader(hwnd);
334 if (lphc == NULL) return 0;
335 lphc->dwState = lphc->dwState | CB_SHOWDROPDOWN;
336 if (wParam != 0) {
337 ShowWindow(lphc->hWndLBox, SW_SHOW);
339 else {
340 lphc->dwState = lphc->dwState ^ CB_SHOWDROPDOWN;
341 ShowWindow(lphc->hWndLBox, SW_HIDE);
342 SendMessage(GetParent(hwnd), WM_COMMAND, wndPtr->wIDmenu,
343 MAKELONG(hwnd, CBN_DROPDOWN));
345 break;
346 case CB_GETITEMDATA:
347 printf("ComboBox CB_GETITEMDATA wParam=%X !\n", wParam);
348 lphc = ComboGetStorageHeader(hwnd);
349 if (lphc == NULL) return 0;
350 return(SendMessage(lphc->hWndLBox, LB_GETITEMDATA, wParam, 0L));
351 break;
352 case CB_SETITEMDATA:
353 printf("ComboBox CB_SETITEMDATA wParam=%X lParam=%lX !\n", wParam, lParam);
354 lphc = ComboGetStorageHeader(hwnd);
355 if (lphc == NULL) return 0;
356 return(SendMessage(lphc->hWndLBox, LB_SETITEMDATA, wParam, lParam));
357 break;
358 case CB_LIMITTEXT:
359 printf("ComboBox CB_LIMITTEXT !\n");
360 lphc = ComboGetStorageHeader(hwnd);
361 if (lphc == NULL) return 0;
362 /* return(SendMessage(lphc->hWndEdit, EM_LIMITTEXT, wParam, 0L)); */
363 break;
365 default:
366 return DefWindowProc( hwnd, message, wParam, lParam );
368 return 0;
373 LPHEADCOMBO ComboGetStorageHeader(HWND hwnd)
375 WND *wndPtr;
376 LPHEADCOMBO lphc;
377 wndPtr = WIN_FindWndPtr(hwnd);
378 if (wndPtr == 0) {
379 printf("Bad Window handle on ComboBox !\n");
380 return 0;
382 lphc = *((LPHEADCOMBO *)&wndPtr->wExtra[1]);
383 return lphc;
388 int CreateComboStruct(HWND hwnd)
390 WND *wndPtr;
391 LPHEADCOMBO lphc;
392 wndPtr = WIN_FindWndPtr(hwnd);
393 if (wndPtr == 0) {
394 printf("Bad Window handle on ComboBox !\n");
395 return 0;
397 lphc = (LPHEADCOMBO)malloc(sizeof(HEADCOMBO));
398 *((LPHEADCOMBO *)&wndPtr->wExtra[1]) = lphc;
399 lphc->dwState = 0;
400 return TRUE;
405 /************************************************************************
406 * DlgDirSelectComboBox [USER.194]
408 BOOL DlgDirSelectComboBox(HWND hDlg, LPSTR lpStr, int nIDLBox)
410 printf("DlgDirSelectComboBox(%04X, '%s', %d) \n", hDlg, lpStr, nIDLBox);
414 /************************************************************************
415 * DlgDirListComboBox [USER.195]
417 int DlgDirListComboBox(HWND hDlg, LPSTR lpPathSpec,
418 int nIDLBox, int nIDStat, WORD wType)
420 HWND hWnd;
421 LPHEADCOMBO lphc;
422 printf("DlgDirListComboBox(%04X, '%s', %d, %d, %04X) \n",
423 hDlg, lpPathSpec, nIDLBox, nIDStat, wType);
424 hWnd = GetDlgItem(hDlg, nIDLBox);
425 lphc = ComboGetStorageHeader(hWnd);
426 if (lphc == NULL) return 0;
427 SendMessage(lphc->hWndLBox, LB_RESETCONTENT, 0, 0L);
428 return SendMessage(lphc->hWndLBox, LB_DIR, wType, (DWORD)lpPathSpec);