/* * Interface code to listbox widgets * * Copyright Martin Ayotte, 1993 * */ /* #define DEBUG_LISTBOX */ static char Copyright[] = "Copyright Martin Ayotte, 1993"; #include <X11/Intrinsic.h> #include <X11/StringDefs.h> #include "windows.h" #include "user.h" #include "heap.h" #include "win.h" #include "listbox.h" #include "scroll.h" #include "dirent.h" #include <sys/stat.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); 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); void LISTBOX_CreateListBox(LPSTR className, LPSTR listboxLabel, HWND hwnd) { WND *wndPtr = WIN_FindWndPtr(hwnd); WND *parentPtr = WIN_FindWndPtr(wndPtr->hwndParent); DWORD style; char widgetName[15]; #ifdef DEBUG_LISTBOX printf("listbox: label = %s, x = %d, y = %d\n", listboxLabel, wndPtr->rectClient.left, wndPtr->rectClient.top); printf(" width = %d, height = %d\n", wndPtr->rectClient.right - wndPtr->rectClient.left, wndPtr->rectClient.bottom - wndPtr->rectClient.top); #endif if (!wndPtr) return; style = wndPtr->dwStyle & 0x0000FFFF; /* if ((style & LBS_NOTIFY) == LBS_NOTIFY) if ((style & LBS_SORT) == LBS_SORT) */ sprintf(widgetName, "%s%d", className, wndPtr->wIDmenu); wndPtr->winWidget = XtVaCreateManagedWidget(widgetName, compositeWidgetClass, parentPtr->winWidget, XtNx, wndPtr->rectClient.left, XtNy, wndPtr->rectClient.top, XtNwidth, wndPtr->rectClient.right - wndPtr->rectClient.left, XtNheight, wndPtr->rectClient.bottom - wndPtr->rectClient.top, NULL ); GlobalUnlock(hwnd); GlobalUnlock(wndPtr->hwndParent); } /*********************************************************************** * WIDGETS_ListBoxWndProc */ LONG LISTBOX_ListBoxWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) { WND *wndPtr; LPHEADLIST lphl; WORD wRet; RECT rect; int y; int width, height; CREATESTRUCT *createStruct; static RECT rectsel; switch(message) { case WM_CREATE: CreateListBoxStruct(hwnd); lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); createStruct = (CREATESTRUCT *)lParam; if (HIWORD(createStruct->lpCreateParams) != 0) lphl->hWndLogicParent = (HWND)HIWORD(createStruct->lpCreateParams); else lphl->hWndLogicParent = GetParent(hwnd); width = wndPtr->rectClient.right - wndPtr->rectClient.left; height = wndPtr->rectClient.bottom - wndPtr->rectClient.top; lphl->hWndScroll = CreateWindow("SCROLLBAR", "", WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | SBS_VERT, width - 17, 0, 16, height, hwnd, 1, wndPtr->hInstance, NULL); ShowWindow(lphl->hWndScroll, SW_HIDE); SetScrollRange(lphl->hWndScroll, WM_VSCROLL, 1, lphl->ItemsCount, TRUE); return 0; case WM_DESTROY: lphl = ListBoxGetStorageHeader(hwnd); ListBoxResetContent(hwnd); DestroyWindow(lphl->hWndScroll); free(lphl); printf("ListBox WM_DESTROY !\n"); 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(lphl->hWndScroll, WM_VSCROLL, lphl->FirstVisible, TRUE); InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); } return 0; case WM_LBUTTONDOWN: lphl = ListBoxGetStorageHeader(hwnd); if (lphl == NULL) return 0; lphl->PrevSelected = lphl->ItemSelected; wRet = ListBoxFindMouse(hwnd, LOWORD(lParam), HIWORD(lParam)); ListBoxSetCurSel(hwnd, wRet); ListBoxGetItemRect(hwnd, wRet, &rectsel); InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); return 0; case WM_LBUTTONUP: lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); if (lphl == NULL) return 0; if (lphl->PrevSelected != lphl->ItemSelected) 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_KEYDOWN: printf("ListBox WM_KEYDOWN wParam %X!\n", wParam); ListBoxFindNextMatch(hwnd, 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_MOUSEMOVE: if ((wParam & MK_LBUTTON) != 0) { y = HIWORD(lParam); if (y < 4) { lphl = ListBoxGetStorageHeader(hwnd); if (lphl->FirstVisible > 1) { lphl->FirstVisible--; SetScrollPos(lphl->hWndScroll, WM_VSCROLL, 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++; SetScrollPos(lphl->hWndScroll, WM_VSCROLL, 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)); ListBoxSetCurSel(hwnd, wRet); ListBoxGetItemRect(hwnd, wRet, &rectsel); InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(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); printf("ListBox LB_GETTEXT #%u '%s' !\n", wParam, (LPSTR)lParam); 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->ItemSelected); if (lphl->ItemSelected == 0) return LB_ERR; return lphl->ItemSelected; case LB_GETHORIZONTALEXTENT: return wRet; case LB_GETITEMDATA: return wRet; case LB_GETITEMHEIGHT: return wRet; case LB_GETITEMRECT: return wRet; case LB_GETSEL: 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: return wRet; 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, 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; SetScrollPos(lphl->hWndScroll, WM_VSCROLL, 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); InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); 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) { LPHEADLIST lphl; LPLISTSTRUCT lpls; PAINTSTRUCT ps; HBRUSH hBrush; HWND hWndParent; HDC hdc; RECT rect; UINT i, h, h2; char C[128]; h = 0; hdc = BeginPaint( hwnd, &ps ); GetClientRect(hwnd, &rect); lphl = ListBoxGetStorageHeader(hwnd); 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); if (lphl->ItemsCount > lphl->ItemsVisible) rect.right -= 16; FillRect(hdc, &rect, hBrush); 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) { h2 = lpls->dis.rcItem.bottom - lpls->dis.rcItem.top; lpls->dis.rcItem.top = h; lpls->dis.rcItem.bottom = h + h2; lpls->dis.rcItem.right = rect.right; TextOut(hdc, 5, h + 2, (char *)lpls->dis.itemData, strlen((char *)lpls->dis.itemData)); if (lpls->dis.itemState != 0) { InvertRect(hdc, &lpls->dis.rcItem); } h += h2; lphl->ItemsVisible++; if (h > rect.bottom) break; } if (lpls->lpNext == NULL) goto EndOfPaint; lpls = (LPLISTSTRUCT)lpls->lpNext; } EndOfPaint: EndPaint( hwnd, &ps ); if (lphl->ItemsCount > lphl->ItemsVisible) { InvalidateRect(lphl->hWndScroll, NULL, TRUE); UpdateWindow(lphl->hWndScroll); } } void OwnerDrawListBox(HWND hwnd) { LPHEADLIST lphl; LPLISTSTRUCT lpls; HANDLE hTemp; PAINTSTRUCT ps; HBRUSH hBrush; HWND hWndParent; HDC hdc; RECT rect; UINT i, h, h2; char C[128]; h = 0; hdc = BeginPaint( hwnd, &ps ); GetClientRect(hwnd, &rect); lphl = ListBoxGetStorageHeader(hwnd); 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); if (lphl->ItemsCount > lphl->ItemsVisible) rect.right -= 16; FillRect(hdc, &rect, hBrush); 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; h2 = lpls->dis.rcItem.bottom - lpls->dis.rcItem.top; lpls->dis.rcItem.top = h; lpls->dis.rcItem.bottom = h + h2; lpls->dis.rcItem.right = rect.right; lpls->dis.itemAction = ODA_DRAWENTIRE; if (lpls->dis.itemState != 0) { lpls->dis.itemAction |= ODA_SELECT; } #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); #endif printf("LBOX WM_DRAWITEM '%s' !\n", lpls->dis.itemData); SendMessage(lphl->hWndLogicParent, WM_DRAWITEM, i, (LPARAM)&lpls->dis); GlobalUnlock(hTemp); GlobalFree(hTemp); if (lpls->dis.itemState != 0) { InvertRect(hdc, &lpls->dis.rcItem); } h += h2; lphl->ItemsVisible++; if (h > rect.bottom) break; } if (lpls->lpNext == NULL) goto EndOfPaint; lpls = (LPLISTSTRUCT)lpls->lpNext; } EndOfPaint: EndPaint( hwnd, &ps ); if (lphl->ItemsCount > lphl->ItemsVisible) { InvalidateRect(lphl->hWndScroll, NULL, TRUE); UpdateWindow(lphl->hWndScroll); } } int ListBoxFindMouse(HWND hwnd, int X, int Y) { LPHEADLIST lphl; LPLISTSTRUCT lpls; RECT rect; UINT i, h, h2; char C[128]; h = 0; lphl = ListBoxGetStorageHeader(hwnd); if (lphl == NULL) return LB_ERR; if (lphl->ItemsCount == 0) return LB_ERR; lpls = lphl->lpFirst; if (lpls == NULL) return LB_ERR; 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)) return(i); } 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; SetScrollRange(lphl->hWndScroll, WM_VSCROLL, 1, lphl->ItemsCount, TRUE); if (lphl->FirstVisible >= (lphl->ItemsCount - lphl->ItemsVisible)) { InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); } if ((lphl->ItemsCount - lphl->FirstVisible) == lphl->ItemsVisible) ShowWindow(lphl->hWndScroll, SW_NORMAL); 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 < 1 || 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; SetScrollRange(lphl->hWndScroll, WM_VSCROLL, 1, lphl->ItemsCount, TRUE); if (((lphl->ItemsCount - lphl->FirstVisible) == lphl->ItemsVisible) && (lphl->ItemsVisible != 0)) ShowWindow(lphl->hWndScroll, SW_NORMAL); 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 < 1 || 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; } 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) { LPHEADLIST lphl; LPLISTSTRUCT lpls, lpls2; UINT Count; lphl = ListBoxGetStorageHeader(hwnd); if (lphl == NULL) return LB_ERR; if (uIndex < 1 || 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); SetScrollRange(lphl->hWndScroll, WM_VSCROLL, 1, lphl->ItemsCount, TRUE); if (lphl->ItemsCount < lphl->ItemsVisible) ShowWindow(lphl->hWndScroll, SW_HIDE); 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 < 1 || nFirst > lphl->ItemsCount) return LB_ERR; lpls = lphl->lpFirst; if (lpls == NULL) return LB_ERR; Count = 1; 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->ItemSelected = 0; lphl->PrevSelected = 0; if ((wndPtr->dwStyle && LBS_NOTIFY) != 0) SendMessage(wndPtr->hwndParent, WM_COMMAND, wndPtr->wIDmenu, MAKELONG(hwnd, LBN_SELCHANGE)); SetScrollRange(lphl->hWndScroll, WM_VSCROLL, 1, lphl->ItemsCount, TRUE); ShowWindow(lphl->hWndScroll, SW_HIDE); 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->ItemSelected = LB_ERR; if (wIndex < 1 || wIndex > lphl->ItemsCount) return LB_ERR; lpls = lphl->lpFirst; if (lpls == NULL) return LB_ERR; for(i = 1; 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->ItemSelected = 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) { LPHEADLIST lphl; LPLISTSTRUCT lpls, lpls2; UINT i; lphl = ListBoxGetStorageHeader(hwnd); if (lphl == NULL) return LB_ERR; if (wIndex < 1 || wIndex > lphl->ItemsCount) return LB_ERR; lpls = lphl->lpFirst; if (lpls == NULL) return LB_ERR; for(i = 1; i <= lphl->ItemsCount; i++) { lpls2 = lpls; lpls = (LPLISTSTRUCT)lpls->lpNext; if (i == wIndex) { lpls2->dis.itemState = 1; break; } if (lpls == NULL) break; } return LB_ERR; } int ListBoxDirectory(HWND hwnd, UINT attrib, LPSTR filespec) { DIR *dirp; struct dirent *dp; struct stat st; char str[128]; int wRet; dirp = opendir("."); while ( (dp = readdir(dirp)) != NULL) { stat(dp->d_name, &st); #ifdef DEBUG_LBDIR printf("LB_DIR : st_mode=%lX / d_name='%s'\n", st.st_mode, dp->d_name); #endif if S_ISDIR(st.st_mode) { sprintf(str, "[%s]", dp->d_name); } else strcpy(str, dp->d_name); wRet = ListBoxAddString(hwnd, str); if (wRet == LB_ERR) break; } closedir(dirp); 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 < 1 || 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 < 1 || 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; 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 = 1; while(lpls != NULL) { if (Count > lphl->ItemSelected) { if (*((char *)lpls->dis.itemData) == (char)wChar) { lphl->FirstVisible = Count - lphl->ItemsVisible / 2; if (lphl->FirstVisible < 1) lphl->FirstVisible = 1; ListBoxSetCurSel(hwnd, Count); SetScrollPos(lphl->hWndScroll, WM_VSCROLL, lphl->FirstVisible, TRUE); InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); return Count; } } lpls = (LPLISTSTRUCT)lpls->lpNext; Count++; } Count = 1; lpls = lphl->lpFirst; while(lpls != NULL) { if (*((char *)lpls->dis.itemData) == (char)wChar) { if (Count == lphl->ItemSelected) return LB_ERR; lphl->FirstVisible = Count - lphl->ItemsVisible / 2; if (lphl->FirstVisible < 1) lphl->FirstVisible = 1; ListBoxSetCurSel(hwnd, Count); SetScrollPos(lphl->hWndScroll, WM_VSCROLL, lphl->FirstVisible, TRUE); InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); return Count; } lpls = (LPLISTSTRUCT)lpls->lpNext; Count++; } return LB_ERR; }