Tue Feb 1 21:14:47 1994 Bob Amstadt (bob@pooh) * [loader/selector.c] Added function CreateNewSegments(). Modified IPCCopySelector to allow aliasing to any arbitrary memory space. * [memory/global.c] Fixed potential bug in GlobalGetFreeSegments(). * [memory/linear.c] Created functions GlobalLinearLock() and GlobalLinearUnlock(). Tue Feb 1 05:51:43 1994 julliard@di.epfl.ch (Alexandre Julliard) * [controls/widgets.c] Removed CAPTION window class. * [loader/cursor.c] Bug fix in LoadCursor(): don't allocate memory every time for built-in cursors. * [windows/clipping.c] Invalidate child windows in InvalidateRgn(). * [windows/defwnd.c] Added repaint of the caption when changing window text. * [windows/event.c] Modified SetCapture() to allow keyboard events while capturing. * [windows/message.c] New function MSG_GetHardwareMessage(), to do mouse tracking without returning control to the Windows program. * [windows/nonclient.c] A couple of changes in frame drawing for DLGMODALFRAME windows. Rewritten window moving code, to use MSG_GetHardwareMessage() instead of non-client mouse events (this is the way Windows does it), and to send WM_ENTERSIZEMOVE messages. Removed WM_NCBUTTONUP and WM_NCMOUSEMOVE handlers. * [windows/win.c] Allocate temporary structures on the USER heap instead of using GlobalAlloc(). * [windows/winpos.c] Added function WINPOS_GetMinMaxInfo() to get sizing informations. Jan 31, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) * [windows/nonclient.c] Call to StdDrawScrollBar() during NC's drawing. Call to NC_ScrollBarButtonDown() on NC mouse events WM_LBUTTONDOWN. Call to NC_ScrollBarButtonUp() on NC mouse events WM_LBUTTONUP. Call to NC_ScrollBarMouseMove() on NC mouse events WM_MOUSEMOVE. * [controls/menu.c] New GetSubMenu() function. Move GetMenu() & SetMenu() functions from 'windows/win.c'. * [controls/listbox.c] Start changes to satisfy recent changes in scrollbars/windows. * [loader/resource.c] Put some code in LoadAccelerators() stub. New TranslateAccelerator() function. * [windows/win.c] Remove GetMenu() & SetMenu() functions. Call to NC_CreateScrollBars() if required by CreateWindow(). Mon Jan 24 10:40:10 EST 1994 John Richardson (jrichard@cs.uml.edu) * [window/win.c] Added functions EnumWindows, EnumChildWindows, and helper WIN_EnumChildWin. EnumWindows won't list all wine windows because GetDesktopWindow isn't complete. However, the code is in place for it to work correctly and only needs GetDesktopWindow to do so. Tue Jan 25 05:51:47 1994 julliard@di.epfl.ch (Alexandre Julliard) * [windows/defwnd.c] Added handling of activation messages (WM_ACTIVATE, WM_NCACTIVATE, WM_MOUSEACTIVATE) * [windows/event.c] De-activate the window when losing input focus. * [windows/focus.c] Bug fix in SetFocus(). * [windows/message.c] Added activation of the window on mouse-clicks. * [windows/nonclient.c] Changed non-client area painting to use the correct colors depending upon the activation state. Added WM_NCACTIVATE message handling. Fixed a couple of bugs in window moving and resizing. * [windows/winpos.c] Implemented Get/SetActiveWindow(). Implemented SWP_NOACTIVATE flag in SetWindowPos(). Jan 17, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) * [misc/message.c] MessageBox has a CaptionBar for his title except for MB_SYSTEMMODAL with MB_ICONHAND. * [windows/nonclient.c] Call to NC_TrackSysMenu on SysMenu button mouse click. * [windows/defwnd.c] Call to NC_TrackSysMenu on Alt key (VK_MENU). * [controls/menu.c] New GetSystemMenu() function. New CopySystemMenu() internal function. New NC_TrackSysMenu() internal function. * [include/windows.h] New WM_INITMENU, WM_INITMENUPOPUP, WM_MENUSELECT & WM_MENUCHAR defines.
1203 lines
34 KiB
C
1203 lines
34 KiB
C
/*
|
|
* Interface code to listbox widgets
|
|
*
|
|
* Copyright Martin Ayotte, 1993
|
|
*
|
|
*/
|
|
|
|
/*
|
|
#define DEBUG_LISTBOX
|
|
*/
|
|
|
|
static char Copyright[] = "Copyright Martin Ayotte, 1993";
|
|
|
|
#include <stdio.h>
|
|
#include <X11/Intrinsic.h>
|
|
#include <X11/StringDefs.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);
|
|
}
|
|
if (wndPtr->hCursor == (HCURSOR)NULL)
|
|
wndPtr->hCursor = LoadCursor((HINSTANCE)NULL, IDC_ARROW);
|
|
return 0;
|
|
case WM_DESTROY:
|
|
lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
|
|
if (lphl == 0) return 0;
|
|
ListBoxResetContent(hwnd);
|
|
DestroyCursor(wndPtr->hCursor);
|
|
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) {
|
|
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 (h > 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;
|
|
}
|
|
}
|
|
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;
|
|
}
|
|
|
|
|