4 * Copyright Martin Ayotte, 1993
5 * Copyright Constantine Sapuntzakis, 1995
11 * - check if multi-column listboxes work
12 * - implement more messages and styles
29 #define LIST_HEAP_ALLOC(lphl,f,size) ((int)HEAP_Alloc(&lphl->Heap,f,size) & 0xffff)
30 #define LIST_HEAP_FREE(lphl,handle) (HEAP_Free(&lphl->Heap,LIST_HEAP_ADDR(lphl,handle)))
31 #define LIST_HEAP_ADDR(lphl,handle) \
32 ((void *)((handle) ? ((handle) | ((int)lphl->Heap & 0xffff0000)) : 0))
34 /* FIXME: shouldn't each listbox have its own heap? */
35 #define LIST_HEAP_ALLOC(lphl,f,size) USER_HEAP_ALLOC(size)
36 #define LIST_HEAP_FREE(lphl,handle) USER_HEAP_FREE(handle)
37 #define LIST_HEAP_ADDR(lphl,handle) USER_HEAP_LIN_ADDR(handle)
38 #define LIST_HEAP_SEG_ADDR(lphl,handle) USER_HEAP_SEG_ADDR(handle)
41 #define LIST_HEAP_SIZE 0x10000
43 static void ListBoxInitialize(LPHEADLIST lphl
)
47 lphl
->ItemsVisible
= 0;
48 lphl
->FirstVisible
= 0;
49 lphl
->ColumnsVisible
= 1;
50 lphl
->ItemsPerColumn
= 0;
51 lphl
->ItemFocused
= -1;
52 lphl
->PrevFocused
= -1;
55 void CreateListBoxStruct(HWND hwnd
, WORD CtlType
, LONG styles
, HWND parent
)
59 lphl
= (LPHEADLIST
)malloc(sizeof(HEADLIST
));
60 SetWindowLong(hwnd
, 0, (LONG
)lphl
);
62 fprintf(stderr
,"malloc failed in CreateListBoxStruct()\n");
63 exit(1); /* Things won't get better */
66 ListBoxInitialize(lphl
);
67 lphl
->DrawCtlType
= CtlType
;
68 lphl
->CtlID
= GetWindowWord(hwnd
,GWW_ID
);
69 lphl
->bRedrawFlag
= TRUE
;
71 lphl
->TabStops
= NULL
;
72 lphl
->hFont
= GetStockObject(SYSTEM_FONT
);
73 lphl
->hParent
= parent
;
74 lphl
->StdItemHeight
= 15; /* FIXME: should get the font height */
75 lphl
->dwStyle
= styles
;
76 lphl
->OwnerDrawn
= styles
& (LBS_OWNERDRAWFIXED
| LBS_OWNERDRAWVARIABLE
);
77 lphl
->HasStrings
= (styles
& LBS_HASSTRINGS
) || !lphl
->OwnerDrawn
;
79 if (lphl
->OwnerDrawn
) {
82 lphl
->hDrawItemStruct
= USER_HEAP_ALLOC(sizeof(DRAWITEMSTRUCT
));
83 lphl
->needMeasure
= TRUE
;
84 dummyls
.mis
.CtlType
= lphl
->DrawCtlType
;
85 dummyls
.mis
.CtlID
= lphl
->CtlID
;
86 dummyls
.mis
.itemID
= -1;
87 dummyls
.mis
.itemWidth
= 0; /* ignored */
88 dummyls
.mis
.itemData
= 0;
90 ListBoxAskMeasure(lphl
,&dummyls
);
92 lphl
->hDrawItemStruct
= 0;
96 HeapHandle
= GlobalAlloc(GMEM_FIXED
, LIST_HEAP_SIZE
);
97 HeapBase
= GlobalLock(HeapHandle
);
98 HEAP_Init(&lphl
->Heap
, HeapBase
, LIST_HEAP_SIZE
);
102 void DestroyListBoxStruct(LPHEADLIST lphl
)
104 if (lphl
->hDrawItemStruct
)
105 USER_HEAP_FREE(lphl
->hDrawItemStruct
);
107 /* XXX need to free lphl->Heap */
111 static LPHEADLIST
ListBoxGetStorageHeader(HWND hwnd
)
113 return (LPHEADLIST
)GetWindowLong(hwnd
,0);
116 /* Send notification "code" as part of a WM_COMMAND-message if hwnd
117 has the LBS_NOTIFY style */
118 void ListBoxSendNotification(LPHEADLIST lphl
, HWND hwnd
, WORD code
)
120 if (lphl
->dwStyle
& LBS_NOTIFY
)
122 SendMessage(lphl
->hParent
, WM_COMMAND
,
123 MAKEWPARAM(lphl
->CtlID
,code
), (LPARAM
)hwnd
);
125 SendMessage(lphl
->hParent
, WM_COMMAND
,
126 lphl
->CtlID
, MAKELONG(hwnd
, code
));
131 /* get the maximum value of lphl->FirstVisible */
132 int ListMaxFirstVisible(LPHEADLIST lphl
)
134 int m
= lphl
->ItemsCount
-lphl
->ItemsVisible
;
135 return (m
< 0) ? 0 : m
;
139 void ListBoxUpdateWindow(HWND hwnd
, LPHEADLIST lphl
, BOOL repaint
)
141 SetScrollRange(hwnd
, SB_VERT
, 0, ListMaxFirstVisible(lphl
), TRUE
);
142 if (lphl
->ItemsPerColumn
!= 0) {
143 SetScrollRange(hwnd
, SB_HORZ
, 1, lphl
->ItemsVisible
/
144 lphl
->ItemsPerColumn
+ 1, TRUE
);
146 if (repaint
&& lphl
->bRedrawFlag
) {
147 InvalidateRect(hwnd
, NULL
, TRUE
);
151 /* Returns: 0 if nothing needs to be changed */
152 /* 1 if FirstVisible changed */
154 int ListBoxScrollToFocus(LPHEADLIST lphl
)
158 if (lphl
->ItemsCount
== 0) return 0;
159 if (lphl
->ItemFocused
== -1) return 0;
161 end
= lphl
->FirstVisible
+ lphl
->ItemsVisible
- 1;
163 if (lphl
->ItemFocused
< lphl
->FirstVisible
) {
164 lphl
->FirstVisible
= lphl
->ItemFocused
;
167 if (lphl
->ItemFocused
> end
) {
168 WORD maxFirstVisible
= ListMaxFirstVisible(lphl
);
170 lphl
->FirstVisible
= lphl
->ItemFocused
;
172 if (lphl
->FirstVisible
> maxFirstVisible
) {
173 lphl
->FirstVisible
= maxFirstVisible
;
182 LPLISTSTRUCT
ListBoxGetItem(LPHEADLIST lphl
, UINT uIndex
)
187 if (uIndex
>= lphl
->ItemsCount
) return NULL
;
189 lpls
= lphl
->lpFirst
;
190 while (Count
++ < uIndex
) lpls
= lpls
->lpNext
;
195 void ListBoxDrawItem (HWND hwnd
, LPHEADLIST lphl
, HDC hdc
, LPLISTSTRUCT lpls
,
196 RECT
*rect
, WORD itemAction
, WORD itemState
)
198 if (lphl
->OwnerDrawn
) {
199 DRAWITEMSTRUCT
*dis
= USER_HEAP_LIN_ADDR(lphl
->hDrawItemStruct
);
201 dis
->CtlID
= lpls
->mis
.CtlID
;
202 dis
->CtlType
= lpls
->mis
.CtlType
;
203 dis
->itemID
= lpls
->mis
.itemID
;
205 dis
->hwndItem
= hwnd
;
206 dis
->itemData
= lpls
->mis
.itemData
;
207 dis
->itemAction
= itemAction
;
208 dis
->itemState
= itemState
;
210 SendMessage(lphl
->hParent
, WM_DRAWITEM
,
211 0, (LPARAM
)USER_HEAP_SEG_ADDR(lphl
->hDrawItemStruct
));
213 if (itemAction
== ODA_DRAWENTIRE
|| itemAction
== ODA_SELECT
) {
215 DWORD dwOldTextColor
= 0;
217 OldBkMode
= SetBkMode(hdc
, TRANSPARENT
);
219 if (itemState
!= 0) {
220 dwOldTextColor
= SetTextColor(hdc
, 0x00FFFFFFL
);
221 FillRect(hdc
, rect
, GetStockObject(BLACK_BRUSH
));
224 if (lphl
->dwStyle
& LBS_USETABSTOPS
) {
225 TabbedTextOut(hdc
, rect
->left
+ 5, rect
->top
+ 2,
226 (char *)lpls
->itemText
, strlen((char *)lpls
->itemText
),
227 lphl
->iNumStops
, lphl
->TabStops
, 0);
229 TextOut(hdc
, rect
->left
+ 5, rect
->top
+ 2,
230 (char *)lpls
->itemText
, strlen((char *)lpls
->itemText
));
233 if (itemState
!= 0) {
234 SetTextColor(hdc
, dwOldTextColor
);
237 SetBkMode(hdc
, OldBkMode
);
238 } else DrawFocusRect(hdc
, rect
);
245 int ListBoxFindMouse(LPHEADLIST lphl
, int X
, int Y
)
247 LPLISTSTRUCT lpls
= lphl
->lpFirst
;
251 point
.x
= X
; point
.y
= Y
;
252 if (lphl
->ItemsCount
== 0) return LB_ERR
;
254 for(i
= 0; i
< lphl
->FirstVisible
; i
++) {
255 if (lpls
== NULL
) return LB_ERR
;
258 for(j
= 0; j
< lphl
->ItemsVisible
; i
++, j
++) {
259 if (lpls
== NULL
) return LB_ERR
;
260 if (PtInRect(&lpls
->itemRect
,point
)) {
265 dprintf_listbox(stddeb
,"ListBoxFindMouse: not found\n");
270 void ListBoxAskMeasure(LPHEADLIST lphl
, LPLISTSTRUCT lpls
)
272 HANDLE hTemp
= USER_HEAP_ALLOC( sizeof(MEASUREITEMSTRUCT
) );
273 MEASUREITEMSTRUCT
*lpmeasure
= (MEASUREITEMSTRUCT
*) USER_HEAP_LIN_ADDR(hTemp
);
275 if (lpmeasure
== NULL
) {
276 fprintf(stderr
,"ListBoxAskMeasure() out of memory !\n");
280 *lpmeasure
= lpls
->mis
;
281 lpmeasure
->itemHeight
= lphl
->StdItemHeight
;
282 SendMessage(lphl
->hParent
, WM_MEASUREITEM
, 0, (LPARAM
)USER_HEAP_SEG_ADDR(hTemp
));
284 if (lphl
->dwStyle
& LBS_OWNERDRAWFIXED
) {
285 lphl
->StdItemHeight
= lpmeasure
->itemHeight
;
286 lphl
->needMeasure
= FALSE
;
289 USER_HEAP_FREE(hTemp
);
293 LPLISTSTRUCT
ListBoxCreateItem(LPHEADLIST lphl
, int id
)
295 LPLISTSTRUCT lplsnew
= (LPLISTSTRUCT
)malloc(sizeof(LISTSTRUCT
));
297 if (lplsnew
== NULL
) return NULL
;
299 lplsnew
->itemState
= 0;
300 lplsnew
->mis
.CtlType
= lphl
->DrawCtlType
;
301 lplsnew
->mis
.CtlID
= lphl
->CtlID
;
302 lplsnew
->mis
.itemID
= id
;
303 lplsnew
->mis
.itemHeight
= lphl
->StdItemHeight
;
304 lplsnew
->mis
.itemWidth
= 0; /* ignored */
305 lplsnew
->mis
.itemData
= 0;
306 SetRect(&lplsnew
->itemRect
, 0, 0, 0, 0);
312 int ListBoxInsertString(LPHEADLIST lphl
, UINT uIndex
, LPSTR newstr
)
314 LPLISTSTRUCT
*lppls
, lplsnew
, lpls
;
319 dprintf_listbox(stddeb
,"ListBoxInsertString(%d, %p);\n", uIndex
, newstr
);
321 if (uIndex
== (UINT
)-1)
322 uIndex
= lphl
->ItemsCount
;
324 lppls
= &lphl
->lpFirst
;
325 for(Count
= 0; Count
< uIndex
; Count
++) {
326 if (*lppls
== NULL
) return LB_ERR
;
327 lppls
= (LPLISTSTRUCT
*) &(*lppls
)->lpNext
;
330 lplsnew
= ListBoxCreateItem(lphl
, Count
);
332 if (lplsnew
== NULL
) {
333 printf("ListBoxInsertString() out of memory !\n");
337 lplsnew
->lpNext
= *lppls
;
342 if (lphl
->HasStrings
) {
343 dprintf_listbox(stddeb
," string: %s\n", newstr
);
344 hStr
= LIST_HEAP_ALLOC(lphl
, LMEM_MOVEABLE
, strlen(newstr
) + 1);
345 str
= (LPSTR
)LIST_HEAP_ADDR(lphl
, hStr
);
346 if (str
== NULL
) return LB_ERRSPACE
;
348 lplsnew
->itemText
= str
;
349 /* I'm not so sure about the next one */
350 lplsnew
->mis
.itemData
= 0;
352 lplsnew
->itemText
= NULL
;
353 lplsnew
->mis
.itemData
= (DWORD
)newstr
;
356 lplsnew
->mis
.itemID
= uIndex
;
357 lplsnew
->hData
= hStr
;
359 /* adjust the itemID field of the following entries */
360 for(lpls
= lplsnew
->lpNext
; lpls
!= NULL
; lpls
= lpls
->lpNext
) {
364 if (lphl
->needMeasure
) {
365 ListBoxAskMeasure(lphl
, lplsnew
);
368 dprintf_listbox(stddeb
,"ListBoxInsertString // count=%d\n", lphl
->ItemsCount
);
373 int ListBoxAddString(LPHEADLIST lphl
, LPSTR newstr
)
375 UINT pos
= (UINT
) -1;
377 if (lphl
->HasStrings
&& (lphl
->dwStyle
& LBS_SORT
)) {
378 LPLISTSTRUCT lpls
= lphl
->lpFirst
;
379 for (pos
= 0; lpls
!= NULL
; lpls
= lpls
->lpNext
, pos
++)
380 if (strcmp(lpls
->itemText
, newstr
) >= 0)
383 return ListBoxInsertString(lphl
, pos
, newstr
);
387 int ListBoxGetText(LPHEADLIST lphl
, UINT uIndex
, LPSTR OutStr
)
392 dprintf_listbox(stddeb
, "ListBoxGetText // OutStr==NULL\n");
396 lpls
= ListBoxGetItem (lphl
, uIndex
);
397 if (lpls
== NULL
) return LB_ERR
;
399 if (!lphl
->HasStrings
) {
400 *((long *)OutStr
) = lpls
->mis
.itemData
;
404 strcpy(OutStr
, lpls
->itemText
);
405 return strlen(OutStr
);
409 DWORD
ListBoxGetItemData(LPHEADLIST lphl
, UINT uIndex
)
413 lpls
= ListBoxGetItem (lphl
, uIndex
);
414 if (lpls
== NULL
) return LB_ERR
;
415 return lpls
->mis
.itemData
;
419 int ListBoxSetItemData(LPHEADLIST lphl
, UINT uIndex
, DWORD ItemData
)
421 LPLISTSTRUCT lpls
= ListBoxGetItem(lphl
, uIndex
);
423 if (lpls
== NULL
) return LB_ERR
;
424 lpls
->mis
.itemData
= ItemData
;
429 int ListBoxDeleteString(LPHEADLIST lphl
, UINT uIndex
)
431 LPLISTSTRUCT lpls
, lpls2
;
434 if (uIndex
>= lphl
->ItemsCount
) return LB_ERR
;
436 lpls
= lphl
->lpFirst
;
437 if (lpls
== NULL
) return LB_ERR
;
440 lphl
->lpFirst
= lpls
->lpNext
;
442 LPLISTSTRUCT lpls2
= NULL
;
443 for(Count
= 0; Count
< uIndex
; Count
++) {
444 if (lpls
->lpNext
== NULL
) return LB_ERR
;
447 lpls
= (LPLISTSTRUCT
)lpls
->lpNext
;
449 lpls2
->lpNext
= lpls
->lpNext
;
452 /* adjust the itemID field of the following entries */
453 for(lpls2
= lpls
->lpNext
; lpls2
!= NULL
; lpls2
= lpls2
->lpNext
) {
459 if (lpls
->hData
!= 0) LIST_HEAP_FREE(lphl
, lpls
->hData
);
462 return lphl
->ItemsCount
;
466 int ListBoxFindString(LPHEADLIST lphl
, UINT nFirst
, SEGPTR MatchStr
)
470 UINT First
= nFirst
+ 1;
471 LPSTR lpMatchStr
= (LPSTR
)MatchStr
;
473 if (First
> lphl
->ItemsCount
) return LB_ERR
;
475 if (lphl
->HasStrings
) lpMatchStr
= PTR_SEG_TO_LIN(MatchStr
);
477 lpls
= ListBoxGetItem(lphl
, First
);
479 while(lpls
!= NULL
) {
480 if (lphl
->HasStrings
) {
481 if (strstr(lpls
->itemText
, lpMatchStr
) == lpls
->itemText
) return Count
;
482 } else if (lphl
->dwStyle
& LBS_SORT
) {
483 /* XXX Do a compare item */
486 if (lpls
->mis
.itemData
== (DWORD
)lpMatchStr
) return Count
;
492 /* Start over at top */
494 lpls
= lphl
->lpFirst
;
496 while (Count
< First
) {
497 if (lphl
->HasStrings
) {
498 if (strstr(lpls
->itemText
, lpMatchStr
) == lpls
->itemText
) return Count
;
499 } else if (lphl
->dwStyle
& LBS_SORT
) {
500 /* XXX Do a compare item */
502 if (lpls
->mis
.itemData
== (DWORD
)lpMatchStr
) return Count
;
512 int ListBoxResetContent(LPHEADLIST lphl
)
517 if (lphl
->ItemsCount
== 0) return 0;
519 dprintf_listbox(stddeb
, "ListBoxResetContent // ItemCount = %d\n",
522 for(i
= 0; i
< lphl
->ItemsCount
; i
++) {
523 lpls
= lphl
->lpFirst
;
524 if (lpls
== NULL
) return LB_ERR
;
526 lphl
->lpFirst
= lpls
->lpNext
;
527 if (lpls
->hData
!= 0) LIST_HEAP_FREE(lphl
, lpls
->hData
);
530 ListBoxInitialize(lphl
);
536 int ListBoxSetCurSel(LPHEADLIST lphl
, WORD wIndex
)
540 if (lphl
->dwStyle
& LBS_MULTIPLESEL
) return 0;
542 if (lphl
->ItemFocused
!= -1) {
543 lpls
= ListBoxGetItem(lphl
, lphl
->ItemFocused
);
544 if (lpls
== 0) return LB_ERR
;
548 if (wIndex
!= (UINT
)-1) {
549 lphl
->ItemFocused
= wIndex
;
550 lpls
= ListBoxGetItem(lphl
, wIndex
);
551 if (lpls
== 0) return LB_ERR
;
552 lpls
->itemState
= ODS_SELECTED
| ODS_FOCUS
;
561 int ListBoxSetSel(LPHEADLIST lphl
, WORD wIndex
, WORD state
)
565 if (!(lphl
->dwStyle
& LBS_MULTIPLESEL
)) return 0;
567 if (wIndex
== (UINT
)-1) {
568 for (lpls
= lphl
->lpFirst
; lpls
!= NULL
; lpls
= lpls
->lpNext
) {
569 lpls
->itemState
= state
;
574 if (wIndex
>= lphl
->ItemsCount
) return LB_ERR
;
576 lpls
= ListBoxGetItem(lphl
, wIndex
);
577 lpls
->itemState
= state
;
583 int ListBoxGetSel(LPHEADLIST lphl
, WORD wIndex
)
585 LPLISTSTRUCT lpls
= ListBoxGetItem(lphl
, wIndex
);
587 if (lpls
== NULL
) return LB_ERR
;
588 return lpls
->itemState
;
592 int ListBoxDirectory(LPHEADLIST lphl
, UINT attrib
, LPSTR filespec
)
594 struct dosdirent
*dp
, *dp_old
;
599 dprintf_listbox(stddeb
,"ListBoxDirectory: %s, %4x\n",filespec
,attrib
);
601 if (strchr(filespec
, '\\') || strchr(filespec
, ':')) {
602 drive
= DOS_GetDefaultDrive();
603 if (filespec
[1] == ':') {
604 drive
= toupper(filespec
[0]) - 'A';
607 strcpy(temp
,filespec
);
608 tstr
= strrchr(temp
, '\\');
611 filespec
+= tstr
- temp
+ 1;
612 if (!DOS_ChangeDir( drive
, temp
)) return 0;
614 DOS_SetDefaultDrive( drive
);
615 dprintf_listbox(stddeb
,"Changing directory to %c:%s, filemask is %s\n",
616 drive
+'A', temp
, filespec
);
619 if ((dp
= (struct dosdirent
*)DOS_opendir(filespec
)) ==NULL
) return 0;
621 while ((dp
= (struct dosdirent
*)DOS_readdir(dp
))) {
622 if (!dp
->inuse
) break;
623 dprintf_listbox(stddeb
, "ListBoxDirectory %p '%s' !\n", dp
->filename
,
625 if (dp
->attribute
& FA_DIREC
) {
626 if (attrib
& DDL_DIRECTORY
&& strcmp(dp
->filename
, ".") != 0) {
627 sprintf(temp
, "[%s]", dp
->filename
);
628 if (ListBoxAddString(lphl
, temp
) == LB_ERR
) break;
632 if (attrib
& DDL_EXCLUSIVE
) {
633 if (attrib
& (DDL_READWRITE
| DDL_READONLY
| DDL_HIDDEN
| DDL_SYSTEM
)) {
634 if (ListBoxAddString(lphl
, dp
->filename
) == LB_ERR
) break;
637 if (ListBoxAddString(lphl
, dp
->filename
) == LB_ERR
) break;
641 DOS_closedir(dp_old
);
643 if (attrib
& DDL_DRIVES
) {
645 for (x
= 0; x
!= MAX_DOS_DRIVES
; x
++) {
646 if (DOS_ValidDrive(x
)) {
647 sprintf(temp
, "[-%c-]", 'a'+x
);
648 if (ListBoxInsertString(lphl
, (UINT
)-1, temp
) == LB_ERR
) break;
656 int ListBoxGetItemRect(LPHEADLIST lphl
, WORD wIndex
, LPRECT lprect
)
658 LPLISTSTRUCT lpls
= ListBoxGetItem(lphl
,wIndex
);
660 if (lpls
== NULL
) return LB_ERR
;
661 *lprect
= lpls
->itemRect
;
666 int ListBoxSetItemHeight(LPHEADLIST lphl
, WORD wIndex
, long height
)
670 if (!(lphl
->dwStyle
& LBS_OWNERDRAWVARIABLE
)) {
671 lphl
->StdItemHeight
= (short)height
;
675 lpls
= ListBoxGetItem(lphl
, wIndex
);
676 if (lpls
== NULL
) return LB_ERR
;
678 lpls
->mis
.itemHeight
= height
;
683 int ListBoxFindNextMatch(LPHEADLIST lphl
, WORD wChar
)
688 if ((char)wChar
< ' ') return LB_ERR
;
689 if (!lphl
->HasStrings
) return LB_ERR
;
691 lpls
= lphl
->lpFirst
;
693 for (count
= 0; lpls
!= NULL
; lpls
= lpls
->lpNext
, count
++) {
694 if (tolower(*lpls
->itemText
) == tolower((char)wChar
)) break;
696 if (lpls
== NULL
) return LB_ERR
;
698 for(; lpls
!= NULL
; lpls
= lpls
->lpNext
, count
++) {
699 if (*lpls
->itemText
!= (char)wChar
)
701 if (count
> lphl
->ItemFocused
)
707 /***********************************************************************
710 static LONG
LBCreate(HWND hwnd
, WORD wParam
, LONG lParam
)
715 CreateListBoxStruct(hwnd
, ODT_LISTBOX
, GetWindowLong(hwnd
,GWL_STYLE
), GetParent(hwnd
));
716 lphl
= ListBoxGetStorageHeader(hwnd
);
717 dprintf_listbox(stddeb
,"ListBox WM_CREATE %p !\n", lphl
);
719 GetClientRect(hwnd
,&rect
);
720 lphl
->ColumnsWidth
= rect
.right
- rect
.left
;
722 SetScrollRange(hwnd
, SB_VERT
, 0, ListMaxFirstVisible(lphl
), TRUE
);
723 SetScrollRange(hwnd
, SB_HORZ
, 1, 1, TRUE
);
728 /***********************************************************************
731 static LONG
LBDestroy(HWND hwnd
, WORD wParam
, LONG lParam
)
733 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
735 ListBoxResetContent(lphl
);
737 DestroyListBoxStruct(lphl
);
738 dprintf_listbox(stddeb
,"ListBox WM_DESTROY %p !\n", lphl
);
742 /***********************************************************************
745 static LONG
LBVScroll(HWND hwnd
, WORD wParam
, LONG lParam
)
747 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
750 dprintf_listbox(stddeb
,"ListBox WM_VSCROLL w=%04X l=%08lX !\n",
752 y
= lphl
->FirstVisible
;
756 if (lphl
->FirstVisible
> 0)
757 lphl
->FirstVisible
--;
761 lphl
->FirstVisible
++;
765 if (lphl
->FirstVisible
> lphl
->ItemsVisible
) {
766 lphl
->FirstVisible
-= lphl
->ItemsVisible
;
768 lphl
->FirstVisible
= 0;
773 lphl
->FirstVisible
+= lphl
->ItemsVisible
;
777 lphl
->FirstVisible
= LOWORD(lParam
);
781 if (lphl
->FirstVisible
> ListMaxFirstVisible(lphl
))
782 lphl
->FirstVisible
= ListMaxFirstVisible(lphl
);
784 if (y
!= lphl
->FirstVisible
) {
785 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
786 InvalidateRect(hwnd
, NULL
, TRUE
);
791 /***********************************************************************
794 static LONG
LBHScroll(HWND hwnd
, WORD wParam
, LONG lParam
)
799 dprintf_listbox(stddeb
,"ListBox WM_HSCROLL w=%04X l=%08lX !\n",
801 lphl
= ListBoxGetStorageHeader(hwnd
);
802 y
= lphl
->FirstVisible
;
805 if (lphl
->FirstVisible
> lphl
->ItemsPerColumn
) {
806 lphl
->FirstVisible
-= lphl
->ItemsPerColumn
;
808 lphl
->FirstVisible
= 0;
812 lphl
->FirstVisible
+= lphl
->ItemsPerColumn
;
815 if (lphl
->ItemsPerColumn
!= 0) {
816 int lbsub
= lphl
->ItemsVisible
/ lphl
->ItemsPerColumn
* lphl
->ItemsPerColumn
;
817 if (lphl
->FirstVisible
> lbsub
) {
818 lphl
->FirstVisible
-= lbsub
;
820 lphl
->FirstVisible
= 0;
825 if (lphl
->ItemsPerColumn
!= 0)
826 lphl
->FirstVisible
+= lphl
->ItemsVisible
/
827 lphl
->ItemsPerColumn
* lphl
->ItemsPerColumn
;
830 lphl
->FirstVisible
= lphl
->ItemsPerColumn
* LOWORD(lParam
);
833 if (lphl
->FirstVisible
> ListMaxFirstVisible(lphl
))
834 lphl
->FirstVisible
= ListMaxFirstVisible(lphl
);
836 if (lphl
->ItemsPerColumn
!= 0) {
837 lphl
->FirstVisible
= lphl
->FirstVisible
/
838 lphl
->ItemsPerColumn
* lphl
->ItemsPerColumn
+ 1;
839 if (y
!= lphl
->FirstVisible
) {
840 SetScrollPos(hwnd
, SB_HORZ
, lphl
->FirstVisible
/
841 lphl
->ItemsPerColumn
+ 1, TRUE
);
842 InvalidateRect(hwnd
, NULL
, TRUE
);
848 /***********************************************************************
851 static LONG
LBLButtonDown(HWND hwnd
, WORD wParam
, LONG lParam
)
853 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
861 lphl
->PrevFocused
= lphl
->ItemFocused
;
863 y
= ListBoxFindMouse(lphl
, LOWORD(lParam
), HIWORD(lParam
));
867 if (lphl
->dwStyle
& LBS_MULTIPLESEL
) {
868 lphl
->ItemFocused
= y
;
869 wRet
= ListBoxGetSel(lphl
, y
);
870 ListBoxSetSel(lphl
, y
, !wRet
);
872 ListBoxSetCurSel(lphl
, y
);
874 if (lphl
->dwStyle
& LBS_MULTIPLESEL
)
875 ListBoxSendNotification(lphl
, hwnd
, LBN_SELCHANGE
);
877 ListBoxGetItemRect(lphl
, y
, &rectsel
);
879 InvalidateRect(hwnd
, NULL
, TRUE
);
884 /***********************************************************************
887 static LONG
LBLButtonUp(HWND hwnd
, WORD wParam
, LONG lParam
)
889 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
891 if (GetCapture() == hwnd
) ReleaseCapture();
893 if (lphl
->PrevFocused
!= lphl
->ItemFocused
)
894 ListBoxSendNotification(lphl
, hwnd
, LBN_SELCHANGE
);
899 /***********************************************************************
902 static LONG
LBRButtonUp(HWND hwnd
, WORD wParam
, LONG lParam
)
904 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
907 SendMessage(lphl
->hParent
, WM_COMMAND
,
908 MAKEWPARAM(GetWindowWord(hwnd
,GWW_ID
),LBN_DBLCLK
),
911 SendMessage(lphl
->hParent
, WM_COMMAND
, GetWindowWord(hwnd
,GWW_ID
),
912 MAKELONG(hwnd
, LBN_DBLCLK
));
918 /***********************************************************************
921 static LONG
LBMouseMove(HWND hwnd
, WORD wParam
, LONG lParam
)
923 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
926 RECT rect
, rectsel
; /* XXX Broken */
928 dprintf_listbox(stddeb
,"LBMouseMove %d %d\n",SLOWORD(lParam
),SHIWORD(lParam
));
929 if ((wParam
& MK_LBUTTON
) != 0) {
932 if (lphl
->FirstVisible
> 0) {
933 lphl
->FirstVisible
--;
934 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
935 InvalidateRect(hwnd
, NULL
, TRUE
);
939 GetClientRect(hwnd
, &rect
);
940 if (y
>= rect
.bottom
) {
941 if (lphl
->FirstVisible
< ListMaxFirstVisible(lphl
)) {
942 lphl
->FirstVisible
++;
943 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
944 InvalidateRect(hwnd
, NULL
, TRUE
);
948 if ((y
> 0) && (y
< (rect
.bottom
- 4))) {
949 if ((y
< rectsel
.top
) || (y
> rectsel
.bottom
)) {
950 wRet
= ListBoxFindMouse(lphl
, LOWORD(lParam
), HIWORD(lParam
));
951 if (wRet
== lphl
->ItemFocused
) {
954 if (lphl
->dwStyle
& LBS_MULTIPLESEL
) {
955 lphl
->ItemFocused
= wRet
;
956 ListBoxSendNotification(lphl
, hwnd
, LBN_SELCHANGE
);
958 ListBoxSetCurSel(lphl
, wRet
);
960 ListBoxGetItemRect(lphl
, wRet
, &rectsel
);
961 InvalidateRect(hwnd
, NULL
, TRUE
);
969 /***********************************************************************
972 static LONG
LBKeyDown(HWND hwnd
, WORD wParam
, LONG lParam
)
974 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
975 WORD newFocused
= lphl
->ItemFocused
;
977 if (wParam
== VK_SPACE
) {
978 if (lphl
->dwStyle
& LBS_MULTIPLESEL
) {
979 WORD wRet
= ListBoxGetSel(lphl
, lphl
->ItemFocused
);
980 ListBoxSetSel(lphl
, lphl
->ItemFocused
, !wRet
);
989 newFocused
= lphl
->ItemsCount
- 1;
992 if (lphl
->dwStyle
& LBS_MULTICOLUMN
) {
993 if (newFocused
>= lphl
->ItemsPerColumn
) {
994 newFocused
-= lphl
->ItemsPerColumn
;
1001 if (newFocused
> 0) newFocused
--;
1004 if (lphl
->dwStyle
& LBS_MULTICOLUMN
) {
1005 newFocused
+= lphl
->ItemsPerColumn
;
1012 if (newFocused
> lphl
->ItemsVisible
) {
1013 newFocused
-= lphl
->ItemsVisible
;
1019 newFocused
+= lphl
->ItemsVisible
;
1025 if (newFocused
>= lphl
->ItemsCount
)
1026 newFocused
= lphl
->ItemsCount
- 1;
1028 if (!(lphl
->dwStyle
& LBS_MULTIPLESEL
)) {
1029 ListBoxSetCurSel(lphl
, newFocused
);
1030 ListBoxSendNotification(lphl
, hwnd
, LBN_SELCHANGE
);
1033 lphl
->ItemFocused
= newFocused
;
1034 ListBoxScrollToFocus(lphl
);
1035 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
1036 InvalidateRect(hwnd
, NULL
, TRUE
);
1041 /***********************************************************************
1044 static LONG
LBChar(HWND hwnd
, WORD wParam
, LONG lParam
)
1046 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1049 newFocused
= ListBoxFindNextMatch(lphl
, wParam
);
1050 if (newFocused
== (WORD
)LB_ERR
) return 0;
1052 if (newFocused
>= lphl
->ItemsCount
)
1053 newFocused
= lphl
->ItemsCount
- 1;
1054 if (!(lphl
->dwStyle
& LBS_MULTIPLESEL
)) {
1055 ListBoxSetCurSel(lphl
, newFocused
);
1056 ListBoxSendNotification(lphl
, hwnd
, LBN_SELCHANGE
);
1059 lphl
->ItemFocused
= newFocused
;
1060 ListBoxScrollToFocus(lphl
);
1061 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
1062 InvalidateRect(hwnd
, NULL
, TRUE
);
1067 /***********************************************************************
1070 static LONG
LBSetRedraw(HWND hwnd
, WORD wParam
, LONG lParam
)
1072 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1074 dprintf_listbox(stddeb
,"ListBox WM_SETREDRAW hWnd="NPFMT
" w=%04X !\n",
1076 lphl
->bRedrawFlag
= wParam
;
1081 /***********************************************************************
1084 static LONG
LBSetFont(HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1086 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1089 lphl
->hFont
= GetStockObject(SYSTEM_FONT
);
1091 lphl
->hFont
= (HFONT
) wParam
;
1096 /***********************************************************************
1099 static LONG
LBPaint(HWND hwnd
, WORD wParam
, LONG lParam
)
1101 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1108 int i
, top
, height
, maxwidth
, ipc
;
1111 hdc
= BeginPaint( hwnd
, &ps
);
1113 if (!IsWindowVisible(hwnd
) || !lphl
->bRedrawFlag
) {
1114 EndPaint(hwnd
, &ps
);
1118 hOldFont
= SelectObject(hdc
, lphl
->hFont
);
1121 hBrush
= (HBRUSH
) SendMessage(lphl
->hParent
, WM_CTLCOLORLISTBOX
, (WPARAM
)hdc
,
1124 hBrush
= SendMessage(lphl
->hParent
, WM_CTLCOLOR
, hdc
,
1125 MAKELONG(hwnd
, CTLCOLOR_LISTBOX
));
1128 if (hBrush
== 0) hBrush
= GetStockObject(WHITE_BRUSH
);
1130 GetClientRect(hwnd
, &rect
);
1131 FillRect(hdc
, &rect
, hBrush
);
1133 maxwidth
= rect
.right
;
1134 if (lphl
->dwStyle
& LBS_MULTICOLUMN
) {
1135 rect
.right
= lphl
->ColumnsWidth
;
1137 lpls
= lphl
->lpFirst
;
1139 lphl
->ItemsVisible
= 0;
1140 lphl
->ItemsPerColumn
= ipc
= 0;
1142 for(i
= 0; i
< lphl
->ItemsCount
; i
++) {
1143 if (lpls
== NULL
) break;
1145 if (i
>= lphl
->FirstVisible
) {
1146 height
= lpls
->mis
.itemHeight
;
1148 if (top
> rect
.bottom
) {
1149 if (lphl
->dwStyle
& LBS_MULTICOLUMN
) {
1150 lphl
->ItemsPerColumn
= max(lphl
->ItemsPerColumn
, ipc
);
1153 rect
.left
+= lphl
->ColumnsWidth
;
1154 rect
.right
+= lphl
->ColumnsWidth
;
1155 if (rect
.left
> maxwidth
) break;
1161 lpls
->itemRect
.top
= top
;
1162 lpls
->itemRect
.bottom
= top
+ height
;
1163 lpls
->itemRect
.left
= rect
.left
;
1164 lpls
->itemRect
.right
= rect
.right
;
1166 dprintf_listbox(stddeb
,"drawing item: %d %d %d %d %d\n",rect
.left
,top
,rect
.right
,top
+height
,lpls
->itemState
);
1167 if (lphl
->OwnerDrawn
) {
1168 ListBoxDrawItem (hwnd
, lphl
, hdc
, lpls
, &lpls
->itemRect
, ODA_DRAWENTIRE
, 0);
1169 if (lpls
->itemState
)
1170 ListBoxDrawItem (hwnd
, lphl
, hdc
, lpls
, &lpls
->itemRect
, ODA_SELECT
, ODS_SELECTED
);
1172 ListBoxDrawItem (hwnd
, lphl
, hdc
, lpls
, &lpls
->itemRect
, ODA_DRAWENTIRE
,
1175 if ((lphl
->ItemFocused
== i
) && GetFocus() == hwnd
)
1176 ListBoxDrawItem (hwnd
,lphl
, hdc
, lpls
, &lpls
->itemRect
, ODA_FOCUS
, ODS_FOCUS
);
1179 lphl
->ItemsVisible
++;
1183 lpls
= lpls
->lpNext
;
1185 SelectObject(hdc
,hOldFont
);
1186 EndPaint( hwnd
, &ps
);
1190 /***********************************************************************
1193 static LONG
LBSetFocus(HWND hwnd
, WORD wParam
, LONG lParam
)
1195 dprintf_listbox(stddeb
,"ListBox WM_SETFOCUS !\n");
1200 /***********************************************************************
1203 static LONG
LBKillFocus(HWND hwnd
, WORD wParam
, LONG lParam
)
1205 dprintf_listbox(stddeb
,"ListBox WM_KILLFOCUS !\n");
1207 InvalidateRect(hwnd
, NULL
, TRUE
);
1212 /***********************************************************************
1215 static LONG
LBResetContent(HWND hwnd
, WORD wParam
, LONG lParam
)
1217 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1219 dprintf_listbox(stddeb
,"ListBox LB_RESETCONTENT !\n");
1220 ListBoxResetContent(lphl
);
1221 ListBoxUpdateWindow(hwnd
, lphl
, TRUE
);
1225 /***********************************************************************
1228 static LONG
LBDir(HWND hwnd
, WORD wParam
, LONG lParam
)
1231 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1232 dprintf_listbox(stddeb
,"ListBox LB_DIR !\n");
1234 wRet
= ListBoxDirectory(lphl
, wParam
, (LPSTR
)PTR_SEG_TO_LIN(lParam
));
1235 ListBoxUpdateWindow(hwnd
, lphl
, TRUE
);
1239 /***********************************************************************
1242 static LONG
LBAddString(HWND hwnd
, WORD wParam
, LONG lParam
)
1245 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1247 if (lphl
->HasStrings
)
1248 wRet
= ListBoxAddString(lphl
, (LPSTR
)PTR_SEG_TO_LIN(lParam
));
1250 wRet
= ListBoxAddString(lphl
, (LPSTR
)lParam
);
1252 ListBoxUpdateWindow(hwnd
,lphl
,TRUE
);
1256 /***********************************************************************
1259 static LONG
LBGetText(HWND hwnd
, WORD wParam
, LONG lParam
)
1262 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1264 dprintf_listbox(stddeb
, "LB_GETTEXT wParam=%d\n",wParam
);
1265 wRet
= ListBoxGetText(lphl
, wParam
, (LPSTR
)PTR_SEG_TO_LIN(lParam
));
1270 /***********************************************************************
1273 static LONG
LBInsertString(HWND hwnd
, WORD wParam
, LONG lParam
)
1276 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1278 if (lphl
->HasStrings
)
1279 wRet
= ListBoxInsertString(lphl
, wParam
, (LPSTR
)PTR_SEG_TO_LIN(lParam
));
1281 wRet
= ListBoxInsertString(lphl
, wParam
, (LPSTR
)lParam
);
1283 ListBoxUpdateWindow(hwnd
,lphl
,TRUE
);
1287 /***********************************************************************
1290 static LONG
LBDeleteString(HWND hwnd
, WORD wParam
, LONG lParam
)
1292 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1293 LONG lRet
= ListBoxDeleteString(lphl
,wParam
);
1295 ListBoxUpdateWindow(hwnd
,lphl
,TRUE
);
1299 /***********************************************************************
1302 static LONG
LBFindString(HWND hwnd
, WORD wParam
, LONG lParam
)
1304 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1305 return ListBoxFindString(lphl
, wParam
, lParam
);
1308 /***********************************************************************
1311 static LONG
LBGetCaretIndex(HWND hwnd
, WORD wParam
, LONG lParam
)
1313 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1314 return lphl
->ItemFocused
;
1317 /***********************************************************************
1320 static LONG
LBGetCount(HWND hwnd
, WORD wParam
, LONG lParam
)
1324 lphl
= ListBoxGetStorageHeader(hwnd
);
1325 return lphl
->ItemsCount
;
1328 /***********************************************************************
1331 static LONG
LBGetCurSel(HWND hwnd
, WORD wParam
, LONG lParam
)
1335 lphl
= ListBoxGetStorageHeader(hwnd
);
1336 dprintf_listbox(stddeb
,"ListBox LB_GETCURSEL %u !\n",
1338 return lphl
->ItemFocused
;
1341 /***********************************************************************
1342 * LBGetHorizontalExtent
1344 static LONG
LBGetHorizontalExtent(HWND hwnd
, WORD wParam
, LONG lParam
)
1349 /***********************************************************************
1352 static LONG
LBGetItemHeight(HWND hwnd
, WORD wParam
, LONG lParam
)
1354 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1355 LPLISTSTRUCT lpls
= ListBoxGetItem (lphl
, wParam
);
1357 if (lpls
== NULL
) return LB_ERR
;
1358 return lpls
->mis
.itemHeight
;
1361 /***********************************************************************
1364 static LONG
LBGetItemRect(HWND hwnd
, WORD wParam
, LONG lParam
)
1366 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1367 return ListBoxGetItemRect(lphl
, wParam
, PTR_SEG_TO_LIN(lParam
));
1370 /***********************************************************************
1373 static LONG
LBGetSel(HWND hwnd
, WORD wParam
, LONG lParam
)
1375 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1376 return ListBoxGetSel(lphl
, wParam
);
1379 /***********************************************************************
1382 static LONG
LBGetSelCount(HWND hwnd
, WORD wParam
, LONG lParam
)
1384 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1388 if (!(lphl
->dwStyle
& LBS_MULTIPLESEL
)) return LB_ERR
;
1390 lpls
= lphl
->lpFirst
;
1392 while (lpls
!= NULL
) {
1393 if (lpls
->itemState
> 0) cnt
++;
1395 lpls
= lpls
->lpNext
;
1401 /***********************************************************************
1404 static LONG
LBGetSelItems(HWND hwnd
, WORD wParam
, LONG lParam
)
1406 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1409 int *lpItems
= PTR_SEG_TO_LIN(lParam
);
1411 if (!(lphl
->dwStyle
& LBS_MULTIPLESEL
)) return LB_ERR
;
1413 if (wParam
== 0) return 0;
1415 lpls
= lphl
->lpFirst
;
1418 while (lpls
!= NULL
) {
1419 if (lpls
->itemState
> 0) lpItems
[cnt
++] = idx
;
1421 if (cnt
== wParam
) break;
1423 lpls
= lpls
->lpNext
;
1429 /***********************************************************************
1432 static LONG
LBGetTextLen(HWND hwnd
, WORD wParam
, LONG lParam
)
1434 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1435 LPLISTSTRUCT lpls
= ListBoxGetItem(lphl
,wParam
);
1437 if (lpls
== NULL
|| !lphl
->HasStrings
) return LB_ERR
;
1438 return strlen(lpls
->itemText
);
1441 /***********************************************************************
1444 static LONG
LBGetDlgCode(HWND hwnd
, WORD wParam
, LONG lParam
)
1446 return DLGC_WANTARROWS
| DLGC_WANTCHARS
;
1449 /***********************************************************************
1452 static LONG
LBGetTopIndex(HWND hwnd
, WORD wParam
, LONG lParam
)
1454 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1456 return lphl
->FirstVisible
;
1460 /***********************************************************************
1463 static LONG
LBSelectString(HWND hwnd
, WORD wParam
, LONG lParam
)
1465 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1468 wRet
= ListBoxFindString(lphl
, wParam
, lParam
);
1470 /* XXX add functionality here */
1475 /***********************************************************************
1478 static LONG
LBSelItemRange(HWND hwnd
, WORD wParam
, LONG lParam
)
1480 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1483 WORD first
= LOWORD(lParam
);
1484 WORD last
= HIWORD(lParam
);
1485 BOOL select
= wParam
;
1487 if (!(lphl
->dwStyle
& LBS_MULTIPLESEL
)) return LB_ERR
;
1489 if (first
>= lphl
->ItemsCount
||
1490 last
>= lphl
->ItemsCount
) return LB_ERR
;
1492 lpls
= lphl
->lpFirst
;
1495 while (lpls
!= NULL
) {
1497 lpls
->itemState
= select
? ODS_SELECTED
: 0;
1502 lpls
= lpls
->lpNext
;
1508 /***********************************************************************
1511 static LONG
LBSetCaretIndex(HWND hwnd
, WORD wParam
, LONG lParam
)
1513 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1515 if (!(lphl
->dwStyle
& LBS_MULTIPLESEL
)) return 0;
1516 if (wParam
>= lphl
->ItemsCount
) return LB_ERR
;
1518 lphl
->ItemFocused
= wParam
;
1519 ListBoxScrollToFocus (lphl
);
1521 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
1522 InvalidateRect(hwnd
, NULL
, TRUE
);
1526 /***********************************************************************
1529 static LONG
LBSetColumnWidth(HWND hwnd
, WORD wParam
, LONG lParam
)
1531 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1532 lphl
->ColumnsWidth
= wParam
;
1533 InvalidateRect(hwnd
,NULL
,TRUE
);
1537 /***********************************************************************
1538 * LBSetHorizontalExtent
1540 static LONG
LBSetHorizontalExtent(HWND hwnd
, WORD wParam
, LONG lParam
)
1545 /***********************************************************************
1548 static LONG
LBGetItemData(HWND hwnd
, WORD wParam
, LONG lParam
)
1550 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1551 dprintf_listbox(stddeb
, "LB_GETITEMDATA wParam=%x\n", wParam
);
1552 return ListBoxGetItemData(lphl
, wParam
);
1555 /***********************************************************************
1558 static LONG
LBSetItemData(HWND hwnd
, WORD wParam
, LONG lParam
)
1560 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1561 dprintf_listbox(stddeb
, "LB_SETITEMDATA wParam=%x lParam=%lx\n", wParam
, lParam
);
1562 return ListBoxSetItemData(lphl
, wParam
, lParam
);
1565 /***********************************************************************
1568 static LONG
LBSetTabStops(HWND hwnd
, WORD wParam
, LONG lParam
)
1572 lphl
= ListBoxGetStorageHeader(hwnd
);
1574 if (lphl
->TabStops
!= NULL
) {
1575 lphl
->iNumStops
= 0;
1576 free (lphl
->TabStops
);
1579 lphl
->TabStops
= malloc (wParam
* sizeof (short));
1580 if (lphl
->TabStops
) {
1581 lphl
->iNumStops
= wParam
;
1582 memcpy (lphl
->TabStops
, PTR_SEG_TO_LIN(lParam
), wParam
* sizeof (short));
1589 /***********************************************************************
1592 static LONG
LBSetCurSel(HWND hwnd
, WORD wParam
, LONG lParam
)
1594 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1597 dprintf_listbox(stddeb
,"ListBox LB_SETCURSEL wParam=%x !\n",
1600 wRet
= ListBoxSetCurSel(lphl
, wParam
);
1602 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
1603 InvalidateRect(hwnd
, NULL
, TRUE
);
1608 /***********************************************************************
1611 static LONG
LBSetSel(HWND hwnd
, WORD wParam
, LONG lParam
)
1613 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1616 dprintf_listbox(stddeb
,"ListBox LB_SETSEL wParam=%x lParam=%lX !\n", wParam
, lParam
);
1618 wRet
= ListBoxSetSel(lphl
, LOWORD(lParam
), wParam
);
1619 InvalidateRect(hwnd
, NULL
, TRUE
);
1624 /***********************************************************************
1627 static LONG
LBSetTopIndex(HWND hwnd
, WORD wParam
, LONG lParam
)
1629 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1631 dprintf_listbox(stddeb
,"ListBox LB_SETTOPINDEX wParam=%x !\n",
1633 lphl
->FirstVisible
= wParam
;
1634 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
1636 InvalidateRect(hwnd
, NULL
, TRUE
);
1641 /***********************************************************************
1644 static LONG
LBSetItemHeight(HWND hwnd
, WORD wParam
, LONG lParam
)
1646 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1649 dprintf_listbox(stddeb
,"ListBox LB_SETITEMHEIGHT wParam=%x lParam=%lX !\n", wParam
, lParam
);
1650 wRet
= ListBoxSetItemHeight(lphl
, wParam
, lParam
);
1651 InvalidateRect(hwnd
,NULL
,TRUE
);
1655 /***********************************************************************
1658 LRESULT
ListBoxWndProc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1661 case WM_CREATE
: return LBCreate(hwnd
, wParam
, lParam
);
1662 case WM_DESTROY
: return LBDestroy(hwnd
, wParam
, lParam
);
1663 case WM_GETDLGCODE
: return LBGetDlgCode(hwnd
, wParam
, lParam
);
1664 case WM_VSCROLL
: return LBVScroll(hwnd
, wParam
, lParam
);
1665 case WM_HSCROLL
: return LBHScroll(hwnd
, wParam
, lParam
);
1666 case WM_LBUTTONDOWN
: return LBLButtonDown(hwnd
, wParam
, lParam
);
1667 case WM_LBUTTONUP
: return LBLButtonUp(hwnd
, wParam
, lParam
);
1668 case WM_RBUTTONUP
: return LBRButtonUp(hwnd
, wParam
, lParam
);
1669 case WM_LBUTTONDBLCLK
: return LBRButtonUp(hwnd
, wParam
, lParam
);
1670 case WM_MOUSEMOVE
: return LBMouseMove(hwnd
, wParam
, lParam
);
1671 case WM_KEYDOWN
: return LBKeyDown(hwnd
, wParam
, lParam
);
1672 case WM_CHAR
: return LBChar(hwnd
, wParam
, lParam
);
1673 case WM_SETFONT
: return LBSetFont(hwnd
, wParam
, lParam
);
1674 case WM_SETREDRAW
: return LBSetRedraw(hwnd
, wParam
, lParam
);
1675 case WM_PAINT
: return LBPaint(hwnd
, wParam
, lParam
);
1676 case WM_SETFOCUS
: return LBSetFocus(hwnd
, wParam
, lParam
);
1677 case WM_KILLFOCUS
: return LBKillFocus(hwnd
, wParam
, lParam
);
1678 case LB_RESETCONTENT
: return LBResetContent(hwnd
, wParam
, lParam
);
1679 case LB_DIR
: return LBDir(hwnd
, wParam
, lParam
);
1680 case LB_ADDSTRING
: return LBAddString(hwnd
, wParam
, lParam
);
1681 case LB_INSERTSTRING
: return LBInsertString(hwnd
, wParam
, lParam
);
1682 case LB_DELETESTRING
: return LBDeleteString(hwnd
, wParam
, lParam
);
1683 case LB_FINDSTRING
: return LBFindString(hwnd
, wParam
, lParam
);
1684 case LB_GETCARETINDEX
: return LBGetCaretIndex(hwnd
, wParam
, lParam
);
1685 case LB_GETCOUNT
: return LBGetCount(hwnd
, wParam
, lParam
);
1686 case LB_GETCURSEL
: return LBGetCurSel(hwnd
, wParam
, lParam
);
1687 case LB_GETHORIZONTALEXTENT
: return LBGetHorizontalExtent(hwnd
, wParam
, lParam
);
1688 case LB_GETITEMDATA
: return LBGetItemData(hwnd
, wParam
, lParam
);
1689 case LB_GETITEMHEIGHT
: return LBGetItemHeight(hwnd
, wParam
, lParam
);
1690 case LB_GETITEMRECT
: return LBGetItemRect(hwnd
, wParam
, lParam
);
1691 case LB_GETSEL
: return LBGetSel(hwnd
, wParam
, lParam
);
1692 case LB_GETSELCOUNT
: return LBGetSelCount(hwnd
, wParam
, lParam
);
1693 case LB_GETSELITEMS
: return LBGetSelItems(hwnd
, wParam
, lParam
);
1694 case LB_GETTEXT
: return LBGetText(hwnd
, wParam
, lParam
);
1695 case LB_GETTEXTLEN
: return LBGetTextLen(hwnd
, wParam
, lParam
);
1696 case LB_GETTOPINDEX
: return LBGetTopIndex(hwnd
, wParam
, lParam
);
1697 case LB_SELECTSTRING
: return LBSelectString(hwnd
, wParam
, lParam
);
1698 case LB_SELITEMRANGE
: return LBSelItemRange(hwnd
, wParam
, lParam
);
1699 case LB_SETCARETINDEX
: return LBSetCaretIndex(hwnd
, wParam
, lParam
);
1700 case LB_SETCOLUMNWIDTH
: return LBSetColumnWidth(hwnd
, wParam
, lParam
);
1701 case LB_SETHORIZONTALEXTENT
: return LBSetHorizontalExtent(hwnd
, wParam
, lParam
);
1702 case LB_SETITEMDATA
: return LBSetItemData(hwnd
, wParam
, lParam
);
1703 case LB_SETTABSTOPS
: return LBSetTabStops(hwnd
, wParam
, lParam
);
1704 case LB_SETCURSEL
: return LBSetCurSel(hwnd
, wParam
, lParam
);
1705 case LB_SETSEL
: return LBSetSel(hwnd
, wParam
, lParam
);
1706 case LB_SETTOPINDEX
: return LBSetTopIndex(hwnd
, wParam
, lParam
);
1707 case LB_SETITEMHEIGHT
: return LBSetItemHeight(hwnd
, wParam
, lParam
);
1710 return DefWindowProc(hwnd
, message
, wParam
, lParam
);
1713 /************************************************************************
1714 * DlgDirSelect [USER.99]
1716 BOOL
DlgDirSelect(HWND hDlg
, LPSTR lpStr
, int nIDLBox
)
1722 dprintf_listbox( stddeb
, "DlgDirSelect("NPFMT
", '%s', %d) \n", hDlg
, lpStr
,
1725 hwnd
= GetDlgItem(hDlg
, nIDLBox
);
1726 lphl
= ListBoxGetStorageHeader(hwnd
);
1727 if(lphl
->ItemFocused
== -1) {
1728 dprintf_listbox(stddeb
, "Nothing selected!\n");
1731 ListBoxGetText(lphl
, lphl
->ItemFocused
, s
);
1732 dprintf_listbox(stddeb
, "Selection is %s\n", s
);
1735 strncpy( lpStr
, s
+2, strlen(s
)-4 ); /* device name */
1736 lpStr
[ strlen(s
)-4 ] = 0;
1737 strcat( lpStr
, ":" );
1740 strncpy( lpStr
, s
+1, strlen(s
)-2 ); /* directory name */
1741 lpStr
[ strlen(s
)-2 ] = 0;
1742 strcat( lpStr
, "\\" );
1744 dprintf_listbox( stddeb
, "Returning %s\n", lpStr
);
1747 strcpy( lpStr
, s
); /* file name */
1748 dprintf_listbox( stddeb
, "Returning %s\n", lpStr
);
1754 /************************************************************************
1755 * DlgDirList [USER.100]
1757 int DlgDirList(HWND hDlg
, LPSTR lpPathSpec
,
1758 int nIDLBox
, int nIDStat
, WORD wType
)
1763 dprintf_listbox(stddeb
,"DlgDirList("NPFMT
", '%s', %d, %d, %04X) \n",
1764 hDlg
, lpPathSpec
, nIDLBox
, nIDStat
, wType
);
1767 hWnd
= GetDlgItem(hDlg
, nIDLBox
);
1768 lphl
= ListBoxGetStorageHeader(hWnd
);
1769 ListBoxResetContent(lphl
);
1770 ret
= ListBoxDirectory(lphl
, wType
, lpPathSpec
);
1771 ListBoxUpdateWindow(hWnd
, lphl
, TRUE
);
1779 drive
= DOS_GetDefaultDrive();
1780 hTemp
= USER_HEAP_ALLOC( 256 );
1781 temp
= (char *) USER_HEAP_LIN_ADDR( hTemp
);
1782 strcpy( temp
+3, DOS_GetCurrentDir(drive
) );
1783 if( temp
[3] == '\\' ) {
1784 temp
[1] = 'A'+drive
;
1786 SendDlgItemMessage( hDlg
, nIDStat
, WM_SETTEXT
, 0,
1787 (LPARAM
)(USER_HEAP_SEG_ADDR(hTemp
) + 1) );
1789 temp
[0] = 'A'+drive
;
1792 SendDlgItemMessage( hDlg
, nIDStat
, WM_SETTEXT
, 0,
1793 (LPARAM
)USER_HEAP_SEG_ADDR(hTemp
) );
1795 USER_HEAP_FREE( hTemp
);