Release 940804
[wine/gsoc-2012-control.git] / controls / listbox.c
blob8b7af561aa52f6b5aef0e3f91d0b117f7849763a
1 /*
2 * Interface code to listbox widgets
4 * Copyright Martin Ayotte, 1993
6 */
8 /*
9 #define DEBUG_LISTBOX
12 static char Copyright[] = "Copyright Martin Ayotte, 1993";
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <sys/types.h>
17 #include <sys/stat.h>
18 #include "windows.h"
19 #include "user.h"
20 #include "heap.h"
21 #include "win.h"
22 #include "msdos.h"
23 #include "wine.h"
24 #include "listbox.h"
25 #include "scroll.h"
26 #include "prototypes.h"
28 #define GMEM_ZEROINIT 0x0040
31 LPHEADLIST ListBoxGetWindowAndStorage(HWND hwnd, WND **wndPtr);
32 LPHEADLIST ListBoxGetStorageHeader(HWND hwnd);
33 void StdDrawListBox(HWND hwnd);
34 void OwnerDrawListBox(HWND hwnd);
35 int ListBoxFindMouse(HWND hwnd, int X, int Y);
36 int CreateListBoxStruct(HWND hwnd);
37 void ListBoxAskMeasure(WND *wndPtr, LPHEADLIST lphl, LPLISTSTRUCT lpls);
38 int ListBoxAddString(HWND hwnd, LPSTR newstr);
39 int ListBoxInsertString(HWND hwnd, UINT uIndex, LPSTR newstr);
40 int ListBoxGetText(HWND hwnd, UINT uIndex, LPSTR OutStr);
41 int ListBoxDeleteString(HWND hwnd, UINT uIndex);
42 int ListBoxFindString(HWND hwnd, UINT nFirst, LPSTR MatchStr);
43 int ListBoxResetContent(HWND hwnd);
44 int ListBoxSetCurSel(HWND hwnd, WORD wIndex);
45 int ListBoxSetSel(HWND hwnd, WORD wIndex, WORD state);
46 int ListBoxGetSel(HWND hwnd, WORD wIndex);
47 int ListBoxDirectory(HWND hwnd, UINT attrib, LPSTR filespec);
48 int ListBoxGetItemRect(HWND hwnd, WORD wIndex, LPRECT rect);
49 int ListBoxSetItemHeight(HWND hwnd, WORD wIndex, long height);
50 int ListBoxDefaultItem(HWND hwnd, WND *wndPtr,
51 LPHEADLIST lphl, LPLISTSTRUCT lpls);
52 int ListBoxFindNextMatch(HWND hwnd, WORD wChar);
55 /***********************************************************************
56 * ListBoxWndProc
58 LONG ListBoxWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam )
60 WND *wndPtr;
61 LPHEADLIST lphl;
62 HWND hWndCtl;
63 WORD wRet;
64 RECT rect;
65 int y;
66 CREATESTRUCT *createStruct;
67 static RECT rectsel;
68 switch(message) {
69 case WM_CREATE:
70 CreateListBoxStruct(hwnd);
71 lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
72 #ifdef DEBUG_LISTBOX
73 printf("ListBox WM_CREATE %lX !\n", lphl);
74 #endif
75 if (lphl == NULL) return 0;
76 createStruct = (CREATESTRUCT *)lParam;
77 if (HIWORD(createStruct->lpCreateParams) != 0)
78 lphl->hWndLogicParent = (HWND)HIWORD(createStruct->lpCreateParams);
79 else
80 lphl->hWndLogicParent = GetParent(hwnd);
81 lphl->hFont = GetStockObject(SYSTEM_FONT);
82 lphl->ColumnsWidth = wndPtr->rectClient.right - wndPtr->rectClient.left;
83 if (wndPtr->dwStyle & WS_VSCROLL) {
84 SetScrollRange(hwnd, SB_VERT, 1, lphl->ItemsCount, TRUE);
85 ShowScrollBar(hwnd, SB_VERT, FALSE);
87 if (wndPtr->dwStyle & WS_HSCROLL) {
88 SetScrollRange(hwnd, SB_HORZ, 1, 1, TRUE);
89 ShowScrollBar(hwnd, SB_HORZ, FALSE);
91 if ((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) == LBS_OWNERDRAWFIXED) {
93 return 0;
94 case WM_DESTROY:
95 lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
96 if (lphl == NULL) return 0;
97 ListBoxResetContent(hwnd);
98 free(lphl);
99 *((LPHEADLIST *)&wndPtr->wExtra[1]) = 0;
100 #ifdef DEBUG_LISTBOX
101 printf("ListBox WM_DESTROY %lX !\n", lphl);
102 #endif
103 return 0;
105 case WM_VSCROLL:
106 #ifdef DEBUG_LISTBOX
107 printf("ListBox WM_VSCROLL w=%04X l=%08X !\n", wParam, lParam);
108 #endif
109 lphl = ListBoxGetStorageHeader(hwnd);
110 if (lphl == NULL) return 0;
111 y = lphl->FirstVisible;
112 switch(wParam) {
113 case SB_LINEUP:
114 if (lphl->FirstVisible > 1)
115 lphl->FirstVisible--;
116 break;
117 case SB_LINEDOWN:
118 if (lphl->FirstVisible < lphl->ItemsCount)
119 lphl->FirstVisible++;
120 break;
121 case SB_PAGEUP:
122 if (lphl->FirstVisible > 1)
123 lphl->FirstVisible -= lphl->ItemsVisible;
124 break;
125 case SB_PAGEDOWN:
126 if (lphl->FirstVisible < lphl->ItemsCount)
127 lphl->FirstVisible += lphl->ItemsVisible;
128 break;
129 case SB_THUMBTRACK:
130 lphl->FirstVisible = LOWORD(lParam);
131 break;
133 if (lphl->FirstVisible < 1) lphl->FirstVisible = 1;
134 if (lphl->FirstVisible > lphl->ItemsCount)
135 lphl->FirstVisible = lphl->ItemsCount;
136 if (y != lphl->FirstVisible) {
137 SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
138 InvalidateRect(hwnd, NULL, TRUE);
139 UpdateWindow(hwnd);
141 return 0;
143 case WM_HSCROLL:
144 #ifdef DEBUG_LISTBOX
145 printf("ListBox WM_HSCROLL w=%04X l=%08X !\n", wParam, lParam);
146 #endif
147 lphl = ListBoxGetStorageHeader(hwnd);
148 if (lphl == NULL) return 0;
149 y = lphl->FirstVisible;
150 switch(wParam) {
151 case SB_LINEUP:
152 if (lphl->FirstVisible > 1)
153 lphl->FirstVisible -= lphl->ItemsPerColumn;
154 break;
155 case SB_LINEDOWN:
156 if (lphl->FirstVisible < lphl->ItemsCount)
157 lphl->FirstVisible += lphl->ItemsPerColumn;
158 break;
159 case SB_PAGEUP:
160 if (lphl->FirstVisible > 1 && lphl->ItemsPerColumn != 0)
161 lphl->FirstVisible -= lphl->ItemsVisible /
162 lphl->ItemsPerColumn * lphl->ItemsPerColumn;
163 break;
164 case SB_PAGEDOWN:
165 if (lphl->FirstVisible < lphl->ItemsCount &&
166 lphl->ItemsPerColumn != 0)
167 lphl->FirstVisible += lphl->ItemsVisible /
168 lphl->ItemsPerColumn * lphl->ItemsPerColumn;
169 break;
170 case SB_THUMBTRACK:
171 lphl->FirstVisible = lphl->ItemsPerColumn *
172 (LOWORD(lParam) - 1) + 1;
173 break;
175 if (lphl->FirstVisible < 1) lphl->FirstVisible = 1;
176 if (lphl->FirstVisible > lphl->ItemsCount)
177 lphl->FirstVisible = lphl->ItemsCount;
178 if (lphl->ItemsPerColumn != 0) {
179 lphl->FirstVisible = lphl->FirstVisible /
180 lphl->ItemsPerColumn * lphl->ItemsPerColumn + 1;
181 if (y != lphl->FirstVisible) {
182 SetScrollPos(hwnd, SB_HORZ, lphl->FirstVisible /
183 lphl->ItemsPerColumn + 1, TRUE);
184 InvalidateRect(hwnd, NULL, TRUE);
185 UpdateWindow(hwnd);
188 return 0;
190 case WM_LBUTTONDOWN:
191 SetFocus(hwnd);
192 SetCapture(hwnd);
193 lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
194 if (lphl == NULL) return 0;
195 lphl->PrevFocused = lphl->ItemFocused;
196 y = ListBoxFindMouse(hwnd, LOWORD(lParam), HIWORD(lParam));
197 if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) {
198 lphl->ItemFocused = y;
199 wRet = ListBoxGetSel(hwnd, y);
200 ListBoxSetSel(hwnd, y, !wRet);
202 else {
203 ListBoxSetCurSel(hwnd, y);
205 ListBoxGetItemRect(hwnd, y, &rectsel);
206 InvalidateRect(hwnd, NULL, TRUE);
207 UpdateWindow(hwnd);
208 return 0;
209 case WM_LBUTTONUP:
210 ReleaseCapture();
211 lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
212 if (lphl == NULL) return 0;
213 if (lphl->PrevFocused != lphl->ItemFocused)
214 SendMessage(lphl->hWndLogicParent, WM_COMMAND, wndPtr->wIDmenu,
215 MAKELONG(hwnd, LBN_SELCHANGE));
216 return 0;
217 case WM_RBUTTONUP:
218 case WM_LBUTTONDBLCLK:
219 lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
220 if (lphl == NULL) return 0;
221 SendMessage(lphl->hWndLogicParent, WM_COMMAND, wndPtr->wIDmenu,
222 MAKELONG(hwnd, LBN_DBLCLK));
223 printf("ListBox Send LBN_DBLCLK !\n");
224 return 0;
225 case WM_MOUSEMOVE:
226 if ((wParam & MK_LBUTTON) != 0) {
227 y = HIWORD(lParam);
228 if (y < 4) {
229 lphl = ListBoxGetStorageHeader(hwnd);
230 if (lphl == NULL) return 0;
231 if (lphl->FirstVisible > 1) {
232 lphl->FirstVisible--;
233 if (wndPtr->dwStyle & WS_VSCROLL)
234 SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
235 InvalidateRect(hwnd, NULL, TRUE);
236 UpdateWindow(hwnd);
237 break;
240 GetClientRect(hwnd, &rect);
241 if (y > (rect.bottom - 4)) {
242 lphl = ListBoxGetStorageHeader(hwnd);
243 if (lphl == NULL) return 0;
244 if (lphl->FirstVisible < lphl->ItemsCount) {
245 lphl->FirstVisible++;
246 if (wndPtr->dwStyle & WS_VSCROLL)
247 SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
248 InvalidateRect(hwnd, NULL, TRUE);
249 UpdateWindow(hwnd);
250 break;
253 if ((y > 0) && (y < (rect.bottom - 4))) {
254 if ((y < rectsel.top) || (y > rectsel.bottom)) {
255 lphl = ListBoxGetStorageHeader(hwnd);
256 if (lphl == NULL) return 0;
257 wRet = ListBoxFindMouse(hwnd, LOWORD(lParam), HIWORD(lParam));
258 if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) {
259 lphl->ItemFocused = wRet;
261 else {
262 ListBoxSetCurSel(hwnd, wRet);
264 ListBoxGetItemRect(hwnd, wRet, &rectsel);
265 InvalidateRect(hwnd, NULL, TRUE);
266 UpdateWindow(hwnd);
270 break;
271 case WM_KEYDOWN:
272 lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
273 if (lphl == NULL) return 0;
274 switch(wParam) {
275 case VK_TAB:
276 hWndCtl = GetNextDlgTabItem(lphl->hWndLogicParent,
277 hwnd, !(GetKeyState(VK_SHIFT) < 0));
278 SetFocus(hWndCtl);
279 if ((GetKeyState(VK_SHIFT) < 0))
280 printf("ListBox PreviousDlgTabItem %04X !\n", hWndCtl);
281 else
282 printf("ListBox NextDlgTabItem %04X !\n", hWndCtl);
283 break;
284 case VK_HOME:
285 lphl->ItemFocused = 0;
286 break;
287 case VK_END:
288 lphl->ItemFocused = lphl->ItemsCount - 1;
289 break;
290 case VK_LEFT:
291 if ((wndPtr->dwStyle & LBS_MULTICOLUMN) == LBS_MULTICOLUMN) {
292 lphl->ItemFocused -= lphl->ItemsPerColumn;
294 break;
295 case VK_UP:
296 lphl->ItemFocused--;
297 break;
298 case VK_RIGHT:
299 if ((wndPtr->dwStyle & LBS_MULTICOLUMN) == LBS_MULTICOLUMN) {
300 lphl->ItemFocused += lphl->ItemsPerColumn;
302 break;
303 case VK_DOWN:
304 lphl->ItemFocused++;
305 break;
306 case VK_PRIOR:
307 lphl->ItemFocused -= lphl->ItemsVisible;
308 break;
309 case VK_NEXT:
310 lphl->ItemFocused += lphl->ItemsVisible;
311 break;
312 case VK_SPACE:
313 wRet = ListBoxGetSel(hwnd, lphl->ItemFocused);
314 ListBoxSetSel(hwnd, lphl->ItemFocused, !wRet);
315 break;
316 default:
317 ListBoxFindNextMatch(hwnd, wParam);
318 return 0;
320 if (lphl->ItemFocused < 0) lphl->ItemFocused = 0;
321 if (lphl->ItemFocused >= lphl->ItemsCount)
322 lphl->ItemFocused = lphl->ItemsCount - 1;
323 lphl->FirstVisible = lphl->ItemFocused / lphl->ItemsVisible *
324 lphl->ItemsVisible + 1;
325 if (lphl->FirstVisible < 1) lphl->FirstVisible = 1;
326 if ((wndPtr->dwStyle & LBS_MULTIPLESEL) != LBS_MULTIPLESEL) {
327 ListBoxSetCurSel(hwnd, lphl->ItemFocused);
329 if (wndPtr->dwStyle & WS_VSCROLL)
330 SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
331 InvalidateRect(hwnd, NULL, TRUE);
332 UpdateWindow(hwnd);
333 break;
334 case WM_SETFONT:
335 lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
336 if (lphl == NULL) return 0;
337 if (wParam == 0)
338 lphl->hFont = GetStockObject(SYSTEM_FONT);
339 else
340 lphl->hFont = wParam;
341 if (wParam == 0) break;
342 case WM_PAINT:
343 wndPtr = WIN_FindWndPtr(hwnd);
344 if ((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) == LBS_OWNERDRAWFIXED) {
345 OwnerDrawListBox(hwnd);
346 break;
348 if ((wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE) == LBS_OWNERDRAWVARIABLE) {
349 OwnerDrawListBox(hwnd);
350 break;
352 StdDrawListBox(hwnd);
353 break;
354 case WM_SETFOCUS:
355 #ifdef DEBUG_LISTBOX
356 printf("ListBox WM_SETFOCUS !\n");
357 #endif
358 lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
359 break;
360 case WM_KILLFOCUS:
361 #ifdef DEBUG_LISTBOX
362 printf("ListBox WM_KILLFOCUS !\n");
363 #endif
364 InvalidateRect(hwnd, NULL, TRUE);
365 UpdateWindow(hwnd);
366 break;
368 case LB_RESETCONTENT:
369 #ifdef DEBUG_LISTBOX
370 printf("ListBox LB_RESETCONTENT !\n");
371 #endif
372 ListBoxResetContent(hwnd);
373 return 0;
374 case LB_DIR:
375 #ifdef DEBUG_LISTBOX
376 printf("ListBox LB_DIR !\n");
377 #endif
378 wRet = ListBoxDirectory(hwnd, wParam, (LPSTR)lParam);
379 InvalidateRect(hwnd, NULL, TRUE);
380 UpdateWindow(hwnd);
381 return wRet;
382 case LB_ADDSTRING:
383 wRet = ListBoxAddString(hwnd, (LPSTR)lParam);
384 return wRet;
385 case LB_GETTEXT:
386 wRet = ListBoxGetText(hwnd, wParam, (LPSTR)lParam);
387 #ifdef DEBUG_LISTBOX
388 printf("ListBox LB_GETTEXT #%u '%s' !\n", wParam, (LPSTR)lParam);
389 #endif
390 return wRet;
391 case LB_INSERTSTRING:
392 wRet = ListBoxInsertString(hwnd, wParam, (LPSTR)lParam);
393 return wRet;
394 case LB_DELETESTRING:
395 printf("ListBox LB_DELETESTRING #%u !\n", wParam);
396 wRet = ListBoxDeleteString(hwnd, wParam);
397 return wRet;
398 case LB_FINDSTRING:
399 wRet = ListBoxFindString(hwnd, wParam, (LPSTR)lParam);
400 return wRet;
401 case LB_GETCARETINDEX:
402 return wRet;
403 case LB_GETCOUNT:
404 lphl = ListBoxGetStorageHeader(hwnd);
405 return lphl->ItemsCount;
406 case LB_GETCURSEL:
407 lphl = ListBoxGetStorageHeader(hwnd);
408 #ifdef DEBUG_LISTBOX
409 printf("ListBox LB_GETCURSEL %u !\n", lphl->ItemFocused);
410 #endif
411 return lphl->ItemFocused;
412 case LB_GETHORIZONTALEXTENT:
413 return wRet;
414 case LB_GETITEMDATA:
415 return wRet;
416 case LB_GETITEMHEIGHT:
417 return wRet;
418 case LB_GETITEMRECT:
419 return wRet;
420 case LB_GETSEL:
421 wRet = ListBoxGetSel(hwnd, wParam);
422 return wRet;
423 case LB_GETSELCOUNT:
424 return wRet;
425 case LB_GETSELITEMS:
426 return wRet;
427 case LB_GETTEXTLEN:
428 return wRet;
429 case LB_GETTOPINDEX:
430 return wRet;
431 case LB_SELECTSTRING:
432 return wRet;
433 case LB_SELITEMRANGE:
434 return wRet;
435 case LB_SETCARETINDEX:
436 return wRet;
437 case LB_SETCOLUMNWIDTH:
438 lphl = ListBoxGetStorageHeader(hwnd);
439 lphl->ColumnsWidth = wParam;
440 break;
441 case LB_SETHORIZONTALEXTENT:
442 return wRet;
443 case LB_SETITEMDATA:
444 return wRet;
445 case LB_SETTABSTOPS:
446 return wRet;
447 case LB_SETCURSEL:
448 #ifdef DEBUG_LISTBOX
449 printf("ListBox LB_SETCURSEL wParam=%x !\n", wParam);
450 #endif
451 wRet = ListBoxSetCurSel(hwnd, wParam);
452 InvalidateRect(hwnd, NULL, TRUE);
453 UpdateWindow(hwnd);
454 return wRet;
455 case LB_SETSEL:
456 printf("ListBox LB_SETSEL wParam=%x lParam=%lX !\n", wParam, lParam);
457 wRet = ListBoxSetSel(hwnd, LOWORD(lParam), wParam);
458 InvalidateRect(hwnd, NULL, TRUE);
459 UpdateWindow(hwnd);
460 return wRet;
461 case LB_SETTOPINDEX:
462 printf("ListBox LB_SETTOPINDEX wParam=%x !\n", wParam);
463 lphl = ListBoxGetStorageHeader(hwnd);
464 lphl->FirstVisible = wParam;
465 wndPtr = WIN_FindWndPtr(hwnd);
466 if (wndPtr->dwStyle & WS_VSCROLL)
467 SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
468 InvalidateRect(hwnd, NULL, TRUE);
469 UpdateWindow(hwnd);
470 break;
471 case LB_SETITEMHEIGHT:
472 #ifdef DEBUG_LISTBOX
473 printf("ListBox LB_SETITEMHEIGHT wParam=%x lParam=%lX !\n", wParam, lParam);
474 #endif
475 wRet = ListBoxSetItemHeight(hwnd, wParam, lParam);
476 return wRet;
478 default:
479 return DefWindowProc( hwnd, message, wParam, lParam );
481 return 0;
485 LPHEADLIST ListBoxGetWindowAndStorage(HWND hwnd, WND **wndPtr)
487 WND *Ptr;
488 LPHEADLIST lphl;
489 *(wndPtr) = Ptr = WIN_FindWndPtr(hwnd);
490 lphl = *((LPHEADLIST *)&Ptr->wExtra[1]);
491 return lphl;
495 LPHEADLIST ListBoxGetStorageHeader(HWND hwnd)
497 WND *wndPtr;
498 LPHEADLIST lphl;
499 wndPtr = WIN_FindWndPtr(hwnd);
500 lphl = *((LPHEADLIST *)&wndPtr->wExtra[1]);
501 return lphl;
505 void StdDrawListBox(HWND hwnd)
507 WND *wndPtr;
508 LPHEADLIST lphl;
509 LPLISTSTRUCT lpls;
510 PAINTSTRUCT ps;
511 HBRUSH hBrush;
512 int OldBkMode;
513 DWORD dwOldTextColor;
514 HWND hWndParent;
515 HDC hdc;
516 RECT rect;
517 UINT i, h, h2, maxwidth, ipc;
518 char C[128];
519 h = 0;
520 hdc = BeginPaint( hwnd, &ps );
521 if (!IsWindowVisible(hwnd)) {
522 EndPaint( hwnd, &ps );
523 return;
525 lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
526 if (lphl == NULL) goto EndOfPaint;
527 SelectObject(hdc, lphl->hFont);
528 hBrush = SendMessage(lphl->hWndLogicParent, WM_CTLCOLOR, (WORD)hdc,
529 MAKELONG(hwnd, CTLCOLOR_LISTBOX));
530 if (hBrush == (HBRUSH)NULL) hBrush = GetStockObject(WHITE_BRUSH);
531 GetClientRect(hwnd, &rect);
533 if (wndPtr->dwStyle & WS_VSCROLL) rect.right -= 16;
534 if (wndPtr->dwStyle & WS_HSCROLL) rect.bottom -= 16;
536 FillRect(hdc, &rect, hBrush);
537 maxwidth = rect.right;
538 rect.right = lphl->ColumnsWidth;
539 if (lphl->ItemsCount == 0) goto EndOfPaint;
540 lpls = lphl->lpFirst;
541 if (lpls == NULL) goto EndOfPaint;
542 lphl->ItemsVisible = 0;
543 lphl->ItemsPerColumn = ipc = 0;
544 for(i = 1; i <= lphl->ItemsCount; i++) {
545 if (i >= lphl->FirstVisible) {
546 if (lpls == NULL) break;
547 if ((h + lpls->dis.rcItem.bottom - lpls->dis.rcItem.top) > rect.bottom) {
548 if ((wndPtr->dwStyle & LBS_MULTICOLUMN) == LBS_MULTICOLUMN) {
549 lphl->ItemsPerColumn = max(lphl->ItemsPerColumn, ipc);
550 ipc = 0;
551 h = 0;
552 rect.left += lphl->ColumnsWidth;
553 rect.right += lphl->ColumnsWidth;
554 if (rect.left > maxwidth) break;
556 else
557 break;
559 h2 = lpls->dis.rcItem.bottom - lpls->dis.rcItem.top;
560 lpls->dis.rcItem.top = h;
561 lpls->dis.rcItem.bottom = h + h2;
562 lpls->dis.rcItem.left = rect.left;
563 lpls->dis.rcItem.right = rect.right;
564 OldBkMode = SetBkMode(hdc, TRANSPARENT);
565 if (lpls->dis.itemState != 0) {
566 dwOldTextColor = SetTextColor(hdc, 0x00FFFFFFL);
567 FillRect(hdc, &lpls->dis.rcItem, GetStockObject(BLACK_BRUSH));
569 TextOut(hdc, rect.left + 5, h + 2, (char *)lpls->dis.itemData,
570 strlen((char *)lpls->dis.itemData));
571 if (lpls->dis.itemState != 0) {
572 SetTextColor(hdc, dwOldTextColor);
574 SetBkMode(hdc, OldBkMode);
575 if ((lphl->ItemFocused == i - 1) && GetFocus() == hwnd) {
576 DrawFocusRect(hdc, &lpls->dis.rcItem);
578 h += h2;
579 lphl->ItemsVisible++;
580 ipc++;
582 if (lpls->lpNext == NULL) goto EndOfPaint;
583 lpls = (LPLISTSTRUCT)lpls->lpNext;
585 EndOfPaint:
586 EndPaint( hwnd, &ps );
587 if ((lphl->ItemsCount > lphl->ItemsVisible) &
588 (wndPtr->dwStyle & WS_VSCROLL)) {
590 InvalidateRect(wndPtr->hWndVScroll, NULL, TRUE);
591 UpdateWindow(wndPtr->hWndVScroll);
598 void OwnerDrawListBox(HWND hwnd)
600 WND *wndPtr;
601 LPHEADLIST lphl;
602 LPLISTSTRUCT lpls;
603 PAINTSTRUCT ps;
604 HBRUSH hBrush;
605 HWND hWndParent;
606 HDC hdc;
607 RECT rect;
608 UINT i, h, h2, maxwidth;
609 char C[128];
610 h = 0;
611 hdc = BeginPaint(hwnd, &ps);
612 if (!IsWindowVisible(hwnd)) {
613 EndPaint( hwnd, &ps );
614 return;
616 lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
617 if (lphl == NULL) goto EndOfPaint;
618 hBrush = SendMessage(lphl->hWndLogicParent, WM_CTLCOLOR, (WORD)hdc,
619 MAKELONG(hwnd, CTLCOLOR_LISTBOX));
620 if (hBrush == (HBRUSH)NULL) hBrush = GetStockObject(WHITE_BRUSH);
621 GetClientRect(hwnd, &rect);
622 if (wndPtr->dwStyle & WS_VSCROLL) rect.right -= 16;
623 if (wndPtr->dwStyle & WS_HSCROLL) rect.bottom -= 16;
624 FillRect(hdc, &rect, hBrush);
625 maxwidth = rect.right;
626 rect.right = lphl->ColumnsWidth;
627 if (lphl->ItemsCount == 0) goto EndOfPaint;
628 lpls = lphl->lpFirst;
629 if (lpls == NULL) goto EndOfPaint;
630 lphl->ItemsVisible = 0;
631 for (i = 1; i <= lphl->ItemsCount; i++) {
632 if (i >= lphl->FirstVisible) {
633 lpls->dis.hDC = hdc;
634 lpls->dis.itemID = i - 1;
635 h2 = lpls->dis.rcItem.bottom - lpls->dis.rcItem.top;
636 lpls->dis.rcItem.top = h;
637 lpls->dis.rcItem.bottom = h + h2;
638 lpls->dis.rcItem.left = rect.left;
639 lpls->dis.rcItem.right = rect.right;
640 lpls->dis.itemAction = ODA_DRAWENTIRE;
641 if (lpls->dis.itemState != 0) {
642 lpls->dis.itemAction |= ODA_SELECT;
644 if (lphl->ItemFocused == i - 1) {
645 lpls->dis.itemAction |= ODA_FOCUS;
647 #ifdef DEBUT_LISTBOX
648 printf("LBOX WM_DRAWITEM #%d left=%d top=%d right=%d bottom=%d !\n",
649 i, lpls->dis.rcItem.left, lpls->dis.rcItem.top,
650 lpls->dis.rcItem.right, lpls->dis.rcItem.bottom);
651 printf("LBOX WM_DRAWITEM Parent=%X &dis=%lX CtlID=%u !\n",
652 hWndParent, (LONG)&lpls->dis, lpls->dis.CtlID);
653 printf("LBOX WM_DRAWITEM '%s' !\n", lpls->dis.itemData);
654 #endif
655 SendMessage(lphl->hWndLogicParent, WM_DRAWITEM, i, (LPARAM)&lpls->dis);
656 if (lpls->dis.itemState != 0) {
657 InvertRect(hdc, &lpls->dis.rcItem);
659 h += h2;
660 lphl->ItemsVisible++;
661 if (h > rect.bottom) goto EndOfPaint;
663 if (lpls->lpNext == NULL) goto EndOfPaint;
664 lpls = (LPLISTSTRUCT)lpls->lpNext;
666 EndOfPaint:
667 EndPaint( hwnd, &ps );
668 if ((lphl->ItemsCount > lphl->ItemsVisible) &
669 (wndPtr->dwStyle & WS_VSCROLL)) {
671 InvalidateRect(wndPtr->hWndVScroll, NULL, TRUE);
672 UpdateWindow(wndPtr->hWndVScroll);
679 int ListBoxFindMouse(HWND hwnd, int X, int Y)
681 WND *wndPtr;
682 LPHEADLIST lphl;
683 LPLISTSTRUCT lpls;
684 RECT rect;
685 UINT i, h, h2, w, w2;
686 char C[128];
687 lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
688 if (lphl == NULL) return LB_ERR;
689 if (lphl->ItemsCount == 0) return LB_ERR;
690 lpls = lphl->lpFirst;
691 if (lpls == NULL) return LB_ERR;
692 GetClientRect(hwnd, &rect);
693 if (wndPtr->dwStyle & WS_VSCROLL) rect.right -= 16;
694 if (wndPtr->dwStyle & WS_HSCROLL) rect.bottom -= 16;
695 h = w2 = 0;
696 w = lphl->ColumnsWidth;
697 for(i = 1; i <= lphl->ItemsCount; i++) {
698 if (i >= lphl->FirstVisible) {
699 h2 = h;
700 h += lpls->dis.rcItem.bottom - lpls->dis.rcItem.top;
701 if ((Y > h2) && (Y < h) &&
702 (X > w2) && (X < w)) return(i - 1);
703 if (h > rect.bottom) {
704 if ((wndPtr->dwStyle & LBS_MULTICOLUMN) != LBS_MULTICOLUMN) return LB_ERR;
705 h = 0;
706 w2 = w;
707 w += lphl->ColumnsWidth;
708 if (w2 > rect.right) return LB_ERR;
711 if (lpls->lpNext == NULL) return LB_ERR;
712 lpls = (LPLISTSTRUCT)lpls->lpNext;
714 return(LB_ERR);
719 int CreateListBoxStruct(HWND hwnd)
721 WND *wndPtr;
722 LPHEADLIST lphl;
723 wndPtr = WIN_FindWndPtr(hwnd);
724 lphl = (LPHEADLIST)malloc(sizeof(HEADLIST));
725 lphl->lpFirst = NULL;
726 *((LPHEADLIST *)&wndPtr->wExtra[1]) = lphl; /* HEAD of List */
727 lphl->ItemsCount = 0;
728 lphl->ItemsVisible = 0;
729 lphl->FirstVisible = 1;
730 lphl->StdItemHeight = 15;
731 lphl->DrawCtlType = ODT_LISTBOX;
732 return TRUE;
736 void ListBoxAskMeasure(WND *wndPtr, LPHEADLIST lphl, LPLISTSTRUCT lpls)
738 MEASUREITEMSTRUCT *measure;
739 HANDLE hTemp = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(MEASUREITEMSTRUCT));
740 measure = (MEASUREITEMSTRUCT *) USER_HEAP_ADDR(hTemp);
741 if (measure == NULL) {
742 printf("ListBoxAskMeasure() // Bad allocation of Measure struct !\n");
743 return;
745 measure->CtlType = ODT_LISTBOX;
746 measure->CtlID = wndPtr->wIDmenu;
747 measure->itemID = lpls->dis.itemID;
748 measure->itemWidth = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
749 measure->itemHeight = 0;
750 measure->itemData = lpls->dis.itemData;
751 SendMessage(lphl->hWndLogicParent, WM_MEASUREITEM, 0, (DWORD)measure);
752 lpls->dis.rcItem.right = lpls->dis.rcItem.left + measure->itemWidth;
753 lpls->dis.rcItem.bottom = lpls->dis.rcItem.top + measure->itemHeight;
754 USER_HEAP_FREE(hTemp);
758 int ListBoxAddString(HWND hwnd, LPSTR newstr)
760 WND *wndPtr;
761 LPHEADLIST lphl;
762 LPLISTSTRUCT lpls, lplsnew;
763 HANDLE hTemp;
764 LPSTR str;
765 lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
766 if (lphl == NULL) return LB_ERR;
767 hTemp = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(LISTSTRUCT));
768 lplsnew = (LPLISTSTRUCT) USER_HEAP_ADDR(hTemp);
769 if (lplsnew == NULL) {
770 printf("ListBoxAddString() // Bad allocation of new item !\n");
771 return LB_ERRSPACE;
773 lpls = lphl->lpFirst;
774 if (lpls != NULL) {
775 while(lpls->lpNext != NULL) {
776 lpls = (LPLISTSTRUCT)lpls->lpNext;
778 lpls->lpNext = lplsnew;
780 else
781 lphl->lpFirst = lplsnew;
782 lphl->ItemsCount++;
783 #ifdef DEBUG_LISTBOX
784 printf("Items Count = %u\n", lphl->ItemsCount);
785 #endif
786 hTemp = 0;
787 if ((wndPtr->dwStyle & LBS_HASSTRINGS) != LBS_HASSTRINGS) {
788 if (((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) != LBS_OWNERDRAWFIXED) &&
789 ((wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE) != LBS_OWNERDRAWVARIABLE)) {
790 hTemp = USER_HEAP_ALLOC(GMEM_MOVEABLE, strlen(newstr) + 1);
791 str = (LPSTR)USER_HEAP_ADDR(hTemp);
792 if (str == NULL) return LB_ERRSPACE;
793 strcpy(str, newstr);
794 newstr = str;
795 #ifdef DEBUG_LISTBOX
796 printf("ListBoxAddString// after strcpy '%s'\n", str);
797 #endif
800 ListBoxDefaultItem(hwnd, wndPtr, lphl, lplsnew);
801 lplsnew->hMem = hTemp;
802 lplsnew->lpNext = NULL;
803 lplsnew->dis.itemID = lphl->ItemsCount;
804 lplsnew->dis.itemData = (DWORD)newstr;
805 lplsnew->hData = hTemp;
806 if ((wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE) == LBS_OWNERDRAWVARIABLE)
807 ListBoxAskMeasure(wndPtr, lphl, lplsnew);
808 if (wndPtr->dwStyle & WS_VSCROLL)
809 SetScrollRange(hwnd, SB_VERT, 1, lphl->ItemsCount,
810 (lphl->FirstVisible != 1));
811 if ((wndPtr->dwStyle & WS_HSCROLL) && lphl->ItemsPerColumn != 0)
812 SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible /
813 lphl->ItemsPerColumn + 1, (lphl->FirstVisible != 1));
814 if (lphl->FirstVisible >= (lphl->ItemsCount - lphl->ItemsVisible)) {
815 InvalidateRect(hwnd, NULL, TRUE);
816 UpdateWindow(hwnd);
818 if ((lphl->ItemsCount - lphl->FirstVisible) == lphl->ItemsVisible) {
819 if (wndPtr->dwStyle & WS_VSCROLL)
820 ShowScrollBar(hwnd, SB_VERT, TRUE);
821 if (wndPtr->dwStyle & WS_HSCROLL)
822 ShowScrollBar(hwnd, SB_HORZ, TRUE);
824 return lphl->ItemsCount;
828 int ListBoxInsertString(HWND hwnd, UINT uIndex, LPSTR newstr)
830 WND *wndPtr;
831 LPHEADLIST lphl;
832 LPLISTSTRUCT lpls, lplsnew;
833 HANDLE hTemp;
834 LPSTR str;
835 UINT Count;
836 #ifdef DEBUG_LISTBOX
837 printf("ListBoxInsertString(%04X, %d, %08X);\n", hwnd, uIndex, newstr);
838 #endif
839 if (uIndex == (UINT)-1) return ListBoxAddString(hwnd, newstr);
840 lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
841 if (lphl == NULL) return LB_ERR;
842 if (uIndex >= lphl->ItemsCount) return LB_ERR;
843 lpls = lphl->lpFirst;
844 if (lpls == NULL) return LB_ERR;
845 if (uIndex > lphl->ItemsCount) return LB_ERR;
846 for(Count = 1; Count < uIndex; Count++) {
847 if (lpls->lpNext == NULL) return LB_ERR;
848 lpls = (LPLISTSTRUCT)lpls->lpNext;
850 hTemp = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(LISTSTRUCT));
851 lplsnew = (LPLISTSTRUCT) USER_HEAP_ADDR(hTemp);
852 if (lplsnew == NULL) {
853 printf("ListBoxInsertString() // Bad allocation of new item !\n");
854 return LB_ERRSPACE;
856 ListBoxDefaultItem(hwnd, wndPtr, lphl, lplsnew);
857 lplsnew->hMem = hTemp;
858 lpls->lpNext = lplsnew;
859 lphl->ItemsCount++;
860 hTemp = 0;
861 if ((wndPtr->dwStyle & LBS_HASSTRINGS) != LBS_HASSTRINGS) {
862 if (((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) != LBS_OWNERDRAWFIXED) &&
863 ((wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE) != LBS_OWNERDRAWVARIABLE)) {
864 hTemp = USER_HEAP_ALLOC(GMEM_MOVEABLE, strlen(newstr) + 1);
865 str = (LPSTR)USER_HEAP_ADDR(hTemp);
866 if (str == NULL) return LB_ERRSPACE;
867 strcpy(str, newstr);
868 newstr = str;
869 #ifdef DEBUG_LISTBOX
870 printf("ListBoxInsertString // after strcpy '%s'\n", str);
871 #endif
874 lplsnew->lpNext = NULL;
875 lplsnew->dis.itemID = lphl->ItemsCount;
876 lplsnew->dis.itemData = (DWORD)newstr;
877 lplsnew->hData = hTemp;
878 if ((wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE) == LBS_OWNERDRAWVARIABLE)
879 ListBoxAskMeasure(wndPtr, lphl, lplsnew);
880 if (wndPtr->dwStyle & WS_VSCROLL)
881 SetScrollRange(hwnd, SB_VERT, 1, lphl->ItemsCount,
882 (lphl->FirstVisible != 1));
883 if ((wndPtr->dwStyle & WS_HSCROLL) && lphl->ItemsPerColumn != 0)
884 SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible /
885 lphl->ItemsPerColumn + 1, (lphl->FirstVisible != 1));
886 if (((lphl->ItemsCount - lphl->FirstVisible) == lphl->ItemsVisible) &&
887 (lphl->ItemsVisible != 0)) {
888 if (wndPtr->dwStyle & WS_VSCROLL) ShowScrollBar(hwnd, SB_VERT, TRUE);
889 if (wndPtr->dwStyle & WS_HSCROLL) ShowScrollBar(hwnd, SB_HORZ, TRUE);
891 if ((lphl->FirstVisible <= uIndex) &&
892 ((lphl->FirstVisible + lphl->ItemsVisible) >= uIndex)) {
893 InvalidateRect(hwnd, NULL, TRUE);
894 UpdateWindow(hwnd);
896 #ifdef DEBUG_LISTBOX
897 printf("ListBoxInsertString // count=%d\n", lphl->ItemsCount);
898 #endif
899 return lphl->ItemsCount;
903 int ListBoxGetText(HWND hwnd, UINT uIndex, LPSTR OutStr)
905 WND *wndPtr;
906 LPHEADLIST lphl;
907 LPLISTSTRUCT lpls;
908 UINT Count;
909 lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
910 if (lphl == NULL) return LB_ERR;
911 if (uIndex >= lphl->ItemsCount) return LB_ERR;
912 lpls = lphl->lpFirst;
913 if (lpls == NULL) return LB_ERR;
914 if (uIndex > lphl->ItemsCount) return LB_ERR;
915 for(Count = 0; Count < uIndex; Count++) {
916 if (lpls->lpNext == NULL) return LB_ERR;
917 lpls = (LPLISTSTRUCT)lpls->lpNext;
919 if (((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) == LBS_OWNERDRAWFIXED) ||
920 ((wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE) == LBS_OWNERDRAWVARIABLE)) {
921 if ((wndPtr->dwStyle & LBS_HASSTRINGS) != LBS_HASSTRINGS) {
922 *((long *)OutStr) = lpls->dis.itemData;
923 return 4;
927 strcpy(OutStr, (char *)lpls->dis.itemData);
928 return strlen(OutStr);
932 int ListBoxDeleteString(HWND hwnd, UINT uIndex)
934 WND *wndPtr;
935 LPHEADLIST lphl;
936 LPLISTSTRUCT lpls, lpls2;
937 UINT Count;
938 lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
939 if (lphl == NULL) return LB_ERR;
940 if (uIndex >= lphl->ItemsCount) return LB_ERR;
941 lpls = lphl->lpFirst;
942 if (lpls == NULL) return LB_ERR;
943 if (uIndex > lphl->ItemsCount) return LB_ERR;
944 for(Count = 1; Count < uIndex; Count++) {
945 if (lpls->lpNext == NULL) return LB_ERR;
946 lpls2 = lpls;
947 lpls = (LPLISTSTRUCT)lpls->lpNext;
949 lpls2->lpNext = (LPLISTSTRUCT)lpls->lpNext;
950 lphl->ItemsCount--;
951 if (lpls->hData != 0) USER_HEAP_FREE(lpls->hData);
952 if (lpls->hMem != 0) USER_HEAP_FREE(lpls->hMem);
953 if (wndPtr->dwStyle & WS_VSCROLL)
954 SetScrollRange(hwnd, SB_VERT, 1, lphl->ItemsCount, TRUE);
955 if ((wndPtr->dwStyle & WS_HSCROLL) && lphl->ItemsPerColumn != 0)
956 SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible /
957 lphl->ItemsPerColumn + 1, TRUE);
958 if (lphl->ItemsCount < lphl->ItemsVisible) {
959 if (wndPtr->dwStyle & WS_VSCROLL)
960 ShowScrollBar(hwnd, SB_VERT, FALSE);
961 if (wndPtr->dwStyle & WS_HSCROLL)
962 ShowScrollBar(hwnd, SB_HORZ, FALSE);
964 if ((lphl->FirstVisible <= uIndex) &&
965 ((lphl->FirstVisible + lphl->ItemsVisible) >= uIndex)) {
966 InvalidateRect(hwnd, NULL, TRUE);
967 UpdateWindow(hwnd);
969 return lphl->ItemsCount;
973 int ListBoxFindString(HWND hwnd, UINT nFirst, LPSTR MatchStr)
975 LPHEADLIST lphl;
976 LPLISTSTRUCT lpls;
977 UINT Count;
978 lphl = ListBoxGetStorageHeader(hwnd);
979 if (lphl == NULL) return LB_ERR;
980 if (nFirst > lphl->ItemsCount) return LB_ERR;
981 lpls = lphl->lpFirst;
982 if (lpls == NULL) return LB_ERR;
983 Count = 0;
984 while(lpls != NULL) {
985 if (strcmp((char *)lpls->dis.itemData, MatchStr) == 0) return Count;
986 lpls = (LPLISTSTRUCT)lpls->lpNext;
987 Count++;
989 return LB_ERR;
993 int ListBoxResetContent(HWND hwnd)
995 WND *wndPtr;
996 LPHEADLIST lphl;
997 LPLISTSTRUCT lpls, lpls2;
998 UINT i;
999 lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
1000 if (lphl == NULL) return LB_ERR;
1001 lpls = lphl->lpFirst;
1002 if (lpls == NULL) return LB_ERR;
1003 for(i = 0; i <= lphl->ItemsCount; i++) {
1004 lpls2 = lpls;
1005 lpls = (LPLISTSTRUCT)lpls->lpNext;
1006 if (i != 0) {
1007 #ifdef DEBUG_LISTBOX
1008 printf("ResetContent #%u\n", i);
1009 #endif
1010 if (lpls2->hData != 0 && lpls2->hData != lpls2->hMem)
1011 USER_HEAP_FREE(lpls2->hData);
1012 if (lpls2->hMem != 0) USER_HEAP_FREE(lpls2->hMem);
1014 if (lpls == NULL) break;
1016 lphl->lpFirst = NULL;
1017 lphl->FirstVisible = 1;
1018 lphl->ItemsCount = 0;
1019 lphl->ItemFocused = 0;
1020 lphl->PrevFocused = 0;
1021 if ((wndPtr->dwStyle && LBS_NOTIFY) != 0)
1022 SendMessage(lphl->hWndLogicParent, WM_COMMAND,
1023 wndPtr->wIDmenu, MAKELONG(hwnd, LBN_SELCHANGE));
1024 if (wndPtr->dwStyle & WS_VSCROLL)
1025 SetScrollRange(hwnd, SB_VERT, 1, lphl->ItemsCount, TRUE);
1026 if ((wndPtr->dwStyle & WS_HSCROLL) && lphl->ItemsPerColumn != 0)
1027 SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible /
1028 lphl->ItemsPerColumn + 1, TRUE);
1029 if (wndPtr->dwStyle & WS_VSCROLL)
1030 ShowScrollBar(hwnd, SB_VERT, FALSE);
1031 if (wndPtr->dwStyle & WS_HSCROLL)
1032 ShowScrollBar(hwnd, SB_HORZ, FALSE);
1033 InvalidateRect(hwnd, NULL, TRUE);
1034 UpdateWindow(hwnd);
1035 return TRUE;
1039 int ListBoxSetCurSel(HWND hwnd, WORD wIndex)
1041 WND *wndPtr;
1042 LPHEADLIST lphl;
1043 LPLISTSTRUCT lpls, lpls2;
1044 UINT i;
1045 lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
1046 if (lphl == NULL) return LB_ERR;
1047 lphl->ItemFocused = LB_ERR;
1048 if (wIndex >= lphl->ItemsCount) return LB_ERR;
1049 lpls = lphl->lpFirst;
1050 if (lpls == NULL) return LB_ERR;
1051 for(i = 0; i < lphl->ItemsCount; i++) {
1052 lpls2 = lpls;
1053 lpls = (LPLISTSTRUCT)lpls->lpNext;
1054 if (i == wIndex)
1055 lpls2->dis.itemState = 1;
1056 else
1057 if (lpls2->dis.itemState != 0)
1058 lpls2->dis.itemState = 0;
1059 if (lpls == NULL) break;
1061 lphl->ItemFocused = wIndex;
1062 if ((wndPtr->dwStyle && LBS_NOTIFY) != 0)
1063 SendMessage(lphl->hWndLogicParent, WM_COMMAND,
1064 wndPtr->wIDmenu, MAKELONG(hwnd, LBN_SELCHANGE));
1065 return LB_ERR;
1070 int ListBoxSetSel(HWND hwnd, WORD wIndex, WORD state)
1072 LPHEADLIST lphl;
1073 LPLISTSTRUCT lpls, lpls2;
1074 UINT i;
1075 lphl = ListBoxGetStorageHeader(hwnd);
1076 if (lphl == NULL) return LB_ERR;
1077 if (wIndex >= lphl->ItemsCount) return LB_ERR;
1078 lpls = lphl->lpFirst;
1079 if (lpls == NULL) return LB_ERR;
1080 for(i = 0; i < lphl->ItemsCount; i++) {
1081 lpls2 = lpls;
1082 lpls = (LPLISTSTRUCT)lpls->lpNext;
1083 if ((i == wIndex) || (wIndex == (WORD)-1)) {
1084 lpls2->dis.itemState = state;
1085 break;
1087 if (lpls == NULL) break;
1089 return LB_ERR;
1093 int ListBoxGetSel(HWND hwnd, WORD wIndex)
1095 LPHEADLIST lphl;
1096 LPLISTSTRUCT lpls, lpls2;
1097 UINT i;
1098 lphl = ListBoxGetStorageHeader(hwnd);
1099 if (lphl == NULL) return LB_ERR;
1100 if (wIndex >= lphl->ItemsCount) return LB_ERR;
1101 lpls = lphl->lpFirst;
1102 if (lpls == NULL) return LB_ERR;
1103 for(i = 0; i < lphl->ItemsCount; i++) {
1104 lpls2 = lpls;
1105 lpls = (LPLISTSTRUCT)lpls->lpNext;
1106 if (i == wIndex) {
1107 return lpls2->dis.itemState;
1109 if (lpls == NULL) break;
1111 return LB_ERR;
1115 int ListBoxDirectory(HWND hwnd, UINT attrib, LPSTR filespec)
1117 struct dosdirent *dp;
1118 struct dosdirent *newdp;
1119 struct stat st;
1120 int x, wRet;
1121 char temp[256];
1122 #ifdef DEBUG_LISTBOX
1123 fprintf(stderr,"ListBoxDirectory: %s, %4x\n",filespec,attrib);
1124 #endif
1125 if ((dp = (struct dosdirent *)DOS_opendir(filespec)) ==NULL) return 0;
1126 while (dp = (struct dosdirent *)DOS_readdir(dp)) {
1127 if (!dp->inuse) break;
1128 #ifdef DEBUG_LISTBOX
1129 printf("ListBoxDirectory %08X '%s' !\n", dp->filename, dp->filename);
1130 #endif
1131 if (dp->attribute & FA_DIREC) {
1132 if (attrib & DDL_DIRECTORY) {
1133 sprintf(temp, "[%s]", dp->filename);
1134 if ( (wRet = ListBoxAddString(hwnd, temp)) == LB_ERR) break;
1136 } else
1137 if (attrib & DDL_EXCLUSIVE) {
1138 if (attrib & (DDL_READWRITE | DDL_READONLY | DDL_HIDDEN | DDL_SYSTEM) )
1139 if ( (wRet = ListBoxAddString(hwnd, dp->filename)) == LB_ERR)
1140 break;
1141 } else {
1142 if ( (wRet = ListBoxAddString(hwnd, dp->filename)) == LB_ERR)
1143 break;
1146 DOS_closedir(dp);
1148 if (attrib & DDL_DRIVES)
1150 for (x=0;x!=MAX_DOS_DRIVES;x++)
1152 if (DOS_ValidDrive(x))
1154 sprintf(temp, "[-%c-]", 'a'+x);
1155 if ( (wRet = ListBoxAddString(hwnd, temp)) == LB_ERR)
1156 break;
1160 #ifdef DEBUG_LISTBOX
1161 printf("End of ListBoxDirectory !\n");
1162 #endif
1163 return wRet;
1167 int ListBoxGetItemRect(HWND hwnd, WORD wIndex, LPRECT lprect)
1169 LPHEADLIST lphl;
1170 LPLISTSTRUCT lpls, lpls2;
1171 UINT i;
1172 lphl = ListBoxGetStorageHeader(hwnd);
1173 if (lphl == NULL) return LB_ERR;
1174 if (wIndex > lphl->ItemsCount) return LB_ERR;
1175 lpls = lphl->lpFirst;
1176 if (lpls == NULL) return LB_ERR;
1177 for(i = 0; i < lphl->ItemsCount; i++) {
1178 lpls2 = lpls;
1179 lpls = (LPLISTSTRUCT)lpls->lpNext;
1180 if (i == wIndex) {
1181 *(lprect) = lpls2->dis.rcItem;
1182 break;
1184 if (lpls == NULL) break;
1186 return LB_ERR;
1191 int ListBoxSetItemHeight(HWND hwnd, WORD wIndex, long height)
1193 LPHEADLIST lphl;
1194 LPLISTSTRUCT lpls, lpls2;
1195 UINT i;
1196 lphl = ListBoxGetStorageHeader(hwnd);
1197 if (lphl == NULL) return LB_ERR;
1198 if (wIndex > lphl->ItemsCount) return LB_ERR;
1199 lpls = lphl->lpFirst;
1200 if (lpls == NULL) return LB_ERR;
1201 for(i = 0; i < lphl->ItemsCount; i++) {
1202 lpls2 = lpls;
1203 lpls = (LPLISTSTRUCT)lpls->lpNext;
1204 if (i == wIndex) {
1205 lpls2->dis.rcItem.bottom = lpls2->dis.rcItem.top + (short)height;
1206 InvalidateRect(hwnd, NULL, TRUE);
1207 UpdateWindow(hwnd);
1208 break;
1210 if (lpls == NULL) break;
1212 return LB_ERR;
1219 int ListBoxDefaultItem(HWND hwnd, WND *wndPtr,
1220 LPHEADLIST lphl, LPLISTSTRUCT lpls)
1222 RECT rect;
1223 if (wndPtr == NULL || lphl == NULL || lpls == NULL) {
1224 printf("ListBoxDefaultItem() // Bad Pointers !\n");
1225 return FALSE;
1227 GetClientRect(hwnd, &rect);
1228 SetRect(&lpls->dis.rcItem, 0, 0, rect.right, lphl->StdItemHeight);
1229 lpls->dis.CtlType = lphl->DrawCtlType;
1230 lpls->dis.CtlID = wndPtr->wIDmenu;
1231 lpls->dis.itemID = 0;
1232 lpls->dis.itemAction = 0;
1233 lpls->dis.itemState = 0;
1234 lpls->dis.hwndItem = hwnd;
1235 lpls->dis.hDC = 0;
1236 lpls->dis.itemData = 0;
1237 return TRUE;
1242 int ListBoxFindNextMatch(HWND hwnd, WORD wChar)
1244 WND *wndPtr;
1245 LPHEADLIST lphl;
1246 LPLISTSTRUCT lpls;
1247 UINT Count;
1248 lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
1249 if (lphl == NULL) return LB_ERR;
1250 lpls = lphl->lpFirst;
1251 if (lpls == NULL) return LB_ERR;
1252 if (wChar < ' ') return LB_ERR;
1253 if (((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) == LBS_OWNERDRAWFIXED) ||
1254 ((wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE) == LBS_OWNERDRAWVARIABLE)) {
1255 if ((wndPtr->dwStyle & LBS_HASSTRINGS) != LBS_HASSTRINGS) {
1256 return LB_ERR;
1259 Count = 0;
1260 while(lpls != NULL) {
1261 if (Count > lphl->ItemFocused) {
1262 if (*((char *)lpls->dis.itemData) == (char)wChar) {
1263 lphl->FirstVisible = Count - lphl->ItemsVisible / 2;
1264 if (lphl->FirstVisible < 1) lphl->FirstVisible = 1;
1265 if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) {
1266 lphl->ItemFocused = Count;
1268 else {
1269 ListBoxSetCurSel(hwnd, Count);
1271 SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
1272 InvalidateRect(hwnd, NULL, TRUE);
1273 UpdateWindow(hwnd);
1274 return Count;
1277 lpls = (LPLISTSTRUCT)lpls->lpNext;
1278 Count++;
1280 Count = 0;
1281 lpls = lphl->lpFirst;
1282 while(lpls != NULL) {
1283 if (*((char *)lpls->dis.itemData) == (char)wChar) {
1284 if (Count == lphl->ItemFocused) return LB_ERR;
1285 lphl->FirstVisible = Count - lphl->ItemsVisible / 2;
1286 if (lphl->FirstVisible < 1) lphl->FirstVisible = 1;
1287 if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) {
1288 lphl->ItemFocused = Count;
1290 else {
1291 ListBoxSetCurSel(hwnd, Count);
1293 SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
1294 InvalidateRect(hwnd, NULL, TRUE);
1295 UpdateWindow(hwnd);
1296 return Count;
1298 lpls = (LPLISTSTRUCT)lpls->lpNext;
1299 Count++;
1301 return LB_ERR;
1305 /************************************************************************
1306 * DlgDirSelect [USER.99]
1308 BOOL DlgDirSelect(HWND hDlg, LPSTR lpStr, int nIDLBox)
1310 printf("DlgDirSelect(%04X, '%s', %d) \n", hDlg, lpStr, nIDLBox);
1314 /************************************************************************
1315 * DlgDirList [USER.100]
1317 int DlgDirList(HWND hDlg, LPSTR lpPathSpec,
1318 int nIDLBox, int nIDStat, WORD wType)
1320 HWND hWnd;
1321 printf("DlgDirList(%04X, '%s', %d, %d, %04X) \n",
1322 hDlg, lpPathSpec, nIDLBox, nIDStat, wType);
1323 hWnd = GetDlgItem(hDlg, nIDLBox);
1324 ListBoxResetContent(hWnd);
1325 return ListBoxDirectory(hWnd, wType, lpPathSpec);