2 * Interface code to listbox widgets
4 * Copyright Martin Ayotte, 1993
9 static char Copyright
[] = "Copyright Martin Ayotte, 1993";
13 #include <sys/types.h>
22 #include "prototypes.h"
24 /* #define DEBUG_LISTBOX */
25 /* #undef DEBUG_LISTBOX */
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
, BOOL bItemData
);
41 int ListBoxSetItemData(HWND hwnd
, UINT uIndex
, DWORD ItemData
);
42 int ListBoxDeleteString(HWND hwnd
, UINT uIndex
);
43 int ListBoxFindString(HWND hwnd
, UINT nFirst
, LPSTR MatchStr
);
44 int ListBoxResetContent(HWND hwnd
);
45 int ListBoxSetCurSel(HWND hwnd
, WORD wIndex
);
46 int ListBoxSetSel(HWND hwnd
, WORD wIndex
, WORD state
);
47 int ListBoxGetSel(HWND hwnd
, WORD wIndex
);
48 int ListBoxDirectory(HWND hwnd
, UINT attrib
, LPSTR filespec
);
49 int ListBoxGetItemRect(HWND hwnd
, WORD wIndex
, LPRECT rect
);
50 int ListBoxSetItemHeight(HWND hwnd
, WORD wIndex
, long height
);
51 int ListBoxDefaultItem(HWND hwnd
, WND
*wndPtr
,
52 LPHEADLIST lphl
, LPLISTSTRUCT lpls
);
53 int ListBoxFindNextMatch(HWND hwnd
, WORD wChar
);
54 int ListMaxFirstVisible(LPHEADLIST lphl
);
56 #define HasStrings(wndPtr) ( \
57 ( ((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) != LBS_OWNERDRAWFIXED) && \
58 ((wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE) != LBS_OWNERDRAWVARIABLE) ) || \
59 ((wndPtr->dwStyle & LBS_HASSTRINGS) == LBS_HASSTRINGS) )
61 #define LIST_HEAP_ALLOC(lphl,f,size) ((int)HEAP_Alloc(&lphl->Heap,f,size) & 0xffff)
62 #define LIST_HEAP_FREE(lphl,handle) (HEAP_Free(&lphl->Heap,LIST_HEAP_ADDR(lphl,handle)))
63 #define LIST_HEAP_ADDR(lphl,handle) \
64 ((void *)((handle) ? ((handle) | ((int)lphl->Heap & 0xffff0000)) : 0))
65 #define LIST_HEAP_SIZE 0x10000
67 /***********************************************************************
70 LONG
ListBoxWndProc( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
79 CREATESTRUCT
*createStruct
;
83 CreateListBoxStruct(hwnd
);
84 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
85 dprintf_listbox(stddeb
,"ListBox WM_CREATE %p !\n", lphl
);
86 if (lphl
== NULL
) return 0;
87 createStruct
= (CREATESTRUCT
*)lParam
;
88 if (HIWORD(createStruct
->lpCreateParams
) != 0)
89 lphl
->hWndLogicParent
= (HWND
)HIWORD(createStruct
->lpCreateParams
);
91 lphl
->hWndLogicParent
= GetParent(hwnd
);
92 lphl
->hFont
= GetStockObject(SYSTEM_FONT
);
93 lphl
->ColumnsWidth
= wndPtr
->rectClient
.right
- wndPtr
->rectClient
.left
;
94 if (wndPtr
->dwStyle
& WS_VSCROLL
) {
95 SetScrollRange(hwnd
, SB_VERT
, 1, ListMaxFirstVisible(lphl
), TRUE
);
96 ShowScrollBar(hwnd
, SB_VERT
, FALSE
);
98 if (wndPtr
->dwStyle
& WS_HSCROLL
) {
99 SetScrollRange(hwnd
, SB_HORZ
, 1, 1, TRUE
);
100 ShowScrollBar(hwnd
, SB_HORZ
, FALSE
);
102 if ((wndPtr
->dwStyle
& LBS_OWNERDRAWFIXED
) == LBS_OWNERDRAWFIXED
) {
106 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
107 if (lphl
== NULL
) return 0;
108 ListBoxResetContent(hwnd
);
109 /* XXX need to free lphl->Heap */
111 *((LPHEADLIST
*)&wndPtr
->wExtra
[1]) = 0;
112 dprintf_listbox(stddeb
,"ListBox WM_DESTROY %p !\n", lphl
);
116 dprintf_listbox(stddeb
,"ListBox WM_VSCROLL w=%04X l=%08lX !\n",
118 lphl
= ListBoxGetStorageHeader(hwnd
);
119 if (lphl
== NULL
) return 0;
120 y
= lphl
->FirstVisible
;
123 if (lphl
->FirstVisible
> 1)
124 lphl
->FirstVisible
--;
127 if (lphl
->FirstVisible
< ListMaxFirstVisible(lphl
))
128 lphl
->FirstVisible
++;
131 if (lphl
->FirstVisible
> 1)
132 lphl
->FirstVisible
-= lphl
->ItemsVisible
;
135 if (lphl
->FirstVisible
< ListMaxFirstVisible(lphl
))
136 lphl
->FirstVisible
+= lphl
->ItemsVisible
;
139 lphl
->FirstVisible
= LOWORD(lParam
);
142 if (lphl
->FirstVisible
< 1) lphl
->FirstVisible
= 1;
143 if (lphl
->FirstVisible
> ListMaxFirstVisible(lphl
))
144 lphl
->FirstVisible
= ListMaxFirstVisible(lphl
);
145 if (y
!= lphl
->FirstVisible
) {
146 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
147 InvalidateRect(hwnd
, NULL
, TRUE
);
153 dprintf_listbox(stddeb
,"ListBox WM_HSCROLL w=%04X l=%08lX !\n",
155 lphl
= ListBoxGetStorageHeader(hwnd
);
156 if (lphl
== NULL
) return 0;
157 y
= lphl
->FirstVisible
;
160 if (lphl
->FirstVisible
> 1)
161 lphl
->FirstVisible
-= lphl
->ItemsPerColumn
;
164 if (lphl
->FirstVisible
< ListMaxFirstVisible(lphl
))
165 lphl
->FirstVisible
+= lphl
->ItemsPerColumn
;
168 if (lphl
->FirstVisible
> 1 && lphl
->ItemsPerColumn
!= 0)
169 lphl
->FirstVisible
-= lphl
->ItemsVisible
/
170 lphl
->ItemsPerColumn
* lphl
->ItemsPerColumn
;
173 if (lphl
->FirstVisible
< ListMaxFirstVisible(lphl
) &&
174 lphl
->ItemsPerColumn
!= 0)
175 lphl
->FirstVisible
+= lphl
->ItemsVisible
/
176 lphl
->ItemsPerColumn
* lphl
->ItemsPerColumn
;
179 lphl
->FirstVisible
= lphl
->ItemsPerColumn
*
180 (LOWORD(lParam
) - 1) + 1;
183 if (lphl
->FirstVisible
< 1) lphl
->FirstVisible
= 1;
184 if (lphl
->FirstVisible
> ListMaxFirstVisible(lphl
))
185 lphl
->FirstVisible
= ListMaxFirstVisible(lphl
);
186 if (lphl
->ItemsPerColumn
!= 0) {
187 lphl
->FirstVisible
= lphl
->FirstVisible
/
188 lphl
->ItemsPerColumn
* lphl
->ItemsPerColumn
+ 1;
189 if (y
!= lphl
->FirstVisible
) {
190 SetScrollPos(hwnd
, SB_HORZ
, lphl
->FirstVisible
/
191 lphl
->ItemsPerColumn
+ 1, TRUE
);
192 InvalidateRect(hwnd
, NULL
, TRUE
);
201 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
202 if (lphl
== NULL
) return 0;
203 lphl
->PrevFocused
= lphl
->ItemFocused
;
204 y
= ListBoxFindMouse(hwnd
, LOWORD(lParam
), HIWORD(lParam
));
207 if ((wndPtr
->dwStyle
& LBS_MULTIPLESEL
) == LBS_MULTIPLESEL
) {
208 lphl
->ItemFocused
= y
;
209 wRet
= ListBoxGetSel(hwnd
, y
);
210 ListBoxSetSel(hwnd
, y
, !wRet
);
213 ListBoxSetCurSel(hwnd
, y
);
214 if ((wndPtr
->dwStyle
&& LBS_NOTIFY
) != 0)
215 SendMessage(lphl
->hWndLogicParent
, WM_COMMAND
,
216 wndPtr
->wIDmenu
, MAKELONG(hwnd
, LBN_SELCHANGE
));
218 ListBoxGetItemRect(hwnd
, y
, &rectsel
);
219 InvalidateRect(hwnd
, NULL
, TRUE
);
224 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
225 if (lphl
== NULL
) return 0;
226 if (lphl
->PrevFocused
!= lphl
->ItemFocused
)
227 SendMessage(lphl
->hWndLogicParent
, WM_COMMAND
, wndPtr
->wIDmenu
,
228 MAKELONG(hwnd
, LBN_SELCHANGE
));
231 case WM_LBUTTONDBLCLK
:
232 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
233 if (lphl
== NULL
) return 0;
234 SendMessage(lphl
->hWndLogicParent
, WM_COMMAND
, wndPtr
->wIDmenu
,
235 MAKELONG(hwnd
, LBN_DBLCLK
));
238 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
239 if (lphl
== NULL
) return 0;
240 if ((wParam
& MK_LBUTTON
) != 0) {
243 if (lphl
->FirstVisible
> 1) {
244 lphl
->FirstVisible
--;
245 if (wndPtr
->dwStyle
& WS_VSCROLL
)
246 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
247 InvalidateRect(hwnd
, NULL
, TRUE
);
252 GetClientRect(hwnd
, &rect
);
253 if (y
> (rect
.bottom
- 4)) {
254 if (lphl
->FirstVisible
< ListMaxFirstVisible(lphl
)) {
255 lphl
->FirstVisible
++;
256 if (wndPtr
->dwStyle
& WS_VSCROLL
)
257 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
258 InvalidateRect(hwnd
, NULL
, TRUE
);
263 if ((y
> 0) && (y
< (rect
.bottom
- 4))) {
264 if ((y
< rectsel
.top
) || (y
> rectsel
.bottom
)) {
265 wRet
= ListBoxFindMouse(hwnd
, LOWORD(lParam
), HIWORD(lParam
));
266 if ((wndPtr
->dwStyle
& LBS_MULTIPLESEL
) == LBS_MULTIPLESEL
) {
267 lphl
->ItemFocused
= wRet
;
270 ListBoxSetCurSel(hwnd
, wRet
);
271 if ((wndPtr
->dwStyle
&& LBS_NOTIFY
) != 0)
272 SendMessage(lphl
->hWndLogicParent
, WM_COMMAND
,
273 wndPtr
->wIDmenu
, MAKELONG(hwnd
, LBN_SELCHANGE
));
275 ListBoxGetItemRect(hwnd
, wRet
, &rectsel
);
276 InvalidateRect(hwnd
, NULL
, TRUE
);
283 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
284 if (lphl
== NULL
) return 0;
287 hWndCtl
= GetNextDlgTabItem(lphl
->hWndLogicParent
,
288 hwnd
, !(GetKeyState(VK_SHIFT
) < 0));
291 if ((GetKeyState(VK_SHIFT
) < 0))
292 dprintf_listbox(stddeb
,"ListBox PreviousDlgTabItem %04X !\n", hWndCtl
);
294 dprintf_listbox(stddeb
,"ListBox NextDlgTabItem %04X !\n", hWndCtl
);
298 lphl
->ItemFocused
= 0;
301 lphl
->ItemFocused
= lphl
->ItemsCount
- 1;
304 if ((wndPtr
->dwStyle
& LBS_MULTICOLUMN
) == LBS_MULTICOLUMN
) {
305 lphl
->ItemFocused
-= lphl
->ItemsPerColumn
;
312 if ((wndPtr
->dwStyle
& LBS_MULTICOLUMN
) == LBS_MULTICOLUMN
) {
313 lphl
->ItemFocused
+= lphl
->ItemsPerColumn
;
320 lphl
->ItemFocused
-= lphl
->ItemsVisible
;
323 lphl
->ItemFocused
+= lphl
->ItemsVisible
;
326 wRet
= ListBoxGetSel(hwnd
, lphl
->ItemFocused
);
327 ListBoxSetSel(hwnd
, lphl
->ItemFocused
, !wRet
);
330 ListBoxFindNextMatch(hwnd
, wParam
);
333 if (lphl
->ItemFocused
< 0) lphl
->ItemFocused
= 0;
334 if (lphl
->ItemFocused
>= lphl
->ItemsCount
)
335 lphl
->ItemFocused
= lphl
->ItemsCount
- 1;
336 lphl
->FirstVisible
= lphl
->ItemFocused
/ lphl
->ItemsVisible
*
337 lphl
->ItemsVisible
+ 1;
338 if (lphl
->FirstVisible
< 1) lphl
->FirstVisible
= 1;
339 if ((wndPtr
->dwStyle
& LBS_MULTIPLESEL
) != LBS_MULTIPLESEL
) {
340 ListBoxSetCurSel(hwnd
, lphl
->ItemFocused
);
341 if ((wndPtr
->dwStyle
&& LBS_NOTIFY
) != 0)
342 SendMessage(lphl
->hWndLogicParent
, WM_COMMAND
,
343 wndPtr
->wIDmenu
, MAKELONG(hwnd
, LBN_SELCHANGE
));
345 if (wndPtr
->dwStyle
& WS_VSCROLL
)
346 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
347 InvalidateRect(hwnd
, NULL
, TRUE
);
351 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
352 if (lphl
== NULL
) return 0;
354 lphl
->hFont
= GetStockObject(SYSTEM_FONT
);
356 lphl
->hFont
= wParam
;
357 if (wParam
== 0) break;
361 printf("ListBox WM_SETREDRAW hWnd=%04X w=%04X !\n", hwnd
, wParam
);
363 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
364 if (lphl
== NULL
) return 0;
365 lphl
->bRedrawFlag
= wParam
;
368 wndPtr
= WIN_FindWndPtr(hwnd
);
369 if ((wndPtr
->dwStyle
& LBS_OWNERDRAWFIXED
) == LBS_OWNERDRAWFIXED
) {
370 OwnerDrawListBox(hwnd
);
373 if ((wndPtr
->dwStyle
& LBS_OWNERDRAWVARIABLE
) == LBS_OWNERDRAWVARIABLE
) {
374 OwnerDrawListBox(hwnd
);
377 StdDrawListBox(hwnd
);
380 dprintf_listbox(stddeb
,"ListBox WM_SETFOCUS !\n");
381 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
384 dprintf_listbox(stddeb
,"ListBox WM_KILLFOCUS !\n");
385 InvalidateRect(hwnd
, NULL
, TRUE
);
389 case LB_RESETCONTENT
:
390 dprintf_listbox(stddeb
,"ListBox LB_RESETCONTENT !\n");
391 ListBoxResetContent(hwnd
);
394 dprintf_listbox(stddeb
,"ListBox LB_DIR !\n");
395 wRet
= ListBoxDirectory(hwnd
, wParam
, (LPSTR
)lParam
);
396 InvalidateRect(hwnd
, NULL
, TRUE
);
400 wRet
= ListBoxAddString(hwnd
, (LPSTR
)lParam
);
403 dprintf_listbox(stddeb
, "LB_GETTEXT wParam=%d\n",wParam
);
404 wRet
= ListBoxGetText(hwnd
, wParam
, (LPSTR
)lParam
, FALSE
);
406 case LB_INSERTSTRING
:
407 wRet
= ListBoxInsertString(hwnd
, wParam
, (LPSTR
)lParam
);
409 case LB_DELETESTRING
:
410 wRet
= ListBoxDeleteString(hwnd
, wParam
);
413 wRet
= ListBoxFindString(hwnd
, wParam
, (LPSTR
)lParam
);
415 case LB_GETCARETINDEX
:
418 lphl
= ListBoxGetStorageHeader(hwnd
);
419 return lphl
->ItemsCount
;
421 lphl
= ListBoxGetStorageHeader(hwnd
);
422 dprintf_listbox(stddeb
,"ListBox LB_GETCURSEL %u !\n",
424 return lphl
->ItemFocused
;
425 case LB_GETHORIZONTALEXTENT
:
428 dprintf_listbox(stddeb
, "LB_GETITEMDATA wParam=%x\n", wParam
);
429 lRet
= ListBoxGetText(hwnd
, wParam
, (LPSTR
)lParam
, TRUE
);
431 case LB_GETITEMHEIGHT
:
432 ListBoxGetItemRect(hwnd
, wParam
, &rect
);
433 return (rect
.bottom
- rect
.top
);
435 ListBoxGetItemRect(hwnd
, wParam
, (LPRECT
)lParam
);
438 wRet
= ListBoxGetSel(hwnd
, wParam
);
441 lphl
= ListBoxGetStorageHeader(hwnd
);
442 if (lphl
== NULL
) return LB_ERR
;
443 return lphl
->SelCount
;
449 lphl
= ListBoxGetStorageHeader(hwnd
);
450 if (lphl
== NULL
) return LB_ERR
;
451 return lphl
->FirstVisible
;
452 case LB_SELECTSTRING
:
454 case LB_SELITEMRANGE
:
456 case LB_SETCARETINDEX
:
458 case LB_SETCOLUMNWIDTH
:
459 lphl
= ListBoxGetStorageHeader(hwnd
);
460 if (lphl
== NULL
) return LB_ERR
;
461 lphl
->ColumnsWidth
= wParam
;
463 case LB_SETHORIZONTALEXTENT
:
466 dprintf_listbox(stddeb
, "LB_SETITEMDATA wParam=%x lParam=%lx\n", wParam
, lParam
);
467 wRet
= ListBoxSetItemData(hwnd
, wParam
, lParam
);
470 lphl
= ListBoxGetStorageHeader(hwnd
);
471 if (lphl
== NULL
) return LB_ERR
;
472 lphl
->FirstVisible
= wParam
;
475 dprintf_listbox(stddeb
,"ListBox LB_SETCURSEL wParam=%x !\n",
477 wRet
= ListBoxSetCurSel(hwnd
, wParam
);
478 InvalidateRect(hwnd
, NULL
, TRUE
);
482 dprintf_listbox(stddeb
,"ListBox LB_SETSEL wParam=%x lParam=%lX !\n", wParam
, lParam
);
483 wRet
= ListBoxSetSel(hwnd
, LOWORD(lParam
), wParam
);
484 InvalidateRect(hwnd
, NULL
, TRUE
);
488 dprintf_listbox(stddeb
,"ListBox LB_SETTOPINDEX wParam=%x !\n",
490 lphl
= ListBoxGetStorageHeader(hwnd
);
491 lphl
->FirstVisible
= wParam
;
492 wndPtr
= WIN_FindWndPtr(hwnd
);
493 if (wndPtr
->dwStyle
& WS_VSCROLL
)
494 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
495 InvalidateRect(hwnd
, NULL
, TRUE
);
498 case LB_SETITEMHEIGHT
:
499 dprintf_listbox(stddeb
,"ListBox LB_SETITEMHEIGHT wParam=%x lParam=%lX !\n", wParam
, lParam
);
500 wRet
= ListBoxSetItemHeight(hwnd
, wParam
, lParam
);
504 return DefWindowProc( hwnd
, message
, wParam
, lParam
);
510 LPHEADLIST
ListBoxGetWindowAndStorage(HWND hwnd
, WND
**wndPtr
)
514 *(wndPtr
) = Ptr
= WIN_FindWndPtr(hwnd
);
515 lphl
= *((LPHEADLIST
*)&Ptr
->wExtra
[1]);
520 LPHEADLIST
ListBoxGetStorageHeader(HWND hwnd
)
524 wndPtr
= WIN_FindWndPtr(hwnd
);
525 lphl
= *((LPHEADLIST
*)&wndPtr
->wExtra
[1]);
530 void StdDrawListBox(HWND hwnd
)
538 DWORD dwOldTextColor
;
541 int i
, h
, h2
, maxwidth
, ipc
;
543 hdc
= BeginPaint( hwnd
, &ps
);
544 if (!IsWindowVisible(hwnd
)) {
545 EndPaint( hwnd
, &ps
);
548 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
549 if (lphl
== NULL
) goto EndOfPaint
;
550 if (!lphl
->bRedrawFlag
) goto EndOfPaint
;
551 SelectObject(hdc
, lphl
->hFont
);
552 hBrush
= SendMessage(lphl
->hWndLogicParent
, WM_CTLCOLOR
, (WORD
)hdc
,
553 MAKELONG(hwnd
, CTLCOLOR_LISTBOX
));
554 if (hBrush
== (HBRUSH
)NULL
) hBrush
= GetStockObject(WHITE_BRUSH
);
555 GetClientRect(hwnd
, &rect
);
557 if (wndPtr->dwStyle & WS_VSCROLL) rect.right -= 16;
558 if (wndPtr->dwStyle & WS_HSCROLL) rect.bottom -= 16;
560 FillRect(hdc
, &rect
, hBrush
);
561 maxwidth
= rect
.right
;
562 rect
.right
= lphl
->ColumnsWidth
;
563 if (lphl
->ItemsCount
== 0) goto EndOfPaint
;
564 lpls
= lphl
->lpFirst
;
565 if (lpls
== NULL
) goto EndOfPaint
;
566 lphl
->ItemsVisible
= 0;
567 lphl
->ItemsPerColumn
= ipc
= 0;
568 for(i
= 1; i
<= lphl
->ItemsCount
; i
++) {
569 if (i
>= lphl
->FirstVisible
) {
570 if (lpls
== NULL
) break;
571 if ((h
+ lpls
->dis
.rcItem
.bottom
- lpls
->dis
.rcItem
.top
) > rect
.bottom
) {
572 if ((wndPtr
->dwStyle
& LBS_MULTICOLUMN
) == LBS_MULTICOLUMN
) {
573 lphl
->ItemsPerColumn
= max(lphl
->ItemsPerColumn
, ipc
);
576 rect
.left
+= lphl
->ColumnsWidth
;
577 rect
.right
+= lphl
->ColumnsWidth
;
578 if (rect
.left
> maxwidth
) break;
583 h2
= lpls
->dis
.rcItem
.bottom
- lpls
->dis
.rcItem
.top
;
584 lpls
->dis
.rcItem
.top
= h
;
585 lpls
->dis
.rcItem
.bottom
= h
+ h2
;
586 lpls
->dis
.rcItem
.left
= rect
.left
;
587 lpls
->dis
.rcItem
.right
= rect
.right
;
588 OldBkMode
= SetBkMode(hdc
, TRANSPARENT
);
589 if (lpls
->dis
.itemState
!= 0) {
590 dwOldTextColor
= SetTextColor(hdc
, 0x00FFFFFFL
);
591 FillRect(hdc
, &lpls
->dis
.rcItem
, GetStockObject(BLACK_BRUSH
));
593 TextOut(hdc
, rect
.left
+ 5, h
+ 2, (char *)lpls
->itemText
,
594 strlen((char *)lpls
->itemText
));
595 if (lpls
->dis
.itemState
!= 0) {
596 SetTextColor(hdc
, dwOldTextColor
);
598 SetBkMode(hdc
, OldBkMode
);
599 if ((lphl
->ItemFocused
== i
- 1) && GetFocus() == hwnd
) {
600 DrawFocusRect(hdc
, &lpls
->dis
.rcItem
);
603 lphl
->ItemsVisible
++;
606 if (lpls
->lpNext
== NULL
) goto EndOfPaint
;
607 lpls
= (LPLISTSTRUCT
)lpls
->lpNext
;
610 EndPaint( hwnd
, &ps
);
611 if ((lphl
->ItemsCount
> lphl
->ItemsVisible
) &
612 (wndPtr
->dwStyle
& WS_VSCROLL
)) {
614 InvalidateRect(wndPtr->hWndVScroll, NULL, TRUE);
615 UpdateWindow(wndPtr->hWndVScroll);
622 void OwnerDrawListBox(HWND hwnd
)
624 WND
*wndPtr
,*ParentWndPtr
;
633 int i
, h
, h2
, maxwidth
;
635 hdc
= BeginPaint(hwnd
, &ps
);
636 if (!IsWindowVisible(hwnd
)) {
637 EndPaint( hwnd
, &ps
);
640 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
641 if (lphl
== NULL
) goto EndOfPaint
;
642 if (!lphl
->bRedrawFlag
) goto EndOfPaint
;
643 hBrush
= SendMessage(lphl
->hWndLogicParent
, WM_CTLCOLOR
, (WORD
)hdc
,
644 MAKELONG(hwnd
, CTLCOLOR_LISTBOX
));
645 if (hBrush
== (HBRUSH
)NULL
) hBrush
= GetStockObject(WHITE_BRUSH
);
646 GetClientRect(hwnd
, &rect
);
647 if (wndPtr
->dwStyle
& WS_VSCROLL
) rect
.right
-= 16;
648 if (wndPtr
->dwStyle
& WS_HSCROLL
) rect
.bottom
-= 16;
649 FillRect(hdc
, &rect
, hBrush
);
650 maxwidth
= rect
.right
;
651 rect
.right
= lphl
->ColumnsWidth
;
652 if (lphl
->ItemsCount
== 0) goto EndOfPaint
;
653 lpls
= lphl
->lpFirst
;
654 if (lpls
== NULL
) goto EndOfPaint
;
655 lphl
->ItemsVisible
= 0;
656 for (i
= 1; i
<= lphl
->ItemsCount
; i
++) {
657 if (i
>= lphl
->FirstVisible
) {
659 lpls
->dis
.hwndItem
= hwnd
;
660 lpls
->dis
.CtlType
= ODT_LISTBOX
;
661 lpls
->dis
.itemID
= i
- 1;
662 if ((!lpls
->dis
.CtlID
) && (lphl
->hWndLogicParent
)) {
663 ParentWndPtr
= WIN_FindWndPtr(lphl
->hWndLogicParent
);
664 lpls
->dis
.CtlID
= ParentWndPtr
->wIDmenu
;
666 h2
= lpls
->dis
.rcItem
.bottom
- lpls
->dis
.rcItem
.top
;
667 lpls
->dis
.rcItem
.top
= h
;
668 lpls
->dis
.rcItem
.bottom
= h
+ h2
;
669 lpls
->dis
.rcItem
.left
= rect
.left
;
670 lpls
->dis
.rcItem
.right
= rect
.right
;
671 lpls
->dis
.itemAction
= ODA_DRAWENTIRE
;
672 /* if (lpls->dis.itemState != 0) {
673 lpls->dis.itemAction |= ODA_SELECT;
675 if (lphl->ItemFocused == i - 1) {
676 lpls->dis.itemAction |= ODA_FOCUS;
678 dprintf_listbox(stddeb
,"LBOX WM_DRAWITEM #%d left=%d top=%d right=%d bottom=%d !\n",
679 i
-1, lpls
->dis
.rcItem
.left
, lpls
->dis
.rcItem
.top
,
680 lpls
->dis
.rcItem
.right
, lpls
->dis
.rcItem
.bottom
);
681 dprintf_listbox(stddeb
,"LBOX WM_DRAWITEM Parent=%X &dis=%lX CtlID=%u !\n",
682 hWndParent
, (LONG
)&lpls
->dis
, lpls
->dis
.CtlID
);
683 dprintf_listbox(stddeb
,"LBOX WM_DRAWITEM %08lX!\n",lpls
->dis
.itemData
);
684 if (HasStrings(wndPtr
))
685 dprintf_listbox(stddeb
," '%s'\n",lpls
->itemText
);
686 if (HasStrings(wndPtr
)) {
687 itemData
= lpls
->dis
.itemData
;
688 lpls
->dis
.itemData
= (DWORD
)lpls
->itemText
;
690 SendMessage(lphl
->hWndLogicParent
, WM_DRAWITEM
,
691 i
-1, (LPARAM
)&lpls
->dis
);
692 if (HasStrings(wndPtr
))
693 lpls
->dis
.itemData
= itemData
;
695 /* if (lpls->dis.itemState != 0) {
696 InvertRect(hdc, &lpls->dis.rcItem);
699 lphl
->ItemsVisible
++;
700 /* if (h > rect.bottom) goto EndOfPaint;*/
702 if (lpls
->lpNext
== NULL
) goto EndOfPaint
;
703 lpls
= (LPLISTSTRUCT
)lpls
->lpNext
;
706 EndPaint( hwnd
, &ps
);
707 if ((lphl
->ItemsCount
> lphl
->ItemsVisible
) &
708 (wndPtr
->dwStyle
& WS_VSCROLL
)) {
710 InvalidateRect(wndPtr->hWndVScroll, NULL, TRUE);
711 UpdateWindow(wndPtr->hWndVScroll);
719 int ListBoxFindMouse(HWND hwnd
, int X
, int Y
)
726 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
727 if (lphl
== NULL
) return LB_ERR
;
728 if (lphl
->ItemsCount
== 0) return LB_ERR
;
729 lpls
= lphl
->lpFirst
;
730 if (lpls
== NULL
) return LB_ERR
;
731 GetClientRect(hwnd
, &rect
);
732 if (wndPtr
->dwStyle
& WS_VSCROLL
) rect
.right
-= 16;
733 if (wndPtr
->dwStyle
& WS_HSCROLL
) rect
.bottom
-= 16;
735 w
= lphl
->ColumnsWidth
;
736 for(i
= 1; i
<= lphl
->ItemsCount
; i
++) {
737 if (i
>= lphl
->FirstVisible
) {
739 h
+= lpls
->dis
.rcItem
.bottom
- lpls
->dis
.rcItem
.top
;
740 if ((Y
> h2
) && (Y
< h
) &&
741 (X
> w2
) && (X
< w
)) return(i
- 1);
742 if (h
> rect
.bottom
) {
743 if ((wndPtr
->dwStyle
& LBS_MULTICOLUMN
) != LBS_MULTICOLUMN
) return LB_ERR
;
746 w
+= lphl
->ColumnsWidth
;
747 if (w2
> rect
.right
) return LB_ERR
;
750 if (lpls
->lpNext
== NULL
) return LB_ERR
;
751 lpls
= (LPLISTSTRUCT
)lpls
->lpNext
;
758 int CreateListBoxStruct(HWND hwnd
)
764 wndPtr
= WIN_FindWndPtr(hwnd
);
765 lphl
= (LPHEADLIST
)malloc(sizeof(HEADLIST
));
766 lphl
->lpFirst
= NULL
;
767 *((LPHEADLIST
*)&wndPtr
->wExtra
[1]) = lphl
; /* HEAD of List */
768 lphl
->ItemsCount
= 0;
769 lphl
->ItemsVisible
= 0;
770 lphl
->FirstVisible
= 1;
771 lphl
->ColumnsVisible
= 1;
772 lphl
->ItemsPerColumn
= 0;
773 lphl
->StdItemHeight
= 15;
774 lphl
->ItemFocused
= 0;
775 lphl
->PrevFocused
= 0;
777 lphl
->DrawCtlType
= ODT_LISTBOX
;
778 lphl
->bRedrawFlag
= TRUE
;
779 HeapHandle
= GlobalAlloc(GMEM_FIXED
, LIST_HEAP_SIZE
);
780 HeapBase
= GlobalLock(HeapHandle
);
781 HEAP_Init(&lphl
->Heap
, HeapBase
, LIST_HEAP_SIZE
);
786 void ListBoxAskMeasure(WND
*wndPtr
, LPHEADLIST lphl
, LPLISTSTRUCT lpls
)
788 MEASUREITEMSTRUCT
*lpmeasure
;
789 HANDLE hTemp
= USER_HEAP_ALLOC(GMEM_MOVEABLE
, sizeof(MEASUREITEMSTRUCT
));
790 lpmeasure
= (MEASUREITEMSTRUCT
*) USER_HEAP_ADDR(hTemp
);
791 if (lpmeasure
== NULL
) {
792 fprintf(stderr
,"ListBoxAskMeasure() // Bad allocation of Measure struct !\n");
795 lpmeasure
->CtlType
= ODT_LISTBOX
;
796 lpmeasure
->CtlID
= wndPtr
->wIDmenu
;
797 lpmeasure
->itemID
= lpls
->dis
.itemID
;
798 lpmeasure
->itemWidth
= wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
;
799 lpmeasure
->itemHeight
= 0;
800 if (HasStrings(wndPtr
))
801 lpmeasure
->itemData
= (DWORD
)lpls
->itemText
;
803 lpmeasure
->itemData
= lpls
->dis
.itemData
;
804 SendMessage(lphl
->hWndLogicParent
, WM_MEASUREITEM
, 0, (DWORD
)lpmeasure
);
805 lpls
->dis
.rcItem
.right
= lpls
->dis
.rcItem
.left
+ lpmeasure
->itemWidth
;
806 lpls
->dis
.rcItem
.bottom
= lpls
->dis
.rcItem
.top
+ lpmeasure
->itemHeight
;
807 USER_HEAP_FREE(hTemp
);
811 int ListBoxAddString(HWND hwnd
, LPSTR newstr
)
814 UINT pos
= (UINT
) -1;
817 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
818 if (lphl
== NULL
) return LB_ERR
;
819 if (HasStrings(wndPtr
) && (wndPtr
->dwStyle
& LBS_SORT
)) {
820 LPLISTSTRUCT lpls
= lphl
->lpFirst
;
821 for (pos
= 0; lpls
; lpls
= lpls
->lpNext
, pos
++)
822 if (strcmp(lpls
->itemText
, newstr
) >= 0)
825 return ListBoxInsertString(hwnd
, pos
, newstr
);
828 int ListBoxInsertString(HWND hwnd
, UINT uIndex
, LPSTR newstr
)
832 LPLISTSTRUCT
*lppls
, lplsnew
;
838 dprintf_listbox(stddeb
,"ListBoxInsertString(%04X, %d, %p);\n",
839 hwnd
, uIndex
, newstr
);
841 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
842 if (lphl
== NULL
) return LB_ERR
;
844 if (uIndex
== (UINT
)-1)
845 uIndex
= lphl
->ItemsCount
;
846 if (uIndex
> lphl
->ItemsCount
) return LB_ERR
;
847 lppls
= (LPLISTSTRUCT
*) &lphl
->lpFirst
;
849 for(Count
= 0; Count
< uIndex
; Count
++) {
850 if (*lppls
== NULL
) return LB_ERR
;
851 lppls
= (LPLISTSTRUCT
*) &(*lppls
)->lpNext
;
854 hItem
= LIST_HEAP_ALLOC(lphl
, GMEM_MOVEABLE
, sizeof(LISTSTRUCT
));
855 lplsnew
= (LPLISTSTRUCT
) LIST_HEAP_ADDR(lphl
, hItem
);
856 if (lplsnew
== NULL
) {
857 printf("ListBoxInsertString() // Bad allocation of new item !\n");
860 ListBoxDefaultItem(hwnd
, wndPtr
, lphl
, lplsnew
);
861 lplsnew
->hMem
= hItem
;
862 lplsnew
->lpNext
= *lppls
;
867 if (HasStrings(wndPtr
)) {
868 hStr
= LIST_HEAP_ALLOC(lphl
, GMEM_MOVEABLE
, strlen(newstr
) + 1);
869 str
= (LPSTR
)LIST_HEAP_ADDR(lphl
, hStr
);
870 if (str
== NULL
) return LB_ERRSPACE
;
873 lplsnew
->itemText
= str
;
874 dprintf_listbox(stddeb
,"ListBoxInsertString // LBS_HASSTRINGS after strcpy '%s'\n", str
);
877 lplsnew
->itemText
= NULL
;
878 lplsnew
->dis
.itemData
= (DWORD
)newstr
;
880 lplsnew
->dis
.itemID
= lphl
->ItemsCount
;
881 lplsnew
->hData
= hStr
;
882 if (((wndPtr
->dwStyle
& LBS_OWNERDRAWVARIABLE
) == LBS_OWNERDRAWVARIABLE
) ||
883 ((wndPtr
->dwStyle
& LBS_OWNERDRAWFIXED
) == LBS_OWNERDRAWFIXED
))
884 ListBoxAskMeasure(wndPtr
, lphl
, lplsnew
);
885 if (wndPtr
->dwStyle
& WS_VSCROLL
)
886 SetScrollRange(hwnd
, SB_VERT
, 1, ListMaxFirstVisible(lphl
),
887 (lphl
->FirstVisible
!= 1 && lphl
->bRedrawFlag
));
888 if ((wndPtr
->dwStyle
& WS_HSCROLL
) && lphl
->ItemsPerColumn
!= 0)
889 SetScrollRange(hwnd
, SB_HORZ
, 1, lphl
->ItemsVisible
/
890 lphl
->ItemsPerColumn
+ 1,
891 (lphl
->FirstVisible
!= 1 && lphl
->bRedrawFlag
));
892 if (((lphl
->ItemsCount
- lphl
->FirstVisible
) == lphl
->ItemsVisible
) &&
893 (lphl
->ItemsVisible
!= 0)) {
894 if (wndPtr
->dwStyle
& WS_VSCROLL
) ShowScrollBar(hwnd
, SB_VERT
, TRUE
);
895 if (wndPtr
->dwStyle
& WS_HSCROLL
) ShowScrollBar(hwnd
, SB_HORZ
, TRUE
);
897 if ((lphl
->FirstVisible
<= uIndex
) &&
898 ((lphl
->FirstVisible
+ lphl
->ItemsVisible
) >= uIndex
)) {
899 InvalidateRect(hwnd
, NULL
, TRUE
);
902 dprintf_listbox(stddeb
,"ListBoxInsertString // count=%d\n", lphl
->ItemsCount
);
907 int ListBoxGetText(HWND hwnd
, UINT uIndex
, LPSTR OutStr
, BOOL bItemData
)
913 if ((!OutStr
)&&(!bItemData
))
914 fprintf(stderr
, "ListBoxGetText // OutStr==NULL\n");
915 if (!bItemData
) *OutStr
=0;
916 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
917 if (lphl
== NULL
) return LB_ERR
;
918 if (uIndex
>= lphl
->ItemsCount
) return LB_ERR
;
919 lpls
= lphl
->lpFirst
;
920 if (lpls
== NULL
) return LB_ERR
;
921 if (uIndex
> lphl
->ItemsCount
) return LB_ERR
;
922 for(Count
= 0; Count
< uIndex
; Count
++) {
923 if (lpls
->lpNext
== NULL
) return LB_ERR
;
924 lpls
= (LPLISTSTRUCT
)lpls
->lpNext
;
927 return lpls
->dis
.itemData
;
928 if (!(HasStrings(wndPtr
)) )
930 *((long *)OutStr
) = lpls
->dis
.itemData
;
934 strcpy(OutStr
, lpls
->itemText
);
935 return strlen(OutStr
);
938 int ListBoxSetItemData(HWND hwnd
, UINT uIndex
, DWORD ItemData
)
944 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
945 if (lphl
== NULL
) return LB_ERR
;
946 if (uIndex
>= lphl
->ItemsCount
) return LB_ERR
;
947 lpls
= lphl
->lpFirst
;
948 if (lpls
== NULL
) return LB_ERR
;
949 if (uIndex
> lphl
->ItemsCount
) return LB_ERR
;
950 for(Count
= 0; Count
< uIndex
; Count
++) {
951 if (lpls
->lpNext
== NULL
) return LB_ERR
;
952 lpls
= (LPLISTSTRUCT
)lpls
->lpNext
;
954 lpls
->dis
.itemData
= ItemData
;
959 int ListBoxDeleteString(HWND hwnd
, UINT uIndex
)
963 LPLISTSTRUCT lpls
, lpls2
;
965 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
966 if (lphl
== NULL
) return LB_ERR
;
967 if (uIndex
>= lphl
->ItemsCount
) return LB_ERR
;
968 lpls
= lphl
->lpFirst
;
969 if (lpls
== NULL
) return LB_ERR
;
970 if (uIndex
> lphl
->ItemsCount
) return LB_ERR
;
971 for(Count
= 1; Count
< uIndex
; Count
++) {
972 if (lpls
->lpNext
== NULL
) return LB_ERR
;
974 lpls
= (LPLISTSTRUCT
)lpls
->lpNext
;
976 lpls2
->lpNext
= (LPLISTSTRUCT
)lpls
->lpNext
;
978 if (lpls
->hData
!= 0) LIST_HEAP_FREE(lphl
, lpls
->hData
);
979 if (lpls
->hMem
!= 0) LIST_HEAP_FREE(lphl
, lpls
->hMem
);
980 if (wndPtr
->dwStyle
& WS_VSCROLL
)
981 SetScrollRange(hwnd
, SB_VERT
, 1, ListMaxFirstVisible(lphl
), TRUE
);
982 if ((wndPtr
->dwStyle
& WS_HSCROLL
) && lphl
->ItemsPerColumn
!= 0)
983 SetScrollRange(hwnd
, SB_HORZ
, 1, lphl
->ItemsVisible
/
984 lphl
->ItemsPerColumn
+ 1, TRUE
);
985 if (lphl
->ItemsCount
< lphl
->ItemsVisible
) {
986 if (wndPtr
->dwStyle
& WS_VSCROLL
)
987 ShowScrollBar(hwnd
, SB_VERT
, FALSE
);
988 if (wndPtr
->dwStyle
& WS_HSCROLL
)
989 ShowScrollBar(hwnd
, SB_HORZ
, FALSE
);
991 if ((lphl
->FirstVisible
<= uIndex
) &&
992 ((lphl
->FirstVisible
+ lphl
->ItemsVisible
) >= uIndex
)) {
993 InvalidateRect(hwnd
, NULL
, TRUE
);
996 return lphl
->ItemsCount
;
1000 int ListBoxFindString(HWND hwnd
, UINT nFirst
, LPSTR MatchStr
)
1006 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
1007 if (lphl
== NULL
) return LB_ERR
;
1008 if (nFirst
> lphl
->ItemsCount
) return LB_ERR
;
1009 lpls
= lphl
->lpFirst
;
1010 if (lpls
== NULL
) return LB_ERR
;
1012 while(lpls
!= NULL
) {
1013 if (HasStrings(wndPtr
))
1015 if (strcmp(lpls
->itemText
, MatchStr
) == 0) return Count
;
1019 if (lpls
->dis
.itemData
== (DWORD
)MatchStr
) return Count
;
1021 lpls
= (LPLISTSTRUCT
)lpls
->lpNext
;
1028 int ListBoxResetContent(HWND hwnd
)
1032 LPLISTSTRUCT lpls
, lpls2
;
1034 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
1035 if (lphl
== NULL
) return LB_ERR
;
1036 lpls
= lphl
->lpFirst
;
1037 if (lpls
== NULL
) return LB_ERR
;
1038 dprintf_listbox(stddeb
, "ListBoxResetContent // ItemCount = %d\n",
1040 for(i
= 0; i
<= lphl
->ItemsCount
; i
++) {
1042 lpls
= (LPLISTSTRUCT
)lpls
->lpNext
;
1044 dprintf_listbox(stddeb
,"ResetContent #%u\n", i
);
1045 if (lpls2
->hData
!= 0 && lpls2
->hData
!= lpls2
->hMem
)
1046 LIST_HEAP_FREE(lphl
, lpls2
->hData
);
1047 if (lpls2
->hMem
!= 0) LIST_HEAP_FREE(lphl
, lpls2
->hMem
);
1049 if (lpls
== NULL
) break;
1051 lphl
->lpFirst
= NULL
;
1052 lphl
->FirstVisible
= 1;
1053 lphl
->ItemsCount
= 0;
1054 lphl
->ItemFocused
= -1;
1055 lphl
->PrevFocused
= -1;
1056 if ((wndPtr
->dwStyle
&& LBS_NOTIFY
) != 0)
1057 SendMessage(lphl
->hWndLogicParent
, WM_COMMAND
,
1058 wndPtr
->wIDmenu
, MAKELONG(hwnd
, LBN_SELCHANGE
));
1059 if (wndPtr
->dwStyle
& WS_VSCROLL
)
1060 SetScrollRange(hwnd
, SB_VERT
, 1, ListMaxFirstVisible(lphl
), TRUE
);
1061 if ((wndPtr
->dwStyle
& WS_HSCROLL
) && lphl
->ItemsPerColumn
!= 0)
1062 SetScrollRange(hwnd
, SB_HORZ
, 1, lphl
->ItemsVisible
/
1063 lphl
->ItemsPerColumn
+ 1, TRUE
);
1064 if (wndPtr
->dwStyle
& WS_VSCROLL
)
1065 ShowScrollBar(hwnd
, SB_VERT
, FALSE
);
1066 if (wndPtr
->dwStyle
& WS_HSCROLL
)
1067 ShowScrollBar(hwnd
, SB_HORZ
, FALSE
);
1068 InvalidateRect(hwnd
, NULL
, TRUE
);
1074 int ListBoxSetCurSel(HWND hwnd
, WORD wIndex
)
1078 LPLISTSTRUCT lpls
, lpls2
;
1080 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
1081 if (lphl
== NULL
) return LB_ERR
;
1082 lphl
->ItemFocused
= LB_ERR
;
1083 if (wIndex
>= lphl
->ItemsCount
) return LB_ERR
;
1084 lpls
= lphl
->lpFirst
;
1085 if (lpls
== NULL
) return LB_ERR
;
1086 for(i
= 0; i
< lphl
->ItemsCount
; i
++) {
1088 lpls
= (LPLISTSTRUCT
)lpls
->lpNext
;
1090 lpls2
->dis
.itemState
= 1;
1092 if (lpls2
->dis
.itemState
!= 0)
1093 lpls2
->dis
.itemState
= 0;
1094 if (lpls
== NULL
) break;
1096 lphl
->ItemFocused
= wIndex
;
1097 if ((wndPtr
->dwStyle
&& LBS_NOTIFY
) != 0)
1098 SendMessage(lphl
->hWndLogicParent
, WM_COMMAND
,
1099 wndPtr
->wIDmenu
, MAKELONG(hwnd
, LBN_SELCHANGE
));
1105 int ListBoxSetSel(HWND hwnd
, WORD wIndex
, WORD state
)
1108 LPLISTSTRUCT lpls
, lpls2
;
1110 lphl
= ListBoxGetStorageHeader(hwnd
);
1111 if (lphl
== NULL
) return LB_ERR
;
1112 if (wIndex
>= lphl
->ItemsCount
) return LB_ERR
;
1113 lpls
= lphl
->lpFirst
;
1114 if (lpls
== NULL
) return LB_ERR
;
1115 for(i
= 0; i
< lphl
->ItemsCount
; i
++) {
1117 lpls
= (LPLISTSTRUCT
)lpls
->lpNext
;
1118 if ((i
== wIndex
) || (wIndex
== (WORD
)-1)) {
1119 lpls2
->dis
.itemState
= state
;
1122 if (lpls
== NULL
) break;
1128 int ListBoxGetSel(HWND hwnd
, WORD wIndex
)
1131 LPLISTSTRUCT lpls
, lpls2
;
1133 lphl
= ListBoxGetStorageHeader(hwnd
);
1134 if (lphl
== NULL
) return LB_ERR
;
1135 if (wIndex
>= lphl
->ItemsCount
) return LB_ERR
;
1136 lpls
= lphl
->lpFirst
;
1137 if (lpls
== NULL
) return LB_ERR
;
1138 for(i
= 0; i
< lphl
->ItemsCount
; i
++) {
1140 lpls
= (LPLISTSTRUCT
)lpls
->lpNext
;
1142 return lpls2
->dis
.itemState
;
1144 if (lpls
== NULL
) break;
1150 int ListBoxDirectory(HWND hwnd
, UINT attrib
, LPSTR filespec
)
1152 struct dosdirent
*dp
;
1157 dprintf_listbox(stddeb
,"ListBoxDirectory: %s, %4x\n",filespec
,attrib
);
1158 lphl
= ListBoxGetStorageHeader(hwnd
);
1159 if (lphl
== NULL
) return LB_ERR
;
1160 if ((dp
= (struct dosdirent
*)DOS_opendir(filespec
)) ==NULL
) return 0;
1161 OldFlag
= lphl
->bRedrawFlag
;
1162 lphl
->bRedrawFlag
= FALSE
;
1163 while ((dp
= (struct dosdirent
*)DOS_readdir(dp
))) {
1164 if (!dp
->inuse
) break;
1165 dprintf_listbox(stddeb
,"ListBoxDirectory %p '%s' !\n", dp
->filename
, dp
->filename
);
1166 if (dp
->attribute
& FA_DIREC
) {
1167 if (attrib
& DDL_DIRECTORY
&&
1168 strcmp(dp
->filename
, ".")) {
1169 sprintf(temp
, "[%s]", dp
->filename
);
1170 if ( (wRet
= ListBoxAddString(hwnd
, temp
)) == LB_ERR
) break;
1174 if (attrib
& DDL_EXCLUSIVE
) {
1175 if (attrib
& (DDL_READWRITE
| DDL_READONLY
| DDL_HIDDEN
|
1177 if ( (wRet
= ListBoxAddString(hwnd
, dp
->filename
))
1181 if ( (wRet
= ListBoxAddString(hwnd
, dp
->filename
))
1188 if (attrib
& DDL_DRIVES
) {
1189 for (x
=0;x
!=MAX_DOS_DRIVES
;x
++) {
1190 if (DOS_ValidDrive(x
)) {
1191 sprintf(temp
, "[-%c-]", 'a'+x
);
1192 if ( (wRet
= ListBoxAddString(hwnd
, temp
)) == LB_ERR
) break;
1196 lphl
->bRedrawFlag
= OldFlag
;
1198 InvalidateRect(hwnd
, NULL
, TRUE
);
1201 dprintf_listbox(stddeb
,"End of ListBoxDirectory !\n");
1206 int ListBoxGetItemRect(HWND hwnd
, WORD wIndex
, LPRECT lprect
)
1209 LPLISTSTRUCT lpls
, lpls2
;
1211 lphl
= ListBoxGetStorageHeader(hwnd
);
1212 if (lphl
== NULL
) return LB_ERR
;
1213 if (wIndex
> lphl
->ItemsCount
) return LB_ERR
;
1214 lpls
= lphl
->lpFirst
;
1215 if (lpls
== NULL
) return LB_ERR
;
1216 for(i
= 0; i
< lphl
->ItemsCount
; i
++) {
1218 lpls
= (LPLISTSTRUCT
)lpls
->lpNext
;
1220 *(lprect
) = lpls2
->dis
.rcItem
;
1223 if (lpls
== NULL
) break;
1230 int ListBoxSetItemHeight(HWND hwnd
, WORD wIndex
, long height
)
1233 LPLISTSTRUCT lpls
, lpls2
;
1235 lphl
= ListBoxGetStorageHeader(hwnd
);
1236 if (lphl
== NULL
) return LB_ERR
;
1237 if (wIndex
> lphl
->ItemsCount
) return LB_ERR
;
1238 lpls
= lphl
->lpFirst
;
1239 if (lpls
== NULL
) return LB_ERR
;
1240 for(i
= 0; i
< lphl
->ItemsCount
; i
++) {
1242 lpls
= (LPLISTSTRUCT
)lpls
->lpNext
;
1244 lpls2
->dis
.rcItem
.bottom
= lpls2
->dis
.rcItem
.top
+ (short)height
;
1245 InvalidateRect(hwnd
, NULL
, TRUE
);
1249 if (lpls
== NULL
) break;
1258 int ListBoxDefaultItem(HWND hwnd
, WND
*wndPtr
,
1259 LPHEADLIST lphl
, LPLISTSTRUCT lpls
)
1262 if (wndPtr
== NULL
|| lphl
== NULL
|| lpls
== NULL
) {
1263 fprintf(stderr
,"ListBoxDefaultItem() // Bad Pointers !\n");
1266 GetClientRect(hwnd
, &rect
);
1267 SetRect(&lpls
->dis
.rcItem
, 0, 0, rect
.right
, lphl
->StdItemHeight
);
1268 lpls
->dis
.CtlType
= lphl
->DrawCtlType
;
1269 lpls
->dis
.CtlID
= wndPtr
->wIDmenu
;
1270 lpls
->dis
.itemID
= 0;
1271 lpls
->dis
.itemAction
= 0;
1272 lpls
->dis
.itemState
= 0;
1273 lpls
->dis
.hwndItem
= hwnd
;
1275 lpls
->dis
.itemData
= 0;
1281 int ListBoxFindNextMatch(HWND hwnd
, WORD wChar
)
1287 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
1288 if (lphl
== NULL
) return LB_ERR
;
1289 lpls
= lphl
->lpFirst
;
1290 if (lpls
== NULL
) return LB_ERR
;
1291 if (wChar
< ' ') return LB_ERR
;
1292 if (((wndPtr
->dwStyle
& LBS_OWNERDRAWFIXED
) == LBS_OWNERDRAWFIXED
) ||
1293 ((wndPtr
->dwStyle
& LBS_OWNERDRAWVARIABLE
) == LBS_OWNERDRAWVARIABLE
)) {
1294 if ((wndPtr
->dwStyle
& LBS_HASSTRINGS
) != LBS_HASSTRINGS
) {
1299 while(lpls
!= NULL
) {
1300 if (Count
> lphl
->ItemFocused
) {
1301 if (*(lpls
->itemText
) == (char)wChar
) {
1302 lphl
->FirstVisible
= Count
- lphl
->ItemsVisible
/ 2;
1303 if (lphl
->FirstVisible
< 1) lphl
->FirstVisible
= 1;
1304 if ((wndPtr
->dwStyle
& LBS_MULTIPLESEL
) == LBS_MULTIPLESEL
) {
1305 lphl
->ItemFocused
= Count
;
1308 ListBoxSetCurSel(hwnd
, Count
);
1310 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
1311 InvalidateRect(hwnd
, NULL
, TRUE
);
1316 lpls
= (LPLISTSTRUCT
)lpls
->lpNext
;
1320 lpls
= lphl
->lpFirst
;
1321 while(lpls
!= NULL
) {
1322 if (*(lpls
->itemText
) == (char)wChar
) {
1323 if (Count
== lphl
->ItemFocused
) return LB_ERR
;
1324 lphl
->FirstVisible
= Count
- lphl
->ItemsVisible
/ 2;
1325 if (lphl
->FirstVisible
< 1) lphl
->FirstVisible
= 1;
1326 if ((wndPtr
->dwStyle
& LBS_MULTIPLESEL
) == LBS_MULTIPLESEL
) {
1327 lphl
->ItemFocused
= Count
;
1330 ListBoxSetCurSel(hwnd
, Count
);
1332 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
1333 InvalidateRect(hwnd
, NULL
, TRUE
);
1337 lpls
= (LPLISTSTRUCT
)lpls
->lpNext
;
1344 /************************************************************************
1345 * DlgDirSelect [USER.99]
1347 BOOL
DlgDirSelect(HWND hDlg
, LPSTR lpStr
, int nIDLBox
)
1349 fprintf(stdnimp
,"DlgDirSelect(%04X, '%s', %d) \n", hDlg
, lpStr
, nIDLBox
);
1354 /************************************************************************
1355 * DlgDirList [USER.100]
1357 int DlgDirList(HWND hDlg
, LPSTR lpPathSpec
,
1358 int nIDLBox
, int nIDStat
, WORD wType
)
1362 dprintf_listbox(stddeb
,"DlgDirList(%04X, '%s', %d, %d, %04X) \n",
1363 hDlg
, lpPathSpec
, nIDLBox
, nIDStat
, wType
);
1365 hWnd
= GetDlgItem(hDlg
, nIDLBox
);
1369 ListBoxResetContent(hWnd
);
1371 ret
=ListBoxDirectory(hWnd
, wType
, lpPathSpec
);
1377 drive
= DOS_GetDefaultDrive();
1378 SendDlgItemMessage(hDlg
, nIDStat
, WM_SETTEXT
, 0,
1379 (LONG
) DOS_GetCurrentDir(drive
) );
1384 /* get the maximum value of lphl->FirstVisible */
1385 int ListMaxFirstVisible(LPHEADLIST lphl
)
1387 int m
= lphl
->ItemsCount
-lphl
->ItemsVisible
+1;
1388 return (m
< 1) ? 1 : m
;