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
30 #include "stackframe.h"
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 static void ListBoxInitialize(LPHEADLIST lphl
)
70 lphl
->ItemsVisible
= 0;
71 lphl
->FirstVisible
= 0;
72 lphl
->ColumnsVisible
= 1;
73 lphl
->ItemsPerColumn
= 0;
74 lphl
->ItemFocused
= -1;
75 lphl
->PrevFocused
= -1;
78 void CreateListBoxStruct(HWND hwnd
, WORD CtlType
, LONG styles
, HWND parent
)
83 lphl
= (LPHEADLIST
)xmalloc(sizeof(HEADLIST
));
84 SetWindowLong(hwnd
, 0, (LONG
)lphl
);
85 ListBoxInitialize(lphl
);
86 lphl
->DrawCtlType
= CtlType
;
87 lphl
->CtlID
= GetWindowWord(hwnd
,GWW_ID
);
88 lphl
->bRedrawFlag
= TRUE
;
90 lphl
->TabStops
= NULL
;
91 lphl
->hFont
= GetStockObject(SYSTEM_FONT
);
93 if (CtlType
==ODT_COMBOBOX
) /* use the "faked" style for COMBOLBOX */
94 /* LBS_SORT instead CBS_SORT e.g. */
95 lphl
->dwStyle
= MAKELONG(LOWORD(styles
),HIWORD(GetWindowLong(hwnd
,GWL_STYLE
)));
97 lphl
->dwStyle
= GetWindowLong(hwnd
,GWL_STYLE
); /* use original style dword */
98 lphl
->hParent
= parent
;
99 lphl
->StdItemHeight
= 15; /* FIXME: should get the font height */
100 lphl
->OwnerDrawn
= styles
& (LBS_OWNERDRAWFIXED
| LBS_OWNERDRAWVARIABLE
);
101 lphl
->HasStrings
= (styles
& LBS_HASSTRINGS
) || !lphl
->OwnerDrawn
;
103 /* create dummy hdc to set text height */
104 if ((hdc
= GetDC(0)))
107 GetTextMetrics( hdc
, &tm
);
108 lphl
->StdItemHeight
= tm
.tmHeight
;
109 dprintf_listbox(stddeb
,"CreateListBoxStruct: font height %d\n",
110 lphl
->StdItemHeight
);
114 if (lphl
->OwnerDrawn
) {
117 lphl
->hDrawItemStruct
= USER_HEAP_ALLOC(sizeof(DRAWITEMSTRUCT
));
118 lphl
->needMeasure
= TRUE
;
119 dummyls
.mis
.CtlType
= lphl
->DrawCtlType
;
120 dummyls
.mis
.CtlID
= lphl
->CtlID
;
121 dummyls
.mis
.itemID
= -1;
122 dummyls
.mis
.itemWidth
= 0; /* ignored */
123 dummyls
.mis
.itemData
= 0;
125 ListBoxAskMeasure(lphl
,&dummyls
);
127 lphl
->hDrawItemStruct
= 0;
131 HeapHandle
= GlobalAlloc(GMEM_FIXED
, LIST_HEAP_SIZE
);
132 HeapBase
= GlobalLock(HeapHandle
);
133 HEAP_Init(&lphl
->Heap
, HeapBase
, LIST_HEAP_SIZE
);
135 /* WINELIBS list boxes do not operate on local heaps */
137 lphl
->HeapSel
= GlobalAlloc(GMEM_FIXED
,LIST_HEAP_SIZE
);
138 LocalInit( lphl
->HeapSel
, 0, LIST_HEAP_SIZE
-1);
144 void DestroyListBoxStruct(LPHEADLIST lphl
)
146 if (lphl
->hDrawItemStruct
)
147 USER_HEAP_FREE(lphl
->hDrawItemStruct
);
149 /* XXX need to free lphl->Heap */
150 GlobalFree(lphl
->HeapSel
);
154 static LPHEADLIST
ListBoxGetStorageHeader(HWND hwnd
)
156 return (LPHEADLIST
)GetWindowLong(hwnd
,0);
159 /* Send notification "code" as part of a WM_COMMAND-message if hwnd
160 has the LBS_NOTIFY style */
161 void ListBoxSendNotification(LPHEADLIST lphl
, WORD code
)
163 if (lphl
->dwStyle
& LBS_NOTIFY
)
165 SendMessage(lphl
->hParent
, WM_COMMAND
,
166 MAKEWPARAM(lphl
->CtlID
,code
), (LPARAM
)lphl
->hSelf
);
168 SendMessage(lphl
->hParent
, WM_COMMAND
,
169 lphl
->CtlID
, MAKELONG(lphl
->hSelf
, code
));
174 /* get the maximum value of lphl->FirstVisible */
175 int ListMaxFirstVisible(LPHEADLIST lphl
)
177 int m
= lphl
->ItemsCount
-lphl
->ItemsVisible
;
178 return (m
< 0) ? 0 : m
;
182 void ListBoxUpdateWindow(HWND hwnd
, LPHEADLIST lphl
, BOOL repaint
)
184 SetScrollRange(hwnd
, SB_VERT
, 0, ListMaxFirstVisible(lphl
), TRUE
);
185 if (lphl
->ItemsPerColumn
!= 0) {
186 SetScrollRange(hwnd
, SB_HORZ
, 1, lphl
->ItemsVisible
/
187 lphl
->ItemsPerColumn
+ 1, TRUE
);
189 if (repaint
&& lphl
->bRedrawFlag
) {
190 InvalidateRect(hwnd
, NULL
, TRUE
);
194 /* Returns: 0 if nothing needs to be changed */
195 /* 1 if FirstVisible changed */
197 int ListBoxScrollToFocus(LPHEADLIST lphl
)
201 if (lphl
->ItemsCount
== 0) return 0;
202 if (lphl
->ItemFocused
== -1) return 0;
204 end
= lphl
->FirstVisible
+ lphl
->ItemsVisible
- 1;
206 if (lphl
->ItemFocused
< lphl
->FirstVisible
) {
207 lphl
->FirstVisible
= lphl
->ItemFocused
;
210 if (lphl
->ItemFocused
> end
) {
211 WORD maxFirstVisible
= ListMaxFirstVisible(lphl
);
213 lphl
->FirstVisible
= lphl
->ItemFocused
;
215 if (lphl
->FirstVisible
> maxFirstVisible
) {
216 lphl
->FirstVisible
= maxFirstVisible
;
225 LPLISTSTRUCT
ListBoxGetItem(LPHEADLIST lphl
, UINT uIndex
)
230 if (uIndex
>= lphl
->ItemsCount
) return NULL
;
232 lpls
= lphl
->lpFirst
;
233 while (Count
++ < uIndex
) lpls
= lpls
->lpNext
;
238 void ListBoxDrawItem (HWND hwnd
, LPHEADLIST lphl
, HDC hdc
, LPLISTSTRUCT lpls
,
239 RECT
*rect
, WORD itemAction
, WORD itemState
)
241 if (lphl
->OwnerDrawn
) {
242 DRAWITEMSTRUCT
*dis
= USER_HEAP_LIN_ADDR(lphl
->hDrawItemStruct
);
244 dis
->CtlID
= lpls
->mis
.CtlID
;
245 dis
->CtlType
= lpls
->mis
.CtlType
;
246 dis
->itemID
= lpls
->mis
.itemID
;
248 dis
->hwndItem
= hwnd
;
249 dis
->itemData
= lpls
->mis
.itemData
;
250 dis
->itemAction
= itemAction
;
251 dis
->itemState
= itemState
;
253 SendMessage(lphl
->hParent
, WM_DRAWITEM
,
254 0, (LPARAM
)USER_HEAP_SEG_ADDR(lphl
->hDrawItemStruct
));
256 if (itemAction
== ODA_DRAWENTIRE
|| itemAction
== ODA_SELECT
) {
258 DWORD dwOldTextColor
= 0;
260 OldBkMode
= SetBkMode(hdc
, TRANSPARENT
);
262 if (itemState
!= 0) {
263 dwOldTextColor
= SetTextColor(hdc
, 0x00FFFFFFL
);
264 FillRect(hdc
, rect
, GetStockObject(BLACK_BRUSH
));
267 if (lphl
->dwStyle
& LBS_USETABSTOPS
) {
268 TabbedTextOut(hdc
, rect
->left
+ 5, rect
->top
+ 2,
269 (char *)lpls
->itemText
, strlen((char *)lpls
->itemText
),
270 lphl
->iNumStops
, lphl
->TabStops
, 0);
272 TextOut(hdc
, rect
->left
+ 5, rect
->top
+ 2,
273 (char *)lpls
->itemText
, strlen((char *)lpls
->itemText
));
276 if (itemState
!= 0) {
277 SetTextColor(hdc
, dwOldTextColor
);
280 SetBkMode(hdc
, OldBkMode
);
281 } else DrawFocusRect(hdc
, rect
);
288 int ListBoxFindMouse(LPHEADLIST lphl
, int X
, int Y
)
290 LPLISTSTRUCT lpls
= lphl
->lpFirst
;
294 point
.x
= X
; point
.y
= Y
;
295 if (lphl
->ItemsCount
== 0) return LB_ERR
;
297 for(i
= 0; i
< lphl
->FirstVisible
; i
++) {
298 if (lpls
== NULL
) return LB_ERR
;
301 for(j
= 0; j
< lphl
->ItemsVisible
; i
++, j
++) {
302 if (lpls
== NULL
) return LB_ERR
;
303 if (PtInRect(&lpls
->itemRect
,point
)) {
308 dprintf_listbox(stddeb
,"ListBoxFindMouse: not found\n");
313 void ListBoxAskMeasure(LPHEADLIST lphl
, LPLISTSTRUCT lpls
)
315 HANDLE hTemp
= USER_HEAP_ALLOC( sizeof(MEASUREITEMSTRUCT
) );
316 MEASUREITEMSTRUCT
*lpmeasure
= (MEASUREITEMSTRUCT
*) USER_HEAP_LIN_ADDR(hTemp
);
318 if (lpmeasure
== NULL
) {
319 fprintf(stdnimp
,"ListBoxAskMeasure() out of memory !\n");
323 *lpmeasure
= lpls
->mis
;
324 lpmeasure
->itemHeight
= lphl
->StdItemHeight
;
325 SendMessage(lphl
->hParent
, WM_MEASUREITEM
, 0, (LPARAM
)USER_HEAP_SEG_ADDR(hTemp
));
327 if (lphl
->dwStyle
& LBS_OWNERDRAWFIXED
) {
328 lphl
->StdItemHeight
= lpmeasure
->itemHeight
;
329 lphl
->needMeasure
= FALSE
;
332 USER_HEAP_FREE(hTemp
);
335 /* -------------------- strings and item data ---------------------- */
337 LPLISTSTRUCT
ListBoxCreateItem(LPHEADLIST lphl
, int id
)
339 LPLISTSTRUCT lplsnew
= (LPLISTSTRUCT
)malloc(sizeof(LISTSTRUCT
));
341 if (lplsnew
== NULL
) return NULL
;
343 lplsnew
->itemState
= 0;
344 lplsnew
->mis
.CtlType
= lphl
->DrawCtlType
;
345 lplsnew
->mis
.CtlID
= lphl
->CtlID
;
346 lplsnew
->mis
.itemID
= id
;
347 lplsnew
->mis
.itemHeight
= lphl
->StdItemHeight
;
348 lplsnew
->mis
.itemWidth
= 0; /* ignored */
349 lplsnew
->mis
.itemData
= 0;
350 SetRect(&lplsnew
->itemRect
, 0, 0, 0, 0);
356 int ListBoxInsertString(LPHEADLIST lphl
, UINT uIndex
, LPCSTR newstr
)
358 LPLISTSTRUCT
*lppls
, lplsnew
, lpls
;
363 dprintf_listbox(stddeb
,"ListBoxInsertString(%d, %p);\n", uIndex
, newstr
);
365 if (!newstr
) return -1;
367 if (uIndex
== (UINT
)-1)
368 uIndex
= lphl
->ItemsCount
;
370 lppls
= &lphl
->lpFirst
;
371 for(Count
= 0; Count
< uIndex
; Count
++) {
372 if (*lppls
== NULL
) return LB_ERR
;
373 lppls
= (LPLISTSTRUCT
*) &(*lppls
)->lpNext
;
376 lplsnew
= ListBoxCreateItem(lphl
, Count
);
378 if (lplsnew
== NULL
) {
379 fprintf(stdnimp
,"ListBoxInsertString() out of memory !\n");
383 lplsnew
->lpNext
= *lppls
;
388 if (lphl
->HasStrings
) {
389 dprintf_listbox(stddeb
," string: %s\n", newstr
);
390 hStr
= LIST_HEAP_ALLOC(lphl
, LMEM_MOVEABLE
, strlen(newstr
) + 1);
391 str
= (LPSTR
)LIST_HEAP_ADDR(lphl
, hStr
);
392 if (str
== NULL
) return LB_ERRSPACE
;
394 lplsnew
->itemText
= str
;
395 /* I'm not so sure about the next one */
396 lplsnew
->mis
.itemData
= 0;
398 lplsnew
->itemText
= NULL
;
399 lplsnew
->mis
.itemData
= (DWORD
)newstr
;
402 lplsnew
->mis
.itemID
= uIndex
;
403 lplsnew
->hData
= hStr
;
405 /* adjust the itemID field of the following entries */
406 for(lpls
= lplsnew
->lpNext
; lpls
!= NULL
; lpls
= lpls
->lpNext
) {
410 if (lphl
->needMeasure
) {
411 ListBoxAskMeasure(lphl
, lplsnew
);
414 dprintf_listbox(stddeb
,"ListBoxInsertString // count=%d\n", lphl
->ItemsCount
);
419 int ListBoxAddString(LPHEADLIST lphl
, LPCSTR newstr
)
421 UINT pos
= (UINT
) -1;
423 if (lphl
->HasStrings
&& (lphl
->dwStyle
& LBS_SORT
)) {
424 LPLISTSTRUCT lpls
= lphl
->lpFirst
;
425 for (pos
= 0; lpls
!= NULL
; lpls
= lpls
->lpNext
, pos
++)
426 if (strcmp(lpls
->itemText
, newstr
) >= 0)
429 return ListBoxInsertString(lphl
, pos
, newstr
);
433 int ListBoxGetText(LPHEADLIST lphl
, UINT uIndex
, LPSTR OutStr
)
438 dprintf_listbox(stddeb
, "ListBoxGetText // OutStr==NULL\n");
442 lpls
= ListBoxGetItem (lphl
, uIndex
);
443 if (lpls
== NULL
) return LB_ERR
;
445 if (!lphl
->HasStrings
) {
446 *((long *)OutStr
) = lpls
->mis
.itemData
;
450 strcpy(OutStr
, lpls
->itemText
);
451 return strlen(OutStr
);
455 DWORD
ListBoxGetItemData(LPHEADLIST lphl
, UINT uIndex
)
459 lpls
= ListBoxGetItem (lphl
, uIndex
);
460 if (lpls
== NULL
) return LB_ERR
;
461 return lpls
->mis
.itemData
;
465 int ListBoxSetItemData(LPHEADLIST lphl
, UINT uIndex
, DWORD ItemData
)
467 LPLISTSTRUCT lpls
= ListBoxGetItem(lphl
, uIndex
);
469 if (lpls
== NULL
) return LB_ERR
;
470 lpls
->mis
.itemData
= ItemData
;
475 int ListBoxDeleteString(LPHEADLIST lphl
, UINT uIndex
)
477 LPLISTSTRUCT lpls
, lpls2
;
480 if (uIndex
>= lphl
->ItemsCount
) return LB_ERR
;
482 lpls
= lphl
->lpFirst
;
483 if (lpls
== NULL
) return LB_ERR
;
486 lphl
->lpFirst
= lpls
->lpNext
;
488 LPLISTSTRUCT lpls2
= NULL
;
489 for(Count
= 0; Count
< uIndex
; Count
++) {
490 if (lpls
->lpNext
== NULL
) return LB_ERR
;
493 lpls
= (LPLISTSTRUCT
)lpls
->lpNext
;
495 lpls2
->lpNext
= lpls
->lpNext
;
498 /* adjust the itemID field of the following entries */
499 for(lpls2
= lpls
->lpNext
; lpls2
!= NULL
; lpls2
= lpls2
->lpNext
) {
505 if (lpls
->hData
!= 0) LIST_HEAP_FREE(lphl
, lpls
->hData
);
508 return lphl
->ItemsCount
;
512 int ListBoxFindString(LPHEADLIST lphl
, UINT nFirst
, SEGPTR MatchStr
)
516 UINT First
= nFirst
+ 1;
517 LPSTR lpMatchStr
= (LPSTR
)MatchStr
;
519 if (First
> lphl
->ItemsCount
) return LB_ERR
;
521 if (lphl
->HasStrings
) lpMatchStr
= PTR_SEG_TO_LIN(MatchStr
);
523 lpls
= ListBoxGetItem(lphl
, First
);
525 while(lpls
!= NULL
) {
526 if (lphl
->HasStrings
) {
527 if (strstr(lpls
->itemText
, lpMatchStr
) == lpls
->itemText
) return Count
;
528 } else if (lphl
->dwStyle
& LBS_SORT
) {
529 /* XXX Do a compare item */
532 if (lpls
->mis
.itemData
== (DWORD
)lpMatchStr
) return Count
;
538 /* Start over at top */
540 lpls
= lphl
->lpFirst
;
542 while (Count
< First
) {
543 if (lphl
->HasStrings
) {
544 if (strstr(lpls
->itemText
, lpMatchStr
) == lpls
->itemText
) return Count
;
545 } else if (lphl
->dwStyle
& LBS_SORT
) {
546 /* XXX Do a compare item */
548 if (lpls
->mis
.itemData
== (DWORD
)lpMatchStr
) return Count
;
558 int ListBoxResetContent(LPHEADLIST lphl
)
563 if (lphl
->ItemsCount
== 0) return 0;
565 dprintf_listbox(stddeb
, "ListBoxResetContent // ItemCount = %d\n",
568 for(i
= 0; i
< lphl
->ItemsCount
; i
++) {
569 lpls
= lphl
->lpFirst
;
570 if (lpls
== NULL
) return LB_ERR
;
572 lphl
->lpFirst
= lpls
->lpNext
;
573 if (lpls
->hData
!= 0) LIST_HEAP_FREE(lphl
, lpls
->hData
);
576 ListBoxInitialize(lphl
);
581 /* --------------------- selection ------------------------- */
583 int ListBoxSetCurSel(LPHEADLIST lphl
, WORD wIndex
)
587 /* use ListBoxSetSel instead */
588 if (lphl
->dwStyle
& (LBS_MULTIPLESEL
| LBS_EXTENDEDSEL
) ) return 0;
590 /* unselect previous item */
591 if (lphl
->ItemFocused
!= -1) {
592 lphl
->PrevFocused
= lphl
->ItemFocused
;
593 lpls
= ListBoxGetItem(lphl
, lphl
->ItemFocused
);
594 if (lpls
== 0) return LB_ERR
;
598 if (wIndex
!= (UINT
)-1) {
599 lphl
->ItemFocused
= wIndex
;
600 lpls
= ListBoxGetItem(lphl
, wIndex
);
601 if (lpls
== 0) return LB_ERR
;
602 lpls
->itemState
= ODS_SELECTED
| ODS_FOCUS
;
611 int ListBoxSetSel(LPHEADLIST lphl
, WORD wIndex
, WORD state
)
616 if (!(lphl
->dwStyle
& (LBS_MULTIPLESEL
| LBS_EXTENDEDSEL
) ))
619 if (wIndex
== (UINT
)-1) {
620 for (lpls
= lphl
->lpFirst
; lpls
!= NULL
; lpls
= lpls
->lpNext
) {
621 if( lpls
->itemState
& ODS_SELECTED
) n
++;
622 lpls
->itemState
= state
? lpls
->itemState
| ODS_SELECTED
623 : lpls
->itemState
& ~ODS_SELECTED
;
628 if (wIndex
>= lphl
->ItemsCount
) return LB_ERR
;
630 lpls
= ListBoxGetItem(lphl
, wIndex
);
631 lpls
->itemState
= state
? lpls
->itemState
| ODS_SELECTED
632 : lpls
->itemState
& ~ODS_SELECTED
;
638 int ListBoxGetSel(LPHEADLIST lphl
, WORD wIndex
)
640 LPLISTSTRUCT lpls
= ListBoxGetItem(lphl
, wIndex
);
642 if (lpls
== NULL
) return LB_ERR
;
643 return lpls
->itemState
& ODS_SELECTED
;
646 /* ------------------------- dir listing ------------------------ */
648 LONG
ListBoxDirectory(LPHEADLIST lphl
, UINT attrib
, LPCSTR filespec
)
650 char temp
[16], mask
[13];
657 dprintf_listbox(stddeb
, "ListBoxDirectory: '%s' %04x\n", filespec
, attrib
);
658 if (!filespec
) return LB_ERR
;
659 if (!(ptr
= DOSFS_GetUnixFileName( filespec
, FALSE
))) return LB_ERR
;
661 p
= strrchr( path
, '/' );
663 if (!(ptr
= DOSFS_ToDosFCBFormat( p
)))
670 dprintf_listbox(stddeb
, "ListBoxDirectory: path=%s mask=%s\n", path
, mask
);
674 while ((count
= DOSFS_FindNext( path
, mask
, 0, attrib
, skip
, &entry
)) > 0)
677 if (entry
.attr
& FA_DIRECTORY
)
679 if ((attrib
& DDL_DIRECTORY
) && strcmp(entry
.name
, ". "))
681 sprintf(temp
, "[%s]", DOSFS_ToDosDTAFormat( entry
.name
) );
683 if ((ret
= ListBoxAddString(lphl
, temp
)) == LB_ERR
) break;
686 else /* not a directory */
688 if (!(attrib
& DDL_EXCLUSIVE
) ||
689 ((attrib
& (FA_RDONLY
|FA_HIDDEN
|FA_SYSTEM
|FA_ARCHIVE
)) ==
690 (entry
.attr
& (FA_RDONLY
|FA_HIDDEN
|FA_SYSTEM
|FA_ARCHIVE
))))
692 strcpy( temp
, DOSFS_ToDosDTAFormat( entry
.name
) );
694 if ((ret
= ListBoxAddString(lphl
, temp
)) == LB_ERR
) break;
698 if (attrib
& DDL_DRIVES
)
701 strcpy( temp
, "[-a-]" );
702 for (x
= 0; x
< MAX_DOS_DRIVES
; x
++, temp
[2]++)
704 if (DRIVE_IsValid(x
))
705 if ((ret
= ListBoxAddString(lphl
, temp
)) == LB_ERR
) break;
712 /* ------------------------- dimensions ------------------------- */
714 int ListBoxGetItemRect(LPHEADLIST lphl
, WORD wIndex
, LPRECT lprect
)
716 LPLISTSTRUCT lpls
= ListBoxGetItem(lphl
,wIndex
);
718 if (lpls
== NULL
) return LB_ERR
;
719 *lprect
= lpls
->itemRect
;
724 int ListBoxSetItemHeight(LPHEADLIST lphl
, WORD wIndex
, long height
)
728 if (!(lphl
->dwStyle
& LBS_OWNERDRAWVARIABLE
)) {
729 lphl
->StdItemHeight
= (short)height
;
733 lpls
= ListBoxGetItem(lphl
, wIndex
);
734 if (lpls
== NULL
) return LB_ERR
;
736 lpls
->mis
.itemHeight
= height
;
740 /* -------------------------- string search ------------------------ */
742 int ListBoxFindNextMatch(LPHEADLIST lphl
, WORD wChar
)
747 if ((char)wChar
< ' ') return LB_ERR
;
748 if (!lphl
->HasStrings
) return LB_ERR
;
750 lpls
= lphl
->lpFirst
;
752 for (count
= 0; lpls
!= NULL
; lpls
= lpls
->lpNext
, count
++) {
753 if (tolower(*lpls
->itemText
) == tolower((char)wChar
)) break;
755 if (lpls
== NULL
) return LB_ERR
;
757 for(; lpls
!= NULL
; lpls
= lpls
->lpNext
, count
++) {
758 if (*lpls
->itemText
!= (char)wChar
)
760 if ((short) count
> lphl
->ItemFocused
)
766 /***********************************************************************
769 static LONG
LBCreate(HWND hwnd
, WORD wParam
, LONG lParam
)
772 LONG dwStyle
= GetWindowLong(hwnd
,GWL_STYLE
);
775 CreateListBoxStruct(hwnd
, ODT_LISTBOX
, dwStyle
, GetParent(hwnd
));
776 lphl
= ListBoxGetStorageHeader(hwnd
);
777 dprintf_listbox(stddeb
,"ListBox created: lphl = %p dwStyle = %04x:%04x\n",
778 lphl
, HIWORD(dwStyle
), LOWORD(dwStyle
));
780 GetClientRect(hwnd
,&rect
);
781 lphl
->ColumnsWidth
= rect
.right
- rect
.left
;
783 SetScrollRange(hwnd
, SB_VERT
, 0, ListMaxFirstVisible(lphl
), TRUE
);
784 SetScrollRange(hwnd
, SB_HORZ
, 1, 1, TRUE
);
790 /***********************************************************************
793 static LONG
LBDestroy(HWND hwnd
, WORD wParam
, LONG lParam
)
795 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
797 ListBoxResetContent(lphl
);
799 DestroyListBoxStruct(lphl
);
800 dprintf_listbox(stddeb
,"ListBox destroyed: lphl = %p\n",lphl
);
804 /***********************************************************************
807 static LONG
LBVScroll(HWND hwnd
, WORD wParam
, LONG lParam
)
809 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
812 dprintf_listbox(stddeb
,"ListBox WM_VSCROLL w=%04X l=%08lX !\n",
814 y
= lphl
->FirstVisible
;
818 if (lphl
->FirstVisible
> 0)
819 lphl
->FirstVisible
--;
823 lphl
->FirstVisible
++;
827 if (lphl
->FirstVisible
> lphl
->ItemsVisible
) {
828 lphl
->FirstVisible
-= lphl
->ItemsVisible
;
830 lphl
->FirstVisible
= 0;
835 lphl
->FirstVisible
+= lphl
->ItemsVisible
;
839 lphl
->FirstVisible
= LOWORD(lParam
);
843 if (lphl
->FirstVisible
> ListMaxFirstVisible(lphl
))
844 lphl
->FirstVisible
= ListMaxFirstVisible(lphl
);
846 if (y
!= lphl
->FirstVisible
) {
847 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
848 InvalidateRect(hwnd
, NULL
, TRUE
);
853 /***********************************************************************
856 static LONG
LBHScroll(HWND hwnd
, WORD wParam
, LONG lParam
)
861 dprintf_listbox(stddeb
,"ListBox WM_HSCROLL w=%04X l=%08lX !\n",
863 lphl
= ListBoxGetStorageHeader(hwnd
);
864 y
= lphl
->FirstVisible
;
867 if (lphl
->FirstVisible
> lphl
->ItemsPerColumn
) {
868 lphl
->FirstVisible
-= lphl
->ItemsPerColumn
;
870 lphl
->FirstVisible
= 0;
874 lphl
->FirstVisible
+= lphl
->ItemsPerColumn
;
877 if (lphl
->ItemsPerColumn
!= 0) {
878 int lbsub
= lphl
->ItemsVisible
/ lphl
->ItemsPerColumn
* lphl
->ItemsPerColumn
;
879 if (lphl
->FirstVisible
> lbsub
) {
880 lphl
->FirstVisible
-= lbsub
;
882 lphl
->FirstVisible
= 0;
887 if (lphl
->ItemsPerColumn
!= 0)
888 lphl
->FirstVisible
+= lphl
->ItemsVisible
/
889 lphl
->ItemsPerColumn
* lphl
->ItemsPerColumn
;
892 lphl
->FirstVisible
= lphl
->ItemsPerColumn
* LOWORD(lParam
);
895 if (lphl
->FirstVisible
> ListMaxFirstVisible(lphl
))
896 lphl
->FirstVisible
= ListMaxFirstVisible(lphl
);
898 if (lphl
->ItemsPerColumn
!= 0) {
899 lphl
->FirstVisible
= lphl
->FirstVisible
/
900 lphl
->ItemsPerColumn
* lphl
->ItemsPerColumn
+ 1;
901 if (y
!= lphl
->FirstVisible
) {
902 SetScrollPos(hwnd
, SB_HORZ
, lphl
->FirstVisible
/
903 lphl
->ItemsPerColumn
+ 1, TRUE
);
904 InvalidateRect(hwnd
, NULL
, TRUE
);
910 /***********************************************************************
913 static LONG
LBLButtonDown(HWND hwnd
, WORD wParam
, LONG lParam
)
915 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
920 tmpPOINT
.x
= LOWORD(lParam
); tmpPOINT
.y
= HIWORD(lParam
);
925 lphl
->PrevFocused
= lphl
->ItemFocused
;
927 y
= ListBoxFindMouse(lphl
, LOWORD(lParam
), HIWORD(lParam
));
929 if (y
== -1) return 0;
931 if (lphl
->dwStyle
& LBS_NOTIFY
&& y
!= LB_ERR
)
932 if( SendMessage(lphl
->hParent
, WM_LBTRACKPOINT
, y
, lParam
) )
936 switch( lphl
->dwStyle
& (LBS_MULTIPLESEL
| LBS_EXTENDEDSEL
) )
938 case LBS_MULTIPLESEL
:
939 lphl
->ItemFocused
= y
;
940 wRet
= ListBoxGetSel(lphl
, y
);
941 ListBoxSetSel(lphl
, y
, !wRet
);
943 case LBS_EXTENDEDSEL
:
944 /* should handle extended mode here and in kbd handler
947 if ( lphl
->PrevFocused
!= y
&& y
!= LB_ERR
)
949 LPLISTSTRUCT lpls
= ListBoxGetItem( lphl
, lphl
->ItemFocused
= y
);
950 n
= ListBoxSetSel(lphl
,-1,FALSE
);
952 lpls
->itemState
= ODS_FOCUS
| ODS_SELECTED
;
954 if( n
> 1 && n
!= LB_ERR
)
955 InvalidateRect(hwnd
,NULL
,TRUE
);
962 if( y
!=lphl
->ItemFocused
)
963 ListBoxSetCurSel(lphl
, y
);
968 fprintf(stdnimp
,"Listbox: LBS_MULTIPLESEL and LBS_EXTENDEDSEL are on!\n");
972 /* invalidate changed items */
973 if( lphl
->dwStyle
& LBS_MULTIPLESEL
|| y
!=lphl
->PrevFocused
)
975 ListBoxGetItemRect(lphl
, y
, &rectsel
);
976 InvalidateRect(hwnd
, &rectsel
, TRUE
);
978 if( lphl
->PrevFocused
!=-1 && y
!=lphl
->PrevFocused
)
980 ListBoxGetItemRect(lphl
, lphl
->PrevFocused
, &rectsel
);
981 InvalidateRect(hwnd
, &rectsel
, TRUE
);
985 if (GetWindowLong(lphl
->hSelf
,GWL_EXSTYLE
) & WS_EX_DRAGDETECT
)
986 if( DragDetect(lphl
->hSelf
,tmpPOINT
) )
987 SendMessage(lphl
->hParent
, WM_BEGINDRAG
,0,0L);
992 /***********************************************************************
995 static LONG
LBLButtonUp(HWND hwnd
, WORD wParam
, LONG lParam
)
997 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
999 if (GetCapture() == hwnd
) ReleaseCapture();
1001 if (lphl
->PrevFocused
!= lphl
->ItemFocused
)
1002 ListBoxSendNotification(lphl
, LBN_SELCHANGE
);
1007 /***********************************************************************
1010 static LONG
LBRButtonUp(HWND hwnd
, WORD wParam
, LONG lParam
)
1012 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1015 SendMessage(lphl
->hParent
, WM_COMMAND
,
1016 MAKEWPARAM(GetWindowWord(hwnd
,GWW_ID
),LBN_DBLCLK
),
1019 SendMessage(lphl
->hParent
, WM_COMMAND
, GetWindowWord(hwnd
,GWW_ID
),
1020 MAKELONG(hwnd
, LBN_DBLCLK
));
1026 /***********************************************************************
1029 static LONG
LBMouseMove(HWND hwnd
, WORD wParam
, LONG lParam
)
1031 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1032 int y
,redraw_prev
= 0;
1034 RECT rect
, rectsel
; /* XXX Broken */
1036 dprintf_listbox(stddeb
,"LBMouseMove %d %d\n",SLOWORD(lParam
),SHIWORD(lParam
));
1037 if ((wParam
& MK_LBUTTON
) != 0) {
1038 y
= SHIWORD(lParam
);
1040 if (lphl
->FirstVisible
> 0) {
1041 lphl
->FirstVisible
--;
1042 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
1043 InvalidateRect(hwnd
, NULL
, TRUE
);
1047 GetClientRect(hwnd
, &rect
);
1048 if (y
>= rect
.bottom
) {
1049 if (lphl
->FirstVisible
< ListMaxFirstVisible(lphl
)) {
1050 lphl
->FirstVisible
++;
1051 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
1052 InvalidateRect(hwnd
, NULL
, TRUE
);
1056 if ((y
> 0) && (y
< (rect
.bottom
- 4))) {
1057 if ((y
< rectsel
.top
) || (y
> rectsel
.bottom
)) {
1058 iRet
= ListBoxFindMouse(lphl
, LOWORD(lParam
), HIWORD(lParam
));
1059 if (iRet
== lphl
->ItemFocused
|| iRet
== -1) {
1062 if (lphl
->dwStyle
& LBS_MULTIPLESEL
) {
1063 lphl
->ItemFocused
= iRet
;
1064 ListBoxSendNotification(lphl
, LBN_SELCHANGE
);
1065 } else if ( lphl
->dwStyle
& LBS_EXTENDEDSEL
)
1067 /* Fixme: extended selection mode */
1068 ListBoxSetSel( lphl
, lphl
->ItemFocused
, 0);
1069 lphl
->PrevFocused
= lphl
->ItemFocused
;
1070 lphl
->ItemFocused
= iRet
;
1071 ListBoxSetSel( lphl
, iRet
, TRUE
);
1076 ListBoxSetCurSel(lphl
, (WORD
)iRet
);
1079 if( lphl
->PrevFocused
!=-1 && redraw_prev
)
1081 ListBoxGetItemRect(lphl
, lphl
->PrevFocused
, &rectsel
);
1082 InvalidateRect(hwnd
, &rectsel
, TRUE
);
1084 ListBoxGetItemRect(lphl
, iRet
, &rectsel
);
1085 InvalidateRect(hwnd
, &rectsel
, TRUE
);
1093 /***********************************************************************
1096 * Doesn't yet handle properly VK_SHIFT with LB_EXTENDEDSEL
1098 static LONG
LBKeyDown(HWND hwnd
, WORD wParam
, LONG lParam
)
1100 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1101 WORD newFocused
= 0xFFFF;
1104 ListBoxGetItemRect(lphl
,lphl
->ItemFocused
,&rect
);
1115 if ( lphl
->dwStyle
& LBS_WANTKEYBOARDINPUT
)
1117 newFocused
= (WORD
)(INT
)SendMessage(lphl
->hParent
,WM_VKEYTOITEM
,
1118 wParam
,MAKELPARAM(lphl
->ItemFocused
,hwnd
));
1119 if ( newFocused
== 0xFFFE ) return 0L;
1121 if ( newFocused
== 0xFFFF )
1123 newFocused
= lphl
->ItemFocused
;
1132 newFocused
= lphl
->ItemsCount
- 1;
1135 if (lphl
->dwStyle
& LBS_MULTICOLUMN
) {
1136 if (newFocused
>= lphl
->ItemsPerColumn
) {
1137 newFocused
-= lphl
->ItemsPerColumn
;
1144 if (newFocused
> 0) newFocused
--;
1147 if (lphl
->dwStyle
& LBS_MULTICOLUMN
)
1148 newFocused
+= lphl
->ItemsPerColumn
;
1154 if (newFocused
> lphl
->ItemsVisible
)
1155 newFocused
-= lphl
->ItemsVisible
;
1156 else newFocused
= 0;
1159 newFocused
+= lphl
->ItemsVisible
;
1164 /* end of nested switch */
1168 if (lphl
->dwStyle
& LBS_MULTIPLESEL
)
1170 WORD wRet
= ListBoxGetSel(lphl
, lphl
->ItemFocused
);
1171 ListBoxSetSel(lphl
, lphl
->ItemFocused
, !wRet
);
1175 /* chars are handled in LBChar */
1180 /* at this point newFocused is set up */
1182 if (newFocused
>= lphl
->ItemsCount
)
1183 newFocused
= lphl
->ItemsCount
- 1;
1185 if (!(lphl
->dwStyle
& LBS_MULTIPLESEL
))
1187 ListBoxSetCurSel(lphl
, newFocused
);
1188 ListBoxSendNotification(lphl
, LBN_SELCHANGE
);
1191 lphl
->ItemFocused
= newFocused
;
1193 if( ListBoxScrollToFocus(lphl
) || (lphl
->dwStyle
&
1194 (LBS_MULTIPLESEL
| LBS_EXTENDEDSEL
)) )
1195 InvalidateRect(hwnd
, NULL
, TRUE
);
1198 InvalidateRect(hwnd
, &rect
, TRUE
);
1199 if( newFocused
< 0x8000 )
1201 ListBoxGetItemRect(lphl
, newFocused
, &rect
);
1202 InvalidateRect(hwnd
, &rect
, TRUE
);
1206 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
1211 /***********************************************************************
1214 static LONG
LBChar(HWND hwnd
, WORD wParam
, LONG lParam
)
1216 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1217 WORD newFocused
= 0xFFFF;
1219 if ( (lphl
->dwStyle
& LBS_WANTKEYBOARDINPUT
) && !(lphl
->HasStrings
))
1221 newFocused
= (WORD
)(INT
)SendMessage(lphl
->hParent
,WM_CHARTOITEM
,
1222 wParam
,MAKELPARAM(lphl
->ItemFocused
,hwnd
));
1223 if ( newFocused
== 0xFFFE ) return 0L;
1226 if (newFocused
== 0xFFFF )
1227 newFocused
= ListBoxFindNextMatch(lphl
, wParam
);
1229 if (newFocused
== (WORD
)LB_ERR
) return 0;
1231 if (newFocused
>= lphl
->ItemsCount
)
1232 newFocused
= lphl
->ItemsCount
- 1;
1234 if (!(lphl
->dwStyle
& LBS_MULTIPLESEL
))
1236 ListBoxSetCurSel(lphl
, newFocused
);
1237 ListBoxSendNotification(lphl
, LBN_SELCHANGE
);
1240 lphl
->ItemFocused
= newFocused
;
1241 ListBoxScrollToFocus(lphl
);
1242 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
1244 InvalidateRect(hwnd
, NULL
, TRUE
);
1249 /***********************************************************************
1252 static LONG
LBSetRedraw(HWND hwnd
, WORD wParam
, LONG lParam
)
1254 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1256 dprintf_listbox(stddeb
,"ListBox WM_SETREDRAW hWnd="NPFMT
" w=%04X !\n",
1258 lphl
->bRedrawFlag
= wParam
;
1263 /***********************************************************************
1266 static LONG
LBSetFont(HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1268 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1272 lphl
->hFont
= GetStockObject(SYSTEM_FONT
);
1274 lphl
->hFont
= (HFONT
) wParam
;
1276 /* a new font means possible new text height */
1277 /* does this mean the height of each entry must be separately changed? */
1278 /* or are we guaranteed to get a LBSetFont before the first insert/add? */
1279 if ((hdc
= GetDC(0)))
1282 GetTextMetrics( hdc
, &tm
);
1283 lphl
->StdItemHeight
= tm
.tmHeight
;
1284 dprintf_listbox(stddeb
,"LBSetFont: new font %d with height %d",
1285 lphl
->hFont
, lphl
->StdItemHeight
);
1286 ReleaseDC( 0, hdc
);
1292 /***********************************************************************
1295 static LONG
LBPaint(HWND hwnd
, WORD wParam
, LONG lParam
)
1297 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1302 HDC hdc
= BeginPaint( hwnd
, &ps
);
1303 DC
*dc
= (DC
*)GDI_GetObjPtr(hdc
, DC_MAGIC
);
1304 RECT rect
, paintRect
, scratchRect
;
1305 int i
, top
, height
, maxwidth
, ipc
;
1310 if (!IsWindowVisible(hwnd
) || !lphl
->bRedrawFlag
) {
1311 EndPaint(hwnd
, &ps
);
1315 GetRgnBox(dc
->w
.hGCClipRgn
,&paintRect
);
1316 GetClientRect(hwnd
, &rect
);
1317 IntersectRect(&paintRect
,&rect
,&paintRect
);
1319 hOldFont
= SelectObject(hdc
, lphl
->hFont
);
1322 hBrush
= (HBRUSH
) SendMessage(lphl
->hParent
, WM_CTLCOLORLISTBOX
, (WPARAM
)hdc
,
1325 hBrush
= SendMessage(lphl
->hParent
, WM_CTLCOLOR
, hdc
,
1326 MAKELONG(hwnd
, CTLCOLOR_LISTBOX
));
1329 if (hBrush
== 0) hBrush
= GetStockObject(WHITE_BRUSH
);
1331 FillRect(hdc
, &rect
, hBrush
);
1333 maxwidth
= rect
.right
;
1334 if (lphl
->dwStyle
& LBS_MULTICOLUMN
) {
1335 rect
.right
= lphl
->ColumnsWidth
;
1337 lpls
= lphl
->lpFirst
;
1339 lphl
->ItemsVisible
= 0;
1340 lphl
->ItemsPerColumn
= ipc
= 0;
1342 for(i
= 0; i
< lphl
->ItemsCount
; i
++) {
1343 if (lpls
== NULL
) break;
1345 if (i
>= lphl
->FirstVisible
) {
1346 height
= lpls
->mis
.itemHeight
;
1348 if (top
> rect
.bottom
) {
1349 if (lphl
->dwStyle
& LBS_MULTICOLUMN
) {
1350 lphl
->ItemsPerColumn
= MAX(lphl
->ItemsPerColumn
, ipc
);
1353 rect
.left
+= lphl
->ColumnsWidth
;
1354 rect
.right
+= lphl
->ColumnsWidth
;
1355 if (rect
.left
> maxwidth
) break;
1361 lpls
->itemRect
.top
= top
;
1362 lpls
->itemRect
.bottom
= top
+ height
;
1363 lpls
->itemRect
.left
= rect
.left
;
1364 lpls
->itemRect
.right
= rect
.right
;
1366 if( IntersectRect(&scratchRect
,&paintRect
,&lpls
->itemRect
) )
1368 dprintf_listbox(stddeb
,"LBPaint: drawing item: %ld %d %ld %d %d\n",(LONG
)rect
.left
,top
,
1369 (LONG
)rect
.right
,top
+height
,lpls
->itemState
);
1371 if (lphl
->OwnerDrawn
&& (lphl
->ItemFocused
== i
) && GetFocus() == hwnd
)
1373 ListBoxDrawItem (hwnd
, lphl
, hdc
, lpls
, &lpls
->itemRect
, ODA_FOCUS
,
1374 lpls
->itemState
& ~ODS_FOCUS
);
1375 ListBoxDrawItem (hwnd
, lphl
, hdc
, lpls
, &lpls
->itemRect
, ODA_DRAWENTIRE
,
1376 lpls
->itemState
& ~ODS_FOCUS
);
1377 ListBoxDrawItem (hwnd
, lphl
, hdc
, lpls
, &lpls
->itemRect
, ODA_FOCUS
, lpls
->itemState
);
1380 ListBoxDrawItem (hwnd
, lphl
, hdc
, lpls
, &lpls
->itemRect
, ODA_DRAWENTIRE
,
1385 lphl
->ItemsVisible
++;
1389 lpls
= lpls
->lpNext
;
1391 ListBoxUpdateWindow(hwnd
,lphl
,FALSE
);
1392 SelectObject(hdc
,hOldFont
);
1393 EndPaint( hwnd
, &ps
);
1397 /***********************************************************************
1400 static LONG
LBSetFocus(HWND hwnd
, WORD wParam
, LONG lParam
)
1402 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1404 dprintf_listbox(stddeb
,"ListBox WM_SETFOCUS for "NPFMT
"\n",hwnd
);
1405 if(!(lphl
->dwStyle
& LBS_MULTIPLESEL
) )
1406 if( lphl
->ItemsCount
&& lphl
->ItemFocused
!= -1)
1408 HDC hDC
= GetDC(hwnd
);
1409 HFONT hOldFont
= SelectObject(hDC
, lphl
->hFont
);
1412 lpls
= ListBoxGetItem(lphl
,lphl
->ItemFocused
);
1413 lpls
->itemState
|= ODS_FOCUS
;
1415 ListBoxDrawItem(hwnd
,lphl
,hDC
,lpls
,&lpls
->itemRect
, ODA_FOCUS
, lpls
->itemState
);
1416 SelectObject(hDC
, hOldFont
);
1417 ReleaseDC(hwnd
,hDC
);
1420 ListBoxSendNotification(lphl
, LBN_SETFOCUS
);
1425 /***********************************************************************
1428 static LONG
LBKillFocus(HWND hwnd
, WORD wParam
, LONG lParam
)
1430 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1432 dprintf_listbox(stddeb
,"ListBox WM_KILLFOCUS for "NPFMT
"\n",hwnd
);
1433 if (!(lphl
->dwStyle
& LBS_MULTIPLESEL
))
1435 if( lphl
->ItemsCount
)
1436 if( lphl
->ItemFocused
!= -1 )
1438 HDC hDC
= GetDC(hwnd
);
1439 HFONT hOldFont
= SelectObject(hDC
, lphl
->hFont
);
1442 lpls
= ListBoxGetItem(lphl
,lphl
->ItemFocused
);
1443 lpls
->itemState
&= ~ODS_FOCUS
;
1445 ListBoxDrawItem(hwnd
,lphl
,hDC
,lpls
,&lpls
->itemRect
, ODA_FOCUS
, lpls
->itemState
);
1446 SelectObject(hDC
, hOldFont
);
1447 ReleaseDC(hwnd
,hDC
);
1450 dprintf_listbox(stddeb
,"LBKillFocus: no focused item!\n");
1453 InvalidateRect(hwnd
, NULL
, TRUE
);
1455 ListBoxSendNotification(lphl
, LBN_KILLFOCUS
);
1460 /***********************************************************************
1463 static LONG
LBResetContent(HWND hwnd
, WORD wParam
, LONG lParam
)
1465 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1467 dprintf_listbox(stddeb
,"ListBox LB_RESETCONTENT !\n");
1468 ListBoxResetContent(lphl
);
1469 ListBoxUpdateWindow(hwnd
, lphl
, TRUE
);
1473 /***********************************************************************
1476 static LONG
LBDir(HWND hwnd
, WORD wParam
, LONG lParam
)
1479 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1480 dprintf_listbox(stddeb
,"ListBox LB_DIR !\n");
1482 ret
= ListBoxDirectory(lphl
, wParam
, (LPSTR
)PTR_SEG_TO_LIN(lParam
));
1483 ListBoxUpdateWindow(hwnd
, lphl
, TRUE
);
1487 /***********************************************************************
1490 static LONG
LBAddString(HWND hwnd
, WORD wParam
, LONG lParam
)
1493 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1495 if (lphl
->HasStrings
)
1496 wRet
= ListBoxAddString(lphl
, (LPCSTR
)PTR_SEG_TO_LIN(lParam
));
1498 wRet
= ListBoxAddString(lphl
, (LPCSTR
)lParam
);
1500 ListBoxUpdateWindow(hwnd
,lphl
,TRUE
);
1504 /***********************************************************************
1507 static LONG
LBGetText(HWND hwnd
, WORD wParam
, LONG lParam
)
1510 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1512 dprintf_listbox(stddeb
, "LB_GETTEXT wParam=%d\n",wParam
);
1513 wRet
= ListBoxGetText(lphl
, wParam
, (LPSTR
)PTR_SEG_TO_LIN(lParam
));
1518 /***********************************************************************
1521 static LONG
LBInsertString(HWND hwnd
, WORD wParam
, LONG lParam
)
1524 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1526 if (lphl
->HasStrings
)
1527 wRet
= ListBoxInsertString(lphl
, wParam
, (LPCSTR
)PTR_SEG_TO_LIN(lParam
));
1529 wRet
= ListBoxInsertString(lphl
, wParam
, (LPCSTR
)lParam
);
1531 ListBoxUpdateWindow(hwnd
,lphl
,TRUE
);
1535 /***********************************************************************
1538 static LONG
LBDeleteString(HWND hwnd
, WORD wParam
, LONG lParam
)
1540 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1541 LONG lRet
= ListBoxDeleteString(lphl
,wParam
);
1543 ListBoxUpdateWindow(hwnd
,lphl
,TRUE
);
1547 /***********************************************************************
1550 static LONG
LBFindString(HWND hwnd
, WORD wParam
, LONG lParam
)
1552 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1553 return ListBoxFindString(lphl
, wParam
, (SEGPTR
)lParam
);
1556 /***********************************************************************
1559 static LONG
LBGetCaretIndex(HWND hwnd
, WORD wParam
, LONG lParam
)
1561 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1562 return lphl
->ItemFocused
;
1565 /***********************************************************************
1568 static LONG
LBGetCount(HWND hwnd
, WORD wParam
, LONG lParam
)
1572 lphl
= ListBoxGetStorageHeader(hwnd
);
1573 return lphl
->ItemsCount
;
1576 /***********************************************************************
1579 static LONG
LBGetCurSel(HWND hwnd
, WORD wParam
, LONG lParam
)
1583 lphl
= ListBoxGetStorageHeader(hwnd
);
1584 dprintf_listbox(stddeb
,"ListBox LB_GETCURSEL %i !\n",
1586 return lphl
->ItemFocused
;
1589 /***********************************************************************
1590 * LBGetHorizontalExtent
1592 static LONG
LBGetHorizontalExtent(HWND hwnd
, WORD wParam
, LONG lParam
)
1597 /***********************************************************************
1600 static LONG
LBGetItemHeight(HWND hwnd
, WORD wParam
, LONG lParam
)
1602 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1603 LPLISTSTRUCT lpls
= ListBoxGetItem (lphl
, wParam
);
1605 if (lpls
== NULL
) return LB_ERR
;
1606 return lpls
->mis
.itemHeight
;
1609 /***********************************************************************
1612 static LONG
LBGetItemRect(HWND hwnd
, WORD wParam
, LONG lParam
)
1614 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1615 return ListBoxGetItemRect(lphl
, wParam
, PTR_SEG_TO_LIN(lParam
));
1618 /***********************************************************************
1621 static LONG
LBGetSel(HWND hwnd
, WORD wParam
, LONG lParam
)
1623 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1624 int iSel
= ListBoxGetSel(lphl
, wParam
);
1626 dprintf_listbox(stdnimp
,"LBGetSel: item %u - %i\n",wParam
,iSel
);
1628 return (iSel
)? 1 : 0;
1631 /***********************************************************************
1634 static LONG
LBGetSelCount(HWND hwnd
, WORD wParam
, LONG lParam
)
1636 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1641 if (!(lphl
->dwStyle
& (LBS_MULTIPLESEL
| LBS_EXTENDEDSEL
) ))
1644 for( lpls
= lphl
->lpFirst
;
1646 lpls
= lpls
->lpNext
)
1649 if (lpls
->itemState
)
1656 /***********************************************************************
1659 static LONG
LBGetSelItems(HWND hwnd
, WORD wParam
, LONG lParam
)
1661 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1664 int *lpItems
= PTR_SEG_TO_LIN(lParam
);
1666 if (!(lphl
->dwStyle
& (LBS_MULTIPLESEL
| LBS_EXTENDEDSEL
) ))
1669 if (wParam
== 0) return 0;
1671 lpls
= lphl
->lpFirst
;
1674 while (lpls
!= NULL
) {
1675 if (lpls
->itemState
> 0) lpItems
[cnt
++] = idx
;
1677 if (cnt
== wParam
) break;
1679 lpls
= lpls
->lpNext
;
1685 /***********************************************************************
1688 static LONG
LBGetTextLen(HWND hwnd
, WORD wParam
, LONG lParam
)
1690 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1691 LPLISTSTRUCT lpls
= ListBoxGetItem(lphl
,wParam
);
1693 if (lpls
== NULL
|| !lphl
->HasStrings
) return LB_ERR
;
1694 return strlen(lpls
->itemText
);
1697 /***********************************************************************
1700 static LONG
LBGetDlgCode(HWND hwnd
, WORD wParam
, LONG lParam
)
1702 return DLGC_WANTARROWS
| DLGC_WANTCHARS
;
1705 /***********************************************************************
1708 static LONG
LBGetTopIndex(HWND hwnd
, WORD wParam
, LONG lParam
)
1710 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1712 return lphl
->FirstVisible
;
1716 /***********************************************************************
1719 static LONG
LBSelectString(HWND hwnd
, WORD wParam
, LONG lParam
)
1721 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1724 iRet
= ListBoxFindString(lphl
, wParam
, (SEGPTR
)lParam
);
1728 if( lphl
->dwStyle
& (LBS_MULTIPLESEL
| LBS_EXTENDEDSEL
) )
1729 ListBoxSetSel(lphl
,iRet
,TRUE
);
1731 ListBoxSetCurSel(lphl
,iRet
);
1733 lphl
->ItemFocused
= iRet
;
1734 InvalidateRect(hwnd
,0,TRUE
);
1739 /***********************************************************************
1742 static LONG
LBSelItemRange(HWND hwnd
, WORD wParam
, LONG lParam
)
1744 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1747 WORD first
= LOWORD(lParam
);
1748 WORD last
= HIWORD(lParam
);
1749 BOOL select
= wParam
;
1751 if (!(lphl
->dwStyle
& (LBS_MULTIPLESEL
| LBS_EXTENDEDSEL
) ))
1754 if (first
>= lphl
->ItemsCount
||
1755 last
>= lphl
->ItemsCount
) return LB_ERR
;
1757 lpls
= lphl
->lpFirst
;
1760 while (lpls
!= NULL
) {
1762 lpls
->itemState
= select
? lpls
->itemState
| ODS_SELECTED
: 0;
1767 lpls
= lpls
->lpNext
;
1773 /***********************************************************************
1776 static LONG
LBSetCaretIndex(HWND hwnd
, WORD wParam
, LONG lParam
)
1778 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1781 if (!(lphl
->dwStyle
& (LBS_MULTIPLESEL
| LBS_EXTENDEDSEL
) )) return 0;
1783 dprintf_listbox(stddeb
,"LBSetCaretIndex: hwnd "NPFMT
" n=%i\n",hwnd
,wParam
);
1785 if (wParam
>= lphl
->ItemsCount
) return LB_ERR
;
1787 lphl
->ItemFocused
= wParam
;
1788 i
= ListBoxScrollToFocus (lphl
);
1790 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
1792 InvalidateRect(hwnd
, NULL
, TRUE
);
1797 /***********************************************************************
1800 static LONG
LBSetColumnWidth(HWND hwnd
, WORD wParam
, LONG lParam
)
1802 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1803 lphl
->ColumnsWidth
= wParam
;
1804 InvalidateRect(hwnd
,NULL
,TRUE
);
1808 /***********************************************************************
1809 * LBSetHorizontalExtent
1811 static LONG
LBSetHorizontalExtent(HWND hwnd
, WORD wParam
, LONG lParam
)
1816 /***********************************************************************
1819 static LONG
LBGetItemData(HWND hwnd
, WORD wParam
, LONG lParam
)
1821 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1822 dprintf_listbox(stddeb
, "LB_GETITEMDATA wParam=%x\n", wParam
);
1823 return ListBoxGetItemData(lphl
, wParam
);
1826 /***********************************************************************
1829 static LONG
LBSetItemData(HWND hwnd
, WORD wParam
, LONG lParam
)
1831 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1832 dprintf_listbox(stddeb
, "LB_SETITEMDATA wParam=%x lParam=%lx\n", wParam
, lParam
);
1833 return ListBoxSetItemData(lphl
, wParam
, lParam
);
1836 /***********************************************************************
1839 static LONG
LBSetTabStops(HWND hwnd
, WORD wParam
, LONG lParam
)
1843 lphl
= ListBoxGetStorageHeader(hwnd
);
1845 if (lphl
->TabStops
!= NULL
) {
1846 lphl
->iNumStops
= 0;
1847 free (lphl
->TabStops
);
1850 lphl
->TabStops
= malloc (wParam
* sizeof (short));
1851 if (lphl
->TabStops
) {
1852 lphl
->iNumStops
= wParam
;
1853 memcpy (lphl
->TabStops
, PTR_SEG_TO_LIN(lParam
), wParam
* sizeof (short));
1860 /***********************************************************************
1863 static LONG
LBSetCurSel(HWND hwnd
, WORD wParam
, LONG lParam
)
1865 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1868 dprintf_listbox(stddeb
,"ListBox LB_SETCURSEL wParam=%x !\n",
1871 wRet
= ListBoxSetCurSel(lphl
, wParam
);
1873 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
1874 InvalidateRect(hwnd
, NULL
, TRUE
);
1879 /***********************************************************************
1882 static LONG
LBSetSel(HWND hwnd
, WORD wParam
, LONG lParam
)
1884 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1888 dprintf_listbox(stddeb
,"ListBox LB_SETSEL wParam=%x lParam=%lX !\n", wParam
, lParam
);
1890 iRet
= ListBoxSetSel(lphl
, LOWORD(lParam
), wParam
);
1893 InvalidateRect(hwnd
, NULL
, TRUE
);
1894 else if( iRet
!= LB_ERR
)
1896 if( lphl
->dwStyle
& LBS_EXTENDEDSEL
&&
1897 lphl
->ItemFocused
!= LOWORD(lParam
) )
1899 ListBoxGetItemRect(lphl
, lphl
->ItemFocused
, &rect
);
1900 InvalidateRect(hwnd
,&rect
,TRUE
);
1901 lphl
->ItemFocused
= LOWORD(lParam
);
1903 ListBoxGetItemRect(lphl
,LOWORD(lParam
),&rect
);
1904 InvalidateRect(hwnd
,&rect
,TRUE
);
1907 return (iRet
== (WORD
)LB_ERR
)? LB_ERR
: 0;
1910 /***********************************************************************
1913 static LONG
LBSetTopIndex(HWND hwnd
, WORD wParam
, LONG lParam
)
1915 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1917 dprintf_listbox(stddeb
,"ListBox LB_SETTOPINDEX wParam=%x !\n",
1919 lphl
->FirstVisible
= wParam
;
1920 SetScrollPos(hwnd
, SB_VERT
, lphl
->FirstVisible
, TRUE
);
1922 InvalidateRect(hwnd
, NULL
, TRUE
);
1927 /***********************************************************************
1930 static LONG
LBSetItemHeight(HWND hwnd
, WORD wParam
, LONG lParam
)
1932 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
1935 dprintf_listbox(stddeb
,"ListBox LB_SETITEMHEIGHT wParam=%x lParam=%lX !\n", wParam
, lParam
);
1936 wRet
= ListBoxSetItemHeight(lphl
, wParam
, lParam
);
1937 InvalidateRect(hwnd
,NULL
,TRUE
);
1941 /***********************************************************************
1944 static LRESULT
LBPassToParent(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1946 WND
* ptrWnd
= WIN_FindWndPtr(hwnd
);
1949 if( /* !(ptrWnd->dwExStyle & WS_EX_NOPARENTNOTIFY) && */
1950 ptrWnd
->hwndParent
)
1951 return SendMessage(ptrWnd
->hwndParent
,message
,wParam
,lParam
);
1955 /***********************************************************************
1958 LRESULT
ListBoxWndProc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1961 case WM_CREATE
: return LBCreate(hwnd
, wParam
, lParam
);
1962 case WM_DESTROY
: return LBDestroy(hwnd
, wParam
, lParam
);
1963 case WM_GETDLGCODE
: return LBGetDlgCode(hwnd
, wParam
, lParam
);
1964 case WM_VSCROLL
: return LBVScroll(hwnd
, wParam
, lParam
);
1965 case WM_HSCROLL
: return LBHScroll(hwnd
, wParam
, lParam
);
1966 case WM_LBUTTONDOWN
: return LBLButtonDown(hwnd
, wParam
, lParam
);
1967 case WM_LBUTTONUP
: return LBLButtonUp(hwnd
, wParam
, lParam
);
1968 case WM_RBUTTONUP
: return LBRButtonUp(hwnd
, wParam
, lParam
);
1969 case WM_LBUTTONDBLCLK
: return LBRButtonUp(hwnd
, wParam
, lParam
);
1970 case WM_MOUSEMOVE
: return LBMouseMove(hwnd
, wParam
, lParam
);
1971 case WM_KEYDOWN
: return LBKeyDown(hwnd
, wParam
, lParam
);
1972 case WM_CHAR
: return LBChar(hwnd
, wParam
, lParam
);
1973 case WM_SETFONT
: return LBSetFont(hwnd
, wParam
, lParam
);
1974 case WM_SETREDRAW
: return LBSetRedraw(hwnd
, wParam
, lParam
);
1975 case WM_PAINT
: return LBPaint(hwnd
, wParam
, lParam
);
1976 case WM_SETFOCUS
: return LBSetFocus(hwnd
, wParam
, lParam
);
1977 case WM_KILLFOCUS
: return LBKillFocus(hwnd
, wParam
, lParam
);
1978 case LB_RESETCONTENT
: return LBResetContent(hwnd
, wParam
, lParam
);
1979 case LB_DIR
: return LBDir(hwnd
, wParam
, lParam
);
1980 case LB_ADDSTRING
: return LBAddString(hwnd
, wParam
, lParam
);
1981 case LB_INSERTSTRING
: return LBInsertString(hwnd
, wParam
, lParam
);
1982 case LB_DELETESTRING
: return LBDeleteString(hwnd
, wParam
, lParam
);
1983 case LB_FINDSTRING
: return LBFindString(hwnd
, wParam
, lParam
);
1984 case LB_GETCARETINDEX
: return LBGetCaretIndex(hwnd
, wParam
, lParam
);
1985 case LB_GETCOUNT
: return LBGetCount(hwnd
, wParam
, lParam
);
1986 case LB_GETCURSEL
: return LBGetCurSel(hwnd
, wParam
, lParam
);
1987 case LB_GETHORIZONTALEXTENT
: return LBGetHorizontalExtent(hwnd
, wParam
, lParam
);
1988 case LB_GETITEMDATA
: return LBGetItemData(hwnd
, wParam
, lParam
);
1989 case LB_GETITEMHEIGHT
: return LBGetItemHeight(hwnd
, wParam
, lParam
);
1990 case LB_GETITEMRECT
: return LBGetItemRect(hwnd
, wParam
, lParam
);
1991 case LB_GETSEL
: return LBGetSel(hwnd
, wParam
, lParam
);
1992 case LB_GETSELCOUNT
: return LBGetSelCount(hwnd
, wParam
, lParam
);
1993 case LB_GETSELITEMS
: return LBGetSelItems(hwnd
, wParam
, lParam
);
1994 case LB_GETTEXT
: return LBGetText(hwnd
, wParam
, lParam
);
1995 case LB_GETTEXTLEN
: return LBGetTextLen(hwnd
, wParam
, lParam
);
1996 case LB_GETTOPINDEX
: return LBGetTopIndex(hwnd
, wParam
, lParam
);
1997 case LB_SELECTSTRING
: return LBSelectString(hwnd
, wParam
, lParam
);
1998 case LB_SELITEMRANGE
: return LBSelItemRange(hwnd
, wParam
, lParam
);
1999 case LB_SETCARETINDEX
: return LBSetCaretIndex(hwnd
, wParam
, lParam
);
2000 case LB_SETCOLUMNWIDTH
: return LBSetColumnWidth(hwnd
, wParam
, lParam
);
2001 case LB_SETHORIZONTALEXTENT
: return LBSetHorizontalExtent(hwnd
, wParam
, lParam
);
2002 case LB_SETITEMDATA
: return LBSetItemData(hwnd
, wParam
, lParam
);
2003 case LB_SETTABSTOPS
: return LBSetTabStops(hwnd
, wParam
, lParam
);
2004 case LB_SETCURSEL
: return LBSetCurSel(hwnd
, wParam
, lParam
);
2005 case LB_SETSEL
: return LBSetSel(hwnd
, wParam
, lParam
);
2006 case LB_SETTOPINDEX
: return LBSetTopIndex(hwnd
, wParam
, lParam
);
2007 case LB_SETITEMHEIGHT
: return LBSetItemHeight(hwnd
, wParam
, lParam
);
2009 case WM_DROPFILES
: return LBPassToParent(hwnd
, message
, wParam
, lParam
);
2011 /* these will have to be implemented for proper LBS_EXTENDEDSEL -
2013 * anchor item is an item that with caret (focused) item defines a
2014 * range of currently selected items when listbox is in the extended
2017 case LB_SETANCHORINDEX
: return LB_SETANCHORINDEX
; /* that's what Windows returns */
2018 case LB_GETANCHORINDEX
: return 0;
2021 case WM_QUERYDROPOBJECT
:
2025 LPDRAGINFO lpDragInfo
= (LPDRAGINFO
) PTR_SEG_TO_LIN((SEGPTR
)lParam
);
2026 LPHEADLIST lphl
= ListBoxGetStorageHeader(hwnd
);
2028 lpDragInfo
->l
= ListBoxFindMouse(lphl
,lpDragInfo
->pt
.x
,
2031 return LBPassToParent(hwnd
, message
, wParam
, lParam
);
2035 return DefWindowProc(hwnd
, message
, wParam
, lParam
);
2039 /**********************************************************************
2040 * DlgDirSelect (USER.99)
2042 BOOL
DlgDirSelect( HWND hDlg
, LPSTR lpStr
, INT id
)
2047 dprintf_listbox( stddeb
, "DlgDirSelect: "NPFMT
" '%s' %d\n",
2049 if ((i
= SendDlgItemMessage( hDlg
, id
, LB_GETCURSEL
, 0, 0 )) == LB_ERR
)
2051 SendDlgItemMessage( hDlg
, id
, LB_GETTEXT
, i
, MAKE_SEGPTR(buffer
) );
2052 if (buffer
[0] == '[') /* drive or directory */
2054 if (buffer
[1] == '-') /* drive */
2056 lpStr
[0] = buffer
[2];
2059 dprintf_listbox( stddeb
, "Returning drive '%s'\n", lpStr
);
2062 strcpy( lpStr
, buffer
+ 1 );
2063 lpStr
[strlen(lpStr
)-1] = '\\';
2064 dprintf_listbox( stddeb
, "Returning directory '%s'\n", lpStr
);
2067 strcpy( lpStr
, buffer
);
2068 dprintf_listbox( stddeb
, "Returning file '%s'\n", lpStr
);
2073 /**********************************************************************
2074 * DlgDirList (USER.100)
2076 INT
DlgDirList( HWND hDlg
, SEGPTR spec
, INT idLBox
, INT idStatic
, UINT attrib
)
2078 char *filespec
= (char *)PTR_SEG_TO_LIN( spec
);
2082 #define SENDMSG(msg,wparam,lparam) \
2083 ((attrib & DDL_POSTMSGS) ? PostMessage( hwnd, msg, wparam, lparam ) \
2084 : SendMessage( hwnd, msg, wparam, lparam ))
2086 dprintf_listbox( stddeb
, "DlgDirList: "NPFMT
" '%s' %d %d %04x\n",
2087 hDlg
, filespec
? filespec
: "NULL",
2088 idLBox
, idStatic
, attrib
);
2090 if (filespec
&& filespec
[0] && (filespec
[1] == ':'))
2092 drive
= toupper( filespec
[0] ) - 'A';
2094 if (!DRIVE_SetCurrentDrive( drive
)) return FALSE
;
2096 else drive
= DRIVE_GetCurrentDrive();
2098 if (idLBox
&& ((hwnd
= GetDlgItem( hDlg
, idLBox
)) != 0))
2101 char temp
[] = "*.*";
2103 if (!filespec
[0]) strcpy( mask
, "*.*" );
2106 /* If the path exists and is a directory, chdir to it */
2107 if (DRIVE_Chdir( drive
, filespec
)) strcpy( mask
, "*.*" );
2112 if ((p2
= strrchr( p
, '\\' ))) p
= p2
+ 1;
2113 if ((p2
= strrchr( p
, '/' ))) p
= p2
+ 1;
2114 lstrcpyn( mask
, p
, sizeof(mask
) );
2118 if (!DRIVE_Chdir( drive
, filespec
)) return FALSE
;
2123 strcpy( (char *)PTR_SEG_TO_LIN(spec
), mask
);
2125 dprintf_listbox(stddeb
, "ListBoxDirectory: path=%c:\\%s mask=%s\n",
2126 'A' + drive
, DRIVE_GetDosCwd(drive
), mask
);
2128 SENDMSG( LB_RESETCONTENT
, 0, 0 );
2129 if ((attrib
& DDL_DIRECTORY
) && !(attrib
& DDL_EXCLUSIVE
))
2131 if (SENDMSG( LB_DIR
, attrib
& ~(DDL_DIRECTORY
| DDL_DRIVES
),
2132 (LPARAM
)spec
) == LB_ERR
) return FALSE
;
2133 if (SENDMSG( LB_DIR
, (attrib
& (DDL_DIRECTORY
| DDL_DRIVES
)) | DDL_EXCLUSIVE
,
2134 (LPARAM
)MAKE_SEGPTR(temp
) ) == LB_ERR
) return FALSE
;
2138 if (SENDMSG( LB_DIR
, attrib
, (LPARAM
)spec
) == LB_ERR
) return FALSE
;
2142 if (idStatic
&& ((hwnd
= GetDlgItem( hDlg
, idStatic
)) != 0))
2145 strcpy( temp
, "A:\\" );
2147 lstrcpyn( temp
+3, DRIVE_GetDosCwd(drive
), 253 );
2149 SENDMSG( WM_SETTEXT
, 0, (LPARAM
)MAKE_SEGPTR(temp
) );