/* * Listbox controls * * Copyright Martin Ayotte, 1993 * Copyright Constantine Sapuntzakis, 1995 * */ /* * TODO: * - check if multi-column listboxes work * - implement more messages and styles */ #include #include #include #include #include "windows.h" #include "user.h" #include "win.h" #include "msdos.h" #include "listbox.h" #include "dos_fs.h" #include "stddebug.h" #include "debug.h" #if 0 #define LIST_HEAP_ALLOC(lphl,f,size) ((int)HEAP_Alloc(&lphl->Heap,f,size) & 0xffff) #define LIST_HEAP_FREE(lphl,handle) (HEAP_Free(&lphl->Heap,LIST_HEAP_ADDR(lphl,handle))) #define LIST_HEAP_ADDR(lphl,handle) \ ((void *)((handle) ? ((handle) | ((int)lphl->Heap & 0xffff0000)) : 0)) #else /* FIXME: shouldn't each listbox have its own heap? */ #define LIST_HEAP_ALLOC(lphl,f,size) USER_HEAP_ALLOC(size) #define LIST_HEAP_FREE(lphl,handle) USER_HEAP_FREE(handle) #define LIST_HEAP_ADDR(lphl,handle) USER_HEAP_LIN_ADDR(handle) #define LIST_HEAP_SEG_ADDR(lphl,handle) USER_HEAP_SEG_ADDR(handle) #endif #define LIST_HEAP_SIZE 0x10000 static void ListBoxInitialize(LPHEADLIST lphl) { lphl->lpFirst = NULL; lphl->ItemsCount = 0; lphl->ItemsVisible = 0; lphl->FirstVisible = 0; lphl->ColumnsVisible = 1; lphl->ItemsPerColumn = 0; lphl->ItemFocused = -1; lphl->PrevFocused = -1; } void CreateListBoxStruct(HWND hwnd, WORD CtlType, LONG styles, HWND parent) { LPHEADLIST lphl; lphl = (LPHEADLIST)malloc(sizeof(HEADLIST)); SetWindowLong(hwnd, 0, (LONG)lphl); if (lphl == NULL) { fprintf(stderr,"malloc failed in CreateListBoxStruct()\n"); exit(1); /* Things won't get better */ } ListBoxInitialize(lphl); lphl->DrawCtlType = CtlType; lphl->CtlID = GetWindowWord(hwnd,GWW_ID); lphl->bRedrawFlag = TRUE; lphl->iNumStops = 0; lphl->TabStops = NULL; lphl->hFont = GetStockObject(SYSTEM_FONT); lphl->hParent = parent; lphl->StdItemHeight = 15; /* FIXME: should get the font height */ lphl->dwStyle = styles; lphl->OwnerDrawn = styles & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE); lphl->HasStrings = (styles & LBS_HASSTRINGS) || !lphl->OwnerDrawn; if (lphl->OwnerDrawn) { LISTSTRUCT dummyls; lphl->hDrawItemStruct = USER_HEAP_ALLOC(sizeof(DRAWITEMSTRUCT)); lphl->needMeasure = TRUE; dummyls.mis.CtlType = lphl->DrawCtlType; dummyls.mis.CtlID = lphl->CtlID; dummyls.mis.itemID = -1; dummyls.mis.itemWidth = 0; /* ignored */ dummyls.mis.itemData = 0; ListBoxAskMeasure(lphl,&dummyls); } else { lphl->hDrawItemStruct = 0; } #if 0 HeapHandle = GlobalAlloc(GMEM_FIXED, LIST_HEAP_SIZE); HeapBase = GlobalLock(HeapHandle); HEAP_Init(&lphl->Heap, HeapBase, LIST_HEAP_SIZE); #endif } void DestroyListBoxStruct(LPHEADLIST lphl) { if (lphl->hDrawItemStruct) USER_HEAP_FREE(lphl->hDrawItemStruct); /* XXX need to free lphl->Heap */ free(lphl); } static LPHEADLIST ListBoxGetStorageHeader(HWND hwnd) { return (LPHEADLIST)GetWindowLong(hwnd,0); } /* Send notification "code" as part of a WM_COMMAND-message if hwnd has the LBS_NOTIFY style */ void ListBoxSendNotification(LPHEADLIST lphl, HWND hwnd, WORD code) { if (lphl->dwStyle & LBS_NOTIFY) SendMessage(lphl->hParent, WM_COMMAND, lphl->CtlID, MAKELONG(hwnd, code)); } /* get the maximum value of lphl->FirstVisible */ int ListMaxFirstVisible(LPHEADLIST lphl) { int m = lphl->ItemsCount-lphl->ItemsVisible; return (m < 0) ? 0 : m; } void ListBoxUpdateWindow(HWND hwnd, LPHEADLIST lphl, BOOL repaint) { SetScrollRange(hwnd, SB_VERT, 0, ListMaxFirstVisible(lphl), TRUE); if (lphl->ItemsPerColumn != 0) { SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible / lphl->ItemsPerColumn + 1, TRUE); } if (repaint && lphl->bRedrawFlag) { InvalidateRect(hwnd, NULL, TRUE); } } /* Returns: 0 if nothing needs to be changed */ /* 1 if FirstVisible changed */ int ListBoxScrollToFocus(LPHEADLIST lphl) { short end; if (lphl->ItemsCount == 0) return 0; if (lphl->ItemFocused == -1) return 0; end = lphl->FirstVisible + lphl->ItemsVisible - 1; if (lphl->ItemFocused < lphl->FirstVisible ) { lphl->FirstVisible = lphl->ItemFocused; return 1; } else { if (lphl->ItemFocused > end) { WORD maxFirstVisible = ListMaxFirstVisible(lphl); lphl->FirstVisible = lphl->ItemFocused; if (lphl->FirstVisible > maxFirstVisible) { lphl->FirstVisible = maxFirstVisible; } return 1; } } return 0; } LPLISTSTRUCT ListBoxGetItem(LPHEADLIST lphl, UINT uIndex) { LPLISTSTRUCT lpls; UINT Count = 0; if (uIndex >= lphl->ItemsCount) return NULL; lpls = lphl->lpFirst; while (Count++ < uIndex) lpls = lpls->lpNext; return lpls; } void ListBoxDrawItem (HWND hwnd, LPHEADLIST lphl, HDC hdc, LPLISTSTRUCT lpls, RECT *rect, WORD itemAction, WORD itemState) { if (lphl->OwnerDrawn) { DRAWITEMSTRUCT *dis = USER_HEAP_LIN_ADDR(lphl->hDrawItemStruct); dis->CtlID = lpls->mis.CtlID; dis->CtlType = lpls->mis.CtlType; dis->itemID = lpls->mis.itemID; dis->hDC = hdc; dis->hwndItem = hwnd; dis->itemData = lpls->mis.itemData; dis->itemAction = itemAction; dis->itemState = itemState; dis->rcItem = *rect; SendMessage(lphl->hParent, WM_DRAWITEM, 0, (LPARAM)USER_HEAP_SEG_ADDR(lphl->hDrawItemStruct)); } else { if (itemAction == ODA_DRAWENTIRE || itemAction == ODA_SELECT) { int OldBkMode; DWORD dwOldTextColor = 0; OldBkMode = SetBkMode(hdc, TRANSPARENT); if (itemState != 0) { dwOldTextColor = SetTextColor(hdc, 0x00FFFFFFL); FillRect(hdc, rect, GetStockObject(BLACK_BRUSH)); } if (lphl->dwStyle & LBS_USETABSTOPS) { TabbedTextOut(hdc, rect->left + 5, rect->top + 2, (char *)lpls->itemText, strlen((char *)lpls->itemText), lphl->iNumStops, lphl->TabStops, 0); } else { TextOut(hdc, rect->left + 5, rect->top + 2, (char *)lpls->itemText, strlen((char *)lpls->itemText)); } if (itemState != 0) { SetTextColor(hdc, dwOldTextColor); } SetBkMode(hdc, OldBkMode); } else DrawFocusRect(hdc, rect); } return; } int ListBoxFindMouse(LPHEADLIST lphl, int X, int Y) { LPLISTSTRUCT lpls = lphl->lpFirst; int i, j; POINT point; point.x = X; point.y = Y; if (lphl->ItemsCount == 0) return LB_ERR; for(i = 0; i < lphl->FirstVisible; i++) { if (lpls == NULL) return LB_ERR; lpls = lpls->lpNext; } for(j = 0; j < lphl->ItemsVisible; i++, j++) { if (lpls == NULL) return LB_ERR; if (PtInRect(&lpls->itemRect,point)) { return i; } lpls = lpls->lpNext; } dprintf_listbox(stddeb,"ListBoxFindMouse: not found\n"); return LB_ERR; } void ListBoxAskMeasure(LPHEADLIST lphl, LPLISTSTRUCT lpls) { HANDLE hTemp = USER_HEAP_ALLOC( sizeof(MEASUREITEMSTRUCT) ); MEASUREITEMSTRUCT *lpmeasure = (MEASUREITEMSTRUCT *) USER_HEAP_LIN_ADDR(hTemp); if (lpmeasure == NULL) { fprintf(stderr,"ListBoxAskMeasure() out of memory !\n"); return; } *lpmeasure = lpls->mis; lpmeasure->itemHeight = lphl->StdItemHeight; SendMessage(lphl->hParent, WM_MEASUREITEM, 0, USER_HEAP_SEG_ADDR(hTemp)); if (lphl->dwStyle & LBS_OWNERDRAWFIXED) { lphl->StdItemHeight = lpmeasure->itemHeight; lphl->needMeasure = FALSE; } USER_HEAP_FREE(hTemp); } LPLISTSTRUCT ListBoxCreateItem(LPHEADLIST lphl, int id) { LPLISTSTRUCT lplsnew = (LPLISTSTRUCT)malloc(sizeof(LISTSTRUCT)); if (lplsnew == NULL) return NULL; lplsnew->itemState = 0; lplsnew->mis.CtlType = lphl->DrawCtlType; lplsnew->mis.CtlID = lphl->CtlID; lplsnew->mis.itemID = id; lplsnew->mis.itemHeight = lphl->StdItemHeight; lplsnew->mis.itemWidth = 0; /* ignored */ lplsnew->mis.itemData = 0; SetRect(&lplsnew->itemRect, 0, 0, 0, 0); return lplsnew; } int ListBoxInsertString(LPHEADLIST lphl, UINT uIndex, LPSTR newstr) { LPLISTSTRUCT *lppls, lplsnew, lpls; HANDLE hStr; LPSTR str; UINT Count; dprintf_listbox(stddeb,"ListBoxInsertString(%d, %p);\n", uIndex, newstr); if (uIndex == (UINT)-1) uIndex = lphl->ItemsCount; lppls = &lphl->lpFirst; for(Count = 0; Count < uIndex; Count++) { if (*lppls == NULL) return LB_ERR; lppls = (LPLISTSTRUCT *) &(*lppls)->lpNext; } lplsnew = ListBoxCreateItem(lphl, Count); if (lplsnew == NULL) { printf("ListBoxInsertString() out of memory !\n"); return LB_ERRSPACE; } lplsnew->lpNext = *lppls; *lppls = lplsnew; lphl->ItemsCount++; hStr = 0; if (lphl->HasStrings) { dprintf_listbox(stddeb," string: %s\n", newstr); hStr = LIST_HEAP_ALLOC(lphl, LMEM_MOVEABLE, strlen(newstr) + 1); str = (LPSTR)LIST_HEAP_ADDR(lphl, hStr); if (str == NULL) return LB_ERRSPACE; strcpy(str, newstr); lplsnew->itemText = str; /* I'm not so sure about the next one */ lplsnew->mis.itemData = 0; } else { lplsnew->itemText = NULL; lplsnew->mis.itemData = (DWORD)newstr; } lplsnew->mis.itemID = uIndex; lplsnew->hData = hStr; /* adjust the itemID field of the following entries */ for(lpls = lplsnew->lpNext; lpls != NULL; lpls = lpls->lpNext) { lpls->mis.itemID++; } if (lphl->needMeasure) { ListBoxAskMeasure(lphl, lplsnew); } dprintf_listbox(stddeb,"ListBoxInsertString // count=%d\n", lphl->ItemsCount); return uIndex; } int ListBoxAddString(LPHEADLIST lphl, LPSTR newstr) { UINT pos = (UINT) -1; if (lphl->HasStrings && (lphl->dwStyle & LBS_SORT)) { LPLISTSTRUCT lpls = lphl->lpFirst; for (pos = 0; lpls != NULL; lpls = lpls->lpNext, pos++) if (strcmp(lpls->itemText, newstr) >= 0) break; } return ListBoxInsertString(lphl, pos, newstr); } int ListBoxGetText(LPHEADLIST lphl, UINT uIndex, LPSTR OutStr) { LPLISTSTRUCT lpls; if (!OutStr) { dprintf_listbox(stddeb, "ListBoxGetText // OutStr==NULL\n"); return 0; } lpls = ListBoxGetItem (lphl, uIndex); if (lpls == NULL) return LB_ERR; if (!lphl->HasStrings) { *((long *)OutStr) = lpls->mis.itemData; return 4; } strcpy(OutStr, lpls->itemText); return strlen(OutStr); } DWORD ListBoxGetItemData(LPHEADLIST lphl, UINT uIndex) { LPLISTSTRUCT lpls; lpls = ListBoxGetItem (lphl, uIndex); if (lpls == NULL) return LB_ERR; return lpls->mis.itemData; } int ListBoxSetItemData(LPHEADLIST lphl, UINT uIndex, DWORD ItemData) { LPLISTSTRUCT lpls = ListBoxGetItem(lphl, uIndex); if (lpls == NULL) return LB_ERR; lpls->mis.itemData = ItemData; return 1; } int ListBoxDeleteString(LPHEADLIST lphl, UINT uIndex) { LPLISTSTRUCT lpls, lpls2; UINT Count; if (uIndex >= lphl->ItemsCount) return LB_ERR; lpls = lphl->lpFirst; if (lpls == NULL) return LB_ERR; if (uIndex == 0) lphl->lpFirst = lpls->lpNext; else { LPLISTSTRUCT lpls2 = NULL; for(Count = 0; Count < uIndex; Count++) { if (lpls->lpNext == NULL) return LB_ERR; lpls2 = lpls; lpls = (LPLISTSTRUCT)lpls->lpNext; } lpls2->lpNext = lpls->lpNext; } /* adjust the itemID field of the following entries */ for(lpls2 = lpls->lpNext; lpls2 != NULL; lpls2 = lpls2->lpNext) { lpls2->mis.itemID--; } lphl->ItemsCount--; if (lpls->hData != 0) LIST_HEAP_FREE(lphl, lpls->hData); free(lpls); return lphl->ItemsCount; } int ListBoxFindString(LPHEADLIST lphl, UINT nFirst, SEGPTR MatchStr) { LPLISTSTRUCT lpls; UINT Count; UINT First = nFirst + 1; LPSTR lpMatchStr = (LPSTR)MatchStr; if (First > lphl->ItemsCount) return LB_ERR; if (lphl->HasStrings) lpMatchStr = PTR_SEG_TO_LIN(MatchStr); lpls = ListBoxGetItem(lphl, First); Count = 0; while(lpls != NULL) { if (lphl->HasStrings) { if (strstr(lpls->itemText, lpMatchStr) == lpls->itemText) return Count; } else if (lphl->dwStyle & LBS_SORT) { /* XXX Do a compare item */ } else if (lpls->mis.itemData == (DWORD)lpMatchStr) return Count; lpls = lpls->lpNext; Count++; } /* Start over at top */ Count = 0; lpls = lphl->lpFirst; while (Count < First) { if (lphl->HasStrings) { if (strstr(lpls->itemText, lpMatchStr) == lpls->itemText) return Count; } else if (lphl->dwStyle & LBS_SORT) { /* XXX Do a compare item */ } else { if (lpls->mis.itemData == (DWORD)lpMatchStr) return Count; } lpls = lpls->lpNext; Count++; } return LB_ERR; } int ListBoxResetContent(LPHEADLIST lphl) { LPLISTSTRUCT lpls; int i; if (lphl->ItemsCount == 0) return 0; dprintf_listbox(stddeb, "ListBoxResetContent // ItemCount = %d\n", lphl->ItemsCount); for(i = 0; i < lphl->ItemsCount; i++) { lpls = lphl->lpFirst; if (lpls == NULL) return LB_ERR; lphl->lpFirst = lpls->lpNext; if (lpls->hData != 0) LIST_HEAP_FREE(lphl, lpls->hData); free(lpls); } ListBoxInitialize(lphl); return TRUE; } int ListBoxSetCurSel(LPHEADLIST lphl, WORD wIndex) { LPLISTSTRUCT lpls; if (lphl->dwStyle & LBS_MULTIPLESEL) return 0; if (lphl->ItemFocused != -1) { lpls = ListBoxGetItem(lphl, lphl->ItemFocused); if (lpls == 0) return LB_ERR; lpls->itemState = 0; } if (wIndex != (UINT)-1) { lphl->ItemFocused = wIndex; lpls = ListBoxGetItem(lphl, wIndex); if (lpls == 0) return LB_ERR; lpls->itemState = ODS_SELECTED | ODS_FOCUS; return 0; } return LB_ERR; } int ListBoxSetSel(LPHEADLIST lphl, WORD wIndex, WORD state) { LPLISTSTRUCT lpls; if (!(lphl->dwStyle & LBS_MULTIPLESEL)) return 0; if (wIndex == (UINT)-1) { for (lpls = lphl->lpFirst; lpls != NULL; lpls = lpls->lpNext) { lpls->itemState = state; } return 0; } if (wIndex >= lphl->ItemsCount) return LB_ERR; lpls = ListBoxGetItem(lphl, wIndex); lpls->itemState = state; return 0; } int ListBoxGetSel(LPHEADLIST lphl, WORD wIndex) { LPLISTSTRUCT lpls = ListBoxGetItem(lphl, wIndex); if (lpls == NULL) return LB_ERR; return lpls->itemState; } int ListBoxDirectory(LPHEADLIST lphl, UINT attrib, LPSTR filespec) { struct dosdirent *dp, *dp_old; char temp[256]; int drive; LPSTR tstr; dprintf_listbox(stddeb,"ListBoxDirectory: %s, %4x\n",filespec,attrib); if (strchr(filespec, '\\') || strchr(filespec, ':')) { drive = DOS_GetDefaultDrive(); if (filespec[1] == ':') { drive = toupper(filespec[0]) - 'A'; filespec += 2; } strcpy(temp,filespec); tstr = strrchr(temp, '\\'); if (tstr == NULL) DOS_SetDefaultDrive( drive ); else { *tstr = 0; filespec = tstr + 1; if (!DOS_ChangeDir( drive, temp )) return 0; DOS_SetDefaultDrive( drive ); } dprintf_listbox(stddeb,"Changing directory to %c:%s, filemask is %s\n", drive+'A', temp, filespec); } if ((dp = (struct dosdirent *)DOS_opendir(filespec)) ==NULL) return 0; dp_old = dp; while ((dp = (struct dosdirent *)DOS_readdir(dp))) { if (!dp->inuse) break; dprintf_listbox(stddeb, "ListBoxDirectory %p '%s' !\n", dp->filename, dp->filename); if (dp->attribute & FA_DIREC) { if (attrib & DDL_DIRECTORY && strcmp(dp->filename, ".") != 0) { sprintf(temp, "[%s]", dp->filename); if (ListBoxAddString(lphl, temp) == LB_ERR) break; } } else { if (attrib & DDL_EXCLUSIVE) { if (attrib & (DDL_READWRITE | DDL_READONLY | DDL_HIDDEN | DDL_SYSTEM)) { if (ListBoxAddString(lphl, dp->filename) == LB_ERR) break; } } else { if (ListBoxAddString(lphl, dp->filename) == LB_ERR) break; } } } DOS_closedir(dp_old); if (attrib & DDL_DRIVES) { int x; for (x = 0; x != MAX_DOS_DRIVES ; x++) { if (DOS_ValidDrive(x)) { sprintf(temp, "[-%c-]", 'a'+x); if (ListBoxInsertString(lphl, (UINT)-1, temp) == LB_ERR) break; } } } return 1; } int ListBoxGetItemRect(LPHEADLIST lphl, WORD wIndex, LPRECT lprect) { LPLISTSTRUCT lpls = ListBoxGetItem(lphl,wIndex); if (lpls == NULL) return LB_ERR; *lprect = lpls->itemRect; return 0; } int ListBoxSetItemHeight(LPHEADLIST lphl, WORD wIndex, long height) { LPLISTSTRUCT lpls; if (!(lphl->dwStyle & LBS_OWNERDRAWVARIABLE)) { lphl->StdItemHeight = (short)height; return 0; } lpls = ListBoxGetItem(lphl, wIndex); if (lpls == NULL) return LB_ERR; lpls->mis.itemHeight = height; return 0; } int ListBoxFindNextMatch(LPHEADLIST lphl, WORD wChar) { LPLISTSTRUCT lpls; UINT count,first; if ((char)wChar < ' ') return LB_ERR; if (!lphl->HasStrings) return LB_ERR; lpls = lphl->lpFirst; for (count = 0; lpls != NULL; lpls = lpls->lpNext, count++) { if (tolower(*lpls->itemText) == tolower((char)wChar)) break; } if (lpls == NULL) return LB_ERR; first = count; for(; lpls != NULL; lpls = lpls->lpNext, count++) { if (*lpls->itemText != (char)wChar) break; if (count > lphl->ItemFocused) return count; } return first; } /*********************************************************************** * LBCreate */ static LONG LBCreate(HWND hwnd, WORD wParam, LONG lParam) { LPHEADLIST lphl; RECT rect; CreateListBoxStruct(hwnd, ODT_LISTBOX, GetWindowLong(hwnd,GWL_STYLE), GetParent(hwnd)); lphl = ListBoxGetStorageHeader(hwnd); dprintf_listbox(stddeb,"ListBox WM_CREATE %p !\n", lphl); GetClientRect(hwnd,&rect); lphl->ColumnsWidth = rect.right - rect.left; SetScrollRange(hwnd, SB_VERT, 0, ListMaxFirstVisible(lphl), TRUE); SetScrollRange(hwnd, SB_HORZ, 1, 1, TRUE); return 0; } /*********************************************************************** * LBDestroy */ static LONG LBDestroy(HWND hwnd, WORD wParam, LONG lParam) { LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); ListBoxResetContent(lphl); DestroyListBoxStruct(lphl); dprintf_listbox(stddeb,"ListBox WM_DESTROY %p !\n", lphl); return 0; } /*********************************************************************** * LBVScroll */ static LONG LBVScroll(HWND hwnd, WORD wParam, LONG lParam) { LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); int y; dprintf_listbox(stddeb,"ListBox WM_VSCROLL w=%04X l=%08lX !\n", wParam, lParam); y = lphl->FirstVisible; switch(wParam) { case SB_LINEUP: if (lphl->FirstVisible > 0) lphl->FirstVisible--; break; case SB_LINEDOWN: lphl->FirstVisible++; break; case SB_PAGEUP: if (lphl->FirstVisible > lphl->ItemsVisible) { lphl->FirstVisible -= lphl->ItemsVisible; } else { lphl->FirstVisible = 0; } break; case SB_PAGEDOWN: lphl->FirstVisible += lphl->ItemsVisible; break; case SB_THUMBTRACK: lphl->FirstVisible = LOWORD(lParam); break; } if (lphl->FirstVisible > ListMaxFirstVisible(lphl)) lphl->FirstVisible = ListMaxFirstVisible(lphl); if (y != lphl->FirstVisible) { SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); InvalidateRect(hwnd, NULL, TRUE); } return 0; } /*********************************************************************** * LBHScroll */ static LONG LBHScroll(HWND hwnd, WORD wParam, LONG lParam) { LPHEADLIST lphl; int y; dprintf_listbox(stddeb,"ListBox WM_HSCROLL w=%04X l=%08lX !\n", wParam, lParam); lphl = ListBoxGetStorageHeader(hwnd); y = lphl->FirstVisible; switch(wParam) { case SB_LINEUP: if (lphl->FirstVisible > lphl->ItemsPerColumn) { lphl->FirstVisible -= lphl->ItemsPerColumn; } else { lphl->FirstVisible = 0; } break; case SB_LINEDOWN: lphl->FirstVisible += lphl->ItemsPerColumn; break; case SB_PAGEUP: if (lphl->ItemsPerColumn != 0) { int lbsub = lphl->ItemsVisible / lphl->ItemsPerColumn * lphl->ItemsPerColumn; if (lphl->FirstVisible > lbsub) { lphl->FirstVisible -= lbsub; } else { lphl->FirstVisible = 0; } } break; case SB_PAGEDOWN: if (lphl->ItemsPerColumn != 0) lphl->FirstVisible += lphl->ItemsVisible / lphl->ItemsPerColumn * lphl->ItemsPerColumn; break; case SB_THUMBTRACK: lphl->FirstVisible = lphl->ItemsPerColumn * LOWORD(lParam); break; } if (lphl->FirstVisible > ListMaxFirstVisible(lphl)) lphl->FirstVisible = ListMaxFirstVisible(lphl); if (lphl->ItemsPerColumn != 0) { lphl->FirstVisible = lphl->FirstVisible / lphl->ItemsPerColumn * lphl->ItemsPerColumn + 1; if (y != lphl->FirstVisible) { SetScrollPos(hwnd, SB_HORZ, lphl->FirstVisible / lphl->ItemsPerColumn + 1, TRUE); InvalidateRect(hwnd, NULL, TRUE); } } return 0; } /*********************************************************************** * LBLButtonDown */ static LONG LBLButtonDown(HWND hwnd, WORD wParam, LONG lParam) { LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); WORD wRet; int y; RECT rectsel; SetFocus(hwnd); SetCapture(hwnd); lphl->PrevFocused = lphl->ItemFocused; y = ListBoxFindMouse(lphl, LOWORD(lParam), HIWORD(lParam)); if (y == -1) return 0; if (lphl->dwStyle & LBS_MULTIPLESEL) { lphl->ItemFocused = y; wRet = ListBoxGetSel(lphl, y); ListBoxSetSel(lphl, y, !wRet); } else { ListBoxSetCurSel(lphl, y); } if (lphl->dwStyle & LBS_MULTIPLESEL) ListBoxSendNotification(lphl, hwnd, LBN_SELCHANGE); ListBoxGetItemRect(lphl, y, &rectsel); InvalidateRect(hwnd, NULL, TRUE); return 0; } /*********************************************************************** * LBLButtonUp */ static LONG LBLButtonUp(HWND hwnd, WORD wParam, LONG lParam) { LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); if (GetCapture() == hwnd) ReleaseCapture(); if (lphl->PrevFocused != lphl->ItemFocused) ListBoxSendNotification(lphl, hwnd, LBN_SELCHANGE); return 0; } /*********************************************************************** * LBRButtonUp */ static LONG LBRButtonUp(HWND hwnd, WORD wParam, LONG lParam) { LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); SendMessage(lphl->hParent, WM_COMMAND, GetWindowWord(hwnd,GWW_ID), MAKELONG(hwnd, LBN_DBLCLK)); return 0; } /*********************************************************************** * LBMouseMove */ static LONG LBMouseMove(HWND hwnd, WORD wParam, LONG lParam) { LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); int y; WORD wRet; RECT rect, rectsel; /* XXX Broken */ dprintf_listbox(stddeb,"LBMouseMove %d %d\n",SLOWORD(lParam),SHIWORD(lParam)); if ((wParam & MK_LBUTTON) != 0) { y = SHIWORD(lParam); if (y < 0) { if (lphl->FirstVisible > 0) { lphl->FirstVisible--; SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); InvalidateRect(hwnd, NULL, TRUE); return 0; } } GetClientRect(hwnd, &rect); if (y >= rect.bottom) { if (lphl->FirstVisible < ListMaxFirstVisible(lphl)) { lphl->FirstVisible++; SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); InvalidateRect(hwnd, NULL, TRUE); return 0; } } if ((y > 0) && (y < (rect.bottom - 4))) { if ((y < rectsel.top) || (y > rectsel.bottom)) { wRet = ListBoxFindMouse(lphl, LOWORD(lParam), HIWORD(lParam)); if (wRet == lphl->ItemFocused) { return 0; } if (lphl->dwStyle & LBS_MULTIPLESEL) { lphl->ItemFocused = wRet; ListBoxSendNotification(lphl, hwnd, LBN_SELCHANGE); } else { ListBoxSetCurSel(lphl, wRet); } ListBoxGetItemRect(lphl, wRet, &rectsel); InvalidateRect(hwnd, NULL, TRUE); } } } return 0; } /*********************************************************************** * LBKeyDown */ static LONG LBKeyDown(HWND hwnd, WORD wParam, LONG lParam) { LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); WORD newFocused = lphl->ItemFocused; if (wParam == VK_SPACE) { if (lphl->dwStyle & LBS_MULTIPLESEL) { WORD wRet = ListBoxGetSel(lphl, lphl->ItemFocused); ListBoxSetSel(lphl, lphl->ItemFocused, !wRet); } return 0; } switch(wParam) { case VK_HOME: newFocused = 0; break; case VK_END: newFocused = lphl->ItemsCount - 1; break; case VK_LEFT: if (lphl->dwStyle & LBS_MULTICOLUMN) { if (newFocused >= lphl->ItemsPerColumn) { newFocused -= lphl->ItemsPerColumn; } else { newFocused = 0; } } break; case VK_UP: if (newFocused > 0) newFocused--; break; case VK_RIGHT: if (lphl->dwStyle & LBS_MULTICOLUMN) { newFocused += lphl->ItemsPerColumn; } break; case VK_DOWN: newFocused++; break; case VK_PRIOR: if (newFocused > lphl->ItemsVisible) { newFocused -= lphl->ItemsVisible; } else { newFocused = 0; } break; case VK_NEXT: newFocused += lphl->ItemsVisible; break; default: return 0; } if (newFocused >= lphl->ItemsCount) newFocused = lphl->ItemsCount - 1; if (!(lphl->dwStyle & LBS_MULTIPLESEL)) { ListBoxSetCurSel(lphl, newFocused); ListBoxSendNotification(lphl, hwnd, LBN_SELCHANGE); } lphl->ItemFocused = newFocused; ListBoxScrollToFocus(lphl); SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); InvalidateRect(hwnd, NULL, TRUE); return 0; } /*********************************************************************** * LBChar */ static LONG LBChar(HWND hwnd, WORD wParam, LONG lParam) { LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); WORD newFocused; newFocused = ListBoxFindNextMatch(lphl, wParam); if (newFocused == (WORD)LB_ERR) return 0; if (newFocused >= lphl->ItemsCount) newFocused = lphl->ItemsCount - 1; if (!(lphl->dwStyle & LBS_MULTIPLESEL)) { ListBoxSetCurSel(lphl, newFocused); ListBoxSendNotification(lphl, hwnd, LBN_SELCHANGE); } lphl->ItemFocused = newFocused; ListBoxScrollToFocus(lphl); SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); InvalidateRect(hwnd, NULL, TRUE); return 0; } /*********************************************************************** * LBSetRedraw */ static LONG LBSetRedraw(HWND hwnd, WORD wParam, LONG lParam) { LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); dprintf_listbox(stddeb,"ListBox WM_SETREDRAW hWnd=%04X w=%04X !\n", hwnd, wParam); lphl->bRedrawFlag = wParam; return 0; } /*********************************************************************** * LBSetFont */ static LONG LBSetFont(HWND hwnd, WORD wParam, LONG lParam) { LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); if (wParam == 0) lphl->hFont = GetStockObject(SYSTEM_FONT); else lphl->hFont = wParam; return 0; } /*********************************************************************** * LBPaint */ static LONG LBPaint(HWND hwnd, WORD wParam, LONG lParam) { LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); LPLISTSTRUCT lpls; PAINTSTRUCT ps; HBRUSH hBrush; HFONT hOldFont; HDC hdc; RECT rect; int i, top, height, maxwidth, ipc; top = 0; hdc = BeginPaint( hwnd, &ps ); if (!IsWindowVisible(hwnd) || !lphl->bRedrawFlag) { EndPaint(hwnd, &ps); return 0; } hOldFont = SelectObject(hdc, lphl->hFont); hBrush = SendMessage(lphl->hParent, WM_CTLCOLOR, hdc, MAKELONG(hwnd, CTLCOLOR_LISTBOX)); if (hBrush == 0) hBrush = GetStockObject(WHITE_BRUSH); GetClientRect(hwnd, &rect); FillRect(hdc, &rect, hBrush); maxwidth = rect.right; if (lphl->dwStyle & LBS_MULTICOLUMN) { rect.right = lphl->ColumnsWidth; } lpls = lphl->lpFirst; lphl->ItemsVisible = 0; lphl->ItemsPerColumn = ipc = 0; for(i = 0; i < lphl->ItemsCount; i++) { if (lpls == NULL) break; if (i >= lphl->FirstVisible) { height = lpls->mis.itemHeight; if (top > rect.bottom) { if (lphl->dwStyle & LBS_MULTICOLUMN) { lphl->ItemsPerColumn = max(lphl->ItemsPerColumn, ipc); ipc = 0; top = 0; rect.left += lphl->ColumnsWidth; rect.right += lphl->ColumnsWidth; if (rect.left > maxwidth) break; } else { break; } } lpls->itemRect.top = top; lpls->itemRect.bottom = top + height; lpls->itemRect.left = rect.left; lpls->itemRect.right = rect.right; dprintf_listbox(stddeb,"drawing item: %d %d %d %d %d\n",rect.left,top,rect.right,top+height,lpls->itemState); if (lphl->OwnerDrawn) { ListBoxDrawItem (hwnd, lphl, hdc, lpls, &lpls->itemRect, ODA_DRAWENTIRE, 0); if (lpls->itemState) ListBoxDrawItem (hwnd, lphl, hdc, lpls, &lpls->itemRect, ODA_SELECT, ODS_SELECTED); } else { ListBoxDrawItem (hwnd, lphl, hdc, lpls, &lpls->itemRect, ODA_DRAWENTIRE, lpls->itemState); } if ((lphl->ItemFocused == i) && GetFocus() == hwnd) ListBoxDrawItem (hwnd,lphl, hdc, lpls, &lpls->itemRect, ODA_FOCUS, ODS_FOCUS); top += height; lphl->ItemsVisible++; ipc++; } lpls = lpls->lpNext; } SelectObject(hdc,hOldFont); EndPaint( hwnd, &ps ); return 0; } /*********************************************************************** * LBSetFocus */ static LONG LBSetFocus(HWND hwnd, WORD wParam, LONG lParam) { dprintf_listbox(stddeb,"ListBox WM_SETFOCUS !\n"); return 0; } /*********************************************************************** * LBKillFocus */ static LONG LBKillFocus(HWND hwnd, WORD wParam, LONG lParam) { dprintf_listbox(stddeb,"ListBox WM_KILLFOCUS !\n"); InvalidateRect(hwnd, NULL, TRUE); return 0; } /*********************************************************************** * LBResetContent */ static LONG LBResetContent(HWND hwnd, WORD wParam, LONG lParam) { LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); dprintf_listbox(stddeb,"ListBox LB_RESETCONTENT !\n"); ListBoxResetContent(lphl); ListBoxUpdateWindow(hwnd, lphl, TRUE); return 0; } /*********************************************************************** * LBDir */ static LONG LBDir(HWND hwnd, WORD wParam, LONG lParam) { WORD wRet; LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); dprintf_listbox(stddeb,"ListBox LB_DIR !\n"); wRet = ListBoxDirectory(lphl, wParam, (LPSTR)PTR_SEG_TO_LIN(lParam)); ListBoxUpdateWindow(hwnd, lphl, TRUE); return wRet; } /*********************************************************************** * LBAddString */ static LONG LBAddString(HWND hwnd, WORD wParam, LONG lParam) { WORD wRet; LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); if (lphl->HasStrings) wRet = ListBoxAddString(lphl, (LPSTR)PTR_SEG_TO_LIN(lParam)); else wRet = ListBoxAddString(lphl, (LPSTR)lParam); ListBoxUpdateWindow(hwnd,lphl,TRUE); return wRet; } /*********************************************************************** * LBGetText */ static LONG LBGetText(HWND hwnd, WORD wParam, LONG lParam) { LONG wRet; LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); dprintf_listbox(stddeb, "LB_GETTEXT wParam=%d\n",wParam); wRet = ListBoxGetText(lphl, wParam, (LPSTR)PTR_SEG_TO_LIN(lParam)); return wRet; } /*********************************************************************** * LBInsertString */ static LONG LBInsertString(HWND hwnd, WORD wParam, LONG lParam) { WORD wRet; LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); if (lphl->HasStrings) wRet = ListBoxInsertString(lphl, wParam, (LPSTR)PTR_SEG_TO_LIN(lParam)); else wRet = ListBoxInsertString(lphl, wParam, (LPSTR)lParam); ListBoxUpdateWindow(hwnd,lphl,TRUE); return wRet; } /*********************************************************************** * LBDeleteString */ static LONG LBDeleteString(HWND hwnd, WORD wParam, LONG lParam) { LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); LONG lRet = ListBoxDeleteString(lphl,wParam); ListBoxUpdateWindow(hwnd,lphl,TRUE); return lRet; } /*********************************************************************** * LBFindString */ static LONG LBFindString(HWND hwnd, WORD wParam, LONG lParam) { LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); return ListBoxFindString(lphl, wParam, lParam); } /*********************************************************************** * LBGetCaretIndex */ static LONG LBGetCaretIndex(HWND hwnd, WORD wParam, LONG lParam) { LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); return lphl->ItemFocused; } /*********************************************************************** * LBGetCount */ static LONG LBGetCount(HWND hwnd, WORD wParam, LONG lParam) { LPHEADLIST lphl; lphl = ListBoxGetStorageHeader(hwnd); return lphl->ItemsCount; } /*********************************************************************** * LBGetCurSel */ static LONG LBGetCurSel(HWND hwnd, WORD wParam, LONG lParam) { LPHEADLIST lphl; lphl = ListBoxGetStorageHeader(hwnd); dprintf_listbox(stddeb,"ListBox LB_GETCURSEL %u !\n", lphl->ItemFocused); return lphl->ItemFocused; } /*********************************************************************** * LBGetHorizontalExtent */ static LONG LBGetHorizontalExtent(HWND hwnd, WORD wParam, LONG lParam) { return 0; } /*********************************************************************** * LBGetItemHeight */ static LONG LBGetItemHeight(HWND hwnd, WORD wParam, LONG lParam) { LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); LPLISTSTRUCT lpls = ListBoxGetItem (lphl, wParam); if (lpls == NULL) return LB_ERR; return lpls->mis.itemHeight; } /*********************************************************************** * LBGetItemRect */ static LONG LBGetItemRect(HWND hwnd, WORD wParam, LONG lParam) { LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); return ListBoxGetItemRect(lphl, wParam, PTR_SEG_TO_LIN(lParam)); } /*********************************************************************** * LBGetSel */ static LONG LBGetSel(HWND hwnd, WORD wParam, LONG lParam) { LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); return ListBoxGetSel(lphl, wParam); } /*********************************************************************** * LBGetSelCount */ static LONG LBGetSelCount(HWND hwnd, WORD wParam, LONG lParam) { LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); LPLISTSTRUCT lpls; int cnt = 0; if (!(lphl->dwStyle & LBS_MULTIPLESEL)) return LB_ERR; lpls = lphl->lpFirst; while (lpls != NULL) { if (lpls->itemState > 0) cnt++; lpls = lpls->lpNext; } return cnt; } /*********************************************************************** * LBGetSelItems */ static LONG LBGetSelItems(HWND hwnd, WORD wParam, LONG lParam) { LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); LPLISTSTRUCT lpls; int cnt, idx; int *lpItems = PTR_SEG_TO_LIN(lParam); if (!(lphl->dwStyle & LBS_MULTIPLESEL)) return LB_ERR; if (wParam == 0) return 0; lpls = lphl->lpFirst; cnt = 0; idx = 0; while (lpls != NULL) { if (lpls->itemState > 0) lpItems[cnt++] = idx; if (cnt == wParam) break; idx++; lpls = lpls->lpNext; } return cnt; } /*********************************************************************** * LBGetTextLen */ static LONG LBGetTextLen(HWND hwnd, WORD wParam, LONG lParam) { LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); LPLISTSTRUCT lpls = ListBoxGetItem(lphl,wParam); if (lpls == NULL || !lphl->HasStrings) return LB_ERR; return strlen(lpls->itemText); } /*********************************************************************** * LBGetDlgCode */ static LONG LBGetDlgCode(HWND hwnd, WORD wParam, LONG lParam) { return DLGC_WANTARROWS | DLGC_WANTCHARS; } /*********************************************************************** * LBGetTopIndex */ static LONG LBGetTopIndex(HWND hwnd, WORD wParam, LONG lParam) { LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); return lphl->FirstVisible; } /*********************************************************************** * LBSelectString */ static LONG LBSelectString(HWND hwnd, WORD wParam, LONG lParam) { LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); WORD wRet; wRet = ListBoxFindString(lphl, wParam, lParam); /* XXX add functionality here */ return 0; } /*********************************************************************** * LBSelItemRange */ static LONG LBSelItemRange(HWND hwnd, WORD wParam, LONG lParam) { LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); LPLISTSTRUCT lpls; WORD cnt; WORD first = LOWORD(lParam); WORD last = HIWORD(lParam); BOOL select = wParam; if (!(lphl->dwStyle & LBS_MULTIPLESEL)) return LB_ERR; if (first >= lphl->ItemsCount || last >= lphl->ItemsCount) return LB_ERR; lpls = lphl->lpFirst; cnt = 0; while (lpls != NULL) { if (cnt++ >= first) lpls->itemState = select ? ODS_SELECTED : 0; if (cnt > last) break; lpls = lpls->lpNext; } return 0; } /*********************************************************************** * LBSetCaretIndex */ static LONG LBSetCaretIndex(HWND hwnd, WORD wParam, LONG lParam) { LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); if (!(lphl->dwStyle & LBS_MULTIPLESEL)) return 0; if (wParam >= lphl->ItemsCount) return LB_ERR; lphl->ItemFocused = wParam; ListBoxScrollToFocus (lphl); SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); InvalidateRect(hwnd, NULL, TRUE); return 0; } /*********************************************************************** * LBSetColumnWidth */ static LONG LBSetColumnWidth(HWND hwnd, WORD wParam, LONG lParam) { LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); lphl->ColumnsWidth = wParam; InvalidateRect(hwnd,NULL,TRUE); return 0; } /*********************************************************************** * LBSetHorizontalExtent */ static LONG LBSetHorizontalExtent(HWND hwnd, WORD wParam, LONG lParam) { return 0; } /*********************************************************************** * LBGetItemData */ static LONG LBGetItemData(HWND hwnd, WORD wParam, LONG lParam) { LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); dprintf_listbox(stddeb, "LB_GETITEMDATA wParam=%x\n", wParam); return ListBoxGetItemData(lphl, wParam); } /*********************************************************************** * LBSetItemData */ static LONG LBSetItemData(HWND hwnd, WORD wParam, LONG lParam) { LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); dprintf_listbox(stddeb, "LB_SETITEMDATA wParam=%x lParam=%lx\n", wParam, lParam); return ListBoxSetItemData(lphl, wParam, lParam); } /*********************************************************************** * LBSetTabStops */ static LONG LBSetTabStops(HWND hwnd, WORD wParam, LONG lParam) { LPHEADLIST lphl; lphl = ListBoxGetStorageHeader(hwnd); if (lphl->TabStops != NULL) { lphl->iNumStops = 0; free (lphl->TabStops); } lphl->TabStops = malloc (wParam * sizeof (short)); if (lphl->TabStops) { lphl->iNumStops = wParam; memcpy (lphl->TabStops, PTR_SEG_TO_LIN(lParam), wParam * sizeof (short)); return TRUE; } return FALSE; } /*********************************************************************** * LBSetCurSel */ static LONG LBSetCurSel(HWND hwnd, WORD wParam, LONG lParam) { LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); WORD wRet; dprintf_listbox(stddeb,"ListBox LB_SETCURSEL wParam=%x !\n", wParam); wRet = ListBoxSetCurSel(lphl, wParam); SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); InvalidateRect(hwnd, NULL, TRUE); return wRet; } /*********************************************************************** * LBSetSel */ static LONG LBSetSel(HWND hwnd, WORD wParam, LONG lParam) { LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); WORD wRet; dprintf_listbox(stddeb,"ListBox LB_SETSEL wParam=%x lParam=%lX !\n", wParam, lParam); wRet = ListBoxSetSel(lphl, LOWORD(lParam), wParam); InvalidateRect(hwnd, NULL, TRUE); return wRet; } /*********************************************************************** * LBSetTopIndex */ static LONG LBSetTopIndex(HWND hwnd, WORD wParam, LONG lParam) { LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); dprintf_listbox(stddeb,"ListBox LB_SETTOPINDEX wParam=%x !\n", wParam); lphl->FirstVisible = wParam; SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); InvalidateRect(hwnd, NULL, TRUE); return 0; } /*********************************************************************** * LBSetItemHeight */ static LONG LBSetItemHeight(HWND hwnd, WORD wParam, LONG lParam) { LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); WORD wRet; dprintf_listbox(stddeb,"ListBox LB_SETITEMHEIGHT wParam=%x lParam=%lX !\n", wParam, lParam); wRet = ListBoxSetItemHeight(lphl, wParam, lParam); InvalidateRect(hwnd,NULL,TRUE); return wRet; } /*********************************************************************** * ListBoxWndProc */ LONG ListBoxWndProc(HWND hwnd, WORD message, WORD wParam, LONG lParam) { switch (message) { case WM_CREATE: return LBCreate(hwnd, wParam, lParam); case WM_DESTROY: return LBDestroy(hwnd, wParam, lParam); case WM_GETDLGCODE: return LBGetDlgCode(hwnd, wParam, lParam); case WM_VSCROLL: return LBVScroll(hwnd, wParam, lParam); case WM_HSCROLL: return LBHScroll(hwnd, wParam, lParam); case WM_LBUTTONDOWN: return LBLButtonDown(hwnd, wParam, lParam); case WM_LBUTTONUP: return LBLButtonUp(hwnd, wParam, lParam); case WM_RBUTTONUP: return LBRButtonUp(hwnd, wParam, lParam); case WM_LBUTTONDBLCLK: return LBRButtonUp(hwnd, wParam, lParam); case WM_MOUSEMOVE: return LBMouseMove(hwnd, wParam, lParam); case WM_KEYDOWN: return LBKeyDown(hwnd, wParam, lParam); case WM_CHAR: return LBChar(hwnd, wParam, lParam); case WM_SETFONT: return LBSetFont(hwnd, wParam, lParam); case WM_SETREDRAW: return LBSetRedraw(hwnd, wParam, lParam); case WM_PAINT: return LBPaint(hwnd, wParam, lParam); case WM_SETFOCUS: return LBSetFocus(hwnd, wParam, lParam); case WM_KILLFOCUS: return LBKillFocus(hwnd, wParam, lParam); case LB_RESETCONTENT: return LBResetContent(hwnd, wParam, lParam); case LB_DIR: return LBDir(hwnd, wParam, lParam); case LB_ADDSTRING: return LBAddString(hwnd, wParam, lParam); case LB_INSERTSTRING: return LBInsertString(hwnd, wParam, lParam); case LB_DELETESTRING: return LBDeleteString(hwnd, wParam, lParam); case LB_FINDSTRING: return LBFindString(hwnd, wParam, lParam); case LB_GETCARETINDEX: return LBGetCaretIndex(hwnd, wParam, lParam); case LB_GETCOUNT: return LBGetCount(hwnd, wParam, lParam); case LB_GETCURSEL: return LBGetCurSel(hwnd, wParam, lParam); case LB_GETHORIZONTALEXTENT: return LBGetHorizontalExtent(hwnd, wParam, lParam); case LB_GETITEMDATA: return LBGetItemData(hwnd, wParam, lParam); case LB_GETITEMHEIGHT: return LBGetItemHeight(hwnd, wParam, lParam); case LB_GETITEMRECT: return LBGetItemRect(hwnd, wParam, lParam); case LB_GETSEL: return LBGetSel(hwnd, wParam, lParam); case LB_GETSELCOUNT: return LBGetSelCount(hwnd, wParam, lParam); case LB_GETSELITEMS: return LBGetSelItems(hwnd, wParam, lParam); case LB_GETTEXT: return LBGetText(hwnd, wParam, lParam); case LB_GETTEXTLEN: return LBGetTextLen(hwnd, wParam, lParam); case LB_GETTOPINDEX: return LBGetTopIndex(hwnd, wParam, lParam); case LB_SELECTSTRING: return LBSelectString(hwnd, wParam, lParam); case LB_SELITEMRANGE: return LBSelItemRange(hwnd, wParam, lParam); case LB_SETCARETINDEX: return LBSetCaretIndex(hwnd, wParam, lParam); case LB_SETCOLUMNWIDTH: return LBSetColumnWidth(hwnd, wParam, lParam); case LB_SETHORIZONTALEXTENT: return LBSetHorizontalExtent(hwnd, wParam, lParam); case LB_SETITEMDATA: return LBSetItemData(hwnd, wParam, lParam); case LB_SETTABSTOPS: return LBSetTabStops(hwnd, wParam, lParam); case LB_SETCURSEL: return LBSetCurSel(hwnd, wParam, lParam); case LB_SETSEL: return LBSetSel(hwnd, wParam, lParam); case LB_SETTOPINDEX: return LBSetTopIndex(hwnd, wParam, lParam); case LB_SETITEMHEIGHT: return LBSetItemHeight(hwnd, wParam, lParam); } return DefWindowProc(hwnd, message, wParam, lParam); } /************************************************************************ * DlgDirSelect [USER.99] */ BOOL DlgDirSelect(HWND hDlg, LPSTR lpStr, int nIDLBox) { HWND hwnd; LPHEADLIST lphl; char s[130]; dprintf_listbox( stddeb, "DlgDirSelect(%04X, '%s', %d) \n", hDlg, lpStr, nIDLBox ); hwnd = GetDlgItem(hDlg, nIDLBox); lphl = ListBoxGetStorageHeader(hwnd); if(lphl->ItemFocused == -1) { dprintf_listbox(stddeb, "Nothing selected!\n"); return FALSE; } ListBoxGetText(lphl, lphl->ItemFocused, s); dprintf_listbox(stddeb, "Selection is %s\n", s); if( s[0] == '[' ) { if( s[1] == '-' ) { strncpy( lpStr, s+2, strlen(s)-4 ); /* device name */ lpStr[ strlen(s)-4 ] = 0; strcat( lpStr, ":" ); } else { strncpy( lpStr, s+1, strlen(s)-2 ); /* directory name */ lpStr[ strlen(s)-2 ] = 0; strcat( lpStr, "\\" ); } dprintf_listbox( stddeb, "Returning %s\n", lpStr ); return TRUE; } else { strcpy( lpStr, s ); /* file name */ dprintf_listbox( stddeb, "Returning %s\n", lpStr ); return FALSE; } } /************************************************************************ * DlgDirList [USER.100] */ int DlgDirList(HWND hDlg, LPSTR lpPathSpec, int nIDLBox, int nIDStat, WORD wType) { HWND hWnd; int ret; dprintf_listbox(stddeb,"DlgDirList(%04X, '%s', %d, %d, %04X) \n", hDlg, lpPathSpec, nIDLBox, nIDStat, wType); if (nIDLBox) { LPHEADLIST lphl; hWnd = GetDlgItem(hDlg, nIDLBox); lphl = ListBoxGetStorageHeader(hWnd); ListBoxResetContent(lphl); ret = ListBoxDirectory(lphl, wType, lpPathSpec); ListBoxUpdateWindow(hWnd, lphl, TRUE); } else { ret = 0; } if (nIDStat) { int drive; HANDLE hTemp; char *temp; drive = DOS_GetDefaultDrive(); hTemp = USER_HEAP_ALLOC( 256 ); temp = (char *) USER_HEAP_LIN_ADDR( hTemp ); strcpy( temp+3, DOS_GetCurrentDir(drive) ); if( temp[3] == '\\' ) { temp[1] = 'A'+drive; temp[2] = ':'; SendDlgItemMessage( hDlg, nIDStat, WM_SETTEXT, 0, USER_HEAP_SEG_ADDR(hTemp) + 1 ); } else { temp[0] = 'A'+drive; temp[1] = ':'; temp[2] = '\\'; SendDlgItemMessage( hDlg, nIDStat, WM_SETTEXT, 0, USER_HEAP_SEG_ADDR(hTemp) ); } USER_HEAP_FREE( hTemp ); } return ret; }