/*
 * Interface code to listbox widgets
 *
 * Copyright  Martin Ayotte, 1993
 *
static char Copyright[] = "Copyright Martin Ayotte, 1993";
*/

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "windows.h"
#include "user.h"
#include "heap.h"
#include "win.h"
#include "msdos.h"
#include "listbox.h"
#include "dos_fs.h"
#include "stddebug.h"
#include "debug.h"

#define GMEM_ZEROINIT 0x0040


LPHEADLIST ListBoxGetWindowAndStorage(HWND hwnd, WND **wndPtr);
LPHEADLIST ListBoxGetStorageHeader(HWND hwnd);
void StdDrawListBox(HWND hwnd);
void OwnerDrawListBox(HWND hwnd);
int ListBoxFindMouse(HWND hwnd, int X, int Y);
int CreateListBoxStruct(HWND hwnd);
void ListBoxAskMeasure(WND *wndPtr, LPHEADLIST lphl, LPLISTSTRUCT lpls);
int ListBoxAddString(HWND hwnd, LPSTR newstr);
int ListBoxInsertString(HWND hwnd, UINT uIndex, LPSTR newstr);
int ListBoxGetText(HWND hwnd, UINT uIndex, LPSTR OutStr, BOOL bItemData);
int ListBoxSetItemData(HWND hwnd, UINT uIndex, DWORD ItemData);
int ListBoxDeleteString(HWND hwnd, UINT uIndex);
int ListBoxFindString(HWND hwnd, UINT nFirst, LPSTR MatchStr);
int ListBoxResetContent(HWND hwnd);
int ListBoxSetCurSel(HWND hwnd, WORD wIndex);
int ListBoxSetSel(HWND hwnd, WORD wIndex, WORD state);
int ListBoxGetSel(HWND hwnd, WORD wIndex);
int ListBoxDirectory(HWND hwnd, UINT attrib, LPSTR filespec);
int ListBoxGetItemRect(HWND hwnd, WORD wIndex, LPRECT rect);
int ListBoxSetItemHeight(HWND hwnd, WORD wIndex, long height);
int ListBoxDefaultItem(HWND hwnd, WND *wndPtr, 
	LPHEADLIST lphl, LPLISTSTRUCT lpls);
int ListBoxFindNextMatch(HWND hwnd, WORD wChar);
int ListMaxFirstVisible(LPHEADLIST lphl);

#define HasStrings(wndPtr) ( \
  ( ((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) != LBS_OWNERDRAWFIXED) && \
    ((wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE) != LBS_OWNERDRAWVARIABLE) ) || \
  ((wndPtr->dwStyle & LBS_HASSTRINGS) == LBS_HASSTRINGS) )

#define LIST_HEAP_ALLOC(lphl,f,size) ((int)HEAP_Alloc(&lphl->Heap,f,size) & 0xffff)
#define LIST_HEAP_FREE(lphl,handle) (HEAP_Free(&lphl->Heap,LIST_HEAP_ADDR(lphl,handle)))
#define LIST_HEAP_ADDR(lphl,handle) \
    ((void *)((handle) ? ((handle) | ((int)lphl->Heap & 0xffff0000)) : 0))
#define LIST_HEAP_SIZE 0x10000

/***********************************************************************
 *           ListBoxWndProc 
 */
LONG ListBoxWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam )
{    
	WND  *wndPtr;
	LPHEADLIST  lphl;
	HWND	hWndCtl;
	WORD	wRet;
	LONG	lRet;
	RECT	rect;
	int		y;
	CREATESTRUCT *createStruct;
	static RECT rectsel;
    switch(message) {
	case WM_CREATE:
		CreateListBoxStruct(hwnd);
		lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
		dprintf_listbox(stddeb,"ListBox WM_CREATE %p !\n", lphl);
		if (lphl == NULL) return 0;
		createStruct = (CREATESTRUCT *)lParam;
		if (HIWORD(createStruct->lpCreateParams) != 0)
			lphl->hWndLogicParent = (HWND)HIWORD(createStruct->lpCreateParams);
		else
			lphl->hWndLogicParent = GetParent(hwnd);
		lphl->hFont = GetStockObject(SYSTEM_FONT);
		lphl->ColumnsWidth = wndPtr->rectClient.right - wndPtr->rectClient.left;
                SetScrollRange(hwnd, SB_VERT, 1, ListMaxFirstVisible(lphl), TRUE);
                SetScrollRange(hwnd, SB_HORZ, 1, 1, TRUE);
		if ((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) == LBS_OWNERDRAWFIXED) {
			}
		return 0;
	case WM_DESTROY:
		lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
		if (lphl == NULL) return 0;
		ListBoxResetContent(hwnd);
		/* XXX need to free lphl->Heap */
		free(lphl);
		*((LPHEADLIST *)&wndPtr->wExtra[1]) = 0;
		dprintf_listbox(stddeb,"ListBox WM_DESTROY %p !\n", lphl);
		return 0;

	case WM_VSCROLL:
		dprintf_listbox(stddeb,"ListBox WM_VSCROLL w=%04X l=%08lX !\n",
				wParam, lParam);
		lphl = ListBoxGetStorageHeader(hwnd);
		if (lphl == NULL) return 0;
		y = lphl->FirstVisible;
		switch(wParam) {
			case SB_LINEUP:
				if (lphl->FirstVisible > 1)	
					lphl->FirstVisible--;
				break;
			case SB_LINEDOWN:
				if (lphl->FirstVisible < ListMaxFirstVisible(lphl))
					lphl->FirstVisible++;
				break;
			case SB_PAGEUP:
				if (lphl->FirstVisible > 1)  
					lphl->FirstVisible -= lphl->ItemsVisible;
				break;
			case SB_PAGEDOWN:
				if (lphl->FirstVisible < ListMaxFirstVisible(lphl))  
					lphl->FirstVisible += lphl->ItemsVisible;
				break;
			case SB_THUMBTRACK:
				lphl->FirstVisible = LOWORD(lParam);
				break;
			}
		if (lphl->FirstVisible < 1)    lphl->FirstVisible = 1;
		if (lphl->FirstVisible > ListMaxFirstVisible(lphl))
			lphl->FirstVisible = ListMaxFirstVisible(lphl);
		if (y != lphl->FirstVisible) {
			SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
			InvalidateRect(hwnd, NULL, TRUE);
			UpdateWindow(hwnd);
			}
		return 0;
	
	case WM_HSCROLL:
		dprintf_listbox(stddeb,"ListBox WM_HSCROLL w=%04X l=%08lX !\n",
				wParam, lParam);
		lphl = ListBoxGetStorageHeader(hwnd);
		if (lphl == NULL) return 0;
		y = lphl->FirstVisible;
		switch(wParam) {
			case SB_LINEUP:
				if (lphl->FirstVisible > 1)
					lphl->FirstVisible -= lphl->ItemsPerColumn;
				break;
			case SB_LINEDOWN:
				if (lphl->FirstVisible < ListMaxFirstVisible(lphl))
					lphl->FirstVisible += lphl->ItemsPerColumn;
				break;
			case SB_PAGEUP:
				if (lphl->FirstVisible > 1 && lphl->ItemsPerColumn != 0)  
					lphl->FirstVisible -= lphl->ItemsVisible /
					lphl->ItemsPerColumn * lphl->ItemsPerColumn;
				break;
			case SB_PAGEDOWN:
				if (lphl->FirstVisible < ListMaxFirstVisible(lphl) &&
							lphl->ItemsPerColumn != 0)  
					lphl->FirstVisible += lphl->ItemsVisible /
					lphl->ItemsPerColumn * lphl->ItemsPerColumn;
				break;
			case SB_THUMBTRACK:
				lphl->FirstVisible = lphl->ItemsPerColumn * 
								(LOWORD(lParam) - 1) + 1;
				break;
			}
		if (lphl->FirstVisible < 1)    lphl->FirstVisible = 1;
		if (lphl->FirstVisible > ListMaxFirstVisible(lphl))
			lphl->FirstVisible = ListMaxFirstVisible(lphl);
		if (lphl->ItemsPerColumn != 0) {
			lphl->FirstVisible = lphl->FirstVisible /
				lphl->ItemsPerColumn * lphl->ItemsPerColumn + 1;
			if (y != lphl->FirstVisible) {
				SetScrollPos(hwnd, SB_HORZ, lphl->FirstVisible / 
				lphl->ItemsPerColumn + 1, TRUE);
				InvalidateRect(hwnd, NULL, TRUE);
				UpdateWindow(hwnd);
				}
			}
		return 0;
	
	case WM_LBUTTONDOWN:
		SetFocus(hwnd);
		SetCapture(hwnd);
		lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
		if (lphl == NULL) return 0;
		lphl->PrevFocused = lphl->ItemFocused;
	        y = ListBoxFindMouse(hwnd, LOWORD(lParam), HIWORD(lParam));
		if (y==-1)
		    return 0;
		if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) {
		    lphl->ItemFocused = y;
		    wRet = ListBoxGetSel(hwnd, y);
		    ListBoxSetSel(hwnd, y, !wRet);
		    }
		else {
		    ListBoxSetCurSel(hwnd, y);
		    if ((wndPtr->dwStyle && LBS_NOTIFY) != 0)
				SendMessage(lphl->hWndLogicParent, WM_COMMAND, 
	    	    wndPtr->wIDmenu, MAKELONG(hwnd, LBN_SELCHANGE));
		    }
		ListBoxGetItemRect(hwnd, y, &rectsel);
		InvalidateRect(hwnd, NULL, TRUE);
		UpdateWindow(hwnd);
		return 0;
	case WM_LBUTTONUP:
		ReleaseCapture();
		lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
		if (lphl == NULL) return 0;
		if (lphl->PrevFocused != lphl->ItemFocused)
			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));
		return 0;
	case WM_MOUSEMOVE:
		lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
		if (lphl == NULL) return 0;
		if ((wParam & MK_LBUTTON) != 0) {
			y = HIWORD(lParam);
			if (y < 4) {
				if (lphl->FirstVisible > 1) {
					lphl->FirstVisible--;
					SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
					InvalidateRect(hwnd, NULL, TRUE);
					UpdateWindow(hwnd);
					break;
					}
				}
			GetClientRect(hwnd, &rect);
			if (y > (rect.bottom - 4)) {
				if (lphl->FirstVisible < ListMaxFirstVisible(lphl)) {
					lphl->FirstVisible++;
					SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
					InvalidateRect(hwnd, NULL, TRUE);
					UpdateWindow(hwnd);
					break;
					}
				}
			if ((y > 0) && (y < (rect.bottom - 4))) {
				if ((y < rectsel.top) || (y > rectsel.bottom)) {
					wRet = ListBoxFindMouse(hwnd, LOWORD(lParam), HIWORD(lParam));
					if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) {
						lphl->ItemFocused = wRet;
						}
					else {
						ListBoxSetCurSel(hwnd, wRet);
					    if ((wndPtr->dwStyle && LBS_NOTIFY) != 0)
							SendMessage(lphl->hWndLogicParent, WM_COMMAND, 
				    	    wndPtr->wIDmenu, MAKELONG(hwnd, LBN_SELCHANGE));
						}
					ListBoxGetItemRect(hwnd, wRet, &rectsel);
					InvalidateRect(hwnd, NULL, TRUE);
					UpdateWindow(hwnd);
					}
				}
			}
		break;
	case WM_KEYDOWN:
		lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
		if (lphl == NULL) return 0;
		switch(wParam) {
			case VK_TAB:
				hWndCtl = GetNextDlgTabItem(lphl->hWndLogicParent,
					hwnd, !(GetKeyState(VK_SHIFT) < 0));
				SetFocus(hWndCtl);
				if(debugging_listbox){
				if ((GetKeyState(VK_SHIFT) < 0))
					dprintf_listbox(stddeb,"ListBox PreviousDlgTabItem %04X !\n", hWndCtl);
				else
					dprintf_listbox(stddeb,"ListBox NextDlgTabItem %04X !\n", hWndCtl);
				}
				break;
			case VK_HOME:
				lphl->ItemFocused = 0;
				break;
			case VK_END:
				lphl->ItemFocused = lphl->ItemsCount - 1;
				break;
			case VK_LEFT:
				if ((wndPtr->dwStyle & LBS_MULTICOLUMN) == LBS_MULTICOLUMN) {
					lphl->ItemFocused -= lphl->ItemsPerColumn;
					}
				break;
			case VK_UP:
				lphl->ItemFocused--;
				break;
			case VK_RIGHT:
				if ((wndPtr->dwStyle & LBS_MULTICOLUMN) == LBS_MULTICOLUMN) {
					lphl->ItemFocused += lphl->ItemsPerColumn;
					}
				break;
			case VK_DOWN:
				lphl->ItemFocused++;
				break;
			case VK_PRIOR:
				lphl->ItemFocused -= lphl->ItemsVisible;
				break;
			case VK_NEXT:
				lphl->ItemFocused += lphl->ItemsVisible;
				break;
			case VK_SPACE:
				wRet = ListBoxGetSel(hwnd, lphl->ItemFocused);
				ListBoxSetSel(hwnd, lphl->ItemFocused, !wRet);
				break;
			default:
				ListBoxFindNextMatch(hwnd, wParam);
				return 0;
			}
		if (lphl->ItemFocused < 0) lphl->ItemFocused = 0;
		if (lphl->ItemFocused >= lphl->ItemsCount)
			lphl->ItemFocused = lphl->ItemsCount - 1;
		lphl->FirstVisible = lphl->ItemFocused / lphl->ItemsVisible * 
											lphl->ItemsVisible + 1;
		if (lphl->FirstVisible < 1) lphl->FirstVisible = 1;
		if ((wndPtr->dwStyle & LBS_MULTIPLESEL) != LBS_MULTIPLESEL) {
			ListBoxSetCurSel(hwnd, lphl->ItemFocused);
		    if ((wndPtr->dwStyle && LBS_NOTIFY) != 0)
				SendMessage(lphl->hWndLogicParent, WM_COMMAND, 
	    	    wndPtr->wIDmenu, MAKELONG(hwnd, LBN_SELCHANGE));
			}
                SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
		InvalidateRect(hwnd, NULL, TRUE);
		UpdateWindow(hwnd);
		break;
	case WM_SETFONT:
		lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
		if (lphl == NULL) return 0;
		if (wParam == 0)
			lphl->hFont = GetStockObject(SYSTEM_FONT);
		else
			lphl->hFont = wParam;
		if (wParam == 0) break;
		break;
	case WM_SETREDRAW:
		dprintf_listbox(stddeb,"ListBox WM_SETREDRAW hWnd=%04X w=%04X !\n", hwnd, wParam);
		lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
		if (lphl == NULL) return 0;
		lphl->bRedrawFlag = wParam;
		break;
	case WM_PAINT:
		wndPtr = WIN_FindWndPtr(hwnd);
		if ((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) == LBS_OWNERDRAWFIXED) {
			OwnerDrawListBox(hwnd);
			break;
			}
		if ((wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE) == LBS_OWNERDRAWVARIABLE) {
			OwnerDrawListBox(hwnd);
			break;
			}
		StdDrawListBox(hwnd);
		break;
	case WM_SETFOCUS:
		dprintf_listbox(stddeb,"ListBox WM_SETFOCUS !\n");
		lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
		break;
	case WM_KILLFOCUS:
		dprintf_listbox(stddeb,"ListBox WM_KILLFOCUS !\n");
		InvalidateRect(hwnd, NULL, TRUE);
		UpdateWindow(hwnd);
		break;

    case LB_RESETCONTENT:
		dprintf_listbox(stddeb,"ListBox LB_RESETCONTENT !\n");
		ListBoxResetContent(hwnd);
		return 0;
    case LB_DIR:
		dprintf_listbox(stddeb,"ListBox LB_DIR !\n");
		wRet = ListBoxDirectory(hwnd, wParam, (LPSTR)lParam);
		InvalidateRect(hwnd, NULL, TRUE);
		UpdateWindow(hwnd);
		return wRet;
	case LB_ADDSTRING:
		wRet = ListBoxAddString(hwnd, (LPSTR)lParam);
		return wRet;
	case LB_GETTEXT:
		dprintf_listbox(stddeb, "LB_GETTEXT  wParam=%d\n",wParam);
		wRet = ListBoxGetText(hwnd, wParam, (LPSTR)lParam, FALSE);
                return wRet;
	case LB_INSERTSTRING:
		wRet = ListBoxInsertString(hwnd, wParam, (LPSTR)lParam);
		return wRet;
	case LB_DELETESTRING:
		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);
		dprintf_listbox(stddeb,"ListBox LB_GETCURSEL %u !\n", 
				lphl->ItemFocused);
		return lphl->ItemFocused;
	case LB_GETHORIZONTALEXTENT:
		return wRet;
	case LB_GETITEMDATA:
		dprintf_listbox(stddeb, "LB_GETITEMDATA wParam=%x\n", wParam);
		lRet = ListBoxGetText(hwnd, wParam, (LPSTR)lParam, TRUE);
		return lRet;
	case LB_GETITEMHEIGHT:
                ListBoxGetItemRect(hwnd, wParam, &rect);
                return (rect.bottom - rect.top);
	case LB_GETITEMRECT:
                ListBoxGetItemRect(hwnd, wParam, (LPRECT)lParam);
                return 0;
	case LB_GETSEL:
		wRet = ListBoxGetSel(hwnd, wParam);
		return wRet;
	case LB_GETSELCOUNT:
		lphl = ListBoxGetStorageHeader(hwnd);
		if (lphl == NULL) return LB_ERR;
		return lphl->SelCount;
	case LB_GETSELITEMS:
		return wRet;
	case LB_GETTEXTLEN:
		return wRet;
	case LB_GETTOPINDEX:
		lphl = ListBoxGetStorageHeader(hwnd);
		if (lphl == NULL) return LB_ERR;
		return lphl->FirstVisible;
	case LB_SELECTSTRING:
		return wRet;
	case LB_SELITEMRANGE:
		return wRet;
	case LB_SETCARETINDEX:
		return wRet;
	case LB_SETCOLUMNWIDTH:
		lphl = ListBoxGetStorageHeader(hwnd);
		if (lphl == NULL) return LB_ERR;
		lphl->ColumnsWidth = wParam;
		break;
	case LB_SETHORIZONTALEXTENT:
		return wRet;
	case LB_SETITEMDATA:
		dprintf_listbox(stddeb, "LB_SETITEMDATA  wParam=%x  lParam=%lx\n", wParam, lParam);
		wRet = ListBoxSetItemData(hwnd, wParam, lParam);
		return wRet;
	case LB_SETTABSTOPS:
		lphl = ListBoxGetStorageHeader(hwnd);
		if (lphl == NULL) return LB_ERR;
		lphl->FirstVisible = wParam;
		return 0;
	case LB_SETCURSEL:
		dprintf_listbox(stddeb,"ListBox LB_SETCURSEL wParam=%x !\n", 
				wParam);
		wRet = ListBoxSetCurSel(hwnd, wParam);
		InvalidateRect(hwnd, NULL, TRUE);
		UpdateWindow(hwnd);
		return wRet;
	case LB_SETSEL:
		dprintf_listbox(stddeb,"ListBox LB_SETSEL wParam=%x lParam=%lX !\n", wParam, lParam);
		wRet = ListBoxSetSel(hwnd, LOWORD(lParam), wParam);
		InvalidateRect(hwnd, NULL, TRUE);
		UpdateWindow(hwnd);
		return wRet;
	case LB_SETTOPINDEX:
		dprintf_listbox(stddeb,"ListBox LB_SETTOPINDEX wParam=%x !\n",
				wParam);
		lphl = ListBoxGetStorageHeader(hwnd);
		lphl->FirstVisible = wParam;
                SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
		InvalidateRect(hwnd, NULL, TRUE);
		UpdateWindow(hwnd);
		break;
	case LB_SETITEMHEIGHT:
		dprintf_listbox(stddeb,"ListBox LB_SETITEMHEIGHT wParam=%x lParam=%lX !\n", wParam, lParam);
		wRet = ListBoxSetItemHeight(hwnd, wParam, lParam);
		return wRet;

	default:
		return DefWindowProc( hwnd, message, wParam, lParam );
    }
return 0;
}


LPHEADLIST ListBoxGetWindowAndStorage(HWND hwnd, WND **wndPtr)
{
    WND  *Ptr;
    LPHEADLIST lphl;
    *(wndPtr) = Ptr = WIN_FindWndPtr(hwnd);
    lphl = *((LPHEADLIST *)&Ptr->wExtra[1]);
    return lphl;
}


LPHEADLIST ListBoxGetStorageHeader(HWND hwnd)
{
    WND  *wndPtr;
    LPHEADLIST lphl;
    wndPtr = WIN_FindWndPtr(hwnd);
    lphl = *((LPHEADLIST *)&wndPtr->wExtra[1]);
    return lphl;
}


void StdDrawListBox(HWND hwnd)
{
	WND 	*wndPtr;
	LPHEADLIST  lphl;
	LPLISTSTRUCT lpls;
	PAINTSTRUCT ps;
	HBRUSH 	hBrush;
	int 	OldBkMode;
	DWORD 	dwOldTextColor;
	HDC 	hdc;
	RECT 	rect;
	int     i, h, h2, maxwidth, ipc;
	h = 0;
	hdc = BeginPaint( hwnd, &ps );
	if (!IsWindowVisible(hwnd)) {
		EndPaint( hwnd, &ps );
		return;
		}
	lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
	if (lphl == NULL) goto EndOfPaint;
	if (!lphl->bRedrawFlag) goto EndOfPaint;
	SelectObject(hdc, lphl->hFont);
	hBrush = SendMessage(lphl->hWndLogicParent, WM_CTLCOLOR, (WORD)hdc,
		    MAKELONG(hwnd, CTLCOLOR_LISTBOX));
	if (hBrush == (HBRUSH)NULL)  hBrush = GetStockObject(WHITE_BRUSH);
	GetClientRect(hwnd, &rect);
	FillRect(hdc, &rect, hBrush);
	maxwidth = rect.right;
	rect.right = lphl->ColumnsWidth;
	if (lphl->ItemsCount == 0) goto EndOfPaint;
	lpls = lphl->lpFirst;
	if (lpls == NULL) goto EndOfPaint;
	lphl->ItemsVisible = 0;
	lphl->ItemsPerColumn = ipc = 0;
	for(i = 1; i <= lphl->ItemsCount; i++) {
	    if (i >= lphl->FirstVisible) {
	        if (lpls == NULL) break;
		if ((h + lpls->dis.rcItem.bottom - lpls->dis.rcItem.top) > rect.bottom) {
		    if ((wndPtr->dwStyle & LBS_MULTICOLUMN) == LBS_MULTICOLUMN) {
			lphl->ItemsPerColumn = max(lphl->ItemsPerColumn, ipc);
			ipc = 0;
			h = 0;
			rect.left += lphl->ColumnsWidth;
			rect.right += lphl->ColumnsWidth;
			if (rect.left > maxwidth) break;
			}
		    else 
			break;
		    }
		h2 = lpls->dis.rcItem.bottom - lpls->dis.rcItem.top;
		lpls->dis.rcItem.top = h;
		lpls->dis.rcItem.bottom = h + h2;
		lpls->dis.rcItem.left = rect.left;
		lpls->dis.rcItem.right = rect.right;
		OldBkMode = SetBkMode(hdc, TRANSPARENT);
		if (lpls->dis.itemState != 0) {
			dwOldTextColor = SetTextColor(hdc, 0x00FFFFFFL);
		    FillRect(hdc, &lpls->dis.rcItem, GetStockObject(BLACK_BRUSH));
		    }
		TextOut(hdc, rect.left + 5, h + 2, (char *)lpls->itemText, 
			strlen((char *)lpls->itemText));
		if (lpls->dis.itemState != 0) {
			SetTextColor(hdc, dwOldTextColor);
		    }
		SetBkMode(hdc, OldBkMode);
		if ((lphl->ItemFocused == i - 1) && GetFocus() == hwnd) {
		    DrawFocusRect(hdc, &lpls->dis.rcItem);
		    }
		h += h2;
		lphl->ItemsVisible++;
		ipc++;
		}
	    if (lpls->lpNext == NULL) goto EndOfPaint;
	    lpls = (LPLISTSTRUCT)lpls->lpNext;
	}
EndOfPaint:
    EndPaint( hwnd, &ps );
}



void OwnerDrawListBox(HWND hwnd)
{
	WND 	*wndPtr,*ParentWndPtr;
	LPHEADLIST  lphl;
	LPLISTSTRUCT lpls;
	PAINTSTRUCT ps;
	HBRUSH 	hBrush;
	HWND	hWndParent;
	DWORD   itemData;
	HDC 	hdc;
	RECT 	rect;
	int     i, h, h2, maxwidth;
	h = 0;
	hdc = BeginPaint(hwnd, &ps);
	if (!IsWindowVisible(hwnd)) {
		EndPaint( hwnd, &ps );
		return;
		}
	lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
	if (lphl == NULL) goto EndOfPaint;
	if (!lphl->bRedrawFlag) goto EndOfPaint;
	hBrush = SendMessage(lphl->hWndLogicParent, WM_CTLCOLOR, (WORD)hdc,
		    MAKELONG(hwnd, CTLCOLOR_LISTBOX));
	if (hBrush == (HBRUSH)NULL)  hBrush = GetStockObject(WHITE_BRUSH);
	GetClientRect(hwnd, &rect);
	FillRect(hdc, &rect, hBrush);
	maxwidth = rect.right;
	rect.right = lphl->ColumnsWidth;
	if (lphl->ItemsCount == 0) goto EndOfPaint;
	lpls = lphl->lpFirst;
	if (lpls == NULL) goto EndOfPaint;
	lphl->ItemsVisible = 0;
	for (i = 1; i <= lphl->ItemsCount; i++) {
	    if (i >= lphl->FirstVisible) {
		lpls->dis.hDC = hdc;
		lpls->dis.hwndItem = hwnd;
		lpls->dis.CtlType = ODT_LISTBOX;
		lpls->dis.itemID = i - 1;
		if ((!lpls->dis.CtlID) && (lphl->hWndLogicParent)) {
			ParentWndPtr = WIN_FindWndPtr(lphl->hWndLogicParent);
			lpls->dis.CtlID = ParentWndPtr->wIDmenu;
			}
		h2 = lpls->dis.rcItem.bottom - lpls->dis.rcItem.top;
		lpls->dis.rcItem.top = h;
		lpls->dis.rcItem.bottom = h + h2;
		lpls->dis.rcItem.left = rect.left;
		lpls->dis.rcItem.right = rect.right;
		lpls->dis.itemAction = ODA_DRAWENTIRE;
/*		if (lpls->dis.itemState != 0) {
		    lpls->dis.itemAction |= ODA_SELECT;
		    }
		if (lphl->ItemFocused == i - 1) {
		    lpls->dis.itemAction |= ODA_FOCUS;
		    }*/
		dprintf_listbox(stddeb,"LBOX WM_DRAWITEM #%d left=%d top=%d right=%d bottom=%d !\n", 
			i-1, lpls->dis.rcItem.left, lpls->dis.rcItem.top, 
			lpls->dis.rcItem.right, lpls->dis.rcItem.bottom);
		dprintf_listbox(stddeb,"LBOX WM_DRAWITEM Parent=%X &dis=%lX CtlID=%u !\n", 
			hWndParent, (LONG)&lpls->dis, lpls->dis.CtlID);
		dprintf_listbox(stddeb,"LBOX WM_DRAWITEM %08lX!\n",lpls->dis.itemData);
		if (HasStrings(wndPtr))
		  dprintf_listbox(stddeb,"  '%s'\n",lpls->itemText);
		if (HasStrings(wndPtr)) {
			itemData = lpls->dis.itemData;
			lpls->dis.itemData = (DWORD)lpls->itemText;
			}
		SendMessage(lphl->hWndLogicParent, WM_DRAWITEM, 
							i-1, (LPARAM)&lpls->dis);
		if (HasStrings(wndPtr))
			lpls->dis.itemData = itemData;

/*		if (lpls->dis.itemState != 0) {
  		    InvertRect(hdc, &lpls->dis.rcItem);  
		    }  */
		h += h2;
		lphl->ItemsVisible++;
		/* if (h > rect.bottom) goto EndOfPaint;*/
		}
	    if (lpls->lpNext == NULL) goto EndOfPaint;
	    lpls = (LPLISTSTRUCT)lpls->lpNext;
	}
EndOfPaint:
    EndPaint( hwnd, &ps );
}



int ListBoxFindMouse(HWND hwnd, int X, int Y)
{
    WND 		*wndPtr;
    LPHEADLIST 		lphl;
    LPLISTSTRUCT	lpls;
    RECT 		rect;
    int                 i, h, h2, w, w2;
    lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
    if (lphl == NULL) return LB_ERR;
    if (lphl->ItemsCount == 0) return LB_ERR;
    lpls = lphl->lpFirst;
    if (lpls == NULL) return LB_ERR;
    GetClientRect(hwnd, &rect);
    h = w2 = 0;
    w = lphl->ColumnsWidth;
    for(i = 1; i <= lphl->ItemsCount; i++) {
	if (i >= lphl->FirstVisible) {
	    h2 = h;
	    h += lpls->dis.rcItem.bottom - lpls->dis.rcItem.top;
	    if ((Y > h2) && (Y < h) &&
		(X > w2) && (X < w)) return(i - 1);
	    if (h > rect.bottom) {
		if ((wndPtr->dwStyle & LBS_MULTICOLUMN) != LBS_MULTICOLUMN) return LB_ERR;
		h = 0;
		w2 = w;
		w += lphl->ColumnsWidth;
		if (w2 > rect.right) return LB_ERR;
		}
	    }
	if (lpls->lpNext == NULL) return LB_ERR;
	lpls = (LPLISTSTRUCT)lpls->lpNext;
	}
    return(LB_ERR);
}



int CreateListBoxStruct(HWND hwnd)
{
	WND  *wndPtr;
	LPHEADLIST lphl;
	int HeapHandle;
	void *HeapBase;
	wndPtr = WIN_FindWndPtr(hwnd);
	lphl = (LPHEADLIST)malloc(sizeof(HEADLIST));
	lphl->lpFirst = NULL;
	*((LPHEADLIST *)&wndPtr->wExtra[1]) = lphl;     /* HEAD of List */
	lphl->ItemsCount = 0;
	lphl->ItemsVisible = 0;
	lphl->FirstVisible = 1;
	lphl->ColumnsVisible = 1;
	lphl->ItemsPerColumn = 0;
	lphl->StdItemHeight = 15;
	lphl->ItemFocused = 0;
	lphl->PrevFocused = 0;
	lphl->SelCount = 0;
	lphl->DrawCtlType = ODT_LISTBOX;
	lphl->bRedrawFlag = TRUE;
	HeapHandle = GlobalAlloc(GMEM_FIXED, LIST_HEAP_SIZE);
	HeapBase = GlobalLock(HeapHandle);
	HEAP_Init(&lphl->Heap, HeapBase, LIST_HEAP_SIZE);
	return TRUE;
}


void ListBoxAskMeasure(WND *wndPtr, LPHEADLIST lphl, LPLISTSTRUCT lpls)  
{
	MEASUREITEMSTRUCT 	*lpmeasure;
	HANDLE hTemp = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(MEASUREITEMSTRUCT));
	lpmeasure = (MEASUREITEMSTRUCT *) USER_HEAP_ADDR(hTemp);
	if (lpmeasure == NULL) {
		fprintf(stderr,"ListBoxAskMeasure() // Bad allocation of Measure struct !\n");
		return;
		}
	lpmeasure->CtlType = ODT_LISTBOX;
	lpmeasure->CtlID = wndPtr->wIDmenu;
	lpmeasure->itemID = lpls->dis.itemID;
	lpmeasure->itemWidth = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
	lpmeasure->itemHeight = 0;
	if (HasStrings(wndPtr))
		lpmeasure->itemData = (DWORD)lpls->itemText;
	else
		lpmeasure->itemData = lpls->dis.itemData;
	SendMessage(lphl->hWndLogicParent, WM_MEASUREITEM, 0, (DWORD)lpmeasure);
	lpls->dis.rcItem.right = lpls->dis.rcItem.left + lpmeasure->itemWidth;
	lpls->dis.rcItem.bottom = lpls->dis.rcItem.top + lpmeasure->itemHeight;
	USER_HEAP_FREE(hTemp);			
}


int ListBoxAddString(HWND hwnd, LPSTR newstr)
{
    LPHEADLIST	lphl;
    UINT	pos = (UINT) -1;
    WND		*wndPtr;
    
    lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
    if (lphl == NULL) return LB_ERR;
    if (HasStrings(wndPtr) && (wndPtr->dwStyle & LBS_SORT)) {
	LPLISTSTRUCT lpls = lphl->lpFirst;
	for (pos = 0; lpls; lpls = lpls->lpNext, pos++)
	    if (strcmp(lpls->itemText, newstr) >= 0)
		break;
    }
    return ListBoxInsertString(hwnd, pos, newstr);
}

int ListBoxInsertString(HWND hwnd, UINT uIndex, LPSTR newstr)
{
    WND  	*wndPtr;
    LPHEADLIST 	lphl;
    LPLISTSTRUCT *lppls, lplsnew;
    HANDLE 	hItem;
    HANDLE 	hStr;
    LPSTR	str;
    UINT	Count;
    
    dprintf_listbox(stddeb,"ListBoxInsertString(%04X, %d, %p);\n", 
		    hwnd, uIndex, newstr);
    
    lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
    if (lphl == NULL) return LB_ERR;
    
    if (uIndex == (UINT)-1)
	uIndex = lphl->ItemsCount;
    if (uIndex > lphl->ItemsCount) return LB_ERR;
    lppls = (LPLISTSTRUCT *) &lphl->lpFirst;
    
    for(Count = 0; Count < uIndex; Count++) {
	if (*lppls == NULL) return LB_ERR;
	lppls = (LPLISTSTRUCT *) &(*lppls)->lpNext;
        }
    
	hItem = LIST_HEAP_ALLOC(lphl, GMEM_MOVEABLE, sizeof(LISTSTRUCT));
	lplsnew = (LPLISTSTRUCT) LIST_HEAP_ADDR(lphl, hItem);
    if (lplsnew == NULL) {
		printf("ListBoxInsertString() // Bad allocation of new item !\n");
		return LB_ERRSPACE;
		}
	ListBoxDefaultItem(hwnd, wndPtr, lphl, lplsnew);
	lplsnew->hMem = hItem;
	lplsnew->lpNext = *lppls;
	*lppls = lplsnew;
	lphl->ItemsCount++;
	hStr = 0;

	if (HasStrings(wndPtr)) {
		hStr = LIST_HEAP_ALLOC(lphl, GMEM_MOVEABLE, strlen(newstr) + 1);
		str = (LPSTR)LIST_HEAP_ADDR(lphl, hStr);
		if (str == NULL) return LB_ERRSPACE;
		strcpy(str, newstr);
		newstr = str;
		lplsnew->itemText = str;
		dprintf_listbox(stddeb,"ListBoxInsertString // LBS_HASSTRINGS after strcpy '%s'\n", str);
		}
	else {
		lplsnew->itemText = NULL;
		lplsnew->dis.itemData = (DWORD)newstr;
		}
	lplsnew->dis.itemID = lphl->ItemsCount;
	lplsnew->hData = hStr;
	if (((wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE) == LBS_OWNERDRAWVARIABLE) ||
		((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) == LBS_OWNERDRAWFIXED))
		ListBoxAskMeasure(wndPtr, lphl, lplsnew);
        SetScrollRange(hwnd, SB_VERT, 1, ListMaxFirstVisible(lphl), 
                       (lphl->FirstVisible != 1 && lphl->bRedrawFlag));
	if (lphl->ItemsPerColumn != 0)
		SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible / 
			lphl->ItemsPerColumn + 1,
			(lphl->FirstVisible != 1 && lphl->bRedrawFlag));
	if ((lphl->FirstVisible <= uIndex) &&
		((lphl->FirstVisible + lphl->ItemsVisible) >= uIndex)) {
		InvalidateRect(hwnd, NULL, TRUE);
		UpdateWindow(hwnd);
		}
        dprintf_listbox(stddeb,"ListBoxInsertString // count=%d\n", lphl->ItemsCount);
	return uIndex;
}


int ListBoxGetText(HWND hwnd, UINT uIndex, LPSTR OutStr, BOOL bItemData)
{
    WND  	*wndPtr;
    LPHEADLIST 	lphl;
    LPLISTSTRUCT lpls;
    UINT	Count;
    if ((!OutStr)&&(!bItemData))
	fprintf(stderr, "ListBoxGetText // OutStr==NULL\n"); 
    if (!bItemData)   	*OutStr=0;
    lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
    if (lphl == NULL) return LB_ERR;
    if (uIndex >= lphl->ItemsCount) return LB_ERR;
    lpls = lphl->lpFirst;
    if (lpls == NULL) return LB_ERR;
    if (uIndex > lphl->ItemsCount) return LB_ERR;
    for(Count = 0; Count < uIndex; Count++) {
	if (lpls->lpNext == NULL) return LB_ERR;
	lpls = (LPLISTSTRUCT)lpls->lpNext;
    }
    if (bItemData)
	return lpls->dis.itemData;
    if (!(HasStrings(wndPtr)) )
      {
	*((long *)OutStr) = lpls->dis.itemData;
	return 4;
      }
	
    strcpy(OutStr, lpls->itemText);
    return strlen(OutStr);
}

int ListBoxSetItemData(HWND hwnd, UINT uIndex, DWORD ItemData)
{
    WND         *wndPtr;
    LPHEADLIST  lphl;
    LPLISTSTRUCT lpls;
    UINT        Count;
    lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
    if (lphl == NULL) return LB_ERR;
    if (uIndex >= lphl->ItemsCount) return LB_ERR;
    lpls = lphl->lpFirst;
    if (lpls == NULL) return LB_ERR;
    if (uIndex > lphl->ItemsCount) return LB_ERR;
    for(Count = 0; Count < uIndex; Count++) {
        if (lpls->lpNext == NULL) return LB_ERR;
        lpls = (LPLISTSTRUCT)lpls->lpNext;
    }
    lpls->dis.itemData = ItemData;
    return 1;
}


int ListBoxDeleteString(HWND hwnd, UINT uIndex)
{
    WND  	*wndPtr;
    LPHEADLIST 	lphl;
    LPLISTSTRUCT lpls, lpls2;
    UINT	Count;
    lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
    if (lphl == NULL) return LB_ERR;
    if (uIndex >= lphl->ItemsCount) return LB_ERR;
    lpls = lphl->lpFirst;
    if (lpls == NULL) return LB_ERR;
    if (uIndex > lphl->ItemsCount) return LB_ERR;
    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) LIST_HEAP_FREE(lphl, lpls->hData);
    if (lpls->hMem != 0) LIST_HEAP_FREE(lphl, lpls->hMem);
    SetScrollRange(hwnd, SB_VERT, 1, ListMaxFirstVisible(lphl), TRUE);
    if (lphl->ItemsPerColumn != 0)
	SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible / 
	    lphl->ItemsPerColumn + 1, TRUE);
    if ((lphl->FirstVisible <= uIndex) &&
        ((lphl->FirstVisible + lphl->ItemsVisible) >= uIndex)) {
        InvalidateRect(hwnd, NULL, TRUE);
        UpdateWindow(hwnd);
        }
    return lphl->ItemsCount;
}


int ListBoxFindString(HWND hwnd, UINT nFirst, LPSTR MatchStr)
{
    WND          *wndPtr;
    LPHEADLIST 	lphl;
    LPLISTSTRUCT lpls;
    UINT	Count;
    lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
    if (lphl == NULL) return LB_ERR;
    if (nFirst > lphl->ItemsCount) return LB_ERR;
    lpls = lphl->lpFirst;
    if (lpls == NULL) return LB_ERR;
    Count = 0;
    while(lpls != NULL) {
      if (HasStrings(wndPtr))
	{
	  if (strcmp(lpls->itemText, MatchStr) == 0) return Count;
	}
      else
	{
	  if (lpls->dis.itemData == (DWORD)MatchStr) return Count;
	}
      lpls = (LPLISTSTRUCT)lpls->lpNext;
      Count++;
    }
    return LB_ERR;
}


int ListBoxResetContent(HWND hwnd)
{
    WND  *wndPtr;
    LPHEADLIST 	lphl;
    LPLISTSTRUCT lpls, lpls2;
    UINT	i;
    lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
    if (lphl == NULL) return LB_ERR;
    lpls = lphl->lpFirst;
    if (lpls == NULL) return LB_ERR;
    dprintf_listbox(stddeb, "ListBoxResetContent // ItemCount = %d\n",
	lphl->ItemsCount);
    for(i = 0; i <= lphl->ItemsCount; i++) {
	lpls2 = lpls;
	lpls = (LPLISTSTRUCT)lpls->lpNext;
	if (i != 0) {
	    dprintf_listbox(stddeb,"ResetContent #%u\n", i);
	    if (lpls2->hData != 0 && lpls2->hData != lpls2->hMem)
		LIST_HEAP_FREE(lphl, lpls2->hData);
	    if (lpls2->hMem != 0) LIST_HEAP_FREE(lphl, lpls2->hMem);
	    }  
	if (lpls == NULL)  break;
    }
    lphl->lpFirst = NULL;
    lphl->FirstVisible = 1;
    lphl->ItemsCount = 0;
    lphl->ItemFocused = -1;
    lphl->PrevFocused = -1;
    if ((wndPtr->dwStyle && LBS_NOTIFY) != 0)
	SendMessage(lphl->hWndLogicParent, WM_COMMAND, 
    	    wndPtr->wIDmenu, MAKELONG(hwnd, LBN_SELCHANGE));
    SetScrollRange(hwnd, SB_VERT, 1, ListMaxFirstVisible(lphl), TRUE);
    if (lphl->ItemsPerColumn != 0)
	SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible / 
	    lphl->ItemsPerColumn + 1, TRUE);
    InvalidateRect(hwnd, NULL, TRUE);
    UpdateWindow(hwnd);
    return TRUE;
}


int ListBoxSetCurSel(HWND hwnd, WORD wIndex)
{
    WND  *wndPtr;
    LPHEADLIST 	lphl;
    LPLISTSTRUCT lpls, lpls2;
    UINT	i;
    lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
    if (lphl == NULL) return LB_ERR;
    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(lphl->hWndLogicParent, 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;
	int	x, wRet;
	BOOL    OldFlag;
	char 	temp[256];
    LPHEADLIST 	lphl;
	dprintf_listbox(stddeb,"ListBoxDirectory: %s, %4x\n",filespec,attrib);
    lphl = ListBoxGetStorageHeader(hwnd);
    if (lphl == NULL) return LB_ERR;
	if ((dp = (struct dosdirent *)DOS_opendir(filespec)) ==NULL) return 0;
	OldFlag = lphl->bRedrawFlag;
	lphl->bRedrawFlag = FALSE;
	while ((dp = (struct dosdirent *)DOS_readdir(dp))) {
		if (!dp->inuse) break;
		dprintf_listbox(stddeb,"ListBoxDirectory %p '%s' !\n", dp->filename, dp->filename);
		if (dp->attribute & FA_DIREC) {
			if (attrib & DDL_DIRECTORY &&
					strcmp(dp->filename, ".")) {
				sprintf(temp, "[%s]", dp->filename);
				if ( (wRet = ListBoxAddString(hwnd, temp)) == LB_ERR) break;
				}
			} 
		else {
			if (attrib & DDL_EXCLUSIVE) {
				if (attrib & (DDL_READWRITE | DDL_READONLY | DDL_HIDDEN | 
					    DDL_SYSTEM) )
					if ( (wRet = ListBoxAddString(hwnd, dp->filename)) 
					    == LB_ERR) break;
				} 
			else {
				if ( (wRet = ListBoxAddString(hwnd, dp->filename)) 
					== LB_ERR) break;
				}
			}
		}
	DOS_closedir(dp);

	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;
				}		
			}
		}
	lphl->bRedrawFlag = OldFlag;
	if (OldFlag) {
		InvalidateRect(hwnd, NULL, TRUE);
		UpdateWindow(hwnd);
		}
	dprintf_listbox(stddeb,"End of ListBoxDirectory !\n");
	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;
	if (wndPtr == NULL || lphl == NULL || lpls == NULL) {
		fprintf(stderr,"ListBoxDefaultItem() // Bad Pointers !\n");
		return FALSE;
		}
    GetClientRect(hwnd, &rect);
    SetRect(&lpls->dis.rcItem, 0, 0, rect.right, lphl->StdItemHeight);
    lpls->dis.CtlType = lphl->DrawCtlType;
    lpls->dis.CtlID = wndPtr->wIDmenu;
    lpls->dis.itemID = 0;
    lpls->dis.itemAction = 0;
    lpls->dis.itemState = 0;
    lpls->dis.hwndItem = hwnd;
    lpls->dis.hDC = 0;
    lpls->dis.itemData = 0;
	return TRUE;
}



int ListBoxFindNextMatch(HWND hwnd, WORD wChar)
{
    WND  	*wndPtr;
    LPHEADLIST 	lphl;
    LPLISTSTRUCT lpls;
    UINT	Count;
    lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
    if (lphl == NULL) return LB_ERR;
    lpls = lphl->lpFirst;
    if (lpls == NULL) return LB_ERR;
    if (wChar < ' ') return LB_ERR;
    if (((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) == LBS_OWNERDRAWFIXED) ||
	    ((wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE) == LBS_OWNERDRAWVARIABLE)) {
	if ((wndPtr->dwStyle & LBS_HASSTRINGS) != LBS_HASSTRINGS) { 
	    return LB_ERR;
	    }
	}
    Count = 0;
    while(lpls != NULL) {
        if (Count > lphl->ItemFocused) {
	    if (*(lpls->itemText) == (char)wChar) {
		lphl->FirstVisible = Count - lphl->ItemsVisible / 2;
		if (lphl->FirstVisible < 1) lphl->FirstVisible = 1;
		if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) {
		    lphl->ItemFocused = Count;
		    }
		else {
		    ListBoxSetCurSel(hwnd, Count);
		    }
		SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
	        InvalidateRect(hwnd, NULL, TRUE);
	        UpdateWindow(hwnd);
	        return Count;
	        }
	    }
	lpls = (LPLISTSTRUCT)lpls->lpNext;
	Count++;
	}
    Count = 0;
    lpls = lphl->lpFirst;
    while(lpls != NULL) {
	if (*(lpls->itemText) == (char)wChar) {
	    if (Count == lphl->ItemFocused)    return LB_ERR;
	    lphl->FirstVisible = Count - lphl->ItemsVisible / 2;
	    if (lphl->FirstVisible < 1) lphl->FirstVisible = 1;
	    if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) {
		lphl->ItemFocused = Count;
		}
	    else {
		ListBoxSetCurSel(hwnd, Count);
		}
	    SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
	    InvalidateRect(hwnd, NULL, TRUE);
	    UpdateWindow(hwnd);
	    return Count;
	    }
	lpls = (LPLISTSTRUCT)lpls->lpNext;
	Count++;
        }
    return LB_ERR;
}


/************************************************************************
 * 					DlgDirSelect			[USER.99]
 */
BOOL DlgDirSelect(HWND hDlg, LPSTR lpStr, int nIDLBox)
{
	fprintf(stdnimp,"DlgDirSelect(%04X, '%s', %d) \n", hDlg, lpStr, nIDLBox);
	return FALSE;
}


/************************************************************************
 * 					DlgDirList				[USER.100]
 */
int DlgDirList(HWND hDlg, LPSTR lpPathSpec, 
	int nIDLBox, int nIDStat, WORD wType)
{
	HWND	hWnd;
	int ret;
	dprintf_listbox(stddeb,"DlgDirList(%04X, '%s', %d, %d, %04X) \n",
			hDlg, lpPathSpec, nIDLBox, nIDStat, wType);
	if (nIDLBox)
	  hWnd = GetDlgItem(hDlg, nIDLBox);
	else
	  hWnd = 0;
	if (hWnd)
	  ListBoxResetContent(hWnd);
	if (hWnd)
	  ret=ListBoxDirectory(hWnd, wType, lpPathSpec);
	else
	  ret=0;
	if (nIDStat)
	  {
	    int drive;
	    drive = DOS_GetDefaultDrive();
	    SendDlgItemMessage(hDlg, nIDStat, WM_SETTEXT, 0, 
			       (LONG) DOS_GetCurrentDir(drive) );
	  } 
	return ret;
}

/* get the maximum value of lphl->FirstVisible */
int ListMaxFirstVisible(LPHEADLIST lphl)
{
    int m = lphl->ItemsCount-lphl->ItemsVisible+1;
    return (m < 1) ? 1 : m;
}
