| /* |
| * Interface code to listbox widgets |
| * |
| * Copyright Martin Ayotte, 1993 |
| * |
| */ |
| |
| /* |
| #define DEBUG_LISTBOX |
| */ |
| |
| static char Copyright[] = "Copyright Martin Ayotte, 1993"; |
| |
| #include <stdio.h> |
| #include <sys/types.h> |
| #include <sys/stat.h> |
| #include <dirent.h> |
| #include "windows.h" |
| #include "user.h" |
| #include "heap.h" |
| #include "win.h" |
| #include "wine.h" |
| #include "listbox.h" |
| #include "scroll.h" |
| #include "int21.h" |
| #include "prototypes.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); |
| int ListBoxAddString(HWND hwnd, LPSTR newstr); |
| int ListBoxInsertString(HWND hwnd, UINT uIndex, LPSTR newstr); |
| int ListBoxGetText(HWND hwnd, UINT uIndex, LPSTR OutStr); |
| 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); |
| |
| |
| /*********************************************************************** |
| * ListBoxWndProc |
| */ |
| LONG ListBoxWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) |
| { |
| WND *wndPtr; |
| LPHEADLIST lphl; |
| WORD wRet; |
| RECT rect; |
| int y; |
| CREATESTRUCT *createStruct; |
| static RECT rectsel; |
| switch(message) |
| { |
| case WM_CREATE: |
| CreateListBoxStruct(hwnd); |
| lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); |
| #ifdef DEBUG_LISTBOX |
| printf("ListBox WM_CREATE %lX !\n", lphl); |
| #endif |
| createStruct = (CREATESTRUCT *)lParam; |
| if (HIWORD(createStruct->lpCreateParams) != 0) |
| lphl->hWndLogicParent = (HWND)HIWORD(createStruct->lpCreateParams); |
| else |
| lphl->hWndLogicParent = GetParent(hwnd); |
| lphl->ColumnsWidth = wndPtr->rectClient.right - wndPtr->rectClient.left; |
| if (wndPtr->dwStyle & WS_VSCROLL) { |
| SetScrollRange(hwnd, SB_VERT, 1, lphl->ItemsCount, TRUE); |
| ShowScrollBar(hwnd, SB_VERT, FALSE); |
| } |
| if (wndPtr->dwStyle & WS_HSCROLL) { |
| SetScrollRange(hwnd, SB_HORZ, 1, 1, TRUE); |
| ShowScrollBar(hwnd, SB_HORZ, FALSE); |
| } |
| return 0; |
| case WM_DESTROY: |
| lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); |
| if (lphl == 0) return 0; |
| ListBoxResetContent(hwnd); |
| free(lphl); |
| *((LPHEADLIST *)&wndPtr->wExtra[1]) = 0; |
| #ifdef DEBUG_LISTBOX |
| printf("ListBox WM_DESTROY %lX !\n", lphl); |
| #endif |
| return 0; |
| |
| case WM_VSCROLL: |
| 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 < lphl->ItemsCount) |
| lphl->FirstVisible++; |
| break; |
| case SB_PAGEUP: |
| if (lphl->FirstVisible > 1) |
| lphl->FirstVisible -= lphl->ItemsVisible; |
| break; |
| case SB_PAGEDOWN: |
| if (lphl->FirstVisible < lphl->ItemsCount) |
| lphl->FirstVisible += lphl->ItemsVisible; |
| break; |
| case SB_THUMBTRACK: |
| lphl->FirstVisible = LOWORD(lParam); |
| break; |
| } |
| if (lphl->FirstVisible < 1) lphl->FirstVisible = 1; |
| if (lphl->FirstVisible > lphl->ItemsCount) |
| lphl->FirstVisible = lphl->ItemsCount; |
| if (y != lphl->FirstVisible) { |
| SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); |
| InvalidateRect(hwnd, NULL, TRUE); |
| UpdateWindow(hwnd); |
| } |
| return 0; |
| |
| case WM_HSCROLL: |
| 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 < lphl->ItemsCount) |
| 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 < lphl->ItemsCount && |
| 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 > lphl->ItemsCount) |
| lphl->FirstVisible = lphl->ItemsCount; |
| 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 ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) { |
| lphl->ItemFocused = y; |
| wRet = ListBoxGetSel(hwnd, y); |
| ListBoxSetSel(hwnd, y, !wRet); |
| } |
| else { |
| ListBoxSetCurSel(hwnd, y); |
| } |
| 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) |
| SendMessage(lphl->hWndLogicParent, WM_COMMAND, wndPtr->wIDmenu, |
| MAKELONG(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)); |
| printf("ListBox Send LBN_DBLCLK !\n"); |
| return 0; |
| case WM_MOUSEMOVE: |
| if ((wParam & MK_LBUTTON) != 0) { |
| y = HIWORD(lParam); |
| if (y < 4) { |
| lphl = ListBoxGetStorageHeader(hwnd); |
| if (lphl->FirstVisible > 1) { |
| lphl->FirstVisible--; |
| if (wndPtr->dwStyle & WS_VSCROLL) |
| SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); |
| InvalidateRect(hwnd, NULL, TRUE); |
| UpdateWindow(hwnd); |
| break; |
| } |
| } |
| GetClientRect(hwnd, &rect); |
| if (y > (rect.bottom - 4)) { |
| lphl = ListBoxGetStorageHeader(hwnd); |
| if (lphl->FirstVisible < lphl->ItemsCount) { |
| lphl->FirstVisible++; |
| if (wndPtr->dwStyle & WS_VSCROLL) |
| 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; |
| } |
| 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_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); |
| } |
| if (wndPtr->dwStyle & WS_VSCROLL) |
| SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); |
| InvalidateRect(hwnd, NULL, TRUE); |
| UpdateWindow(hwnd); |
| 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 LB_RESETCONTENT: |
| printf("ListBox LB_RESETCONTENT !\n"); |
| ListBoxResetContent(hwnd); |
| return 0; |
| case LB_DIR: |
| printf("ListBox LB_DIR !\n"); |
| wRet = ListBoxDirectory(hwnd, wParam, (LPSTR)lParam); |
| InvalidateRect(hwnd, NULL, TRUE); |
| UpdateWindow(hwnd); |
| return wRet; |
| case LB_ADDSTRING: |
| wRet = ListBoxAddString(hwnd, (LPSTR)lParam); |
| return wRet; |
| case LB_GETTEXT: |
| wRet = ListBoxGetText(hwnd, wParam, (LPSTR)lParam); |
| #ifdef DEBUG_LISTBOX |
| printf("ListBox LB_GETTEXT #%u '%s' !\n", wParam, (LPSTR)lParam); |
| #endif |
| return wRet; |
| case LB_INSERTSTRING: |
| wRet = ListBoxInsertString(hwnd, wParam, (LPSTR)lParam); |
| return wRet; |
| case LB_DELETESTRING: |
| printf("ListBox LB_DELETESTRING #%u !\n", wParam); |
| wRet = ListBoxDeleteString(hwnd, wParam); |
| return wRet; |
| case LB_FINDSTRING: |
| wRet = ListBoxFindString(hwnd, wParam, (LPSTR)lParam); |
| return wRet; |
| case LB_GETCARETINDEX: |
| return wRet; |
| case LB_GETCOUNT: |
| lphl = ListBoxGetStorageHeader(hwnd); |
| return lphl->ItemsCount; |
| case LB_GETCURSEL: |
| lphl = ListBoxGetStorageHeader(hwnd); |
| printf("ListBox LB_GETCURSEL %u !\n", lphl->ItemFocused); |
| return lphl->ItemFocused; |
| case LB_GETHORIZONTALEXTENT: |
| return wRet; |
| case LB_GETITEMDATA: |
| return wRet; |
| case LB_GETITEMHEIGHT: |
| return wRet; |
| case LB_GETITEMRECT: |
| return wRet; |
| case LB_GETSEL: |
| wRet = ListBoxGetSel(hwnd, wParam); |
| return wRet; |
| case LB_GETSELCOUNT: |
| return wRet; |
| case LB_GETSELITEMS: |
| return wRet; |
| case LB_GETTEXTLEN: |
| return wRet; |
| case LB_GETTOPINDEX: |
| return wRet; |
| case LB_SELECTSTRING: |
| return wRet; |
| case LB_SELITEMRANGE: |
| return wRet; |
| case LB_SETCARETINDEX: |
| return wRet; |
| case LB_SETCOLUMNWIDTH: |
| lphl = ListBoxGetStorageHeader(hwnd); |
| lphl->ColumnsWidth = wParam; |
| break; |
| case LB_SETHORIZONTALEXTENT: |
| return wRet; |
| case LB_SETITEMDATA: |
| return wRet; |
| case LB_SETTABSTOPS: |
| return wRet; |
| case LB_SETCURSEL: |
| #ifdef DEBUG_LISTBOX |
| printf("ListBox LB_SETCURSEL wParam=%x !\n", wParam); |
| #endif |
| wRet = ListBoxSetCurSel(hwnd, wParam); |
| InvalidateRect(hwnd, NULL, TRUE); |
| UpdateWindow(hwnd); |
| return wRet; |
| case LB_SETSEL: |
| printf("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: |
| printf("ListBox LB_SETTOPINDEX wParam=%x !\n", wParam); |
| lphl = ListBoxGetStorageHeader(hwnd); |
| lphl->FirstVisible = wParam; |
| if (wndPtr->dwStyle & WS_VSCROLL) |
| SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); |
| InvalidateRect(hwnd, NULL, TRUE); |
| UpdateWindow(hwnd); |
| break; |
| case LB_SETITEMHEIGHT: |
| #ifdef DEBUG_LISTBOX |
| printf("ListBox LB_SETITEMHEIGHT wParam=%x lParam=%lX !\n", wParam, lParam); |
| #endif |
| 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; |
| HWND hWndParent; |
| HDC hdc; |
| RECT rect; |
| UINT i, h, h2, maxwidth, ipc; |
| char C[128]; |
| h = 0; |
| hdc = BeginPaint( hwnd, &ps ); |
| if (!IsWindowVisible(hwnd)) { |
| EndPaint( hwnd, &ps ); |
| return; |
| } |
| lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); |
| if (lphl == NULL) 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); |
| /* |
| if (wndPtr->dwStyle & WS_VSCROLL) rect.right -= 16; |
| if (wndPtr->dwStyle & WS_HSCROLL) rect.bottom -= 16; |
| */ |
| 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; |
| TextOut(hdc, rect.left + 5, h + 2, (char *)lpls->dis.itemData, |
| strlen((char *)lpls->dis.itemData)); |
| if (lpls->dis.itemState != 0) { |
| InvertRect(hdc, &lpls->dis.rcItem); |
| } |
| if (lphl->ItemFocused == i - 1) { |
| DrawFocusRect(hdc, &lpls->dis.rcItem); |
| } |
| h += h2; |
| lphl->ItemsVisible++; |
| ipc++; |
| } |
| if (lpls->lpNext == NULL) goto EndOfPaint; |
| lpls = (LPLISTSTRUCT)lpls->lpNext; |
| } |
| EndOfPaint: |
| EndPaint( hwnd, &ps ); |
| if ((lphl->ItemsCount > lphl->ItemsVisible) & |
| (wndPtr->dwStyle & WS_VSCROLL)) { |
| /* |
| InvalidateRect(wndPtr->hWndVScroll, NULL, TRUE); |
| UpdateWindow(wndPtr->hWndVScroll); |
| */ |
| } |
| } |
| |
| |
| |
| void OwnerDrawListBox(HWND hwnd) |
| { |
| WND *wndPtr; |
| LPHEADLIST lphl; |
| LPLISTSTRUCT lpls; |
| PAINTSTRUCT ps; |
| HBRUSH hBrush; |
| HWND hWndParent; |
| HDC hdc; |
| RECT rect; |
| UINT i, h, h2, maxwidth; |
| char C[128]; |
| h = 0; |
| hdc = BeginPaint(hwnd, &ps); |
| if (!IsWindowVisible(hwnd)) { |
| EndPaint( hwnd, &ps ); |
| return; |
| } |
| lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); |
| if (lphl == NULL) 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); |
| if (wndPtr->dwStyle & WS_VSCROLL) rect.right -= 16; |
| if (wndPtr->dwStyle & WS_HSCROLL) rect.bottom -= 16; |
| 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; |
| for (i = 1; i <= lphl->ItemsCount; i++) { |
| if (i >= lphl->FirstVisible) { |
| lpls->dis.hDC = hdc; |
| lpls->dis.itemID = i - 1; |
| 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; |
| } |
| #ifdef DEBUT_LISTBOX |
| printf("LBOX WM_DRAWITEM #%d left=%d top=%d right=%d bottom=%d !\n", |
| i, lpls->dis.rcItem.left, lpls->dis.rcItem.top, |
| lpls->dis.rcItem.right, lpls->dis.rcItem.bottom); |
| printf("LBOX WM_DRAWITEM Parent=%X &dis=%lX CtlID=%u !\n", |
| hWndParent, (LONG)&lpls->dis, lpls->dis.CtlID); |
| printf("LBOX WM_DRAWITEM '%s' !\n", lpls->dis.itemData); |
| #endif |
| SendMessage(lphl->hWndLogicParent, WM_DRAWITEM, i, (LPARAM)&lpls->dis); |
| if (lpls->dis.itemState != 0) { |
| InvertRect(hdc, &lpls->dis.rcItem); |
| } |
| h += h2; |
| lphl->ItemsVisible++; |
| if (h > rect.bottom) goto EndOfPaint; |
| } |
| if (lpls->lpNext == NULL) goto EndOfPaint; |
| lpls = (LPLISTSTRUCT)lpls->lpNext; |
| } |
| EndOfPaint: |
| EndPaint( hwnd, &ps ); |
| if ((lphl->ItemsCount > lphl->ItemsVisible) & |
| (wndPtr->dwStyle & WS_VSCROLL)) { |
| /* |
| InvalidateRect(wndPtr->hWndVScroll, NULL, TRUE); |
| UpdateWindow(wndPtr->hWndVScroll); |
| */ |
| } |
| } |
| |
| |
| |
| int ListBoxFindMouse(HWND hwnd, int X, int Y) |
| { |
| WND *wndPtr; |
| LPHEADLIST lphl; |
| LPLISTSTRUCT lpls; |
| RECT rect; |
| UINT i, h, h2, w, w2; |
| char C[128]; |
| 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); |
| if (wndPtr->dwStyle & WS_VSCROLL) rect.right -= 16; |
| if (wndPtr->dwStyle & WS_HSCROLL) rect.bottom -= 16; |
| 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->StdItemHeight = 15; |
| lphl->DrawCtlType = ODT_LISTBOX; |
| return TRUE; |
| } |
| |
| |
| int ListBoxAddString(HWND hwnd, LPSTR newstr) |
| { |
| WND *wndPtr; |
| LPHEADLIST lphl; |
| LPLISTSTRUCT lpls, lplsnew; |
| HANDLE hTemp; |
| LPSTR str; |
| lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); |
| if (lphl == NULL) return LB_ERR; |
| hTemp = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(LISTSTRUCT)); |
| lplsnew = (LPLISTSTRUCT) USER_HEAP_ADDR(hTemp); |
| lpls = lphl->lpFirst; |
| if (lpls != NULL) { |
| while(lpls->lpNext != NULL) { |
| lpls = (LPLISTSTRUCT)lpls->lpNext; |
| } |
| lpls->lpNext = lplsnew; |
| } |
| else |
| lphl->lpFirst = lplsnew; |
| lphl->ItemsCount++; |
| #ifdef DEBUG_LISTBOX |
| printf("Items Count = %u\n", lphl->ItemsCount); |
| #endif |
| hTemp = 0; |
| if ((wndPtr->dwStyle & LBS_HASSTRINGS) != LBS_HASSTRINGS) { |
| if (((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) != LBS_OWNERDRAWFIXED) && |
| ((wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE) != LBS_OWNERDRAWVARIABLE)) { |
| hTemp = USER_HEAP_ALLOC(GMEM_MOVEABLE, strlen(newstr) + 1); |
| str = (LPSTR)USER_HEAP_ADDR(hTemp); |
| if (str == NULL) return LB_ERRSPACE; |
| strcpy(str, newstr); |
| newstr = str; |
| } |
| } |
| ListBoxDefaultItem(hwnd, wndPtr, lphl, lplsnew); |
| lplsnew->hMem = hTemp; |
| lplsnew->lpNext = NULL; |
| lplsnew->dis.itemID = lphl->ItemsCount; |
| lplsnew->dis.itemData = (DWORD)newstr; |
| lplsnew->hData = hTemp; |
| if (wndPtr->dwStyle & WS_VSCROLL) |
| SetScrollRange(hwnd, SB_VERT, 1, lphl->ItemsCount, |
| (lphl->FirstVisible != 1)); |
| if ((wndPtr->dwStyle & WS_HSCROLL) && lphl->ItemsPerColumn != 0) |
| SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible / |
| lphl->ItemsPerColumn + 1, (lphl->FirstVisible != 1)); |
| if (lphl->FirstVisible >= (lphl->ItemsCount - lphl->ItemsVisible)) { |
| InvalidateRect(hwnd, NULL, TRUE); |
| UpdateWindow(hwnd); |
| } |
| if ((lphl->ItemsCount - lphl->FirstVisible) == lphl->ItemsVisible) { |
| if (wndPtr->dwStyle & WS_VSCROLL) |
| ShowScrollBar(hwnd, SB_VERT, TRUE); |
| if (wndPtr->dwStyle & WS_HSCROLL) |
| ShowScrollBar(hwnd, SB_HORZ, TRUE); |
| } |
| return lphl->ItemsCount; |
| } |
| |
| |
| int ListBoxInsertString(HWND hwnd, UINT uIndex, LPSTR newstr) |
| { |
| WND *wndPtr; |
| LPHEADLIST lphl; |
| LPLISTSTRUCT lpls, lplsnew; |
| HANDLE hTemp; |
| LPSTR str; |
| 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 = 1; Count < uIndex; Count++) { |
| if (lpls->lpNext == NULL) return LB_ERR; |
| lpls = (LPLISTSTRUCT)lpls->lpNext; |
| } |
| hTemp = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(LISTSTRUCT)); |
| lplsnew = (LPLISTSTRUCT) USER_HEAP_ADDR(hTemp); |
| ListBoxDefaultItem(hwnd, wndPtr, lphl, lplsnew); |
| lplsnew->hMem = hTemp; |
| lpls->lpNext = lplsnew; |
| lphl->ItemsCount++; |
| hTemp = 0; |
| if ((wndPtr->dwStyle & LBS_HASSTRINGS) != LBS_HASSTRINGS) { |
| if (((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) != LBS_OWNERDRAWFIXED) && |
| ((wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE) != LBS_OWNERDRAWVARIABLE)) { |
| hTemp = USER_HEAP_ALLOC(GMEM_MOVEABLE, strlen(newstr) + 1); |
| str = (LPSTR)USER_HEAP_ADDR(hTemp); |
| if (str == NULL) return LB_ERRSPACE; |
| strcpy(str, newstr); |
| newstr = str; |
| } |
| } |
| lplsnew->lpNext = NULL; |
| lplsnew->dis.itemID = lphl->ItemsCount; |
| lplsnew->dis.itemData = (DWORD)newstr; |
| lplsnew->hData = hTemp; |
| if (wndPtr->dwStyle & WS_VSCROLL) |
| SetScrollRange(hwnd, SB_VERT, 1, lphl->ItemsCount, |
| (lphl->FirstVisible != 1)); |
| if ((wndPtr->dwStyle & WS_HSCROLL) && lphl->ItemsPerColumn != 0) |
| SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible / |
| lphl->ItemsPerColumn + 1, (lphl->FirstVisible != 1)); |
| if (((lphl->ItemsCount - lphl->FirstVisible) == lphl->ItemsVisible) && |
| (lphl->ItemsVisible != 0)) { |
| if (wndPtr->dwStyle & WS_VSCROLL) |
| ShowScrollBar(hwnd, SB_VERT, TRUE); |
| if (wndPtr->dwStyle & WS_HSCROLL) |
| ShowScrollBar(hwnd, SB_HORZ, TRUE); |
| } |
| if ((lphl->FirstVisible <= uIndex) && |
| ((lphl->FirstVisible + lphl->ItemsVisible) >= uIndex)) { |
| InvalidateRect(hwnd, NULL, TRUE); |
| UpdateWindow(hwnd); |
| } |
| return lphl->ItemsCount; |
| } |
| |
| |
| int ListBoxGetText(HWND hwnd, UINT uIndex, LPSTR OutStr) |
| { |
| 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; |
| } |
| if (((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) == LBS_OWNERDRAWFIXED) || |
| ((wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE) == LBS_OWNERDRAWVARIABLE)) { |
| if ((wndPtr->dwStyle & LBS_HASSTRINGS) != LBS_HASSTRINGS) { |
| *((long *)OutStr) = lpls->dis.itemData; |
| return 4; |
| } |
| } |
| |
| strcpy(OutStr, (char *)lpls->dis.itemData); |
| return strlen(OutStr); |
| } |
| |
| |
| 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; |
| for(Count = 1; 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) USER_HEAP_FREE(lpls->hData); |
| if (lpls->hMem != 0) USER_HEAP_FREE(lpls->hMem); |
| if (wndPtr->dwStyle & WS_VSCROLL) |
| SetScrollRange(hwnd, SB_VERT, 1, lphl->ItemsCount, TRUE); |
| if ((wndPtr->dwStyle & WS_HSCROLL) && lphl->ItemsPerColumn != 0) |
| SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible / |
| lphl->ItemsPerColumn + 1, TRUE); |
| if (lphl->ItemsCount < lphl->ItemsVisible) { |
| if (wndPtr->dwStyle & WS_VSCROLL) |
| ShowScrollBar(hwnd, SB_VERT, FALSE); |
| if (wndPtr->dwStyle & WS_HSCROLL) |
| ShowScrollBar(hwnd, SB_HORZ, FALSE); |
| } |
| 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) |
| { |
| LPHEADLIST lphl; |
| LPLISTSTRUCT lpls; |
| UINT Count; |
| lphl = ListBoxGetStorageHeader(hwnd); |
| 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 (strcmp((char *)lpls->dis.itemData, MatchStr) == 0) 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; |
| for(i = 0; i <= lphl->ItemsCount; i++) { |
| lpls2 = lpls; |
| lpls = (LPLISTSTRUCT)lpls->lpNext; |
| if (i != 0) { |
| #ifdef DEBUG_LISTBOX |
| printf("ResetContent #%u\n", i); |
| #endif |
| if (lpls2->hData != 0) USER_HEAP_FREE(lpls->hData); |
| if (lpls2->hMem != 0) USER_HEAP_FREE(lpls->hMem); |
| } |
| if (lpls == NULL) break; |
| } |
| lphl->lpFirst = NULL; |
| lphl->FirstVisible = 1; |
| lphl->ItemsCount = 0; |
| lphl->ItemFocused = 0; |
| lphl->PrevFocused = 0; |
| if ((wndPtr->dwStyle && LBS_NOTIFY) != 0) |
| SendMessage(wndPtr->hwndParent, WM_COMMAND, |
| wndPtr->wIDmenu, MAKELONG(hwnd, LBN_SELCHANGE)); |
| |
| if (wndPtr->dwStyle & WS_VSCROLL) |
| SetScrollRange(hwnd, SB_VERT, 1, lphl->ItemsCount, TRUE); |
| if ((wndPtr->dwStyle & WS_HSCROLL) && lphl->ItemsPerColumn != 0) |
| SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible / |
| lphl->ItemsPerColumn + 1, TRUE); |
| if (wndPtr->dwStyle & WS_VSCROLL) |
| ShowScrollBar(hwnd, SB_VERT, FALSE); |
| if (wndPtr->dwStyle & WS_HSCROLL) |
| ShowScrollBar(hwnd, SB_HORZ, FALSE); |
| 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; |
| 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; |
| if ((wndPtr->dwStyle && LBS_NOTIFY) != 0) |
| SendMessage(wndPtr->hwndParent, WM_COMMAND, |
| wndPtr->wIDmenu, MAKELONG(hwnd, LBN_SELCHANGE)); |
| return LB_ERR; |
| } |
| |
| |
| |
| 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; |
| struct stat st; |
| int x, wRet; |
| char temp[256]; |
| |
| fprintf(stderr,"ListBoxDirectory: %s, %4x\n",filespec,attrib); |
| |
| |
| if ((dp = (struct dosdirent *)DOS_opendir(filespec)) ==NULL) |
| return 0; |
| |
| while (1) |
| { |
| dp = (struct dosdirent *)DOS_readdir(dp); |
| if (!dp->inuse) |
| break; |
| |
| if (dp->attribute & 0x08) |
| { |
| if (attrib & DDL_DIRECTORY) { |
| 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); |
| |
| if (attrib & DDL_DRIVES) |
| { |
| for (x=0;x!=MAX_DOS_DRIVES;x++) |
| { |
| if (DOS_ValidDrive(x)) |
| { |
| sprintf(temp, "[-%c-]", 'A'+x); |
| if ( (wRet = ListBoxAddString(hwnd, temp)) == LB_ERR) |
| break; |
| } |
| } |
| } |
| |
| return wRet; |
| } |
| |
| |
| 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; |
| 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; |
| } |
| |
| |
| |
| 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 (*((char *)lpls->dis.itemData) == (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 (*((char *)lpls->dis.itemData) == (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; |
| } |
| |
| |