4 * Copyright Martin Ayotte, 1993
5 * Constantine Sapuntzakis, 1995
12 * - check if multi-column listboxes work
13 * - implement more messages and styles
14 * - implement caret for LBS_EXTENDEDSEL
36 #define LIST_HEAP_ALLOC(lphl,f,size) ((int)HEAP_Alloc(&lphl->Heap,f,size) & 0xffff)
37 #define LIST_HEAP_FREE(lphl,handle) (HEAP_Free(&lphl->Heap,LIST_HEAP_ADDR(lphl,handle)))
38 #define LIST_HEAP_ADDR(lphl,handle) \
39 ((void *)((handle) ? ((handle) | ((int)lphl->Heap & 0xffff0000)) : 0))
41 /* FIXME: shouldn't each listbox have its own heap? */
43 #define LIST_HEAP_ALLOC(lphl,f,size) USER_HEAP_ALLOC(size)
44 #define LIST_HEAP_FREE(lphl,handle) USER_HEAP_FREE(handle)
45 #define LIST_HEAP_ADDR(lphl,handle) USER_HEAP_LIN_ADDR(handle)
46 #define LIST_HEAP_SEG_ADDR(lphl,handle) USER_HEAP_SEG_ADDR(handle)
48 /* Something like this maybe ? */
49 #define LIST_HEAP_ALLOC(lphl,f,size) \
50 LOCAL_Alloc( lphl->HeapSel, LMEM_FIXED, (size) )
52 #define LIST_HEAP_REALLOC(handle,size) \
53 LOCAL_ReAlloc( USER_HeapSel, (handle), (size), LMEM_FIXED )
55 #define LIST_HEAP_FREE(lphl,handle) \
56 LOCAL_Free( lphl->HeapSel, (handle) )
57 #define LIST_HEAP_ADDR(lphl,handle) \
58 ((handle) ? PTR_SEG_OFF_TO_LIN(lphl->HeapSel, (handle)) : NULL)
59 #define LIST_HEAP_SEG_ADDR(lphl,handle) \
60 ((handle) ? MAKELONG((handle), lphl->HeapSel) : 0)
64 #define LIST_HEAP_SIZE 0x10000
66 #define LBMM_EDGE 4 /* distance inside box which is same as moving mouse
67 outside box, to trigger scrolling of LB */
69 static void ListBoxInitialize(LPHEADLIST lphl
)
73 lphl
->ItemsVisible
= 0;
74 lphl
->FirstVisible
= 0;
75 lphl
->ColumnsVisible
= 1;
76 lphl
->ItemsPerColumn
= 0;
77 lphl
->ItemFocused
= -1;
78 lphl
->PrevFocused
= -1;
81 void CreateListBoxStruct(HWND hwnd
, WORD CtlType
, LONG styles
, HWND parent
)
86 lphl
= (LPHEADLIST
)xmalloc(sizeof(HEADLIST
));
87 SetWindowLong32A(hwnd
, 0, (LONG
)lphl
);
88 ListBoxInitialize(lphl
);
89 lphl
->DrawCtlType
= CtlType
;
90 lphl
->CtlID
= GetWindowWord(hwnd
,GWW_ID
);
91 lphl
->bRedrawFlag
= TRUE
;
93 lphl
->TabStops
= NULL
;
94 lphl
->hFont
= GetStockObject(SYSTEM_FONT
);
96 if (CtlType
==ODT_COMBOBOX
) /* use the "faked" style for COMBOLBOX */
97 /* LBS_SORT instead CBS_SORT e.g. */
98 lphl
->dwStyle
= MAKELONG(LOWORD(styles
),HIWORD(GetWindowLong(hwnd
,GWL_STYLE
)));
100 lphl
->dwStyle
= GetWindowLong(hwnd
,GWL_STYLE
); /* use original style dword */
101 lphl
->hParent
= parent
;
102 lphl
->StdItemHeight
= 15; /* FIXME: should get the font height */
103 lphl
->OwnerDrawn
= styles
& (LBS_OWNERDRAWFIXED
| LBS_OWNERDRAWVARIABLE
);
104 lphl
->HasStrings
= (styles
& LBS_HASSTRINGS
) || !lphl
->OwnerDrawn
;
106 /* create dummy hdc to set text height */
107 if ((hdc
= GetDC(0)))
110 GetTextMetrics( hdc
, &tm
);
111 lphl
->StdItemHeight
= tm
.tmHeight
;
112 dprintf_listbox(stddeb
,"CreateListBoxStruct: font height %d\n",
113 lphl
->StdItemHeight
);
117 if (lphl
->OwnerDrawn
)
121 lphl
->needMeasure
= TRUE
;
122 dummyls
.mis
.CtlType
= lphl
->DrawCtlType
;
123 dummyls
.mis
.CtlID
= lphl
->CtlID
;
124 dummyls
.mis
.itemID
= -1;
125 dummyls
.mis
.itemWidth
= 0; /* ignored */
126 dummyls
.mis
.itemData
= 0;
128 ListBoxAskMeasure(lphl
,&dummyls
);
131 /* WINELIBS list boxes do not operate on local heaps */
133 lphl
->HeapSel
= GlobalAlloc16(GMEM_FIXED
,LIST_HEAP_SIZE
);
134 LocalInit( lphl
->HeapSel
, 0, LIST_HEAP_SIZE
-1);
140 void DestroyListBoxStruct(LPHEADLIST lphl
)
142 /* XXX need to free lphl->Heap */
143 GlobalFree16(lphl
->HeapSel
);
147 static LPHEADLIST
ListBoxGetStorageHeader(HWND hwnd
)
149 return (LPHEADLIST
)GetWindowLong(hwnd
,0);
152 /* Send notification "code" as part of a WM_COMMAND-message if hwnd
153 has the LBS_NOTIFY style */
154 void ListBoxSendNotification(LPHEADLIST lphl
, WORD code
)
156 if (lphl
->dwStyle
& LBS_NOTIFY
)
158 SendMessage32A(lphl
->hParent
, WM_COMMAND
,
159 MAKEWPARAM(lphl
->CtlID
,code
), (LPARAM
)lphl
->hSelf
);
161 SendMessage16(lphl
->hParent
, WM_COMMAND
,
162 lphl
->CtlID
, MAKELONG(lphl
->hSelf
, code
));
167 /* get the maximum value of lphl->FirstVisible */
168 int ListMaxFirstVisible(LPHEADLIST lphl
)
170 int m
= lphl
->ItemsCount
-lphl
->ItemsVisible
;
171 return (m
< 0) ? 0 : m
;
175 void ListBoxUpdateWindow(HWND hwnd
, LPHEADLIST lphl
, BOOL repaint
)
177 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
179 if (wndPtr
->dwStyle
& WS_VSCROLL
)
180 SetScrollRange(hwnd
, SB_VERT
, 0, ListMaxFirstVisible(lphl
), TRUE
);
181 if ((wndPtr
->dwStyle
& WS_HSCROLL
) && (lphl
->ItemsPerColumn
!= 0))
182 SetScrollRange(hwnd
, SB_HORZ
, 1, lphl
->ItemsVisible
/
183 lphl
->ItemsPerColumn
+ 1, TRUE
);
185 if (repaint
&& lphl
->bRedrawFlag
) InvalidateRect32( hwnd
, NULL
, TRUE
);
188 /* Returns: 0 if nothing needs to be changed */
189 /* 1 if FirstVisible changed */
191 int ListBoxScrollToFocus(LPHEADLIST lphl
)
195 if (lphl
->ItemsCount
== 0) return 0;
196 if (lphl
->ItemFocused
== -1) return 0;
198 end
= lphl
->FirstVisible
+ lphl
->ItemsVisible
- 1;
200 if (lphl
->ItemFocused
< lphl
->FirstVisible
) {
201 lphl
->FirstVisible
= lphl
->ItemFocused
;
204 if (lphl
->ItemFocused
> end
) {
205 WORD maxFirstVisible
= ListMaxFirstVisible(lphl
);
207 lphl
->FirstVisible
= lphl
->ItemFocused
;
209 if (lphl
->FirstVisible
> maxFirstVisible
) {
210 lphl
->FirstVisible
= maxFirstVisible
;
219 LPLISTSTRUCT
ListBoxGetItem(LPHEADLIST lphl
, UINT uIndex
)
224 if (uIndex
>= lphl
->ItemsCount
) return NULL
;
226 lpls
= lphl
->lpFirst
;
227 while (Count
++ < uIndex
) lpls
= lpls
->lpNext
;
232 void ListBoxDrawItem (HWND hwnd
, LPHEADLIST lphl
, HDC hdc
, LPLISTSTRUCT lpls
,
233 RECT16
*rect
, WORD itemAction
, WORD itemState
)
235 if (lphl
->OwnerDrawn
)
237 DRAWITEMSTRUCT32 dis
;
239 dis
.CtlID
= lpls
->mis
.CtlID
;
240 dis
.CtlType
= lpls
->mis
.CtlType
;
241 dis
.itemID
= lpls
->mis
.itemID
;
244 dis
.itemData
= lpls
->mis
.itemData
;
245 dis
.itemAction
= itemAction
;
246 dis
.itemState
= itemState
;
247 CONV_RECT16TO32( rect
, &dis
.rcItem
);
248 SendMessage32A( lphl
->hParent
, WM_DRAWITEM
, 0, (LPARAM
)&dis
);
251 if (itemAction
== ODA_DRAWENTIRE
|| itemAction
== ODA_SELECT
) {
253 DWORD dwOldTextColor
= 0;
255 OldBkMode
= SetBkMode(hdc
, TRANSPARENT
);
257 if (itemState
!= 0) {
258 dwOldTextColor
= SetTextColor(hdc
, 0x00FFFFFFL
);
259 FillRect16(hdc
, rect
, GetStockObject(BLACK_BRUSH
));
262 if (lphl
->dwStyle
& LBS_USETABSTOPS
) {
263 TabbedTextOut(hdc
, rect
->left
+ 5, rect
->top
+ 2,
264 (char *)lpls
->itemText
, strlen((char *)lpls
->itemText
),
265 lphl
->iNumStops
, lphl
->TabStops
, 0);
267 TextOut16(hdc
, rect
->left
+ 5, rect
->top
+ 2,
268 (char *)lpls
->itemText
, strlen((char *)lpls
->itemText
));
271 if (itemState
!= 0) {
272 SetTextColor(hdc
, dwOldTextColor
);
275 SetBkMode(hdc
, OldBkMode
);
277 else DrawFocusRect16(hdc
, rect
);
281 int ListBoxFindMouse(LPHEADLIST lphl
, int X
, int Y
)
283 LPLISTSTRUCT lpls
= lphl
->lpFirst
;
287 point
.x
= X
; point
.y
= Y
;
288 if (lphl
->ItemsCount
== 0) return LB_ERR
;
290 for(i
= 0; i
< lphl
->FirstVisible
; i
++) {
291 if (lpls
== NULL
) return LB_ERR
;
294 for(j
= 0; j
< lphl
->ItemsVisible
; i
++, j
++) {
295 if (lpls
== NULL
) return LB_ERR
;
296 if (PtInRect16(&lpls
->itemRect
,point
)) {
301 dprintf_listbox(stddeb
,"ListBoxFindMouse: not found\n");
306 void ListBoxAskMeasure(LPHEADLIST lphl
, LPLISTSTRUCT lpls
)
308 HANDLE hTemp
= USER_HEAP_ALLOC( sizeof(MEASUREITEMSTRUCT
) );
309 MEASUREITEMSTRUCT
*lpmeasure
= (MEASUREITEMSTRUCT
*) USER_HEAP_LIN_ADDR(hTemp
);
311 if (lpmeasure
== NULL
) {
312 fprintf(stdnimp
,"ListBoxAskMeasure() out of memory !\n");
316 *lpmeasure
= lpls
->mis
;
317 lpmeasure
->itemHeight
= lphl
->StdItemHeight
;
318 SendMessage16(lphl
->hParent
, WM_MEASUREITEM
, 0, (LPARAM
)USER_HEAP_SEG_ADDR(hTemp
));
320 if (lphl
->dwStyle
& LBS_OWNERDRAWFIXED
) {
321 if (lpmeasure
->itemHeight
> lphl
->StdItemHeight
)
322 lphl
->StdItemHeight
= lpmeasure
->itemHeight
;
323 lpls
->mis
.itemHeight
= lpmeasure
->itemHeight
;
326 USER_HEAP_FREE(hTemp
);
329 /* -------------------- strings and item data ---------------------- */
331 LPLISTSTRUCT
ListBoxCreateItem(LPHEADLIST lphl
, int id
)
333 LPLISTSTRUCT lplsnew
= (LPLISTSTRUCT
)malloc(sizeof(LISTSTRUCT
));
335 if (lplsnew
== NULL
) return NULL
;
337 lplsnew
->itemState
= 0;
338 lplsnew
->mis
.CtlType
= lphl
->DrawCtlType
;
339 lplsnew
->mis
.CtlID
= lphl
->CtlID
;
340 lplsnew
->mis
.itemID
= id
;
341 lplsnew
->mis
.itemHeight
= lphl
->StdItemHeight
;
342 lplsnew
->mis
.itemWidth
= 0; /* ignored */
343 lplsnew
->mis
.itemData
= 0;
344 SetRectEmpty16( &lplsnew
->itemRect
);
351 int ListBoxInsertString(LPHEADLIST lphl
, UINT uIndex
, LPCSTR newstr
)
353 LPLISTSTRUCT
*lppls
, lplsnew
, lpls
;
358 dprintf_listbox(stddeb
,"ListBoxInsertString(%d, %p);\n", uIndex
, newstr
);
360 if (!newstr
) return -1;
362 if (uIndex
== (UINT
)-1)
363 uIndex
= lphl
->ItemsCount
;
365 lppls
= &lphl
->lpFirst
;
366 for(Count
= 0; Count
< uIndex
; Count
++) {
367 if (*lppls
== NULL
) return LB_ERR
;
368 lppls
= (LPLISTSTRUCT
*) &(*lppls
)->lpNext
;
371 lplsnew
= ListBoxCreateItem(lphl
, Count
);
373 if (lplsnew
== NULL
) {
374 fprintf(stdnimp
,"ListBoxInsertString() out of memory !\n");
378 lplsnew
->lpNext
= *lppls
;
383 if (lphl
->HasStrings
) {
384 dprintf_listbox(stddeb
," string: %s\n", newstr
);
385 hStr
= LIST_HEAP_ALLOC(lphl
, LMEM_MOVEABLE
, strlen(newstr
) + 1);
386 str
= (LPSTR
)LIST_HEAP_ADDR(lphl
, hStr
);
387 if (str
== NULL
) return LB_ERRSPACE
;
389 lplsnew
->itemText
= str
;
390 /* I'm not so sure about the next one */
391 lplsnew
->mis
.itemData
= 0;
393 lplsnew
->itemText
= NULL
;
394 lplsnew
->mis
.itemData
= (DWORD
)newstr
;
397 lplsnew
->mis
.itemID
= uIndex
;
398 lplsnew
->hData
= hStr
;
400 /* adjust the itemID field of the following entries */
401 for(lpls
= lplsnew
->lpNext
; lpls
!= NULL
; lpls
= lpls
->lpNext
) {
405 if (lphl
->needMeasure
) {
406 ListBoxAskMeasure(lphl
, lplsnew
);
409 dprintf_listbox(stddeb
,"ListBoxInsertString // count=%d\n", lphl
->ItemsCount
);
414 int ListBoxAddString(LPHEADLIST lphl
, LPCSTR newstr
)
416 UINT pos
= (UINT
) -1;
418 if (lphl
->HasStrings
&& (lphl
->dwStyle
& LBS_SORT
)) {
419 LPLISTSTRUCT lpls
= lphl
->lpFirst
;
420 for (pos
= 0; lpls
!= NULL
; lpls
= lpls
->lpNext
, pos
++)
421 if (strcmp(lpls
->itemText
, newstr
) >= 0)
424 return ListBoxInsertString(lphl
, pos
, newstr
);
428 int ListBoxGetText(LPHEADLIST lphl
, UINT uIndex
, LPSTR OutStr
)
433 dprintf_listbox(stddeb
, "ListBoxGetText // OutStr==NULL\n");
437 lpls
= ListBoxGetItem (lphl
, uIndex
);
438 if (lpls
== NULL
) return LB_ERR
;
440 if (!lphl
->HasStrings
) {
441 *((long *)OutStr
) = lpls
->mis
.itemData
;
445 strcpy(OutStr
, lpls
->itemText
);
446 return strlen(OutStr
);
450 DWORD
ListBoxGetItemData(LPHEADLIST lphl
, UINT uIndex
)
454 lpls
= ListBoxGetItem (lphl
, uIndex
);
455 if (lpls
== NULL
) return LB_ERR
;
456 return lpls
->mis
.itemData
;
460 int ListBoxSetItemData(LPHEADLIST lphl
, UINT uIndex
, DWORD ItemData
)
462 LPLISTSTRUCT lpls
= ListBoxGetItem(lphl
, uIndex
);
464 if (lpls
== NULL
) return LB_ERR
;
465 lpls
->mis
.itemData
= ItemData
;
470 int ListBoxDeleteString(LPHEADLIST lphl
, UINT uIndex
)
472 LPLISTSTRUCT lpls
, lpls2
;
475 if (uIndex
>= lphl
->ItemsCount
) return LB_ERR
;
477 lpls
= lphl
->lpFirst
;
478 if (lpls
== NULL
) return LB_ERR
;
481 lphl
->lpFirst
= lpls
->lpNext
;
483 LPLISTSTRUCT lpls2
= NULL
;
484 for(Count
= 0; Count
< uIndex
; Count
++) {
485 if (lpls
->lpNext
== NULL
) return LB_ERR
;
488 lpls
= (LPLISTSTRUCT
)lpls
->lpNext
;
490 lpls2
->lpNext
= lpls
->lpNext
;
493 /* adjust the itemID field of the following entries */
494 for(lpls2
= lpls
->lpNext
; lpls2
!= NULL
; lpls2
= lpls2
->lpNext
) {
500 if (lpls
->hData
!= 0) LIST_HEAP_FREE(lphl
, lpls
->hData
);
503 return lphl
->ItemsCount
;
507 int ListBoxFindString(LPHEADLIST lphl
, UINT nFirst
, SEGPTR MatchStr
)
511 UINT First
= nFirst
+ 1;
512 LPSTR lpMatchStr
= (LPSTR
)MatchStr
;
514 if (First
> lphl
->ItemsCount
) return LB_ERR
;
516 if (lphl
->HasStrings
) lpMatchStr
= PTR_SEG_TO_LIN(MatchStr
);
518 lpls
= ListBoxGetItem(lphl
, First
);
520 while(lpls
!= NULL
) {
521 if (lphl
->HasStrings
) {
522 if (strstr(lpls
->itemText
, lpMatchStr
) == lpls
->itemText
) return Count
;
523 } else if (lphl
->dwStyle
& LBS_SORT
) {
524 /* XXX Do a compare item */
527 if (lpls
->mis
.itemData
== (DWORD
)lpMatchStr
) return Count
;
533 /* Start over at top */
535 lpls
= lphl
->lpFirst
;
537 while (Count
< First
) {
538 if (lphl
->HasStrings
) {
539 if (strstr(lpls
->itemText
, lpMatchStr
) == lpls
->itemText
) return Count
;
540 } else if (lphl
->dwStyle
& LBS_SORT
) {
541 /* XXX Do a compare item */
543 if (lpls
->mis
.itemData
== (DWORD
)lpMatchStr
) return Count
;
553 int ListBoxResetContent(LPHEADLIST lphl
)
558 if (lphl
->ItemsCount
== 0) return 0;
560 dprintf_listbox(stddeb
, "ListBoxResetContent // ItemCount = %d\n",
563 for(i
= 0; i
< lphl
->ItemsCount
; i
++) {
564 lpls
= lphl
->lpFirst
;
565 if (lpls
== NULL
) return LB_ERR
;
567 lphl
->lpFirst
= lpls
->lpNext
;
568 if (lpls
->hData
!= 0) LIST_HEAP_FREE(lphl
, lpls
->hData
);
571 ListBoxInitialize(lphl
);
576 /* --------------------- selection ------------------------- */
578 int ListBoxSetCurSel(LPHEADLIST lphl
, WORD wIndex
)
582 /* use ListBoxSetSel instead */
583 if (lphl
->dwStyle
& (LBS_MULTIPLESEL
| LBS_EXTENDEDSEL
) ) return 0;
585 /* unselect previous item */
586 if (lphl
->ItemFocused
!= -1) {
587 lphl
->PrevFocused
= lphl
->ItemFocused
;
588 lpls
= ListBoxGetItem(lphl
, lphl
->ItemFocused
);
589 if (lpls
== 0) return LB_ERR
;
593 if ((wIndex
!= (UINT
)-1) && (wIndex
< lphl
->ItemsCount
))
595 lphl
->ItemFocused
= wIndex
;
596 lpls
= ListBoxGetItem(lphl
, wIndex
);
597 if (lpls
== 0) return LB_ERR
;
598 lpls
->itemState
= ODS_SELECTED
| ODS_FOCUS
;
607 int ListBoxSetSel(LPHEADLIST lphl
, WORD wIndex
, WORD state
)
612 if (!(lphl
->dwStyle
& (LBS_MULTIPLESEL
| LBS_EXTENDEDSEL
) ))
615 if (wIndex
== (UINT
)-1) {
616 for (lpls
= lphl
->lpFirst
; lpls
!= NULL
; lpls
= lpls
->lpNext
) {
617 if( lpls
->itemState
& ODS_SELECTED
) n
++;
618 lpls
->itemState
= state
? lpls
->itemState
| ODS_SELECTED
619 : lpls
->itemState
& ~ODS_SELECTED
;
624 if (wIndex
>= lphl
->ItemsCount
) return LB_ERR
;
626 lpls
= ListBoxGetItem(lphl
, wIndex
);
627 lpls
->itemState
= state
? lpls
->itemState
| ODS_SELECTED
628 : lpls
->itemState
& ~ODS_SELECTED
;
634 int ListBoxGetSel(LPHEADLIST lphl
, WORD wIndex
)
636 LPLISTSTRUCT lpls
= ListBoxGetItem(lphl
, wIndex
);
638 if (lpls
== NULL
) return LB_ERR
;
639 return lpls
->itemState
& ODS_SELECTED
;
642 /* ------------------------- dir listing ------------------------ */
644 LONG
ListBoxDirectory(LPHEADLIST lphl
, UINT attrib
, LPCSTR filespec
)
646 char temp
[16], mask
[13];
653 dprintf_listbox(stddeb
, "ListBoxDirectory: '%s' %04x\n", filespec
, attrib
);
654 if (!filespec
) return LB_ERR
;
655 if (!(ptr
= DOSFS_GetUnixFileName( filespec
, FALSE
))) return LB_ERR
;
657 p
= strrchr( path
, '/' );
659 if (!(ptr
= DOSFS_ToDosFCBFormat( p
)))
666 dprintf_listbox(stddeb
, "ListBoxDirectory: path=%s mask=%s\n", path
, mask
);
670 while ((count
= DOSFS_FindNext( path
, mask
, 0, attrib
, skip
, &entry
)) > 0)
673 if (entry
.attr
& FA_DIRECTORY
)
675 if ((attrib
& DDL_DIRECTORY
) && strcmp(entry
.name
, ". "))
677 sprintf(temp
, "[%s]", DOSFS_ToDosDTAFormat( entry
.name
) );
679 if ((ret
= ListBoxAddString(lphl
, temp
)) == LB_ERR
) break;
682 else /* not a directory */
684 if (!(attrib
& DDL_EXCLUSIVE
) ||
685 ((attrib
& (FA_RDONLY
|FA_HIDDEN
|FA_SYSTEM
|FA_ARCHIVE
)) ==
686 (entry
.attr
& (FA_RDONLY
|FA_HIDDEN
|FA_SYSTEM
|FA_ARCHIVE
))))
688 strcpy( temp
, DOSFS_ToDosDTAFormat( entry
.name
) );
690 if ((ret
= ListBoxAddString(lphl
, temp
)) == LB_ERR
) break;
694 if (attrib
& DDL_DRIVES
)
697 strcpy( temp
, "[-a-]" );
698 for (x
= 0; x
< MAX_DOS_DRIVES
; x
++, temp
[2]++)
700 if (DRIVE_IsValid(x
))
701 if ((ret
= ListBoxAddString(lphl
, temp
)) == LB_ERR
) break;
708 /* ------------------------- dimensions ------------------------- */
710 int ListBoxGetItemRect(LPHEADLIST lphl
, WORD wIndex
, LPRECT16 lprect
)
712 LPLISTSTRUCT lpls
= ListBoxGetItem(lphl
,wIndex
);
714 if (lpls
== NULL
) return LB_ERR
;
715 *lprect
= lpls
->itemRect
;
720 int ListBoxSetItemHeight(LPHEADLIST lphl
, WORD wIndex
, long height
)
724 if (!(lphl
->dwStyle
& LBS_OWNERDRAWVARIABLE
)) {
725 lphl
->StdItemHeight
= (short)height
;
729 lpls
= ListBoxGetItem(lphl
, wIndex
);
730 if (lpls
== NULL
) return LB_ERR
;
732 lpls
->mis
.itemHeight
= height
;
736 /* -------------------------- string search ------------------------ */
738 int ListBoxFindNextMatch(LPHEADLIST lphl
, WORD wChar
)
743 if ((char)wChar
< ' ') return LB_ERR
;
744 if (!lphl
->HasStrings
) return LB_ERR
;
746 lpls
= lphl
->lpFirst
;
748 for (count
= 0; lpls
!= NULL
; lpls
= lpls
->lpNext
, count
++) {
749 if (tolower(*lpls
->itemText
) == tolower((char)wChar
)) break;
751 if (lpls
== NULL
) return LB_ERR
;
753 for(; lpls
!= NULL
; lpls
= lpls
->lpNext
, count
++) {
754 if (*lpls
->itemText
!= (char)wChar
)
756 if ((short) count
> lphl
->ItemFocused
)
762 /***********************************************************************
765 static LONG
LBCreate(HWND hwnd
, WORD wParam
, LONG lParam
)
768 LONG dwStyle
= GetWindowLong(hwnd
,GWL_STYLE
);
771 CreateListBoxStruct(hwnd
, ODT_LISTBOX
, dwStyle
, GetParent(hwnd
));
772 lphl
= ListBoxGetStorageHeader(hwnd
);
773 dprintf_listbox(stddeb
,"ListBox created: lphl = %p dwStyle = %04x:%04x\n",
774 lphl
, HIWORD(dwStyle
), LOWORD(dwStyle
));
776 GetClientRect16(hwnd
,&rect
);
777 lphl
->ColumnsWidth
= rect
.right
- rect
.left
;
779 if (dwStyle
& WS_VSCROLL
)
780 SetScrollRange(hwnd
, SB_VERT
, 0, ListMaxFirstVisible(lphl
), TRUE
);
781 if (dwStyle
& WS_HSCROLL
)
782 SetScrollRange(hwnd
, SB_HORZ
, 1, 1, TRUE
);
788 /***********************************************************************
791 static LONG
LBDestroy(HWND hwnd
, WORD wParam
, LONG lParam
)
793 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
795 ListBoxResetContent(lphl
);
797 DestroyListBoxStruct(lphl
);
798 dprintf_listbox(stddeb
,"ListBox destroyed: lphl = %p\n",lphl
);
802 /***********************************************************************
805 static LONG
LBVScroll(HWND hwnd
, WORD wParam
, LONG lParam
)
807 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
810 dprintf_listbox(stddeb
,"ListBox WM_VSCROLL w=%04X l=%08lX !\n",
812 y
= lphl
->FirstVisible
;
816 if (lphl
->FirstVisible
> 0)
817 lphl
->FirstVisible
--;
821 lphl
->FirstVisible
++;
825 if (lphl
->FirstVisible
> lphl
->ItemsVisible
) {
826 lphl
->FirstVisible
-= lphl
->ItemsVisible
;
828 lphl
->FirstVisible
= 0;
833 lphl
->FirstVisible
+= lphl
->ItemsVisible
;
837 lphl
->FirstVisible
= LOWORD(lParam
);
841 if (lphl
->FirstVisible
> ListMaxFirstVisible(lphl
))
842 lphl
->FirstVisible
= ListMaxFirstVisible(lphl
);
844 if (y
!= lphl
->FirstVisible
) {
845 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
846 InvalidateRect32( hwnd
, NULL
, TRUE
);
851 /***********************************************************************
854 static LONG
LBHScroll(HWND hwnd
, WORD wParam
, LONG lParam
)
859 dprintf_listbox(stddeb
,"ListBox WM_HSCROLL w=%04X l=%08lX !\n",
861 lphl
= ListBoxGetStorageHeader(hwnd
);
862 y
= lphl
->FirstVisible
;
865 if (lphl
->FirstVisible
> lphl
->ItemsPerColumn
) {
866 lphl
->FirstVisible
-= lphl
->ItemsPerColumn
;
868 lphl
->FirstVisible
= 0;
872 lphl
->FirstVisible
+= lphl
->ItemsPerColumn
;
875 if (lphl
->ItemsPerColumn
!= 0) {
876 int lbsub
= lphl
->ItemsVisible
/ lphl
->ItemsPerColumn
* lphl
->ItemsPerColumn
;
877 if (lphl
->FirstVisible
> lbsub
) {
878 lphl
->FirstVisible
-= lbsub
;
880 lphl
->FirstVisible
= 0;
885 if (lphl
->ItemsPerColumn
!= 0)
886 lphl
->FirstVisible
+= lphl
->ItemsVisible
/
887 lphl
->ItemsPerColumn
* lphl
->ItemsPerColumn
;
890 lphl
->FirstVisible
= lphl
->ItemsPerColumn
* LOWORD(lParam
);
893 if (lphl
->FirstVisible
> ListMaxFirstVisible(lphl
))
894 lphl
->FirstVisible
= ListMaxFirstVisible(lphl
);
896 if (lphl
->ItemsPerColumn
!= 0) {
897 lphl
->FirstVisible
= lphl
->FirstVisible
/
898 lphl
->ItemsPerColumn
* lphl
->ItemsPerColumn
+ 1;
899 if (y
!= lphl
->FirstVisible
) {
900 SetScrollPos(hwnd
, SB_HORZ
, lphl
->FirstVisible
/
901 lphl
->ItemsPerColumn
+ 1, TRUE
);
902 InvalidateRect32( hwnd
, NULL
, TRUE
);
908 /***********************************************************************
911 static LONG
LBLButtonDown(HWND hwnd
, WORD wParam
, LONG lParam
)
913 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
921 lphl
->PrevFocused
= lphl
->ItemFocused
;
923 y
= ListBoxFindMouse(lphl
, LOWORD(lParam
), HIWORD(lParam
));
925 if (y
== -1) return 0;
927 if (lphl
->dwStyle
& LBS_NOTIFY
&& y
!= LB_ERR
)
928 if( SendMessage16(lphl
->hParent
, WM_LBTRACKPOINT
, y
, lParam
) )
932 switch( lphl
->dwStyle
& (LBS_MULTIPLESEL
| LBS_EXTENDEDSEL
) )
934 case LBS_MULTIPLESEL
:
935 lphl
->ItemFocused
= y
;
936 wRet
= ListBoxGetSel(lphl
, y
);
937 ListBoxSetSel(lphl
, y
, !wRet
);
939 case LBS_EXTENDEDSEL
:
940 /* should handle extended mode here and in kbd handler
943 if ( lphl
->PrevFocused
!= y
&& y
!= LB_ERR
)
945 LPLISTSTRUCT lpls
= ListBoxGetItem( lphl
, lphl
->ItemFocused
= y
);
946 n
= ListBoxSetSel(lphl
,-1,FALSE
);
948 lpls
->itemState
= ODS_FOCUS
| ODS_SELECTED
;
950 if( n
> 1 && n
!= LB_ERR
)
951 InvalidateRect32( hwnd
,NULL
,TRUE
);
958 if( y
!=lphl
->ItemFocused
)
959 ListBoxSetCurSel(lphl
, y
);
964 fprintf(stdnimp
,"Listbox: LBS_MULTIPLESEL and LBS_EXTENDEDSEL are on!\n");
968 /* invalidate changed items */
969 if( lphl
->dwStyle
& LBS_MULTIPLESEL
|| y
!=lphl
->PrevFocused
)
971 ListBoxGetItemRect(lphl
, y
, &rectsel
);
972 InvalidateRect16( hwnd
, &rectsel
, TRUE
);
974 if( lphl
->PrevFocused
!=-1 && y
!=lphl
->PrevFocused
)
976 ListBoxGetItemRect(lphl
, lphl
->PrevFocused
, &rectsel
);
977 InvalidateRect16( hwnd
, &rectsel
, TRUE
);
981 if (GetWindowLong(lphl
->hSelf
,GWL_EXSTYLE
) & WS_EX_DRAGDETECT
)
982 if( DragDetect(lphl
->hSelf
,MAKEPOINT16(lParam
)) )
983 SendMessage16(lphl
->hParent
, WM_BEGINDRAG
,0,0L);
988 /***********************************************************************
991 static LONG
LBLButtonUp(HWND hwnd
, WORD wParam
, LONG lParam
)
993 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
995 if (GetCapture() == hwnd
) ReleaseCapture();
997 if (lphl
->PrevFocused
!= lphl
->ItemFocused
)
998 ListBoxSendNotification(lphl
, LBN_SELCHANGE
);
1003 /***********************************************************************
1006 static LONG
LBRButtonUp(HWND hwnd
, WORD wParam
, LONG lParam
)
1008 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1011 SendMessage32A(lphl
->hParent
, WM_COMMAND
,
1012 MAKEWPARAM(GetWindowWord(hwnd
,GWW_ID
),LBN_DBLCLK
),
1015 SendMessage16(lphl
->hParent
, WM_COMMAND
, GetWindowWord(hwnd
,GWW_ID
),
1016 MAKELONG(hwnd
, LBN_DBLCLK
));
1022 /***********************************************************************
1025 static LONG
LBMouseMove(HWND hwnd
, WORD wParam
, LONG lParam
)
1027 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1028 int y
,redraw_prev
= 0;
1030 RECT16 rect
, rectsel
; /* XXX Broken */
1032 dprintf_listbox(stddeb
,"LBMouseMove %d %d\n",SLOWORD(lParam
),SHIWORD(lParam
));
1033 if ((wParam
& MK_LBUTTON
) != 0) {
1034 y
= SHIWORD(lParam
);
1035 if (y
< LBMM_EDGE
) {
1036 if (lphl
->FirstVisible
> 0) {
1037 lphl
->FirstVisible
--;
1038 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
1039 InvalidateRect32( hwnd
, NULL
, TRUE
);
1043 GetClientRect16(hwnd
, &rect
);
1044 if (y
>= (rect
.bottom
-LBMM_EDGE
)) {
1045 if (lphl
->FirstVisible
< ListMaxFirstVisible(lphl
)) {
1046 lphl
->FirstVisible
++;
1047 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
1048 InvalidateRect32( hwnd
, NULL
, TRUE
);
1052 if ((y
> 0) && (y
< (rect
.bottom
- LBMM_EDGE
))) {
1053 if ((y
< rectsel
.top
) || (y
> rectsel
.bottom
)) {
1054 iRet
= ListBoxFindMouse(lphl
, LOWORD(lParam
), HIWORD(lParam
));
1055 if (iRet
== lphl
->ItemFocused
|| iRet
== -1) {
1058 if (lphl
->dwStyle
& LBS_MULTIPLESEL
) {
1059 lphl
->ItemFocused
= iRet
;
1060 ListBoxSendNotification(lphl
, LBN_SELCHANGE
);
1061 } else if ( lphl
->dwStyle
& LBS_EXTENDEDSEL
)
1063 /* Fixme: extended selection mode */
1064 ListBoxSetSel( lphl
, lphl
->ItemFocused
, 0);
1065 lphl
->PrevFocused
= lphl
->ItemFocused
;
1066 lphl
->ItemFocused
= iRet
;
1067 ListBoxSetSel( lphl
, iRet
, TRUE
);
1072 ListBoxSetCurSel(lphl
, (WORD
)iRet
);
1075 if( lphl
->PrevFocused
!=-1 && redraw_prev
)
1077 ListBoxGetItemRect(lphl
, lphl
->PrevFocused
, &rectsel
);
1078 InvalidateRect16( hwnd
, &rectsel
, TRUE
);
1080 ListBoxGetItemRect(lphl
, iRet
, &rectsel
);
1081 InvalidateRect16( hwnd
, &rectsel
, TRUE
);
1089 /***********************************************************************
1092 * Doesn't yet handle properly VK_SHIFT with LB_EXTENDEDSEL
1094 static LONG
LBKeyDown(HWND hwnd
, WORD wParam
, LONG lParam
)
1096 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1097 WORD newFocused
= 0xFFFF;
1100 ListBoxGetItemRect(lphl
,lphl
->ItemFocused
,&rect
);
1111 if ( lphl
->dwStyle
& LBS_WANTKEYBOARDINPUT
)
1113 newFocused
= (WORD
)(INT
)SendMessage16(lphl
->hParent
,WM_VKEYTOITEM
,
1114 wParam
,MAKELPARAM(lphl
->ItemFocused
,hwnd
));
1115 if ( newFocused
== 0xFFFE ) return 0L;
1117 if ( newFocused
== 0xFFFF )
1119 newFocused
= lphl
->ItemFocused
;
1128 newFocused
= lphl
->ItemsCount
- 1;
1131 if (lphl
->dwStyle
& LBS_MULTICOLUMN
) {
1132 if (newFocused
>= lphl
->ItemsPerColumn
) {
1133 newFocused
-= lphl
->ItemsPerColumn
;
1140 if (newFocused
> 0) newFocused
--;
1143 if (lphl
->dwStyle
& LBS_MULTICOLUMN
)
1144 newFocused
+= lphl
->ItemsPerColumn
;
1150 if (newFocused
> lphl
->ItemsVisible
)
1151 newFocused
-= lphl
->ItemsVisible
;
1152 else newFocused
= 0;
1155 newFocused
+= lphl
->ItemsVisible
;
1160 /* end of nested switch */
1164 if (lphl
->dwStyle
& LBS_MULTIPLESEL
)
1166 WORD wRet
= ListBoxGetSel(lphl
, lphl
->ItemFocused
);
1167 ListBoxSetSel(lphl
, lphl
->ItemFocused
, !wRet
);
1171 /* chars are handled in LBChar */
1176 /* at this point newFocused is set up */
1178 if (newFocused
>= lphl
->ItemsCount
)
1179 newFocused
= lphl
->ItemsCount
- 1;
1181 if (!(lphl
->dwStyle
& LBS_MULTIPLESEL
))
1183 ListBoxSetCurSel(lphl
, newFocused
);
1184 ListBoxSendNotification(lphl
, LBN_SELCHANGE
);
1187 lphl
->ItemFocused
= newFocused
;
1189 if( ListBoxScrollToFocus(lphl
) || (lphl
->dwStyle
&
1190 (LBS_MULTIPLESEL
| LBS_EXTENDEDSEL
)) )
1191 InvalidateRect32( hwnd
, NULL
, TRUE
);
1194 InvalidateRect16( hwnd
, &rect
, TRUE
);
1195 if( newFocused
< 0x8000 )
1197 ListBoxGetItemRect(lphl
, newFocused
, &rect
);
1198 InvalidateRect16( hwnd
, &rect
, TRUE
);
1202 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
1207 /***********************************************************************
1210 static LONG
LBChar(HWND hwnd
, WORD wParam
, LONG lParam
)
1212 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1213 WORD newFocused
= 0xFFFF;
1215 if ( (lphl
->dwStyle
& LBS_WANTKEYBOARDINPUT
) && !(lphl
->HasStrings
))
1217 newFocused
= (WORD
)(INT
)SendMessage16(lphl
->hParent
,WM_CHARTOITEM
,
1218 wParam
,MAKELPARAM(lphl
->ItemFocused
,hwnd
));
1219 if ( newFocused
== 0xFFFE ) return 0L;
1222 if (newFocused
== 0xFFFF )
1223 newFocused
= ListBoxFindNextMatch(lphl
, wParam
);
1225 if (newFocused
== (WORD
)LB_ERR
) return 0;
1227 if (newFocused
>= lphl
->ItemsCount
)
1228 newFocused
= lphl
->ItemsCount
- 1;
1230 if (!(lphl
->dwStyle
& LBS_MULTIPLESEL
))
1232 ListBoxSetCurSel(lphl
, newFocused
);
1233 ListBoxSendNotification(lphl
, LBN_SELCHANGE
);
1236 lphl
->ItemFocused
= newFocused
;
1237 ListBoxScrollToFocus(lphl
);
1238 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
1240 InvalidateRect32( hwnd
, NULL
, TRUE
);
1245 /***********************************************************************
1248 static LONG
LBSetRedraw(HWND hwnd
, WORD wParam
, LONG lParam
)
1250 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1252 dprintf_listbox(stddeb
,"ListBox WM_SETREDRAW hWnd=%04x w=%04x !\n",
1254 lphl
->bRedrawFlag
= wParam
;
1259 /***********************************************************************
1262 static LONG
LBSetFont(HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1264 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1268 lphl
->hFont
= GetStockObject(SYSTEM_FONT
);
1270 lphl
->hFont
= (HFONT
) wParam
;
1272 /* a new font means possible new text height */
1273 /* does this mean the height of each entry must be separately changed? */
1274 /* or are we guaranteed to get a LBSetFont before the first insert/add? */
1275 if ((hdc
= GetDC(0)))
1278 GetTextMetrics( hdc
, &tm
);
1279 lphl
->StdItemHeight
= tm
.tmHeight
;
1280 dprintf_listbox(stddeb
,"LBSetFont: new font %d with height %d\n",
1281 lphl
->hFont
, lphl
->StdItemHeight
);
1282 ReleaseDC( 0, hdc
);
1288 /***********************************************************************
1291 static LONG
LBPaint(HWND hwnd
, WORD wParam
, LONG lParam
)
1293 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1298 HDC16 hdc
= BeginPaint16( hwnd
, &ps
);
1299 DC
*dc
= (DC
*)GDI_GetObjPtr(hdc
, DC_MAGIC
);
1300 RECT16 rect
, paintRect
, scratchRect
;
1301 int i
, top
, height
, maxwidth
, ipc
;
1305 if (!IsWindowVisible(hwnd
) || !lphl
->bRedrawFlag
) {
1306 EndPaint16(hwnd
, &ps
);
1310 GetRgnBox16(dc
->w
.hGCClipRgn
,&paintRect
);
1311 GetClientRect16(hwnd
, &rect
);
1312 IntersectRect16(&paintRect
,&rect
,&paintRect
);
1314 hOldFont
= SelectObject(hdc
, lphl
->hFont
);
1317 hBrush
= (HBRUSH
) SendMessage16(lphl
->hParent
, WM_CTLCOLORLISTBOX
, (WPARAM
)hdc
,
1320 hBrush
= SendMessage16(lphl
->hParent
, WM_CTLCOLOR
, hdc
,
1321 MAKELONG(hwnd
, CTLCOLOR_LISTBOX
));
1324 if (hBrush
== 0) hBrush
= GetStockObject(WHITE_BRUSH
);
1326 FillRect16(hdc
, &rect
, hBrush
);
1328 maxwidth
= rect
.right
;
1329 if (lphl
->dwStyle
& LBS_MULTICOLUMN
) {
1330 rect
.right
= lphl
->ColumnsWidth
;
1332 lpls
= lphl
->lpFirst
;
1334 lphl
->ItemsVisible
= 0;
1335 lphl
->ItemsPerColumn
= ipc
= 0;
1337 for(i
= 0; i
< lphl
->ItemsCount
; i
++) {
1338 if (lpls
== NULL
) break;
1340 if (i
>= lphl
->FirstVisible
) {
1341 height
= lpls
->mis
.itemHeight
;
1343 if (top
> (rect
.bottom
-height
+1)) {
1344 if (lphl
->dwStyle
& LBS_MULTICOLUMN
) {
1345 lphl
->ItemsPerColumn
= MAX(lphl
->ItemsPerColumn
, ipc
);
1348 rect
.left
+= lphl
->ColumnsWidth
;
1349 rect
.right
+= lphl
->ColumnsWidth
;
1350 if (rect
.left
> maxwidth
) break;
1356 lpls
->itemRect
.top
= top
;
1357 lpls
->itemRect
.bottom
= top
+ height
;
1358 lpls
->itemRect
.left
= rect
.left
;
1359 lpls
->itemRect
.right
= rect
.right
;
1361 if( IntersectRect16(&scratchRect
,&paintRect
,&lpls
->itemRect
) )
1363 dprintf_listbox(stddeb
,"LBPaint: drawing item: %d %d %d %d %d\n",
1364 rect
.left
,top
,rect
.right
,top
+height
,lpls
->itemState
);
1366 if (lphl
->OwnerDrawn
&& (lphl
->ItemFocused
== i
) && GetFocus() == hwnd
)
1368 ListBoxDrawItem (hwnd
, lphl
, hdc
, lpls
, &lpls
->itemRect
, ODA_FOCUS
,
1369 lpls
->itemState
& ~ODS_FOCUS
);
1370 ListBoxDrawItem (hwnd
, lphl
, hdc
, lpls
, &lpls
->itemRect
, ODA_DRAWENTIRE
,
1371 lpls
->itemState
& ~ODS_FOCUS
);
1372 ListBoxDrawItem (hwnd
, lphl
, hdc
, lpls
, &lpls
->itemRect
, ODA_FOCUS
, lpls
->itemState
);
1375 ListBoxDrawItem (hwnd
, lphl
, hdc
, lpls
, &lpls
->itemRect
, ODA_DRAWENTIRE
,
1380 lphl
->ItemsVisible
++;
1384 lpls
= lpls
->lpNext
;
1386 ListBoxUpdateWindow(hwnd
,lphl
,FALSE
);
1387 SelectObject(hdc
,hOldFont
);
1388 EndPaint16( hwnd
, &ps
);
1392 /***********************************************************************
1395 static LONG
LBSetFocus(HWND hwnd
, WORD wParam
, LONG lParam
)
1397 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1399 dprintf_listbox(stddeb
,"ListBox WM_SETFOCUS for %04x\n",hwnd
);
1400 if(!(lphl
->dwStyle
& LBS_MULTIPLESEL
) )
1401 if( lphl
->ItemsCount
&& lphl
->ItemFocused
!= -1)
1403 HDC hDC
= GetDC(hwnd
);
1404 HFONT hOldFont
= SelectObject(hDC
, lphl
->hFont
);
1407 lpls
= ListBoxGetItem(lphl
,lphl
->ItemFocused
);
1408 lpls
->itemState
|= ODS_FOCUS
;
1410 ListBoxDrawItem(hwnd
,lphl
,hDC
,lpls
,&lpls
->itemRect
, ODA_FOCUS
, lpls
->itemState
);
1411 SelectObject(hDC
, hOldFont
);
1412 ReleaseDC(hwnd
,hDC
);
1415 ListBoxSendNotification(lphl
, LBN_SETFOCUS
);
1420 /***********************************************************************
1423 static LONG
LBKillFocus(HWND hwnd
, WORD wParam
, LONG lParam
)
1425 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1427 dprintf_listbox(stddeb
,"ListBox WM_KILLFOCUS for %04x\n",hwnd
);
1428 if (!(lphl
->dwStyle
& LBS_MULTIPLESEL
))
1430 if( lphl
->ItemsCount
)
1431 if( lphl
->ItemFocused
!= -1 )
1433 HDC hDC
= GetDC(hwnd
);
1434 HFONT hOldFont
= SelectObject(hDC
, lphl
->hFont
);
1437 lpls
= ListBoxGetItem(lphl
,lphl
->ItemFocused
);
1438 lpls
->itemState
&= ~ODS_FOCUS
;
1440 ListBoxDrawItem(hwnd
,lphl
,hDC
,lpls
,&lpls
->itemRect
, ODA_FOCUS
, lpls
->itemState
);
1441 SelectObject(hDC
, hOldFont
);
1442 ReleaseDC(hwnd
,hDC
);
1445 dprintf_listbox(stddeb
,"LBKillFocus: no focused item!\n");
1448 InvalidateRect32( hwnd
, NULL
, TRUE
);
1450 ListBoxSendNotification(lphl
, LBN_KILLFOCUS
);
1455 /***********************************************************************
1458 static LONG
LBResetContent(HWND hwnd
, WORD wParam
, LONG lParam
)
1460 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1462 dprintf_listbox(stddeb
,"ListBox LB_RESETCONTENT !\n");
1463 ListBoxResetContent(lphl
);
1464 ListBoxUpdateWindow(hwnd
, lphl
, TRUE
);
1468 /***********************************************************************
1471 static LONG
LBDir(HWND hwnd
, WORD wParam
, LONG lParam
)
1474 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1475 dprintf_listbox(stddeb
,"ListBox LB_DIR !\n");
1477 ret
= ListBoxDirectory(lphl
, wParam
, (LPSTR
)PTR_SEG_TO_LIN(lParam
));
1478 ListBoxUpdateWindow(hwnd
, lphl
, TRUE
);
1482 /***********************************************************************
1485 static LONG
LBAddString(HWND hwnd
, WORD wParam
, LONG lParam
)
1488 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1490 if (lphl
->HasStrings
)
1491 wRet
= ListBoxAddString(lphl
, (LPCSTR
)PTR_SEG_TO_LIN(lParam
));
1493 wRet
= ListBoxAddString(lphl
, (LPCSTR
)lParam
);
1495 ListBoxUpdateWindow(hwnd
,lphl
,TRUE
);
1499 /***********************************************************************
1502 static LONG
LBGetText(HWND hwnd
, WORD wParam
, LONG lParam
)
1505 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1507 dprintf_listbox(stddeb
, "LB_GETTEXT wParam=%d\n",wParam
);
1508 wRet
= ListBoxGetText(lphl
, wParam
, (LPSTR
)PTR_SEG_TO_LIN(lParam
));
1513 /***********************************************************************
1516 static LONG
LBInsertString(HWND hwnd
, WORD wParam
, LONG lParam
)
1519 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1521 if (lphl
->HasStrings
)
1522 wRet
= ListBoxInsertString(lphl
, wParam
, (LPCSTR
)PTR_SEG_TO_LIN(lParam
));
1524 wRet
= ListBoxInsertString(lphl
, wParam
, (LPCSTR
)lParam
);
1526 ListBoxUpdateWindow(hwnd
,lphl
,TRUE
);
1530 /***********************************************************************
1533 static LONG
LBDeleteString(HWND hwnd
, WORD wParam
, LONG lParam
)
1535 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1536 LONG lRet
= ListBoxDeleteString(lphl
,wParam
);
1538 ListBoxUpdateWindow(hwnd
,lphl
,TRUE
);
1542 /***********************************************************************
1545 static LONG
LBFindString(HWND hwnd
, WORD wParam
, LONG lParam
)
1547 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1548 return ListBoxFindString(lphl
, wParam
, (SEGPTR
)lParam
);
1551 /***********************************************************************
1554 static LONG
LBGetCaretIndex(HWND hwnd
, WORD wParam
, LONG lParam
)
1556 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1557 return lphl
->ItemFocused
;
1560 /***********************************************************************
1563 static LONG
LBGetCount(HWND hwnd
, WORD wParam
, LONG lParam
)
1567 lphl
= ListBoxGetStorageHeader(hwnd
);
1568 return lphl
->ItemsCount
;
1571 /***********************************************************************
1574 static LONG
LBGetCurSel(HWND hwnd
, WORD wParam
, LONG lParam
)
1578 lphl
= ListBoxGetStorageHeader(hwnd
);
1579 dprintf_listbox(stddeb
,"ListBox LB_GETCURSEL %i !\n",
1581 return lphl
->ItemFocused
;
1584 /***********************************************************************
1585 * LBGetHorizontalExtent
1587 static LONG
LBGetHorizontalExtent(HWND hwnd
, WORD wParam
, LONG lParam
)
1592 /***********************************************************************
1595 static LONG
LBGetItemHeight(HWND hwnd
, WORD wParam
, LONG lParam
)
1597 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1598 LPLISTSTRUCT lpls
= ListBoxGetItem (lphl
, wParam
);
1600 if (lpls
== NULL
) return LB_ERR
;
1601 return lpls
->mis
.itemHeight
;
1604 /***********************************************************************
1607 static LONG
LBGetItemRect(HWND hwnd
, WORD wParam
, LONG lParam
)
1609 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1610 return ListBoxGetItemRect(lphl
, wParam
, PTR_SEG_TO_LIN(lParam
));
1613 /***********************************************************************
1616 static LONG
LBGetSel(HWND hwnd
, WORD wParam
, LONG lParam
)
1618 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1619 int iSel
= ListBoxGetSel(lphl
, wParam
);
1621 dprintf_listbox(stdnimp
,"LBGetSel: item %u - %i\n",wParam
,iSel
);
1623 return (iSel
)? 1 : 0;
1626 /***********************************************************************
1629 static LONG
LBGetSelCount(HWND hwnd
, WORD wParam
, LONG lParam
)
1631 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1636 if (!(lphl
->dwStyle
& (LBS_MULTIPLESEL
| LBS_EXTENDEDSEL
) ))
1639 for( lpls
= lphl
->lpFirst
;
1641 lpls
= lpls
->lpNext
)
1644 if (lpls
->itemState
)
1651 /***********************************************************************
1654 static LONG
LBGetSelItems(HWND hwnd
, WORD wParam
, LONG lParam
)
1656 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1659 int *lpItems
= PTR_SEG_TO_LIN(lParam
);
1661 if (!(lphl
->dwStyle
& (LBS_MULTIPLESEL
| LBS_EXTENDEDSEL
) ))
1664 if (wParam
== 0) return 0;
1666 lpls
= lphl
->lpFirst
;
1669 while (lpls
!= NULL
) {
1670 if (lpls
->itemState
> 0) lpItems
[cnt
++] = idx
;
1672 if (cnt
== wParam
) break;
1674 lpls
= lpls
->lpNext
;
1680 /***********************************************************************
1683 static LONG
LBGetTextLen(HWND hwnd
, WORD wParam
, LONG lParam
)
1685 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1686 LPLISTSTRUCT lpls
= ListBoxGetItem(lphl
,wParam
);
1688 if (lpls
== NULL
|| !lphl
->HasStrings
) return LB_ERR
;
1689 return strlen(lpls
->itemText
);
1692 /***********************************************************************
1695 static LONG
LBGetDlgCode(HWND hwnd
, WORD wParam
, LONG lParam
)
1697 return DLGC_WANTARROWS
| DLGC_WANTCHARS
;
1700 /***********************************************************************
1703 static LONG
LBGetTopIndex(HWND hwnd
, WORD wParam
, LONG lParam
)
1705 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1707 return lphl
->FirstVisible
;
1711 /***********************************************************************
1714 static LONG
LBSelectString(HWND hwnd
, WORD wParam
, LONG lParam
)
1716 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1719 iRet
= ListBoxFindString(lphl
, wParam
, (SEGPTR
)lParam
);
1723 if( lphl
->dwStyle
& (LBS_MULTIPLESEL
| LBS_EXTENDEDSEL
) )
1724 ListBoxSetSel(lphl
,iRet
,TRUE
);
1726 ListBoxSetCurSel(lphl
,iRet
);
1728 lphl
->ItemFocused
= iRet
;
1729 InvalidateRect32( hwnd
, 0, TRUE
);
1734 /***********************************************************************
1737 static LONG
LBSelItemRange(HWND hwnd
, WORD wParam
, LONG lParam
)
1739 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1742 WORD first
= LOWORD(lParam
);
1743 WORD last
= HIWORD(lParam
);
1744 BOOL select
= wParam
;
1746 if (!(lphl
->dwStyle
& (LBS_MULTIPLESEL
| LBS_EXTENDEDSEL
) ))
1749 if (first
>= lphl
->ItemsCount
||
1750 last
>= lphl
->ItemsCount
) return LB_ERR
;
1752 lpls
= lphl
->lpFirst
;
1755 while (lpls
!= NULL
) {
1757 lpls
->itemState
= select
? lpls
->itemState
| ODS_SELECTED
: 0;
1762 lpls
= lpls
->lpNext
;
1768 /***********************************************************************
1771 static LONG
LBSetCaretIndex(HWND hwnd
, WORD wParam
, LONG lParam
)
1773 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1776 if (!(lphl
->dwStyle
& (LBS_MULTIPLESEL
| LBS_EXTENDEDSEL
) )) return 0;
1778 dprintf_listbox(stddeb
,"LBSetCaretIndex: hwnd %04x n=%i\n",hwnd
,wParam
);
1780 if (wParam
>= lphl
->ItemsCount
) return LB_ERR
;
1782 lphl
->ItemFocused
= wParam
;
1783 i
= ListBoxScrollToFocus (lphl
);
1785 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
1787 InvalidateRect32( hwnd
, NULL
, TRUE
);
1792 /***********************************************************************
1795 static LONG
LBSetColumnWidth(HWND hwnd
, WORD wParam
, LONG lParam
)
1797 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1798 lphl
->ColumnsWidth
= wParam
;
1799 InvalidateRect32( hwnd
, NULL
, TRUE
);
1803 /***********************************************************************
1804 * LBSetHorizontalExtent
1806 static LONG
LBSetHorizontalExtent(HWND hwnd
, WORD wParam
, LONG lParam
)
1811 /***********************************************************************
1814 static LONG
LBGetItemData(HWND hwnd
, WORD wParam
, LONG lParam
)
1816 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1817 dprintf_listbox(stddeb
, "LB_GETITEMDATA wParam=%x\n", wParam
);
1818 return ListBoxGetItemData(lphl
, wParam
);
1821 /***********************************************************************
1824 static LONG
LBSetItemData(HWND hwnd
, WORD wParam
, LONG lParam
)
1826 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1827 dprintf_listbox(stddeb
, "LB_SETITEMDATA wParam=%x lParam=%lx\n", wParam
, lParam
);
1828 return ListBoxSetItemData(lphl
, wParam
, lParam
);
1831 /***********************************************************************
1834 static LONG
LBSetTabStops(HWND hwnd
, WORD wParam
, LONG lParam
)
1838 lphl
= ListBoxGetStorageHeader(hwnd
);
1840 if (lphl
->TabStops
!= NULL
) {
1841 lphl
->iNumStops
= 0;
1842 free (lphl
->TabStops
);
1845 lphl
->TabStops
= malloc (wParam
* sizeof (short));
1846 if (lphl
->TabStops
) {
1847 lphl
->iNumStops
= wParam
;
1848 memcpy (lphl
->TabStops
, PTR_SEG_TO_LIN(lParam
), wParam
* sizeof (short));
1855 /***********************************************************************
1858 static LONG
LBSetCurSel(HWND hwnd
, WORD wParam
, LONG lParam
)
1860 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1863 dprintf_listbox(stddeb
,"ListBox LB_SETCURSEL wParam=%x !\n",
1866 wRet
= ListBoxSetCurSel(lphl
, wParam
);
1868 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
1869 InvalidateRect32( hwnd
, NULL
, TRUE
);
1874 /***********************************************************************
1877 static LONG
LBSetSel(HWND hwnd
, WORD wParam
, LONG lParam
)
1879 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1883 dprintf_listbox(stddeb
,"ListBox LB_SETSEL wParam=%x lParam=%lX !\n", wParam
, lParam
);
1885 iRet
= ListBoxSetSel(lphl
, LOWORD(lParam
), wParam
);
1887 if( iRet
> 1 ) InvalidateRect32( hwnd
, NULL
, TRUE
);
1888 else if( iRet
!= LB_ERR
)
1890 if( lphl
->dwStyle
& LBS_EXTENDEDSEL
&&
1891 lphl
->ItemFocused
!= LOWORD(lParam
) )
1893 ListBoxGetItemRect(lphl
, lphl
->ItemFocused
, &rect
);
1894 InvalidateRect16( hwnd
, &rect
, TRUE
);
1895 lphl
->ItemFocused
= LOWORD(lParam
);
1897 ListBoxGetItemRect(lphl
,LOWORD(lParam
),&rect
);
1898 InvalidateRect16( hwnd
, &rect
, TRUE
);
1901 return (iRet
== (WORD
)LB_ERR
)? LB_ERR
: 0;
1904 /***********************************************************************
1907 static LONG
LBSetTopIndex(HWND hwnd
, WORD wParam
, LONG lParam
)
1909 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1911 dprintf_listbox(stddeb
,"ListBox LB_SETTOPINDEX wParam=%x !\n",
1913 lphl
->FirstVisible
= wParam
;
1914 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
1916 InvalidateRect32( hwnd
, NULL
, TRUE
);
1921 /***********************************************************************
1924 static LONG
LBSetItemHeight(HWND hwnd
, WORD wParam
, LONG lParam
)
1926 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1929 dprintf_listbox(stddeb
,"ListBox LB_SETITEMHEIGHT wParam=%x lParam=%lX !\n", wParam
, lParam
);
1930 wRet
= ListBoxSetItemHeight(lphl
, wParam
, lParam
);
1931 InvalidateRect32( hwnd
, NULL
, TRUE
);
1935 /***********************************************************************
1938 static LRESULT
LBPassToParent(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1940 WND
* ptrWnd
= WIN_FindWndPtr(hwnd
);
1943 if( /* !(ptrWnd->dwExStyle & WS_EX_NOPARENTNOTIFY) && */
1945 return SendMessage16(ptrWnd
->parent
->hwndSelf
,message
,wParam
,lParam
);
1949 /***********************************************************************
1952 LRESULT
ListBoxWndProc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1955 case WM_CREATE
: return LBCreate(hwnd
, wParam
, lParam
);
1956 case WM_DESTROY
: return LBDestroy(hwnd
, wParam
, lParam
);
1957 case WM_GETDLGCODE
: return LBGetDlgCode(hwnd
, wParam
, lParam
);
1958 case WM_VSCROLL
: return LBVScroll(hwnd
, wParam
, lParam
);
1959 case WM_HSCROLL
: return LBHScroll(hwnd
, wParam
, lParam
);
1960 case WM_LBUTTONDOWN
: return LBLButtonDown(hwnd
, wParam
, lParam
);
1961 case WM_LBUTTONUP
: return LBLButtonUp(hwnd
, wParam
, lParam
);
1962 case WM_RBUTTONUP
: return LBRButtonUp(hwnd
, wParam
, lParam
);
1963 case WM_LBUTTONDBLCLK
: return LBRButtonUp(hwnd
, wParam
, lParam
);
1964 case WM_MOUSEMOVE
: return LBMouseMove(hwnd
, wParam
, lParam
);
1965 case WM_KEYDOWN
: return LBKeyDown(hwnd
, wParam
, lParam
);
1966 case WM_CHAR
: return LBChar(hwnd
, wParam
, lParam
);
1967 case WM_SETFONT
: return LBSetFont(hwnd
, wParam
, lParam
);
1968 case WM_SETREDRAW
: return LBSetRedraw(hwnd
, wParam
, lParam
);
1969 case WM_PAINT
: return LBPaint(hwnd
, wParam
, lParam
);
1970 case WM_SETFOCUS
: return LBSetFocus(hwnd
, wParam
, lParam
);
1971 case WM_KILLFOCUS
: return LBKillFocus(hwnd
, wParam
, lParam
);
1972 case LB_RESETCONTENT
: return LBResetContent(hwnd
, wParam
, lParam
);
1973 case LB_DIR
: return LBDir(hwnd
, wParam
, lParam
);
1974 case LB_ADDSTRING
: return LBAddString(hwnd
, wParam
, lParam
);
1975 case LB_INSERTSTRING
: return LBInsertString(hwnd
, wParam
, lParam
);
1976 case LB_DELETESTRING
: return LBDeleteString(hwnd
, wParam
, lParam
);
1977 case LB_FINDSTRING
: return LBFindString(hwnd
, wParam
, lParam
);
1978 case LB_GETCARETINDEX
: return LBGetCaretIndex(hwnd
, wParam
, lParam
);
1979 case LB_GETCOUNT
: return LBGetCount(hwnd
, wParam
, lParam
);
1980 case LB_GETCURSEL
: return LBGetCurSel(hwnd
, wParam
, lParam
);
1981 case LB_GETHORIZONTALEXTENT
: return LBGetHorizontalExtent(hwnd
, wParam
, lParam
);
1982 case LB_GETITEMDATA
: return LBGetItemData(hwnd
, wParam
, lParam
);
1983 case LB_GETITEMHEIGHT
: return LBGetItemHeight(hwnd
, wParam
, lParam
);
1984 case LB_GETITEMRECT
: return LBGetItemRect(hwnd
, wParam
, lParam
);
1985 case LB_GETSEL
: return LBGetSel(hwnd
, wParam
, lParam
);
1986 case LB_GETSELCOUNT
: return LBGetSelCount(hwnd
, wParam
, lParam
);
1987 case LB_GETSELITEMS
: return LBGetSelItems(hwnd
, wParam
, lParam
);
1988 case LB_GETTEXT
: return LBGetText(hwnd
, wParam
, lParam
);
1989 case LB_GETTEXTLEN
: return LBGetTextLen(hwnd
, wParam
, lParam
);
1990 case LB_GETTOPINDEX
: return LBGetTopIndex(hwnd
, wParam
, lParam
);
1991 case LB_SELECTSTRING
: return LBSelectString(hwnd
, wParam
, lParam
);
1992 case LB_SELITEMRANGE
: return LBSelItemRange(hwnd
, wParam
, lParam
);
1993 case LB_SETCARETINDEX
: return LBSetCaretIndex(hwnd
, wParam
, lParam
);
1994 case LB_SETCOLUMNWIDTH
: return LBSetColumnWidth(hwnd
, wParam
, lParam
);
1995 case LB_SETHORIZONTALEXTENT
: return LBSetHorizontalExtent(hwnd
, wParam
, lParam
);
1996 case LB_SETITEMDATA
: return LBSetItemData(hwnd
, wParam
, lParam
);
1997 case LB_SETTABSTOPS
: return LBSetTabStops(hwnd
, wParam
, lParam
);
1998 case LB_SETCURSEL
: return LBSetCurSel(hwnd
, wParam
, lParam
);
1999 case LB_SETSEL
: return LBSetSel(hwnd
, wParam
, lParam
);
2000 case LB_SETTOPINDEX
: return LBSetTopIndex(hwnd
, wParam
, lParam
);
2001 case LB_SETITEMHEIGHT
: return LBSetItemHeight(hwnd
, wParam
, lParam
);
2003 case WM_DROPFILES
: return LBPassToParent(hwnd
, message
, wParam
, lParam
);
2005 /* these will have to be implemented for proper LBS_EXTENDEDSEL -
2007 * anchor item is an item that with caret (focused) item defines a
2008 * range of currently selected items when listbox is in the extended
2011 case LB_SETANCHORINDEX
: return LB_SETANCHORINDEX
; /* that's what Windows returns */
2012 case LB_GETANCHORINDEX
: return 0;
2015 case WM_QUERYDROPOBJECT
:
2019 LPDRAGINFO lpDragInfo
= (LPDRAGINFO
) PTR_SEG_TO_LIN((SEGPTR
)lParam
);
2020 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
2022 lpDragInfo
->l
= ListBoxFindMouse(lphl
,lpDragInfo
->pt
.x
,
2025 return LBPassToParent(hwnd
, message
, wParam
, lParam
);
2029 return DefWindowProc16(hwnd
, message
, wParam
, lParam
);
2033 /**********************************************************************
2034 * DlgDirSelect (USER.99)
2036 BOOL
DlgDirSelect( HWND hDlg
, LPSTR lpStr
, INT id
)
2041 dprintf_listbox( stddeb
, "DlgDirSelect: %04x '%s' %d\n", hDlg
, lpStr
, id
);
2042 if ((i
= SendDlgItemMessage16( hDlg
, id
, LB_GETCURSEL
, 0, 0 )) == LB_ERR
)
2044 if (!(buffer
= SEGPTR_ALLOC( 20 * sizeof(char) ))) return FALSE
;
2045 SendDlgItemMessage16(hDlg
, id
, LB_GETTEXT
, i
, (LPARAM
)SEGPTR_GET(buffer
) );
2046 if (buffer
[0] == '[') /* drive or directory */
2048 if (buffer
[1] == '-') /* drive */
2050 lpStr
[0] = buffer
[2];
2053 dprintf_listbox( stddeb
, "Returning drive '%s'\n", lpStr
);
2054 SEGPTR_FREE(buffer
);
2057 strcpy( lpStr
, buffer
+ 1 );
2058 lpStr
[strlen(lpStr
)-1] = '\\';
2059 dprintf_listbox( stddeb
, "Returning directory '%s'\n", lpStr
);
2060 SEGPTR_FREE(buffer
);
2063 strcpy( lpStr
, buffer
);
2064 dprintf_listbox( stddeb
, "Returning file '%s'\n", lpStr
);
2065 SEGPTR_FREE(buffer
);
2070 /**********************************************************************
2071 * DlgDirList (USER.100)
2073 INT
DlgDirList( HWND hDlg
, SEGPTR spec
, INT idLBox
, INT idStatic
, UINT attrib
)
2075 char *filespec
= (char *)PTR_SEG_TO_LIN( spec
);
2079 #define SENDMSG(msg,wparam,lparam) \
2080 ((attrib & DDL_POSTMSGS) ? PostMessage( hwnd, msg, wparam, lparam ) \
2081 : SendMessage16( hwnd, msg, wparam, lparam ))
2083 dprintf_listbox( stddeb
, "DlgDirList: %04x '%s' %d %d %04x\n",
2084 hDlg
, filespec
? filespec
: "NULL",
2085 idLBox
, idStatic
, attrib
);
2087 if (filespec
&& filespec
[0] && (filespec
[1] == ':'))
2089 drive
= toupper( filespec
[0] ) - 'A';
2091 if (!DRIVE_SetCurrentDrive( drive
)) return FALSE
;
2093 else drive
= DRIVE_GetCurrentDrive();
2095 if (idLBox
&& ((hwnd
= GetDlgItem( hDlg
, idLBox
)) != 0))
2099 if (!filespec
[0]) strcpy( mask
, "*.*" );
2102 /* If the path exists and is a directory, chdir to it */
2103 if (DRIVE_Chdir( drive
, filespec
)) strcpy( mask
, "*.*" );
2108 if ((p2
= strrchr( p
, '\\' ))) p
= p2
+ 1;
2109 if ((p2
= strrchr( p
, '/' ))) p
= p2
+ 1;
2110 lstrcpyn( mask
, p
, sizeof(mask
) );
2114 if (!DRIVE_Chdir( drive
, filespec
)) return FALSE
;
2119 strcpy( (char *)PTR_SEG_TO_LIN(spec
), mask
);
2121 dprintf_listbox(stddeb
, "ListBoxDirectory: path=%c:\\%s mask=%s\n",
2122 'A' + drive
, DRIVE_GetDosCwd(drive
), mask
);
2124 SENDMSG( LB_RESETCONTENT
, 0, 0 );
2125 if ((attrib
& DDL_DIRECTORY
) && !(attrib
& DDL_EXCLUSIVE
))
2128 if (SENDMSG( LB_DIR
, attrib
& ~(DDL_DIRECTORY
| DDL_DRIVES
),
2129 (LPARAM
)spec
) == LB_ERR
) return FALSE
;
2130 if (!(temp
= SEGPTR_ALLOC( 4*sizeof(char) ))) return FALSE
;
2131 strcpy( temp
, "*.*" );
2132 /* FIXME: this won't work with PostMessage(), as temp will */
2133 /* have been freed by the time we do a DispatchMessage(). */
2134 if (SENDMSG( LB_DIR
, (attrib
& (DDL_DIRECTORY
| DDL_DRIVES
)) | DDL_EXCLUSIVE
,
2135 (LPARAM
)SEGPTR_GET(temp
) ) == LB_ERR
)
2144 if (SENDMSG( LB_DIR
, attrib
, (LPARAM
)spec
) == LB_ERR
) return FALSE
;
2148 if (idStatic
&& ((hwnd
= GetDlgItem( hDlg
, idStatic
)) != 0))
2151 int drive
= DRIVE_GetCurrentDrive();
2152 strcpy( temp
, "A:\\" );
2154 lstrcpyn( temp
+ 3, DRIVE_GetDosCwd(drive
), sizeof(temp
)-3 );
2156 /* Can't use PostMessage() here, because the string is on the stack */
2157 SetDlgItemText32A( hDlg
, idStatic
, temp
);