/*
 * Combo controls
 * 
 * Copyright 1993 Martin Ayotte
 * Copyright 1995 Bernd Schmidt
 * Copyright 1996 Albrecht Kleine  [some fixes]
 * 
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>

#include "windows.h"
#include "sysmetrics.h"
#include "win.h"
#include "combo.h"
#include "user.h"
#include "graphics.h"
#include "heap.h"
#include "listbox.h"
#include "drive.h"
#include "stddebug.h"
#include "debug.h"
#include "xmalloc.h"

 /*
  * Note: Combos are probably implemented in a different way by Windows.
  * Using a message spy for Windows, you can see some undocumented
  * messages being passed between ComboBox and ComboLBox.
  * I hope no programs rely on the implementation of combos.
  */

#define ID_EDIT  1
#define ID_CLB   2
#define CBLMM_EDGE   4    /* distance inside box which is same as moving mouse
			     outside box, to trigger scrolling of CBL */

static BOOL CBCheckSize(HWND hwnd);
static BOOL CBLCheckSize(HWND hwnd);

static HBITMAP16 hComboBit = 0;
static WORD CBitHeight, CBitWidth;

static int COMBO_Init()
{
  BITMAP16 bm;
  
  dprintf_combo(stddeb, "COMBO_Init\n");
  hComboBit = LoadBitmap16(0, MAKEINTRESOURCE(OBM_COMBO));
  GetObject16( hComboBit, sizeof(bm), &bm );
  CBitHeight = bm.bmHeight;
  CBitWidth = bm.bmWidth;
  return 0;
}

LPHEADCOMBO ComboGetStorageHeader(HWND hwnd)
{
  return (LPHEADCOMBO)GetWindowLong32A(hwnd,4);
}

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

int CreateComboStruct(HWND hwnd, LONG style)
{
  LPHEADCOMBO lphc;

  lphc = (LPHEADCOMBO)xmalloc(sizeof(HEADCOMBO));
  SetWindowLong32A(hwnd,4,(LONG)lphc);
  lphc->hWndEdit = 0;
  lphc->hWndLBox = 0;
  lphc->dwState = 0;
  lphc->LastSel = -1;
  lphc->dwStyle = style; 
  lphc->DropDownVisible = FALSE;
  return TRUE;
}

void ComboUpdateWindow(HWND hwnd, LPHEADLIST lphl, LPHEADCOMBO lphc, BOOL repaint)
{
  WND *wndPtr = WIN_FindWndPtr(hwnd);

  if (wndPtr->dwStyle & WS_VSCROLL) 
    SetScrollRange32(lphc->hWndLBox,SB_VERT,0,ListMaxFirstVisible(lphl),TRUE);
  if (repaint && lphl->bRedrawFlag) InvalidateRect32( hwnd, NULL, TRUE );
}

/***********************************************************************
 *           CBNCCreate
 */
static LRESULT CBNCCreate(HWND hwnd, WPARAM16 wParam, LPARAM lParam)
{
  CREATESTRUCT16 *createStruct;

  if (!hComboBit) COMBO_Init();

  createStruct = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam);
  createStruct->style |= WS_BORDER;
  SetWindowLong32A(hwnd, GWL_STYLE, createStruct->style);

  dprintf_combo(stddeb,"ComboBox WM_NCCREATE!\n");
  return DefWindowProc16(hwnd, WM_NCCREATE, wParam, lParam);

}

/***********************************************************************
 *           CBCreate
 */
static LRESULT CBCreate(HWND hwnd, WPARAM16 wParam, LPARAM lParam)
{
  LPHEADLIST   lphl;
  LPHEADCOMBO  lphc;
  LONG         style = 0;
  LONG         cstyle = GetWindowLong32A(hwnd,GWL_STYLE);
  RECT16       rect,lboxrect;
  WND*         wndPtr = WIN_FindWndPtr(hwnd);
  char className[] = "COMBOLBOX";  /* Hack so that class names are > 0x10000 */
  char editName[] = "EDIT";
  HWND hwndp=0;

  /* translate combo into listbox styles */
  cstyle |= WS_BORDER;
  if (cstyle & CBS_OWNERDRAWFIXED) style |= LBS_OWNERDRAWFIXED;
  if (cstyle & CBS_OWNERDRAWVARIABLE) style |= LBS_OWNERDRAWVARIABLE;
  if (cstyle & CBS_SORT) style |= LBS_SORT;
  if (cstyle & CBS_HASSTRINGS) style |= LBS_HASSTRINGS;
  style |= LBS_NOTIFY;
  CreateListBoxStruct(hwnd, ODT_COMBOBOX, style, GetParent16(hwnd));
  CreateComboStruct(hwnd,cstyle);

  lphl = ComboGetListHeader(hwnd);
  lphc = ComboGetStorageHeader(hwnd);

  GetClientRect16(hwnd,&rect);
  lphc->LBoxTop = lphl->StdItemHeight;

  switch(cstyle & 3) 
  {
   case CBS_SIMPLE:            /* edit control, list always visible  */
     lboxrect=rect;    
     dprintf_combo(stddeb,"CBS_SIMPLE\n");
     style= WS_BORDER |  WS_CHILD | WS_VISIBLE | WS_VSCROLL;
     SetRectEmpty16(&lphc->RectButton);
     hwndp=hwnd;
     break;

   case CBS_DROPDOWNLIST:      /* static control, dropdown listbox   */
   case CBS_DROPDOWN:          /* edit control, dropdown listbox     */
     GetWindowRect16(hwnd,&lboxrect);
     style = WS_POPUP | WS_BORDER | WS_VSCROLL;
     /* FIXME: WinSight says these should be CHILD windows with the TOPMOST flag
      * set. Wine doesn't support TOPMOST, and simply setting the WS_CHILD
      * flag doesn't work. */
     lphc->RectButton = rect;
     lphc->RectButton.left = lphc->RectButton.right - 6 - CBitWidth;
     lphc->RectButton.bottom = lphc->RectButton.top + lphl->StdItemHeight;
     SetWindowPos32(hwnd, 0, 0, 0, rect.right -rect.left + 2*SYSMETRICS_CXBORDER,
		 lphl->StdItemHeight + 2*SYSMETRICS_CYBORDER,
		 SWP_NOMOVE | SWP_NOZORDER | SWP_NOSENDCHANGING | SWP_NOACTIVATE);
     dprintf_combo(stddeb,(cstyle & 3)==CBS_DROPDOWN ? "CBS_DROPDOWN\n": "CBS_DROPDOWNLIST\n");
     break;
     
   default: fprintf(stderr,"COMBOBOX error: bad class style!\n");
     return 0;
  }

  if ((cstyle & 3) != CBS_DROPDOWNLIST)
      lphc->hWndEdit = CreateWindow16( editName, NULL,
				  WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | ES_LEFT,
				  0, 0, rect.right-6-CBitWidth,
				  lphl->StdItemHeight+2*SYSMETRICS_CYBORDER,
				  hwnd, (HMENU16)ID_EDIT, WIN_GetWindowInstance(hwnd), NULL );
				  
  lboxrect.top+=lphc->LBoxTop;
  lphc->hWndLBox = CreateWindow16( className, NULL, style |
 				((cstyle & WS_HSCROLL)? WS_HSCROLL : 0) |
 				((cstyle & WS_VSCROLL)? WS_VSCROLL : 0),
				lboxrect.left, lboxrect.top,
				lboxrect.right - lboxrect.left, 
				lboxrect.bottom - lboxrect.top,
				hwndp,(HMENU16)ID_CLB, WIN_GetWindowInstance(hwnd),
				(LPVOID)(HWND32)hwnd );

   wndPtr->dwStyle &= ~(WS_VSCROLL | WS_HSCROLL);

   dprintf_combo( stddeb, "Combo Creation hwnd=%04x  LBox=%04x  Edit=%04x\n",
                  hwnd, lphc->hWndLBox, lphc->hWndEdit);
   dprintf_combo( stddeb, "  lbox %d,%d-%d,%d     button %d,%d-%d,%d\n",
                  lboxrect.left, lboxrect.top, lboxrect.right, lboxrect.bottom,
                  lphc->RectButton.left, lphc->RectButton.top,
                  lphc->RectButton.right, lphc->RectButton.bottom );
   dprintf_combo( stddeb, "   client %d,%d-%d,%d     window %d,%d-%d,%d\n",
                  wndPtr->rectClient.left, wndPtr->rectClient.top,
                  wndPtr->rectClient.right, wndPtr->rectClient.bottom,
                  wndPtr->rectWindow.left, wndPtr->rectWindow.top,
                  wndPtr->rectWindow.right, wndPtr->rectWindow.bottom );
   return 0;
}

/***********************************************************************
 *           CBDestroy
 */
static LRESULT CBDestroy(HWND hwnd, WPARAM16 wParam, LPARAM lParam)
{
  LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd);

  if (lphc->hWndEdit) DestroyWindow32( lphc->hWndEdit );
  if (lphc->hWndLBox) DestroyWindow32( lphc->hWndLBox );
  return 0;
}

/***********************************************************************
 *           CBPaint
 */
static LRESULT CBPaint(HWND hwnd, WPARAM16 wParam, LPARAM lParam)
{
  LPHEADLIST lphl = ComboGetListHeader(hwnd);
  LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd);
  LPLISTSTRUCT lpls;
  PAINTSTRUCT16  ps;
  HBRUSH32 hBrush;
  HFONT32 hOldFont;
  HDC16 hdc;
  RECT16 rect;
  
  hdc = BeginPaint16(hwnd, &ps);

  GetClientRect16(hwnd, &rect);
  CBCheckSize(hwnd);
  /* 1 for button border */
  rect.right = lphc->RectButton.left - 1;

  if (hComboBit != 0 && !IsRectEmpty16(&lphc->RectButton))
  {
    Rectangle32(hdc,lphc->RectButton.left-1,lphc->RectButton.top-1,
                lphc->RectButton.right+1,lphc->RectButton.bottom+1);
    {
        RECT32 r;
        CONV_RECT16TO32( &lphc->RectButton, &r );
        GRAPH_DrawReliefRect(hdc, &r, 2, 2, FALSE);
    }
    GRAPH_DrawBitmap(hdc, hComboBit,
		     lphc->RectButton.left + 2,lphc->RectButton.top + 2,
		     0, 0, CBitWidth, CBitHeight );
  }
  if (!IsWindowVisible16(hwnd) || !lphl->bRedrawFlag 
      || (lphc->dwStyle & 3) != CBS_DROPDOWNLIST) 
  {
    /* we don't want to draw an entry when there is an edit control */
    EndPaint16(hwnd, &ps);
    return 0;
  }

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

  hBrush = SendMessage32A( lphl->hParent, WM_CTLCOLORLISTBOX, hdc, hwnd );
  if (hBrush == 0) hBrush = GetStockObject32(WHITE_BRUSH);

  lpls = ListBoxGetItem(lphl,lphl->ItemFocused);
  if (lpls != NULL) {  
    FillRect16(hdc, &rect, hBrush);
    ListBoxDrawItem (hwnd, lphl, hdc, lpls, &rect, ODA_DRAWENTIRE, 0);
    if (GetFocus32() == hwnd)
    ListBoxDrawItem (hwnd,lphl, hdc, lpls, &rect, ODA_FOCUS, ODS_FOCUS);
  }
  else FillRect16(hdc, &rect, hBrush);
  SelectObject32(hdc,hOldFont);
  EndPaint16(hwnd, &ps);
  return 0;
}

/***********************************************************************
 *           CBGetDlgCode
 */
static LRESULT CBGetDlgCode(HWND hwnd, WPARAM16 wParam, LPARAM lParam)
{
  return DLGC_WANTARROWS | DLGC_WANTCHARS;
}

/***********************************************************************
 *           CBLButtonDown
 */
static LRESULT CBLButtonDown(HWND hwnd, WPARAM16 wParam, LPARAM lParam)
{
  LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd);
  SendMessage16(hwnd,CB_SHOWDROPDOWN16,!lphc->DropDownVisible,0);
  return 0;
}

/***********************************************************************
 *           CBKeyDown
 */
static LRESULT CBKeyDown(HWND hwnd, WPARAM16 wParam, LPARAM lParam)
{
  LPHEADLIST lphl = ComboGetListHeader(hwnd);
  WORD       newFocused = lphl->ItemFocused;

  switch(wParam) {
  case VK_HOME:
    newFocused = 0;
    break;
  case VK_END:
    newFocused = lphl->ItemsCount - 1;
    break;
  case VK_UP:
    if (newFocused > 0) newFocused--;
    break;
  case VK_DOWN:
    newFocused++;
    break;
  default:
    return 0;
  }

  if (newFocused >= lphl->ItemsCount)
    newFocused = lphl->ItemsCount - 1;
  
  ListBoxSetCurSel(lphl, newFocused);
  SendMessage16(hwnd, WM_COMMAND,ID_CLB,MAKELONG(0,CBN_SELCHANGE));
  ListBoxSendNotification(lphl, CBN_SELCHANGE);

  lphl->ItemFocused = newFocused;
  ListBoxScrollToFocus(lphl);
/*  SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);*/
  InvalidateRect32( hwnd, NULL, TRUE );

  return 0;
}

/***********************************************************************
 *           CBChar
 */
static LRESULT CBChar(HWND hwnd, WPARAM16 wParam, LPARAM lParam)
{
  LPHEADLIST lphl = ComboGetListHeader(hwnd);
  WORD       newFocused;

  newFocused = ListBoxFindNextMatch(lphl, wParam);
  if (newFocused == (WORD)LB_ERR) return 0;

  if (newFocused >= lphl->ItemsCount)
    newFocused = lphl->ItemsCount - 1;
  
  ListBoxSetCurSel(lphl, newFocused);
  SendMessage16(hwnd, WM_COMMAND,ID_CLB,MAKELONG(0,CBN_SELCHANGE));
  ListBoxSendNotification(lphl, CBN_SELCHANGE);
  lphl->ItemFocused = newFocused;
  ListBoxScrollToFocus(lphl);
  
/*  SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);*/
  InvalidateRect32( hwnd, NULL, TRUE );

  return 0;
}

/***********************************************************************
 *           CBKillFocus
 */
static LRESULT CBKillFocus(HWND hwnd, WPARAM16 wParam, LPARAM lParam)
{
  return 0;
}

/***********************************************************************
 *           CBSetFocus
 */
static LRESULT CBSetFocus(HWND hwnd, WPARAM16 wParam, LPARAM lParam)
{
  return 0;
}

/***********************************************************************
 *           CBResetContent
 */
static LRESULT CBResetContent(HWND hwnd, WPARAM16 wParam, LPARAM lParam)
{
  LPHEADLIST lphl = ComboGetListHeader(hwnd);
  LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd);

  ListBoxResetContent(lphl);
  ComboUpdateWindow(hwnd, lphl, lphc, TRUE);
  return 0;
}

/***********************************************************************
 *           CBDir
 */
static LRESULT CBDir(HWND hwnd, WPARAM16 wParam, LPARAM lParam)
{
  WORD wRet;
  LPHEADLIST lphl = ComboGetListHeader(hwnd);
  LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd);

  wRet = ListBoxDirectory(lphl, wParam, (LPSTR)PTR_SEG_TO_LIN(lParam));
  ComboUpdateWindow(hwnd, lphl, lphc, TRUE);
  return wRet;
}

/***********************************************************************
 *           CBInsertString
 */
static LRESULT CBInsertString(HWND hwnd, WPARAM16 wParam, LPARAM lParam)
{
  WORD  wRet;
  LPHEADLIST lphl = ComboGetListHeader(hwnd);
  LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd);

  if (lphl->HasStrings)
    wRet = ListBoxInsertString(lphl, wParam, (LPSTR)PTR_SEG_TO_LIN(lParam));
  else
    wRet = ListBoxInsertString(lphl, wParam, (LPSTR)lParam);
  ComboUpdateWindow(hwnd, lphl, lphc, TRUE);
  return wRet;
}

/***********************************************************************
 *           CBAddString
 */
static LRESULT CBAddString(HWND hwnd, WPARAM16 wParam, LPARAM lParam)
{
  WORD  wRet;
  LPHEADLIST lphl = ComboGetListHeader(hwnd);
  LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd);

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

  ComboUpdateWindow(hwnd, lphl, lphc, TRUE);
  return wRet;
}

/***********************************************************************
 *           CBDeleteString
 */
static LRESULT CBDeleteString(HWND hwnd, WPARAM16 wParam, LPARAM lParam)
{
  LPHEADLIST lphl = ComboGetListHeader(hwnd);
  LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd);
  LONG lRet = ListBoxDeleteString(lphl,wParam);
  
  ComboUpdateWindow(hwnd, lphl, lphc, TRUE);
  return lRet;
}

/***********************************************************************
 *           CBSelectString
 */
static LRESULT CBSelectString(HWND hwnd, WPARAM16 wParam, LPARAM lParam)
{
  LPHEADLIST lphl = ComboGetListHeader(hwnd);
  WORD  wRet;

  wRet = ListBoxFindString(lphl, wParam, (SEGPTR)lParam);

  /* XXX add functionality here */

  return 0;
}

/***********************************************************************
 *           CBFindString
 */
static LRESULT CBFindString(HWND hwnd, WPARAM16 wParam, LPARAM lParam)
{
  LPHEADLIST lphl = ComboGetListHeader(hwnd);
  return ListBoxFindString(lphl, wParam, (SEGPTR)lParam);
}

/***********************************************************************
 *           CBFindStringExact
 */
static LRESULT CBFindStringExact(HWND hwnd, WPARAM16 wParam, LPARAM lParam)
{
  LPHEADLIST lphl = ComboGetListHeader(hwnd);
  return ListBoxFindStringExact(lphl, wParam, (SEGPTR)lParam);
}

/***********************************************************************
 *           CBGetCount
 */
static LRESULT CBGetCount(HWND hwnd, WPARAM16 wParam, LPARAM lParam)
{
  LPHEADLIST lphl = ComboGetListHeader(hwnd);
  return lphl->ItemsCount;
}

/***********************************************************************
 *           CBSetCurSel
 */
static LRESULT CBSetCurSel(HWND hwnd, WPARAM16 wParam, LPARAM lParam)
{
  LPHEADLIST lphl = ComboGetListHeader(hwnd);
  WORD  wRet;

  wRet = ListBoxSetCurSel(lphl, wParam);

  dprintf_combo(stddeb,"CBSetCurSel: hwnd %04x wp %x lp %lx wRet %d\n",
		hwnd,wParam,lParam,wRet);
/*  SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);*/
  InvalidateRect32( hwnd, NULL, TRUE );

  return wRet;
}

/***********************************************************************
 *           CBGetCurSel
 */
static LRESULT CBGetCurSel(HWND hwnd, WPARAM16 wParam, LPARAM lParam)
{
  LPHEADLIST lphl = ComboGetListHeader(hwnd);
  return lphl->ItemFocused;
}

/***********************************************************************
 *           CBGetItemHeight
 */
static LRESULT CBGetItemHeight(HWND hwnd, WPARAM16 wParam, LPARAM lParam)
{
  LPHEADLIST lphl = ComboGetListHeader(hwnd);
  LPLISTSTRUCT lpls = ListBoxGetItem (lphl, wParam);

  if (lpls == NULL) return LB_ERR;
  return lpls->mis.itemHeight;
}

/***********************************************************************
 *           CBSetItemHeight
 */
static LRESULT CBSetItemHeight(HWND hwnd, WPARAM16 wParam, LPARAM lParam)
{
  LPHEADLIST lphl = ComboGetListHeader(hwnd);
  return ListBoxSetItemHeight(lphl, wParam, lParam);
}

/***********************************************************************
 *           CBSetRedraw
 */
static LRESULT CBSetRedraw(HWND hwnd, WPARAM16 wParam, LPARAM lParam)
{
  LPHEADLIST lphl = ComboGetListHeader(hwnd);
  lphl->bRedrawFlag = wParam;
  return 0;
}

/***********************************************************************
 *           CBSetFont
 */
static LRESULT CBSetFont(HWND hwnd, WPARAM16 wParam, LPARAM lParam)
{
  LPHEADLIST  lphl = ComboGetListHeader(hwnd);
  LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd);
  
  if (wParam == 0)
    lphl->hFont = GetStockObject32(SYSTEM_FONT);
  else
    lphl->hFont = (HFONT16)wParam;
  if (lphc->hWndEdit)
     SendMessage16(lphc->hWndEdit,WM_SETFONT,lphl->hFont,0); 
  return 0;
}

/***********************************************************************
 *           CBGetLBTextLen
 */
static LRESULT CBGetLBTextLen(HWND hwnd, WPARAM16 wParam, LPARAM lParam)
{
  LPHEADLIST   lphl = ComboGetListHeader(hwnd);
  LPLISTSTRUCT lpls = ListBoxGetItem(lphl,wParam);

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

/***********************************************************************
 *           CBGetLBText
 */
static LRESULT CBGetLBText(HWND hwnd, WPARAM16 wParam, LPARAM lParam)
{
  LPHEADLIST lphl = ComboGetListHeader(hwnd);
  return ListBoxGetText(lphl, wParam, (LPSTR)PTR_SEG_TO_LIN(lParam));
}

/***********************************************************************
 *           CBGetItemData
 */
static LRESULT CBGetItemData(HWND hwnd, WPARAM16 wParam, LPARAM lParam)
{
  LPHEADLIST lphl = ComboGetListHeader(hwnd);
  return ListBoxGetItemData(lphl, wParam);
}

/***********************************************************************
 *           CBSetItemData
 */
static LRESULT CBSetItemData(HWND hwnd, WPARAM16 wParam, LPARAM lParam)
{
  LPHEADLIST lphl = ComboGetListHeader(hwnd);
  return ListBoxSetItemData(lphl, wParam, lParam);
}

/***********************************************************************
 *           CBShowDropDown
 */
static LRESULT CBShowDropDown(HWND hwnd, WPARAM16 wParam, LPARAM lParam)
{
  LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd);
  RECT32 rect;
  
  if ((lphc->dwStyle & 3) == CBS_SIMPLE) return LB_ERR;
  
  wParam = !!wParam;
  if (wParam != lphc->DropDownVisible) {
    lphc->DropDownVisible = wParam;
    GetWindowRect32(hwnd,&rect);
    SetWindowPos32(lphc->hWndLBox, 0, rect.left, rect.top+lphc->LBoxTop, 0, 0,
		 SWP_NOSIZE | SWP_NOACTIVATE |
                 (wParam ? SWP_SHOWWINDOW : SWP_HIDEWINDOW));
    if (!wParam) SetFocus32(hwnd);
  }
  return 0;
}


/***********************************************************************
 *             CBCheckSize
 */
static BOOL CBCheckSize(HWND hwnd)
{
  LPHEADCOMBO  lphc = ComboGetStorageHeader(hwnd);
  LPHEADLIST   lphl = ComboGetListHeader(hwnd);
  LONG         cstyle = GetWindowLong32A(hwnd,GWL_STYLE);
  RECT16       cRect, wRect;

  if (lphc->hWndLBox == 0) return FALSE;

  GetClientRect16(hwnd,&cRect);
  GetWindowRect16(hwnd,&wRect);

  dprintf_combo(stddeb,
	 "CBCheckSize: hwnd %04x Rect %d,%d-%d,%d  wRect %d,%d-%d,%d\n", 
		hwnd,cRect.left,cRect.top,cRect.right,cRect.bottom,
		wRect.left,wRect.top,wRect.right,wRect.bottom);
  if ((cstyle & 3) == CBS_SIMPLE) return TRUE;

  if ((cRect.bottom - cRect.top) >
      (lphl->StdItemHeight + 2*SYSMETRICS_CYBORDER)) {
    SetWindowPos32(hwnd, 0, 0, 0, 
		 cRect.right-cRect.left,
		 lphl->StdItemHeight+2*SYSMETRICS_CYBORDER, 
		 SWP_NOMOVE | SWP_NOZORDER | SWP_NOREDRAW | SWP_NOACTIVATE );
    GetClientRect16(hwnd,&cRect);
    GetWindowRect16(hwnd,&wRect);

    lphc->RectButton.right = cRect.right;
    lphc->RectButton.left = cRect.right - 2*SYSMETRICS_CXBORDER - 4 
                            - CBitWidth;
    lphc->RectButton.top = cRect.top;
    lphc->RectButton.bottom = cRect.bottom;
  }

  if (cRect.right < lphc->RectButton.left) {
    /* if the button is outside the window move it in */
    if ((wRect.right - wRect.left - 2*SYSMETRICS_CXBORDER) == (cRect.right - cRect.left)) {
      lphc->RectButton.right = cRect.right;
      lphc->RectButton.left = cRect.right - 2*SYSMETRICS_CXBORDER - 4 
	                       - CBitWidth;
      lphc->RectButton.top = cRect.top;
      lphc->RectButton.bottom = cRect.bottom;
    }
    /* otherwise we need to make the client include the button */
    else
      SetWindowPos32(hwnd, 0, 0, 0, lphc->RectButton.right,
		   lphl->StdItemHeight+2*SYSMETRICS_CYBORDER,
		   SWP_NOMOVE | SWP_NOZORDER | SWP_NOREDRAW | SWP_NOACTIVATE);

      if ((lphc->dwStyle & 3) != CBS_DROPDOWNLIST)
        SetWindowPos32(lphc->hWndEdit, 0, 0, 0, lphc->RectButton.left,
		     lphl->StdItemHeight,
		     SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER );
  }

  CBLCheckSize(hwnd);
  return TRUE;
}

/***********************************************************************
 *           CBCommand        
 */
static LRESULT CBCommand(HWND hwnd, WPARAM16 wParam, LPARAM lParam)
{
  LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd);
  LPHEADLIST lphl = ComboGetListHeader(hwnd);
  char       buffer[256];
  WORD       newFocused;
  WORD       id;
  if (lphc->hWndEdit)  /* interdependence only used for CBS_SIMPLE and CBS_DROPDOWN styles */
  {
   switch (wParam)
   {
    case ID_CLB:                                        /* update EDIT window */
                if (HIWORD(lParam)==CBN_SELCHANGE)
                 if (lphl->HasStrings)
                 { 
                  ListBoxGetText(lphl,lphl->ItemFocused, buffer);
                  dprintf_combo(stddeb,"CBCommand: update Edit: %s\n",buffer);
                  SetWindowText32A( lphc->hWndEdit, buffer );
                 }
                break;
    case ID_EDIT:                                      /* update LISTBOX window */
                 id=GetWindowWord(hwnd,GWW_ID);
                 switch (HIWORD(lParam))
                 {
                  case EN_UPDATE:GetWindowText32A(lphc->hWndEdit,buffer,255);
                                 if (*buffer)
                                 {
                                  char *str = SEGPTR_STRDUP(buffer);
                                  newFocused=ListBoxFindString(lphl, -1, SEGPTR_GET(str));
                                  SEGPTR_FREE(str);
                                  dprintf_combo(stddeb,"CBCommand: new selection #%d is= %s\n",
                                                newFocused,buffer);
                                  if (newFocused != (WORD)LB_ERR)
                                  {                             /* if found something */
                                   ListBoxSetCurSel(lphl, newFocused);
                                   ListBoxSendNotification(lphl, CBN_SELCHANGE);
                                   InvalidateRect32(hwnd, NULL, TRUE); 
                                  }
                                 }
                                 SendMessage16(GetParent16(hwnd),WM_COMMAND,id,
                                         MAKELONG(hwnd, CBN_EDITUPDATE));
                                 break;
                  case EN_CHANGE:SendMessage16(GetParent16(hwnd),WM_COMMAND,id,
                                         MAKELONG(hwnd, CBN_EDITCHANGE));
                                 break;
                  case EN_ERRSPACE:SendMessage16(GetParent16(hwnd),WM_COMMAND,id,
                                         MAKELONG(hwnd, CBN_ERRSPACE));
                                 break;
                }
                break;        
   }
  } 
  return 0;
}


/***********************************************************************
 *           CBGetEditSel
 * Look out! Under Win32, the parameter packing is very different.
 */
static LRESULT CBGetEditSel(HWND hwnd, WPARAM16 wParam, LPARAM lParam)
{
    LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd);

    if ((lphc->dwStyle & 3) == CBS_DROPDOWNLIST)
      return CB_ERR;	/* err, documented for CBSetEditSel */
    return SendMessage16(lphc->hWndEdit, EM_GETSEL16, 0, 0);
}


/***********************************************************************
 *           CBSetEditSel
 * Look out! Under Win32, the parameter packing is very different.
 */
static LRESULT CBSetEditSel(HWND hwnd, WPARAM16 wParam, LPARAM lParam)
{
    LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd);

    if ((lphc->dwStyle & 3) == CBS_DROPDOWNLIST)
      return CB_ERR;
    return SendMessage16(lphc->hWndEdit, EM_SETSEL16, 0, lParam);
}

/***********************************************************************
 *           CBGetText
 */
static LRESULT CBGetText(HWND hwnd, WPARAM16 wParam, LPARAM lParam)
{
    LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd);

    return SendMessage16(lphc->hWndEdit, WM_GETTEXT, wParam, lParam);   
}

/***********************************************************************
 *           ComboWndProc
 */
LRESULT ComboBoxWndProc(HWND hwnd, UINT message, WPARAM16 wParam, LPARAM lParam)
{
    switch(message) {	
     case WM_NCCREATE: return CBNCCreate(hwnd, wParam, lParam);
     case WM_CREATE: return CBCreate(hwnd, wParam, lParam);
     case WM_DESTROY: return CBDestroy(hwnd, wParam, lParam);
     case WM_GETDLGCODE: return CBGetDlgCode(hwnd, wParam, lParam);
     case WM_KEYDOWN: return CBKeyDown(hwnd, wParam, lParam);
     case WM_CHAR: return CBChar(hwnd, wParam, lParam);
     case WM_SETFONT: return CBSetFont(hwnd, wParam, lParam);
     case WM_SETREDRAW: return CBSetRedraw(hwnd, wParam, lParam);
     case WM_PAINT: return CBPaint(hwnd, wParam, lParam);
     case WM_GETTEXT: return CBGetText( hwnd, wParam, lParam);
     case WM_LBUTTONDOWN: return CBLButtonDown(hwnd, wParam, lParam);
     case WM_SETFOCUS: return CBSetFocus(hwnd, wParam, lParam);
     case WM_KILLFOCUS: return CBKillFocus(hwnd, wParam, lParam);
     case WM_SIZE: return CBCheckSize(hwnd);
     case WM_COMMAND: return CBCommand(hwnd, wParam, lParam);
     case CB_RESETCONTENT16: return CBResetContent(hwnd, wParam, lParam);
     case CB_DIR16: return CBDir(hwnd, wParam, lParam);
     case CB_ADDSTRING16: return CBAddString(hwnd, wParam, lParam);
     case CB_INSERTSTRING16: return CBInsertString(hwnd, wParam, lParam);
     case CB_DELETESTRING16: return CBDeleteString(hwnd, wParam, lParam);
     case CB_FINDSTRING16: return CBFindString(hwnd, wParam, lParam);
     case CB_GETCOUNT16: return CBGetCount(hwnd, wParam, lParam);
     case CB_GETCURSEL16: return CBGetCurSel(hwnd, wParam, lParam);
     case CB_GETITEMDATA16: return CBGetItemData(hwnd, wParam, lParam);
     case CB_GETITEMHEIGHT16: return CBGetItemHeight(hwnd, wParam, lParam);
     case CB_GETLBTEXT16: return CBGetLBText(hwnd, wParam, lParam);
     case CB_GETLBTEXTLEN16: return CBGetLBTextLen(hwnd, wParam, lParam);
     case CB_SELECTSTRING16: return CBSelectString(hwnd, wParam, lParam);
     case CB_SETITEMDATA16: return CBSetItemData(hwnd, wParam, lParam);
     case CB_SETCURSEL16: return CBSetCurSel(hwnd, wParam, lParam);
     case CB_SETITEMHEIGHT16: return CBSetItemHeight(hwnd, wParam, lParam);
     case CB_SHOWDROPDOWN16: return CBShowDropDown(hwnd, wParam, lParam);
     case CB_GETEDITSEL16: return CBGetEditSel(hwnd, wParam, lParam);
     case CB_SETEDITSEL16: return CBSetEditSel(hwnd, wParam, lParam);
     case CB_FINDSTRINGEXACT16: return CBFindStringExact(hwnd, wParam, lParam);
    }
    return DefWindowProc16(hwnd, message, wParam, lParam);
}

/*--------------------------------------------------------------------*/
/* ComboLBox code starts here */

HWND CLBoxGetCombo(HWND hwnd)
{
  return (HWND)GetWindowLong32A(hwnd,0);
}

LPHEADLIST CLBoxGetListHeader(HWND hwnd)
{
  return ComboGetListHeader(CLBoxGetCombo(hwnd));
}

/***********************************************************************
 *           CBLCreate
 */
static LRESULT CBLCreate( HWND hwnd, WPARAM16 wParam, LPARAM lParam )
{
  CREATESTRUCT16 *createStruct = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam);
  SetWindowLong32A(hwnd,0,(LONG)createStruct->lpCreateParams);
  return 0;
}

/***********************************************************************
 *           CBLGetDlgCode
 */
static LRESULT CBLGetDlgCode( HWND hwnd, WPARAM16 wParam, LPARAM lParam )
{
  return DLGC_WANTARROWS | DLGC_WANTCHARS;
}

/***********************************************************************
 *           CBLKeyDown
 */
static LRESULT CBLKeyDown( HWND hwnd, WPARAM16 wParam, LPARAM lParam ) 
{
  LPHEADLIST lphl = CLBoxGetListHeader(hwnd);
  WORD newFocused = lphl->ItemFocused;

  switch(wParam) {
  case VK_HOME:
    newFocused = 0;
    break;
  case VK_END:
    newFocused = lphl->ItemsCount - 1;
    break;
  case VK_UP:
    if (newFocused > 0) newFocused--;
    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;
  }

  if (newFocused >= lphl->ItemsCount)
    newFocused = lphl->ItemsCount - 1;
  
  ListBoxSetCurSel(lphl, newFocused);
  ListBoxSendNotification(lphl, CBN_SELCHANGE);
  SendMessage16(GetParent16(hwnd), WM_COMMAND,ID_CLB,MAKELONG(0,CBN_SELCHANGE));
  lphl->ItemFocused = newFocused;
  ListBoxScrollToFocus(lphl);
  SetScrollPos32(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
  InvalidateRect32( hwnd, NULL, TRUE );
  return 0;
}

/***********************************************************************
 *           CBLChar
 */
static LRESULT CBLChar( HWND hwnd, WPARAM16 wParam, LPARAM lParam )
{
  return 0;
}

/***********************************************************************
 *           CBLPaint
 */
static LRESULT CBLPaint( HWND hwnd, WPARAM16 wParam, LPARAM lParam )
{
  LPHEADLIST   lphl = CLBoxGetListHeader(hwnd);
  LPLISTSTRUCT lpls;
  PAINTSTRUCT16  ps;
  HBRUSH32 hBrush;
  HFONT32 hOldFont;
  WND * wndPtr = WIN_FindWndPtr(hwnd);
  HWND  combohwnd = CLBoxGetCombo(hwnd);
  HDC16 hdc;
  RECT16 rect;
  int   i, top, height;

  top = 0;
  hdc = BeginPaint16( hwnd, &ps );

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

  hOldFont = SelectObject32(hdc, lphl->hFont);
  /* listboxes should be white */
  hBrush = GetStockObject32(WHITE_BRUSH);

  GetClientRect16(hwnd, &rect);
  FillRect16(hdc, &rect, hBrush);
  CBLCheckSize(hwnd);

  lpls = lphl->lpFirst;

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

    if (i >= lphl->FirstVisible) {
      height = lpls->mis.itemHeight;
      /* must have enough room to draw entire item */
      if (top > (rect.bottom-height+1)) break;

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

      dprintf_listbox(stddeb,"drawing item: %d %d %d %d %d\n",
                      rect.left,top,rect.right,top+height,lpls->itemState);
      if (lphl->OwnerDrawn) {
	ListBoxDrawItem (combohwnd, lphl, hdc, lpls, &lpls->itemRect, ODA_DRAWENTIRE, 0);
	if (lpls->itemState)
	  ListBoxDrawItem (combohwnd, lphl, hdc, lpls, &lpls->itemRect, ODA_SELECT, ODS_SELECTED);
      } else {
	ListBoxDrawItem (combohwnd, lphl, hdc, lpls, &lpls->itemRect, ODA_DRAWENTIRE, 
			 lpls->itemState);
      }
      if ((lphl->ItemFocused == i) && GetFocus32() == hwnd)
	ListBoxDrawItem (combohwnd, lphl, hdc, lpls, &lpls->itemRect, ODA_FOCUS, ODS_FOCUS);

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

    lpls = lpls->lpNext;
  }

  if (wndPtr->dwStyle & WS_VSCROLL) 
      SetScrollRange32(hwnd, SB_VERT, 0, ListMaxFirstVisible(lphl), TRUE);

  SelectObject32(hdc,hOldFont);
  EndPaint16( hwnd, &ps );
  return 0;

}

/***********************************************************************
 *           CBLKillFocus
 */
static LRESULT CBLKillFocus( HWND hwnd, WPARAM16 wParam, LPARAM lParam )
{
/*  SendMessage16(CLBoxGetCombo(hwnd),CB_SHOWDROPDOWN16,0,0);*/
  return 0;
}

/***********************************************************************
 *           CBLActivate
 */
static LRESULT CBLActivate( HWND hwnd, WPARAM16 wParam, LPARAM lParam )
{
  if (wParam == WA_INACTIVE)
    SendMessage16(CLBoxGetCombo(hwnd),CB_SHOWDROPDOWN16,0,0);
  return 0;
}

/***********************************************************************
 *           CBLLButtonDown
 */
static LRESULT CBLLButtonDown( HWND hwnd, WPARAM16 wParam, LPARAM lParam )
{
  LPHEADLIST lphl = CLBoxGetListHeader(hwnd);
  int        y;
  RECT16     rectsel;

/*  SetFocus32(hwnd); */
  SetCapture32(hwnd);

  lphl->PrevFocused = lphl->ItemFocused;

  y = ListBoxFindMouse(lphl, LOWORD(lParam), HIWORD(lParam));
  if (y == -1)
    return 0;

  ListBoxSetCurSel(lphl, y);
  ListBoxGetItemRect(lphl, y, &rectsel);

  InvalidateRect32( hwnd, NULL, TRUE );
  return 0;
}

/***********************************************************************
 *           CBLLButtonUp
 */
static LRESULT CBLLButtonUp( HWND hwnd, WPARAM16 wParam, LPARAM lParam )
{
  LPHEADLIST lphl = CLBoxGetListHeader(hwnd);

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

  if(!lphl)
     {
      fprintf(stdnimp,"CBLLButtonUp: CLBoxGetListHeader returned NULL!\n");
     }
  else if (lphl->PrevFocused != lphl->ItemFocused) 
          {
      		SendMessage16(CLBoxGetCombo(hwnd),CB_SETCURSEL16,lphl->ItemFocused,0);
      		SendMessage16(GetParent16(hwnd), WM_COMMAND,ID_CLB,MAKELONG(0,CBN_SELCHANGE));
      		ListBoxSendNotification(lphl, CBN_SELCHANGE);
     	  }

  SendMessage16(CLBoxGetCombo(hwnd),CB_SHOWDROPDOWN16,0,0);

  return 0;
}

/***********************************************************************
 *           CBLMouseMove
 */
static LRESULT CBLMouseMove( HWND hwnd, WPARAM16 wParam, LPARAM lParam )
{
  LPHEADLIST lphl = CLBoxGetListHeader(hwnd);
  short y;
  WORD wRet;
  RECT16 rect, rectsel;

  y = SHIWORD(lParam);
  wRet = ListBoxFindMouse(lphl, LOWORD(lParam), HIWORD(lParam));
  ListBoxGetItemRect(lphl, wRet, &rectsel);
  GetClientRect16(hwnd, &rect);

  dprintf_combo(stddeb,"CBLMouseMove: hwnd %04x wp %x lp %lx  y %d  if %d wret %d %d,%d-%d,%d\n",
hwnd,wParam,lParam,y,lphl->ItemFocused,wRet,rectsel.left,rectsel.top,rectsel.right,rectsel.bottom);
  
  if ((wParam & MK_LBUTTON) != 0) {
    if (y < CBLMM_EDGE) {
      if (lphl->FirstVisible > 0) {
	lphl->FirstVisible--;
	SetScrollPos32(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
	ListBoxSetCurSel(lphl, wRet);
	InvalidateRect32( hwnd, NULL, TRUE );
	return 0;
      }
    }
    else if (y >= (rect.bottom-CBLMM_EDGE)) {
      if (lphl->FirstVisible < ListMaxFirstVisible(lphl)) {
	lphl->FirstVisible++;
	SetScrollPos32(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
	ListBoxSetCurSel(lphl, wRet);
	InvalidateRect32( hwnd, NULL, TRUE );
	return 0;
      }
    }
    else {
      if ((short) wRet == lphl->ItemFocused) return 0;
      ListBoxSetCurSel(lphl, wRet);
      InvalidateRect32( hwnd, NULL, TRUE );
    }
  }

  return 0;
}

/***********************************************************************
 *           CBLVScroll
 */
static LRESULT CBLVScroll( HWND hwnd, WPARAM16 wParam, LPARAM lParam )
{
  LPHEADLIST lphl = CLBoxGetListHeader(hwnd);
  int  y;

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


/***********************************************************************
 *             CBLCheckSize
 */
static BOOL CBLCheckSize(HWND hwnd)
{
  LPHEADCOMBO  lphc = ComboGetStorageHeader(hwnd);
  LPHEADLIST   lphl = ComboGetListHeader(hwnd);
  LPLISTSTRUCT lpls;
  HWND         hWndLBox;
  RECT16 cRect,wRect,lRect,lwRect;
  int totheight,dw;
  char className[80];

  GetClassName32A(hwnd,className,80);
  fflush(stddeb);
  if (strncmp(className,"COMBOBOX",8)) return FALSE;
  if ((hWndLBox = lphc->hWndLBox) == 0) return FALSE;
  dprintf_combo(stddeb,"CBLCheckSize headers hw %04x  lb %04x  name %s\n",
		hwnd,hWndLBox,className);

  GetClientRect16(hwnd,&cRect);
  GetWindowRect16(hwnd,&wRect);
  GetClientRect16(hWndLBox,&lRect);
  GetWindowRect16(hWndLBox,&lwRect);

  dprintf_combo(stddeb,"CBLCheckSize: init cRect %d,%d-%d,%d  wRect %d,%d-%d,%d\n",
		cRect.left,cRect.top,cRect.right,cRect.bottom,
		wRect.left,wRect.top,wRect.right,wRect.bottom);
  dprintf_combo(stddeb,"                   lRect %d,%d-%d,%d  lwRect %d,%d-%d,%d\n",
	      lRect.left,lRect.top,lRect.right,lRect.bottom,
	      lwRect.left,lwRect.top,lwRect.right,lwRect.bottom);
  fflush(stddeb);
  
  totheight = 0;
  for (lpls=lphl->lpFirst; lpls != NULL; lpls=lpls->lpNext)
    totheight += lpls->mis.itemHeight;

  dw = cRect.right-cRect.left+2*SYSMETRICS_CXBORDER+SYSMETRICS_CXVSCROLL;
  dw -= lwRect.right-lwRect.left;
  dw -= SYSMETRICS_CXVSCROLL;

  /* TODO: This isn't really what windows does */
  if ((lRect.bottom-lRect.top < 3*lphl->StdItemHeight) || dw) {
    dprintf_combo(stddeb,"    Changing; totHeight %d  StdItemHght %d  dw %d\n",
		  totheight,lphl->StdItemHeight,dw);
    SetWindowPos32(hWndLBox, 0, lRect.left, lRect.top, 
		 lwRect.right-lwRect.left+dw, totheight+2*SYSMETRICS_CYBORDER, 
		 SWP_NOMOVE | SWP_NOZORDER | SWP_NOREDRAW | SWP_NOACTIVATE );
  }
  return TRUE;
}


/***********************************************************************
 *           ComboLBoxWndProc
 */
LRESULT ComboLBoxWndProc(HWND hwnd, UINT message, WPARAM16 wParam, LPARAM lParam)
{
    switch(message) {	
     case WM_CREATE: return CBLCreate(hwnd, wParam, lParam);
     case WM_GETDLGCODE: return CBLGetDlgCode(hwnd, wParam, lParam);
     case WM_KEYDOWN: return CBLKeyDown(hwnd, wParam, lParam);
     case WM_CHAR: return CBLChar(hwnd, wParam, lParam);
     case WM_PAINT: return CBLPaint(hwnd, wParam, lParam);
     case WM_KILLFOCUS: return CBLKillFocus(hwnd, wParam, lParam);
     case WM_ACTIVATE: return CBLActivate(hwnd, wParam, lParam);
     case WM_LBUTTONDOWN: return CBLLButtonDown(hwnd, wParam, lParam);
     case WM_LBUTTONUP: return CBLLButtonUp(hwnd, wParam, lParam);
     case WM_MOUSEMOVE: return CBLMouseMove(hwnd, wParam, lParam);
     case WM_VSCROLL: return CBLVScroll(hwnd, wParam, lParam);
     case WM_SIZE: return CBLCheckSize(hwnd);
     case WM_MOUSEACTIVATE:  /* We don't want to be activated */
	return MA_NOACTIVATE;
    }
    return DefWindowProc16(hwnd, message, wParam, lParam);
}
