2 * Interface code to listbox widgets
4 * Copyright Martin Ayotte, 1993
5 * Copyright Constantine Sapuntzakis, 1995
7 static char Copyright[] = "Copyright Martin Ayotte, 1993";
14 #include <sys/types.h>
25 #define GMEM_ZEROINIT 0x0040
27 LPLISTSTRUCT
ListBoxGetItem (HWND hwnd
, UINT uIndex
);
28 int ListBoxScrolltoFocus(HWND hwnd
);
29 LPHEADLIST
ListBoxGetWindowAndStorage(HWND hwnd
, WND
**wndPtr
);
30 LPHEADLIST
ListBoxGetStorageHeader(HWND hwnd
);
31 void RepaintListBox(HWND hwnd
);
32 int ListBoxFindMouse(HWND hwnd
, int X
, int Y
);
33 int CreateListBoxStruct(HWND hwnd
);
34 void ListBoxAskMeasure(WND
*wndPtr
, LPHEADLIST lphl
, LPLISTSTRUCT lpls
);
35 int ListBoxAddString(HWND hwnd
, LPSTR newstr
);
36 int ListBoxInsertString(HWND hwnd
, UINT uIndex
, LPSTR newstr
);
37 int ListBoxGetText(HWND hwnd
, UINT uIndex
, LPSTR OutStr
, BOOL bItemData
);
38 int ListBoxSetItemData(HWND hwnd
, UINT uIndex
, DWORD ItemData
);
39 int ListBoxDeleteString(HWND hwnd
, UINT uIndex
);
40 int ListBoxFindString(HWND hwnd
, UINT nFirst
, LPSTR MatchStr
);
41 int ListBoxResetContent(HWND hwnd
);
42 int ListBoxSetCurSel(HWND hwnd
, WORD wIndex
);
43 int ListBoxSetSel(HWND hwnd
, WORD wIndex
, WORD state
);
44 int ListBoxGetSel(HWND hwnd
, WORD wIndex
);
45 int ListBoxDirectory(HWND hwnd
, UINT attrib
, LPSTR filespec
);
46 int ListBoxGetItemRect(HWND hwnd
, WORD wIndex
, LPRECT rect
);
47 int ListBoxSetItemHeight(HWND hwnd
, WORD wIndex
, long height
);
48 int ListBoxDefaultItem(HWND hwnd
, WND
*wndPtr
,
49 LPHEADLIST lphl
, LPLISTSTRUCT lpls
);
50 int ListBoxFindNextMatch(HWND hwnd
, WORD wChar
);
51 int ListMaxFirstVisible(LPHEADLIST lphl
);
52 void ListBoxSendNotification(HWND hwnd
, WORD code
);
54 #define OWNER_DRAWN(wndPtr) \
55 ((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) || \
56 (wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE))
58 #define HasStrings(wndPtr) ( \
59 (! OWNER_DRAWN (wndPtr)) || \
60 (wndPtr->dwStyle & LBS_HASSTRINGS))
63 #define LIST_HEAP_ALLOC(lphl,f,size) ((int)HEAP_Alloc(&lphl->Heap,f,size) & 0xffff)
64 #define LIST_HEAP_FREE(lphl,handle) (HEAP_Free(&lphl->Heap,LIST_HEAP_ADDR(lphl,handle)))
65 #define LIST_HEAP_ADDR(lphl,handle) \
66 ((void *)((handle) ? ((handle) | ((int)lphl->Heap & 0xffff0000)) : 0))
68 /* FIXME: shouldn't each listbox have its own heap? */
69 #define LIST_HEAP_ALLOC(lphl,f,size) USER_HEAP_ALLOC(size)
70 #define LIST_HEAP_FREE(lphl,handle) USER_HEAP_FREE(handle)
71 #define LIST_HEAP_ADDR(lphl,handle) USER_HEAP_LIN_ADDR(handle)
72 #define LIST_HEAP_SEG_ADDR(lphl,handle) USER_HEAP_SEG_ADDR(handle)
75 #define LIST_HEAP_SIZE 0x10000
77 /* Design notes go here */
79 LONG
LBCreate( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
80 LONG
LBGetDlgCode( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
81 LONG
LBDestroy( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
82 LONG
LBVScroll( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
83 LONG
LBHScroll( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
84 LONG
LBLButtonDown( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
85 LONG
LBLButtonUp( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
86 LONG
LBRButtonUp( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
87 LONG
LBMouseMove( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
88 LONG
LBKeyDown( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
89 LONG
LBSetFont( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
90 LONG
LBSetRedraw( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
91 LONG
LBPaint( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
92 LONG
LBSetFocus( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
93 LONG
LBKillFocus( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
94 LONG
LBResetContent( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
95 LONG
LBDir( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
96 LONG
LBAddString( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
97 LONG
LBGetText( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
98 LONG
LBInsertString( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
99 LONG
LBDeleteString( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
100 LONG
LBFindString( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
101 LONG
LBGetCaretIndex( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
102 LONG
LBGetCount( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
103 LONG
LBGetCurSel( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
104 LONG
LBGetHorizontalExtent(HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
105 LONG
LBGetItemData( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
106 LONG
LBGetItemHeight( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
107 LONG
LBGetItemRect( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
108 LONG
LBGetSel( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
109 LONG
LBGetSelCount( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
110 LONG
LBGetSelItems( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
111 LONG
LBGetTextLen( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
112 LONG
LBGetTopIndex( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
113 LONG
LBSelectString( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
114 LONG
LBSelItemRange( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
115 LONG
LBSetCaretIndex( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
116 LONG
LBSetColumnWidth( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
117 LONG
LBSetHorizontalExtent(HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
118 LONG
LBSetItemData( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
119 LONG
LBSetTabStops( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
120 LONG
LBSetCurSel( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
121 LONG
LBSetSel( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
122 LONG
LBSetTopIndex( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
123 LONG
LBSetItemHeight( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
128 LONG (*handler
)(HWND
, WORD
, WPARAM
, LPARAM
);
131 static msg_tbl methods
[] = {
132 {WM_CREATE
, LBCreate
},
133 {WM_DESTROY
, LBDestroy
},
134 {WM_GETDLGCODE
, LBGetDlgCode
},
135 {WM_VSCROLL
, LBVScroll
},
136 {WM_HSCROLL
, LBHScroll
},
137 {WM_LBUTTONDOWN
, LBLButtonDown
},
138 {WM_LBUTTONUP
, LBLButtonUp
},
139 {WM_RBUTTONUP
, LBRButtonUp
},
140 {WM_LBUTTONDBLCLK
, LBRButtonUp
},
141 {WM_MOUSEMOVE
, LBMouseMove
},
142 {WM_KEYDOWN
, LBKeyDown
},
143 {WM_SETFONT
, LBSetFont
},
144 {WM_SETREDRAW
, LBSetRedraw
},
146 {WM_SETFOCUS
, LBSetFocus
},
147 {WM_KILLFOCUS
, LBKillFocus
},
148 {LB_RESETCONTENT
, LBResetContent
},
150 {LB_ADDSTRING
, LBAddString
},
151 {LB_INSERTSTRING
, LBInsertString
},
152 {LB_DELETESTRING
, LBDeleteString
},
153 {LB_FINDSTRING
, LBFindString
},
154 {LB_GETCARETINDEX
, LBGetCaretIndex
},
155 {LB_GETCOUNT
, LBGetCount
},
156 {LB_GETCURSEL
, LBGetCurSel
},
157 {LB_GETHORIZONTALEXTENT
, LBGetHorizontalExtent
},
158 {LB_GETITEMDATA
, LBGetItemData
},
159 {LB_GETITEMHEIGHT
, LBGetItemHeight
},
160 {LB_GETITEMRECT
, LBGetItemRect
},
161 {LB_GETSEL
, LBGetSel
},
162 {LB_GETSELCOUNT
, LBGetSelCount
},
163 {LB_GETSELITEMS
, LBGetSelItems
},
164 {LB_GETTEXT
, LBGetText
},
165 {LB_GETTEXTLEN
, LBGetTextLen
},
166 {LB_GETTOPINDEX
, LBGetTopIndex
},
167 {LB_SELECTSTRING
, LBSelectString
},
168 {LB_SELITEMRANGE
, LBSelItemRange
},
169 {LB_SETCARETINDEX
, LBSetCaretIndex
},
170 {LB_SETCOLUMNWIDTH
, LBSetColumnWidth
},
171 {LB_SETHORIZONTALEXTENT
, LBSetHorizontalExtent
},
172 {LB_SETITEMDATA
, LBSetItemData
},
173 {LB_SETTABSTOPS
, LBSetTabStops
},
174 {LB_SETCURSEL
, LBSetCurSel
},
175 {LB_SETSEL
, LBSetSel
},
176 {LB_SETTOPINDEX
, LBSetTopIndex
},
177 {LB_SETITEMHEIGHT
, LBSetItemHeight
}
180 /***********************************************************************
183 LONG
LBCreate( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
187 CREATESTRUCT
*createStruct
;
190 CreateListBoxStruct(hwnd
);
191 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
193 dprintf_listbox(stddeb
,"ListBox WM_CREATE %p !\n", lphl
);
195 if (lphl
== NULL
) return 0;
197 createStruct
= (CREATESTRUCT
*)PTR_SEG_TO_LIN(lParam
);
199 if (HIWORD(createStruct
->lpCreateParams
) != 0)
200 lphl
->hWndLogicParent
= (HWND
)HIWORD(createStruct
->lpCreateParams
);
202 lphl
->hWndLogicParent
= GetParent(hwnd
);
204 lphl
->hFont
= GetStockObject(SYSTEM_FONT
);
205 lphl
->ColumnsWidth
= wndPtr
->rectClient
.right
- wndPtr
->rectClient
.left
;
207 SetScrollRange(hwnd
, SB_VERT
, 1, ListMaxFirstVisible(lphl
), TRUE
);
208 SetScrollRange(hwnd
, SB_HORZ
, 1, 1, TRUE
);
213 int CreateListBoxStruct(HWND hwnd
)
219 wndPtr
= WIN_FindWndPtr(hwnd
);
221 lphl
= (LPHEADLIST
)malloc(sizeof(HEADLIST
));
222 *((LPHEADLIST
*)&wndPtr
->wExtra
[1]) = lphl
;
224 lphl
->lpFirst
= NULL
;
225 lphl
->ItemsCount
= 0;
226 lphl
->ItemsVisible
= 0;
227 lphl
->FirstVisible
= 1;
228 lphl
->ColumnsVisible
= 1;
229 lphl
->ItemsPerColumn
= 0;
230 lphl
->StdItemHeight
= 15;
231 lphl
->ItemFocused
= -1;
232 lphl
->PrevFocused
= -1;
233 lphl
->DrawCtlType
= ODT_LISTBOX
;
234 lphl
->bRedrawFlag
= TRUE
;
236 lphl
->TabStops
= NULL
;
238 if (OWNER_DRAWN(wndPtr
))
239 lphl
->hDrawItemStruct
= USER_HEAP_ALLOC(sizeof(DRAWITEMSTRUCT
));
241 lphl
->hDrawItemStruct
= 0;
244 HeapHandle
= GlobalAlloc(GMEM_FIXED
, LIST_HEAP_SIZE
);
245 HeapBase
= GlobalLock(HeapHandle
);
246 HEAP_Init(&lphl
->Heap
, HeapBase
, LIST_HEAP_SIZE
);
252 /***********************************************************************
255 LONG
LBDestroy( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
261 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
263 if (lphl
== NULL
) return 0;
264 ListBoxResetContent(hwnd
);
266 if (lphl
->hDrawItemStruct
)
267 USER_HEAP_FREE(lphl
->hDrawItemStruct
);
269 /* XXX need to free lphl->Heap */
271 *((LPHEADLIST
*)&wndPtr
->wExtra
[1]) = 0;
272 dprintf_listbox(stddeb
,"ListBox WM_DESTROY %p !\n", lphl
);
276 /* get the maximum value of lphl->FirstVisible */
277 int ListMaxFirstVisible(LPHEADLIST lphl
)
279 int m
= lphl
->ItemsCount
-lphl
->ItemsVisible
+1;
280 return (m
< 1) ? 1 : m
;
284 /***********************************************************************
287 LONG
LBVScroll( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
293 dprintf_listbox(stddeb
,"ListBox WM_VSCROLL w=%04X l=%08lX !\n",
295 lphl
= ListBoxGetStorageHeader(hwnd
);
296 if (lphl
== NULL
) return 0;
297 y
= lphl
->FirstVisible
;
301 if (lphl
->FirstVisible
> 1)
302 lphl
->FirstVisible
--;
306 if (lphl
->FirstVisible
< ListMaxFirstVisible(lphl
))
307 lphl
->FirstVisible
++;
311 if (lphl
->FirstVisible
> 1)
312 lphl
->FirstVisible
-= lphl
->ItemsVisible
;
316 if (lphl
->FirstVisible
< ListMaxFirstVisible(lphl
))
317 lphl
->FirstVisible
+= lphl
->ItemsVisible
;
321 lphl
->FirstVisible
= LOWORD(lParam
);
325 if (lphl
->FirstVisible
< 1) lphl
->FirstVisible
= 1;
326 if (lphl
->FirstVisible
> ListMaxFirstVisible(lphl
))
327 lphl
->FirstVisible
= ListMaxFirstVisible(lphl
);
329 if (y
!= lphl
->FirstVisible
) {
330 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
331 InvalidateRect(hwnd
, NULL
, TRUE
);
337 /***********************************************************************
340 LONG
LBHScroll( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
346 dprintf_listbox(stddeb
,"ListBox WM_HSCROLL w=%04X l=%08lX !\n",
348 lphl
= ListBoxGetStorageHeader(hwnd
);
349 if (lphl
== NULL
) return 0;
350 y
= lphl
->FirstVisible
;
353 if (lphl
->FirstVisible
> 1)
354 lphl
->FirstVisible
-= lphl
->ItemsPerColumn
;
357 if (lphl
->FirstVisible
< ListMaxFirstVisible(lphl
))
358 lphl
->FirstVisible
+= lphl
->ItemsPerColumn
;
361 if (lphl
->FirstVisible
> 1 && lphl
->ItemsPerColumn
!= 0)
362 lphl
->FirstVisible
-= lphl
->ItemsVisible
/
363 lphl
->ItemsPerColumn
* lphl
->ItemsPerColumn
;
366 if (lphl
->FirstVisible
< ListMaxFirstVisible(lphl
) &&
367 lphl
->ItemsPerColumn
!= 0)
368 lphl
->FirstVisible
+= lphl
->ItemsVisible
/
369 lphl
->ItemsPerColumn
* lphl
->ItemsPerColumn
;
372 lphl
->FirstVisible
= lphl
->ItemsPerColumn
*
373 (LOWORD(lParam
) - 1) + 1;
376 if (lphl
->FirstVisible
< 1) lphl
->FirstVisible
= 1;
377 if (lphl
->FirstVisible
> ListMaxFirstVisible(lphl
))
378 lphl
->FirstVisible
= ListMaxFirstVisible(lphl
);
380 if (lphl
->ItemsPerColumn
!= 0) {
381 lphl
->FirstVisible
= lphl
->FirstVisible
/
382 lphl
->ItemsPerColumn
* lphl
->ItemsPerColumn
+ 1;
383 if (y
!= lphl
->FirstVisible
) {
384 SetScrollPos(hwnd
, SB_HORZ
, lphl
->FirstVisible
/
385 lphl
->ItemsPerColumn
+ 1, TRUE
);
386 InvalidateRect(hwnd
, NULL
, TRUE
);
393 /***********************************************************************
396 LONG
LBLButtonDown( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
408 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
409 if (lphl
== NULL
) return 0;
411 lphl
->PrevFocused
= lphl
->ItemFocused
;
413 y
= ListBoxFindMouse(hwnd
, LOWORD(lParam
), HIWORD(lParam
));
417 if (wndPtr
->dwStyle
& LBS_MULTIPLESEL
) {
418 lphl
->ItemFocused
= y
;
419 wRet
= ListBoxGetSel(hwnd
, y
);
420 ListBoxSetSel(hwnd
, y
, !wRet
);
423 ListBoxSetCurSel(hwnd
, y
);
425 if (wndPtr
->dwStyle
& LBS_MULTIPLESEL
)
426 ListBoxSendNotification( hwnd
, LBN_SELCHANGE
);
428 ListBoxGetItemRect(hwnd
, y
, &rectsel
);
430 InvalidateRect(hwnd
, NULL
, TRUE
);
436 /***********************************************************************
439 LONG
LBLButtonUp( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
445 if (GetCapture() == hwnd
) ReleaseCapture();
447 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
448 if (lphl
== NULL
) return 0;
449 if (lphl
->PrevFocused
!= lphl
->ItemFocused
)
450 ListBoxSendNotification( hwnd
, LBN_SELCHANGE
);
455 /***********************************************************************
458 LONG
LBRButtonUp( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
464 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
465 if (lphl
== NULL
) return 0;
466 SendMessage(lphl
->hWndLogicParent
, WM_COMMAND
, wndPtr
->wIDmenu
,
467 MAKELONG(hwnd
, LBN_DBLCLK
));
472 /***********************************************************************
475 LONG
LBMouseMove( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
482 RECT rect
, rectsel
; /* XXX Broken */
484 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
485 if (lphl
== NULL
) return 0;
486 if ((wParam
& MK_LBUTTON
) != 0) {
489 if (lphl
->FirstVisible
> 1) {
490 lphl
->FirstVisible
--;
491 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
492 InvalidateRect(hwnd
, NULL
, TRUE
);
497 GetClientRect(hwnd
, &rect
);
498 if (y
> (rect
.bottom
- 4)) {
499 if (lphl
->FirstVisible
< ListMaxFirstVisible(lphl
)) {
500 lphl
->FirstVisible
++;
501 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
502 InvalidateRect(hwnd
, NULL
, TRUE
);
507 if ((y
> 0) && (y
< (rect
.bottom
- 4))) {
508 if ((y
< rectsel
.top
) || (y
> rectsel
.bottom
)) {
509 wRet
= ListBoxFindMouse(hwnd
, LOWORD(lParam
), HIWORD(lParam
));
510 if ((wndPtr
->dwStyle
& LBS_MULTIPLESEL
) == LBS_MULTIPLESEL
) {
511 lphl
->ItemFocused
= wRet
;
512 ListBoxSendNotification(hwnd
, LBN_SELCHANGE
);
515 ListBoxSetCurSel(hwnd
, wRet
);
516 ListBoxGetItemRect(hwnd
, wRet
, &rectsel
);
517 InvalidateRect(hwnd
, NULL
, TRUE
);
526 /***********************************************************************
529 LONG
LBKeyDown( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
537 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
538 if (lphl
== NULL
) return 0;
541 hWndCtl
= GetNextDlgTabItem(lphl
->hWndLogicParent
,
542 hwnd
, !(GetKeyState(VK_SHIFT
) < 0));
544 if(debugging_listbox
){
545 if ((GetKeyState(VK_SHIFT
) < 0))
546 dprintf_listbox(stddeb
,"ListBox PreviousDlgTabItem %04X !\n", hWndCtl
);
548 dprintf_listbox(stddeb
,"ListBox NextDlgTabItem %04X !\n", hWndCtl
);
552 lphl
->ItemFocused
= 0;
555 lphl
->ItemFocused
= lphl
->ItemsCount
- 1;
558 if ((wndPtr
->dwStyle
& LBS_MULTICOLUMN
) == LBS_MULTICOLUMN
) {
559 lphl
->ItemFocused
-= lphl
->ItemsPerColumn
;
566 if ((wndPtr
->dwStyle
& LBS_MULTICOLUMN
) == LBS_MULTICOLUMN
) {
567 lphl
->ItemFocused
+= lphl
->ItemsPerColumn
;
574 lphl
->ItemFocused
-= lphl
->ItemsVisible
;
577 lphl
->ItemFocused
+= lphl
->ItemsVisible
;
580 wRet
= ListBoxGetSel(hwnd
, lphl
->ItemFocused
);
581 ListBoxSetSel(hwnd
, lphl
->ItemFocused
, !wRet
);
584 ListBoxFindNextMatch(hwnd
, wParam
);
588 if (lphl
->ItemFocused
< 0) lphl
->ItemFocused
= 0;
589 if (lphl
->ItemFocused
>= lphl
->ItemsCount
)
590 lphl
->ItemFocused
= lphl
->ItemsCount
- 1;
592 if (lphl
->ItemsVisible
!= 0)
593 lphl
->FirstVisible
= lphl
->ItemFocused
/ lphl
->ItemsVisible
*
594 lphl
->ItemsVisible
+ 1;
596 if (lphl
->FirstVisible
< 1) lphl
->FirstVisible
= 1;
597 if (lphl
->FirstVisible
> ListMaxFirstVisible(lphl
))
598 lphl
->FirstVisible
= ListMaxFirstVisible(lphl
);
600 if ((wndPtr
->dwStyle
& LBS_MULTIPLESEL
) != LBS_MULTIPLESEL
) {
601 ListBoxSetCurSel(hwnd
, lphl
->ItemFocused
);
602 ListBoxSendNotification(hwnd
, LBN_SELCHANGE
);
605 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
606 InvalidateRect(hwnd
, NULL
, TRUE
);
612 /***********************************************************************
615 LONG
LBSetRedraw( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
621 dprintf_listbox(stddeb
,"ListBox WM_SETREDRAW hWnd=%04X w=%04X !\n", hwnd
, wParam
);
622 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
623 if (lphl
== NULL
) return 0;
624 lphl
->bRedrawFlag
= wParam
;
629 /***********************************************************************
633 LONG
LBSetFont( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
639 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
640 if (lphl
== NULL
) return 0;
643 lphl
->hFont
= GetStockObject(SYSTEM_FONT
);
645 lphl
->hFont
= wParam
;
650 /***********************************************************************
653 LONG
LBPaint( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
656 RepaintListBox(hwnd
);
660 /***********************************************************************
663 LONG
LBSetFocus( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
669 dprintf_listbox(stddeb
,"ListBox WM_SETFOCUS !\n");
670 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
675 /***********************************************************************
678 LONG
LBKillFocus( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
681 dprintf_listbox(stddeb
,"ListBox WM_KILLFOCUS !\n");
683 InvalidateRect(hwnd
, NULL
, TRUE
);
689 /***********************************************************************
692 LONG
LBResetContent( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
695 dprintf_listbox(stddeb
,"ListBox LB_RESETCONTENT !\n");
696 ListBoxResetContent(hwnd
);
701 /***********************************************************************
704 LONG
LBDir( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
708 dprintf_listbox(stddeb
,"ListBox LB_DIR !\n");
710 wRet
= ListBoxDirectory(hwnd
, wParam
,
711 (LPSTR
)PTR_SEG_TO_LIN(lParam
));
712 InvalidateRect(hwnd
, NULL
, TRUE
);
717 /***********************************************************************
720 LONG
LBAddString( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
726 wndPtr
= WIN_FindWndPtr(hwnd
);
728 if (HasStrings(wndPtr
))
729 wRet
= ListBoxAddString(hwnd
, (LPSTR
)PTR_SEG_TO_LIN(lParam
));
731 wRet
= ListBoxAddString(hwnd
, (LPSTR
)lParam
);
736 /***********************************************************************
739 LONG
LBGetText( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
744 dprintf_listbox(stddeb
, "LB_GETTEXT wParam=%d\n",wParam
);
745 wRet
= ListBoxGetText(hwnd
, wParam
,
746 (LPSTR
)PTR_SEG_TO_LIN(lParam
), FALSE
);
751 /***********************************************************************
754 LONG
LBInsertString( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
760 wndPtr
= WIN_FindWndPtr(hwnd
);
762 if (HasStrings(wndPtr
))
763 wRet
= ListBoxInsertString(hwnd
, wParam
, (LPSTR
)PTR_SEG_TO_LIN(lParam
));
765 wRet
= ListBoxInsertString(hwnd
, wParam
, (LPSTR
)lParam
);
770 /***********************************************************************
773 LONG
LBDeleteString( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
776 return ListBoxDeleteString(hwnd
, wParam
);
779 /***********************************************************************
782 LONG
LBFindString( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
785 return ListBoxFindString(hwnd
, wParam
,
786 (LPSTR
)PTR_SEG_TO_LIN(lParam
));
789 /***********************************************************************
792 LONG
LBGetCaretIndex( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
797 lphl
= ListBoxGetStorageHeader(hwnd
);
798 if (lphl
== NULL
) return LB_ERR
;
800 return lphl
->ItemFocused
;
803 /***********************************************************************
806 LONG
LBGetCount( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
811 lphl
= ListBoxGetStorageHeader(hwnd
);
812 return lphl
->ItemsCount
;
815 /***********************************************************************
818 LONG
LBGetCurSel( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
823 lphl
= ListBoxGetStorageHeader(hwnd
);
824 dprintf_listbox(stddeb
,"ListBox LB_GETCURSEL %u !\n",
826 return lphl
->ItemFocused
;
829 /***********************************************************************
830 * LBGetHorizontalExtent
832 LONG
LBGetHorizontalExtent( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
838 /***********************************************************************
841 LONG
LBGetItemData( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
844 dprintf_listbox(stddeb
, "LB_GETITEMDATA wParam=%x\n", wParam
);
845 return ListBoxGetText(hwnd
, wParam
,
846 (LPSTR
)PTR_SEG_TO_LIN(lParam
), TRUE
);
849 /***********************************************************************
852 LONG
LBGetItemHeight( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
857 ListBoxGetItemRect(hwnd
, wParam
, &rect
);
858 return (rect
.bottom
- rect
.top
);
861 /***********************************************************************
864 LONG
LBGetItemRect( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
867 return ListBoxGetItemRect (hwnd
, wParam
, PTR_SEG_TO_LIN(lParam
));
870 /***********************************************************************
873 LONG
LBGetSel( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
876 return ListBoxGetSel (hwnd
, wParam
);
879 /***********************************************************************
882 LONG
LBGetSelCount( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
890 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
891 if (lphl
== NULL
) return LB_ERR
;
893 if (!(wndPtr
->dwStyle
& LBS_MULTIPLESEL
)) return LB_ERR
;
895 lpls
= lphl
->lpFirst
;
897 while (lpls
!= NULL
) {
898 if (lpls
->dis
.itemState
> 0) cnt
++;
906 /***********************************************************************
909 LONG
LBGetSelItems( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
916 int *lpItems
= PTR_SEG_TO_LIN(lParam
);
918 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
919 if (lphl
== NULL
) return LB_ERR
;
921 if (!(wndPtr
->dwStyle
& LBS_MULTIPLESEL
)) return LB_ERR
;
923 if (wParam
== 0) return 0;
925 lpls
= lphl
->lpFirst
;
928 while (lpls
!= NULL
) {
929 if (lpls
->dis
.itemState
> 0) lpItems
[cnt
++] = idx
;
931 if (cnt
== wParam
) break;
939 /***********************************************************************
942 LONG
LBGetTextLen( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
950 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
951 if (lphl
== NULL
) return LB_ERR
;
953 if (!HasStrings(wndPtr
)) return LB_ERR
;
955 if (wParam
>= lphl
->ItemsCount
) return LB_ERR
;
957 lpls
= lphl
->lpFirst
;
959 while (cnt
++ < wParam
) lpls
= lpls
->lpNext
;
961 return strlen(lpls
->itemText
);
964 /***********************************************************************
967 LONG
LBGetDlgCode( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
970 return DLGC_WANTALLKEYS
;
973 /***********************************************************************
976 LONG
LBGetTopIndex( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
981 lphl
= ListBoxGetStorageHeader(hwnd
);
982 if (lphl
== NULL
) return LB_ERR
;
984 return (lphl
->FirstVisible
- 1);
988 /***********************************************************************
991 LONG
LBSelectString( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
997 wndPtr
= WIN_FindWndPtr(hwnd
);
999 wRet
= ListBoxFindString(hwnd
, wParam
,
1000 (LPSTR
)PTR_SEG_TO_LIN(lParam
));
1002 /* XXX add functionality here */
1007 /***********************************************************************
1010 LONG
LBSelItemRange( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
1017 WORD first
= LOWORD(lParam
);
1018 WORD last
= HIWORD(lParam
);
1019 BOOL select
= wParam
;
1021 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
1022 if (lphl
== NULL
) return LB_ERR
;
1024 if (!(wndPtr
->dwStyle
& LBS_MULTIPLESEL
)) return LB_ERR
;
1026 if (first
>= lphl
->ItemsCount
||
1027 last
>= lphl
->ItemsCount
) return LB_ERR
;
1029 lpls
= lphl
->lpFirst
;
1032 while (lpls
!= NULL
) {
1034 lpls
->dis
.itemState
= select
? ODS_SELECTED
: 0;
1039 lpls
= lpls
->lpNext
;
1045 /***********************************************************************
1048 LONG
LBSetCaretIndex( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
1054 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
1055 if (lphl
== NULL
) return LB_ERR
;
1057 if (!(wndPtr
->dwStyle
& LBS_MULTIPLESEL
)) return 0;
1058 if (wParam
>= lphl
->ItemsCount
) return LB_ERR
;
1060 lphl
->ItemFocused
= wParam
;
1061 ListBoxScrolltoFocus (hwnd
);
1063 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
1064 InvalidateRect(hwnd
, NULL
, TRUE
);
1069 /***********************************************************************
1072 LONG
LBSetColumnWidth( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
1077 lphl
= ListBoxGetStorageHeader(hwnd
);
1078 if (lphl
== NULL
) return LB_ERR
;
1079 lphl
->ColumnsWidth
= wParam
;
1084 /***********************************************************************
1085 * LBSetHorizontalExtent
1087 LONG
LBSetHorizontalExtent( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
1093 /***********************************************************************
1096 LONG
LBSetItemData( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
1099 dprintf_listbox(stddeb
, "LB_SETITEMDATA wParam=%x lParam=%lx\n", wParam
, lParam
);
1100 return ListBoxSetItemData(hwnd
, wParam
, lParam
);
1103 /***********************************************************************
1106 LONG
LBSetTabStops( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
1111 lphl
= ListBoxGetStorageHeader(hwnd
);
1113 if (lphl
->TabStops
!= NULL
) {
1114 lphl
->iNumStops
= 0;
1115 free (lphl
->TabStops
);
1118 lphl
->TabStops
= malloc (wParam
* sizeof (short));
1119 if (lphl
->TabStops
) {
1120 lphl
->iNumStops
= wParam
;
1121 memcpy (lphl
->TabStops
, PTR_SEG_TO_LIN(lParam
), wParam
* sizeof (short));
1128 /***********************************************************************
1131 LONG
LBSetCurSel( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
1137 lphl
= ListBoxGetStorageHeader(hwnd
);
1138 if (lphl
== NULL
) return LB_ERR
;
1140 dprintf_listbox(stddeb
,"ListBox LB_SETCURSEL wParam=%x !\n",
1143 wRet
= ListBoxSetCurSel(hwnd
, wParam
);
1145 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
1146 InvalidateRect(hwnd
, NULL
, TRUE
);
1152 /***********************************************************************
1155 LONG
LBSetSel( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
1160 dprintf_listbox(stddeb
,"ListBox LB_SETSEL wParam=%x lParam=%lX !\n", wParam
, lParam
);
1162 wRet
= ListBoxSetSel(hwnd
, LOWORD(lParam
), wParam
);
1163 InvalidateRect(hwnd
, NULL
, TRUE
);
1169 /***********************************************************************
1172 LONG
LBSetTopIndex( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
1177 dprintf_listbox(stddeb
,"ListBox LB_SETTOPINDEX wParam=%x !\n",
1179 lphl
= ListBoxGetStorageHeader(hwnd
);
1180 lphl
->FirstVisible
= wParam
;
1181 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
1183 InvalidateRect(hwnd
, NULL
, TRUE
);
1189 /***********************************************************************
1192 LONG
LBSetItemHeight( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
1197 dprintf_listbox(stddeb
,"ListBox LB_SETITEMHEIGHT wParam=%x lParam=%lX !\n", wParam
, lParam
);
1198 wRet
= ListBoxSetItemHeight(hwnd
, wParam
, lParam
);
1203 /***********************************************************************
1207 LONG
ListBoxWndProc( HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
)
1211 int table_size
= sizeof (methods
) / sizeof (msg_tbl
);
1213 while (idx
< table_size
) {
1214 if (message
== methods
[idx
].message
) {
1215 return (*(methods
[idx
].handler
))(hwnd
, message
, wParam
, lParam
);
1219 return DefWindowProc (hwnd
, message
, wParam
, lParam
);
1223 LPLISTSTRUCT
ListBoxGetItem(HWND hwnd
, UINT uIndex
)
1226 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1230 if (uIndex
>= lphl
->ItemsCount
) return NULL
;
1232 lpls
= lphl
->lpFirst
;
1234 while (Count
++ < uIndex
) lpls
= lpls
->lpNext
;
1240 LPHEADLIST
ListBoxGetWindowAndStorage(HWND hwnd
, WND
**wndPtr
)
1244 *(wndPtr
) = Ptr
= WIN_FindWndPtr(hwnd
);
1245 lphl
= *((LPHEADLIST
*)&Ptr
->wExtra
[1]);
1250 LPHEADLIST
ListBoxGetStorageHeader(HWND hwnd
)
1254 wndPtr
= WIN_FindWndPtr(hwnd
);
1255 lphl
= *((LPHEADLIST
*)&wndPtr
->wExtra
[1]);
1260 void ListBoxDrawItem (HWND hwnd
, HDC hdc
, LPLISTSTRUCT lpls
,
1261 WORD itemAction
, WORD itemState
)
1267 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
1269 if (OWNER_DRAWN(wndPtr
)) {
1270 DRAWITEMSTRUCT
*dis
= USER_HEAP_LIN_ADDR(lphl
->hDrawItemStruct
);
1272 memcpy (dis
, &lpls
->dis
, sizeof(DRAWITEMSTRUCT
));
1274 dis
->CtlType
= ODT_LISTBOX
;
1277 if ((!dis
->CtlID
) && lphl
->hWndLogicParent
) {
1280 ParentWndPtr
= WIN_FindWndPtr(lphl
->hWndLogicParent
);
1281 dis
->CtlID
= ParentWndPtr
->wIDmenu
;
1284 if (HasStrings(wndPtr
)) dis
->itemData
= LIST_HEAP_SEG_ADDR(lpls
,lpls
->hData
);
1286 dis
->itemAction
= itemAction
;
1287 dis
->itemState
= itemState
;
1289 SendMessage(lphl
->hWndLogicParent
, WM_DRAWITEM
,
1290 0, (LPARAM
)USER_HEAP_SEG_ADDR(lphl
->hDrawItemStruct
));
1293 if (itemAction
== ODA_DRAWENTIRE
||
1294 itemAction
== ODA_SELECT
) {
1296 DWORD dwOldTextColor
;
1298 OldBkMode
= SetBkMode(hdc
, TRANSPARENT
);
1300 if (itemState
!= 0) {
1301 dwOldTextColor
= SetTextColor(hdc
, 0x00FFFFFFL
);
1302 FillRect(hdc
, &lpls
->dis
.rcItem
, GetStockObject(BLACK_BRUSH
));
1305 if (wndPtr
->dwStyle
& LBS_USETABSTOPS
)
1306 TabbedTextOut(hdc
, lpls
->dis
.rcItem
.left
+ 5,
1307 lpls
->dis
.rcItem
.top
+ 2,
1308 (char *)lpls
->itemText
,
1309 strlen((char *)lpls
->itemText
), lphl
->iNumStops
,
1312 TextOut(hdc
, lpls
->dis
.rcItem
.left
+ 5, lpls
->dis
.rcItem
.top
+ 2,
1313 (char *)lpls
->itemText
, strlen((char *)lpls
->itemText
));
1315 if (itemState
!= 0) {
1316 SetTextColor(hdc
, dwOldTextColor
);
1319 SetBkMode(hdc
, OldBkMode
);
1320 } else DrawFocusRect(hdc
, &lpls
->dis
.rcItem
);
1326 void RepaintListBox(HWND hwnd
)
1337 int i
, top
, height
, maxwidth
, ipc
;
1341 hdc
= BeginPaint( hwnd
, &ps
);
1343 if (!IsWindowVisible(hwnd
)) {
1344 EndPaint( hwnd
, &ps
);
1348 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
1349 if (lphl
== NULL
) goto EndOfPaint
;
1350 if (!lphl
->bRedrawFlag
) goto EndOfPaint
;
1352 SelectObject(hdc
, lphl
->hFont
);
1354 hBrush
= SendMessage(lphl
->hWndLogicParent
, WM_CTLCOLOR
, (WORD
)hdc
,
1355 MAKELONG(hwnd
, CTLCOLOR_LISTBOX
));
1357 if (hBrush
== (HBRUSH
)NULL
) hBrush
= GetStockObject(WHITE_BRUSH
);
1359 GetClientRect(hwnd
, &rect
);
1360 FillRect(hdc
, &rect
, hBrush
);
1362 maxwidth
= rect
.right
;
1363 rect
.right
= lphl
->ColumnsWidth
;
1365 if (lphl
->ItemsCount
== 0) goto EndOfPaint
;
1367 lpls
= lphl
->lpFirst
;
1369 lphl
->ItemsVisible
= 0;
1370 lphl
->ItemsPerColumn
= ipc
= 0;
1372 for(i
= 0; i
< lphl
->ItemsCount
; i
++) {
1373 if (lpls
== NULL
) goto EndOfPaint
;
1375 if (i
>= lphl
->FirstVisible
- 1) {
1376 height
= lpls
->dis
.rcItem
.bottom
- lpls
->dis
.rcItem
.top
;
1378 if (top
> rect
.bottom
) {
1379 if ((wndPtr
->dwStyle
& LBS_MULTICOLUMN
) == LBS_MULTICOLUMN
) {
1380 lphl
->ItemsPerColumn
= max(lphl
->ItemsPerColumn
, ipc
);
1383 rect
.left
+= lphl
->ColumnsWidth
;
1384 rect
.right
+= lphl
->ColumnsWidth
;
1385 if (rect
.left
> maxwidth
) break;
1391 lpls
->dis
.rcItem
.top
= top
;
1392 lpls
->dis
.rcItem
.bottom
= top
+ height
;
1393 lpls
->dis
.rcItem
.left
= rect
.left
;
1394 lpls
->dis
.rcItem
.right
= rect
.right
;
1396 if (OWNER_DRAWN(wndPtr
)) {
1397 ListBoxDrawItem (hwnd
, hdc
, lpls
, ODA_DRAWENTIRE
, 0);
1398 if (lpls
->dis
.itemState
)
1399 ListBoxDrawItem (hwnd
, hdc
, lpls
, ODA_SELECT
, ODS_SELECTED
);
1402 ListBoxDrawItem (hwnd
, hdc
, lpls
, ODA_DRAWENTIRE
, lpls
->dis
.itemState
);
1404 if ((lphl
->ItemFocused
== i
) && GetFocus() == hwnd
)
1405 ListBoxDrawItem (hwnd
, hdc
, lpls
, ODA_FOCUS
, ODS_FOCUS
);
1408 lphl
->ItemsVisible
++;
1412 lpls
= lpls
->lpNext
;
1415 EndPaint( hwnd
, &ps
);
1418 int ListBoxFindMouse(HWND hwnd
, int X
, int Y
)
1425 int i
, h
, h2
, w
, w2
;
1427 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
1429 if (lphl
== NULL
) return LB_ERR
;
1430 if (lphl
->ItemsCount
== 0) return LB_ERR
;
1432 lpls
= lphl
->lpFirst
;
1433 if (lpls
== NULL
) return LB_ERR
;
1434 GetClientRect(hwnd
, &rect
);
1436 w
= lphl
->ColumnsWidth
;
1438 for(i
= 1; i
<= lphl
->ItemsCount
; i
++) {
1439 if (i
>= lphl
->FirstVisible
) {
1441 h
+= lpls
->dis
.rcItem
.bottom
- lpls
->dis
.rcItem
.top
;
1442 if ((Y
> h2
) && (Y
< h
) &&
1443 (X
> w2
) && (X
< w
)) return(i
- 1);
1444 if (h
> rect
.bottom
) {
1445 if ((wndPtr
->dwStyle
& LBS_MULTICOLUMN
) != LBS_MULTICOLUMN
) return LB_ERR
;
1448 w
+= lphl
->ColumnsWidth
;
1449 if (w2
> rect
.right
) return LB_ERR
;
1452 if (lpls
->lpNext
== NULL
) return LB_ERR
;
1453 lpls
= (LPLISTSTRUCT
)lpls
->lpNext
;
1458 void ListBoxAskMeasure(WND
*wndPtr
, LPHEADLIST lphl
, LPLISTSTRUCT lpls
)
1461 MEASUREITEMSTRUCT
*lpmeasure
;
1463 HANDLE hTemp
= USER_HEAP_ALLOC( sizeof(MEASUREITEMSTRUCT
) );
1465 lpmeasure
= (MEASUREITEMSTRUCT
*) USER_HEAP_LIN_ADDR(hTemp
);
1467 if (lpmeasure
== NULL
) {
1468 fprintf(stderr
,"ListBoxAskMeasure() // Bad allocation of Measure struct !\n");
1472 lpmeasure
->CtlType
= ODT_LISTBOX
;
1473 lpmeasure
->CtlID
= wndPtr
->wIDmenu
;
1474 lpmeasure
->itemID
= lpls
->dis
.itemID
;
1475 lpmeasure
->itemWidth
= wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
;
1476 lpmeasure
->itemHeight
= 0;
1478 if (HasStrings(wndPtr
))
1479 lpmeasure
->itemData
= LIST_HEAP_SEG_ADDR(lpls
,lpls
->hData
);
1481 lpmeasure
->itemData
= lpls
->dis
.itemData
;
1483 SendMessage(lphl
->hWndLogicParent
, WM_MEASUREITEM
,
1484 0, USER_HEAP_SEG_ADDR(hTemp
));
1486 if (wndPtr
->dwStyle
& LBS_OWNERDRAWFIXED
) {
1487 lphl
->StdItemHeight
= lpmeasure
->itemHeight
;
1490 lpls
->dis
.rcItem
.right
= lpls
->dis
.rcItem
.left
+ lpmeasure
->itemWidth
;
1491 lpls
->dis
.rcItem
.bottom
= lpls
->dis
.rcItem
.top
+ lpmeasure
->itemHeight
;
1492 USER_HEAP_FREE(hTemp
);
1496 int ListBoxAddString(HWND hwnd
, LPSTR newstr
)
1499 UINT pos
= (UINT
) -1;
1502 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
1503 if (lphl
== NULL
) return LB_ERR
;
1505 if (HasStrings(wndPtr
) && (wndPtr
->dwStyle
& LBS_SORT
)) {
1506 LPLISTSTRUCT lpls
= lphl
->lpFirst
;
1507 for (pos
= 0; lpls
; lpls
= lpls
->lpNext
, pos
++)
1508 if (strcmp(lpls
->itemText
, newstr
) >= 0)
1511 return ListBoxInsertString(hwnd
, pos
, newstr
);
1514 int ListBoxInsertString(HWND hwnd
, UINT uIndex
, LPSTR newstr
)
1519 LPLISTSTRUCT
*lppls
, lplsnew
;
1525 dprintf_listbox(stddeb
,"ListBoxInsertString(%04X, %d, %p);\n",
1526 hwnd
, uIndex
, newstr
);
1528 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
1529 if (lphl
== NULL
) return LB_ERR
;
1531 if (uIndex
== (UINT
)-1)
1532 uIndex
= lphl
->ItemsCount
;
1534 if (uIndex
> lphl
->ItemsCount
) return LB_ERR
;
1536 lppls
= (LPLISTSTRUCT
*) &lphl
->lpFirst
;
1538 for(Count
= 0; Count
< uIndex
; Count
++) {
1539 if (*lppls
== NULL
) return LB_ERR
;
1540 lppls
= (LPLISTSTRUCT
*) &(*lppls
)->lpNext
;
1543 hItem
= LIST_HEAP_ALLOC(lphl
, GMEM_MOVEABLE
, sizeof(LISTSTRUCT
));
1544 lplsnew
= (LPLISTSTRUCT
) LIST_HEAP_ADDR(lphl
, hItem
);
1546 if (lplsnew
== NULL
) {
1547 printf("ListBoxInsertString() // Bad allocation of new item !\n");
1551 ListBoxDefaultItem(hwnd
, wndPtr
, lphl
, lplsnew
);
1552 lplsnew
->hMem
= hItem
;
1553 lplsnew
->lpNext
= *lppls
;
1558 if (HasStrings(wndPtr
)) {
1559 hStr
= LIST_HEAP_ALLOC(lphl
, GMEM_MOVEABLE
, strlen(newstr
) + 1);
1560 str
= (LPSTR
)LIST_HEAP_ADDR(lphl
, hStr
);
1561 if (str
== NULL
) return LB_ERRSPACE
;
1562 strcpy(str
, newstr
);
1564 lplsnew
->itemText
= str
;
1565 dprintf_listbox(stddeb
,"ListBoxInsertString // LBS_HASSTRINGS after strcpy '%s'\n", str
);
1567 lplsnew
->itemText
= NULL
;
1568 lplsnew
->dis
.itemData
= (DWORD
)newstr
;
1571 lplsnew
->dis
.itemID
= lphl
->ItemsCount
;
1572 lplsnew
->hData
= hStr
;
1574 if ((wndPtr
->dwStyle
& LBS_OWNERDRAWFIXED
) && (lphl
->ItemsCount
== 1)) {
1575 ListBoxAskMeasure(wndPtr
, lphl
, lplsnew
);
1578 if (wndPtr
->dwStyle
& LBS_OWNERDRAWVARIABLE
)
1579 ListBoxAskMeasure(wndPtr
, lphl
, lplsnew
);
1581 SetScrollRange(hwnd
, SB_VERT
, 1, ListMaxFirstVisible(lphl
),
1582 (lphl
->FirstVisible
!= 1 && lphl
->bRedrawFlag
));
1584 if (lphl
->ItemsPerColumn
!= 0)
1585 SetScrollRange(hwnd
, SB_HORZ
, 1, lphl
->ItemsVisible
/
1586 lphl
->ItemsPerColumn
+ 1,
1587 (lphl
->FirstVisible
!= 1 && lphl
->bRedrawFlag
));
1589 if ((lphl
->FirstVisible
<= uIndex
) &&
1590 ((lphl
->FirstVisible
+ lphl
->ItemsVisible
) >= uIndex
)) {
1591 InvalidateRect(hwnd
, NULL
, TRUE
);
1595 dprintf_listbox(stddeb
,"ListBoxInsertString // count=%d\n", lphl
->ItemsCount
);
1600 int ListBoxGetText(HWND hwnd
, UINT uIndex
, LPSTR OutStr
, BOOL bItemData
)
1606 wndPtr
= WIN_FindWndPtr(hwnd
);
1608 if (!OutStr
&& !bItemData
) {
1609 dprintf_listbox(stddeb
, "ListBoxGetText // OutStr==NULL\n");
1613 if (!bItemData
) *OutStr
=0;
1615 if ((lpls
= ListBoxGetItem (hwnd
, uIndex
)) == NULL
)
1619 return lpls
->dis
.itemData
;
1621 if (!HasStrings(wndPtr
)) {
1622 *((long *)OutStr
) = lpls
->dis
.itemData
;
1626 strcpy(OutStr
, lpls
->itemText
);
1627 return strlen(OutStr
);
1630 int ListBoxSetItemData(HWND hwnd
, UINT uIndex
, DWORD ItemData
)
1635 if ((lpls
= ListBoxGetItem(hwnd
, uIndex
)) == NULL
)
1638 lpls
->dis
.itemData
= ItemData
;
1643 int ListBoxDeleteString(HWND hwnd
, UINT uIndex
)
1648 LPLISTSTRUCT lpls
, lpls2
;
1651 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
1652 if (lphl
== NULL
) return LB_ERR
;
1654 if (uIndex
>= lphl
->ItemsCount
) return LB_ERR
;
1656 lpls
= lphl
->lpFirst
;
1657 if (lpls
== NULL
) return LB_ERR
;
1660 lphl
->lpFirst
= lpls
->lpNext
;
1662 for(Count
= 0; Count
< uIndex
; Count
++) {
1663 if (lpls
->lpNext
== NULL
) return LB_ERR
;
1666 lpls
= (LPLISTSTRUCT
)lpls
->lpNext
;
1668 lpls2
->lpNext
= (LPLISTSTRUCT
)lpls
->lpNext
;
1673 if (lpls
->hData
!= 0) LIST_HEAP_FREE(lphl
, lpls
->hData
);
1674 if (lpls
->hMem
!= 0) LIST_HEAP_FREE(lphl
, lpls
->hMem
);
1676 SetScrollRange(hwnd
, SB_VERT
, 1, ListMaxFirstVisible(lphl
), TRUE
);
1677 if (lphl
->ItemsPerColumn
!= 0)
1678 SetScrollRange(hwnd
, SB_HORZ
, 1, lphl
->ItemsVisible
/
1679 lphl
->ItemsPerColumn
+ 1, TRUE
);
1681 if ((lphl
->FirstVisible
<= uIndex
) &&
1682 ((lphl
->FirstVisible
+ lphl
->ItemsVisible
) >= uIndex
)) {
1683 InvalidateRect(hwnd
, NULL
, TRUE
);
1687 return lphl
->ItemsCount
;
1691 int ListBoxFindString(HWND hwnd
, UINT nFirst
, LPSTR MatchStr
)
1697 UINT First
= nFirst
+ 1;
1699 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
1701 if (lphl
== NULL
) return LB_ERR
;
1703 if (First
> lphl
->ItemsCount
) return LB_ERR
;
1705 lpls
= ListBoxGetItem(hwnd
, First
);
1707 while(lpls
!= NULL
) {
1708 if (HasStrings(wndPtr
)) {
1709 if (strstr(lpls
->itemText
, MatchStr
) == lpls
->itemText
) return Count
;
1710 } else if (wndPtr
->dwStyle
& LBS_SORT
) {
1711 /* XXX Do a compare item */
1714 if (lpls
->dis
.itemData
== (DWORD
)MatchStr
) return Count
;
1716 lpls
= lpls
->lpNext
;
1720 /* Start over at top */
1722 lpls
= lphl
->lpFirst
;
1724 while (Count
< First
) {
1725 if (HasStrings(wndPtr
)) {
1726 if (strstr(lpls
->itemText
, MatchStr
) == lpls
->itemText
) return Count
;
1727 } else if (wndPtr
->dwStyle
& LBS_SORT
) {
1728 /* XXX Do a compare item */
1731 if (lpls
->dis
.itemData
== (DWORD
)MatchStr
) return Count
;
1733 lpls
= lpls
->lpNext
;
1741 int ListBoxResetContent(HWND hwnd
)
1748 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
1749 if (lphl
== NULL
) return LB_ERR
;
1751 if (lphl
->ItemsCount
== 0) return 0;
1753 lpls
= lphl
->lpFirst
;
1755 dprintf_listbox(stddeb
, "ListBoxResetContent // ItemCount = %d\n",
1758 for(i
= 0; i
< lphl
->ItemsCount
; i
++) {
1761 if (lpls
== NULL
) return LB_ERR
;
1763 lpls2
= lpls
->lpNext
;
1766 dprintf_listbox(stddeb
,"ResetContent #%u\n", i
);
1767 if (lpls
->hData
!= 0 && lpls
->hData
!= lpls
->hMem
)
1768 LIST_HEAP_FREE(lphl
, lpls
->hData
);
1770 if (lpls
->hMem
!= 0) LIST_HEAP_FREE(lphl
, lpls
->hMem
);
1776 lphl
->lpFirst
= NULL
;
1777 lphl
->FirstVisible
= 1;
1778 lphl
->ItemsCount
= 0;
1779 lphl
->ItemFocused
= -1;
1780 lphl
->PrevFocused
= -1;
1782 SetScrollRange(hwnd
, SB_VERT
, 1, ListMaxFirstVisible(lphl
), TRUE
);
1784 if (lphl
->ItemsPerColumn
!= 0)
1785 SetScrollRange(hwnd
, SB_HORZ
, 1, lphl
->ItemsVisible
/
1786 lphl
->ItemsPerColumn
+ 1, TRUE
);
1788 InvalidateRect(hwnd
, NULL
, TRUE
);
1795 int ListBoxSetCurSel(HWND hwnd
, WORD wIndex
)
1802 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
1803 if (lphl
== NULL
) return LB_ERR
;
1805 if (wndPtr
->dwStyle
& LBS_MULTIPLESEL
) return 0;
1807 if (lphl
->ItemFocused
!= -1) {
1808 lpls
= ListBoxGetItem(hwnd
, lphl
->ItemFocused
);
1809 if (lpls
== 0) return LB_ERR
;
1810 lpls
->dis
.itemState
= 0;
1813 if (wIndex
!= (UINT
)-1) {
1814 lphl
->ItemFocused
= wIndex
;
1815 lpls
= ListBoxGetItem(hwnd
, wIndex
);
1816 if (lpls
== 0) return LB_ERR
;
1817 lpls
->dis
.itemState
= ODS_SELECTED
| ODS_FOCUS
;
1825 int ListBoxSetSel(HWND hwnd
, WORD wIndex
, WORD state
)
1832 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
1833 if (lphl
== NULL
) return LB_ERR
;
1835 if (!(wndPtr
->dwStyle
& LBS_MULTIPLESEL
)) return 0;
1837 if (wIndex
== (UINT
)-1) {
1838 lpls
= lphl
->lpFirst
;
1840 while (lpls
!= NULL
) {
1841 lpls
->dis
.itemState
= state
;
1842 lpls
= lpls
->lpNext
;
1848 if (wIndex
>= lphl
->ItemsCount
) return LB_ERR
;
1850 lpls
= ListBoxGetItem(hwnd
, wIndex
);
1851 lpls
->dis
.itemState
= state
;
1857 int ListBoxGetSel(HWND hwnd
, WORD wIndex
)
1861 if ((lpls
= ListBoxGetItem(hwnd
, wIndex
)) == NULL
) return LB_ERR
;
1863 return lpls
->dis
.itemState
;
1867 int ListBoxDirectory(HWND hwnd
, UINT attrib
, LPSTR filespec
)
1869 struct dosdirent
*dp
, *dp_old
;
1870 int x
, wRet
= LB_OKAY
;
1877 dprintf_listbox(stddeb
,"ListBoxDirectory: %s, %4x\n",filespec
,attrib
);
1879 if( strchr( filespec
, '\\' ) || strchr( filespec
, ':' ) ) {
1880 drive
= DOS_GetDefaultDrive();
1881 if( filespec
[1] == ':' ) {
1882 drive
= toupper(filespec
[0]) - 'A';
1885 strcpy(temp
,filespec
);
1886 tstr
= strrchr(temp
, '\\');
1888 DOS_SetDefaultDrive( drive
);
1891 filespec
= tstr
+ 1;
1892 DOS_ChangeDir( drive
, temp
);
1893 if (!DOS_ChangeDir( drive
, temp
)) return 0;
1895 dprintf_listbox(stddeb
,"Changing directory to %c:%s, filemask is %s\n",
1896 drive
+'A', temp
, filespec
);
1898 lphl
= ListBoxGetStorageHeader(hwnd
);
1899 if (lphl
== NULL
) return LB_ERR
;
1900 if ((dp
= (struct dosdirent
*)DOS_opendir(filespec
)) ==NULL
) return 0;
1902 OldFlag
= lphl
->bRedrawFlag
;
1903 lphl
->bRedrawFlag
= FALSE
;
1904 while ((dp
= (struct dosdirent
*)DOS_readdir(dp
))) {
1905 if (!dp
->inuse
) break;
1906 dprintf_listbox( stddeb
, "ListBoxDirectory %p '%s' !\n", dp
->filename
,
1908 if (dp
->attribute
& FA_DIREC
) {
1909 if (attrib
& DDL_DIRECTORY
&& strcmp(dp
->filename
, ".") != 0) {
1910 sprintf(temp
, "[%s]", dp
->filename
);
1911 if ( (wRet
= ListBoxAddString(hwnd
, temp
)) == LB_ERR
) break;
1915 if (attrib
& DDL_EXCLUSIVE
) {
1916 if (attrib
& (DDL_READWRITE
| DDL_READONLY
| DDL_HIDDEN
|
1918 if ( (wRet
= ListBoxAddString(hwnd
, dp
->filename
))
1922 if ( (wRet
= ListBoxAddString(hwnd
, dp
->filename
))
1927 DOS_closedir(dp_old
);
1929 if (attrib
& DDL_DRIVES
) {
1930 for (x
=0;x
!=MAX_DOS_DRIVES
;x
++) {
1931 if (DOS_ValidDrive(x
)) {
1932 sprintf(temp
, "[-%c-]", 'a'+x
);
1933 if((wRet
= ListBoxInsertString(hwnd
, (UINT
)-1, temp
)) == LB_ERR
) break;
1937 lphl
->bRedrawFlag
= OldFlag
;
1939 InvalidateRect(hwnd
, NULL
, TRUE
);
1942 dprintf_listbox(stddeb
,"End of ListBoxDirectory !\n");
1943 return 1; /* FIXME: Should be 0 if "filespec" is invalid */
1947 int ListBoxGetItemRect(HWND hwnd
, WORD wIndex
, LPRECT lprect
)
1952 if ((lpls
= ListBoxGetItem(hwnd
, wIndex
)) == NULL
) return LB_ERR
;
1954 *(lprect
) = lpls
->dis
.rcItem
;
1960 int ListBoxSetItemHeight(HWND hwnd
, WORD wIndex
, long height
)
1967 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
1968 if (lphl
== NULL
) return LB_ERR
;
1970 if (!(wndPtr
->dwStyle
& LBS_OWNERDRAWVARIABLE
)) {
1971 lphl
->StdItemHeight
= (short)height
;
1972 InvalidateRect(hwnd
, NULL
, TRUE
);
1978 if ((lpls
= ListBoxGetItem(hwnd
, wIndex
)) == NULL
) return LB_ERR
;
1980 lpls
->dis
.rcItem
.bottom
= lpls
->dis
.rcItem
.top
+ (short)height
;
1981 InvalidateRect(hwnd
, NULL
, TRUE
);
1987 int ListBoxDefaultItem(HWND hwnd
, WND
*wndPtr
,
1988 LPHEADLIST lphl
, LPLISTSTRUCT lpls
)
1993 if (wndPtr
== NULL
|| lphl
== NULL
|| lpls
== NULL
) {
1994 fprintf(stderr
,"ListBoxDefaultItem() // Bad Pointers !\n");
1998 GetClientRect(hwnd
, &rect
);
1999 SetRect(&lpls
->dis
.rcItem
, 0, 0, rect
.right
, lphl
->StdItemHeight
);
2001 lpls
->dis
.CtlType
= lphl
->DrawCtlType
;
2002 lpls
->dis
.CtlID
= wndPtr
->wIDmenu
;
2003 lpls
->dis
.itemID
= 0;
2004 lpls
->dis
.itemAction
= 0;
2005 lpls
->dis
.itemState
= 0;
2006 lpls
->dis
.hwndItem
= hwnd
;
2008 lpls
->dis
.itemData
= 0;
2015 int ListBoxFindNextMatch(HWND hwnd
, WORD wChar
)
2023 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
2024 if (lphl
== NULL
) return LB_ERR
;
2025 lpls
= lphl
->lpFirst
;
2026 if (lpls
== NULL
) return LB_ERR
;
2027 if (wChar
< ' ') return LB_ERR
;
2029 if (!HasStrings(wndPtr
)) return LB_ERR
;
2032 while(lpls
!= NULL
) {
2033 if (Count
> lphl
->ItemFocused
) {
2034 if (*(lpls
->itemText
) == (char)wChar
) {
2035 if ((wndPtr
->dwStyle
& LBS_MULTIPLESEL
) == LBS_MULTIPLESEL
) {
2036 lphl
->ItemFocused
= Count
;
2037 ListBoxScrolltoFocus(hwnd
);
2040 ListBoxSetCurSel(hwnd
, Count
);
2042 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
2043 InvalidateRect(hwnd
, NULL
, TRUE
);
2048 lpls
= (LPLISTSTRUCT
)lpls
->lpNext
;
2052 lpls
= lphl
->lpFirst
;
2053 while(lpls
!= NULL
) {
2054 if (*(lpls
->itemText
) == (char)wChar
) {
2055 if (Count
== lphl
->ItemFocused
) return LB_ERR
;
2057 if ((wndPtr
->dwStyle
& LBS_MULTIPLESEL
) == LBS_MULTIPLESEL
) {
2058 lphl
->ItemFocused
= Count
;
2059 ListBoxScrolltoFocus(hwnd
);
2062 ListBoxSetCurSel(hwnd
, Count
);
2064 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
2065 InvalidateRect(hwnd
, NULL
, TRUE
);
2069 lpls
= lpls
->lpNext
;
2076 /************************************************************************
2077 * DlgDirSelect [USER.99]
2079 BOOL
DlgDirSelect(HWND hDlg
, LPSTR lpStr
, int nIDLBox
)
2085 dprintf_listbox( stddeb
, "DlgDirSelect(%04X, '%s', %d) \n", hDlg
, lpStr
,
2088 hwnd
= GetDlgItem(hDlg
, nIDLBox
);
2089 lphl
= ListBoxGetStorageHeader(hwnd
);
2090 if( lphl
->ItemFocused
== -1 ) {
2091 dprintf_listbox( stddeb
, "Nothing selected!\n" );
2094 ListBoxGetText(hwnd
, lphl
->ItemFocused
, (LPSTR
)s
, FALSE
);
2095 dprintf_listbox( stddeb
, "Selection is %s\n", s
);
2098 strncpy( lpStr
, s
+2, strlen(s
)-4 ); /* device name */
2099 lpStr
[ strlen(s
)-4 ] = 0;
2100 strcat( lpStr
, ":" );
2103 strncpy( lpStr
, s
+1, strlen(s
)-2 ); /* directory name */
2104 lpStr
[ strlen(s
)-2 ] = 0;
2105 strcat( lpStr
, "\\" );
2107 dprintf_listbox( stddeb
, "Returning %s\n", lpStr
);
2111 strcpy( lpStr
, s
); /* file name */
2112 dprintf_listbox( stddeb
, "Returning %s\n", lpStr
);
2118 /************************************************************************
2119 * DlgDirList [USER.100]
2121 int DlgDirList(HWND hDlg
, LPSTR lpPathSpec
,
2122 int nIDLBox
, int nIDStat
, WORD wType
)
2126 dprintf_listbox(stddeb
,"DlgDirList(%04X, '%s', %d, %d, %04X) \n",
2127 hDlg
, lpPathSpec
, nIDLBox
, nIDStat
, wType
);
2129 hWnd
= GetDlgItem(hDlg
, nIDLBox
);
2133 ListBoxResetContent(hWnd
);
2135 ret
=ListBoxDirectory(hWnd
, wType
, lpPathSpec
);
2143 drive
= DOS_GetDefaultDrive();
2144 hTemp
= USER_HEAP_ALLOC( 256 );
2145 temp
= (char *) USER_HEAP_LIN_ADDR( hTemp
);
2146 strcpy( temp
+3, DOS_GetCurrentDir(drive
) );
2147 if( temp
[3] == '\\' ) {
2148 temp
[1] = 'A'+drive
;
2150 SendDlgItemMessage( hDlg
, nIDStat
, WM_SETTEXT
, 0,
2151 USER_HEAP_SEG_ADDR(hTemp
) + 1 );
2154 temp
[0] = 'A'+drive
;
2157 SendDlgItemMessage( hDlg
, nIDStat
, WM_SETTEXT
, 0,
2158 USER_HEAP_SEG_ADDR(hTemp
) );
2160 USER_HEAP_FREE( hTemp
);
2166 /* Returns: 0 if nothing needs to be changed */
2167 /* 1 if FirstVisible changed */
2169 int ListBoxScrolltoFocus(HWND hwnd
)
2176 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
2178 if (lphl
->ItemsCount
== 0) return 0;
2179 if (lphl
->ItemFocused
== -1) return 0;
2181 end
= lphl
->FirstVisible
+ lphl
->ItemsVisible
- 2;
2183 if (lphl
->ItemFocused
< lphl
->FirstVisible
- 1) {
2184 lphl
->FirstVisible
= lphl
->ItemFocused
+ 1;
2186 else if (lphl
->ItemFocused
> end
) {
2187 UINT maxFirstVisible
= ListMaxFirstVisible(lphl
);
2189 lphl
->FirstVisible
= lphl
->ItemFocused
;
2191 if (lphl
->FirstVisible
> maxFirstVisible
) {
2192 lphl
->FirstVisible
= maxFirstVisible
;
2199 /* Send notification "code" as part of a WM_COMMAND-message if hwnd
2200 has the LBS_NOTIFY style */
2201 void ListBoxSendNotification(HWND hwnd
, WORD code
)
2205 lphl
= ListBoxGetWindowAndStorage(hwnd
, &wndPtr
);
2207 if (wndPtr
&& (wndPtr
->dwStyle
& LBS_NOTIFY
))
2208 SendMessage(lphl
->hWndLogicParent
, WM_COMMAND
,
2209 wndPtr
->wIDmenu
, MAKELONG(hwnd
, code
));