/*
 * Listbox controls
 * 
 * Copyright  Martin Ayotte, 1993
 *            Constantine Sapuntzakis, 1995
 * 	      Alex Korobka, 1995, 1996 
 * 
 */

 /*
  * FIXME: 
  * - proper scrolling for multicolumn style
  * - anchor and caret for LBS_EXTENDEDSEL
  * - proper selection with keyboard
  * - how to handle (LBS_EXTENDEDSEL | LBS_MULTIPLESEL) style
  * - support for LBS_NOINTEGRALHEIGHT and LBS_OWNERDRAWVARIABLE styles
  */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "windows.h"
#include "win.h"
#include "gdi.h"
#include "msdos.h"
#include "listbox.h"
#include "dos_fs.h"
#include "drive.h"
#include "file.h"
#include "heap.h"
#include "stddebug.h"
#include "debug.h"
#include "xmalloc.h"

#define LIST_HEAP_ALLOC(lphl,f,size) \
    LOCAL_Alloc( lphl->HeapSel, LMEM_FIXED, (size) )
#define LIST_HEAP_FREE(lphl,handle) \
    LOCAL_Free( lphl->HeapSel, (handle) )
#define LIST_HEAP_ADDR(lphl,handle)  \
    ((handle) ? PTR_SEG_OFF_TO_LIN(lphl->HeapSel, (handle)) : NULL)

#define LIST_HEAP_SIZE 0x10000

#define LBMM_EDGE   4    /* distance inside box which is same as moving mouse
			    outside box, to trigger scrolling of LB */

#define MATCH_SUBSTR            2
#define MATCH_EXACT             1
#define MATCH_NEAREST           0

static void ListBoxInitialize(LPHEADLIST lphl)
{
  lphl->lpFirst        = NULL;
  lphl->ItemsCount     = 0;
  lphl->ItemsVisible   = 0;
  lphl->FirstVisible   = 0;
  lphl->ColumnsVisible = 1;
  lphl->ItemsPerColumn = 0;
  lphl->ItemFocused    = -1;
  lphl->PrevFocused    = -1;
}

void CreateListBoxStruct(HWND hwnd, WORD CtlType, LONG styles, HWND parent)
{
  LPHEADLIST lphl;
  HDC32         hdc;

  lphl = (LPHEADLIST)xmalloc(sizeof(HEADLIST));
  SetWindowLong32A(hwnd, 0, (LONG)lphl);
  ListBoxInitialize(lphl);
  lphl->DrawCtlType    = CtlType;
  lphl->CtlID          = GetWindowWord(hwnd,GWW_ID);
  lphl->bRedrawFlag    = TRUE;
  lphl->iNumStops      = 0;
  lphl->TabStops       = NULL;
  lphl->hFont          = GetStockObject(SYSTEM_FONT);
  lphl->hSelf          = hwnd;  
  if (CtlType==ODT_COMBOBOX)              /* use the "faked" style for COMBOLBOX */
                                          /* LBS_SORT instead CBS_SORT e.g.      */
    lphl->dwStyle   = MAKELONG(LOWORD(styles),HIWORD(GetWindowLong32A(hwnd,GWL_STYLE)));
  else
    lphl->dwStyle   = GetWindowLong32A(hwnd,GWL_STYLE); /* use original style dword */
  lphl->hParent        = parent;
  lphl->StdItemHeight  = 15; /* FIXME: should get the font height */
  lphl->OwnerDrawn     = styles & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE);
  lphl->HasStrings     = (styles & LBS_HASSTRINGS) || !lphl->OwnerDrawn;

  /* create dummy hdc to set text height */
  if ((hdc = GetDC32(0)))
  {
      TEXTMETRIC16 tm;
      GetTextMetrics16( hdc, &tm );
      lphl->StdItemHeight = tm.tmHeight;
      dprintf_listbox(stddeb,"CreateListBoxStruct:  font height %d\n",
                      lphl->StdItemHeight);
      ReleaseDC32( 0, hdc );
  }

  if (lphl->OwnerDrawn)
  {
    LISTSTRUCT dummyls;
    
    lphl->needMeasure = TRUE;
    dummyls.mis.CtlType    = lphl->DrawCtlType;
    dummyls.mis.CtlID      = lphl->CtlID;
    dummyls.mis.itemID     = -1;
    dummyls.mis.itemWidth  = 0; /* ignored */
    dummyls.mis.itemData   = 0;

    ListBoxAskMeasure(lphl,&dummyls);
  }

  lphl->HeapSel = GlobalAlloc16(GMEM_FIXED,LIST_HEAP_SIZE);
  LocalInit( lphl->HeapSel, 0, LIST_HEAP_SIZE-1);
}

void DestroyListBoxStruct(LPHEADLIST lphl)
{
  /* XXX need to free lphl->Heap */
  GlobalFree16(lphl->HeapSel);
  free(lphl);
}

static LPHEADLIST ListBoxGetStorageHeader(HWND hwnd)
{
    return (LPHEADLIST)GetWindowLong32A(hwnd,0);
}

/* Send notification "code" as part of a WM_COMMAND-message if hwnd
   has the LBS_NOTIFY style */
void ListBoxSendNotification(LPHEADLIST lphl, WORD code)
{
  if (lphl->dwStyle & LBS_NOTIFY)
      SendMessage32A( lphl->hParent, WM_COMMAND,
                      MAKEWPARAM( lphl->CtlID, code), (LPARAM)lphl->hSelf );
}


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


void ListBoxUpdateWindow(HWND hwnd, LPHEADLIST lphl, BOOL repaint)
{
  if (lphl->dwStyle & WS_VSCROLL)
    SetScrollRange32(hwnd, SB_VERT, 0, ListMaxFirstVisible(lphl), TRUE);
  if ((lphl->dwStyle & WS_HSCROLL) && (lphl->ItemsPerColumn != 0))
    SetScrollRange32(hwnd, SB_HORZ, 1, lphl->ItemsVisible /
		   lphl->ItemsPerColumn + 1, TRUE);

  if (repaint && lphl->bRedrawFlag) InvalidateRect32( hwnd, NULL, TRUE );
}

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

int ListBoxScrollToFocus(LPHEADLIST lphl)
{
  short       end;

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

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

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

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


LPLISTSTRUCT ListBoxGetItem(LPHEADLIST lphl, UINT uIndex)
{
  LPLISTSTRUCT lpls;
  UINT         Count = 0;

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

  lpls = lphl->lpFirst;
  while (Count++ < uIndex) lpls = lpls->lpNext;
  return lpls;
}


void ListBoxDrawItem (HWND hwnd, LPHEADLIST lphl, HDC hdc, LPLISTSTRUCT lpls, 
		      RECT16 *rect, WORD itemAction, WORD itemState)
{
    if (lphl->OwnerDrawn)
    {
        DRAWITEMSTRUCT32 dis;

        dis.CtlID      = lpls->mis.CtlID;
        dis.CtlType    = lpls->mis.CtlType;
        dis.itemID     = lpls->mis.itemID;
        dis.hDC        = hdc;
        dis.hwndItem   = hwnd;
        dis.itemData   = lpls->mis.itemData;
        dis.itemAction = itemAction;
        dis.itemState  = itemState;
        CONV_RECT16TO32( rect, &dis.rcItem );
        SendMessage32A( lphl->hParent, WM_DRAWITEM, dis.CtlID, (LPARAM)&dis );
        return;
    }
    if (itemAction == ODA_DRAWENTIRE || itemAction == ODA_SELECT) {
      int 	OldBkMode;
      DWORD 	dwOldTextColor = 0;

      OldBkMode = SetBkMode(hdc, TRANSPARENT);

      if (itemState != 0) {
	dwOldTextColor = SetTextColor(hdc, 0x00FFFFFFL);
	FillRect16(hdc, rect, GetStockObject(BLACK_BRUSH));
      }

      if (lphl->dwStyle & LBS_USETABSTOPS) {
	TabbedTextOut(hdc, rect->left + 5, rect->top + 2, 
		      (char *)lpls->itemText, strlen((char *)lpls->itemText), 
		      lphl->iNumStops, lphl->TabStops, 0);
      } else {
	TextOut16(hdc, rect->left + 5, rect->top + 2,
                  (char *)lpls->itemText, strlen((char *)lpls->itemText));
      }

      if (itemState != 0) {
	SetTextColor(hdc, dwOldTextColor);
      }
      
      SetBkMode(hdc, OldBkMode);
    }
    else DrawFocusRect16(hdc, rect);
}


int ListBoxFindMouse(LPHEADLIST lphl, int X, int Y)
{
  LPLISTSTRUCT lpls = lphl->lpFirst;
  int          i, j;
  POINT16      point;
  
  point.x = X; point.y = Y;
  if (lphl->ItemsCount == 0) return LB_ERR;

  for(i = 0; i < lphl->FirstVisible; i++) {
    if (lpls == NULL) return LB_ERR;
    lpls = lpls->lpNext;
  }
  for(j = 0; j < lphl->ItemsVisible; i++, j++) {
    if (lpls == NULL) return LB_ERR;
    if (PtInRect16(&lpls->itemRect,point)) {
      return i;
    }
    lpls = lpls->lpNext;
  }
  dprintf_listbox(stddeb,"ListBoxFindMouse: not found\n");
  return LB_ERR;
}

BOOL32 lbDeleteItemNotify(LPHEADLIST lphl, LPLISTSTRUCT lpls)
{
    /* called only for owner drawn listboxes */
    BOOL32 ret;
    DELETEITEMSTRUCT16 *delItem = SEGPTR_NEW(DELETEITEMSTRUCT16);
    if (!delItem) return FALSE;

    delItem->CtlType  = lphl->DrawCtlType;
    delItem->CtlID    = lphl->CtlID;
    delItem->itemID   = lpls->mis.itemID;
    delItem->hwndItem = lphl->hSelf;
    delItem->itemData = lpls->mis.itemData;

    ret = SendMessage16( lphl->hParent, WM_DELETEITEM, (WPARAM)lphl->CtlID,
                         (LPARAM)SEGPTR_GET(delItem) );
    SEGPTR_FREE(delItem);
    return ret;
}

void ListBoxAskMeasure(LPHEADLIST lphl, LPLISTSTRUCT lpls)  
{
    MEASUREITEMSTRUCT16 *lpmeasure = SEGPTR_NEW(MEASUREITEMSTRUCT16);
    if (!lpmeasure) return;
    *lpmeasure = lpls->mis;
    lpmeasure->itemHeight = lphl->StdItemHeight;
    SendMessage16( lphl->hParent, WM_MEASUREITEM, lphl->CtlID,
                   (LPARAM)SEGPTR_GET(lpmeasure) );

    if (lphl->dwStyle & LBS_OWNERDRAWFIXED)
    {
        if (lpmeasure->itemHeight > lphl->StdItemHeight)
            lphl->StdItemHeight = lpmeasure->itemHeight;
        lpls->mis.itemHeight = lpmeasure->itemHeight;
    }
    SEGPTR_FREE(lpmeasure);
}

/* -------------------- strings and item data ---------------------- */

LPLISTSTRUCT ListBoxCreateItem(LPHEADLIST lphl, int id)
{
  LPLISTSTRUCT lplsnew = (LPLISTSTRUCT)malloc(sizeof(LISTSTRUCT));

  if (lplsnew == NULL) return NULL;
  
  lplsnew->itemState      = 0;
  lplsnew->mis.CtlType    = lphl->DrawCtlType;
  lplsnew->mis.CtlID      = lphl->CtlID;
  lplsnew->mis.itemID     = id;
  lplsnew->mis.itemHeight = lphl->StdItemHeight;
  lplsnew->mis.itemWidth  = 0; /* ignored */
  lplsnew->mis.itemData   = 0;
  SetRectEmpty16( &lplsnew->itemRect );

  return lplsnew;
}

int ListBoxAskCompare(LPHEADLIST lphl, int startItem, SEGPTR matchData, BOOL exactMatch )
{
 /*  Do binary search for sorted listboxes. Linked list item storage sort of 
  *  defeats the purpose ( forces to traverse item list all the time ) but M$ does it this way...
  *
  *  MATCH_NEAREST (0) - return position for insertion - for all styles
  *  MATCH_EXACT   (1) - search for an item, return index or LB_ERR 
  *  MATCH_SUBSTR  (2) - same as exact match but with strncmp for string comparision
  */

 COMPAREITEMSTRUCT16   *itemCmp;
 LPLISTSTRUCT		currentItem = NULL;
 LPCSTR			matchStr = (lphl->HasStrings)?(LPCSTR)PTR_SEG_TO_LIN(matchData):NULL;
 int                    head, pos = -1, tail, loop = 1;
 short                  b = 0, s_length = 0;

 /* check if empty */

 if( !lphl->ItemsCount )
    return (exactMatch)? LB_ERR: 0;

 /* set up variables */

 if( exactMatch == MATCH_NEAREST )
     startItem = 0;
 else if( ++startItem ) 
   {
     loop = 2;
     if( startItem >= lphl->ItemsCount ) startItem = lphl->ItemsCount - 1;
   }

 if( exactMatch == MATCH_SUBSTR && lphl->HasStrings )
   {
     s_length = strlen( matchStr );
     if( !s_length ) return 0; 		        /* head of the list - empty string */
   }

 head = startItem; tail = lphl->ItemsCount - 1;

 dprintf_listbox(stddeb,"AskCompare: head = %i, tail = %i, data = %08x\n", head, tail, (unsigned)matchData );

 if (!(itemCmp = SEGPTR_NEW(COMPAREITEMSTRUCT16))) return 0;
 itemCmp->CtlType        = lphl->DrawCtlType;
 itemCmp->CtlID          = lphl->CtlID;
 itemCmp->hwndItem       = lphl->hSelf;

 /* search from startItem */

 while ( loop-- )
  {
    while( head <= tail )
     {
       pos = (tail + head)/2;
       currentItem = ListBoxGetItem( lphl, pos );

       if( lphl->HasStrings )
	 {
           b = ( s_length )? lstrncmpi32A( currentItem->itemText, matchStr, s_length)
                           : lstrcmpi32A( currentItem->itemText, matchStr);
	 }
       else
         {
           itemCmp->itemID1      = pos;
           itemCmp->itemData1    = currentItem->mis.itemData;
           itemCmp->itemID2      = -1;
           itemCmp->itemData2    = matchData;

           b = SendMessage16( lphl->hParent, WM_COMPAREITEM, (WPARAM)lphl->CtlID, 
                              (LPARAM)SEGPTR_GET(itemCmp) );
         }

       if( b == 0 )
       {
           SEGPTR_FREE(itemCmp);
           return pos;  /* found exact match */
       }
       else
         if( b < 0 ) head = ++pos;
         else
           if( b > 0 ) tail = pos - 1;
     }

    /* reset to search from the first item */
    head = 0; tail = startItem - 1;
  }

 dprintf_listbox(stddeb,"\t-> pos = %i\n", pos );
 SEGPTR_FREE(itemCmp);

 /* if we got here match is not exact */

 if( pos < 0 ) pos = 0;
 else if( pos > lphl->ItemsCount ) pos = lphl->ItemsCount;

 return (exactMatch)? LB_ERR: pos;
}

int ListBoxInsertString(LPHEADLIST lphl, UINT uIndex, LPCSTR newstr)
{
  LPLISTSTRUCT *lppls, lplsnew, lpls;
  HANDLE       hStr;
  LPSTR	str;
  UINT	Count;
    
  dprintf_listbox(stddeb,"ListBoxInsertString(%d, %p);\n", uIndex, newstr);
    
  if (!newstr) return -1;

  if (uIndex == (UINT)-1)
    uIndex = lphl->ItemsCount;

  lppls = &lphl->lpFirst;
  for(Count = 0; Count < uIndex; Count++) {
    if (*lppls == NULL) return LB_ERR;
    lppls = (LPLISTSTRUCT *) &(*lppls)->lpNext;
  }
    
  lplsnew = ListBoxCreateItem(lphl, Count);
  
  if (lplsnew == NULL) {
    fprintf(stdnimp,"ListBoxInsertString() out of memory !\n");
    return LB_ERRSPACE;
  }

  lplsnew->lpNext = *lppls;
  *lppls = lplsnew;
  lphl->ItemsCount++;
  
  hStr = 0;
  if (lphl->HasStrings) {
    dprintf_listbox(stddeb,"  string: %s\n", newstr);
    hStr = LIST_HEAP_ALLOC(lphl, LMEM_MOVEABLE, strlen(newstr) + 1);
    str = (LPSTR)LIST_HEAP_ADDR(lphl, hStr);
    if (str == NULL) return LB_ERRSPACE;
    strcpy(str, newstr); 
    lplsnew->itemText = str;
    /* I'm not so sure about the next one */
    lplsnew->mis.itemData = 0;
  } else {
    lplsnew->itemText = NULL;
    lplsnew->mis.itemData = (DWORD)newstr;
  }

  lplsnew->mis.itemID = uIndex;
  lplsnew->hData = hStr;
  
  /* adjust the itemID field of the following entries */
  for(lpls = lplsnew->lpNext; lpls != NULL; lpls = lpls->lpNext) {
      lpls->mis.itemID++;
  }
 
  if (lphl->needMeasure) {
    ListBoxAskMeasure(lphl, lplsnew);
  }

  dprintf_listbox(stddeb,"ListBoxInsertString // count=%d\n", lphl->ItemsCount);
  return uIndex;
}


int ListBoxAddString(LPHEADLIST lphl, SEGPTR itemData)
{
    UINT 	pos = (UINT) -1;
    LPCSTR	newstr = (lphl->HasStrings)?(LPCSTR)PTR_SEG_TO_LIN(itemData):(LPCSTR)itemData;

    if ( lphl->dwStyle & LBS_SORT ) 
	 pos = ListBoxAskCompare( lphl, -1, itemData, MATCH_NEAREST );

    return ListBoxInsertString(lphl, pos, newstr);
}


int ListBoxGetText(LPHEADLIST lphl, UINT uIndex, LPSTR OutStr)
{
  LPLISTSTRUCT lpls;

  if (!OutStr) {
    dprintf_listbox(stddeb, "ListBoxGetText // OutStr==NULL\n");
    return 0;
  }
  *OutStr = '\0';
  lpls = ListBoxGetItem (lphl, uIndex);
  if (lpls == NULL) return LB_ERR;

  if (!lphl->HasStrings) {
    *((long *)OutStr) = lpls->mis.itemData;
    return 4;
  }
	
  strcpy(OutStr, lpls->itemText);
  return strlen(OutStr);
}


DWORD ListBoxGetItemData(LPHEADLIST lphl, UINT uIndex)
{
  LPLISTSTRUCT lpls;

  lpls = ListBoxGetItem (lphl, uIndex);
  if (lpls == NULL) return LB_ERR;
  return lpls->mis.itemData;
}


int ListBoxSetItemData(LPHEADLIST lphl, UINT uIndex, DWORD ItemData)
{
  LPLISTSTRUCT lpls = ListBoxGetItem(lphl, uIndex);

  if (lpls == NULL) return LB_ERR;
  lpls->mis.itemData = ItemData;
  return 1;
}


int ListBoxDeleteString(LPHEADLIST lphl, UINT uIndex)
{
  LPLISTSTRUCT lpls, lpls2;
  UINT	Count;

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

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

  if (uIndex == 0)
  {
    if( lphl->OwnerDrawn )
        lbDeleteItemNotify( lphl, lpls);
    lphl->lpFirst = lpls->lpNext;
  }
  else 
  {
    LPLISTSTRUCT lpls2 = NULL;
    for(Count = 0; Count < uIndex; Count++) {
      if (lpls->lpNext == NULL) return LB_ERR;

      lpls2 = lpls;
      lpls = (LPLISTSTRUCT)lpls->lpNext;
    }
    if( lphl->OwnerDrawn )
	lbDeleteItemNotify( lphl, lpls);
    lpls2->lpNext = lpls->lpNext;
  }

  /* adjust the itemID field of the following entries */
  for(lpls2 = lpls->lpNext; lpls2 != NULL; lpls2 = lpls2->lpNext) {
      lpls2->mis.itemID--;
  }
 
  lphl->ItemsCount--;

  if (lpls->hData != 0) LIST_HEAP_FREE(lphl, lpls->hData);
  free(lpls);
  
  return lphl->ItemsCount;
}

int lbFindString(LPHEADLIST lphl, UINT nFirst, SEGPTR MatchStr, BOOL match)
{
  /*  match is either MATCH_SUBSTR or MATCH_EXACT */

  LPLISTSTRUCT lpls;
  UINT	       Count;
  UINT         First      = nFirst + 1;
  int	       s_length   = 0;
  LPSTR        lpMatchStr = (LPSTR)MatchStr;

  if (First > lphl->ItemsCount) return LB_ERR;

  if (lphl->dwStyle & LBS_SORT )
      return ListBoxAskCompare( lphl, nFirst, MatchStr, match );

  if (lphl->HasStrings ) 
  {
    lpMatchStr = PTR_SEG_TO_LIN(MatchStr);

    if( match == MATCH_SUBSTR )
    {
      s_length = strlen(lpMatchStr);
      if( !s_length ) return (lphl->ItemsCount)?0:LB_ERR;
    }
  }

  lpls = ListBoxGetItem(lphl, First);
  Count = 0;
  while(lpls != NULL) 
  {
    if (lphl->HasStrings) 
    {
      if ( ( s_length )? !lstrncmpi32A(lpls->itemText, lpMatchStr, s_length)
                       : !lstrcmpi32A(lpls->itemText, lpMatchStr)  ) return Count;
    }
    else
      if ( lpls->mis.itemData == (DWORD)lpMatchStr ) return Count;

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

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

  while (Count < First) 
  {
    if (lphl->HasStrings) 
    {
      if ( ( s_length )? !lstrncmpi32A(lpls->itemText, lpMatchStr, s_length)
                       : !lstrcmpi32A(lpls->itemText, lpMatchStr)  ) return Count;
    }
    else
      if ( lpls->mis.itemData == (DWORD)lpMatchStr ) return Count;
    
    lpls = lpls->lpNext;
    Count++;
  }

  return LB_ERR;
}

int ListBoxFindString(LPHEADLIST lphl, UINT nFirst, SEGPTR MatchStr)
{
  return lbFindString(lphl, nFirst, MatchStr, MATCH_SUBSTR );
}

int ListBoxFindStringExact(LPHEADLIST lphl, UINT nFirst, SEGPTR MatchStr)
{
  return lbFindString(lphl, nFirst, MatchStr, MATCH_EXACT );
}

int ListBoxResetContent(LPHEADLIST lphl)
{
    LPLISTSTRUCT lpls;
    int i;

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

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

    for(i = 0; i < lphl->ItemsCount; i++) {
      lpls = lphl->lpFirst;
      if (lpls == NULL) return LB_ERR;

      if (lphl->OwnerDrawn) lbDeleteItemNotify(lphl, lpls);

      lphl->lpFirst = lpls->lpNext;
      if (lpls->hData != 0) LIST_HEAP_FREE(lphl, lpls->hData);
      free(lpls);
    }
    ListBoxInitialize(lphl);

    return TRUE;
}

/* --------------------- selection ------------------------- */

int ListBoxSetCurSel(LPHEADLIST lphl, WORD wIndex)
{
  LPLISTSTRUCT lpls;

  /* use ListBoxSetSel instead */
  if (lphl->dwStyle & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL) ) return 0;

  /* unselect previous item */
  if (lphl->ItemFocused != -1) {
    lphl->PrevFocused = lphl->ItemFocused;
    lpls = ListBoxGetItem(lphl, lphl->ItemFocused);
    if (lpls == 0) return LB_ERR;
    lpls->itemState = 0;
  }

  if ((wIndex != (UINT)-1) && (wIndex < lphl->ItemsCount))
  {
    lphl->ItemFocused = wIndex;
    lpls = ListBoxGetItem(lphl, wIndex);
    if (lpls == 0) return LB_ERR;
    lpls->itemState = ODS_SELECTED | ODS_FOCUS;

    return 0;
  }

  return LB_ERR;
}


int ListBoxSetSel(LPHEADLIST lphl, WORD wIndex, WORD state)
{
  LPLISTSTRUCT  lpls;
  int           n = 0;

  if (!(lphl->dwStyle &  (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)  )) 
        return LB_ERR;

  if (wIndex == (UINT)-1) {
    for (lpls = lphl->lpFirst; lpls != NULL; lpls = lpls->lpNext) {
      if( lpls->itemState & ODS_SELECTED) n++;
      lpls->itemState = state? lpls->itemState |  ODS_SELECTED
                             : lpls->itemState & ~ODS_SELECTED;
    }
    return n;
  }

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

  lpls = ListBoxGetItem(lphl, wIndex);
  lpls->itemState = state? lpls->itemState |  ODS_SELECTED
                         : lpls->itemState & ~ODS_SELECTED;

  return 0;
}


int ListBoxGetSel(LPHEADLIST lphl, WORD wIndex)
{
  LPLISTSTRUCT lpls = ListBoxGetItem(lphl, wIndex);

  if (lpls == NULL) return LB_ERR;
  return lpls->itemState & ODS_SELECTED;
}

/* ------------------------- dir listing ------------------------ */

LONG ListBoxDirectory(LPHEADLIST lphl, UINT attrib, LPCSTR filespec)
{
    char 	mask[13];
    char*	temp = NULL;
    const char*	ptr;
    int 	skip, count;
    LONG 	ret;
    DOS_DIRENT 	entry;
    char *path, *p;

    dprintf_listbox(stddeb, "ListBoxDirectory: '%s' %04x\n", filespec, attrib);
    if (!filespec) return LB_ERR;
    if (!(ptr = DOSFS_GetUnixFileName( filespec, FALSE ))) return LB_ERR;
    path = xstrdup(ptr);
    p = strrchr( path, '/' );
    *p++ = '\0';
    if (!(ptr = DOSFS_ToDosFCBFormat( p )) || 
        !(temp = SEGPTR_ALLOC( sizeof(char) * 16 )) )
    {
        free( path );
        return LB_ERR;
    }

    strcpy( mask, ptr );

    dprintf_listbox(stddeb, "ListBoxDirectory: path=%s mask=%s\n", path, mask);

    skip = ret = 0;
    attrib &= ~FA_LABEL;
    while ((count = DOSFS_FindNext( path, mask, 0, attrib, skip, &entry )) > 0)
    {
        skip += count;
        if (entry.attr & FA_DIRECTORY)
        {
            if ((attrib & DDL_DIRECTORY) && strcmp(entry.name, ".          "))
            {
                sprintf(temp, "[%s]", DOSFS_ToDosDTAFormat( entry.name ) );
                AnsiLower( temp );
                if ((ret = ListBoxAddString(lphl, SEGPTR_GET(temp))) == LB_ERR) break;
            }
        }
        else  /* not a directory */
        {
            if (!(attrib & DDL_EXCLUSIVE) ||
                ((attrib & (FA_RDONLY|FA_HIDDEN|FA_SYSTEM|FA_ARCHIVE)) ==
                 (entry.attr & (FA_RDONLY|FA_HIDDEN|FA_SYSTEM|FA_ARCHIVE))))
            {
                strcpy( temp, DOSFS_ToDosDTAFormat( entry.name ) );
                AnsiLower( temp );
                if ((ret = ListBoxAddString(lphl, SEGPTR_GET(temp))) == LB_ERR) break;
            }
        }

        dprintf_listbox(stddeb,"\tn - %i, file '%s'\n", count, temp); 
    }
    if (attrib & DDL_DRIVES)
    {
        int x;
	DWORD oldstyle = lphl->dwStyle;
	    
	lphl->dwStyle &= ~LBS_SORT;
        strcpy( temp, "[-a-]" );
        for (x = 0; x < MAX_DOS_DRIVES; x++, temp[2]++)
        {
            if (DRIVE_IsValid(x))
                if ((ret = ListBoxAddString(lphl, SEGPTR_GET(temp))) == LB_ERR) break;
        }
	lphl->dwStyle = oldstyle;
    }

    free( path );
    SEGPTR_FREE( temp );

    return ret;
}

/* ------------------------- dimensions ------------------------- */

int ListBoxGetItemRect(LPHEADLIST lphl, WORD wIndex, LPRECT16 lprect)
{
  LPLISTSTRUCT lpls = ListBoxGetItem(lphl,wIndex);

  dprintf_listbox(stddeb,"ListBox LB_GETITEMRECT %i %p", wIndex,lpls);
  if (lpls == NULL)
  {
    if (lphl->dwStyle & LBS_OWNERDRAWVARIABLE)
      return LB_ERR;
    else 
    {
     GetClientRect16(lphl->hSelf,lprect);
     lprect->bottom=lphl->StdItemHeight;
     if (lprect->right<0) lprect->right=0;
    }
  }
  else
   *lprect = lpls->itemRect;
  dprintf_listbox(stddeb," = %d,%d  %d,%d\n", lprect->left,lprect->top,
                                              lprect->right,lprect->bottom);
  return 0;
}


int ListBoxSetItemHeight(LPHEADLIST lphl, WORD wIndex, long height)
{
  LPLISTSTRUCT lpls;

  if (!(lphl->dwStyle & LBS_OWNERDRAWVARIABLE)) {
    lphl->StdItemHeight = (short)height;
    return 0;
  }
  
  lpls = ListBoxGetItem(lphl, wIndex);
  if (lpls == NULL) return LB_ERR;
  
  lpls->mis.itemHeight = height;
  return 0;
}

/* -------------------------- string search ------------------------ */  

int ListBoxFindNextMatch(LPHEADLIST lphl, WORD wChar)
{
  LPLISTSTRUCT lpls;
  UINT	       count,first;

  if ((char)wChar < ' ') return LB_ERR;
  if (!lphl->HasStrings) return LB_ERR;

  lpls = lphl->lpFirst;
  
  for (count = 0; lpls != NULL; lpls = lpls->lpNext, count++) {
    if (tolower(*lpls->itemText) == tolower((char)wChar)) break;
  }
  if (lpls == NULL) return LB_ERR;
  first = count;
  for(; lpls != NULL; lpls = lpls->lpNext, count++) {
    if (*lpls->itemText != (char)wChar) 
      break;
    if ((short) count > lphl->ItemFocused)
      return count;
  }
  return first;
}

/***********************************************************************
 *           LBCreate
 */
static LONG LBCreate(HWND hwnd, WORD wParam, LONG lParam)
{
  LPHEADLIST   lphl;
  LONG	       dwStyle = GetWindowLong32A(hwnd,GWL_STYLE);
  RECT16 rect;

  CreateListBoxStruct(hwnd, ODT_LISTBOX, dwStyle, GetParent16(hwnd));
  lphl = ListBoxGetStorageHeader(hwnd);
  dprintf_listbox(stddeb,"ListBox created: lphl = %p dwStyle = %04x:%04x\n", 
			  lphl, HIWORD(dwStyle), LOWORD(dwStyle));

  GetClientRect16(hwnd,&rect);
  lphl->ColumnsWidth = rect.right - rect.left;

  if (dwStyle & WS_VSCROLL) 
    SetScrollRange32(hwnd, SB_VERT, 0, ListMaxFirstVisible(lphl), TRUE);
  if (dwStyle & WS_HSCROLL) 
    SetScrollRange32(hwnd, SB_HORZ, 1, 1, TRUE);

  return 0;
}


/***********************************************************************
 *           LBDestroy
 */
static LONG LBDestroy(HWND hwnd, WORD wParam, LONG lParam)
{
  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);

  ListBoxResetContent(lphl);

  DestroyListBoxStruct(lphl);
  dprintf_listbox(stddeb,"ListBox destroyed: lphl = %p\n",lphl);
  return 0;
}


/***********************************************************************
 *           LBNCCalcSize
 */
static LONG LBNCCalcSize(HWND hwnd, WORD wParam, LONG lParam)
{
  LONG	     ret = DefWindowProc16(hwnd, WM_NCCALCSIZE, wParam, lParam);

  return (GetWindowLong32A(hwnd,GWL_STYLE) & LBS_MULTICOLUMN)? WVR_VREDRAW : ret;
}


/***********************************************************************
 *           LBVScroll
 */
static LONG LBVScroll(HWND hwnd, WORD wParam, LONG lParam)
{
  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
  int  y;

  dprintf_listbox(stddeb,"ListBox WM_VSCROLL w=%04X l=%08lX !\n",
		  wParam, lParam);
  y = lphl->FirstVisible;

  switch(wParam) {
  case SB_LINEUP:
    if (lphl->FirstVisible > 0)
      lphl->FirstVisible--;
    break;

  case SB_LINEDOWN:
    lphl->FirstVisible++;
    break;

  case SB_PAGEUP:
    if (lphl->FirstVisible > lphl->ItemsVisible) {
      lphl->FirstVisible -= lphl->ItemsVisible;
    } else {
      lphl->FirstVisible = 0;
    }
    break;

  case SB_PAGEDOWN:
    lphl->FirstVisible += lphl->ItemsVisible;
    break;

  case SB_THUMBTRACK:
    lphl->FirstVisible = LOWORD(lParam);
    break;
  }

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

  if (y != lphl->FirstVisible) {
    SetScrollPos32(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
    InvalidateRect32( hwnd, NULL, TRUE );
  }
  return 0;
}

/***********************************************************************
 *           LBHScroll
 */
static LONG LBHScroll(HWND hwnd, WORD wParam, LONG lParam)
{
  LPHEADLIST lphl;
  int        y;

  dprintf_listbox(stddeb,"ListBox WM_HSCROLL w=%04X l=%08lX !\n",
		  wParam, lParam);
  lphl = ListBoxGetStorageHeader(hwnd);
  y = lphl->FirstVisible;
  switch(wParam) {
  case SB_LINEUP:
    if (lphl->FirstVisible > lphl->ItemsPerColumn) {
      lphl->FirstVisible -= lphl->ItemsPerColumn;
    } else {
      lphl->FirstVisible = 0;
    }
    break;
  case SB_LINEDOWN:
    lphl->FirstVisible += lphl->ItemsPerColumn;
    break;
  case SB_PAGEUP:
    if (lphl->ItemsPerColumn != 0) {
      int lbsub = lphl->ItemsVisible / lphl->ItemsPerColumn * lphl->ItemsPerColumn;
      if (lphl->FirstVisible > lbsub) {
	lphl->FirstVisible -= lbsub;
      } else {
	lphl->FirstVisible = 0;
      }
    }
    break;
  case SB_PAGEDOWN:
    if (lphl->ItemsPerColumn != 0)
      lphl->FirstVisible += lphl->ItemsVisible /
	lphl->ItemsPerColumn * lphl->ItemsPerColumn;
    break;
  case SB_THUMBTRACK:
    lphl->FirstVisible = lphl->ItemsPerColumn * LOWORD(lParam);
    break;
  } 
  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) {
      SetScrollPos32(hwnd, SB_HORZ, lphl->FirstVisible / 
		   lphl->ItemsPerColumn + 1, TRUE);
      InvalidateRect32( hwnd, NULL, TRUE );
    }
  }
  return 0;
}

/***********************************************************************
 *           LBLButtonDown
 */
static LONG LBLButtonDown(HWND hwnd, WORD wParam, LONG lParam)
{
  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
  WORD       wRet;
  int        y,n;
  RECT16     rectsel;

  SetFocus32(hwnd);
  SetCapture32(hwnd);

  lphl->PrevFocused = lphl->ItemFocused;

  y = ListBoxFindMouse(lphl, LOWORD(lParam), HIWORD(lParam));

  if (y == -1) return 0;

  if (lphl->dwStyle & LBS_NOTIFY && y!= LB_ERR )
     if( SendMessage16(lphl->hParent, WM_LBTRACKPOINT, y, lParam) )
         return 0;


  switch( lphl->dwStyle & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL) )
   {
        case LBS_MULTIPLESEL:
                lphl->ItemFocused = y;
                wRet = ListBoxGetSel(lphl, y);
                ListBoxSetSel(lphl, y, !wRet);
                break;
        case LBS_EXTENDEDSEL:
                /* should handle extended mode here and in kbd handler 
                 */ 

                if ( lphl->PrevFocused != y && y!= LB_ERR)
                 {
                   LPLISTSTRUCT lpls = ListBoxGetItem( lphl, lphl->ItemFocused = y );
                   n = ListBoxSetSel(lphl,-1,FALSE);

                   lpls->itemState = ODS_FOCUS | ODS_SELECTED;

                   if( n > 1 && n != LB_ERR )
                     InvalidateRect32( hwnd,NULL,TRUE );
                 }
                else
                       return 0;

                break;
        case 0:
                if( y!=lphl->ItemFocused )
                  ListBoxSetCurSel(lphl, y);
                else
                  return 0;
                break;
        default:
                fprintf(stdnimp,"Listbox: LBS_MULTIPLESEL and LBS_EXTENDEDSEL are on!\n");
                return 0;
   }

 /* invalidate changed items */
 if( lphl->dwStyle & LBS_MULTIPLESEL || y!=lphl->PrevFocused )
   {
     ListBoxGetItemRect(lphl, y, &rectsel);
     InvalidateRect16( hwnd, &rectsel, TRUE );
   }
 if( lphl->PrevFocused!=-1 && y!=lphl->PrevFocused ) 
   {
     ListBoxGetItemRect(lphl, lphl->PrevFocused, &rectsel);
     InvalidateRect16( hwnd, &rectsel, TRUE );
   }

  if (GetWindowLong32A(lphl->hSelf,GWL_EXSTYLE) & WS_EX_DRAGDETECT)
     if( DragDetect(lphl->hSelf,MAKEPOINT16(lParam)) )
         SendMessage16(lphl->hParent, WM_BEGINDRAG,0,0L);
  return 0;
}

/***********************************************************************
 *           LBLButtonUp
 */
static LONG LBLButtonUp(HWND hwnd, WORD wParam, LONG lParam)
{
  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);

  if (GetCapture32() == hwnd) ReleaseCapture();

  if (lphl->PrevFocused != lphl->ItemFocused)
    ListBoxSendNotification(lphl, LBN_SELCHANGE);

  return 0;
}

/***********************************************************************
 *           LBRButtonUp
 */
static LONG LBRButtonUp(HWND hwnd, WORD wParam, LONG lParam)
{
  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);

  SendMessage16(lphl->hParent, WM_COMMAND, GetWindowWord(hwnd,GWW_ID),
		MAKELONG(hwnd, LBN_DBLCLK));
  return 0;
}

/***********************************************************************
 *           LBMouseMove
 */
static LONG LBMouseMove(HWND hwnd, WORD wParam, LONG lParam)
{
  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
  int  y,redraw_prev = 0;
  int  iRet;
  RECT16 rect, rectsel;   /* XXX Broken */

  dprintf_listbox(stddeb,"LBMouseMove %d %d\n",SLOWORD(lParam),SHIWORD(lParam));
  if ((wParam & MK_LBUTTON) != 0) {
    y = SHIWORD(lParam);
    if (y < LBMM_EDGE) {
      if (lphl->FirstVisible > 0) {
	lphl->FirstVisible--;
	SetScrollPos32(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
	InvalidateRect32( hwnd, NULL, TRUE );
	return 0;
      }
    }
    GetClientRect16(hwnd, &rect);
    if (y >= (rect.bottom-LBMM_EDGE)) {
      if (lphl->FirstVisible < ListMaxFirstVisible(lphl)) {
	lphl->FirstVisible++;
	SetScrollPos32(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
	InvalidateRect32( hwnd, NULL, TRUE );
	return 0;
      }
      }
    if ((y > 0) && (y < (rect.bottom - LBMM_EDGE))) {
      if ((y < rectsel.top) || (y > rectsel.bottom)) {
        iRet = ListBoxFindMouse(lphl, LOWORD(lParam), HIWORD(lParam));
        if (iRet == lphl->ItemFocused || iRet == -1)  {
	  return 0;
	}
	if (lphl->dwStyle & LBS_MULTIPLESEL) {
          lphl->ItemFocused = iRet;
	  ListBoxSendNotification(lphl, LBN_SELCHANGE);
        } else if ( lphl->dwStyle & LBS_EXTENDEDSEL )
                  {
                     /* Fixme: extended selection mode */
                     ListBoxSetSel( lphl, lphl->ItemFocused, 0);
                     lphl->PrevFocused = lphl->ItemFocused;
                     lphl->ItemFocused = iRet;
                     ListBoxSetSel( lphl, iRet, TRUE);
                     redraw_prev = 1;
                  }
               else
                  {
                     ListBoxSetCurSel(lphl, (WORD)iRet);
                     redraw_prev = 1; 
                  }
        if( lphl->PrevFocused!=-1 && redraw_prev )
          {
            ListBoxGetItemRect(lphl, lphl->PrevFocused, &rectsel);
            InvalidateRect16( hwnd, &rectsel, TRUE );
          }
        ListBoxGetItemRect(lphl, iRet, &rectsel);
	InvalidateRect16( hwnd, &rectsel, TRUE );
      }
    }
  }

  return 0;
  }

/***********************************************************************
 *           LBKeyDown
 *
 * Doesn't yet handle properly VK_SHIFT with LB_EXTENDEDSEL
 */
static LONG LBKeyDown(HWND hwnd, WORD wParam, LONG lParam)
{
  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
  WORD       newFocused = 0xFFFF;
  RECT16     rect;

  ListBoxGetItemRect(lphl,lphl->ItemFocused,&rect);
  switch(wParam) 
    {
	case VK_HOME:
	case VK_END:
	case VK_LEFT:
	case VK_RIGHT:
	case VK_UP:
	case VK_DOWN:
	case VK_PRIOR:
	case VK_NEXT:
	     if ( lphl->dwStyle & LBS_WANTKEYBOARDINPUT )
	        {
		  newFocused = (WORD)(INT)SendMessage16(lphl->hParent,WM_VKEYTOITEM,
                                                        wParam,MAKELPARAM(lphl->ItemFocused,hwnd));
	          if ( newFocused == 0xFFFE ) return 0L;
                }
	     if ( newFocused == 0xFFFF ) 
		{
		  newFocused = lphl->ItemFocused;

		  /* nested switch */
		  switch(wParam)
		    {
                        case VK_HOME:
                          newFocused = 0;
                          break;
                        case VK_END:
                          newFocused = lphl->ItemsCount - 1;
                          break;
                        case VK_LEFT:
  			  if (lphl->dwStyle & LBS_MULTICOLUMN) {
                            if (newFocused >= lphl->ItemsPerColumn) {
                                newFocused -= lphl->ItemsPerColumn;
                            } else {
                                newFocused = 0;
                            }
                          }
                          break;
                        case VK_UP:
                          if (newFocused > 0) newFocused--;
                          break;
                        case VK_RIGHT:
                          if (lphl->dwStyle & LBS_MULTICOLUMN) 
                             newFocused += lphl->ItemsPerColumn;
                          break;
                        case VK_DOWN:
                          newFocused++;
                          break;
                        case VK_PRIOR:
                          if (newFocused > lphl->ItemsVisible)
                              newFocused -= lphl->ItemsVisible;
			    else  newFocused = 0;
                            break;
                        case VK_NEXT:
                          newFocused += lphl->ItemsVisible;
                          break;
                        default:
                          return 0;
                    }
		  /* end of nested switch */
		}
	     break;   
	case VK_SPACE:
             if (lphl->dwStyle & LBS_MULTIPLESEL)
                {
                 WORD wRet = ListBoxGetSel(lphl, lphl->ItemFocused);
                 ListBoxSetSel(lphl, lphl->ItemFocused, !wRet);
                 }
             return 0;

        /* chars are handled in LBChar */
	default:
	     return 0;
    }

  /* at this point newFocused is set up */

  if (newFocused >= lphl->ItemsCount)
    newFocused = lphl->ItemsCount - 1;
  
  if (!(lphl->dwStyle & LBS_MULTIPLESEL)) 
     {
        ListBoxSetCurSel(lphl, newFocused);
	ListBoxSendNotification(lphl, LBN_SELCHANGE);
     }

  lphl->ItemFocused = newFocused;

  if( ListBoxScrollToFocus(lphl) || (lphl->dwStyle & 
                          (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) )
  InvalidateRect32( hwnd, NULL, TRUE );
  else
    {
	InvalidateRect16( hwnd, &rect, TRUE );
	if( newFocused < 0x8000 )
          {
	   ListBoxGetItemRect(lphl, newFocused, &rect);
	   InvalidateRect16( hwnd, &rect, TRUE );
          }
    }

  SetScrollPos32(hwnd, SB_VERT, lphl->FirstVisible, TRUE);

  return 0;
}

/***********************************************************************
 *           LBChar
 */
static LONG LBChar(HWND hwnd, WORD wParam, LONG lParam)
{
  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
  WORD       newFocused = 0xFFFF;

  if ( (lphl->dwStyle & LBS_WANTKEYBOARDINPUT) && !(lphl->HasStrings))
       {
        newFocused = (WORD)(INT)SendMessage16(lphl->hParent,WM_CHARTOITEM,
                                              wParam,MAKELPARAM(lphl->ItemFocused,hwnd));
        if ( newFocused == 0xFFFE ) return 0L;
       }

  if (newFocused == 0xFFFF ) 
  newFocused = ListBoxFindNextMatch(lphl, wParam);

  if (newFocused == (WORD)LB_ERR) return 0;

  if (newFocused >= lphl->ItemsCount)
    newFocused = lphl->ItemsCount - 1;

  if (!(lphl->dwStyle & LBS_MULTIPLESEL)) 
     {
    ListBoxSetCurSel(lphl, newFocused);
	ListBoxSendNotification(lphl, LBN_SELCHANGE);
  }

  lphl->ItemFocused = newFocused;
  ListBoxScrollToFocus(lphl);
  SetScrollPos32(hwnd, SB_VERT, lphl->FirstVisible, TRUE);

  InvalidateRect32( hwnd, NULL, TRUE );

  return 0;
}

/***********************************************************************
 *           LBSetRedraw
 */
static LONG LBSetRedraw(HWND hwnd, WORD wParam, LONG lParam)
{
  LPHEADLIST  lphl = ListBoxGetStorageHeader(hwnd);

  dprintf_listbox(stddeb,"ListBox WM_SETREDRAW hWnd=%04x w=%04x !\n",
		  hwnd, wParam);
  lphl->bRedrawFlag = wParam;

  return 0;
}

/***********************************************************************
 *           LBSetFont
 */
static LONG LBSetFont(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  LPHEADLIST  lphl = ListBoxGetStorageHeader(hwnd);
  HDC32 hdc;

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

  /* a new font means possible new text height */
  /* does this mean the height of each entry must be separately changed? */
  /* or are we guaranteed to get a LBSetFont before the first insert/add? */
  if ((hdc = GetDC32(0)))
  {
      TEXTMETRIC16 tm;
      GetTextMetrics16( hdc, &tm );
      lphl->StdItemHeight = tm.tmHeight;
      dprintf_listbox(stddeb,"LBSetFont:  new font %d with height %d\n",
                      lphl->hFont, lphl->StdItemHeight);
      ReleaseDC32( 0, hdc );
  }

  return 0;
}

/***********************************************************************
 *           LBPaint
 */
static LONG LBPaint(HWND hwnd, WORD wParam, LONG lParam)
{
  LPHEADLIST   lphl = ListBoxGetStorageHeader(hwnd);
  LPLISTSTRUCT lpls;
  PAINTSTRUCT16 ps;
  HBRUSH       hBrush;
  HFONT        hOldFont;
  HDC16 hdc    = BeginPaint16( hwnd, &ps );
  DC    *dc    = (DC *)GDI_GetObjPtr(hdc, DC_MAGIC);
  RECT16  rect, paintRect, scratchRect;
  int   i, top, height, maxwidth, ipc;

  top = 0;

  if (!IsWindowVisible(hwnd) || !lphl->bRedrawFlag) {
    EndPaint16(hwnd, &ps);
    return 0;
  }

  GetRgnBox16(dc->w.hGCClipRgn,&paintRect);
  GetClientRect16(hwnd, &rect);
  IntersectRect16(&paintRect,&rect,&paintRect);

  hOldFont = SelectObject(hdc, lphl->hFont);

  hBrush = (HBRUSH)SendMessage32A( lphl->hParent, WM_CTLCOLORLISTBOX,
                                   (WPARAM)hdc, (LPARAM)hwnd);
  if (hBrush == 0) hBrush = GetStockObject(WHITE_BRUSH);

  FillRect16(hdc, &rect, hBrush);

  maxwidth = rect.right;
  if (lphl->dwStyle & LBS_MULTICOLUMN) {
    rect.right = lphl->ColumnsWidth;
  }
  lpls = lphl->lpFirst;

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

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

    if (i >= lphl->FirstVisible) {
      height = lpls->mis.itemHeight;

      if (top > (rect.bottom-height+1)) {
	if (lphl->dwStyle & 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->itemRect.top    = top;
      lpls->itemRect.bottom = top + height;
      lpls->itemRect.left   = rect.left;
      lpls->itemRect.right  = rect.right;

      if( IntersectRect16(&scratchRect,&paintRect,&lpls->itemRect) )
       {
        dprintf_listbox(stddeb,"LBPaint: drawing item: %d %d %d %d %d\n",
                        rect.left,top,rect.right,top+height,lpls->itemState);

        if (lphl->OwnerDrawn && (lphl->ItemFocused == i) && GetFocus32() == hwnd)
           {
             ListBoxDrawItem (hwnd, lphl, hdc, lpls, &lpls->itemRect, ODA_FOCUS, 
                                                      lpls->itemState & ~ODS_FOCUS);
             ListBoxDrawItem (hwnd, lphl, hdc, lpls, &lpls->itemRect, ODA_DRAWENTIRE, 
                                                      lpls->itemState & ~ODS_FOCUS);
             ListBoxDrawItem (hwnd, lphl, hdc, lpls, &lpls->itemRect, ODA_FOCUS, lpls->itemState);
           }
        else
            ListBoxDrawItem (hwnd, lphl, hdc, lpls, &lpls->itemRect, ODA_DRAWENTIRE,
                                                     lpls->itemState);
       }

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

    lpls = lpls->lpNext;
  }
  ListBoxUpdateWindow(hwnd,lphl,FALSE);
  SelectObject(hdc,hOldFont);
  EndPaint16( hwnd, &ps );
  return 0;
}

/***********************************************************************
 *           LBSetFocus
 */
static LONG LBSetFocus(HWND hwnd, WORD wParam, LONG lParam)
{
  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);

  dprintf_listbox(stddeb,"ListBox WM_SETFOCUS for %04x\n",hwnd);
  if(!(lphl->dwStyle & LBS_MULTIPLESEL) )
       if( lphl->ItemsCount && lphl->ItemFocused != -1)
         {
           HDC32        hDC = GetDC32(hwnd);
           HFONT        hOldFont = SelectObject(hDC, lphl->hFont);
           LPLISTSTRUCT lpls;

           lpls = ListBoxGetItem(lphl,lphl->ItemFocused);
           lpls->itemState |= ODS_FOCUS;

           ListBoxDrawItem(hwnd,lphl,hDC,lpls,&lpls->itemRect, ODA_FOCUS, lpls->itemState);
           SelectObject(hDC, hOldFont);
           ReleaseDC32(hwnd,hDC);
         }

  ListBoxSendNotification(lphl, LBN_SETFOCUS);

  return 0;
}

/***********************************************************************
 *           LBKillFocus
 */
static LONG LBKillFocus(HWND hwnd, WORD wParam, LONG lParam)
{
  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);

  dprintf_listbox(stddeb,"ListBox WM_KILLFOCUS for %04x\n",hwnd);
  if (!(lphl->dwStyle & LBS_MULTIPLESEL))
     {
       if( lphl->ItemsCount )
           if( lphl->ItemFocused != -1 )
             {
              HDC32        hDC = GetDC32(hwnd);
              HFONT        hOldFont = SelectObject(hDC, lphl->hFont);
              LPLISTSTRUCT lpls;

              lpls = ListBoxGetItem(lphl,lphl->ItemFocused);
              lpls->itemState &= ~ODS_FOCUS;

              ListBoxDrawItem(hwnd,lphl,hDC,lpls,&lpls->itemRect, ODA_FOCUS, lpls->itemState);
              SelectObject(hDC, hOldFont);
              ReleaseDC32(hwnd,hDC);
             }
           else
             dprintf_listbox(stddeb,"LBKillFocus: no focused item!\n");
     }
  else
     InvalidateRect32( hwnd, NULL, TRUE );

  ListBoxSendNotification(lphl, LBN_KILLFOCUS);

  return 0;
}

/***********************************************************************
 *           LBResetContent
 */
static LONG LBResetContent(HWND hwnd, WORD wParam, LONG lParam)
{
  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);

  dprintf_listbox(stddeb,"ListBox LB_RESETCONTENT !\n");
  ListBoxResetContent(lphl);
  ListBoxUpdateWindow(hwnd, lphl, TRUE);
  return 0;
}

/***********************************************************************
 *           LBDir
 */
static LONG LBDir(HWND hwnd, WORD wParam, LONG lParam)
{
    LONG ret;
    LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
    dprintf_listbox(stddeb,"ListBox LB_DIR !\n");

    ret = ListBoxDirectory(lphl, wParam, (LPSTR)PTR_SEG_TO_LIN(lParam));
    ListBoxUpdateWindow(hwnd, lphl, TRUE);
    return ret;
}

/***********************************************************************
 *           LBAddString
 */
static LONG LBAddString(HWND hwnd, WORD wParam, LONG lParam)
{
  WORD  wRet;
  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);

  wRet = ListBoxAddString(lphl, (SEGPTR)lParam);

  ListBoxUpdateWindow(hwnd,lphl,TRUE);
  return wRet;
}

/***********************************************************************
 *           LBGetText
 */
static LONG LBGetText(HWND hwnd, WORD wParam, LONG lParam)
{
  LONG   wRet;
  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);

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

  return wRet;
}

/***********************************************************************
 *           LBInsertString
 */
static LONG LBInsertString(HWND hwnd, WORD wParam, LONG lParam)
{
  WORD  wRet;
  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);

  if (lphl->HasStrings)
    wRet = ListBoxInsertString(lphl, wParam, (LPCSTR)PTR_SEG_TO_LIN(lParam));
  else
    wRet = ListBoxInsertString(lphl, wParam, (LPCSTR)lParam);

  ListBoxUpdateWindow(hwnd,lphl,TRUE);
  return wRet;
}

/***********************************************************************
 *           LBDeleteString
 */
static LONG LBDeleteString(HWND hwnd, WORD wParam, LONG lParam)
{
  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
  LONG lRet = ListBoxDeleteString(lphl,wParam);
  
  ListBoxUpdateWindow(hwnd,lphl,TRUE);
  return lRet;
}

/***********************************************************************
 *           LBFindString
 */
static LONG LBFindString(HWND hwnd, WORD wParam, LONG lParam)
{
  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
  return lbFindString(lphl, wParam, (SEGPTR)lParam, MATCH_SUBSTR);
}

/***********************************************************************
 *           LBFindStringExact
 */
static LONG LBFindStringExact(HWND hwnd, WORD wParam, LONG lParam)
{
  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
  return lbFindString(lphl, wParam, (SEGPTR)lParam, MATCH_EXACT);
}

/***********************************************************************
 *           LBGetCaretIndex
 */
static LONG LBGetCaretIndex(HWND hwnd, WORD wParam, LONG lParam)
{
  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
  return lphl->ItemFocused;
}

/***********************************************************************
 *           LBGetCount
 */
static LONG LBGetCount(HWND hwnd, WORD wParam, LONG lParam)
{
  LPHEADLIST  lphl;

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

/***********************************************************************
 *           LBGetCurSel
 */
static LONG LBGetCurSel(HWND hwnd, WORD wParam, LONG lParam)
{
  LPHEADLIST  lphl;

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

/***********************************************************************
 *           LBGetHorizontalExtent
 */
static LONG LBGetHorizontalExtent(HWND hwnd, WORD wParam, LONG lParam)
{    
  return 0;
}

/***********************************************************************
 *           LBGetItemHeight
 */
static LONG LBGetItemHeight(HWND hwnd, WORD wParam, LONG lParam)
{
  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
  LPLISTSTRUCT lpls = ListBoxGetItem (lphl, wParam);
  
  if (lpls == NULL) return LB_ERR;
  return lpls->mis.itemHeight;
}

/***********************************************************************
 *           LBGetItemRect
 */
static LONG LBGetItemRect(HWND hwnd, WORD wParam, LONG lParam)
{
  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
  return ListBoxGetItemRect(lphl, wParam, PTR_SEG_TO_LIN(lParam));
}

/***********************************************************************
 *           LBGetSel
 */
static LONG LBGetSel(HWND hwnd, WORD wParam, LONG lParam)
{
  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
  int        iSel = ListBoxGetSel(lphl, wParam);

  dprintf_listbox(stdnimp,"LBGetSel: item %u - %i\n",wParam,iSel);

  return (iSel)? 1 : 0;
}

/***********************************************************************
 *           LBGetSelCount
 */
static LONG LBGetSelCount(HWND hwnd, WORD wParam, LONG lParam)
{
  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
  LPLISTSTRUCT lpls;
  int          cnt = 0;
  int          items = 0;

  if (!(lphl->dwStyle & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)  )) 
	 return LB_ERR;

  for( lpls = lphl->lpFirst;
       lpls;
       lpls = lpls->lpNext )
	{
	   items++;
           if (lpls->itemState ) 
               cnt++;
  }

  return cnt;
}

/***********************************************************************
 *           LBGetSelItems
 */
static LONG LBGetSelItems(HWND hwnd, WORD wParam, LONG lParam)
{
  LPHEADLIST  lphl = ListBoxGetStorageHeader(hwnd);
  LPLISTSTRUCT lpls;
  int cnt, idx;
  int *lpItems = PTR_SEG_TO_LIN(lParam);

  if (!(lphl->dwStyle & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)  )) 
        return LB_ERR;

  if (wParam == 0) return 0;

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

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

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

  return cnt;
}

/***********************************************************************
 *           LBGetTextLen
 */
static LONG LBGetTextLen(HWND hwnd, WORD wParam, LONG lParam)
{
  LPHEADLIST   lphl = ListBoxGetStorageHeader(hwnd);
  LPLISTSTRUCT lpls = ListBoxGetItem(lphl,wParam);

  if (lpls == NULL || !lphl->HasStrings) return LB_ERR;
  return strlen(lpls->itemText);
}

/***********************************************************************
 *           LBGetDlgCode
 */
static LONG LBGetDlgCode(HWND hwnd, WORD wParam, LONG lParam)
{
  return DLGC_WANTARROWS | DLGC_WANTCHARS;
}

/***********************************************************************
 *           LBGetTopIndex
 */
static LONG LBGetTopIndex(HWND hwnd, WORD wParam, LONG lParam)
{
  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);

  return lphl->FirstVisible;
}


/***********************************************************************
 *           LBSelectString
 */
static LONG LBSelectString(HWND hwnd, WORD wParam, LONG lParam)
{
  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
  INT  iRet;

  iRet = lbFindString(lphl, wParam, (SEGPTR)lParam, MATCH_SUBSTR);

  if( iRet != LB_ERR)
    {
      if( lphl->dwStyle & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL) )
         ListBoxSetSel(lphl,iRet,TRUE);
      else
         ListBoxSetCurSel(lphl,iRet);

      lphl->ItemFocused = iRet;
      InvalidateRect32( hwnd, 0, TRUE );
    }
  return iRet;
}

/***********************************************************************
 *           LBSelItemRange
 */
static LONG LBSelItemRange(HWND hwnd, WORD wParam, LONG lParam)
{
  LPHEADLIST   lphl = ListBoxGetStorageHeader(hwnd);
  LPLISTSTRUCT lpls;
  WORD         cnt;
  WORD         first = LOWORD(lParam);
  WORD         last = HIWORD(lParam);
  BOOL         select = wParam;

  if (!(lphl->dwStyle & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)  )) 
        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->itemState = select ? lpls->itemState | ODS_SELECTED : 0;

    if (cnt > last)
      break;

    lpls = lpls->lpNext;
  }

  return 0;
}

/***********************************************************************
 *           LBSetCaretIndex
 */
static LONG LBSetCaretIndex(HWND hwnd, WORD wParam, LONG lParam)
{
  LPHEADLIST   lphl = ListBoxGetStorageHeader(hwnd);
  int          i;

  if (!(lphl->dwStyle & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL) )) return 0;

  dprintf_listbox(stddeb,"LBSetCaretIndex: hwnd %04x n=%i\n",hwnd,wParam);  

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

  lphl->ItemFocused = wParam;
  i = ListBoxScrollToFocus (lphl);

  SetScrollPos32(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
  if(i)
    InvalidateRect32( hwnd, NULL, TRUE );
 
  return 1;
}

/***********************************************************************
 *           LBSetColumnWidth
 */
static LONG LBSetColumnWidth(HWND hwnd, WORD wParam, LONG lParam)
{
  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
  lphl->ColumnsWidth = wParam;
  InvalidateRect32( hwnd, NULL, TRUE );
  return 0;
}

/***********************************************************************
 *           LBSetHorizontalExtent
 */
static LONG LBSetHorizontalExtent(HWND hwnd, WORD wParam, LONG lParam)
{
  return 0;
}

/***********************************************************************
 *           LBGetItemData
 */
static LONG LBGetItemData(HWND hwnd, WORD wParam, LONG lParam)
{
  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
  dprintf_listbox(stddeb, "LB_GETITEMDATA wParam=%x\n", wParam);
  return ListBoxGetItemData(lphl, wParam);
}

/***********************************************************************
 *           LBSetItemData
 */
static LONG LBSetItemData(HWND hwnd, WORD wParam, LONG lParam)
{
  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
  dprintf_listbox(stddeb, "LB_SETITEMDATA  wParam=%x  lParam=%lx\n", wParam, lParam);
  return ListBoxSetItemData(lphl, wParam, lParam);
}

/***********************************************************************
 *           LBSetTabStops
 */
static LONG LBSetTabStops(HWND hwnd, 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
 */
static LONG LBSetCurSel(HWND hwnd, WORD wParam, LONG lParam)
{
  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
  WORD  wRet;

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

  wRet = ListBoxSetCurSel(lphl, wParam);

  SetScrollPos32(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
  InvalidateRect32( hwnd, NULL, TRUE );

  return wRet;
}

/***********************************************************************
 *           LBSetSel
 */
static LONG LBSetSel(HWND hwnd, WORD wParam, LONG lParam)
{
  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
  RECT16 rect;
  int iRet;

  dprintf_listbox(stddeb,"ListBox LB_SETSEL wParam=%x lParam=%lX !\n", wParam, lParam);

  iRet = ListBoxSetSel(lphl, LOWORD(lParam), wParam);

  if( iRet > 1 ) InvalidateRect32( hwnd, NULL, TRUE );
  else if( iRet != LB_ERR )
      {
        if( lphl->dwStyle & LBS_EXTENDEDSEL &&
            lphl->ItemFocused != LOWORD(lParam) )
          {
            ListBoxGetItemRect(lphl, lphl->ItemFocused , &rect);
            InvalidateRect16( hwnd, &rect, TRUE );
            lphl->ItemFocused = LOWORD(lParam);
          }
        ListBoxGetItemRect(lphl,LOWORD(lParam),&rect);
        InvalidateRect16( hwnd, &rect, TRUE );
      }

  return (iRet == (WORD)LB_ERR)? LB_ERR: 0;
}

/***********************************************************************
 *           LBSetTopIndex
 */
static LONG LBSetTopIndex(HWND hwnd, WORD wParam, LONG lParam)
{
  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);

  dprintf_listbox(stddeb,"ListBox LB_SETTOPINDEX wParam=%x !\n",
		  wParam);
  lphl->FirstVisible = wParam;
  SetScrollPos32(hwnd, SB_VERT, lphl->FirstVisible, TRUE);

  InvalidateRect32( hwnd, NULL, TRUE );

  return 0;
}

/***********************************************************************
 *           LBSetItemHeight
 */
static LONG LBSetItemHeight(HWND hwnd, WORD wParam, LONG lParam)
{
  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
  WORD wRet;
  
  dprintf_listbox(stddeb,"ListBox LB_SETITEMHEIGHT wParam=%x lParam=%lX !\n", wParam, lParam);
  wRet = ListBoxSetItemHeight(lphl, wParam, lParam);
  InvalidateRect32( hwnd, NULL, TRUE );
  return wRet;
}

/***********************************************************************
 *	     LBPassToParent
 */
static LRESULT LBPassToParent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  WND* ptrWnd = WIN_FindWndPtr(hwnd);  

  if( ptrWnd )
      if( /* !(ptrWnd->dwExStyle & WS_EX_NOPARENTNOTIFY) && */ 
          ptrWnd->parent ) 
          return SendMessage16(ptrWnd->parent->hwndSelf,message,wParam,lParam);
  return 0;
}

/***********************************************************************
 *           ListBoxWndProc 
 */
LRESULT ListBoxWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{ 
    switch (message) {
     case WM_CREATE: return LBCreate(hwnd, wParam, lParam);
     case WM_DESTROY: return LBDestroy(hwnd, wParam, lParam);
     case WM_GETDLGCODE: return LBGetDlgCode(hwnd, wParam, lParam);
     case WM_VSCROLL: return LBVScroll(hwnd, wParam, lParam);
     case WM_HSCROLL: return LBHScroll(hwnd, wParam, lParam);
     case WM_LBUTTONDOWN: return LBLButtonDown(hwnd, wParam, lParam);
     case WM_LBUTTONUP: return LBLButtonUp(hwnd, wParam, lParam);
     case WM_RBUTTONUP: return LBRButtonUp(hwnd, wParam, lParam);
     case WM_LBUTTONDBLCLK: return LBRButtonUp(hwnd, wParam, lParam);
     case WM_MOUSEMOVE: return LBMouseMove(hwnd, wParam, lParam);
     case WM_KEYDOWN: return LBKeyDown(hwnd, wParam, lParam);
     case WM_CHAR: return LBChar(hwnd, wParam, lParam);
     case WM_SETFONT: return LBSetFont(hwnd, wParam, lParam);
     case WM_SETREDRAW: return LBSetRedraw(hwnd, wParam, lParam);
     case WM_PAINT: return LBPaint(hwnd, wParam, lParam);
     case WM_SETFOCUS: return LBSetFocus(hwnd, wParam, lParam);
     case WM_KILLFOCUS: return LBKillFocus(hwnd, wParam, lParam);
     case WM_NCCALCSIZE: return LBNCCalcSize(hwnd, wParam, lParam);
     case LB_RESETCONTENT16: return LBResetContent(hwnd, wParam, lParam);
     case LB_DIR16: return LBDir(hwnd, wParam, lParam);
     case LB_ADDSTRING16: return LBAddString(hwnd, wParam, lParam);
     case LB_INSERTSTRING16: return LBInsertString(hwnd, wParam, lParam);
     case LB_DELETESTRING16: return LBDeleteString(hwnd, wParam, lParam);
     case LB_FINDSTRING16: return LBFindString(hwnd, wParam, lParam);
     case LB_FINDSTRINGEXACT16: return LBFindStringExact(hwnd, wParam, lParam);
     case LB_GETCARETINDEX16: return LBGetCaretIndex(hwnd, wParam, lParam);
     case LB_GETCOUNT16: return LBGetCount(hwnd, wParam, lParam);
     case LB_GETCURSEL16: return LBGetCurSel(hwnd, wParam, lParam);
     case LB_GETHORIZONTALEXTENT16: return LBGetHorizontalExtent(hwnd, wParam, lParam);
     case LB_GETITEMDATA16: return LBGetItemData(hwnd, wParam, lParam);
     case LB_GETITEMHEIGHT16: return LBGetItemHeight(hwnd, wParam, lParam);
     case LB_GETITEMRECT16: return LBGetItemRect(hwnd, wParam, lParam);
     case LB_GETSEL16: return LBGetSel(hwnd, wParam, lParam);
     case LB_GETSELCOUNT16: return LBGetSelCount(hwnd, wParam, lParam);
     case LB_GETSELITEMS16: return LBGetSelItems(hwnd, wParam, lParam);
     case LB_GETTEXT16: return LBGetText(hwnd, wParam, lParam);
     case LB_GETTEXTLEN16: return LBGetTextLen(hwnd, wParam, lParam);
     case LB_GETTOPINDEX16: return LBGetTopIndex(hwnd, wParam, lParam);
     case LB_SELECTSTRING16: return LBSelectString(hwnd, wParam, lParam);
     case LB_SELITEMRANGE16: return LBSelItemRange(hwnd, wParam, lParam);
     case LB_SETCARETINDEX16: return LBSetCaretIndex(hwnd, wParam, lParam);
     case LB_SETCOLUMNWIDTH16: return LBSetColumnWidth(hwnd, wParam, lParam);
     case LB_SETHORIZONTALEXTENT16: return LBSetHorizontalExtent(hwnd, wParam, lParam);
     case LB_SETITEMDATA16: return LBSetItemData(hwnd, wParam, lParam);
     case LB_SETTABSTOPS16: return LBSetTabStops(hwnd, wParam, lParam);
     case LB_SETCURSEL16: return LBSetCurSel(hwnd, wParam, lParam);
     case LB_SETSEL16: return LBSetSel(hwnd, wParam, lParam);
     case LB_SETTOPINDEX16: return LBSetTopIndex(hwnd, wParam, lParam);
     case LB_SETITEMHEIGHT16: return LBSetItemHeight(hwnd, wParam, lParam);

     case WM_DROPFILES: return LBPassToParent(hwnd, message, wParam, lParam);

     /* these will have to be implemented for proper LBS_EXTENDEDSEL -
      *
      * anchor item is an item that with caret (focused) item defines a 
      * range of currently selected items when listbox is in the extended 
      * selection mode.
      */
     case LB_SETANCHORINDEX16: return LB_SETANCHORINDEX16; /* that's what Windows returns */
     case LB_GETANCHORINDEX16: return 0;

	case WM_DROPOBJECT:
	case WM_QUERYDROPOBJECT:
	case WM_DRAGSELECT:
	case WM_DRAGMOVE:
	        {
		 LPDRAGINFO lpDragInfo = (LPDRAGINFO) PTR_SEG_TO_LIN((SEGPTR)lParam);
		 LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);

		 lpDragInfo->l = ListBoxFindMouse(lphl,lpDragInfo->pt.x,
						       lpDragInfo->pt.y);
	        
		 return LBPassToParent(hwnd, message, wParam, lParam);
		}
    }
    
    return DefWindowProc16(hwnd, message, wParam, lParam);
}


/**********************************************************************
 *	    DlgDirSelect    (USER.99)
 */
BOOL DlgDirSelect( HWND hDlg, LPSTR lpStr, INT id )
{
    char *buffer;
    INT i;

    dprintf_listbox( stddeb, "DlgDirSelect: %04x '%s' %d\n", hDlg, lpStr, id );
    if ((i = SendDlgItemMessage16( hDlg, id, LB_GETCURSEL16, 0, 0 )) == LB_ERR)
        return FALSE;
    if (!(buffer = SEGPTR_ALLOC( 20 * sizeof(char) ))) return FALSE;
    SendDlgItemMessage16(hDlg, id, LB_GETTEXT16, i, (LPARAM)SEGPTR_GET(buffer) );
    if (buffer[0] == '[')  /* drive or directory */
    {
        if (buffer[1] == '-')  /* drive */
        {
            lpStr[0] = buffer[2];
            lpStr[1] = ':';
            lpStr[2] = '\0';
            dprintf_listbox( stddeb, "Returning drive '%s'\n", lpStr );
            SEGPTR_FREE(buffer);
            return TRUE;
        }
        strcpy( lpStr, buffer + 1 );
        lpStr[strlen(lpStr)-1] = '\\';
        dprintf_listbox( stddeb, "Returning directory '%s'\n", lpStr );
        SEGPTR_FREE(buffer);
        return TRUE;
    }
    strcpy( lpStr, buffer );
    dprintf_listbox( stddeb, "Returning file '%s'\n", lpStr );
    SEGPTR_FREE(buffer);
    return FALSE;
}


/**********************************************************************
 *	    DlgDirList    (USER.100)
 */
INT DlgDirList( HWND hDlg, SEGPTR spec, INT idLBox, INT idStatic, UINT attrib )
{
    char *filespec = (char *)PTR_SEG_TO_LIN( spec );
    int drive;
    HWND hwnd;

#define SENDMSG(msg,wparam,lparam) \
    ((attrib & DDL_POSTMSGS) ? PostMessage( hwnd, msg, wparam, lparam ) \
                             : SendMessage16( hwnd, msg, wparam, lparam ))

    dprintf_listbox( stddeb, "DlgDirList: %04x '%s' %d %d %04x\n",
                     hDlg, filespec ? filespec : "NULL",
                     idLBox, idStatic, attrib );

    if (filespec && filespec[0] && (filespec[1] == ':'))
    {
        drive = toupper( filespec[0] ) - 'A';
        filespec += 2;
        if (!DRIVE_SetCurrentDrive( drive )) return FALSE;
    }
    else drive = DRIVE_GetCurrentDrive();

    if (idLBox && ((hwnd = GetDlgItem( hDlg, idLBox )) != 0))
    {
        char mask[20];
        
        if (!filespec || !filespec[0]) strcpy( mask, "*.*" );
        else
        {
            /* If the path exists and is a directory, chdir to it */
            if (DRIVE_Chdir( drive, filespec )) strcpy( mask, "*.*" );
            else
            {
                char *p, *p2;
                p = filespec;
                if ((p2 = strrchr( p, '\\' ))) p = p2 + 1;
                if ((p2 = strrchr( p, '/' ))) p = p2 + 1;
                lstrcpyn32A( mask, p, sizeof(mask) );
                if (p != filespec)
                {
                    p[-1] = '\0';
                    if (!DRIVE_Chdir( drive, filespec )) return FALSE;
                }
            }
        }
        
        strcpy( (char *)PTR_SEG_TO_LIN(spec), mask );

        dprintf_listbox(stddeb, "ListBoxDirectory: path=%c:\\%s mask=%s\n",
                        'A' + drive, DRIVE_GetDosCwd(drive), mask);
        
        SENDMSG( LB_RESETCONTENT16, 0, 0 );
        if ((attrib & DDL_DIRECTORY) && !(attrib & DDL_EXCLUSIVE))
        {
            char *temp;
            if (SENDMSG( LB_DIR16, attrib & ~(DDL_DIRECTORY | DDL_DRIVES),
                         (LPARAM)spec ) == LB_ERR) return FALSE;
            if (!(temp = SEGPTR_ALLOC( 4*sizeof(char) ))) return FALSE;
            strcpy( temp, "*.*" );
            /* FIXME: this won't work with PostMessage(), as temp will */
            /* have been freed by the time we do a DispatchMessage().  */
            if (SENDMSG( LB_DIR16, (attrib & (DDL_DIRECTORY | DDL_DRIVES)) | DDL_EXCLUSIVE,
                         (LPARAM)SEGPTR_GET(temp) ) == LB_ERR)
            {
                SEGPTR_FREE(temp);
                return FALSE;
            }
            SEGPTR_FREE(temp);
        }
        else
        {
            if (SENDMSG( LB_DIR16, attrib, (LPARAM)spec) == LB_ERR) return FALSE;
        }
    }

    if (idStatic && ((hwnd = GetDlgItem( hDlg, idStatic )) != 0))
    {
        char temp[512];
        int drive = DRIVE_GetCurrentDrive();
        strcpy( temp, "A:\\" );
        temp[0] += drive;
        lstrcpyn32A( temp + 3, DRIVE_GetDosCwd(drive), sizeof(temp)-3 );
        AnsiLower( temp );
        /* Can't use PostMessage() here, because the string is on the stack */
        SetDlgItemText32A( hDlg, idStatic, temp );
    }
    return TRUE;
#undef SENDMSG
}
