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

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

#define GMEM_ZEROINIT 0x0040

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

#define OWNER_DRAWN(wndPtr) \
  ((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) ||  \
   (wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE))

#define HasStrings(wndPtr) (  \
  (! OWNER_DRAWN (wndPtr)) || \
  (wndPtr->dwStyle & LBS_HASSTRINGS))

#if 0
#define LIST_HEAP_ALLOC(lphl,f,size) ((int)HEAP_Alloc(&lphl->Heap,f,size) & 0xffff)
#define LIST_HEAP_FREE(lphl,handle) (HEAP_Free(&lphl->Heap,LIST_HEAP_ADDR(lphl,handle)))
#define LIST_HEAP_ADDR(lphl,handle) \
    ((void *)((handle) ? ((handle) | ((int)lphl->Heap & 0xffff0000)) : 0))
#else
#define LIST_HEAP_ALLOC(lphl,f,size) USER_HEAP_ALLOC(size)
#define LIST_HEAP_FREE(lphl,handle)  USER_HEAP_FREE(handle)
#define LIST_HEAP_ADDR(lphl,handle)  USER_HEAP_LIN_ADDR(handle)
#endif

#define LIST_HEAP_SIZE 0x10000

/* Design notes go here */

LONG LBCreate( HWND hwnd, WORD message, WORD wParam, LONG lParam );
LONG LBGetDlgCode( HWND hwnd, WORD message, WORD wParam, LONG lParam );
LONG LBDestroy( HWND hwnd, WORD message, WORD wParam, LONG lParam );
LONG LBVScroll( HWND hwnd, WORD message, WORD wParam, LONG lParam );
LONG LBHScroll( HWND hwnd, WORD message, WORD wParam, LONG lParam );
LONG LBLButtonDown( HWND hwnd, WORD message, WORD wParam, LONG lParam );
LONG LBLButtonUp( HWND hwnd, WORD message, WORD wParam, LONG lParam );
LONG LBRButtonUp( HWND hwnd, WORD message, WORD wParam, LONG lParam );
LONG LBMouseMove( HWND hwnd, WORD message, WORD wParam, LONG lParam );
LONG LBKeyDown( HWND hwnd, WORD message, WORD wParam, LONG lParam );
LONG LBSetFont( HWND hwnd, WORD message, WORD wParam, LONG lParam );
LONG LBSetRedraw( HWND hwnd, WORD message, WORD wParam, LONG lParam );
LONG LBPaint( HWND hwnd, WORD message, WORD wParam, LONG lParam );
LONG LBSetFocus( HWND hwnd, WORD message, WORD wParam, LONG lParam );
LONG LBKillFocus( HWND hwnd, WORD message, WORD wParam, LONG lParam );
LONG LBResetContent( HWND hwnd, WORD message, WORD wParam, LONG lParam );
LONG LBDir( HWND hwnd, WORD message, WORD wParam, LONG lParam );
LONG LBAddString( HWND hwnd, WORD message, WORD wParam, LONG lParam );
LONG LBGetText( HWND hwnd, WORD message, WORD wParam, LONG lParam );
LONG LBInsertString( HWND hwnd, WORD message, WORD wParam, LONG lParam );
LONG LBDeleteString( HWND hwnd, WORD message, WORD wParam, LONG lParam );
LONG LBFindString( HWND hwnd, WORD message, WORD wParam, LONG lParam );
LONG LBGetCaretIndex( HWND hwnd, WORD message, WORD wParam, LONG lParam );
LONG LBGetCount( HWND hwnd, WORD message, WORD wParam, LONG lParam );
LONG LBGetCurSel( HWND hwnd, WORD message, WORD wParam, LONG lParam );
LONG LBGetHorizontalExtent(HWND hwnd, WORD message, WORD wParam, LONG lParam );
LONG LBGetItemData( HWND hwnd, WORD message, WORD wParam, LONG lParam );
LONG LBGetItemHeight( HWND hwnd, WORD message, WORD wParam, LONG lParam );
LONG LBGetItemRect( HWND hwnd, WORD message, WORD wParam, LONG lParam );
LONG LBGetSel( HWND hwnd, WORD message, WORD wParam, LONG lParam );
LONG LBGetSelCount( HWND hwnd, WORD message, WORD wParam, LONG lParam );
LONG LBGetSelItems( HWND hwnd, WORD message, WORD wParam, LONG lParam );
LONG LBGetTextLen( HWND hwnd, WORD message, WORD wParam, LONG lParam );
LONG LBGetTopIndex( HWND hwnd, WORD message, WORD wParam, LONG lParam );
LONG LBSelectString( HWND hwnd, WORD message, WORD wParam, LONG lParam );
LONG LBSelItemRange( HWND hwnd, WORD message, WORD wParam, LONG lParam );
LONG LBSetCaretIndex( HWND hwnd, WORD message, WORD wParam, LONG lParam );
LONG LBSetColumnWidth( HWND hwnd, WORD message, WORD wParam, LONG lParam );
LONG LBSetHorizontalExtent(HWND hwnd, WORD message, WORD wParam, LONG lParam );
LONG LBSetItemData( HWND hwnd, WORD message, WORD wParam, LONG lParam );
LONG LBSetTabStops( HWND hwnd, WORD message, WORD wParam, LONG lParam );
LONG LBSetCurSel( HWND hwnd, WORD message, WORD wParam, LONG lParam );
LONG LBSetSel( HWND hwnd, WORD message, WORD wParam, LONG lParam );
LONG LBSetTopIndex( HWND hwnd, WORD message, WORD wParam, LONG lParam );
LONG LBSetItemHeight( HWND hwnd, WORD message, WORD wParam, LONG lParam );


typedef struct {
  WORD   message;
  LONG  (*handler)(HWND, WORD, WPARAM, LPARAM);
} msg_tbl;

static msg_tbl methods[] = {
  {WM_CREATE, LBCreate},
  {WM_DESTROY, LBDestroy},
  {WM_GETDLGCODE, LBGetDlgCode},
  {WM_VSCROLL, LBVScroll},
  {WM_HSCROLL, LBHScroll},
  {WM_LBUTTONDOWN, LBLButtonDown},
  {WM_LBUTTONUP, LBLButtonUp},
  {WM_RBUTTONUP, LBRButtonUp},
  {WM_LBUTTONDBLCLK, LBRButtonUp},
  {WM_MOUSEMOVE, LBMouseMove},
  {WM_KEYDOWN, LBKeyDown},
  {WM_SETFONT, LBSetFont},
  {WM_SETREDRAW, LBSetRedraw},
  {WM_PAINT, LBPaint},
  {WM_SETFOCUS, LBSetFocus},
  {WM_KILLFOCUS, LBKillFocus},
  {LB_RESETCONTENT, LBResetContent},
  {LB_DIR, LBDir},
  {LB_ADDSTRING, LBAddString},
  {LB_INSERTSTRING, LBInsertString},
  {LB_DELETESTRING, LBDeleteString},
  {LB_FINDSTRING, LBFindString},
  {LB_GETCARETINDEX, LBGetCaretIndex},
  {LB_GETCOUNT, LBGetCount},
  {LB_GETCURSEL, LBGetCurSel},
  {LB_GETHORIZONTALEXTENT, LBGetHorizontalExtent},
  {LB_GETITEMDATA, LBGetItemData},
  {LB_GETITEMHEIGHT, LBGetItemHeight},
  {LB_GETITEMRECT, LBGetItemRect},
  {LB_GETSEL, LBGetSel},
  {LB_GETSELCOUNT, LBGetSelCount},
  {LB_GETSELITEMS, LBGetSelItems},
  {LB_GETTEXT, LBGetText},
  {LB_GETTEXTLEN, LBGetTextLen},
  {LB_GETTOPINDEX, LBGetTopIndex},
  {LB_SELECTSTRING, LBSelectString},
  {LB_SELITEMRANGE, LBSelItemRange},
  {LB_SETCARETINDEX, LBSetCaretIndex},
  {LB_SETCOLUMNWIDTH, LBSetColumnWidth},
  {LB_SETHORIZONTALEXTENT, LBSetHorizontalExtent},
  {LB_SETITEMDATA, LBSetItemData},
  {LB_SETTABSTOPS, LBSetTabStops},
  {LB_SETCURSEL, LBSetCurSel},
  {LB_SETSEL, LBSetSel},
  {LB_SETTOPINDEX, LBSetTopIndex},
  {LB_SETITEMHEIGHT, LBSetItemHeight}
};

/***********************************************************************
 *           LBCreate
 */
LONG LBCreate( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{
  LPHEADLIST  lphl;
  CREATESTRUCT *createStruct;
  WND          *wndPtr;

  CreateListBoxStruct(hwnd);
  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);

  dprintf_listbox(stddeb,"ListBox WM_CREATE %p !\n", lphl);

  if (lphl == NULL) return 0;

  createStruct = (CREATESTRUCT *)PTR_SEG_TO_LIN(lParam);

  if (HIWORD(createStruct->lpCreateParams) != 0)
    lphl->hWndLogicParent = (HWND)HIWORD(createStruct->lpCreateParams);
  else
    lphl->hWndLogicParent = GetParent(hwnd);

  lphl->hFont = GetStockObject(SYSTEM_FONT);
  lphl->ColumnsWidth = wndPtr->rectClient.right - wndPtr->rectClient.left;

  SetScrollRange(hwnd, SB_VERT, 1, ListMaxFirstVisible(lphl), TRUE);
  SetScrollRange(hwnd, SB_HORZ, 1, 1, TRUE);

  return 0;
}

int CreateListBoxStruct(HWND hwnd)

{
  WND  *wndPtr;
  LPHEADLIST lphl;

  wndPtr = WIN_FindWndPtr(hwnd);

  lphl = (LPHEADLIST)malloc(sizeof(HEADLIST));
  *((LPHEADLIST *)&wndPtr->wExtra[1]) = lphl;

  lphl->lpFirst        = NULL;
  lphl->ItemsCount     = 0;
  lphl->ItemsVisible   = 0;
  lphl->FirstVisible   = 1;
  lphl->ColumnsVisible = 1;
  lphl->ItemsPerColumn = 0;
  lphl->StdItemHeight  = 15;
  lphl->ItemFocused    = -1;
  lphl->PrevFocused    = -1;
  lphl->DrawCtlType    = ODT_LISTBOX;
  lphl->bRedrawFlag    = TRUE;
  lphl->iNumStops      = 0;
  lphl->TabStops       = NULL;

  if (OWNER_DRAWN(wndPtr)) 
    lphl->hDrawItemStruct = USER_HEAP_ALLOC(sizeof(DRAWITEMSTRUCT));
  else
    lphl->hDrawItemStruct = 0;

#if 0
  HeapHandle = GlobalAlloc(GMEM_FIXED, LIST_HEAP_SIZE);
  HeapBase = GlobalLock(HeapHandle);
  HEAP_Init(&lphl->Heap, HeapBase, LIST_HEAP_SIZE);
#endif
  return TRUE;
}


/***********************************************************************
 *           LBDestroy
 */
LONG LBDestroy( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{
  LPHEADLIST lphl;
  WND        *wndPtr;

  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);

  if (lphl == NULL) return 0;
  ListBoxResetContent(hwnd);

  if (lphl->hDrawItemStruct)
    USER_HEAP_FREE(lphl->hDrawItemStruct);

  /* XXX need to free lphl->Heap */
  free(lphl);
  *((LPHEADLIST *)&wndPtr->wExtra[1]) = 0;
  dprintf_listbox(stddeb,"ListBox WM_DESTROY %p !\n", lphl);
  return 0;
}

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


/***********************************************************************
 *           LBVScroll
 */
LONG LBVScroll( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{
  LPHEADLIST lphl;
  int  y;

  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;
}

/***********************************************************************
 *           LBHScroll
 */
LONG LBHScroll( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{
  LPHEADLIST lphl;
  int        y;

  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;
}

/***********************************************************************
 *           LBLButtonDown
 */
LONG LBLButtonDown( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{
  LPHEADLIST lphl;
  WND        *wndPtr;
  WORD       wRet;
  int        y;
  RECT       rectsel;

  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) {
    lphl->ItemFocused = y;
    wRet = ListBoxGetSel(hwnd, y);
    ListBoxSetSel(hwnd, y, !wRet);
  }
  else
    ListBoxSetCurSel(hwnd, y);

  if (wndPtr->dwStyle & LBS_MULTIPLESEL)
    ListBoxSendNotification( hwnd, LBN_SELCHANGE );

  ListBoxGetItemRect(hwnd, y, &rectsel);

  InvalidateRect(hwnd, NULL, TRUE);
  UpdateWindow(hwnd);

  return 0;
}

/***********************************************************************
 *           LBLButtonUp
 */
LONG LBLButtonUp( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{
  LPHEADLIST lphl;
  WND        *wndPtr;

  ReleaseCapture();

  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
  if (lphl == NULL) return 0;
  if (lphl->PrevFocused != lphl->ItemFocused)
    ListBoxSendNotification( hwnd, LBN_SELCHANGE );

  return 0;
}

/***********************************************************************
 *           LBRButtonUp
 */
LONG LBRButtonUp( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{
  LPHEADLIST lphl;
  WND        *wndPtr;
  
  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
  if (lphl == NULL) return 0;
  SendMessage(lphl->hWndLogicParent, WM_COMMAND, wndPtr->wIDmenu,
		MAKELONG(hwnd, LBN_DBLCLK));

  return 0;
}

/***********************************************************************
 *           LBMouseMove
 */
LONG LBMouseMove( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{
  LPHEADLIST  lphl;
  WND        *wndPtr;
  int  y;
  WORD        wRet;
  RECT        rect, rectsel;   /* XXX Broken */

  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);
	return 0;
      }
    }
    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);
	return 0;
      }
    }
    if ((y > 0) && (y < (rect.bottom - 4))) {
      if ((y < rectsel.top) || (y > rectsel.bottom)) {
	wRet = ListBoxFindMouse(hwnd, LOWORD(lParam), HIWORD(lParam));
	if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) {
	  lphl->ItemFocused = wRet;
	  ListBoxSendNotification(hwnd, LBN_SELCHANGE);
	}
	else
	  ListBoxSetCurSel(hwnd, wRet);
	ListBoxGetItemRect(hwnd, wRet, &rectsel);
	InvalidateRect(hwnd, NULL, TRUE);
	UpdateWindow(hwnd);
      }
    }
  }

  return 0;
}

/***********************************************************************
 *           LBKeyDown
 */
LONG LBKeyDown( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{
  LPHEADLIST  lphl;
  WND        *wndPtr;
  HWND        hWndCtl;
  WORD        wRet;

  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;

  if (lphl->ItemsVisible != 0)
    lphl->FirstVisible = lphl->ItemFocused / lphl->ItemsVisible * 
      lphl->ItemsVisible + 1;

  if (lphl->FirstVisible < 1) lphl->FirstVisible = 1;
  if (lphl->FirstVisible > ListMaxFirstVisible(lphl))
    lphl->FirstVisible = ListMaxFirstVisible(lphl);

  if ((wndPtr->dwStyle & LBS_MULTIPLESEL) != LBS_MULTIPLESEL) {
    ListBoxSetCurSel(hwnd, lphl->ItemFocused);
    ListBoxSendNotification(hwnd, LBN_SELCHANGE);
  }

  SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
  InvalidateRect(hwnd, NULL, TRUE);
  UpdateWindow(hwnd);

  return 0;
}

/***********************************************************************
 *           LBSetRedraw
 */
LONG LBSetRedraw( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{
  LPHEADLIST  lphl;
  WND        *wndPtr;

  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;

  return 0;
}

/***********************************************************************
 *           LBSetFont
 */

LONG LBSetFont( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{
  LPHEADLIST  lphl;
  WND        *wndPtr;

  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
  if (lphl == NULL) return 0;

  if (wParam == 0)
    lphl->hFont = GetStockObject(SYSTEM_FONT);
  else
    lphl->hFont = wParam;

  return 0;
}

/***********************************************************************
 *           LBPaint
 */
LONG LBPaint( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{
  RepaintListBox(hwnd);
  return 0;
}

/***********************************************************************
 *           LBSetFocus
 */
LONG LBSetFocus( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{
  LPHEADLIST lphl;
  WND       *wndPtr;

  dprintf_listbox(stddeb,"ListBox WM_SETFOCUS !\n");
  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);

  return 0;
}

/***********************************************************************
 *           LBKillFocus
 */
LONG LBKillFocus( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{
  dprintf_listbox(stddeb,"ListBox WM_KILLFOCUS !\n");

  InvalidateRect(hwnd, NULL, TRUE);
  UpdateWindow(hwnd);
  
  return 0;
}

/***********************************************************************
 *           LBResetContent
 */
LONG LBResetContent( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{
  dprintf_listbox(stddeb,"ListBox LB_RESETCONTENT !\n");
  ListBoxResetContent(hwnd);

  return 0;
}

/***********************************************************************
 *           LBDir
 */
LONG LBDir( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{
  WORD   wRet;
  dprintf_listbox(stddeb,"ListBox LB_DIR !\n");

  wRet = ListBoxDirectory(hwnd, wParam,
			  (LPSTR)PTR_SEG_TO_LIN(lParam));
  InvalidateRect(hwnd, NULL, TRUE);
  UpdateWindow(hwnd);
  return wRet;
}

/***********************************************************************
 *           LBAddString
 */
LONG LBAddString( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{
  WORD  wRet;
  WND  *wndPtr;

  wndPtr = WIN_FindWndPtr(hwnd);

  if (HasStrings(wndPtr))
    wRet = ListBoxAddString(hwnd, (LPSTR)PTR_SEG_TO_LIN(lParam));
  else
    wRet = ListBoxAddString(hwnd, (LPSTR)lParam);

  return wRet;
}

/***********************************************************************
 *           LBGetText
 */
LONG LBGetText( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{
  LONG   wRet;

  dprintf_listbox(stddeb, "LB_GETTEXT  wParam=%d\n",wParam);
  wRet = ListBoxGetText(hwnd, wParam,
			(LPSTR)PTR_SEG_TO_LIN(lParam), FALSE);

  return wRet;
}

/***********************************************************************
 *           LBInsertString
 */
LONG LBInsertString( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{
  WORD  wRet;
  WND  *wndPtr;

  wndPtr = WIN_FindWndPtr(hwnd);

  if (HasStrings(wndPtr))
    wRet = ListBoxInsertString(hwnd, wParam, (LPSTR)PTR_SEG_TO_LIN(lParam));
  else
    wRet = ListBoxInsertString(hwnd, wParam, (LPSTR)lParam);

  return wRet;
}

/***********************************************************************
 *           LBDeleteString
 */    
LONG LBDeleteString( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{
  return ListBoxDeleteString(hwnd, wParam); 
}

/***********************************************************************
 *           LBFindString
 */
LONG LBFindString( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{
  return ListBoxFindString(hwnd, wParam,
			   (LPSTR)PTR_SEG_TO_LIN(lParam));
}

/***********************************************************************
 *           LBGetCaretIndex
 */
LONG LBGetCaretIndex( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{
  LPHEADLIST  lphl;

  lphl = ListBoxGetStorageHeader(hwnd);
  if (lphl == NULL) return LB_ERR;

  return lphl->ItemFocused;
}

/***********************************************************************
 *           LBGetCount
 */
LONG LBGetCount( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{
  LPHEADLIST  lphl;

  lphl = ListBoxGetStorageHeader(hwnd);
  return lphl->ItemsCount;
}

/***********************************************************************
 *           LBGetCurSel
 */
LONG LBGetCurSel( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{
  LPHEADLIST  lphl;

  lphl = ListBoxGetStorageHeader(hwnd);
  dprintf_listbox(stddeb,"ListBox LB_GETCURSEL %u !\n", 
		  lphl->ItemFocused);
  return lphl->ItemFocused;
}

/***********************************************************************
 *           LBGetHorizontalExtent
 */
LONG LBGetHorizontalExtent( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{    
  return 0;
}

/***********************************************************************
 *           LBGetItemData
 */
LONG LBGetItemData( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{
    dprintf_listbox(stddeb, "LB_GETITEMDATA wParam=%x\n", wParam);
    return ListBoxGetText(hwnd, wParam,
			  (LPSTR)PTR_SEG_TO_LIN(lParam), TRUE);
}

/***********************************************************************
 *           LBGetItemHeight
 */
LONG LBGetItemHeight( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{
  RECT   rect;

  ListBoxGetItemRect(hwnd, wParam, &rect);
  return (rect.bottom - rect.top);
}

/***********************************************************************
 *           LBGetItemRect
 */
LONG LBGetItemRect( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{
  return ListBoxGetItemRect (hwnd, wParam, PTR_SEG_TO_LIN(lParam));
}

/***********************************************************************
 *           LBGetSel
 */
LONG LBGetSel( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{
  return ListBoxGetSel (hwnd, wParam);
}

/***********************************************************************
 *           LBGetSelCount
 */
LONG LBGetSelCount( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{
  LPHEADLIST   lphl;
  LPLISTSTRUCT lpls;
  int          cnt = 0;
  WND        *wndPtr;

  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
  if (lphl == NULL) return LB_ERR;

  if (!(wndPtr->dwStyle & LBS_MULTIPLESEL)) return LB_ERR;

  lpls = lphl->lpFirst;

  while (lpls != NULL) {
    if (lpls->dis.itemState > 0) cnt++;

    lpls = lpls->lpNext;
  }

  return cnt;
}

/***********************************************************************
 *           LBGetSelItems
 */
LONG LBGetSelItems( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{
  LPHEADLIST   lphl;
  LPLISTSTRUCT lpls;
  int          cnt, idx;
  WND         *wndPtr;
  int         *lpItems = PTR_SEG_TO_LIN(lParam);

  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
  if (lphl == NULL) return LB_ERR;

  if (!(wndPtr->dwStyle & LBS_MULTIPLESEL)) return LB_ERR;

  if (wParam == 0) return 0;

  lpls = lphl->lpFirst;
  cnt = 0; idx = 0;

  while (lpls != NULL) {
    if (lpls->dis.itemState > 0) lpItems[cnt++] = idx;

    if (cnt == wParam) break;
    idx++;
    lpls = lpls->lpNext;
  }

  return cnt;
}

/***********************************************************************
 *           LBGetTextLen
 */
LONG LBGetTextLen( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{
  LPHEADLIST   lphl;
  LPLISTSTRUCT lpls;
  WND         *wndPtr;
  int          cnt = 0;

  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
  if (lphl == NULL) return LB_ERR;

  if (!HasStrings(wndPtr)) return LB_ERR;

  if (wParam >= lphl->ItemsCount) return LB_ERR;
    
  lpls = lphl->lpFirst;

  while (cnt++ < wParam) lpls = lpls->lpNext;
  
  return strlen(lpls->itemText);
}

/***********************************************************************
 *           LBGetDlgCode
 */
LONG LBGetDlgCode( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{
  return DLGC_WANTALLKEYS;
}

/***********************************************************************
 *           LBGetTopIndex
 */
LONG LBGetTopIndex( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{
  LPHEADLIST lphl;

  lphl = ListBoxGetStorageHeader(hwnd);
  if (lphl == NULL) return LB_ERR;

  return (lphl->FirstVisible - 1);
}


/***********************************************************************
 *           LBSelectString
 */
LONG LBSelectString( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{
  WND  *wndPtr;
  WORD  wRet;

  wndPtr = WIN_FindWndPtr(hwnd);

  wRet = ListBoxFindString(hwnd, wParam,
			   (LPSTR)PTR_SEG_TO_LIN(lParam));

  /* XXX add functionality here */

  return 0;
}

/***********************************************************************
 *           LBSelItemRange
 */
LONG LBSelItemRange( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{
  LPHEADLIST   lphl;
  LPLISTSTRUCT lpls;
  WND         *wndPtr;
  WORD         cnt;
  WORD         first = LOWORD(lParam);
  WORD         last = HIWORD(lParam);
  BOOL         select = wParam;

  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
  if (lphl == NULL) return LB_ERR;

  if (!(wndPtr->dwStyle & LBS_MULTIPLESEL)) return LB_ERR;

  if (first >= lphl->ItemsCount ||
      last >= lphl->ItemsCount) return LB_ERR;

  lpls = lphl->lpFirst;
  cnt = 0;

  while (lpls != NULL) {
    if (cnt++ >= first)
      lpls->dis.itemState = select ? ODS_SELECTED : 0;

    if (cnt > last)
      break;

    lpls = lpls->lpNext;
  }

  return 0;
}

/***********************************************************************
 *           LBSetCaretIndex
 */
LONG LBSetCaretIndex( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{
  LPHEADLIST   lphl;
  WND         *wndPtr;

  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
  if (lphl == NULL) return LB_ERR;

  if (!(wndPtr->dwStyle & LBS_MULTIPLESEL)) return 0;
  if (wParam >= lphl->ItemsCount) return LB_ERR;

  lphl->ItemFocused = wParam;
  ListBoxScrolltoFocus (hwnd);

  SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
  InvalidateRect(hwnd, NULL, TRUE);
  UpdateWindow(hwnd);
  return 0;
}

/***********************************************************************
 *           LBSetColumnWidth
 */
LONG LBSetColumnWidth( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{
  LPHEADLIST   lphl;

  lphl = ListBoxGetStorageHeader(hwnd);
  if (lphl == NULL) return LB_ERR;
  lphl->ColumnsWidth = wParam;

  return 0;
}

/***********************************************************************
 *           LBSetHorizontalExtent
 */
LONG LBSetHorizontalExtent( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{
  return 0;
}

/***********************************************************************
 *           LBSetItemData
 */
LONG LBSetItemData( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{
  dprintf_listbox(stddeb, "LB_SETITEMDATA  wParam=%x  lParam=%lx\n", wParam, lParam);
  return ListBoxSetItemData(hwnd, wParam, lParam);
}

/***********************************************************************
 *           LBSetTabStops
 */
LONG LBSetTabStops( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{
  LPHEADLIST  lphl;

  lphl = ListBoxGetStorageHeader(hwnd);

  if (lphl->TabStops != NULL) {
    lphl->iNumStops = 0;
    free (lphl->TabStops);
  }

  lphl->TabStops = malloc (wParam * sizeof (short));
  if (lphl->TabStops) {
    lphl->iNumStops = wParam;
    memcpy (lphl->TabStops, PTR_SEG_TO_LIN(lParam), wParam * sizeof (short));
    return TRUE;
  }

  return FALSE;
}

/***********************************************************************
 *           LBSetCurSel
 */
LONG LBSetCurSel( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{
  LPHEADLIST  lphl;
  WORD  wRet;

  lphl = ListBoxGetStorageHeader(hwnd);
  if (lphl == NULL) return LB_ERR; 

  dprintf_listbox(stddeb,"ListBox LB_SETCURSEL wParam=%x !\n", 
		  wParam);

  wRet = ListBoxSetCurSel(hwnd, wParam);

  SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
  InvalidateRect(hwnd, NULL, TRUE);
  UpdateWindow(hwnd);

  return wRet;
}

/***********************************************************************
 *           LBSetSel
 */
LONG LBSetSel( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{
  WORD wRet;

  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;
}

/***********************************************************************
 *           LBSetTopIndex
 */
LONG LBSetTopIndex( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{
  LPHEADLIST lphl;

  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);

  return 0;
}

/***********************************************************************
 *           LBSetItemHeight
 */
LONG LBSetItemHeight( HWND hwnd, WORD message, WORD wParam, LONG lParam)

{
  WORD  wRet;

  dprintf_listbox(stddeb,"ListBox LB_SETITEMHEIGHT wParam=%x lParam=%lX !\n", wParam, lParam);
  wRet = ListBoxSetItemHeight(hwnd, wParam, lParam);
  return wRet;
}


/***********************************************************************
 *           ListBoxWndProc 
 */

LONG ListBoxWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam )

{ 
  int idx = 0;
  int table_size = sizeof (methods) / sizeof (msg_tbl);

  while (idx < table_size) {
    if (message == methods[idx].message) {
      return (*(methods[idx].handler))(hwnd, message, wParam, lParam);
    }
    idx++;
  }
  
  return DefWindowProc (hwnd, message, wParam, lParam);
}


LPLISTSTRUCT ListBoxGetItem(HWND hwnd, UINT uIndex)

{
  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
  LPLISTSTRUCT lpls;
  UINT         Count = 0;

  if (uIndex >= lphl->ItemsCount) return NULL;

  lpls = lphl->lpFirst;

  while (Count++ < uIndex) lpls = lpls->lpNext;

  return lpls;
}

 
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 ListBoxDrawItem (HWND hwnd, HDC hdc, LPLISTSTRUCT lpls,
		      WORD itemAction, WORD itemState)

{
  LPHEADLIST  lphl;
  WND        *wndPtr;

  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);

  if (OWNER_DRAWN(wndPtr)) {
    DRAWITEMSTRUCT   *dis = USER_HEAP_LIN_ADDR(lphl->hDrawItemStruct);

    memcpy (dis, &lpls->dis, sizeof(DRAWITEMSTRUCT));

    dis->CtlType  = ODT_LISTBOX;
    dis->hDC      = hdc;

    if ((!dis->CtlID) && lphl->hWndLogicParent) {
      WND   *ParentWndPtr;

      ParentWndPtr = WIN_FindWndPtr(lphl->hWndLogicParent);
      dis->CtlID   = ParentWndPtr->wIDmenu;
    }

    if (HasStrings(wndPtr)) dis->itemData = (DWORD)lpls->itemText;
   
    dis->itemAction = itemAction;
    dis->itemState  = itemState;

    SendMessage(lphl->hWndLogicParent, WM_DRAWITEM, 
		0, (LPARAM)USER_HEAP_SEG_ADDR(lphl->hDrawItemStruct));
  }
  else {

    if (itemAction == ODA_DRAWENTIRE ||
	itemAction == ODA_SELECT) {
      int 	OldBkMode;
      DWORD 	dwOldTextColor;

      OldBkMode = SetBkMode(hdc, TRANSPARENT);

      if (itemState != 0) {
	dwOldTextColor = SetTextColor(hdc, 0x00FFFFFFL);
	FillRect(hdc, &lpls->dis.rcItem, GetStockObject(BLACK_BRUSH));
      }

      if (wndPtr->dwStyle & LBS_USETABSTOPS)
	TabbedTextOut(hdc, lpls->dis.rcItem.left + 5, 
		      lpls->dis.rcItem.top + 2, 
		      (char *)lpls->itemText, 
		      strlen((char *)lpls->itemText), lphl->iNumStops,
		      lphl->TabStops, 0);
      else
	TextOut(hdc, lpls->dis.rcItem.left + 5, lpls->dis.rcItem.top + 2, 
		(char *)lpls->itemText, strlen((char *)lpls->itemText));

      if (itemState != 0) {
	SetTextColor(hdc, dwOldTextColor);
      }
      
      SetBkMode(hdc, OldBkMode);
    } else DrawFocusRect(hdc, &lpls->dis.rcItem);
  }

  return;
}

void RepaintListBox(HWND hwnd)

{
  WND 	*wndPtr;
  LPHEADLIST  lphl;
  LPLISTSTRUCT lpls;
  PAINTSTRUCT ps;
  HBRUSH 	hBrush;

  HDC 	hdc;
  RECT 	rect;
  int   i, top, height, maxwidth, ipc;

  top = 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;

  lphl->ItemsVisible = 0;
  lphl->ItemsPerColumn = ipc = 0;

  for(i = 0; i < lphl->ItemsCount; i++) {
    if (lpls == NULL) goto EndOfPaint;

    if (i >= lphl->FirstVisible - 1) {
      height = lpls->dis.rcItem.bottom - lpls->dis.rcItem.top;

      if (top > rect.bottom) {
	if ((wndPtr->dwStyle & LBS_MULTICOLUMN) == LBS_MULTICOLUMN) {
	  lphl->ItemsPerColumn = max(lphl->ItemsPerColumn, ipc);
	  ipc = 0;
	  top = 0;
	  rect.left += lphl->ColumnsWidth;
	  rect.right += lphl->ColumnsWidth;
	  if (rect.left > maxwidth) break;
	}
	else 
	  break;
      }

      lpls->dis.rcItem.top    = top;
      lpls->dis.rcItem.bottom = top + height;
      lpls->dis.rcItem.left   = rect.left;
      lpls->dis.rcItem.right  = rect.right;

      if (OWNER_DRAWN(wndPtr)) {
	ListBoxDrawItem (hwnd, hdc, lpls, ODA_DRAWENTIRE, 0);
	if (lpls->dis.itemState)
	  ListBoxDrawItem (hwnd, hdc, lpls, ODA_SELECT, ODS_SELECTED);
      }
      else 
	ListBoxDrawItem (hwnd, hdc, lpls, ODA_DRAWENTIRE, lpls->dis.itemState);

      if ((lphl->ItemFocused == i) && GetFocus() == hwnd)
	ListBoxDrawItem (hwnd, hdc, lpls, ODA_FOCUS, ODS_FOCUS);

      top += height;
      lphl->ItemsVisible++;
      ipc++;
    }

    lpls = 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);
}

void ListBoxAskMeasure(WND *wndPtr, LPHEADLIST lphl, LPLISTSTRUCT lpls)  

{
  MEASUREITEMSTRUCT 	*lpmeasure;

  HANDLE hTemp = USER_HEAP_ALLOC( sizeof(MEASUREITEMSTRUCT) );

  lpmeasure = (MEASUREITEMSTRUCT *) USER_HEAP_LIN_ADDR(hTemp);

  if (lpmeasure == NULL) {
    fprintf(stderr,"ListBoxAskMeasure() // Bad allocation of Measure struct !\n");
    return;
  }
 
  lpmeasure->CtlType    = ODT_LISTBOX;
  lpmeasure->CtlID      = wndPtr->wIDmenu;
  lpmeasure->itemID     = lpls->dis.itemID;
  lpmeasure->itemWidth  = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
  lpmeasure->itemHeight = 0;

  if (HasStrings(wndPtr))
    lpmeasure->itemData = (DWORD)lpls->itemText;
  else
    lpmeasure->itemData = lpls->dis.itemData;

  SendMessage(lphl->hWndLogicParent, WM_MEASUREITEM,
	      0, USER_HEAP_SEG_ADDR(hTemp));

  if (wndPtr->dwStyle & LBS_OWNERDRAWFIXED) {
    lphl->StdItemHeight = lpmeasure->itemHeight;
  }

  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_OWNERDRAWFIXED) && (lphl->ItemsCount == 1)) {
    ListBoxAskMeasure(wndPtr, lphl, lplsnew);
  }

  if (wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE)
    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;
  LPLISTSTRUCT lpls;

  wndPtr = WIN_FindWndPtr(hwnd);

  if (!OutStr && !bItemData) {
    dprintf_listbox(stddeb, "ListBoxGetText // OutStr==NULL\n");
    return 0;
  }

  if (!bItemData) *OutStr=0;

  if ((lpls = ListBoxGetItem (hwnd, uIndex)) == NULL) 
    return 0;

  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)

{
  LPLISTSTRUCT lpls;

  if ((lpls = ListBoxGetItem(hwnd, uIndex)) == NULL)
    return 0;

  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 == 0 )
    lphl->lpFirst = lpls->lpNext;
  else {
    for(Count = 0; Count < uIndex; Count++) {
      if (lpls->lpNext == NULL) return LB_ERR;

      lpls2 = lpls;
      lpls = (LPLISTSTRUCT)lpls->lpNext;
    }
    lpls2->lpNext = (LPLISTSTRUCT)lpls->lpNext;
  }

  lphl->ItemsCount--;

  if (lpls->hData != 0) LIST_HEAP_FREE(lphl, lpls->hData);
  if (lpls->hMem != 0) LIST_HEAP_FREE(lphl, lpls->hMem);

  SetScrollRange(hwnd, SB_VERT, 1, ListMaxFirstVisible(lphl), TRUE);
  if (lphl->ItemsPerColumn != 0)
    SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible / 
		   lphl->ItemsPerColumn + 1, TRUE);

  if ((lphl->FirstVisible <= uIndex) &&
      ((lphl->FirstVisible + lphl->ItemsVisible) >= uIndex)) {
    InvalidateRect(hwnd, NULL, TRUE);
    UpdateWindow(hwnd);
  }

  return lphl->ItemsCount;
}


int ListBoxFindString(HWND hwnd, UINT nFirst, LPSTR MatchStr)
{
  WND          *wndPtr;
  LPHEADLIST   lphl;
  LPLISTSTRUCT lpls;
  UINT	       Count;
  UINT         First = nFirst + 1;

  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);

  if (lphl == NULL) return LB_ERR;

  if (First > lphl->ItemsCount) return LB_ERR;
 
  lpls = ListBoxGetItem(hwnd, First);
  Count = 0;
  while(lpls != NULL) {
    if (HasStrings(wndPtr)) {
      if (strstr(lpls->itemText, MatchStr) == lpls->itemText) return Count;
    } else if (wndPtr->dwStyle & LBS_SORT) {
      /* XXX Do a compare item */
    }
    else
      if (lpls->dis.itemData == (DWORD)MatchStr) return Count;

    lpls = lpls->lpNext;
    Count++;
  }

  /* Start over at top */
  Count = 0;
  lpls = lphl->lpFirst;

  while (Count < First) {
    if (HasStrings(wndPtr)) {
      if (strstr(lpls->itemText, MatchStr) == lpls->itemText) return Count;
    } else if (wndPtr->dwStyle & LBS_SORT) {
      /* XXX Do a compare item */
    }
    else
      if (lpls->dis.itemData == (DWORD)MatchStr) return Count;

    lpls = lpls->lpNext;
    Count++;
  }

  return LB_ERR;
}


int ListBoxResetContent(HWND hwnd)
{
    WND  *wndPtr;
    LPHEADLIST 	lphl;
    LPLISTSTRUCT lpls;
    UINT	i;

    lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
    if (lphl == NULL) return LB_ERR;

    if (lphl->ItemsCount == 0) return 0;

    lpls = lphl->lpFirst;

    dprintf_listbox(stddeb, "ListBoxResetContent // ItemCount = %d\n",
	lphl->ItemsCount);

    for(i = 0; i < lphl->ItemsCount; i++) {
      LPLISTSTRUCT lpls2;

      if (lpls == NULL) return LB_ERR;

      lpls2 = lpls->lpNext;

      if (i != 0) {
	dprintf_listbox(stddeb,"ResetContent #%u\n", i);
	if (lpls->hData != 0 && lpls->hData != lpls->hMem)
	  LIST_HEAP_FREE(lphl, lpls->hData);

	if (lpls->hMem != 0) LIST_HEAP_FREE(lphl, lpls->hMem);
      }  

      lpls = lpls2;
    }

    lphl->lpFirst      = NULL;
    lphl->FirstVisible = 1;
    lphl->ItemsCount   = 0;
    lphl->ItemFocused  = -1;
    lphl->PrevFocused  = -1;

    SetScrollRange(hwnd, SB_VERT, 1, ListMaxFirstVisible(lphl), TRUE);

    if (lphl->ItemsPerColumn != 0)
	SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible / 
	    lphl->ItemsPerColumn + 1, TRUE);

    InvalidateRect(hwnd, NULL, TRUE);
    UpdateWindow(hwnd);

    return TRUE;
}


int ListBoxSetCurSel(HWND hwnd, WORD wIndex)

{
  WND  *wndPtr;
  LPHEADLIST 	lphl;
  LPLISTSTRUCT lpls;

  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
  if (lphl == NULL) return LB_ERR;

  if (wndPtr->dwStyle & LBS_MULTIPLESEL) return 0;

  if (lphl->ItemFocused != -1) {
    lpls = ListBoxGetItem(hwnd, lphl->ItemFocused);
    lpls->dis.itemState = 0;
  }

  if (wIndex != (UINT)-1) {
    lphl->ItemFocused = wIndex;
    lpls = ListBoxGetItem(hwnd, wIndex);
    lpls->dis.itemState = ODS_SELECTED | ODS_FOCUS;

    return 0;
  }

  return LB_ERR;
}

int ListBoxSetSel(HWND hwnd, WORD wIndex, WORD state)

{
  LPHEADLIST 	lphl;
  LPLISTSTRUCT lpls;
  WND         *wndPtr;

  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
  if (lphl == NULL) return LB_ERR;

  if (!(wndPtr->dwStyle & LBS_MULTIPLESEL)) return 0;

  if (wIndex == (UINT)-1) {
    lpls = lphl->lpFirst;

    while (lpls != NULL) {
      lpls->dis.itemState = state;
      lpls = lpls->lpNext;
    }

    return 0;
  }

  if (wIndex >= lphl->ItemsCount) return LB_ERR;

  lpls = ListBoxGetItem(hwnd, wIndex);
  lpls->dis.itemState = state;

  return 0;
}


int ListBoxGetSel(HWND hwnd, WORD wIndex)
{
  LPLISTSTRUCT lpls;

  if ((lpls = ListBoxGetItem(hwnd, wIndex)) == NULL) return LB_ERR;

  return lpls->dis.itemState;
}


int ListBoxDirectory(HWND hwnd, UINT attrib, LPSTR filespec)
{
  struct dosdirent *dp, *dp_old;
  int	x, wRet = LB_OKAY;
  BOOL    OldFlag;
  char 	temp[256];
  LPHEADLIST 	lphl;
  int drive;

  dprintf_listbox(stddeb,"ListBoxDirectory: %s, %4x\n",filespec,attrib);

  if( strchr( filespec, '\\' ) || strchr( filespec, ':' ) ) {
    drive = DOS_GetDefaultDrive();
    if( filespec[1] == ':' ) {
      drive = toupper(filespec[0]) - 'A';
      filespec += 2;
    }
    if( !strchr( filespec, '\\' ) ) 
      DOS_SetDefaultDrive( drive );
    else {
      int i;
      strcpy( temp, filespec );
      for( i=0; i<strlen(temp); i++ )
	if( temp[i] == '\\' ) {
	  temp[i] = 0;
	  filespec += ( i+1 );
	  break;
	}
      DOS_ChangeDir( drive, temp );
      DOS_SetDefaultDrive( drive );
    }
    dprintf_listbox(stddeb,"Changing directory to %c:%s, filemask is %s\n",
		    drive+'A', temp, filespec );
  }
  lphl = ListBoxGetStorageHeader(hwnd);
  if (lphl == NULL) return LB_ERR;
  if ((dp = (struct dosdirent *)DOS_opendir(filespec)) ==NULL) return 0;
  dp_old = dp;
  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_old);
  
  if (attrib & DDL_DRIVES) {
    for (x=0;x!=MAX_DOS_DRIVES;x++) {
      if (DOS_ValidDrive(x)) {
	sprintf(temp, "[-%c-]", 'a'+x);
	if((wRet = ListBoxInsertString(hwnd, (UINT)-1, temp)) == LB_ERR) break;
      }		
    }
  }
  lphl->bRedrawFlag = OldFlag;
  if (OldFlag) {
    InvalidateRect(hwnd, NULL, TRUE);
    UpdateWindow(hwnd);
  }
  dprintf_listbox(stddeb,"End of ListBoxDirectory !\n");
  return 1;  /* FIXME: Should be 0 if "filespec" is invalid */
}


int ListBoxGetItemRect(HWND hwnd, WORD wIndex, LPRECT lprect)

{
  LPLISTSTRUCT lpls;

  if ((lpls = ListBoxGetItem(hwnd, wIndex)) == NULL) return LB_ERR;

  *(lprect) = lpls->dis.rcItem;

  return 0;
}


int ListBoxSetItemHeight(HWND hwnd, WORD wIndex, long height)

{
  LPHEADLIST    lphl;
  WND          *wndPtr;
  LPLISTSTRUCT  lpls;

  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
  if (lphl == NULL) return LB_ERR;

  if (!(wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE)) {
    lphl->StdItemHeight = (short)height;
    InvalidateRect(hwnd, NULL, TRUE);
    UpdateWindow(hwnd);

    return 0;
  }

  if ((lpls = ListBoxGetItem(hwnd, wIndex)) == NULL) return LB_ERR;
  
  lpls->dis.rcItem.bottom = lpls->dis.rcItem.top + (short)height;
  InvalidateRect(hwnd, NULL, TRUE);
  UpdateWindow(hwnd);

  return 0;
}

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 (!HasStrings(wndPtr)) return LB_ERR;

  Count = 0;
  while(lpls != NULL) {
    if (Count > lphl->ItemFocused) {
      if (*(lpls->itemText) == (char)wChar) {
	if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) {
	  lphl->ItemFocused = Count;
	  ListBoxScrolltoFocus(hwnd);
	}
	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;

      if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) {
	lphl->ItemFocused = Count;
	ListBoxScrolltoFocus(hwnd);
      }
      else {
	ListBoxSetCurSel(hwnd, Count);
      }
      SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
      InvalidateRect(hwnd, NULL, TRUE);
      UpdateWindow(hwnd);
      return Count;
    }
    lpls = lpls->lpNext;
    Count++;
  }
  return LB_ERR;
}


/************************************************************************
 * 		      	DlgDirSelect			[USER.99]
 */
BOOL DlgDirSelect(HWND hDlg, LPSTR lpStr, int nIDLBox)
{
  HWND hwnd;
  LPHEADLIST lphl;
  char s[130];

  dprintf_listbox( stddeb, "DlgDirSelect(%04X, '%s', %d) \n", hDlg, lpStr, 
		  nIDLBox );

  hwnd = GetDlgItem(hDlg, nIDLBox);
  lphl = ListBoxGetStorageHeader(hwnd);
  if( lphl->ItemFocused == -1 ) {
    dprintf_listbox( stddeb, "Nothing selected!\n" );
    return FALSE;
  }
  ListBoxGetText(hwnd, lphl->ItemFocused, (LPSTR)s, FALSE);
  dprintf_listbox( stddeb, "Selection is %s\n", s );
  if( s[0] == '[' ) {
    if( s[1] == '-' ) {
      strncpy( lpStr, s+2, strlen(s)-4 );    /* device name */
      lpStr[ strlen(s)-4 ] = 0;
      strcat( lpStr, ":" );
    }
    else {
      strncpy( lpStr, s+1, strlen(s)-2 );    /* directory name */
      lpStr[ strlen(s)-2 ] = 0;
      strcat( lpStr, "\\" );
    }
    dprintf_listbox( stddeb, "Returning %s\n", lpStr );
    return TRUE;
  }
  else {
    strcpy( lpStr, s );                     /* file name */
    dprintf_listbox( stddeb, "Returning %s\n", lpStr );
    return FALSE;
  }
}


/************************************************************************
 * 			   DlgDirList				[USER.100]
 */
int DlgDirList(HWND hDlg, LPSTR lpPathSpec, 
	int nIDLBox, int nIDStat, WORD wType)
{
  HWND	hWnd;
  int ret;
  dprintf_listbox(stddeb,"DlgDirList(%04X, '%s', %d, %d, %04X) \n",
		  hDlg, lpPathSpec, nIDLBox, nIDStat, wType);
  if (nIDLBox)
    hWnd = GetDlgItem(hDlg, nIDLBox);
  else
    hWnd = 0;
  if (hWnd)
    ListBoxResetContent(hWnd);
  if (hWnd)
    ret=ListBoxDirectory(hWnd, wType, lpPathSpec);
  else
    ret=0;
  if (nIDStat)
    {
      int drive;
      HANDLE hTemp;
      char *temp;
      drive = DOS_GetDefaultDrive();
      hTemp = USER_HEAP_ALLOC( 256 );
      temp = (char *) USER_HEAP_LIN_ADDR( hTemp );
      strcpy( temp+3, DOS_GetCurrentDir(drive) );
      if( temp[3] == '\\' ) {
	temp[1] = 'A'+drive;
	temp[2] = ':';
	SendDlgItemMessage( hDlg, nIDStat, WM_SETTEXT, 0,
                            USER_HEAP_SEG_ADDR(hTemp) + 1 );
      }
      else {
	temp[0] = 'A'+drive;
	temp[1] = ':';
	temp[2] = '\\';
	SendDlgItemMessage( hDlg, nIDStat, WM_SETTEXT, 0,
                            USER_HEAP_SEG_ADDR(hTemp) );
      }
      USER_HEAP_FREE( hTemp );
    } 
  return ret;
}


/* Returns: 0 if nothing needs to be changed */
/*          1 if FirstVisible changed */

int ListBoxScrolltoFocus(HWND hwnd)

{
  WND  *wndPtr;
  LPHEADLIST  lphl;
  short       end;

  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);

  if (lphl->ItemsCount == 0) return 0;
  if (lphl->ItemFocused == -1) return 0;

  end = lphl->FirstVisible + lphl->ItemsVisible - 2;

  if (lphl->ItemFocused < lphl->FirstVisible - 1) {
    lphl->FirstVisible = lphl->ItemFocused + 1;
  }
  else if (lphl->ItemFocused > end) {
    UINT maxFirstVisible = ListMaxFirstVisible(lphl);

    lphl->FirstVisible = lphl->ItemFocused;

    if (lphl->FirstVisible > maxFirstVisible) {
      lphl->FirstVisible = maxFirstVisible;
    }
  } else return 0;

  return 1;
}

/* Send notification "code" as part of a WM_COMMAND-message if hwnd
   has the LBS_NOTIFY style */
void ListBoxSendNotification(HWND hwnd, WORD code)
{
  WND  *wndPtr;
  LPHEADLIST  lphl;
  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);

  if (wndPtr && (wndPtr->dwStyle & LBS_NOTIFY))
    SendMessage(lphl->hWndLogicParent, WM_COMMAND,
		wndPtr->wIDmenu, MAKELONG(hwnd, code));
}
