Release 950319
[wine] / controls / combo.c
1 /*
2  * Interface code to COMBOBOX widget
3  *
4  * Copyright  Martin Ayotte, 1993
5  *
6 static char Copyright[] = "Copyright Martin Ayotte, 1993";
7 */
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <sys/types.h>
12 #include <sys/stat.h>
13
14 #include "windows.h"
15 #include "combo.h"
16 #include "user.h"
17 #include "win.h"
18 #include "stddebug.h"
19 /* #define DEBUG_COMBO */
20 #include "debug.h"
21 #include "graphics.h"
22
23 HBITMAP hComboBit = 0;
24
25 LPHEADCOMBO ComboGetStorageHeader(HWND hwnd);
26 int CreateComboStruct(HWND hwnd);
27 void ComboBoxStaticOwnerDraw(HWND hWnd, LPHEADCOMBO lphc);
28
29
30 /***********************************************************************
31  *           ComboWndProc
32  */
33 LONG ComboBoxWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam )
34 {    
35         RECT    rect;
36         int             y, count;
37         int             width, height;
38         WND     *wndPtr;
39         LPHEADCOMBO lphc;
40         HDC             hDC;
41         BITMAP  bm;
42         PAINTSTRUCT paintstruct;
43         LPDRAWITEMSTRUCT lpdis;
44         DWORD       dwStyle;
45         HANDLE hStr;
46
47         switch(message) {
48                 case WM_CREATE:
49                         wndPtr = WIN_FindWndPtr(hwnd);
50                         if (wndPtr == NULL) return 0;
51                         dprintf_combo(stddeb,"Combo WM_CREATE %d !\n", hwnd);
52                         if (hComboBit == (HBITMAP)NULL) 
53                         hComboBit = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_COMBO));
54                         GetObject(hComboBit, sizeof(BITMAP), (LPSTR)&bm);
55                         wndPtr->dwStyle &= 0xFFFFFFFFL ^ (WS_VSCROLL | WS_HSCROLL);
56                         GetWindowRect(hwnd, &rect);
57                         width = rect.right - rect.left;
58                         height = rect.bottom - rect.top;
59                         if (height < bm.bmHeight) height = bm.bmHeight;
60 /*                      SetWindowPos(hwnd, 0, 0, 0, width + bm.bmHeight, bm.bmHeight, 
61                                                                         SWP_NOMOVE | SWP_NOZORDER); */
62                         SetWindowPos(hwnd, 0, 0, 0, width, bm.bmHeight, 
63                                                                 SWP_NOMOVE | SWP_NOZORDER); 
64                         CreateComboStruct(hwnd);
65                         lphc = ComboGetStorageHeader(hwnd);
66                         if (lphc == NULL) return 0;
67 /*                      SetRect(&lphc->RectEdit, 0, 0, width - 2, bm.bmHeight); */
68                         SetRect(&lphc->RectEdit, 0, 0, width - bm.bmHeight, bm.bmHeight);
69                         if (wndPtr->dwStyle & CBS_DROPDOWNLIST) {
70                                 if ((wndPtr->dwStyle & CBS_OWNERDRAWFIXED) == CBS_OWNERDRAWFIXED ||
71                                         (wndPtr->dwStyle & CBS_OWNERDRAWVARIABLE) == CBS_OWNERDRAWVARIABLE)
72                                         lphc->hWndEdit = 0;
73                                 else
74                                         lphc->hWndEdit = CreateWindow("STATIC", "",
75                                                 WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | SS_LEFT,
76                                                 0, 0, width - bm.bmHeight, bm.bmHeight,
77                                                 hwnd, 1, wndPtr->hInstance, 0L);
78                                 }
79                         else {
80 /*                              lphc->hWndEdit = CreateWindow("EDIT", "", */
81                                 lphc->hWndEdit = CreateWindow("STATIC", "",
82                                         WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | SS_LEFT,
83                                         0, 0, width - bm.bmHeight, bm.bmHeight,
84                                         hwnd, 1, wndPtr->hInstance, 0L);
85                                 }
86                         dwStyle = WS_POPUP | WS_BORDER | WS_VSCROLL | LBS_NOTIFY;
87                         if ((wndPtr->dwStyle & CBS_HASSTRINGS) == CBS_HASSTRINGS)
88                                 dwStyle |= LBS_HASSTRINGS;
89                         if ((wndPtr->dwStyle & CBS_SORT) == CBS_SORT)
90                                 dwStyle |= LBS_SORT;
91                         if ((wndPtr->dwStyle & CBS_OWNERDRAWFIXED) == CBS_OWNERDRAWFIXED)
92                                 dwStyle |= LBS_OWNERDRAWFIXED;
93                         if ((wndPtr->dwStyle & CBS_OWNERDRAWVARIABLE) == CBS_OWNERDRAWVARIABLE)
94                                 dwStyle |= LBS_OWNERDRAWVARIABLE;
95                         lphc->hWndLBox = CreateWindow("LISTBOX", "", dwStyle,
96                                 rect.left, rect.top + bm.bmHeight,
97                                 width, height, wndPtr->hwndParent, 0,
98                                 wndPtr->hInstance, (SEGPTR)MAKELONG(0, hwnd));
99                         ShowWindow(lphc->hWndLBox, SW_HIDE);
100                         dprintf_combo(stddeb,"Combo Creation LBox=%X!\n", lphc->hWndLBox);
101                         return 0;
102     case WM_DESTROY:
103                 lphc = ComboGetStorageHeader(hwnd);
104                 if (lphc == 0) return 0;
105 /*
106                 if (lphc->hWndEdit != 0) DestroyWindow(lphc->hWndEdit);
107 */
108                 DestroyWindow(lphc->hWndLBox);
109                 free(lphc);
110 /*
111                 *((LPHEADCOMBO *)&wndPtr->wExtra[1]) = 0; 
112                 printf("Combo WM_DESTROY after clearing wExtra !\n");
113 */
114                 dprintf_combo(stddeb,"Combo WM_DESTROY %p !\n", lphc);
115                 return DefWindowProc( hwnd, message, wParam, lParam );
116         case WM_SHOWWINDOW:
117                 dprintf_combo(stddeb,"ComboBox WM_SHOWWINDOW hWnd=%04X !\n", 
118                               hwnd);
119                 if (!(wParam == 0 && lParam == 0L)) {
120                         InvalidateRect(hwnd, NULL, TRUE);
121                         }
122             break;
123         
124     case WM_COMMAND:
125                 wndPtr = WIN_FindWndPtr(hwnd);
126                 lphc = ComboGetStorageHeader(hwnd);
127                 if (lphc == NULL || wndPtr == NULL) return 0;
128                 if (LOWORD(lParam) == lphc->hWndLBox) {
129                     hStr = USER_HEAP_ALLOC( 256 );
130                         switch(HIWORD(lParam)) {
131                                 case LBN_SELCHANGE:
132                                         lphc->dwState = lphc->dwState & (CB_SHOWDROPDOWN ^ 0xFFFFFFFFL);
133                                         ShowWindow(lphc->hWndLBox, SW_HIDE);
134                                         y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L);
135                                         if (y != LB_ERR) {
136                                                 SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, USER_HEAP_SEG_ADDR(hStr));
137                                                 if (lphc->hWndEdit != 0) 
138                                                         SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, USER_HEAP_SEG_ADDR(hStr));
139                                                 else {
140                                                         InvalidateRect(hwnd, NULL, TRUE);
141                                                         UpdateWindow(hwnd);
142                                                         }
143                                                 }
144                                         SendMessage(GetParent(hwnd), WM_COMMAND, wndPtr->wIDmenu,
145                                                                                 MAKELONG(hwnd, CBN_SELCHANGE));
146                                         break;
147                                 case LBN_DBLCLK:
148                                         SendMessage(GetParent(hwnd), WM_COMMAND, wndPtr->wIDmenu,
149                                                                                 MAKELONG(hwnd, CBN_DBLCLK));
150                                         break;
151                         }
152                     USER_HEAP_FREE( hStr );
153             }
154                 break;
155     case WM_LBUTTONDOWN:
156                 dprintf_combo(stddeb,"Combo WM_LBUTTONDOWN wParam=%x lParam=%lX !\n", wParam, lParam);
157                 GetClientRect(hwnd, &rect);
158                 rect.left = rect.right - (rect.bottom - rect.top); 
159                 hDC = GetDC(hwnd);
160                 InflateRect(&rect, -1, -1);
161                 GRAPH_DrawReliefRect(hDC, &rect, 1, 1, TRUE);
162                 ReleaseDC(hwnd, hDC);
163                 wndPtr = WIN_FindWndPtr(hwnd);
164                 lphc = ComboGetStorageHeader(hwnd);
165                 if (lphc == NULL) return 0;
166                 lphc->dwState = lphc->dwState ^ CB_SHOWDROPDOWN;
167                 if ((lphc->dwState & CB_SHOWDROPDOWN) == CB_SHOWDROPDOWN) {
168                     ShowWindow(lphc->hWndLBox, SW_SHOW);
169                     SetFocus(lphc->hWndLBox);
170                         }
171                 else {
172                         dprintf_combo(stddeb,"before Combo Restore Focus !\n");
173                         SetFocus(lphc->hWndEdit);
174                         dprintf_combo(stddeb,"before Combo List Hide !\n");
175                         ShowWindow(lphc->hWndLBox, SW_HIDE);
176                         dprintf_combo(stddeb,"before Combo List GetCurSel !\n");
177                         y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L);
178                         if (y != LB_ERR) {
179                                 hStr = USER_HEAP_ALLOC( 256 );
180                                 dprintf_combo(stddeb,"before Combo List GetText !\n");
181                                 SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, USER_HEAP_SEG_ADDR(hStr));
182                                 SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, USER_HEAP_SEG_ADDR(hStr));
183                                 USER_HEAP_FREE( hStr );
184                                 }
185                         dprintf_combo(stddeb,"End of Combo List Hide !\n");
186                         }
187                 break;
188     case WM_LBUTTONUP:
189                 dprintf_combo(stddeb,"Combo WM_LBUTTONUP wParam=%x lParam=%lX !\n", wParam, lParam);
190                 GetClientRect(hwnd, &rect);
191                 rect.left = rect.right - (rect.bottom - rect.top); 
192                 hDC = GetDC(hwnd);
193                 InflateRect(&rect, -1, -1);
194                 GRAPH_DrawReliefRect(hDC, &rect, 1, 1, FALSE);
195                 ReleaseDC(hwnd, hDC);
196                 break;
197    case WM_KEYDOWN:
198                 wndPtr = WIN_FindWndPtr(hwnd);
199                 lphc = ComboGetStorageHeader(hwnd);
200                 if (lphc == NULL || wndPtr == NULL) return 0;
201                 y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L);
202                 count = SendMessage(lphc->hWndLBox, LB_GETCOUNT, 0, 0L);
203                 dprintf_combo(stddeb,"COMBOBOX // GetKeyState(VK_MENU)=%d\n", GetKeyState(VK_MENU));
204                 if (GetKeyState(VK_MENU) < 0) {
205                         lphc->dwState = lphc->dwState ^ CB_SHOWDROPDOWN;
206                         if ((lphc->dwState & CB_SHOWDROPDOWN) == CB_SHOWDROPDOWN) {
207                                 GetWindowRect(hwnd, &rect);
208                                 SetWindowPos(lphc->hWndLBox, 0, rect.left, rect.bottom, 0, 0, 
209                                                                         SWP_NOREDRAW | SWP_NOSIZE); 
210                                 SetWindowPos(lphc->hWndLBox, 0, 0, 0, 0, 0, SWP_SHOWWINDOW | 
211                                                                         SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER); 
212                             SetFocus(lphc->hWndLBox);
213                                 }
214                         else {
215                                 ShowWindow(lphc->hWndLBox, SW_HIDE);
216                                 y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L);
217                                 if (y != LB_ERR) {
218                                         hStr = USER_HEAP_ALLOC( 256 );
219                                         SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, USER_HEAP_SEG_ADDR(hStr));
220                                         if (lphc->hWndEdit != 0) 
221                                                 SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, USER_HEAP_SEG_ADDR(hStr));
222                                         USER_HEAP_FREE( hStr );
223                                         }
224                                 }
225                     }
226                 else {
227                     switch(wParam) {
228                                 case VK_HOME:
229                                     y = 0;
230                                         break;
231                                 case VK_END:
232                                     y = count - 1;
233                                     break;
234                                 case VK_UP:
235                                     y--;
236                                     break;
237                                 case VK_DOWN:
238                                     y++;
239                                     break;
240                                 }
241                         if (y < 0) y = 0;
242                         if (y >= count) y = count - 1;
243                         lphc->LastSel = y;
244                         SendMessage(lphc->hWndLBox, LB_SETCURSEL, y, 0L);
245                         hStr = USER_HEAP_ALLOC( 256 );
246                         SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, USER_HEAP_SEG_ADDR(hStr));
247                         if (lphc->hWndEdit != 0) 
248                                 SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, USER_HEAP_SEG_ADDR(hStr));
249                         SendMessage(GetParent(hwnd), WM_COMMAND, wndPtr->wIDmenu,
250                         MAKELONG(hwnd, CBN_SELCHANGE));
251                         USER_HEAP_FREE( hStr );
252                         }
253                 break;
254     case WM_MEASUREITEM:
255         dprintf_combo(stddeb,"ComboBoxWndProc WM_MEASUREITEM !\n");
256         return(SendMessage(GetParent(hwnd), WM_MEASUREITEM, wParam, lParam));
257     case WM_CTLCOLOR:
258         return(SendMessage(GetParent(hwnd), WM_CTLCOLOR, wParam, lParam));
259         case WM_SETREDRAW:
260                 dprintf_combo(stddeb,"ComboBoxWndProc WM_SETREDRAW hWnd=%04X w=%04X !\n", hwnd, wParam);
261                 lphc = ComboGetStorageHeader(hwnd);
262                 if (lphc == NULL) return 0;
263                 lphc->bRedrawFlag = wParam;
264                 break;
265     case WM_DRAWITEM:
266                 dprintf_combo(stddeb,"ComboBoxWndProc // WM_DRAWITEM w=%04X l=%08lX\n", wParam, lParam);
267                 wndPtr = WIN_FindWndPtr(hwnd);
268                 if (wndPtr == NULL) break;
269                 lpdis = (LPDRAWITEMSTRUCT)PTR_SEG_TO_LIN(lParam);
270                 if (lpdis == NULL) break;
271                 lpdis->CtlType = ODT_COMBOBOX;
272                 lpdis->CtlID = wndPtr->wIDmenu;
273                 return(SendMessage(GetParent(hwnd), WM_DRAWITEM, wParam, lParam));
274     case WM_PAINT:
275                 GetClientRect(hwnd, &rect);
276                 hDC = BeginPaint(hwnd, &paintstruct);
277                 if (hComboBit != 0) {
278                         GetObject(hComboBit, sizeof(BITMAP), (LPSTR)&bm);
279                         GRAPH_DrawBitmap( hDC, hComboBit,
280                                           rect.right - bm.bmWidth, 0,
281                                           0, 0, bm.bmWidth, bm.bmHeight );
282                         }
283                 EndPaint(hwnd, &paintstruct);
284                 lphc = ComboGetStorageHeader(hwnd);
285                 if (lphc == NULL) return 0;
286                 if (lphc->hWndEdit != 0) {
287                         InvalidateRect(lphc->hWndEdit, NULL, TRUE);
288                         UpdateWindow(lphc->hWndEdit);
289                         }
290                 else {
291                         ComboBoxStaticOwnerDraw(hwnd, lphc);
292                         }
293                 if ((lphc->dwState & CB_SHOWDROPDOWN) == CB_SHOWDROPDOWN) {
294                         InvalidateRect(lphc->hWndLBox, NULL, TRUE);
295                         UpdateWindow(lphc->hWndLBox);
296                         }
297                 break;
298         case WM_SETFOCUS:
299                 lphc = ComboGetStorageHeader(hwnd);
300                 if (lphc == NULL) return 0;
301                 if (lphc->hWndEdit != 0) 
302                         SetFocus(lphc->hWndEdit);
303                 break;
304         case WM_KILLFOCUS:
305                 lphc = ComboGetStorageHeader(hwnd);
306                 if (lphc == NULL) return 0;
307                 ShowWindow(lphc->hWndLBox, SW_HIDE);
308                 y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L);
309                 if (y != LB_ERR) {
310                         hStr = USER_HEAP_ALLOC( 256 );
311                         SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, USER_HEAP_SEG_ADDR(hStr));
312                         if (lphc->hWndEdit != 0) 
313                                 SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, USER_HEAP_SEG_ADDR(hStr));
314                         USER_HEAP_FREE( hStr );
315                         }
316                 break;
317         case CB_ADDSTRING:
318                 dprintf_combo(stddeb,"CB_ADDSTRING '%s' !\n", (LPSTR)PTR_SEG_TO_LIN(lParam));
319                 lphc = ComboGetStorageHeader(hwnd);
320                 if (lphc == NULL) return 0;
321                 return(SendMessage(lphc->hWndLBox, LB_ADDSTRING, wParam, lParam));
322     case CB_GETLBTEXT:
323                 dprintf_combo(stddeb,"CB_GETLBTEXT #%u !\n", wParam);
324                 lphc = ComboGetStorageHeader(hwnd);
325                 if (lphc == NULL) return 0;
326                 return(SendMessage(lphc->hWndLBox, LB_GETTEXT, wParam, lParam));
327     case CB_GETLBTEXTLEN:
328                 dprintf_combo(stddeb,"CB_GETLBTEXTLEN !\n");
329                 lphc = ComboGetStorageHeader(hwnd);
330                 if (lphc == NULL) return 0;
331                 return(SendMessage(lphc->hWndLBox, LB_GETTEXTLEN, wParam, lParam));
332     case CB_INSERTSTRING:
333                 dprintf_combo(stddeb,"CB_INSERTSTRING '%s' !\n",(LPSTR)PTR_SEG_TO_LIN(lParam));
334                 lphc = ComboGetStorageHeader(hwnd);
335                 if (lphc == NULL) return 0;
336                 return(SendMessage(lphc->hWndLBox, LB_INSERTSTRING, wParam, lParam));
337         case CB_DELETESTRING:
338                 dprintf_combo(stddeb,"CB_DELETESTRING #%u !\n", wParam);
339                 lphc = ComboGetStorageHeader(hwnd);
340                 if (lphc == NULL) return 0;
341                 return(SendMessage(lphc->hWndLBox, LB_DELETESTRING, wParam, 0L));
342         case CB_RESETCONTENT:
343                 dprintf_combo(stddeb,"CB_RESETCONTENT !\n");
344                 lphc = ComboGetStorageHeader(hwnd);
345                 if (lphc == NULL) return 0;
346                 return(SendMessage(lphc->hWndLBox, LB_RESETCONTENT, 0, 0L));
347     case CB_DIR:
348                 dprintf_combo(stddeb,"ComboBox CB_DIR !\n");
349                 lphc = ComboGetStorageHeader(hwnd);
350                 if (lphc == NULL) return 0;
351                 return(SendMessage(lphc->hWndLBox, LB_DIR, wParam, lParam));
352         case CB_FINDSTRING:
353                 lphc = ComboGetStorageHeader(hwnd);
354                 return(SendMessage(lphc->hWndLBox, LB_FINDSTRING, wParam, lParam));
355         case CB_GETCOUNT:
356                 lphc = ComboGetStorageHeader(hwnd);
357                 if (lphc == NULL) return 0;
358                 return(SendMessage(lphc->hWndLBox, LB_GETCOUNT, 0, 0L));
359         case CB_GETCURSEL:
360                 dprintf_combo(stddeb,"ComboBox CB_GETCURSEL !\n");
361                 lphc = ComboGetStorageHeader(hwnd);
362                 if (lphc == NULL) return 0;
363                 return(SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L));
364     case CB_SETCURSEL:
365                 dprintf_combo(stddeb,"ComboBox CB_SETCURSEL wParam=%X !\n", wParam);
366                 lphc = ComboGetStorageHeader(hwnd);
367                 if (lphc == NULL) return 0;
368                 return(SendMessage(lphc->hWndLBox, LB_SETCURSEL, wParam, 0L));
369         case CB_GETEDITSEL:
370                 dprintf_combo(stddeb,"ComboBox CB_GETEDITSEL !\n");
371                 lphc = ComboGetStorageHeader(hwnd);
372                 if (lphc == NULL) return 0;
373 /*              if (lphc->hWndEdit != 0)
374                         return(SendMessage(lphc->hWndEdit, EM_GETSEL, 0, 0L)); */
375                 break;
376         case CB_SETEDITSEL:
377                 dprintf_combo(stddeb,"ComboBox CB_SETEDITSEL lParam=%lX !\n", 
378                               lParam);
379                 lphc = ComboGetStorageHeader(hwnd);
380                 if (lphc == NULL) return 0;
381 /*              if (lphc->hWndEdit != 0)
382                         return(SendMessage(lphc->hWndEdit, EM_SETSEL, 0, lParam)); */
383                 break;
384         case CB_SELECTSTRING:
385                 dprintf_combo(stddeb,"ComboBox CB_SELECTSTRING !\n");
386                 lphc = ComboGetStorageHeader(hwnd);
387                 if (lphc == NULL) return 0;
388                 break;
389         case CB_SHOWDROPDOWN:
390                 dprintf_combo(stddeb,"ComboBox CB_SHOWDROPDOWN !\n");
391                 lphc = ComboGetStorageHeader(hwnd);
392                 if (lphc == NULL) return 0;
393                 wndPtr = WIN_FindWndPtr(hwnd);
394                 lphc->dwState = lphc->dwState | CB_SHOWDROPDOWN;
395                 if (wParam != 0) {
396                         GetWindowRect(hwnd, &rect);
397                         SetWindowPos(lphc->hWndLBox, 0, rect.left, rect.bottom, 0, 0, 
398                                                                 SWP_NOREDRAW | SWP_NOSIZE); 
399                         SetWindowPos(lphc->hWndLBox, 0, 0, 0, 0, 0, SWP_SHOWWINDOW | 
400                                                                 SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER); 
401                         }
402                 else {
403                         lphc->dwState = lphc->dwState ^ CB_SHOWDROPDOWN;
404                         ShowWindow(lphc->hWndLBox, SW_HIDE);
405                         SendMessage(GetParent(hwnd), WM_COMMAND, wndPtr->wIDmenu,
406                                                                         MAKELONG(hwnd, CBN_DROPDOWN));
407                 }
408                 break;
409     case CB_GETITEMDATA:
410                 dprintf_combo(stddeb,"ComboBox CB_GETITEMDATA wParam=%X !\n", wParam);
411                 lphc = ComboGetStorageHeader(hwnd);
412                 if (lphc == NULL) return 0;
413                 return(SendMessage(lphc->hWndLBox, LB_GETITEMDATA, wParam, 0L));
414         break;
415     case CB_SETITEMDATA:
416                 dprintf_combo(stddeb,"ComboBox CB_SETITEMDATA wParam=%04X lParam=%08lX!\n", wParam, lParam);
417                 lphc = ComboGetStorageHeader(hwnd);
418                 if (lphc == NULL) return 0;
419                 return(SendMessage(lphc->hWndLBox, LB_SETITEMDATA, wParam, lParam));
420         break;
421     case CB_LIMITTEXT:
422                 dprintf_combo(stddeb,"ComboBox CB_LIMITTEXT !\n");
423                 lphc = ComboGetStorageHeader(hwnd);
424                 if (lphc == NULL) return 0;
425 /*              if (lphc->hWndEdit != 0) 
426                 return(SendMessage(lphc->hWndEdit, EM_LIMITTEXT, wParam, 0L)); */
427         break;
428
429     default:
430                 return DefWindowProc( hwnd, message, wParam, lParam );
431     }
432 return 0;
433 }
434
435
436
437 LPHEADCOMBO ComboGetStorageHeader(HWND hwnd)
438 {
439         WND  *wndPtr;
440         LPHEADCOMBO lphc;
441         wndPtr = WIN_FindWndPtr(hwnd);
442         if (wndPtr == 0) {
443                 fprintf(stderr,"Bad Window handle on ComboBox !\n");
444                 return 0;
445                 }
446         lphc = *((LPHEADCOMBO *)&wndPtr->wExtra[1]);
447         return lphc;
448 }
449
450
451
452 int CreateComboStruct(HWND hwnd)
453 {
454         WND  *wndPtr;
455         LPHEADCOMBO lphc;
456         wndPtr = WIN_FindWndPtr(hwnd);
457         if (wndPtr == 0) {
458                 fprintf(stderr,"Bad Window handle on ComboBox !\n");
459                 return 0;
460                 }
461         lphc = (LPHEADCOMBO)malloc(sizeof(HEADCOMBO));
462         *((LPHEADCOMBO *)&wndPtr->wExtra[1]) = lphc;
463         lphc->hWndEdit = 0;
464         lphc->hWndLBox = 0;
465         lphc->dwState = 0;
466         lphc->LastSel = -1;
467         return TRUE;
468 }
469
470
471 void ComboBoxStaticOwnerDraw(HWND hWnd, LPHEADCOMBO lphc)
472 {
473         HDC     hDC;
474         HBRUSH  hBrush;
475         short   y;
476         LPSTR   ptr = NULL;
477         HANDLE  hTemp;
478         WND       *wndPtr;
479         LPDRAWITEMSTRUCT lpdis;
480         dprintf_combo(stddeb,"ComboBoxStaticOwnerDraw(%04X, %p) !\n", hWnd, lphc);
481         y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L);
482         if (y != LB_ERR) {
483                 ptr = (LPSTR)SendMessage(lphc->hWndLBox, LB_GETITEMDATA, y, 0L);
484                 }
485         hDC = GetDC(hWnd);
486         hBrush = SendMessage(GetParent(hWnd), WM_CTLCOLOR, (WORD)hDC,
487                                                 MAKELONG(hWnd, CTLCOLOR_STATIC)); 
488         if (hBrush == (HBRUSH)NULL)  hBrush = GetStockObject(WHITE_BRUSH);
489         wndPtr = WIN_FindWndPtr(hWnd);
490         if (wndPtr == NULL) return;
491         hTemp = USER_HEAP_ALLOC( sizeof(DRAWITEMSTRUCT) );
492         lpdis = (LPDRAWITEMSTRUCT) USER_HEAP_LIN_ADDR(hTemp);
493         if (lpdis == NULL) {
494                 printf("ComboBox Ownerdraw // Error allocating DRAWITEMSTRUCT !\n");
495                 ReleaseDC( hWnd, hDC );
496                 return;
497                 }
498         FillRect(hDC, &lphc->RectEdit, hBrush);
499         lpdis->hDC = hDC;
500         if (y != LB_ERR) lpdis->itemID = y - 1;
501         CopyRect(&lpdis->rcItem, &lphc->RectEdit);
502         lpdis->itemData = (DWORD)ptr;
503         lpdis->itemAction = ODA_DRAWENTIRE;
504         lpdis->CtlType = ODT_COMBOBOX;
505         lpdis->CtlID = wndPtr->wIDmenu;
506         SendMessage(GetParent(hWnd), WM_DRAWITEM, y,USER_HEAP_SEG_ADDR(hTemp));
507         USER_HEAP_FREE(hTemp);
508         ReleaseDC(hWnd, hDC);
509 }
510
511
512 /************************************************************************
513  *                                      DlgDirSelectComboBox    [USER.194]
514  */
515 BOOL DlgDirSelectComboBox(HWND hDlg, LPSTR lpStr, int nIDLBox)
516 {
517         fprintf(stdnimp,"DlgDirSelectComboBox(%04X, '%s', %d) \n",      
518                                 hDlg, lpStr, nIDLBox);
519         return TRUE;
520 }
521
522
523 /************************************************************************
524  *                                      DlgDirListComboBox     [USER.195]
525  */
526 int DlgDirListComboBox(HWND hDlg, SEGPTR lpPathSpec, 
527         int nIDLBox, int nIDStat, WORD wType)
528 {
529         HWND            hWnd;
530         LPHEADCOMBO lphc;
531         dprintf_combo(stddeb,"DlgDirListComboBox(%04X, '%s', %d, %d, %04X) \n",
532                         hDlg, (char *)PTR_SEG_TO_LIN(lpPathSpec), nIDLBox, nIDStat, wType);
533         hWnd = GetDlgItem(hDlg, nIDLBox);
534         lphc = ComboGetStorageHeader(hWnd);
535         if (lphc == NULL) return 0;
536         SendMessage(lphc->hWndLBox, LB_RESETCONTENT, 0, 0L);
537         return SendMessage(lphc->hWndLBox, LB_DIR, wType, (DWORD)lpPathSpec);
538 }
539
540
541