/* * Interface code to listbox widgets * * Copyright Martin Ayotte, 1993 * static char Copyright[] = "Copyright Martin Ayotte, 1993"; */ #include #include #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" #define GMEM_ZEROINIT 0x0040 LPHEADLIST ListBoxGetWindowAndStorage(HWND hwnd, WND **wndPtr); LPHEADLIST ListBoxGetStorageHeader(HWND hwnd); void StdDrawListBox(HWND hwnd); void OwnerDrawListBox(HWND hwnd); int ListBoxFindMouse(HWND hwnd, int X, int Y); int CreateListBoxStruct(HWND hwnd); void ListBoxAskMeasure(WND *wndPtr, LPHEADLIST lphl, LPLISTSTRUCT lpls); int ListBoxAddString(HWND hwnd, LPSTR newstr); int ListBoxInsertString(HWND hwnd, UINT uIndex, LPSTR newstr); int ListBoxGetText(HWND hwnd, UINT uIndex, LPSTR OutStr, BOOL bItemData); int ListBoxSetItemData(HWND hwnd, UINT uIndex, DWORD ItemData); int ListBoxDeleteString(HWND hwnd, UINT uIndex); int ListBoxFindString(HWND hwnd, UINT nFirst, LPSTR MatchStr); int ListBoxResetContent(HWND hwnd); int ListBoxSetCurSel(HWND hwnd, WORD wIndex); int ListBoxSetSel(HWND hwnd, WORD wIndex, WORD state); int ListBoxGetSel(HWND hwnd, WORD wIndex); int ListBoxDirectory(HWND hwnd, UINT attrib, LPSTR filespec); int ListBoxGetItemRect(HWND hwnd, WORD wIndex, LPRECT rect); int ListBoxSetItemHeight(HWND hwnd, WORD wIndex, long height); int ListBoxDefaultItem(HWND hwnd, WND *wndPtr, LPHEADLIST lphl, LPLISTSTRUCT lpls); int ListBoxFindNextMatch(HWND hwnd, WORD wChar); int ListMaxFirstVisible(LPHEADLIST lphl); void ListBoxSendNotification(HWND hwnd, WORD code); #define HasStrings(wndPtr) ( \ ( ((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) != LBS_OWNERDRAWFIXED) && \ ((wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE) != LBS_OWNERDRAWVARIABLE) ) || \ ((wndPtr->dwStyle & LBS_HASSTRINGS) == LBS_HASSTRINGS) ) #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 #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) #endif #define LIST_HEAP_SIZE 0x10000 /*********************************************************************** * ListBoxWndProc */ LONG ListBoxWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) { WND *wndPtr; LPHEADLIST lphl; HWND hWndCtl; WORD wRet; LONG lRet; RECT rect; int y; CREATESTRUCT *createStruct; static RECT rectsel; switch(message) { case WM_CREATE: CreateListBoxStruct(hwnd); lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); dprintf_listbox(stddeb,"ListBox WM_CREATE %p !\n", lphl); if (lphl == NULL) return 0; createStruct = (CREATESTRUCT *)PTR_SEG_TO_LIN(lParam); if (HIWORD(createStruct->lpCreateParams) != 0) lphl->hWndLogicParent = (HWND)HIWORD(createStruct->lpCreateParams); else lphl->hWndLogicParent = GetParent(hwnd); lphl->hFont = GetStockObject(SYSTEM_FONT); lphl->ColumnsWidth = wndPtr->rectClient.right - wndPtr->rectClient.left; SetScrollRange(hwnd, SB_VERT, 1, ListMaxFirstVisible(lphl), TRUE); SetScrollRange(hwnd, SB_HORZ, 1, 1, TRUE); if ((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) == LBS_OWNERDRAWFIXED) { } return 0; case WM_DESTROY: lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); if (lphl == NULL) return 0; ListBoxResetContent(hwnd); /* XXX need to free lphl->Heap */ free(lphl); *((LPHEADLIST *)&wndPtr->wExtra[1]) = 0; dprintf_listbox(stddeb,"ListBox WM_DESTROY %p !\n", lphl); return 0; case WM_VSCROLL: dprintf_listbox(stddeb,"ListBox WM_VSCROLL w=%04X l=%08lX !\n", wParam, lParam); lphl = ListBoxGetStorageHeader(hwnd); if (lphl == NULL) return 0; y = lphl->FirstVisible; switch(wParam) { case SB_LINEUP: if (lphl->FirstVisible > 1) lphl->FirstVisible--; break; case SB_LINEDOWN: if (lphl->FirstVisible < ListMaxFirstVisible(lphl)) lphl->FirstVisible++; break; case SB_PAGEUP: if (lphl->FirstVisible > 1) lphl->FirstVisible -= lphl->ItemsVisible; break; case SB_PAGEDOWN: if (lphl->FirstVisible < ListMaxFirstVisible(lphl)) lphl->FirstVisible += lphl->ItemsVisible; break; case SB_THUMBTRACK: lphl->FirstVisible = LOWORD(lParam); break; } if (lphl->FirstVisible < 1) lphl->FirstVisible = 1; if (lphl->FirstVisible > ListMaxFirstVisible(lphl)) lphl->FirstVisible = ListMaxFirstVisible(lphl); if (y != lphl->FirstVisible) { SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); } return 0; case WM_HSCROLL: dprintf_listbox(stddeb,"ListBox WM_HSCROLL w=%04X l=%08lX !\n", wParam, lParam); lphl = ListBoxGetStorageHeader(hwnd); if (lphl == NULL) return 0; y = lphl->FirstVisible; switch(wParam) { case SB_LINEUP: if (lphl->FirstVisible > 1) lphl->FirstVisible -= lphl->ItemsPerColumn; break; case SB_LINEDOWN: if (lphl->FirstVisible < ListMaxFirstVisible(lphl)) lphl->FirstVisible += lphl->ItemsPerColumn; break; case SB_PAGEUP: if (lphl->FirstVisible > 1 && lphl->ItemsPerColumn != 0) lphl->FirstVisible -= lphl->ItemsVisible / lphl->ItemsPerColumn * lphl->ItemsPerColumn; break; case SB_PAGEDOWN: if (lphl->FirstVisible < ListMaxFirstVisible(lphl) && lphl->ItemsPerColumn != 0) lphl->FirstVisible += lphl->ItemsVisible / lphl->ItemsPerColumn * lphl->ItemsPerColumn; break; case SB_THUMBTRACK: lphl->FirstVisible = lphl->ItemsPerColumn * (LOWORD(lParam) - 1) + 1; break; } if (lphl->FirstVisible < 1) lphl->FirstVisible = 1; 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); UpdateWindow(hwnd); } } return 0; case WM_LBUTTONDOWN: SetFocus(hwnd); SetCapture(hwnd); lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); if (lphl == NULL) return 0; lphl->PrevFocused = lphl->ItemFocused; y = ListBoxFindMouse(hwnd, LOWORD(lParam), HIWORD(lParam)); if (y==-1) return 0; if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) { lphl->ItemFocused = y; wRet = ListBoxGetSel(hwnd, y); ListBoxSetSel(hwnd, y, !wRet); } else ListBoxSetCurSel(hwnd, y); if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) ListBoxSendNotification( hwnd, LBN_SELCHANGE ); ListBoxGetItemRect(hwnd, y, &rectsel); InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); return 0; case WM_LBUTTONUP: ReleaseCapture(); lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); if (lphl == NULL) return 0; if (lphl->PrevFocused != lphl->ItemFocused) ListBoxSendNotification( hwnd, LBN_SELCHANGE ); return 0; case WM_RBUTTONUP: case WM_LBUTTONDBLCLK: lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); if (lphl == NULL) return 0; SendMessage(lphl->hWndLogicParent, WM_COMMAND, wndPtr->wIDmenu, MAKELONG(hwnd, LBN_DBLCLK)); return 0; case WM_MOUSEMOVE: lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); if (lphl == NULL) return 0; if ((wParam & MK_LBUTTON) != 0) { y = HIWORD(lParam); if (y < 4) { if (lphl->FirstVisible > 1) { lphl->FirstVisible--; SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); break; } } GetClientRect(hwnd, &rect); if (y > (rect.bottom - 4)) { if (lphl->FirstVisible < ListMaxFirstVisible(lphl)) { lphl->FirstVisible++; SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); break; } } if ((y > 0) && (y < (rect.bottom - 4))) { if ((y < rectsel.top) || (y > rectsel.bottom)) { wRet = ListBoxFindMouse(hwnd, LOWORD(lParam), HIWORD(lParam)); if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) { lphl->ItemFocused = wRet; ListBoxSendNotification(hwnd, LBN_SELCHANGE); } else ListBoxSetCurSel(hwnd, wRet); ListBoxGetItemRect(hwnd, wRet, &rectsel); InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); } } } break; case WM_KEYDOWN: lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); if (lphl == NULL) return 0; switch(wParam) { case VK_TAB: hWndCtl = GetNextDlgTabItem(lphl->hWndLogicParent, hwnd, !(GetKeyState(VK_SHIFT) < 0)); SetFocus(hWndCtl); if(debugging_listbox){ if ((GetKeyState(VK_SHIFT) < 0)) dprintf_listbox(stddeb,"ListBox PreviousDlgTabItem %04X !\n", hWndCtl); else dprintf_listbox(stddeb,"ListBox NextDlgTabItem %04X !\n", hWndCtl); } break; case VK_HOME: lphl->ItemFocused = 0; break; case VK_END: lphl->ItemFocused = lphl->ItemsCount - 1; break; case VK_LEFT: if ((wndPtr->dwStyle & LBS_MULTICOLUMN) == LBS_MULTICOLUMN) { lphl->ItemFocused -= lphl->ItemsPerColumn; } break; case VK_UP: lphl->ItemFocused--; break; case VK_RIGHT: if ((wndPtr->dwStyle & LBS_MULTICOLUMN) == LBS_MULTICOLUMN) { lphl->ItemFocused += lphl->ItemsPerColumn; } break; case VK_DOWN: lphl->ItemFocused++; break; case VK_PRIOR: lphl->ItemFocused -= lphl->ItemsVisible; break; case VK_NEXT: lphl->ItemFocused += lphl->ItemsVisible; break; case VK_SPACE: wRet = ListBoxGetSel(hwnd, lphl->ItemFocused); ListBoxSetSel(hwnd, lphl->ItemFocused, !wRet); break; default: ListBoxFindNextMatch(hwnd, wParam); return 0; } if (lphl->ItemFocused < 0) lphl->ItemFocused = 0; if (lphl->ItemFocused >= lphl->ItemsCount) lphl->ItemFocused = lphl->ItemsCount - 1; lphl->FirstVisible = lphl->ItemFocused / lphl->ItemsVisible * lphl->ItemsVisible + 1; if (lphl->FirstVisible < 1) lphl->FirstVisible = 1; if ((wndPtr->dwStyle & LBS_MULTIPLESEL) != LBS_MULTIPLESEL) { ListBoxSetCurSel(hwnd, lphl->ItemFocused); ListBoxSendNotification(hwnd, LBN_SELCHANGE); } SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); break; case WM_SETFONT: lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); if (lphl == NULL) return 0; if (wParam == 0) lphl->hFont = GetStockObject(SYSTEM_FONT); else lphl->hFont = wParam; if (wParam == 0) break; break; case WM_SETREDRAW: dprintf_listbox(stddeb,"ListBox WM_SETREDRAW hWnd=%04X w=%04X !\n", hwnd, wParam); lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); if (lphl == NULL) return 0; lphl->bRedrawFlag = wParam; break; case WM_PAINT: wndPtr = WIN_FindWndPtr(hwnd); if ((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) == LBS_OWNERDRAWFIXED) { OwnerDrawListBox(hwnd); break; } if ((wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE) == LBS_OWNERDRAWVARIABLE) { OwnerDrawListBox(hwnd); break; } StdDrawListBox(hwnd); break; case WM_SETFOCUS: dprintf_listbox(stddeb,"ListBox WM_SETFOCUS !\n"); lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); break; case WM_KILLFOCUS: dprintf_listbox(stddeb,"ListBox WM_KILLFOCUS !\n"); InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); break; case LB_RESETCONTENT: dprintf_listbox(stddeb,"ListBox LB_RESETCONTENT !\n"); ListBoxResetContent(hwnd); return 0; case LB_DIR: dprintf_listbox(stddeb,"ListBox LB_DIR !\n"); wRet = ListBoxDirectory(hwnd, wParam, (LPSTR)PTR_SEG_TO_LIN(lParam)); InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); return wRet; case LB_ADDSTRING: wRet = ListBoxAddString(hwnd, (LPSTR)PTR_SEG_TO_LIN(lParam)); return wRet; case LB_GETTEXT: dprintf_listbox(stddeb, "LB_GETTEXT wParam=%d\n",wParam); wRet = ListBoxGetText(hwnd, wParam, (LPSTR)PTR_SEG_TO_LIN(lParam), FALSE); return wRet; case LB_INSERTSTRING: wRet = ListBoxInsertString(hwnd, wParam, (LPSTR)PTR_SEG_TO_LIN(lParam)); return wRet; case LB_DELETESTRING: wRet = ListBoxDeleteString(hwnd, wParam); return wRet; case LB_FINDSTRING: wRet = ListBoxFindString(hwnd, wParam, (LPSTR)PTR_SEG_TO_LIN(lParam)); return wRet; case LB_GETCARETINDEX: return wRet; case LB_GETCOUNT: lphl = ListBoxGetStorageHeader(hwnd); return lphl->ItemsCount; case LB_GETCURSEL: lphl = ListBoxGetStorageHeader(hwnd); dprintf_listbox(stddeb,"ListBox LB_GETCURSEL %u !\n", lphl->ItemFocused); return lphl->ItemFocused; case LB_GETHORIZONTALEXTENT: return wRet; case LB_GETITEMDATA: dprintf_listbox(stddeb, "LB_GETITEMDATA wParam=%x\n", wParam); lRet = ListBoxGetText(hwnd, wParam, (LPSTR)PTR_SEG_TO_LIN(lParam), TRUE); return lRet; case LB_GETITEMHEIGHT: ListBoxGetItemRect(hwnd, wParam, &rect); return (rect.bottom - rect.top); case LB_GETITEMRECT: ListBoxGetItemRect(hwnd,wParam,(LPRECT)PTR_SEG_TO_LIN(lParam)); return 0; case LB_GETSEL: wRet = ListBoxGetSel(hwnd, wParam); return wRet; case LB_GETSELCOUNT: lphl = ListBoxGetStorageHeader(hwnd); if (lphl == NULL) return LB_ERR; return lphl->SelCount; case LB_GETSELITEMS: return wRet; case LB_GETTEXTLEN: return wRet; case LB_GETTOPINDEX: lphl = ListBoxGetStorageHeader(hwnd); if (lphl == NULL) return LB_ERR; return lphl->FirstVisible; case LB_SELECTSTRING: return wRet; case LB_SELITEMRANGE: return wRet; case LB_SETCARETINDEX: return wRet; case LB_SETCOLUMNWIDTH: lphl = ListBoxGetStorageHeader(hwnd); if (lphl == NULL) return LB_ERR; lphl->ColumnsWidth = wParam; break; case LB_SETHORIZONTALEXTENT: return wRet; case LB_SETITEMDATA: dprintf_listbox(stddeb, "LB_SETITEMDATA wParam=%x lParam=%lx\n", wParam, lParam); wRet = ListBoxSetItemData(hwnd, wParam, lParam); return wRet; case LB_SETTABSTOPS: lphl = ListBoxGetStorageHeader(hwnd); if (lphl == NULL) return LB_ERR; lphl->FirstVisible = wParam; return 0; case LB_SETCURSEL: dprintf_listbox(stddeb,"ListBox LB_SETCURSEL wParam=%x !\n", wParam); wRet = ListBoxSetCurSel(hwnd, wParam); InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); return wRet; case LB_SETSEL: dprintf_listbox(stddeb,"ListBox LB_SETSEL wParam=%x lParam=%lX !\n", wParam, lParam); wRet = ListBoxSetSel(hwnd, LOWORD(lParam), wParam); InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); return wRet; case LB_SETTOPINDEX: dprintf_listbox(stddeb,"ListBox LB_SETTOPINDEX wParam=%x !\n", wParam); lphl = ListBoxGetStorageHeader(hwnd); lphl->FirstVisible = wParam; SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); break; case LB_SETITEMHEIGHT: dprintf_listbox(stddeb,"ListBox LB_SETITEMHEIGHT wParam=%x lParam=%lX !\n", wParam, lParam); wRet = ListBoxSetItemHeight(hwnd, wParam, lParam); return wRet; default: return DefWindowProc( hwnd, message, wParam, lParam ); } return 0; } LPHEADLIST ListBoxGetWindowAndStorage(HWND hwnd, WND **wndPtr) { WND *Ptr; LPHEADLIST lphl; *(wndPtr) = Ptr = WIN_FindWndPtr(hwnd); lphl = *((LPHEADLIST *)&Ptr->wExtra[1]); return lphl; } LPHEADLIST ListBoxGetStorageHeader(HWND hwnd) { WND *wndPtr; LPHEADLIST lphl; wndPtr = WIN_FindWndPtr(hwnd); lphl = *((LPHEADLIST *)&wndPtr->wExtra[1]); return lphl; } void StdDrawListBox(HWND hwnd) { WND *wndPtr; LPHEADLIST lphl; LPLISTSTRUCT lpls; PAINTSTRUCT ps; HBRUSH hBrush; int OldBkMode; DWORD dwOldTextColor; HDC hdc; RECT rect; int i, h, h2, maxwidth, ipc; h = 0; hdc = BeginPaint( hwnd, &ps ); if (!IsWindowVisible(hwnd)) { EndPaint( hwnd, &ps ); return; } lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); if (lphl == NULL) goto EndOfPaint; if (!lphl->bRedrawFlag) goto EndOfPaint; SelectObject(hdc, lphl->hFont); hBrush = SendMessage(lphl->hWndLogicParent, WM_CTLCOLOR, (WORD)hdc, MAKELONG(hwnd, CTLCOLOR_LISTBOX)); if (hBrush == (HBRUSH)NULL) hBrush = GetStockObject(WHITE_BRUSH); GetClientRect(hwnd, &rect); FillRect(hdc, &rect, hBrush); maxwidth = rect.right; rect.right = lphl->ColumnsWidth; if (lphl->ItemsCount == 0) goto EndOfPaint; lpls = lphl->lpFirst; if (lpls == NULL) goto EndOfPaint; lphl->ItemsVisible = 0; lphl->ItemsPerColumn = ipc = 0; for(i = 1; i <= lphl->ItemsCount; i++) { if (i >= lphl->FirstVisible) { if (lpls == NULL) break; if ((h + lpls->dis.rcItem.bottom - lpls->dis.rcItem.top) > rect.bottom) { if ((wndPtr->dwStyle & LBS_MULTICOLUMN) == LBS_MULTICOLUMN) { lphl->ItemsPerColumn = max(lphl->ItemsPerColumn, ipc); ipc = 0; h = 0; rect.left += lphl->ColumnsWidth; rect.right += lphl->ColumnsWidth; if (rect.left > maxwidth) break; } else break; } h2 = lpls->dis.rcItem.bottom - lpls->dis.rcItem.top; lpls->dis.rcItem.top = h; lpls->dis.rcItem.bottom = h + h2; lpls->dis.rcItem.left = rect.left; lpls->dis.rcItem.right = rect.right; OldBkMode = SetBkMode(hdc, TRANSPARENT); if (lpls->dis.itemState != 0) { dwOldTextColor = SetTextColor(hdc, 0x00FFFFFFL); FillRect(hdc, &lpls->dis.rcItem, GetStockObject(BLACK_BRUSH)); } TextOut(hdc, rect.left + 5, h + 2, (char *)lpls->itemText, strlen((char *)lpls->itemText)); if (lpls->dis.itemState != 0) { SetTextColor(hdc, dwOldTextColor); } SetBkMode(hdc, OldBkMode); if ((lphl->ItemFocused == i - 1) && GetFocus() == hwnd) { DrawFocusRect(hdc, &lpls->dis.rcItem); } h += h2; lphl->ItemsVisible++; ipc++; } if (lpls->lpNext == NULL) goto EndOfPaint; lpls = (LPLISTSTRUCT)lpls->lpNext; } EndOfPaint: EndPaint( hwnd, &ps ); } void OwnerDrawListBox(HWND hwnd) { WND *wndPtr,*ParentWndPtr; LPHEADLIST lphl; LPLISTSTRUCT lpls; PAINTSTRUCT ps; HBRUSH hBrush; DWORD itemData; HDC hdc; RECT rect; int i, h, h2, maxwidth; HANDLE hDrawItemStruct; h = 0; hdc = BeginPaint(hwnd, &ps); if (!IsWindowVisible(hwnd)) { EndPaint( hwnd, &ps ); return; } lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); if (lphl == NULL) goto EndOfPaint; if (!lphl->bRedrawFlag) goto EndOfPaint; hBrush = SendMessage(lphl->hWndLogicParent, WM_CTLCOLOR, (WORD)hdc, MAKELONG(hwnd, CTLCOLOR_LISTBOX)); if (hBrush == (HBRUSH)NULL) hBrush = GetStockObject(WHITE_BRUSH); GetClientRect(hwnd, &rect); FillRect(hdc, &rect, hBrush); maxwidth = rect.right; rect.right = lphl->ColumnsWidth; if (lphl->ItemsCount == 0) goto EndOfPaint; lpls = lphl->lpFirst; if (lpls == NULL) goto EndOfPaint; lphl->ItemsVisible = 0; hDrawItemStruct = USER_HEAP_ALLOC( sizeof(DRAWITEMSTRUCT) ); for (i = 1; i <= lphl->ItemsCount; i++) { if (i >= lphl->FirstVisible) { lpls->dis.hDC = hdc; lpls->dis.hwndItem = hwnd; lpls->dis.CtlType = ODT_LISTBOX; lpls->dis.itemID = i - 1; if ((!lpls->dis.CtlID) && (lphl->hWndLogicParent)) { ParentWndPtr = WIN_FindWndPtr(lphl->hWndLogicParent); lpls->dis.CtlID = ParentWndPtr->wIDmenu; } h2 = lpls->dis.rcItem.bottom - lpls->dis.rcItem.top; lpls->dis.rcItem.top = h; lpls->dis.rcItem.bottom = h + h2; lpls->dis.rcItem.left = rect.left; lpls->dis.rcItem.right = rect.right; lpls->dis.itemAction = ODA_DRAWENTIRE; /* if (lpls->dis.itemState != 0) { lpls->dis.itemAction |= ODA_SELECT; } if (lphl->ItemFocused == i - 1) { lpls->dis.itemAction |= ODA_FOCUS; }*/ dprintf_listbox(stddeb,"LBOX WM_DRAWITEM #%d left=%d top=%d right=%d bottom=%d !\n", i-1, lpls->dis.rcItem.left, lpls->dis.rcItem.top, lpls->dis.rcItem.right, lpls->dis.rcItem.bottom); dprintf_listbox(stddeb,"LBOX WM_DRAWITEM &dis=%lX CtlID=%u !\n", (LONG)&lpls->dis, lpls->dis.CtlID); dprintf_listbox(stddeb,"LBOX WM_DRAWITEM %08lX!\n",lpls->dis.itemData); if (HasStrings(wndPtr)) dprintf_listbox(stddeb," '%s'\n",lpls->itemText); if (HasStrings(wndPtr)) { itemData = lpls->dis.itemData; lpls->dis.itemData = (DWORD)lpls->itemText; } memcpy( USER_HEAP_LIN_ADDR(hDrawItemStruct), &lpls->dis, sizeof(DRAWITEMSTRUCT) ); SendMessage(lphl->hWndLogicParent, WM_DRAWITEM, i-1, (LPARAM)USER_HEAP_SEG_ADDR(hDrawItemStruct)); if (HasStrings(wndPtr)) lpls->dis.itemData = itemData; /* if (lpls->dis.itemState != 0) { InvertRect(hdc, &lpls->dis.rcItem); } */ h += h2; lphl->ItemsVisible++; /* if (h > rect.bottom) goto EndOfPaint;*/ } if (lpls->lpNext == NULL) break; lpls = (LPLISTSTRUCT)lpls->lpNext; } USER_HEAP_FREE( hDrawItemStruct ); EndOfPaint: EndPaint( hwnd, &ps ); } int ListBoxFindMouse(HWND hwnd, int X, int Y) { WND *wndPtr; LPHEADLIST lphl; LPLISTSTRUCT lpls; RECT rect; int i, h, h2, w, w2; lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); if (lphl == NULL) return LB_ERR; if (lphl->ItemsCount == 0) return LB_ERR; lpls = lphl->lpFirst; if (lpls == NULL) return LB_ERR; GetClientRect(hwnd, &rect); h = w2 = 0; w = lphl->ColumnsWidth; for(i = 1; i <= lphl->ItemsCount; i++) { if (i >= lphl->FirstVisible) { h2 = h; h += lpls->dis.rcItem.bottom - lpls->dis.rcItem.top; if ((Y > h2) && (Y < h) && (X > w2) && (X < w)) return(i - 1); if (h > rect.bottom) { if ((wndPtr->dwStyle & LBS_MULTICOLUMN) != LBS_MULTICOLUMN) return LB_ERR; h = 0; w2 = w; w += lphl->ColumnsWidth; if (w2 > rect.right) return LB_ERR; } } if (lpls->lpNext == NULL) return LB_ERR; lpls = (LPLISTSTRUCT)lpls->lpNext; } return(LB_ERR); } int CreateListBoxStruct(HWND hwnd) { WND *wndPtr; LPHEADLIST lphl; wndPtr = WIN_FindWndPtr(hwnd); lphl = (LPHEADLIST)malloc(sizeof(HEADLIST)); lphl->lpFirst = NULL; *((LPHEADLIST *)&wndPtr->wExtra[1]) = lphl; /* HEAD of List */ lphl->ItemsCount = 0; lphl->ItemsVisible = 0; lphl->FirstVisible = 1; lphl->ColumnsVisible = 1; lphl->ItemsPerColumn = 0; lphl->StdItemHeight = 15; lphl->ItemFocused = 0; lphl->PrevFocused = 0; lphl->SelCount = 0; lphl->DrawCtlType = ODT_LISTBOX; lphl->bRedrawFlag = TRUE; #if 0 HeapHandle = GlobalAlloc(GMEM_FIXED, LIST_HEAP_SIZE); HeapBase = GlobalLock(HeapHandle); HEAP_Init(&lphl->Heap, HeapBase, LIST_HEAP_SIZE); #endif return TRUE; } void ListBoxAskMeasure(WND *wndPtr, LPHEADLIST lphl, LPLISTSTRUCT lpls) { MEASUREITEMSTRUCT *lpmeasure; HANDLE hTemp = USER_HEAP_ALLOC( sizeof(MEASUREITEMSTRUCT) ); lpmeasure = (MEASUREITEMSTRUCT *) USER_HEAP_LIN_ADDR(hTemp); if (lpmeasure == NULL) { fprintf(stderr,"ListBoxAskMeasure() // Bad allocation of Measure struct !\n"); return; } lpmeasure->CtlType = ODT_LISTBOX; lpmeasure->CtlID = wndPtr->wIDmenu; lpmeasure->itemID = lpls->dis.itemID; lpmeasure->itemWidth = wndPtr->rectWindow.right - wndPtr->rectWindow.left; lpmeasure->itemHeight = 0; if (HasStrings(wndPtr)) lpmeasure->itemData = (DWORD)lpls->itemText; else lpmeasure->itemData = lpls->dis.itemData; SendMessage(lphl->hWndLogicParent, WM_MEASUREITEM, 0, USER_HEAP_SEG_ADDR(hTemp)); lpls->dis.rcItem.right = lpls->dis.rcItem.left + lpmeasure->itemWidth; lpls->dis.rcItem.bottom = lpls->dis.rcItem.top + lpmeasure->itemHeight; USER_HEAP_FREE(hTemp); } int ListBoxAddString(HWND hwnd, LPSTR newstr) { LPHEADLIST lphl; UINT pos = (UINT) -1; WND *wndPtr; lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); if (lphl == NULL) return LB_ERR; if (HasStrings(wndPtr) && (wndPtr->dwStyle & LBS_SORT)) { LPLISTSTRUCT lpls = lphl->lpFirst; for (pos = 0; lpls; lpls = lpls->lpNext, pos++) if (strcmp(lpls->itemText, newstr) >= 0) break; } return ListBoxInsertString(hwnd, pos, newstr); } int ListBoxInsertString(HWND hwnd, UINT uIndex, LPSTR newstr) { WND *wndPtr; LPHEADLIST lphl; LPLISTSTRUCT *lppls, lplsnew; HANDLE hItem; HANDLE hStr; LPSTR str; UINT Count; dprintf_listbox(stddeb,"ListBoxInsertString(%04X, %d, %p);\n", hwnd, uIndex, newstr); lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); if (lphl == NULL) return LB_ERR; if (uIndex == (UINT)-1) uIndex = lphl->ItemsCount; if (uIndex > lphl->ItemsCount) return LB_ERR; lppls = (LPLISTSTRUCT *) &lphl->lpFirst; for(Count = 0; Count < uIndex; Count++) { if (*lppls == NULL) return LB_ERR; lppls = (LPLISTSTRUCT *) &(*lppls)->lpNext; } hItem = LIST_HEAP_ALLOC(lphl, GMEM_MOVEABLE, sizeof(LISTSTRUCT)); lplsnew = (LPLISTSTRUCT) LIST_HEAP_ADDR(lphl, hItem); if (lplsnew == NULL) { printf("ListBoxInsertString() // Bad allocation of new item !\n"); return LB_ERRSPACE; } ListBoxDefaultItem(hwnd, wndPtr, lphl, lplsnew); lplsnew->hMem = hItem; lplsnew->lpNext = *lppls; *lppls = lplsnew; lphl->ItemsCount++; hStr = 0; if (HasStrings(wndPtr)) { hStr = LIST_HEAP_ALLOC(lphl, GMEM_MOVEABLE, strlen(newstr) + 1); str = (LPSTR)LIST_HEAP_ADDR(lphl, hStr); if (str == NULL) return LB_ERRSPACE; strcpy(str, newstr); newstr = str; lplsnew->itemText = str; dprintf_listbox(stddeb,"ListBoxInsertString // LBS_HASSTRINGS after strcpy '%s'\n", str); } else { lplsnew->itemText = NULL; lplsnew->dis.itemData = (DWORD)newstr; } lplsnew->dis.itemID = lphl->ItemsCount; lplsnew->hData = hStr; if (((wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE) == LBS_OWNERDRAWVARIABLE) || ((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) == LBS_OWNERDRAWFIXED)) ListBoxAskMeasure(wndPtr, lphl, lplsnew); SetScrollRange(hwnd, SB_VERT, 1, ListMaxFirstVisible(lphl), (lphl->FirstVisible != 1 && lphl->bRedrawFlag)); if (lphl->ItemsPerColumn != 0) SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible / lphl->ItemsPerColumn + 1, (lphl->FirstVisible != 1 && lphl->bRedrawFlag)); if ((lphl->FirstVisible <= uIndex) && ((lphl->FirstVisible + lphl->ItemsVisible) >= uIndex)) { InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); } dprintf_listbox(stddeb,"ListBoxInsertString // count=%d\n", lphl->ItemsCount); return uIndex; } int ListBoxGetText(HWND hwnd, UINT uIndex, LPSTR OutStr, BOOL bItemData) { WND *wndPtr; LPHEADLIST lphl; LPLISTSTRUCT lpls; UINT Count; if ((!OutStr)&&(!bItemData)) fprintf(stderr, "ListBoxGetText // OutStr==NULL\n"); if (!bItemData) *OutStr=0; lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); if (lphl == NULL) return LB_ERR; if (uIndex >= lphl->ItemsCount) return LB_ERR; lpls = lphl->lpFirst; if (lpls == NULL) return LB_ERR; if (uIndex > lphl->ItemsCount) return LB_ERR; for(Count = 0; Count < uIndex; Count++) { if (lpls->lpNext == NULL) return LB_ERR; lpls = (LPLISTSTRUCT)lpls->lpNext; } if (bItemData) return lpls->dis.itemData; if (!(HasStrings(wndPtr)) ) { *((long *)OutStr) = lpls->dis.itemData; return 4; } strcpy(OutStr, lpls->itemText); return strlen(OutStr); } int ListBoxSetItemData(HWND hwnd, UINT uIndex, DWORD ItemData) { WND *wndPtr; LPHEADLIST lphl; LPLISTSTRUCT lpls; UINT Count; lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); if (lphl == NULL) return LB_ERR; if (uIndex >= lphl->ItemsCount) return LB_ERR; lpls = lphl->lpFirst; if (lpls == NULL) return LB_ERR; if (uIndex > lphl->ItemsCount) return LB_ERR; for(Count = 0; Count < uIndex; Count++) { if (lpls->lpNext == NULL) return LB_ERR; lpls = (LPLISTSTRUCT)lpls->lpNext; } lpls->dis.itemData = ItemData; return 1; } int ListBoxDeleteString(HWND hwnd, UINT uIndex) { WND *wndPtr; LPHEADLIST lphl; LPLISTSTRUCT lpls, lpls2; UINT Count; lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); if (lphl == NULL) return LB_ERR; if (uIndex >= lphl->ItemsCount) return LB_ERR; lpls = lphl->lpFirst; if (lpls == NULL) return LB_ERR; if (uIndex > lphl->ItemsCount) return LB_ERR; if( uIndex == 0 ) lphl->lpFirst = lpls->lpNext; else { for(Count = 0; Count < uIndex; Count++) { if (lpls->lpNext == NULL) return LB_ERR; lpls2 = lpls; lpls = (LPLISTSTRUCT)lpls->lpNext; } lpls2->lpNext = (LPLISTSTRUCT)lpls->lpNext; } lphl->ItemsCount--; if (lpls->hData != 0) LIST_HEAP_FREE(lphl, lpls->hData); if (lpls->hMem != 0) LIST_HEAP_FREE(lphl, lpls->hMem); SetScrollRange(hwnd, SB_VERT, 1, ListMaxFirstVisible(lphl), TRUE); if (lphl->ItemsPerColumn != 0) SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible / lphl->ItemsPerColumn + 1, TRUE); if ((lphl->FirstVisible <= uIndex) && ((lphl->FirstVisible + lphl->ItemsVisible) >= uIndex)) { InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); } return lphl->ItemsCount; } int ListBoxFindString(HWND hwnd, UINT nFirst, LPSTR MatchStr) { WND *wndPtr; LPHEADLIST lphl; LPLISTSTRUCT lpls; UINT Count; lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); if (lphl == NULL) return LB_ERR; if (nFirst > lphl->ItemsCount) return LB_ERR; lpls = lphl->lpFirst; if (lpls == NULL) return LB_ERR; Count = 0; while(lpls != NULL) { if (HasStrings(wndPtr)) { if (strcmp(lpls->itemText, MatchStr) == 0) return Count; } else { if (lpls->dis.itemData == (DWORD)MatchStr) return Count; } lpls = (LPLISTSTRUCT)lpls->lpNext; Count++; } return LB_ERR; } int ListBoxResetContent(HWND hwnd) { WND *wndPtr; LPHEADLIST lphl; LPLISTSTRUCT lpls, lpls2; UINT i; lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); if (lphl == NULL) return LB_ERR; lpls = lphl->lpFirst; if (lpls == NULL) return LB_ERR; dprintf_listbox(stddeb, "ListBoxResetContent // ItemCount = %d\n", lphl->ItemsCount); for(i = 0; i <= lphl->ItemsCount; i++) { lpls2 = lpls; lpls = (LPLISTSTRUCT)lpls->lpNext; if (i != 0) { dprintf_listbox(stddeb,"ResetContent #%u\n", i); if (lpls2->hData != 0 && lpls2->hData != lpls2->hMem) LIST_HEAP_FREE(lphl, lpls2->hData); if (lpls2->hMem != 0) LIST_HEAP_FREE(lphl, lpls2->hMem); } if (lpls == NULL) break; } lphl->lpFirst = NULL; lphl->FirstVisible = 1; lphl->ItemsCount = 0; lphl->ItemFocused = -1; lphl->PrevFocused = -1; SetScrollRange(hwnd, SB_VERT, 1, ListMaxFirstVisible(lphl), TRUE); if (lphl->ItemsPerColumn != 0) SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible / lphl->ItemsPerColumn + 1, TRUE); InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); return TRUE; } int ListBoxSetCurSel(HWND hwnd, WORD wIndex) { WND *wndPtr; LPHEADLIST lphl; LPLISTSTRUCT lpls, lpls2; UINT i; lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); if (lphl == NULL) return LB_ERR; if( (wIndex != (WORD)(-1)) && (wIndex > lphl->ItemsCount) ) return LB_ERR; lphl->ItemFocused = LB_ERR; if (wIndex >= lphl->ItemsCount) return LB_ERR; lpls = lphl->lpFirst; if (lpls == NULL) return LB_ERR; for(i = 0; i < lphl->ItemsCount; i++) { lpls2 = lpls; lpls = (LPLISTSTRUCT)lpls->lpNext; if (i == wIndex) lpls2->dis.itemState = 1; else if (lpls2->dis.itemState != 0) lpls2->dis.itemState = 0; if (lpls == NULL) break; } lphl->ItemFocused = wIndex; return wIndex; } int ListBoxSetSel(HWND hwnd, WORD wIndex, WORD state) { LPHEADLIST lphl; LPLISTSTRUCT lpls, lpls2; UINT i; lphl = ListBoxGetStorageHeader(hwnd); if (lphl == NULL) return LB_ERR; if (wIndex >= lphl->ItemsCount) return LB_ERR; lpls = lphl->lpFirst; if (lpls == NULL) return LB_ERR; for(i = 0; i < lphl->ItemsCount; i++) { lpls2 = lpls; lpls = (LPLISTSTRUCT)lpls->lpNext; if ((i == wIndex) || (wIndex == (WORD)-1)) { lpls2->dis.itemState = state; break; } if (lpls == NULL) break; } return LB_ERR; } int ListBoxGetSel(HWND hwnd, WORD wIndex) { LPHEADLIST lphl; LPLISTSTRUCT lpls, lpls2; UINT i; lphl = ListBoxGetStorageHeader(hwnd); if (lphl == NULL) return LB_ERR; if (wIndex >= lphl->ItemsCount) return LB_ERR; lpls = lphl->lpFirst; if (lpls == NULL) return LB_ERR; for(i = 0; i < lphl->ItemsCount; i++) { lpls2 = lpls; lpls = (LPLISTSTRUCT)lpls->lpNext; if (i == wIndex) { return lpls2->dis.itemState; } if (lpls == NULL) break; } return LB_ERR; } int ListBoxDirectory(HWND hwnd, UINT attrib, LPSTR filespec) { struct dosdirent *dp, *dp_old; int x, wRet = LB_OKAY; BOOL OldFlag; char temp[256]; LPHEADLIST lphl; int drive; 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; } if( !strchr( filespec, '\\' ) ) DOS_SetDefaultDrive( drive ); else { int i; strcpy( temp, filespec ); for( i=0; ibRedrawFlag; lphl->bRedrawFlag = FALSE; 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, ".")) { sprintf(temp, "[%s]", dp->filename); if ( (wRet = ListBoxAddString(hwnd, temp)) == LB_ERR) break; } } else { if (attrib & DDL_EXCLUSIVE) { if (attrib & (DDL_READWRITE | DDL_READONLY | DDL_HIDDEN | DDL_SYSTEM) ) if ( (wRet = ListBoxAddString(hwnd, dp->filename)) == LB_ERR) break; } else { if ( (wRet = ListBoxAddString(hwnd, dp->filename)) == LB_ERR) break; } } } DOS_closedir(dp_old); if (attrib & DDL_DRIVES) { for (x=0;x!=MAX_DOS_DRIVES;x++) { if (DOS_ValidDrive(x)) { sprintf(temp, "[-%c-]", 'a'+x); if((wRet = ListBoxInsertString(hwnd, (UINT)-1, temp)) == LB_ERR) break; } } } lphl->bRedrawFlag = OldFlag; if (OldFlag) { InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); } dprintf_listbox(stddeb,"End of ListBoxDirectory !\n"); return 1; /* FIXME: Should be 0 if "filespec" is invalid */ } int ListBoxGetItemRect(HWND hwnd, WORD wIndex, LPRECT lprect) { LPHEADLIST lphl; LPLISTSTRUCT lpls, lpls2; UINT i; lphl = ListBoxGetStorageHeader(hwnd); if (lphl == NULL) return LB_ERR; if (wIndex > lphl->ItemsCount) return LB_ERR; lpls = lphl->lpFirst; if (lpls == NULL) return LB_ERR; for(i = 0; i < lphl->ItemsCount; i++) { lpls2 = lpls; lpls = (LPLISTSTRUCT)lpls->lpNext; if (i == wIndex) { *(lprect) = lpls2->dis.rcItem; break; } if (lpls == NULL) break; } return LB_ERR; } int ListBoxSetItemHeight(HWND hwnd, WORD wIndex, long height) { LPHEADLIST lphl; LPLISTSTRUCT lpls, lpls2; UINT i; lphl = ListBoxGetStorageHeader(hwnd); if (lphl == NULL) return LB_ERR; if (wIndex > lphl->ItemsCount) return LB_ERR; lpls = lphl->lpFirst; if (lpls == NULL) return LB_ERR; for(i = 0; i < lphl->ItemsCount; i++) { lpls2 = lpls; lpls = (LPLISTSTRUCT)lpls->lpNext; if (i == wIndex) { lpls2->dis.rcItem.bottom = lpls2->dis.rcItem.top + (short)height; InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); break; } if (lpls == NULL) break; } return LB_ERR; } int ListBoxDefaultItem(HWND hwnd, WND *wndPtr, LPHEADLIST lphl, LPLISTSTRUCT lpls) { RECT rect; if (wndPtr == NULL || lphl == NULL || lpls == NULL) { fprintf(stderr,"ListBoxDefaultItem() // Bad Pointers !\n"); return FALSE; } GetClientRect(hwnd, &rect); SetRect(&lpls->dis.rcItem, 0, 0, rect.right, lphl->StdItemHeight); lpls->dis.CtlType = lphl->DrawCtlType; lpls->dis.CtlID = wndPtr->wIDmenu; lpls->dis.itemID = 0; lpls->dis.itemAction = 0; lpls->dis.itemState = 0; lpls->dis.hwndItem = hwnd; lpls->dis.hDC = 0; lpls->dis.itemData = 0; return TRUE; } int ListBoxFindNextMatch(HWND hwnd, WORD wChar) { WND *wndPtr; LPHEADLIST lphl; LPLISTSTRUCT lpls; UINT Count; lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); if (lphl == NULL) return LB_ERR; lpls = lphl->lpFirst; if (lpls == NULL) return LB_ERR; if (wChar < ' ') return LB_ERR; if (((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) == LBS_OWNERDRAWFIXED) || ((wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE) == LBS_OWNERDRAWVARIABLE)) { if ((wndPtr->dwStyle & LBS_HASSTRINGS) != LBS_HASSTRINGS) { return LB_ERR; } } Count = 0; while(lpls != NULL) { if (Count > lphl->ItemFocused) { if (*(lpls->itemText) == (char)wChar) { lphl->FirstVisible = Count - lphl->ItemsVisible / 2; if (lphl->FirstVisible < 1) lphl->FirstVisible = 1; if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) { lphl->ItemFocused = Count; } else { ListBoxSetCurSel(hwnd, Count); } SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); return Count; } } lpls = (LPLISTSTRUCT)lpls->lpNext; Count++; } Count = 0; lpls = lphl->lpFirst; while(lpls != NULL) { if (*(lpls->itemText) == (char)wChar) { if (Count == lphl->ItemFocused) return LB_ERR; lphl->FirstVisible = Count - lphl->ItemsVisible / 2; if (lphl->FirstVisible < 1) lphl->FirstVisible = 1; if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) { lphl->ItemFocused = Count; } else { ListBoxSetCurSel(hwnd, Count); } SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); return Count; } lpls = (LPLISTSTRUCT)lpls->lpNext; Count++; } return LB_ERR; } /************************************************************************ * 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(hwnd, lphl->ItemFocused, (LPSTR)s, FALSE); 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) hWnd = GetDlgItem(hDlg, nIDLBox); else hWnd = 0; if (hWnd) ListBoxResetContent(hWnd); if (hWnd) ret=ListBoxDirectory(hWnd, wType, lpPathSpec); else ret=0; if (nIDStat) { int drive; char temp[255]; drive = DOS_GetDefaultDrive(); strcpy( temp+3, DOS_GetCurrentDir(drive) ); if( temp[3] == '\\' ) { temp[1] = 'A'+drive; temp[2] = ':'; SendDlgItemMessage(hDlg, nIDStat, WM_SETTEXT, 0, (LONG)(temp+1)); } else { temp[0] = 'A'+drive; temp[1] = ':'; temp[2] = '\\'; SendDlgItemMessage(hDlg, nIDStat, WM_SETTEXT, 0, (LONG) temp ); } } return ret; } /* get the maximum value of lphl->FirstVisible */ int ListMaxFirstVisible(LPHEADLIST lphl) { int m = lphl->ItemsCount-lphl->ItemsVisible+1; return (m < 1) ? 1 : m; } /* Send notification "code" as part of a WM_COMMAND-message if hwnd has the LBS_NOTIFY style */ void ListBoxSendNotification(HWND hwnd, WORD code) { WND *wndPtr; LPHEADLIST lphl; lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); if( wndPtr && ( (wndPtr->dwStyle && LBS_NOTIFY) != 0) ) SendMessage(lphl->hWndLogicParent, WM_COMMAND, wndPtr->wIDmenu, MAKELONG(hwnd, code)); }