Release 940405
[wine/gsoc-2012-control.git] / controls / listbox.c
bloba20eea90138621a848df110ca6de9edb8f6d5150
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 createStruct = (CREATESTRUCT *)lParam;
76 if (HIWORD(createStruct->lpCreateParams) != 0)
77 lphl->hWndLogicParent = (HWND)HIWORD(createStruct->lpCreateParams);
78 else
79 lphl->hWndLogicParent = GetParent(hwnd);
80 lphl->ColumnsWidth = wndPtr->rectClient.right - wndPtr->rectClient.left;
81 if (wndPtr->dwStyle & WS_VSCROLL) {
82 SetScrollRange(hwnd, SB_VERT, 1, lphl->ItemsCount, TRUE);
83 ShowScrollBar(hwnd, SB_VERT, FALSE);
85 if (wndPtr->dwStyle & WS_HSCROLL) {
86 SetScrollRange(hwnd, SB_HORZ, 1, 1, TRUE);
87 ShowScrollBar(hwnd, SB_HORZ, FALSE);
89 if ((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) == LBS_OWNERDRAWFIXED) {
91 return 0;
92 case WM_DESTROY:
93 lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
94 if (lphl == 0) return 0;
95 ListBoxResetContent(hwnd);
96 free(lphl);
97 *((LPHEADLIST *)&wndPtr->wExtra[1]) = 0;
98 #ifdef DEBUG_LISTBOX
99 printf("ListBox WM_DESTROY %lX !\n", lphl);
100 #endif
101 return 0;
103 case WM_VSCROLL:
104 #ifdef DEBUG_LISTBOX
105 printf("ListBox WM_VSCROLL w=%04X l=%08X !\n", wParam, lParam);
106 #endif
107 lphl = ListBoxGetStorageHeader(hwnd);
108 if (lphl == NULL) return 0;
109 y = lphl->FirstVisible;
110 switch(wParam) {
111 case SB_LINEUP:
112 if (lphl->FirstVisible > 1)
113 lphl->FirstVisible--;
114 break;
115 case SB_LINEDOWN:
116 if (lphl->FirstVisible < lphl->ItemsCount)
117 lphl->FirstVisible++;
118 break;
119 case SB_PAGEUP:
120 if (lphl->FirstVisible > 1)
121 lphl->FirstVisible -= lphl->ItemsVisible;
122 break;
123 case SB_PAGEDOWN:
124 if (lphl->FirstVisible < lphl->ItemsCount)
125 lphl->FirstVisible += lphl->ItemsVisible;
126 break;
127 case SB_THUMBTRACK:
128 lphl->FirstVisible = LOWORD(lParam);
129 break;
131 if (lphl->FirstVisible < 1) lphl->FirstVisible = 1;
132 if (lphl->FirstVisible > lphl->ItemsCount)
133 lphl->FirstVisible = lphl->ItemsCount;
134 if (y != lphl->FirstVisible) {
135 SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
136 InvalidateRect(hwnd, NULL, TRUE);
137 UpdateWindow(hwnd);
139 return 0;
141 case WM_HSCROLL:
142 #ifdef DEBUG_LISTBOX
143 printf("ListBox WM_HSCROLL w=%04X l=%08X !\n", wParam, lParam);
144 #endif
145 lphl = ListBoxGetStorageHeader(hwnd);
146 if (lphl == NULL) return 0;
147 y = lphl->FirstVisible;
148 switch(wParam) {
149 case SB_LINEUP:
150 if (lphl->FirstVisible > 1)
151 lphl->FirstVisible -= lphl->ItemsPerColumn;
152 break;
153 case SB_LINEDOWN:
154 if (lphl->FirstVisible < lphl->ItemsCount)
155 lphl->FirstVisible += lphl->ItemsPerColumn;
156 break;
157 case SB_PAGEUP:
158 if (lphl->FirstVisible > 1 && lphl->ItemsPerColumn != 0)
159 lphl->FirstVisible -= lphl->ItemsVisible /
160 lphl->ItemsPerColumn * lphl->ItemsPerColumn;
161 break;
162 case SB_PAGEDOWN:
163 if (lphl->FirstVisible < lphl->ItemsCount &&
164 lphl->ItemsPerColumn != 0)
165 lphl->FirstVisible += lphl->ItemsVisible /
166 lphl->ItemsPerColumn * lphl->ItemsPerColumn;
167 break;
168 case SB_THUMBTRACK:
169 lphl->FirstVisible = lphl->ItemsPerColumn *
170 (LOWORD(lParam) - 1) + 1;
171 break;
173 if (lphl->FirstVisible < 1) lphl->FirstVisible = 1;
174 if (lphl->FirstVisible > lphl->ItemsCount)
175 lphl->FirstVisible = lphl->ItemsCount;
176 if (lphl->ItemsPerColumn != 0) {
177 lphl->FirstVisible = lphl->FirstVisible /
178 lphl->ItemsPerColumn * lphl->ItemsPerColumn + 1;
179 if (y != lphl->FirstVisible) {
180 SetScrollPos(hwnd, SB_HORZ, lphl->FirstVisible /
181 lphl->ItemsPerColumn + 1, TRUE);
182 InvalidateRect(hwnd, NULL, TRUE);
183 UpdateWindow(hwnd);
186 return 0;
188 case WM_LBUTTONDOWN:
189 SetFocus(hwnd);
190 SetCapture(hwnd);
191 lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
192 if (lphl == NULL) return 0;
193 lphl->PrevFocused = lphl->ItemFocused;
194 y = ListBoxFindMouse(hwnd, LOWORD(lParam), HIWORD(lParam));
195 if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) {
196 lphl->ItemFocused = y;
197 wRet = ListBoxGetSel(hwnd, y);
198 ListBoxSetSel(hwnd, y, !wRet);
200 else {
201 ListBoxSetCurSel(hwnd, y);
203 ListBoxGetItemRect(hwnd, y, &rectsel);
204 InvalidateRect(hwnd, NULL, TRUE);
205 UpdateWindow(hwnd);
206 return 0;
207 case WM_LBUTTONUP:
208 ReleaseCapture();
209 lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
210 if (lphl == NULL) return 0;
211 if (lphl->PrevFocused != lphl->ItemFocused)
212 SendMessage(lphl->hWndLogicParent, WM_COMMAND, wndPtr->wIDmenu,
213 MAKELONG(hwnd, LBN_SELCHANGE));
214 return 0;
215 case WM_RBUTTONUP:
216 case WM_LBUTTONDBLCLK:
217 lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
218 if (lphl == NULL) return 0;
219 SendMessage(lphl->hWndLogicParent, WM_COMMAND, wndPtr->wIDmenu,
220 MAKELONG(hwnd, LBN_DBLCLK));
221 printf("ListBox Send LBN_DBLCLK !\n");
222 return 0;
223 case WM_MOUSEMOVE:
224 if ((wParam & MK_LBUTTON) != 0) {
225 y = HIWORD(lParam);
226 if (y < 4) {
227 lphl = ListBoxGetStorageHeader(hwnd);
228 if (lphl->FirstVisible > 1) {
229 lphl->FirstVisible--;
230 if (wndPtr->dwStyle & WS_VSCROLL)
231 SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
232 InvalidateRect(hwnd, NULL, TRUE);
233 UpdateWindow(hwnd);
234 break;
237 GetClientRect(hwnd, &rect);
238 if (y > (rect.bottom - 4)) {
239 lphl = ListBoxGetStorageHeader(hwnd);
240 if (lphl->FirstVisible < lphl->ItemsCount) {
241 lphl->FirstVisible++;
242 if (wndPtr->dwStyle & WS_VSCROLL)
243 SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
244 InvalidateRect(hwnd, NULL, TRUE);
245 UpdateWindow(hwnd);
246 break;
249 if ((y > 0) && (y < (rect.bottom - 4))) {
250 if ((y < rectsel.top) || (y > rectsel.bottom)) {
251 wRet = ListBoxFindMouse(hwnd, LOWORD(lParam), HIWORD(lParam));
252 if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) {
253 lphl->ItemFocused = wRet;
255 else {
256 ListBoxSetCurSel(hwnd, wRet);
258 ListBoxGetItemRect(hwnd, wRet, &rectsel);
259 InvalidateRect(hwnd, NULL, TRUE);
260 UpdateWindow(hwnd);
264 break;
265 case WM_KEYDOWN:
266 lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
267 if (lphl == NULL) return 0;
268 switch(wParam) {
269 case VK_TAB:
270 hWndCtl = GetNextDlgTabItem(lphl->hWndLogicParent,
271 hwnd, !(GetKeyState(VK_SHIFT) < 0));
272 SetFocus(hWndCtl);
273 if ((GetKeyState(VK_SHIFT) < 0))
274 printf("ListBox PreviousDlgTabItem %04X !\n", hWndCtl);
275 else
276 printf("ListBox NextDlgTabItem %04X !\n", hWndCtl);
277 break;
278 case VK_HOME:
279 lphl->ItemFocused = 0;
280 break;
281 case VK_END:
282 lphl->ItemFocused = lphl->ItemsCount - 1;
283 break;
284 case VK_LEFT:
285 if ((wndPtr->dwStyle & LBS_MULTICOLUMN) == LBS_MULTICOLUMN) {
286 lphl->ItemFocused -= lphl->ItemsPerColumn;
288 break;
289 case VK_UP:
290 lphl->ItemFocused--;
291 break;
292 case VK_RIGHT:
293 if ((wndPtr->dwStyle & LBS_MULTICOLUMN) == LBS_MULTICOLUMN) {
294 lphl->ItemFocused += lphl->ItemsPerColumn;
296 break;
297 case VK_DOWN:
298 lphl->ItemFocused++;
299 break;
300 case VK_PRIOR:
301 lphl->ItemFocused -= lphl->ItemsVisible;
302 break;
303 case VK_NEXT:
304 lphl->ItemFocused += lphl->ItemsVisible;
305 break;
306 case VK_SPACE:
307 wRet = ListBoxGetSel(hwnd, lphl->ItemFocused);
308 ListBoxSetSel(hwnd, lphl->ItemFocused, !wRet);
309 break;
310 default:
311 ListBoxFindNextMatch(hwnd, wParam);
312 return 0;
314 if (lphl->ItemFocused < 0) lphl->ItemFocused = 0;
315 if (lphl->ItemFocused >= lphl->ItemsCount)
316 lphl->ItemFocused = lphl->ItemsCount - 1;
317 lphl->FirstVisible = lphl->ItemFocused / lphl->ItemsVisible *
318 lphl->ItemsVisible + 1;
319 if (lphl->FirstVisible < 1) lphl->FirstVisible = 1;
320 if ((wndPtr->dwStyle & LBS_MULTIPLESEL) != LBS_MULTIPLESEL) {
321 ListBoxSetCurSel(hwnd, lphl->ItemFocused);
323 if (wndPtr->dwStyle & WS_VSCROLL)
324 SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
325 InvalidateRect(hwnd, NULL, TRUE);
326 UpdateWindow(hwnd);
327 break;
328 case WM_PAINT:
329 wndPtr = WIN_FindWndPtr(hwnd);
330 if ((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) == LBS_OWNERDRAWFIXED) {
331 OwnerDrawListBox(hwnd);
332 break;
334 if ((wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE) == LBS_OWNERDRAWVARIABLE) {
335 OwnerDrawListBox(hwnd);
336 break;
338 StdDrawListBox(hwnd);
339 break;
340 case WM_SETFOCUS:
341 #ifdef DEBUG_LISTBOX
342 printf("ListBox WM_SETFOCUS !\n");
343 #endif
344 lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
345 break;
346 case WM_KILLFOCUS:
347 #ifdef DEBUG_LISTBOX
348 printf("ListBox WM_KILLFOCUS !\n");
349 #endif
350 InvalidateRect(hwnd, NULL, TRUE);
351 UpdateWindow(hwnd);
352 break;
354 case LB_RESETCONTENT:
355 #ifdef DEBUG_LISTBOX
356 printf("ListBox LB_RESETCONTENT !\n");
357 #endif
358 ListBoxResetContent(hwnd);
359 return 0;
360 case LB_DIR:
361 #ifdef DEBUG_LISTBOX
362 printf("ListBox LB_DIR !\n");
363 #endif
364 wRet = ListBoxDirectory(hwnd, wParam, (LPSTR)lParam);
365 InvalidateRect(hwnd, NULL, TRUE);
366 UpdateWindow(hwnd);
367 return wRet;
368 case LB_ADDSTRING:
369 wRet = ListBoxAddString(hwnd, (LPSTR)lParam);
370 return wRet;
371 case LB_GETTEXT:
372 wRet = ListBoxGetText(hwnd, wParam, (LPSTR)lParam);
373 #ifdef DEBUG_LISTBOX
374 printf("ListBox LB_GETTEXT #%u '%s' !\n", wParam, (LPSTR)lParam);
375 #endif
376 return wRet;
377 case LB_INSERTSTRING:
378 wRet = ListBoxInsertString(hwnd, wParam, (LPSTR)lParam);
379 return wRet;
380 case LB_DELETESTRING:
381 printf("ListBox LB_DELETESTRING #%u !\n", wParam);
382 wRet = ListBoxDeleteString(hwnd, wParam);
383 return wRet;
384 case LB_FINDSTRING:
385 wRet = ListBoxFindString(hwnd, wParam, (LPSTR)lParam);
386 return wRet;
387 case LB_GETCARETINDEX:
388 return wRet;
389 case LB_GETCOUNT:
390 lphl = ListBoxGetStorageHeader(hwnd);
391 return lphl->ItemsCount;
392 case LB_GETCURSEL:
393 lphl = ListBoxGetStorageHeader(hwnd);
394 #ifdef DEBUG_LISTBOX
395 printf("ListBox LB_GETCURSEL %u !\n", lphl->ItemFocused);
396 #endif
397 return lphl->ItemFocused;
398 case LB_GETHORIZONTALEXTENT:
399 return wRet;
400 case LB_GETITEMDATA:
401 return wRet;
402 case LB_GETITEMHEIGHT:
403 return wRet;
404 case LB_GETITEMRECT:
405 return wRet;
406 case LB_GETSEL:
407 wRet = ListBoxGetSel(hwnd, wParam);
408 return wRet;
409 case LB_GETSELCOUNT:
410 return wRet;
411 case LB_GETSELITEMS:
412 return wRet;
413 case LB_GETTEXTLEN:
414 return wRet;
415 case LB_GETTOPINDEX:
416 return wRet;
417 case LB_SELECTSTRING:
418 return wRet;
419 case LB_SELITEMRANGE:
420 return wRet;
421 case LB_SETCARETINDEX:
422 return wRet;
423 case LB_SETCOLUMNWIDTH:
424 lphl = ListBoxGetStorageHeader(hwnd);
425 lphl->ColumnsWidth = wParam;
426 break;
427 case LB_SETHORIZONTALEXTENT:
428 return wRet;
429 case LB_SETITEMDATA:
430 return wRet;
431 case LB_SETTABSTOPS:
432 return wRet;
433 case LB_SETCURSEL:
434 #ifdef DEBUG_LISTBOX
435 printf("ListBox LB_SETCURSEL wParam=%x !\n", wParam);
436 #endif
437 wRet = ListBoxSetCurSel(hwnd, wParam);
438 InvalidateRect(hwnd, NULL, TRUE);
439 UpdateWindow(hwnd);
440 return wRet;
441 case LB_SETSEL:
442 printf("ListBox LB_SETSEL wParam=%x lParam=%lX !\n", wParam, lParam);
443 wRet = ListBoxSetSel(hwnd, LOWORD(lParam), wParam);
444 InvalidateRect(hwnd, NULL, TRUE);
445 UpdateWindow(hwnd);
446 return wRet;
447 case LB_SETTOPINDEX:
448 printf("ListBox LB_SETTOPINDEX wParam=%x !\n", wParam);
449 lphl = ListBoxGetStorageHeader(hwnd);
450 lphl->FirstVisible = wParam;
451 if (wndPtr->dwStyle & WS_VSCROLL)
452 SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
453 InvalidateRect(hwnd, NULL, TRUE);
454 UpdateWindow(hwnd);
455 break;
456 case LB_SETITEMHEIGHT:
457 #ifdef DEBUG_LISTBOX
458 printf("ListBox LB_SETITEMHEIGHT wParam=%x lParam=%lX !\n", wParam, lParam);
459 #endif
460 wRet = ListBoxSetItemHeight(hwnd, wParam, lParam);
461 return wRet;
463 default:
464 return DefWindowProc( hwnd, message, wParam, lParam );
466 return 0;
470 LPHEADLIST ListBoxGetWindowAndStorage(HWND hwnd, WND **wndPtr)
472 WND *Ptr;
473 LPHEADLIST lphl;
474 *(wndPtr) = Ptr = WIN_FindWndPtr(hwnd);
475 lphl = *((LPHEADLIST *)&Ptr->wExtra[1]);
476 return lphl;
480 LPHEADLIST ListBoxGetStorageHeader(HWND hwnd)
482 WND *wndPtr;
483 LPHEADLIST lphl;
484 wndPtr = WIN_FindWndPtr(hwnd);
485 lphl = *((LPHEADLIST *)&wndPtr->wExtra[1]);
486 return lphl;
490 void StdDrawListBox(HWND hwnd)
492 WND *wndPtr;
493 LPHEADLIST lphl;
494 LPLISTSTRUCT lpls;
495 PAINTSTRUCT ps;
496 HBRUSH hBrush;
497 int OldBkMode;
498 DWORD dwOldTextColor;
499 HWND hWndParent;
500 HDC hdc;
501 RECT rect;
502 UINT i, h, h2, maxwidth, ipc;
503 char C[128];
504 h = 0;
505 hdc = BeginPaint( hwnd, &ps );
506 if (!IsWindowVisible(hwnd)) {
507 EndPaint( hwnd, &ps );
508 return;
510 lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
511 if (lphl == NULL) goto EndOfPaint;
512 hBrush = SendMessage(lphl->hWndLogicParent, WM_CTLCOLOR, (WORD)hdc,
513 MAKELONG(hwnd, CTLCOLOR_LISTBOX));
514 if (hBrush == (HBRUSH)NULL) hBrush = GetStockObject(WHITE_BRUSH);
515 GetClientRect(hwnd, &rect);
517 if (wndPtr->dwStyle & WS_VSCROLL) rect.right -= 16;
518 if (wndPtr->dwStyle & WS_HSCROLL) rect.bottom -= 16;
520 FillRect(hdc, &rect, hBrush);
521 maxwidth = rect.right;
522 rect.right = lphl->ColumnsWidth;
523 if (lphl->ItemsCount == 0) goto EndOfPaint;
524 lpls = lphl->lpFirst;
525 if (lpls == NULL) goto EndOfPaint;
526 lphl->ItemsVisible = 0;
527 lphl->ItemsPerColumn = ipc = 0;
528 for(i = 1; i <= lphl->ItemsCount; i++) {
529 if (i >= lphl->FirstVisible) {
530 if (lpls == NULL) break;
531 if ((h + lpls->dis.rcItem.bottom - lpls->dis.rcItem.top) > rect.bottom) {
532 if ((wndPtr->dwStyle & LBS_MULTICOLUMN) == LBS_MULTICOLUMN) {
533 lphl->ItemsPerColumn = max(lphl->ItemsPerColumn, ipc);
534 ipc = 0;
535 h = 0;
536 rect.left += lphl->ColumnsWidth;
537 rect.right += lphl->ColumnsWidth;
538 if (rect.left > maxwidth) break;
540 else
541 break;
543 h2 = lpls->dis.rcItem.bottom - lpls->dis.rcItem.top;
544 lpls->dis.rcItem.top = h;
545 lpls->dis.rcItem.bottom = h + h2;
546 lpls->dis.rcItem.left = rect.left;
547 lpls->dis.rcItem.right = rect.right;
548 OldBkMode = SetBkMode(hdc, TRANSPARENT);
549 if (lpls->dis.itemState != 0) {
550 dwOldTextColor = SetTextColor(hdc, 0x00FFFFFFL);
551 FillRect(hdc, &lpls->dis.rcItem, GetStockObject(BLACK_BRUSH));
553 TextOut(hdc, rect.left + 5, h + 2, (char *)lpls->dis.itemData,
554 strlen((char *)lpls->dis.itemData));
555 if (lpls->dis.itemState != 0) {
556 SetTextColor(hdc, dwOldTextColor);
558 SetBkMode(hdc, OldBkMode);
559 if ((lphl->ItemFocused == i - 1) && GetFocus() == hwnd) {
560 DrawFocusRect(hdc, &lpls->dis.rcItem);
562 h += h2;
563 lphl->ItemsVisible++;
564 ipc++;
566 if (lpls->lpNext == NULL) goto EndOfPaint;
567 lpls = (LPLISTSTRUCT)lpls->lpNext;
569 EndOfPaint:
570 EndPaint( hwnd, &ps );
571 if ((lphl->ItemsCount > lphl->ItemsVisible) &
572 (wndPtr->dwStyle & WS_VSCROLL)) {
574 InvalidateRect(wndPtr->hWndVScroll, NULL, TRUE);
575 UpdateWindow(wndPtr->hWndVScroll);
582 void OwnerDrawListBox(HWND hwnd)
584 WND *wndPtr;
585 LPHEADLIST lphl;
586 LPLISTSTRUCT lpls;
587 PAINTSTRUCT ps;
588 HBRUSH hBrush;
589 HWND hWndParent;
590 HDC hdc;
591 RECT rect;
592 UINT i, h, h2, maxwidth;
593 char C[128];
594 h = 0;
595 hdc = BeginPaint(hwnd, &ps);
596 if (!IsWindowVisible(hwnd)) {
597 EndPaint( hwnd, &ps );
598 return;
600 lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
601 if (lphl == NULL) goto EndOfPaint;
602 hBrush = SendMessage(lphl->hWndLogicParent, WM_CTLCOLOR, (WORD)hdc,
603 MAKELONG(hwnd, CTLCOLOR_LISTBOX));
604 if (hBrush == (HBRUSH)NULL) hBrush = GetStockObject(WHITE_BRUSH);
605 GetClientRect(hwnd, &rect);
606 if (wndPtr->dwStyle & WS_VSCROLL) rect.right -= 16;
607 if (wndPtr->dwStyle & WS_HSCROLL) rect.bottom -= 16;
608 FillRect(hdc, &rect, hBrush);
609 maxwidth = rect.right;
610 rect.right = lphl->ColumnsWidth;
611 if (lphl->ItemsCount == 0) goto EndOfPaint;
612 lpls = lphl->lpFirst;
613 if (lpls == NULL) goto EndOfPaint;
614 lphl->ItemsVisible = 0;
615 for (i = 1; i <= lphl->ItemsCount; i++) {
616 if (i >= lphl->FirstVisible) {
617 lpls->dis.hDC = hdc;
618 lpls->dis.itemID = i - 1;
619 h2 = lpls->dis.rcItem.bottom - lpls->dis.rcItem.top;
620 lpls->dis.rcItem.top = h;
621 lpls->dis.rcItem.bottom = h + h2;
622 lpls->dis.rcItem.left = rect.left;
623 lpls->dis.rcItem.right = rect.right;
624 lpls->dis.itemAction = ODA_DRAWENTIRE;
625 if (lpls->dis.itemState != 0) {
626 lpls->dis.itemAction |= ODA_SELECT;
628 if (lphl->ItemFocused == i - 1) {
629 lpls->dis.itemAction |= ODA_FOCUS;
631 #ifdef DEBUT_LISTBOX
632 printf("LBOX WM_DRAWITEM #%d left=%d top=%d right=%d bottom=%d !\n",
633 i, lpls->dis.rcItem.left, lpls->dis.rcItem.top,
634 lpls->dis.rcItem.right, lpls->dis.rcItem.bottom);
635 printf("LBOX WM_DRAWITEM Parent=%X &dis=%lX CtlID=%u !\n",
636 hWndParent, (LONG)&lpls->dis, lpls->dis.CtlID);
637 printf("LBOX WM_DRAWITEM '%s' !\n", lpls->dis.itemData);
638 #endif
639 SendMessage(lphl->hWndLogicParent, WM_DRAWITEM, i, (LPARAM)&lpls->dis);
640 if (lpls->dis.itemState != 0) {
641 InvertRect(hdc, &lpls->dis.rcItem);
643 h += h2;
644 lphl->ItemsVisible++;
645 if (h > rect.bottom) goto EndOfPaint;
647 if (lpls->lpNext == NULL) goto EndOfPaint;
648 lpls = (LPLISTSTRUCT)lpls->lpNext;
650 EndOfPaint:
651 EndPaint( hwnd, &ps );
652 if ((lphl->ItemsCount > lphl->ItemsVisible) &
653 (wndPtr->dwStyle & WS_VSCROLL)) {
655 InvalidateRect(wndPtr->hWndVScroll, NULL, TRUE);
656 UpdateWindow(wndPtr->hWndVScroll);
663 int ListBoxFindMouse(HWND hwnd, int X, int Y)
665 WND *wndPtr;
666 LPHEADLIST lphl;
667 LPLISTSTRUCT lpls;
668 RECT rect;
669 UINT i, h, h2, w, w2;
670 char C[128];
671 lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
672 if (lphl == NULL) return LB_ERR;
673 if (lphl->ItemsCount == 0) return LB_ERR;
674 lpls = lphl->lpFirst;
675 if (lpls == NULL) return LB_ERR;
676 GetClientRect(hwnd, &rect);
677 if (wndPtr->dwStyle & WS_VSCROLL) rect.right -= 16;
678 if (wndPtr->dwStyle & WS_HSCROLL) rect.bottom -= 16;
679 h = w2 = 0;
680 w = lphl->ColumnsWidth;
681 for(i = 1; i <= lphl->ItemsCount; i++) {
682 if (i >= lphl->FirstVisible) {
683 h2 = h;
684 h += lpls->dis.rcItem.bottom - lpls->dis.rcItem.top;
685 if ((Y > h2) && (Y < h) &&
686 (X > w2) && (X < w)) return(i - 1);
687 if (h > rect.bottom) {
688 if ((wndPtr->dwStyle & LBS_MULTICOLUMN) != LBS_MULTICOLUMN) return LB_ERR;
689 h = 0;
690 w2 = w;
691 w += lphl->ColumnsWidth;
692 if (w2 > rect.right) return LB_ERR;
695 if (lpls->lpNext == NULL) return LB_ERR;
696 lpls = (LPLISTSTRUCT)lpls->lpNext;
698 return(LB_ERR);
703 int CreateListBoxStruct(HWND hwnd)
705 WND *wndPtr;
706 LPHEADLIST lphl;
707 wndPtr = WIN_FindWndPtr(hwnd);
708 lphl = (LPHEADLIST)malloc(sizeof(HEADLIST));
709 lphl->lpFirst = NULL;
710 *((LPHEADLIST *)&wndPtr->wExtra[1]) = lphl; /* HEAD of List */
711 lphl->ItemsCount = 0;
712 lphl->ItemsVisible = 0;
713 lphl->FirstVisible = 1;
714 lphl->StdItemHeight = 15;
715 lphl->DrawCtlType = ODT_LISTBOX;
716 return TRUE;
720 void ListBoxAskMeasure(WND *wndPtr, LPHEADLIST lphl, LPLISTSTRUCT lpls)
722 MEASUREITEMSTRUCT *measure;
723 HANDLE hTemp = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(MEASUREITEMSTRUCT));
724 measure = (MEASUREITEMSTRUCT *) USER_HEAP_ADDR(hTemp);
725 if (measure == NULL) return;
726 measure->CtlType = ODT_LISTBOX;
727 measure->CtlID = wndPtr->wIDmenu;
728 measure->itemID = lpls->dis.itemID;
729 measure->itemWidth = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
730 measure->itemHeight = 0;
731 measure->itemData = lpls->dis.itemData;
732 SendMessage(lphl->hWndLogicParent, WM_MEASUREITEM, 0, (DWORD)measure);
733 lpls->dis.rcItem.right = lpls->dis.rcItem.left + measure->itemWidth;
734 lpls->dis.rcItem.bottom = lpls->dis.rcItem.top + measure->itemHeight;
735 USER_HEAP_FREE(hTemp);
739 int ListBoxAddString(HWND hwnd, LPSTR newstr)
741 WND *wndPtr;
742 LPHEADLIST lphl;
743 LPLISTSTRUCT lpls, lplsnew;
744 HANDLE hTemp;
745 LPSTR str;
746 lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
747 if (lphl == NULL) return LB_ERR;
748 hTemp = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(LISTSTRUCT));
749 lplsnew = (LPLISTSTRUCT) USER_HEAP_ADDR(hTemp);
750 lpls = lphl->lpFirst;
751 if (lpls != NULL) {
752 while(lpls->lpNext != NULL) {
753 lpls = (LPLISTSTRUCT)lpls->lpNext;
755 lpls->lpNext = lplsnew;
757 else
758 lphl->lpFirst = lplsnew;
759 lphl->ItemsCount++;
760 #ifdef DEBUG_LISTBOX
761 printf("Items Count = %u\n", lphl->ItemsCount);
762 #endif
763 hTemp = 0;
764 if ((wndPtr->dwStyle & LBS_HASSTRINGS) != LBS_HASSTRINGS) {
765 if (((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) != LBS_OWNERDRAWFIXED) &&
766 ((wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE) != LBS_OWNERDRAWVARIABLE)) {
767 hTemp = USER_HEAP_ALLOC(GMEM_MOVEABLE, strlen(newstr) + 1);
768 str = (LPSTR)USER_HEAP_ADDR(hTemp);
769 if (str == NULL) return LB_ERRSPACE;
770 strcpy(str, newstr);
771 newstr = str;
772 #ifdef DEBUG_LISTBOX
773 printf("ListBoxAddString// after strcpy '%s'\n", str);
774 #endif
777 ListBoxDefaultItem(hwnd, wndPtr, lphl, lplsnew);
778 lplsnew->hMem = hTemp;
779 lplsnew->lpNext = NULL;
780 lplsnew->dis.itemID = lphl->ItemsCount;
781 lplsnew->dis.itemData = (DWORD)newstr;
782 lplsnew->hData = hTemp;
783 if ((wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE) == LBS_OWNERDRAWVARIABLE)
784 ListBoxAskMeasure(wndPtr, lphl, lplsnew);
785 if (wndPtr->dwStyle & WS_VSCROLL)
786 SetScrollRange(hwnd, SB_VERT, 1, lphl->ItemsCount,
787 (lphl->FirstVisible != 1));
788 if ((wndPtr->dwStyle & WS_HSCROLL) && lphl->ItemsPerColumn != 0)
789 SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible /
790 lphl->ItemsPerColumn + 1, (lphl->FirstVisible != 1));
791 if (lphl->FirstVisible >= (lphl->ItemsCount - lphl->ItemsVisible)) {
792 InvalidateRect(hwnd, NULL, TRUE);
793 UpdateWindow(hwnd);
795 if ((lphl->ItemsCount - lphl->FirstVisible) == lphl->ItemsVisible) {
796 if (wndPtr->dwStyle & WS_VSCROLL)
797 ShowScrollBar(hwnd, SB_VERT, TRUE);
798 if (wndPtr->dwStyle & WS_HSCROLL)
799 ShowScrollBar(hwnd, SB_HORZ, TRUE);
801 return lphl->ItemsCount;
805 int ListBoxInsertString(HWND hwnd, UINT uIndex, LPSTR newstr)
807 WND *wndPtr;
808 LPHEADLIST lphl;
809 LPLISTSTRUCT lpls, lplsnew;
810 HANDLE hTemp;
811 LPSTR str;
812 UINT Count;
813 lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
814 if (lphl == NULL) return LB_ERR;
815 if (uIndex >= lphl->ItemsCount) return LB_ERR;
816 lpls = lphl->lpFirst;
817 if (lpls == NULL) return LB_ERR;
818 if (uIndex > lphl->ItemsCount) return LB_ERR;
819 for(Count = 1; Count < uIndex; Count++) {
820 if (lpls->lpNext == NULL) return LB_ERR;
821 lpls = (LPLISTSTRUCT)lpls->lpNext;
823 hTemp = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(LISTSTRUCT));
824 lplsnew = (LPLISTSTRUCT) USER_HEAP_ADDR(hTemp);
825 ListBoxDefaultItem(hwnd, wndPtr, lphl, lplsnew);
826 lplsnew->hMem = hTemp;
827 lpls->lpNext = lplsnew;
828 lphl->ItemsCount++;
829 hTemp = 0;
830 if ((wndPtr->dwStyle & LBS_HASSTRINGS) != LBS_HASSTRINGS) {
831 if (((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) != LBS_OWNERDRAWFIXED) &&
832 ((wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE) != LBS_OWNERDRAWVARIABLE)) {
833 hTemp = USER_HEAP_ALLOC(GMEM_MOVEABLE, strlen(newstr) + 1);
834 str = (LPSTR)USER_HEAP_ADDR(hTemp);
835 if (str == NULL) return LB_ERRSPACE;
836 strcpy(str, newstr);
837 newstr = str;
840 lplsnew->lpNext = NULL;
841 lplsnew->dis.itemID = lphl->ItemsCount;
842 lplsnew->dis.itemData = (DWORD)newstr;
843 lplsnew->hData = hTemp;
844 if ((wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE) == LBS_OWNERDRAWVARIABLE)
845 ListBoxAskMeasure(wndPtr, lphl, lplsnew);
846 if (wndPtr->dwStyle & WS_VSCROLL)
847 SetScrollRange(hwnd, SB_VERT, 1, lphl->ItemsCount,
848 (lphl->FirstVisible != 1));
849 if ((wndPtr->dwStyle & WS_HSCROLL) && lphl->ItemsPerColumn != 0)
850 SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible /
851 lphl->ItemsPerColumn + 1, (lphl->FirstVisible != 1));
852 if (((lphl->ItemsCount - lphl->FirstVisible) == lphl->ItemsVisible) &&
853 (lphl->ItemsVisible != 0)) {
854 if (wndPtr->dwStyle & WS_VSCROLL) ShowScrollBar(hwnd, SB_VERT, TRUE);
855 if (wndPtr->dwStyle & WS_HSCROLL) ShowScrollBar(hwnd, SB_HORZ, TRUE);
857 if ((lphl->FirstVisible <= uIndex) &&
858 ((lphl->FirstVisible + lphl->ItemsVisible) >= uIndex)) {
859 InvalidateRect(hwnd, NULL, TRUE);
860 UpdateWindow(hwnd);
862 return lphl->ItemsCount;
866 int ListBoxGetText(HWND hwnd, UINT uIndex, LPSTR OutStr)
868 WND *wndPtr;
869 LPHEADLIST lphl;
870 LPLISTSTRUCT lpls;
871 UINT Count;
872 lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
873 if (lphl == NULL) return LB_ERR;
874 if (uIndex >= lphl->ItemsCount) return LB_ERR;
875 lpls = lphl->lpFirst;
876 if (lpls == NULL) return LB_ERR;
877 if (uIndex > lphl->ItemsCount) return LB_ERR;
878 for(Count = 0; Count < uIndex; Count++) {
879 if (lpls->lpNext == NULL) return LB_ERR;
880 lpls = (LPLISTSTRUCT)lpls->lpNext;
882 if (((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) == LBS_OWNERDRAWFIXED) ||
883 ((wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE) == LBS_OWNERDRAWVARIABLE)) {
884 if ((wndPtr->dwStyle & LBS_HASSTRINGS) != LBS_HASSTRINGS) {
885 *((long *)OutStr) = lpls->dis.itemData;
886 return 4;
890 strcpy(OutStr, (char *)lpls->dis.itemData);
891 return strlen(OutStr);
895 int ListBoxDeleteString(HWND hwnd, UINT uIndex)
897 WND *wndPtr;
898 LPHEADLIST lphl;
899 LPLISTSTRUCT lpls, lpls2;
900 UINT Count;
901 lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
902 if (lphl == NULL) return LB_ERR;
903 if (uIndex >= lphl->ItemsCount) return LB_ERR;
904 lpls = lphl->lpFirst;
905 if (lpls == NULL) return LB_ERR;
906 if (uIndex > lphl->ItemsCount) return LB_ERR;
907 for(Count = 1; Count < uIndex; Count++) {
908 if (lpls->lpNext == NULL) return LB_ERR;
909 lpls2 = lpls;
910 lpls = (LPLISTSTRUCT)lpls->lpNext;
912 lpls2->lpNext = (LPLISTSTRUCT)lpls->lpNext;
913 lphl->ItemsCount--;
914 if (lpls->hData != 0) USER_HEAP_FREE(lpls->hData);
915 if (lpls->hMem != 0) USER_HEAP_FREE(lpls->hMem);
916 if (wndPtr->dwStyle & WS_VSCROLL)
917 SetScrollRange(hwnd, SB_VERT, 1, lphl->ItemsCount, TRUE);
918 if ((wndPtr->dwStyle & WS_HSCROLL) && lphl->ItemsPerColumn != 0)
919 SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible /
920 lphl->ItemsPerColumn + 1, TRUE);
921 if (lphl->ItemsCount < lphl->ItemsVisible) {
922 if (wndPtr->dwStyle & WS_VSCROLL)
923 ShowScrollBar(hwnd, SB_VERT, FALSE);
924 if (wndPtr->dwStyle & WS_HSCROLL)
925 ShowScrollBar(hwnd, SB_HORZ, FALSE);
927 if ((lphl->FirstVisible <= uIndex) &&
928 ((lphl->FirstVisible + lphl->ItemsVisible) >= uIndex)) {
929 InvalidateRect(hwnd, NULL, TRUE);
930 UpdateWindow(hwnd);
932 return lphl->ItemsCount;
936 int ListBoxFindString(HWND hwnd, UINT nFirst, LPSTR MatchStr)
938 LPHEADLIST lphl;
939 LPLISTSTRUCT lpls;
940 UINT Count;
941 lphl = ListBoxGetStorageHeader(hwnd);
942 if (lphl == NULL) return LB_ERR;
943 if (nFirst > lphl->ItemsCount) return LB_ERR;
944 lpls = lphl->lpFirst;
945 if (lpls == NULL) return LB_ERR;
946 Count = 0;
947 while(lpls != NULL) {
948 if (strcmp((char *)lpls->dis.itemData, MatchStr) == 0) return Count;
949 lpls = (LPLISTSTRUCT)lpls->lpNext;
950 Count++;
952 return LB_ERR;
956 int ListBoxResetContent(HWND hwnd)
958 WND *wndPtr;
959 LPHEADLIST lphl;
960 LPLISTSTRUCT lpls, lpls2;
961 UINT i;
962 lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
963 if (lphl == NULL) return LB_ERR;
964 lpls = lphl->lpFirst;
965 if (lpls == NULL) return LB_ERR;
966 for(i = 0; i <= lphl->ItemsCount; i++) {
967 lpls2 = lpls;
968 lpls = (LPLISTSTRUCT)lpls->lpNext;
969 if (i != 0) {
970 #ifdef DEBUG_LISTBOX
971 printf("ResetContent #%u\n", i);
972 #endif
973 if (lpls2->hData != 0) USER_HEAP_FREE(lpls->hData);
974 if (lpls2->hMem != 0) USER_HEAP_FREE(lpls->hMem);
976 if (lpls == NULL) break;
978 lphl->lpFirst = NULL;
979 lphl->FirstVisible = 1;
980 lphl->ItemsCount = 0;
981 lphl->ItemFocused = 0;
982 lphl->PrevFocused = 0;
983 if ((wndPtr->dwStyle && LBS_NOTIFY) != 0)
984 SendMessage(wndPtr->hwndParent, WM_COMMAND,
985 wndPtr->wIDmenu, MAKELONG(hwnd, LBN_SELCHANGE));
987 if (wndPtr->dwStyle & WS_VSCROLL)
988 SetScrollRange(hwnd, SB_VERT, 1, lphl->ItemsCount, TRUE);
989 if ((wndPtr->dwStyle & WS_HSCROLL) && lphl->ItemsPerColumn != 0)
990 SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible /
991 lphl->ItemsPerColumn + 1, TRUE);
992 if (wndPtr->dwStyle & WS_VSCROLL)
993 ShowScrollBar(hwnd, SB_VERT, FALSE);
994 if (wndPtr->dwStyle & WS_HSCROLL)
995 ShowScrollBar(hwnd, SB_HORZ, FALSE);
996 InvalidateRect(hwnd, NULL, TRUE);
997 UpdateWindow(hwnd);
998 return TRUE;
1002 int ListBoxSetCurSel(HWND hwnd, WORD wIndex)
1004 WND *wndPtr;
1005 LPHEADLIST lphl;
1006 LPLISTSTRUCT lpls, lpls2;
1007 UINT i;
1008 lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
1009 if (lphl == NULL) return LB_ERR;
1010 lphl->ItemFocused = LB_ERR;
1011 if (wIndex >= lphl->ItemsCount) return LB_ERR;
1012 lpls = lphl->lpFirst;
1013 if (lpls == NULL) return LB_ERR;
1014 for(i = 0; i < lphl->ItemsCount; i++) {
1015 lpls2 = lpls;
1016 lpls = (LPLISTSTRUCT)lpls->lpNext;
1017 if (i == wIndex)
1018 lpls2->dis.itemState = 1;
1019 else
1020 if (lpls2->dis.itemState != 0)
1021 lpls2->dis.itemState = 0;
1022 if (lpls == NULL) break;
1024 lphl->ItemFocused = wIndex;
1025 if ((wndPtr->dwStyle && LBS_NOTIFY) != 0)
1026 SendMessage(wndPtr->hwndParent, WM_COMMAND,
1027 wndPtr->wIDmenu, MAKELONG(hwnd, LBN_SELCHANGE));
1028 return LB_ERR;
1033 int ListBoxSetSel(HWND hwnd, WORD wIndex, WORD state)
1035 LPHEADLIST lphl;
1036 LPLISTSTRUCT lpls, lpls2;
1037 UINT i;
1038 lphl = ListBoxGetStorageHeader(hwnd);
1039 if (lphl == NULL) return LB_ERR;
1040 if (wIndex >= lphl->ItemsCount) return LB_ERR;
1041 lpls = lphl->lpFirst;
1042 if (lpls == NULL) return LB_ERR;
1043 for(i = 0; i < lphl->ItemsCount; i++) {
1044 lpls2 = lpls;
1045 lpls = (LPLISTSTRUCT)lpls->lpNext;
1046 if ((i == wIndex) || (wIndex == (WORD)-1)) {
1047 lpls2->dis.itemState = state;
1048 break;
1050 if (lpls == NULL) break;
1052 return LB_ERR;
1056 int ListBoxGetSel(HWND hwnd, WORD wIndex)
1058 LPHEADLIST lphl;
1059 LPLISTSTRUCT lpls, lpls2;
1060 UINT i;
1061 lphl = ListBoxGetStorageHeader(hwnd);
1062 if (lphl == NULL) return LB_ERR;
1063 if (wIndex >= lphl->ItemsCount) return LB_ERR;
1064 lpls = lphl->lpFirst;
1065 if (lpls == NULL) return LB_ERR;
1066 for(i = 0; i < lphl->ItemsCount; i++) {
1067 lpls2 = lpls;
1068 lpls = (LPLISTSTRUCT)lpls->lpNext;
1069 if (i == wIndex) {
1070 return lpls2->dis.itemState;
1072 if (lpls == NULL) break;
1074 return LB_ERR;
1078 int ListBoxDirectory(HWND hwnd, UINT attrib, LPSTR filespec)
1080 struct dosdirent *dp;
1081 struct stat st;
1082 int x, wRet;
1083 char temp[256];
1084 #ifdef DEBUG_LISTBOX
1085 fprintf(stderr,"ListBoxDirectory: %s, %4x\n",filespec,attrib);
1086 #endif
1087 if ((dp = (struct dosdirent *)DOS_opendir(filespec)) ==NULL) return 0;
1088 while (1) {
1089 dp = (struct dosdirent *)DOS_readdir(dp);
1090 if (!dp->inuse) break;
1091 #ifdef DEBUG_LISTBOX
1092 printf("ListBoxDirectory %08X '%s' !\n", dp->filename, dp->filename);
1093 #endif
1094 if (dp->attribute & FA_DIREC) {
1095 if (attrib & DDL_DIRECTORY) {
1096 sprintf(temp, "[%s]", dp->filename);
1097 if ( (wRet = ListBoxAddString(hwnd, temp)) == LB_ERR) break;
1099 } else
1100 if (attrib & DDL_EXCLUSIVE) {
1101 if (attrib & (DDL_READWRITE | DDL_READONLY | DDL_HIDDEN | DDL_SYSTEM) )
1102 if ( (wRet = ListBoxAddString(hwnd, dp->filename)) == LB_ERR)
1103 break;
1104 } else {
1105 if ( (wRet = ListBoxAddString(hwnd, dp->filename)) == LB_ERR)
1106 break;
1109 DOS_closedir(dp);
1111 if (attrib & DDL_DRIVES)
1113 for (x=0;x!=MAX_DOS_DRIVES;x++)
1115 if (DOS_ValidDrive(x))
1117 sprintf(temp, "[-%c-]", 'A'+x);
1118 if ( (wRet = ListBoxAddString(hwnd, temp)) == LB_ERR)
1119 break;
1123 #ifdef DEBUG_LISTBOX
1124 printf("End of ListBoxDirectory !\n");
1125 #endif
1126 return wRet;
1130 int ListBoxGetItemRect(HWND hwnd, WORD wIndex, LPRECT lprect)
1132 LPHEADLIST lphl;
1133 LPLISTSTRUCT lpls, lpls2;
1134 UINT i;
1135 lphl = ListBoxGetStorageHeader(hwnd);
1136 if (lphl == NULL) return LB_ERR;
1137 if (wIndex > lphl->ItemsCount) return LB_ERR;
1138 lpls = lphl->lpFirst;
1139 if (lpls == NULL) return LB_ERR;
1140 for(i = 0; i < lphl->ItemsCount; i++) {
1141 lpls2 = lpls;
1142 lpls = (LPLISTSTRUCT)lpls->lpNext;
1143 if (i == wIndex) {
1144 *(lprect) = lpls2->dis.rcItem;
1145 break;
1147 if (lpls == NULL) break;
1149 return LB_ERR;
1154 int ListBoxSetItemHeight(HWND hwnd, WORD wIndex, long height)
1156 LPHEADLIST lphl;
1157 LPLISTSTRUCT lpls, lpls2;
1158 UINT i;
1159 lphl = ListBoxGetStorageHeader(hwnd);
1160 if (lphl == NULL) return LB_ERR;
1161 if (wIndex > lphl->ItemsCount) return LB_ERR;
1162 lpls = lphl->lpFirst;
1163 if (lpls == NULL) return LB_ERR;
1164 for(i = 0; i < lphl->ItemsCount; i++) {
1165 lpls2 = lpls;
1166 lpls = (LPLISTSTRUCT)lpls->lpNext;
1167 if (i == wIndex) {
1168 lpls2->dis.rcItem.bottom = lpls2->dis.rcItem.top + (short)height;
1169 InvalidateRect(hwnd, NULL, TRUE);
1170 UpdateWindow(hwnd);
1171 break;
1173 if (lpls == NULL) break;
1175 return LB_ERR;
1182 int ListBoxDefaultItem(HWND hwnd, WND *wndPtr,
1183 LPHEADLIST lphl, LPLISTSTRUCT lpls)
1185 RECT rect;
1186 GetClientRect(hwnd, &rect);
1187 SetRect(&lpls->dis.rcItem, 0, 0, rect.right, lphl->StdItemHeight);
1188 lpls->dis.CtlType = lphl->DrawCtlType;
1189 lpls->dis.CtlID = wndPtr->wIDmenu;
1190 lpls->dis.itemID = 0;
1191 lpls->dis.itemAction = 0;
1192 lpls->dis.itemState = 0;
1193 lpls->dis.hwndItem = hwnd;
1194 lpls->dis.hDC = 0;
1195 lpls->dis.itemData = 0;
1200 int ListBoxFindNextMatch(HWND hwnd, WORD wChar)
1202 WND *wndPtr;
1203 LPHEADLIST lphl;
1204 LPLISTSTRUCT lpls;
1205 UINT Count;
1206 lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
1207 if (lphl == NULL) return LB_ERR;
1208 lpls = lphl->lpFirst;
1209 if (lpls == NULL) return LB_ERR;
1210 if (wChar < ' ') return LB_ERR;
1211 if (((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) == LBS_OWNERDRAWFIXED) ||
1212 ((wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE) == LBS_OWNERDRAWVARIABLE)) {
1213 if ((wndPtr->dwStyle & LBS_HASSTRINGS) != LBS_HASSTRINGS) {
1214 return LB_ERR;
1217 Count = 0;
1218 while(lpls != NULL) {
1219 if (Count > lphl->ItemFocused) {
1220 if (*((char *)lpls->dis.itemData) == (char)wChar) {
1221 lphl->FirstVisible = Count - lphl->ItemsVisible / 2;
1222 if (lphl->FirstVisible < 1) lphl->FirstVisible = 1;
1223 if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) {
1224 lphl->ItemFocused = Count;
1226 else {
1227 ListBoxSetCurSel(hwnd, Count);
1229 SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
1230 InvalidateRect(hwnd, NULL, TRUE);
1231 UpdateWindow(hwnd);
1232 return Count;
1235 lpls = (LPLISTSTRUCT)lpls->lpNext;
1236 Count++;
1238 Count = 0;
1239 lpls = lphl->lpFirst;
1240 while(lpls != NULL) {
1241 if (*((char *)lpls->dis.itemData) == (char)wChar) {
1242 if (Count == lphl->ItemFocused) return LB_ERR;
1243 lphl->FirstVisible = Count - lphl->ItemsVisible / 2;
1244 if (lphl->FirstVisible < 1) lphl->FirstVisible = 1;
1245 if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) {
1246 lphl->ItemFocused = Count;
1248 else {
1249 ListBoxSetCurSel(hwnd, Count);
1251 SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
1252 InvalidateRect(hwnd, NULL, TRUE);
1253 UpdateWindow(hwnd);
1254 return Count;
1256 lpls = (LPLISTSTRUCT)lpls->lpNext;
1257 Count++;
1259 return LB_ERR;