2 * Interface code to listbox widgets
4 * Copyright Martin Ayotte, 1993
6 static char Copyright[] = "Copyright Martin Ayotte, 1993";
11 #include <sys/types.h>
23 #define GMEM_ZEROINIT 0x0040
26 LPHEADLIST
ListBoxGetWindowAndStorage(HWND hwnd
, WND
**wndPtr
);
27 LPHEADLIST
ListBoxGetStorageHeader(HWND hwnd
);
28 void StdDrawListBox(HWND hwnd
);
29 void OwnerDrawListBox(HWND hwnd
);
30 int ListBoxFindMouse(HWND hwnd
, int X
, int Y
);
31 int CreateListBoxStruct(HWND hwnd
);
32 void ListBoxAskMeasure(WND
*wndPtr
, LPHEADLIST lphl
, LPLISTSTRUCT lpls
);
33 int ListBoxAddString(HWND hwnd
, LPSTR newstr
);
34 int ListBoxInsertString(HWND hwnd
, UINT uIndex
, LPSTR newstr
);
35 int ListBoxGetText(HWND hwnd
, UINT uIndex
, LPSTR OutStr
, BOOL bItemData
);
36 int ListBoxSetItemData(HWND hwnd
, UINT uIndex
, DWORD ItemData
);
37 int ListBoxDeleteString(HWND hwnd
, UINT uIndex
);
38 int ListBoxFindString(HWND hwnd
, UINT nFirst
, LPSTR MatchStr
);
39 int ListBoxResetContent(HWND hwnd
);
40 int ListBoxSetCurSel(HWND hwnd
, WORD wIndex
);
41 int ListBoxSetSel(HWND hwnd
, WORD wIndex
, WORD state
);
42 int ListBoxGetSel(HWND hwnd
, WORD wIndex
);
43 int ListBoxDirectory(HWND hwnd
, UINT attrib
, LPSTR filespec
);
44 int ListBoxGetItemRect(HWND hwnd
, WORD wIndex
, LPRECT rect
);
45 int ListBoxSetItemHeight(HWND hwnd
, WORD wIndex
, long height
);
46 int ListBoxDefaultItem(HWND hwnd
, WND
*wndPtr
,
47 LPHEADLIST lphl
, LPLISTSTRUCT lpls
);
48 int ListBoxFindNextMatch(HWND hwnd
, WORD wChar
);
49 int ListMaxFirstVisible(LPHEADLIST lphl
);
51 #define HasStrings(wndPtr) ( \
52 ( ((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) != LBS_OWNERDRAWFIXED) && \
53 ((wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE) != LBS_OWNERDRAWVARIABLE) ) || \
54 ((wndPtr->dwStyle & LBS_HASSTRINGS) == LBS_HASSTRINGS) )
56 #define LIST_HEAP_ALLOC(lphl,f,size) ((int)HEAP_Alloc(&lphl->Heap,f,size) & 0xffff)
57 #define LIST_HEAP_FREE(lphl,handle) (HEAP_Free(&lphl->Heap,LIST_HEAP_ADDR(lphl,handle)))
58 #define LIST_HEAP_ADDR(lphl,handle) \
59 ((void *)((handle) ? ((handle) | ((int)lphl->Heap & 0xffff0000)) : 0))
60 #define LIST_HEAP_SIZE 0x10000
62 /***********************************************************************
65 LONG
ListBoxWndProc( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
74 CREATESTRUCT
*createStruct
;
78 CreateListBoxStruct(hwnd
);
79 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
80 dprintf_listbox(stddeb
,"ListBox WM_CREATE %p !\n", lphl
);
81 if (lphl
== NULL
) return 0;
82 createStruct
= (CREATESTRUCT
*)lParam
;
83 if (HIWORD(createStruct
->lpCreateParams
) != 0)
84 lphl
->hWndLogicParent
= (HWND
)HIWORD(createStruct
->lpCreateParams
);
86 lphl
->hWndLogicParent
= GetParent(hwnd
);
87 lphl
->hFont
= GetStockObject(SYSTEM_FONT
);
88 lphl
->ColumnsWidth
= wndPtr
->rectClient
.right
- wndPtr
->rectClient
.left
;
89 SetScrollRange(hwnd
, SB_VERT
, 1, ListMaxFirstVisible(lphl
), TRUE
);
90 SetScrollRange(hwnd
, SB_HORZ
, 1, 1, TRUE
);
91 if ((wndPtr
->dwStyle
& LBS_OWNERDRAWFIXED
) == LBS_OWNERDRAWFIXED
) {
95 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
96 if (lphl
== NULL
) return 0;
97 ListBoxResetContent(hwnd
);
98 /* XXX need to free lphl->Heap */
100 *((LPHEADLIST
*)&wndPtr
->wExtra
[1]) = 0;
101 dprintf_listbox(stddeb
,"ListBox WM_DESTROY %p !\n", lphl
);
105 dprintf_listbox(stddeb
,"ListBox WM_VSCROLL w=%04X l=%08lX !\n",
107 lphl
= ListBoxGetStorageHeader(hwnd
);
108 if (lphl
== NULL
) return 0;
109 y
= lphl
->FirstVisible
;
112 if (lphl
->FirstVisible
> 1)
113 lphl
->FirstVisible
--;
116 if (lphl
->FirstVisible
< ListMaxFirstVisible(lphl
))
117 lphl
->FirstVisible
++;
120 if (lphl
->FirstVisible
> 1)
121 lphl
->FirstVisible
-= lphl
->ItemsVisible
;
124 if (lphl
->FirstVisible
< ListMaxFirstVisible(lphl
))
125 lphl
->FirstVisible
+= lphl
->ItemsVisible
;
128 lphl
->FirstVisible
= LOWORD(lParam
);
131 if (lphl
->FirstVisible
< 1) lphl
->FirstVisible
= 1;
132 if (lphl
->FirstVisible
> ListMaxFirstVisible(lphl
))
133 lphl
->FirstVisible
= ListMaxFirstVisible(lphl
);
134 if (y
!= lphl
->FirstVisible
) {
135 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
136 InvalidateRect(hwnd
, NULL
, TRUE
);
142 dprintf_listbox(stddeb
,"ListBox WM_HSCROLL w=%04X l=%08lX !\n",
144 lphl
= ListBoxGetStorageHeader(hwnd
);
145 if (lphl
== NULL
) return 0;
146 y
= lphl
->FirstVisible
;
149 if (lphl
->FirstVisible
> 1)
150 lphl
->FirstVisible
-= lphl
->ItemsPerColumn
;
153 if (lphl
->FirstVisible
< ListMaxFirstVisible(lphl
))
154 lphl
->FirstVisible
+= lphl
->ItemsPerColumn
;
157 if (lphl
->FirstVisible
> 1 && lphl
->ItemsPerColumn
!= 0)
158 lphl
->FirstVisible
-= lphl
->ItemsVisible
/
159 lphl
->ItemsPerColumn
* lphl
->ItemsPerColumn
;
162 if (lphl
->FirstVisible
< ListMaxFirstVisible(lphl
) &&
163 lphl
->ItemsPerColumn
!= 0)
164 lphl
->FirstVisible
+= lphl
->ItemsVisible
/
165 lphl
->ItemsPerColumn
* lphl
->ItemsPerColumn
;
168 lphl
->FirstVisible
= lphl
->ItemsPerColumn
*
169 (LOWORD(lParam
) - 1) + 1;
172 if (lphl
->FirstVisible
< 1) lphl
->FirstVisible
= 1;
173 if (lphl
->FirstVisible
> ListMaxFirstVisible(lphl
))
174 lphl
->FirstVisible
= ListMaxFirstVisible(lphl
);
175 if (lphl
->ItemsPerColumn
!= 0) {
176 lphl
->FirstVisible
= lphl
->FirstVisible
/
177 lphl
->ItemsPerColumn
* lphl
->ItemsPerColumn
+ 1;
178 if (y
!= lphl
->FirstVisible
) {
179 SetScrollPos(hwnd
, SB_HORZ
, lphl
->FirstVisible
/
180 lphl
->ItemsPerColumn
+ 1, TRUE
);
181 InvalidateRect(hwnd
, NULL
, TRUE
);
190 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
191 if (lphl
== NULL
) return 0;
192 lphl
->PrevFocused
= lphl
->ItemFocused
;
193 y
= ListBoxFindMouse(hwnd
, LOWORD(lParam
), HIWORD(lParam
));
196 if ((wndPtr
->dwStyle
& LBS_MULTIPLESEL
) == LBS_MULTIPLESEL
) {
197 lphl
->ItemFocused
= y
;
198 wRet
= ListBoxGetSel(hwnd
, y
);
199 ListBoxSetSel(hwnd
, y
, !wRet
);
202 ListBoxSetCurSel(hwnd
, y
);
203 if ((wndPtr
->dwStyle
&& LBS_NOTIFY
) != 0)
204 SendMessage(lphl
->hWndLogicParent
, WM_COMMAND
,
205 wndPtr
->wIDmenu
, MAKELONG(hwnd
, LBN_SELCHANGE
));
207 ListBoxGetItemRect(hwnd
, y
, &rectsel
);
208 InvalidateRect(hwnd
, NULL
, TRUE
);
213 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
214 if (lphl
== NULL
) return 0;
215 if (lphl
->PrevFocused
!= lphl
->ItemFocused
)
216 SendMessage(lphl
->hWndLogicParent
, WM_COMMAND
, wndPtr
->wIDmenu
,
217 MAKELONG(hwnd
, LBN_SELCHANGE
));
220 case WM_LBUTTONDBLCLK
:
221 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
222 if (lphl
== NULL
) return 0;
223 SendMessage(lphl
->hWndLogicParent
, WM_COMMAND
, wndPtr
->wIDmenu
,
224 MAKELONG(hwnd
, LBN_DBLCLK
));
227 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
228 if (lphl
== NULL
) return 0;
229 if ((wParam
& MK_LBUTTON
) != 0) {
232 if (lphl
->FirstVisible
> 1) {
233 lphl
->FirstVisible
--;
234 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
235 InvalidateRect(hwnd
, NULL
, TRUE
);
240 GetClientRect(hwnd
, &rect
);
241 if (y
> (rect
.bottom
- 4)) {
242 if (lphl
->FirstVisible
< ListMaxFirstVisible(lphl
)) {
243 lphl
->FirstVisible
++;
244 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
245 InvalidateRect(hwnd
, NULL
, TRUE
);
250 if ((y
> 0) && (y
< (rect
.bottom
- 4))) {
251 if ((y
< rectsel
.top
) || (y
> rectsel
.bottom
)) {
252 wRet
= ListBoxFindMouse(hwnd
, LOWORD(lParam
), HIWORD(lParam
));
253 if ((wndPtr
->dwStyle
& LBS_MULTIPLESEL
) == LBS_MULTIPLESEL
) {
254 lphl
->ItemFocused
= wRet
;
257 ListBoxSetCurSel(hwnd
, wRet
);
258 if ((wndPtr
->dwStyle
&& LBS_NOTIFY
) != 0)
259 SendMessage(lphl
->hWndLogicParent
, WM_COMMAND
,
260 wndPtr
->wIDmenu
, MAKELONG(hwnd
, LBN_SELCHANGE
));
262 ListBoxGetItemRect(hwnd
, wRet
, &rectsel
);
263 InvalidateRect(hwnd
, NULL
, TRUE
);
270 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
271 if (lphl
== NULL
) return 0;
274 hWndCtl
= GetNextDlgTabItem(lphl
->hWndLogicParent
,
275 hwnd
, !(GetKeyState(VK_SHIFT
) < 0));
277 if(debugging_listbox
){
278 if ((GetKeyState(VK_SHIFT
) < 0))
279 dprintf_listbox(stddeb
,"ListBox PreviousDlgTabItem %04X !\n", hWndCtl
);
281 dprintf_listbox(stddeb
,"ListBox NextDlgTabItem %04X !\n", hWndCtl
);
285 lphl
->ItemFocused
= 0;
288 lphl
->ItemFocused
= lphl
->ItemsCount
- 1;
291 if ((wndPtr
->dwStyle
& LBS_MULTICOLUMN
) == LBS_MULTICOLUMN
) {
292 lphl
->ItemFocused
-= lphl
->ItemsPerColumn
;
299 if ((wndPtr
->dwStyle
& LBS_MULTICOLUMN
) == LBS_MULTICOLUMN
) {
300 lphl
->ItemFocused
+= lphl
->ItemsPerColumn
;
307 lphl
->ItemFocused
-= lphl
->ItemsVisible
;
310 lphl
->ItemFocused
+= lphl
->ItemsVisible
;
313 wRet
= ListBoxGetSel(hwnd
, lphl
->ItemFocused
);
314 ListBoxSetSel(hwnd
, lphl
->ItemFocused
, !wRet
);
317 ListBoxFindNextMatch(hwnd
, wParam
);
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
);
328 if ((wndPtr
->dwStyle
&& LBS_NOTIFY
) != 0)
329 SendMessage(lphl
->hWndLogicParent
, WM_COMMAND
,
330 wndPtr
->wIDmenu
, MAKELONG(hwnd
, LBN_SELCHANGE
));
332 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
333 InvalidateRect(hwnd
, NULL
, TRUE
);
337 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
338 if (lphl
== NULL
) return 0;
340 lphl
->hFont
= GetStockObject(SYSTEM_FONT
);
342 lphl
->hFont
= wParam
;
343 if (wParam
== 0) break;
346 dprintf_listbox(stddeb
,"ListBox WM_SETREDRAW hWnd=%04X w=%04X !\n", hwnd
, wParam
);
347 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
348 if (lphl
== NULL
) return 0;
349 lphl
->bRedrawFlag
= wParam
;
352 wndPtr
= WIN_FindWndPtr(hwnd
);
353 if ((wndPtr
->dwStyle
& LBS_OWNERDRAWFIXED
) == LBS_OWNERDRAWFIXED
) {
354 OwnerDrawListBox(hwnd
);
357 if ((wndPtr
->dwStyle
& LBS_OWNERDRAWVARIABLE
) == LBS_OWNERDRAWVARIABLE
) {
358 OwnerDrawListBox(hwnd
);
361 StdDrawListBox(hwnd
);
364 dprintf_listbox(stddeb
,"ListBox WM_SETFOCUS !\n");
365 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
368 dprintf_listbox(stddeb
,"ListBox WM_KILLFOCUS !\n");
369 InvalidateRect(hwnd
, NULL
, TRUE
);
373 case LB_RESETCONTENT
:
374 dprintf_listbox(stddeb
,"ListBox LB_RESETCONTENT !\n");
375 ListBoxResetContent(hwnd
);
378 dprintf_listbox(stddeb
,"ListBox LB_DIR !\n");
379 wRet
= ListBoxDirectory(hwnd
, wParam
, (LPSTR
)lParam
);
380 InvalidateRect(hwnd
, NULL
, TRUE
);
384 wRet
= ListBoxAddString(hwnd
, (LPSTR
)lParam
);
387 dprintf_listbox(stddeb
, "LB_GETTEXT wParam=%d\n",wParam
);
388 wRet
= ListBoxGetText(hwnd
, wParam
, (LPSTR
)lParam
, FALSE
);
390 case LB_INSERTSTRING
:
391 wRet
= ListBoxInsertString(hwnd
, wParam
, (LPSTR
)lParam
);
393 case LB_DELETESTRING
:
394 wRet
= ListBoxDeleteString(hwnd
, wParam
);
397 wRet
= ListBoxFindString(hwnd
, wParam
, (LPSTR
)lParam
);
399 case LB_GETCARETINDEX
:
402 lphl
= ListBoxGetStorageHeader(hwnd
);
403 return lphl
->ItemsCount
;
405 lphl
= ListBoxGetStorageHeader(hwnd
);
406 dprintf_listbox(stddeb
,"ListBox LB_GETCURSEL %u !\n",
408 return lphl
->ItemFocused
;
409 case LB_GETHORIZONTALEXTENT
:
412 dprintf_listbox(stddeb
, "LB_GETITEMDATA wParam=%x\n", wParam
);
413 lRet
= ListBoxGetText(hwnd
, wParam
, (LPSTR
)lParam
, TRUE
);
415 case LB_GETITEMHEIGHT
:
416 ListBoxGetItemRect(hwnd
, wParam
, &rect
);
417 return (rect
.bottom
- rect
.top
);
419 ListBoxGetItemRect(hwnd
, wParam
, (LPRECT
)lParam
);
422 wRet
= ListBoxGetSel(hwnd
, wParam
);
425 lphl
= ListBoxGetStorageHeader(hwnd
);
426 if (lphl
== NULL
) return LB_ERR
;
427 return lphl
->SelCount
;
433 lphl
= ListBoxGetStorageHeader(hwnd
);
434 if (lphl
== NULL
) return LB_ERR
;
435 return lphl
->FirstVisible
;
436 case LB_SELECTSTRING
:
438 case LB_SELITEMRANGE
:
440 case LB_SETCARETINDEX
:
442 case LB_SETCOLUMNWIDTH
:
443 lphl
= ListBoxGetStorageHeader(hwnd
);
444 if (lphl
== NULL
) return LB_ERR
;
445 lphl
->ColumnsWidth
= wParam
;
447 case LB_SETHORIZONTALEXTENT
:
450 dprintf_listbox(stddeb
, "LB_SETITEMDATA wParam=%x lParam=%lx\n", wParam
, lParam
);
451 wRet
= ListBoxSetItemData(hwnd
, wParam
, lParam
);
454 lphl
= ListBoxGetStorageHeader(hwnd
);
455 if (lphl
== NULL
) return LB_ERR
;
456 lphl
->FirstVisible
= wParam
;
459 dprintf_listbox(stddeb
,"ListBox LB_SETCURSEL wParam=%x !\n",
461 wRet
= ListBoxSetCurSel(hwnd
, wParam
);
462 InvalidateRect(hwnd
, NULL
, TRUE
);
466 dprintf_listbox(stddeb
,"ListBox LB_SETSEL wParam=%x lParam=%lX !\n", wParam
, lParam
);
467 wRet
= ListBoxSetSel(hwnd
, LOWORD(lParam
), wParam
);
468 InvalidateRect(hwnd
, NULL
, TRUE
);
472 dprintf_listbox(stddeb
,"ListBox LB_SETTOPINDEX wParam=%x !\n",
474 lphl
= ListBoxGetStorageHeader(hwnd
);
475 lphl
->FirstVisible
= wParam
;
476 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
477 InvalidateRect(hwnd
, NULL
, TRUE
);
480 case LB_SETITEMHEIGHT
:
481 dprintf_listbox(stddeb
,"ListBox LB_SETITEMHEIGHT wParam=%x lParam=%lX !\n", wParam
, lParam
);
482 wRet
= ListBoxSetItemHeight(hwnd
, wParam
, lParam
);
486 return DefWindowProc( hwnd
, message
, wParam
, lParam
);
492 LPHEADLIST
ListBoxGetWindowAndStorage(HWND hwnd
, WND
**wndPtr
)
496 *(wndPtr
) = Ptr
= WIN_FindWndPtr(hwnd
);
497 lphl
= *((LPHEADLIST
*)&Ptr
->wExtra
[1]);
502 LPHEADLIST
ListBoxGetStorageHeader(HWND hwnd
)
506 wndPtr
= WIN_FindWndPtr(hwnd
);
507 lphl
= *((LPHEADLIST
*)&wndPtr
->wExtra
[1]);
512 void StdDrawListBox(HWND hwnd
)
520 DWORD dwOldTextColor
;
523 int i
, h
, h2
, maxwidth
, ipc
;
525 hdc
= BeginPaint( hwnd
, &ps
);
526 if (!IsWindowVisible(hwnd
)) {
527 EndPaint( hwnd
, &ps
);
530 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
531 if (lphl
== NULL
) goto EndOfPaint
;
532 if (!lphl
->bRedrawFlag
) goto EndOfPaint
;
533 SelectObject(hdc
, lphl
->hFont
);
534 hBrush
= SendMessage(lphl
->hWndLogicParent
, WM_CTLCOLOR
, (WORD
)hdc
,
535 MAKELONG(hwnd
, CTLCOLOR_LISTBOX
));
536 if (hBrush
== (HBRUSH
)NULL
) hBrush
= GetStockObject(WHITE_BRUSH
);
537 GetClientRect(hwnd
, &rect
);
538 FillRect(hdc
, &rect
, hBrush
);
539 maxwidth
= rect
.right
;
540 rect
.right
= lphl
->ColumnsWidth
;
541 if (lphl
->ItemsCount
== 0) goto EndOfPaint
;
542 lpls
= lphl
->lpFirst
;
543 if (lpls
== NULL
) goto EndOfPaint
;
544 lphl
->ItemsVisible
= 0;
545 lphl
->ItemsPerColumn
= ipc
= 0;
546 for(i
= 1; i
<= lphl
->ItemsCount
; i
++) {
547 if (i
>= lphl
->FirstVisible
) {
548 if (lpls
== NULL
) break;
549 if ((h
+ lpls
->dis
.rcItem
.bottom
- lpls
->dis
.rcItem
.top
) > rect
.bottom
) {
550 if ((wndPtr
->dwStyle
& LBS_MULTICOLUMN
) == LBS_MULTICOLUMN
) {
551 lphl
->ItemsPerColumn
= max(lphl
->ItemsPerColumn
, ipc
);
554 rect
.left
+= lphl
->ColumnsWidth
;
555 rect
.right
+= lphl
->ColumnsWidth
;
556 if (rect
.left
> maxwidth
) break;
561 h2
= lpls
->dis
.rcItem
.bottom
- lpls
->dis
.rcItem
.top
;
562 lpls
->dis
.rcItem
.top
= h
;
563 lpls
->dis
.rcItem
.bottom
= h
+ h2
;
564 lpls
->dis
.rcItem
.left
= rect
.left
;
565 lpls
->dis
.rcItem
.right
= rect
.right
;
566 OldBkMode
= SetBkMode(hdc
, TRANSPARENT
);
567 if (lpls
->dis
.itemState
!= 0) {
568 dwOldTextColor
= SetTextColor(hdc
, 0x00FFFFFFL
);
569 FillRect(hdc
, &lpls
->dis
.rcItem
, GetStockObject(BLACK_BRUSH
));
571 TextOut(hdc
, rect
.left
+ 5, h
+ 2, (char *)lpls
->itemText
,
572 strlen((char *)lpls
->itemText
));
573 if (lpls
->dis
.itemState
!= 0) {
574 SetTextColor(hdc
, dwOldTextColor
);
576 SetBkMode(hdc
, OldBkMode
);
577 if ((lphl
->ItemFocused
== i
- 1) && GetFocus() == hwnd
) {
578 DrawFocusRect(hdc
, &lpls
->dis
.rcItem
);
581 lphl
->ItemsVisible
++;
584 if (lpls
->lpNext
== NULL
) goto EndOfPaint
;
585 lpls
= (LPLISTSTRUCT
)lpls
->lpNext
;
588 EndPaint( hwnd
, &ps
);
593 void OwnerDrawListBox(HWND hwnd
)
595 WND
*wndPtr
,*ParentWndPtr
;
604 int i
, h
, h2
, maxwidth
;
606 hdc
= BeginPaint(hwnd
, &ps
);
607 if (!IsWindowVisible(hwnd
)) {
608 EndPaint( hwnd
, &ps
);
611 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
612 if (lphl
== NULL
) goto EndOfPaint
;
613 if (!lphl
->bRedrawFlag
) goto EndOfPaint
;
614 hBrush
= SendMessage(lphl
->hWndLogicParent
, WM_CTLCOLOR
, (WORD
)hdc
,
615 MAKELONG(hwnd
, CTLCOLOR_LISTBOX
));
616 if (hBrush
== (HBRUSH
)NULL
) hBrush
= GetStockObject(WHITE_BRUSH
);
617 GetClientRect(hwnd
, &rect
);
618 FillRect(hdc
, &rect
, hBrush
);
619 maxwidth
= rect
.right
;
620 rect
.right
= lphl
->ColumnsWidth
;
621 if (lphl
->ItemsCount
== 0) goto EndOfPaint
;
622 lpls
= lphl
->lpFirst
;
623 if (lpls
== NULL
) goto EndOfPaint
;
624 lphl
->ItemsVisible
= 0;
625 for (i
= 1; i
<= lphl
->ItemsCount
; i
++) {
626 if (i
>= lphl
->FirstVisible
) {
628 lpls
->dis
.hwndItem
= hwnd
;
629 lpls
->dis
.CtlType
= ODT_LISTBOX
;
630 lpls
->dis
.itemID
= i
- 1;
631 if ((!lpls
->dis
.CtlID
) && (lphl
->hWndLogicParent
)) {
632 ParentWndPtr
= WIN_FindWndPtr(lphl
->hWndLogicParent
);
633 lpls
->dis
.CtlID
= ParentWndPtr
->wIDmenu
;
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 dprintf_listbox(stddeb
,"LBOX WM_DRAWITEM #%d left=%d top=%d right=%d bottom=%d !\n",
648 i
-1, lpls
->dis
.rcItem
.left
, lpls
->dis
.rcItem
.top
,
649 lpls
->dis
.rcItem
.right
, lpls
->dis
.rcItem
.bottom
);
650 dprintf_listbox(stddeb
,"LBOX WM_DRAWITEM Parent=%X &dis=%lX CtlID=%u !\n",
651 hWndParent
, (LONG
)&lpls
->dis
, lpls
->dis
.CtlID
);
652 dprintf_listbox(stddeb
,"LBOX WM_DRAWITEM %08lX!\n",lpls
->dis
.itemData
);
653 if (HasStrings(wndPtr
))
654 dprintf_listbox(stddeb
," '%s'\n",lpls
->itemText
);
655 if (HasStrings(wndPtr
)) {
656 itemData
= lpls
->dis
.itemData
;
657 lpls
->dis
.itemData
= (DWORD
)lpls
->itemText
;
659 SendMessage(lphl
->hWndLogicParent
, WM_DRAWITEM
,
660 i
-1, (LPARAM
)&lpls
->dis
);
661 if (HasStrings(wndPtr
))
662 lpls
->dis
.itemData
= itemData
;
664 /* if (lpls->dis.itemState != 0) {
665 InvertRect(hdc, &lpls->dis.rcItem);
668 lphl
->ItemsVisible
++;
669 /* if (h > rect.bottom) goto EndOfPaint;*/
671 if (lpls
->lpNext
== NULL
) goto EndOfPaint
;
672 lpls
= (LPLISTSTRUCT
)lpls
->lpNext
;
675 EndPaint( hwnd
, &ps
);
680 int ListBoxFindMouse(HWND hwnd
, int X
, int Y
)
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
);
694 w
= lphl
->ColumnsWidth
;
695 for(i
= 1; i
<= lphl
->ItemsCount
; i
++) {
696 if (i
>= lphl
->FirstVisible
) {
698 h
+= lpls
->dis
.rcItem
.bottom
- lpls
->dis
.rcItem
.top
;
699 if ((Y
> h2
) && (Y
< h
) &&
700 (X
> w2
) && (X
< w
)) return(i
- 1);
701 if (h
> rect
.bottom
) {
702 if ((wndPtr
->dwStyle
& LBS_MULTICOLUMN
) != LBS_MULTICOLUMN
) return LB_ERR
;
705 w
+= lphl
->ColumnsWidth
;
706 if (w2
> rect
.right
) return LB_ERR
;
709 if (lpls
->lpNext
== NULL
) return LB_ERR
;
710 lpls
= (LPLISTSTRUCT
)lpls
->lpNext
;
717 int CreateListBoxStruct(HWND hwnd
)
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
->ColumnsVisible
= 1;
731 lphl
->ItemsPerColumn
= 0;
732 lphl
->StdItemHeight
= 15;
733 lphl
->ItemFocused
= 0;
734 lphl
->PrevFocused
= 0;
736 lphl
->DrawCtlType
= ODT_LISTBOX
;
737 lphl
->bRedrawFlag
= TRUE
;
738 HeapHandle
= GlobalAlloc(GMEM_FIXED
, LIST_HEAP_SIZE
);
739 HeapBase
= GlobalLock(HeapHandle
);
740 HEAP_Init(&lphl
->Heap
, HeapBase
, LIST_HEAP_SIZE
);
745 void ListBoxAskMeasure(WND
*wndPtr
, LPHEADLIST lphl
, LPLISTSTRUCT lpls
)
747 MEASUREITEMSTRUCT
*lpmeasure
;
748 HANDLE hTemp
= USER_HEAP_ALLOC(GMEM_MOVEABLE
, sizeof(MEASUREITEMSTRUCT
));
749 lpmeasure
= (MEASUREITEMSTRUCT
*) USER_HEAP_ADDR(hTemp
);
750 if (lpmeasure
== NULL
) {
751 fprintf(stderr
,"ListBoxAskMeasure() // Bad allocation of Measure struct !\n");
754 lpmeasure
->CtlType
= ODT_LISTBOX
;
755 lpmeasure
->CtlID
= wndPtr
->wIDmenu
;
756 lpmeasure
->itemID
= lpls
->dis
.itemID
;
757 lpmeasure
->itemWidth
= wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
;
758 lpmeasure
->itemHeight
= 0;
759 if (HasStrings(wndPtr
))
760 lpmeasure
->itemData
= (DWORD
)lpls
->itemText
;
762 lpmeasure
->itemData
= lpls
->dis
.itemData
;
763 SendMessage(lphl
->hWndLogicParent
, WM_MEASUREITEM
, 0, (DWORD
)lpmeasure
);
764 lpls
->dis
.rcItem
.right
= lpls
->dis
.rcItem
.left
+ lpmeasure
->itemWidth
;
765 lpls
->dis
.rcItem
.bottom
= lpls
->dis
.rcItem
.top
+ lpmeasure
->itemHeight
;
766 USER_HEAP_FREE(hTemp
);
770 int ListBoxAddString(HWND hwnd
, LPSTR newstr
)
773 UINT pos
= (UINT
) -1;
776 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
777 if (lphl
== NULL
) return LB_ERR
;
778 if (HasStrings(wndPtr
) && (wndPtr
->dwStyle
& LBS_SORT
)) {
779 LPLISTSTRUCT lpls
= lphl
->lpFirst
;
780 for (pos
= 0; lpls
; lpls
= lpls
->lpNext
, pos
++)
781 if (strcmp(lpls
->itemText
, newstr
) >= 0)
784 return ListBoxInsertString(hwnd
, pos
, newstr
);
787 int ListBoxInsertString(HWND hwnd
, UINT uIndex
, LPSTR newstr
)
791 LPLISTSTRUCT
*lppls
, lplsnew
;
797 dprintf_listbox(stddeb
,"ListBoxInsertString(%04X, %d, %p);\n",
798 hwnd
, uIndex
, newstr
);
800 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
801 if (lphl
== NULL
) return LB_ERR
;
803 if (uIndex
== (UINT
)-1)
804 uIndex
= lphl
->ItemsCount
;
805 if (uIndex
> lphl
->ItemsCount
) return LB_ERR
;
806 lppls
= (LPLISTSTRUCT
*) &lphl
->lpFirst
;
808 for(Count
= 0; Count
< uIndex
; Count
++) {
809 if (*lppls
== NULL
) return LB_ERR
;
810 lppls
= (LPLISTSTRUCT
*) &(*lppls
)->lpNext
;
813 hItem
= LIST_HEAP_ALLOC(lphl
, GMEM_MOVEABLE
, sizeof(LISTSTRUCT
));
814 lplsnew
= (LPLISTSTRUCT
) LIST_HEAP_ADDR(lphl
, hItem
);
815 if (lplsnew
== NULL
) {
816 printf("ListBoxInsertString() // Bad allocation of new item !\n");
819 ListBoxDefaultItem(hwnd
, wndPtr
, lphl
, lplsnew
);
820 lplsnew
->hMem
= hItem
;
821 lplsnew
->lpNext
= *lppls
;
826 if (HasStrings(wndPtr
)) {
827 hStr
= LIST_HEAP_ALLOC(lphl
, GMEM_MOVEABLE
, strlen(newstr
) + 1);
828 str
= (LPSTR
)LIST_HEAP_ADDR(lphl
, hStr
);
829 if (str
== NULL
) return LB_ERRSPACE
;
832 lplsnew
->itemText
= str
;
833 dprintf_listbox(stddeb
,"ListBoxInsertString // LBS_HASSTRINGS after strcpy '%s'\n", str
);
836 lplsnew
->itemText
= NULL
;
837 lplsnew
->dis
.itemData
= (DWORD
)newstr
;
839 lplsnew
->dis
.itemID
= lphl
->ItemsCount
;
840 lplsnew
->hData
= hStr
;
841 if (((wndPtr
->dwStyle
& LBS_OWNERDRAWVARIABLE
) == LBS_OWNERDRAWVARIABLE
) ||
842 ((wndPtr
->dwStyle
& LBS_OWNERDRAWFIXED
) == LBS_OWNERDRAWFIXED
))
843 ListBoxAskMeasure(wndPtr
, lphl
, lplsnew
);
844 SetScrollRange(hwnd
, SB_VERT
, 1, ListMaxFirstVisible(lphl
),
845 (lphl
->FirstVisible
!= 1 && lphl
->bRedrawFlag
));
846 if (lphl
->ItemsPerColumn
!= 0)
847 SetScrollRange(hwnd
, SB_HORZ
, 1, lphl
->ItemsVisible
/
848 lphl
->ItemsPerColumn
+ 1,
849 (lphl
->FirstVisible
!= 1 && lphl
->bRedrawFlag
));
850 if ((lphl
->FirstVisible
<= uIndex
) &&
851 ((lphl
->FirstVisible
+ lphl
->ItemsVisible
) >= uIndex
)) {
852 InvalidateRect(hwnd
, NULL
, TRUE
);
855 dprintf_listbox(stddeb
,"ListBoxInsertString // count=%d\n", lphl
->ItemsCount
);
860 int ListBoxGetText(HWND hwnd
, UINT uIndex
, LPSTR OutStr
, BOOL bItemData
)
866 if ((!OutStr
)&&(!bItemData
))
867 fprintf(stderr
, "ListBoxGetText // OutStr==NULL\n");
868 if (!bItemData
) *OutStr
=0;
869 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
870 if (lphl
== NULL
) return LB_ERR
;
871 if (uIndex
>= lphl
->ItemsCount
) return LB_ERR
;
872 lpls
= lphl
->lpFirst
;
873 if (lpls
== NULL
) return LB_ERR
;
874 if (uIndex
> lphl
->ItemsCount
) return LB_ERR
;
875 for(Count
= 0; Count
< uIndex
; Count
++) {
876 if (lpls
->lpNext
== NULL
) return LB_ERR
;
877 lpls
= (LPLISTSTRUCT
)lpls
->lpNext
;
880 return lpls
->dis
.itemData
;
881 if (!(HasStrings(wndPtr
)) )
883 *((long *)OutStr
) = lpls
->dis
.itemData
;
887 strcpy(OutStr
, lpls
->itemText
);
888 return strlen(OutStr
);
891 int ListBoxSetItemData(HWND hwnd
, UINT uIndex
, DWORD ItemData
)
897 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
898 if (lphl
== NULL
) return LB_ERR
;
899 if (uIndex
>= lphl
->ItemsCount
) return LB_ERR
;
900 lpls
= lphl
->lpFirst
;
901 if (lpls
== NULL
) return LB_ERR
;
902 if (uIndex
> lphl
->ItemsCount
) return LB_ERR
;
903 for(Count
= 0; Count
< uIndex
; Count
++) {
904 if (lpls
->lpNext
== NULL
) return LB_ERR
;
905 lpls
= (LPLISTSTRUCT
)lpls
->lpNext
;
907 lpls
->dis
.itemData
= ItemData
;
912 int ListBoxDeleteString(HWND hwnd
, UINT uIndex
)
916 LPLISTSTRUCT lpls
, lpls2
;
918 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
919 if (lphl
== NULL
) return LB_ERR
;
920 if (uIndex
>= lphl
->ItemsCount
) return LB_ERR
;
921 lpls
= lphl
->lpFirst
;
922 if (lpls
== NULL
) return LB_ERR
;
923 if (uIndex
> lphl
->ItemsCount
) return LB_ERR
;
924 for(Count
= 1; Count
< uIndex
; Count
++) {
925 if (lpls
->lpNext
== NULL
) return LB_ERR
;
927 lpls
= (LPLISTSTRUCT
)lpls
->lpNext
;
929 lpls2
->lpNext
= (LPLISTSTRUCT
)lpls
->lpNext
;
931 if (lpls
->hData
!= 0) LIST_HEAP_FREE(lphl
, lpls
->hData
);
932 if (lpls
->hMem
!= 0) LIST_HEAP_FREE(lphl
, lpls
->hMem
);
933 SetScrollRange(hwnd
, SB_VERT
, 1, ListMaxFirstVisible(lphl
), TRUE
);
934 if (lphl
->ItemsPerColumn
!= 0)
935 SetScrollRange(hwnd
, SB_HORZ
, 1, lphl
->ItemsVisible
/
936 lphl
->ItemsPerColumn
+ 1, TRUE
);
937 if ((lphl
->FirstVisible
<= uIndex
) &&
938 ((lphl
->FirstVisible
+ lphl
->ItemsVisible
) >= uIndex
)) {
939 InvalidateRect(hwnd
, NULL
, TRUE
);
942 return lphl
->ItemsCount
;
946 int ListBoxFindString(HWND hwnd
, UINT nFirst
, LPSTR MatchStr
)
952 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
953 if (lphl
== NULL
) return LB_ERR
;
954 if (nFirst
> lphl
->ItemsCount
) return LB_ERR
;
955 lpls
= lphl
->lpFirst
;
956 if (lpls
== NULL
) return LB_ERR
;
958 while(lpls
!= NULL
) {
959 if (HasStrings(wndPtr
))
961 if (strcmp(lpls
->itemText
, MatchStr
) == 0) return Count
;
965 if (lpls
->dis
.itemData
== (DWORD
)MatchStr
) return Count
;
967 lpls
= (LPLISTSTRUCT
)lpls
->lpNext
;
974 int ListBoxResetContent(HWND hwnd
)
978 LPLISTSTRUCT lpls
, lpls2
;
980 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
981 if (lphl
== NULL
) return LB_ERR
;
982 lpls
= lphl
->lpFirst
;
983 if (lpls
== NULL
) return LB_ERR
;
984 dprintf_listbox(stddeb
, "ListBoxResetContent // ItemCount = %d\n",
986 for(i
= 0; i
<= lphl
->ItemsCount
; i
++) {
988 lpls
= (LPLISTSTRUCT
)lpls
->lpNext
;
990 dprintf_listbox(stddeb
,"ResetContent #%u\n", i
);
991 if (lpls2
->hData
!= 0 && lpls2
->hData
!= lpls2
->hMem
)
992 LIST_HEAP_FREE(lphl
, lpls2
->hData
);
993 if (lpls2
->hMem
!= 0) LIST_HEAP_FREE(lphl
, lpls2
->hMem
);
995 if (lpls
== NULL
) break;
997 lphl
->lpFirst
= NULL
;
998 lphl
->FirstVisible
= 1;
999 lphl
->ItemsCount
= 0;
1000 lphl
->ItemFocused
= -1;
1001 lphl
->PrevFocused
= -1;
1002 if ((wndPtr
->dwStyle
&& LBS_NOTIFY
) != 0)
1003 SendMessage(lphl
->hWndLogicParent
, WM_COMMAND
,
1004 wndPtr
->wIDmenu
, MAKELONG(hwnd
, LBN_SELCHANGE
));
1005 SetScrollRange(hwnd
, SB_VERT
, 1, ListMaxFirstVisible(lphl
), TRUE
);
1006 if (lphl
->ItemsPerColumn
!= 0)
1007 SetScrollRange(hwnd
, SB_HORZ
, 1, lphl
->ItemsVisible
/
1008 lphl
->ItemsPerColumn
+ 1, TRUE
);
1009 InvalidateRect(hwnd
, NULL
, TRUE
);
1015 int ListBoxSetCurSel(HWND hwnd
, WORD wIndex
)
1019 LPLISTSTRUCT lpls
, lpls2
;
1021 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
1022 if (lphl
== NULL
) return LB_ERR
;
1023 lphl
->ItemFocused
= LB_ERR
;
1024 if (wIndex
>= lphl
->ItemsCount
) return LB_ERR
;
1025 lpls
= lphl
->lpFirst
;
1026 if (lpls
== NULL
) return LB_ERR
;
1027 for(i
= 0; i
< lphl
->ItemsCount
; i
++) {
1029 lpls
= (LPLISTSTRUCT
)lpls
->lpNext
;
1031 lpls2
->dis
.itemState
= 1;
1033 if (lpls2
->dis
.itemState
!= 0)
1034 lpls2
->dis
.itemState
= 0;
1035 if (lpls
== NULL
) break;
1037 lphl
->ItemFocused
= wIndex
;
1038 if ((wndPtr
->dwStyle
&& LBS_NOTIFY
) != 0)
1039 SendMessage(lphl
->hWndLogicParent
, WM_COMMAND
,
1040 wndPtr
->wIDmenu
, MAKELONG(hwnd
, LBN_SELCHANGE
));
1046 int ListBoxSetSel(HWND hwnd
, WORD wIndex
, WORD state
)
1049 LPLISTSTRUCT lpls
, lpls2
;
1051 lphl
= ListBoxGetStorageHeader(hwnd
);
1052 if (lphl
== NULL
) return LB_ERR
;
1053 if (wIndex
>= lphl
->ItemsCount
) return LB_ERR
;
1054 lpls
= lphl
->lpFirst
;
1055 if (lpls
== NULL
) return LB_ERR
;
1056 for(i
= 0; i
< lphl
->ItemsCount
; i
++) {
1058 lpls
= (LPLISTSTRUCT
)lpls
->lpNext
;
1059 if ((i
== wIndex
) || (wIndex
== (WORD
)-1)) {
1060 lpls2
->dis
.itemState
= state
;
1063 if (lpls
== NULL
) break;
1069 int ListBoxGetSel(HWND hwnd
, WORD wIndex
)
1072 LPLISTSTRUCT lpls
, lpls2
;
1074 lphl
= ListBoxGetStorageHeader(hwnd
);
1075 if (lphl
== NULL
) return LB_ERR
;
1076 if (wIndex
>= lphl
->ItemsCount
) return LB_ERR
;
1077 lpls
= lphl
->lpFirst
;
1078 if (lpls
== NULL
) return LB_ERR
;
1079 for(i
= 0; i
< lphl
->ItemsCount
; i
++) {
1081 lpls
= (LPLISTSTRUCT
)lpls
->lpNext
;
1083 return lpls2
->dis
.itemState
;
1085 if (lpls
== NULL
) break;
1091 int ListBoxDirectory(HWND hwnd
, UINT attrib
, LPSTR filespec
)
1093 struct dosdirent
*dp
;
1094 int x
, wRet
= LB_OKAY
;
1098 dprintf_listbox(stddeb
,"ListBoxDirectory: %s, %4x\n",filespec
,attrib
);
1099 lphl
= ListBoxGetStorageHeader(hwnd
);
1100 if (lphl
== NULL
) return LB_ERR
;
1101 if ((dp
= (struct dosdirent
*)DOS_opendir(filespec
)) ==NULL
) return 0;
1102 OldFlag
= lphl
->bRedrawFlag
;
1103 lphl
->bRedrawFlag
= FALSE
;
1104 while ((dp
= (struct dosdirent
*)DOS_readdir(dp
))) {
1105 if (!dp
->inuse
) break;
1106 dprintf_listbox(stddeb
,"ListBoxDirectory %p '%s' !\n", dp
->filename
, dp
->filename
);
1107 if (dp
->attribute
& FA_DIREC
) {
1108 if (attrib
& DDL_DIRECTORY
&&
1109 strcmp(dp
->filename
, ".")) {
1110 sprintf(temp
, "[%s]", dp
->filename
);
1111 if ( (wRet
= ListBoxAddString(hwnd
, temp
)) == LB_ERR
) break;
1115 if (attrib
& DDL_EXCLUSIVE
) {
1116 if (attrib
& (DDL_READWRITE
| DDL_READONLY
| DDL_HIDDEN
|
1118 if ( (wRet
= ListBoxAddString(hwnd
, dp
->filename
))
1122 if ( (wRet
= ListBoxAddString(hwnd
, dp
->filename
))
1129 if (attrib
& DDL_DRIVES
) {
1130 for (x
=0;x
!=MAX_DOS_DRIVES
;x
++) {
1131 if (DOS_ValidDrive(x
)) {
1132 sprintf(temp
, "[-%c-]", 'a'+x
);
1133 if ( (wRet
= ListBoxAddString(hwnd
, temp
)) == LB_ERR
) break;
1137 lphl
->bRedrawFlag
= OldFlag
;
1139 InvalidateRect(hwnd
, NULL
, TRUE
);
1142 dprintf_listbox(stddeb
,"End of ListBoxDirectory !\n");
1147 int ListBoxGetItemRect(HWND hwnd
, WORD wIndex
, LPRECT lprect
)
1150 LPLISTSTRUCT lpls
, lpls2
;
1152 lphl
= ListBoxGetStorageHeader(hwnd
);
1153 if (lphl
== NULL
) return LB_ERR
;
1154 if (wIndex
> lphl
->ItemsCount
) return LB_ERR
;
1155 lpls
= lphl
->lpFirst
;
1156 if (lpls
== NULL
) return LB_ERR
;
1157 for(i
= 0; i
< lphl
->ItemsCount
; i
++) {
1159 lpls
= (LPLISTSTRUCT
)lpls
->lpNext
;
1161 *(lprect
) = lpls2
->dis
.rcItem
;
1164 if (lpls
== NULL
) break;
1171 int ListBoxSetItemHeight(HWND hwnd
, WORD wIndex
, long height
)
1174 LPLISTSTRUCT lpls
, lpls2
;
1176 lphl
= ListBoxGetStorageHeader(hwnd
);
1177 if (lphl
== NULL
) return LB_ERR
;
1178 if (wIndex
> lphl
->ItemsCount
) return LB_ERR
;
1179 lpls
= lphl
->lpFirst
;
1180 if (lpls
== NULL
) return LB_ERR
;
1181 for(i
= 0; i
< lphl
->ItemsCount
; i
++) {
1183 lpls
= (LPLISTSTRUCT
)lpls
->lpNext
;
1185 lpls2
->dis
.rcItem
.bottom
= lpls2
->dis
.rcItem
.top
+ (short)height
;
1186 InvalidateRect(hwnd
, NULL
, TRUE
);
1190 if (lpls
== NULL
) break;
1199 int ListBoxDefaultItem(HWND hwnd
, WND
*wndPtr
,
1200 LPHEADLIST lphl
, LPLISTSTRUCT lpls
)
1203 if (wndPtr
== NULL
|| lphl
== NULL
|| lpls
== NULL
) {
1204 fprintf(stderr
,"ListBoxDefaultItem() // Bad Pointers !\n");
1207 GetClientRect(hwnd
, &rect
);
1208 SetRect(&lpls
->dis
.rcItem
, 0, 0, rect
.right
, lphl
->StdItemHeight
);
1209 lpls
->dis
.CtlType
= lphl
->DrawCtlType
;
1210 lpls
->dis
.CtlID
= wndPtr
->wIDmenu
;
1211 lpls
->dis
.itemID
= 0;
1212 lpls
->dis
.itemAction
= 0;
1213 lpls
->dis
.itemState
= 0;
1214 lpls
->dis
.hwndItem
= hwnd
;
1216 lpls
->dis
.itemData
= 0;
1222 int ListBoxFindNextMatch(HWND hwnd
, WORD wChar
)
1228 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
1229 if (lphl
== NULL
) return LB_ERR
;
1230 lpls
= lphl
->lpFirst
;
1231 if (lpls
== NULL
) return LB_ERR
;
1232 if (wChar
< ' ') return LB_ERR
;
1233 if (((wndPtr
->dwStyle
& LBS_OWNERDRAWFIXED
) == LBS_OWNERDRAWFIXED
) ||
1234 ((wndPtr
->dwStyle
& LBS_OWNERDRAWVARIABLE
) == LBS_OWNERDRAWVARIABLE
)) {
1235 if ((wndPtr
->dwStyle
& LBS_HASSTRINGS
) != LBS_HASSTRINGS
) {
1240 while(lpls
!= NULL
) {
1241 if (Count
> lphl
->ItemFocused
) {
1242 if (*(lpls
->itemText
) == (char)wChar
) {
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
;
1249 ListBoxSetCurSel(hwnd
, Count
);
1251 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
1252 InvalidateRect(hwnd
, NULL
, TRUE
);
1257 lpls
= (LPLISTSTRUCT
)lpls
->lpNext
;
1261 lpls
= lphl
->lpFirst
;
1262 while(lpls
!= NULL
) {
1263 if (*(lpls
->itemText
) == (char)wChar
) {
1264 if (Count
== lphl
->ItemFocused
) return LB_ERR
;
1265 lphl
->FirstVisible
= Count
- lphl
->ItemsVisible
/ 2;
1266 if (lphl
->FirstVisible
< 1) lphl
->FirstVisible
= 1;
1267 if ((wndPtr
->dwStyle
& LBS_MULTIPLESEL
) == LBS_MULTIPLESEL
) {
1268 lphl
->ItemFocused
= Count
;
1271 ListBoxSetCurSel(hwnd
, Count
);
1273 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
1274 InvalidateRect(hwnd
, NULL
, TRUE
);
1278 lpls
= (LPLISTSTRUCT
)lpls
->lpNext
;
1285 /************************************************************************
1286 * DlgDirSelect [USER.99]
1288 BOOL
DlgDirSelect(HWND hDlg
, LPSTR lpStr
, int nIDLBox
)
1290 fprintf(stdnimp
,"DlgDirSelect(%04X, '%s', %d) \n", hDlg
, lpStr
, nIDLBox
);
1295 /************************************************************************
1296 * DlgDirList [USER.100]
1298 int DlgDirList(HWND hDlg
, LPSTR lpPathSpec
,
1299 int nIDLBox
, int nIDStat
, WORD wType
)
1303 dprintf_listbox(stddeb
,"DlgDirList(%04X, '%s', %d, %d, %04X) \n",
1304 hDlg
, lpPathSpec
, nIDLBox
, nIDStat
, wType
);
1306 hWnd
= GetDlgItem(hDlg
, nIDLBox
);
1310 ListBoxResetContent(hWnd
);
1312 ret
=ListBoxDirectory(hWnd
, wType
, lpPathSpec
);
1318 drive
= DOS_GetDefaultDrive();
1319 SendDlgItemMessage(hDlg
, nIDStat
, WM_SETTEXT
, 0,
1320 (LONG
) DOS_GetCurrentDir(drive
) );
1325 /* get the maximum value of lphl->FirstVisible */
1326 int ListMaxFirstVisible(LPHEADLIST lphl
)
1328 int m
= lphl
->ItemsCount
-lphl
->ItemsVisible
+1;
1329 return (m
< 1) ? 1 : m
;