/*
 * Combo controls
 * 
 * Copyright 1997 Alex Korobka
 * 
 * FIXME: roll up in Netscape 3.01.
 */

#include <stdio.h>
#include <string.h>

#include "windows.h"
#include "sysmetrics.h"
#include "syscolor.h"
#include "win.h"
#include "spy.h"
#include "user.h"
#include "graphics.h"
#include "heap.h"
#include "combo.h"
#include "drive.h"
#include "stddebug.h"
#include "debug.h"

  /* bits in the dwKeyData */
#define KEYDATA_ALT             0x2000
#define KEYDATA_PREVSTATE       0x4000

/*
 * Additional combo box definitions
 */

#define CB_GETPTR( wnd )      (*(LPHEADCOMBO*)((wnd)->wExtra))
#define CB_NOTIFY( lphc, code ) \
	(SendMessage32A( (lphc)->owner, WM_COMMAND, \
			 MAKEWPARAM((lphc)->self->wIDmenu, (code)), (lphc)->self->hwndSelf))
#define CB_GETEDITTEXTLENGTH( lphc ) \
	(SendMessage32A( (lphc)->hWndEdit, WM_GETTEXTLENGTH, 0, 0 ))

static HBITMAP16 	hComboBmp = 0;
static UINT16		CBitHeight, CBitWidth;
static UINT16		CBitOffset = 8;

/***********************************************************************
 *           COMBO_Init
 *
 * Load combo button bitmap.
 */
static BOOL32 COMBO_Init()
{
  HDC16		hDC;
  
  if( hComboBmp ) return TRUE;
  if( (hDC = CreateCompatibleDC16(0)) )
  {
    BOOL32	bRet = FALSE;
    if( (hComboBmp = LoadBitmap16(0, MAKEINTRESOURCE(OBM_COMBO))) )
    {
      BITMAP16      bm;
      HBITMAP16     hPrevB;
      RECT16        r;

      GetObject16( hComboBmp, sizeof(bm), &bm );
      CBitHeight = bm.bmHeight;
      CBitWidth  = bm.bmWidth;

      dprintf_combo(stddeb, "combo bitmap [%i,%i]\n", CBitWidth, CBitHeight );

      hPrevB = SelectObject16( hDC, hComboBmp);
      SetRect16( &r, 0, 0, CBitWidth, CBitHeight );
      InvertRect16( hDC, &r );
      SelectObject16( hDC, hPrevB );
      bRet = TRUE;
    }
    DeleteDC16( hDC );
    return bRet;
  }
  return FALSE;
}

/***********************************************************************
 *           COMBO_NCCreate
 */
static LRESULT COMBO_NCCreate(WND* wnd, LPARAM lParam)
{
   LPHEADCOMBO 		lphc;

   if ( wnd && COMBO_Init() &&
      (lphc = HeapAlloc(GetProcessHeap(), 0, sizeof(HEADCOMBO))) )
   {
	LPCREATESTRUCT32A     lpcs = (CREATESTRUCT32A*)lParam;
       
	memset( lphc, 0, sizeof(HEADCOMBO) );
       *(LPHEADCOMBO*)wnd->wExtra = lphc;

       /* some braindead apps do try to use scrollbar/border flags */

	lphc->dwStyle = (lpcs->style & ~(WS_BORDER | WS_HSCROLL | WS_VSCROLL));
	wnd->dwStyle &= ~(WS_BORDER | WS_HSCROLL | WS_VSCROLL);

	if( !(lpcs->style & (CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE)) )
              lphc->dwStyle |= CBS_HASSTRINGS;
	if( !(wnd->dwExStyle & WS_EX_NOPARENTNOTIFY) )
	      lphc->wState |= CBF_NOTIFY;

	dprintf_combo(stddeb, "COMBO_NCCreate: [0x%08x], style = %08x\n", 
						(UINT32)lphc, lphc->dwStyle );

	return (LRESULT)(UINT32)wnd->hwndSelf; 
    }
    return (LRESULT)FALSE;
}

/***********************************************************************
 *           COMBO_NCDestroy
 */
static LRESULT COMBO_NCDestroy( LPHEADCOMBO lphc )
{

   if( lphc )
   {
       WND*		wnd = lphc->self;

       dprintf_combo(stddeb,"Combo [%04x]: freeing storage\n", CB_HWND(lphc));

       if( (CB_GETTYPE(lphc) != CBS_SIMPLE) && lphc->hWndLBox ) 
   	   DestroyWindow32( lphc->hWndLBox );

       HeapFree( GetProcessHeap(), 0, lphc );
       wnd->wExtra[0] = 0;
   }
   return 0;
}

/***********************************************************************
 *           CBCalcPlacement
 *
 * Set up component coordinates given valid lphc->RectCombo.
 */
static void CBCalcPlacement( LPHEADCOMBO lphc, 
			     LPRECT16 lprEdit, LPRECT16 lprButton, LPRECT16 lprLB )
{
   RECT16	rect = lphc->RectCombo;
   SIZE16	size;

   /* get combo height and width */

   if( lphc->editHeight )
       size.cy = (INT16)lphc->editHeight;
   else
   {
       HDC16	hDC = GetDC16( lphc->self->hwndSelf );
       HFONT16	hPrevFont = (HFONT16)0;

       if( lphc->hFont ) hPrevFont = SelectObject16( hDC, lphc->hFont );
   
       GetTextExtentPoint16( hDC, "0", 1, &size);

       size.cy += size.cy / 4 + 4 * SYSMETRICS_CYBORDER;

       if( hPrevFont ) SelectObject16( hDC, hPrevFont );
       ReleaseDC16( lphc->self->hwndSelf, hDC );
   }
   size.cx = rect.right - rect.left;

   if( CB_OWNERDRAWN(lphc) )
   {
       UINT16	u = lphc->RectEdit.bottom - lphc->RectEdit.top;

       if( lphc->wState & CBF_MEASUREITEM ) /* first initialization */
       {
	 MEASUREITEMSTRUCT32        mi32;

	 lphc->wState &= ~CBF_MEASUREITEM;
	 mi32.CtlType = ODT_COMBOBOX;
	 mi32.CtlID   = lphc->self->wIDmenu;
	 mi32.itemID  = -1;
	 mi32.itemWidth  = size.cx;
	 mi32.itemHeight = size.cy - 6;	/* ownerdrawn cb is taller */
	 mi32.itemData   = 0;
	 SendMessage32A(lphc->owner, WM_MEASUREITEM, 
				(WPARAM32)mi32.CtlID, (LPARAM)&mi32);
	 u = 6 + (UINT16)mi32.itemHeight;
       }
       size.cy = u;
   }

   /* calculate text and button placement */

   lprEdit->left = lprEdit->top = lprButton->top = 0;
   if( CB_GETTYPE(lphc) == CBS_SIMPLE ) 	/* no button */
       lprButton->left = lprButton->right = lprButton->bottom = 0;
   else
   {
       INT32	i = size.cx - CBitWidth - 10;	/* seems ok */

       lprButton->right = size.cx;
       lprButton->left = (INT16)i;
       lprButton->bottom = lprButton->top + size.cy;

       if( i < 0 ) size.cx = 0;
       else size.cx = (INT16)i;
   }

   if( CB_GETTYPE(lphc) == CBS_DROPDOWN )
   {
       size.cx -= CBitOffset;
       if( size.cx < 0 ) size.cx = 0;
   }

   lprEdit->right = size.cx; lprEdit->bottom = size.cy;

   /* listbox placement */

   lprLB->left = ( CB_GETTYPE(lphc) == CBS_DROPDOWNLIST ) ? 0 : CBitOffset;
   lprLB->top = lprEdit->bottom - SYSMETRICS_CYBORDER;
   lprLB->right = rect.right - rect.left;
   lprLB->bottom = rect.bottom - rect.top;

   if( lphc->droppedWidth > (lprLB->right - lprLB->left) )
       lprLB->right = lprLB->left + (INT16)lphc->droppedWidth;

dprintf_combo(stddeb,"Combo [%04x]: (%i,%i-%i,%i) placement\n\ttext\t= (%i,%i-%i,%i)\
\n\tbutton\t= (%i,%i-%i,%i)\n\tlbox\t= (%i,%i-%i,%i)\n", CB_HWND(lphc),
lphc->RectCombo.left, lphc->RectCombo.top, lphc->RectCombo.right, lphc->RectCombo.bottom,
lprEdit->left, lprEdit->top, lprEdit->right, lprEdit->bottom,
lprButton->left, lprButton->top, lprButton->right, lprButton->bottom, 
lprLB->left, lprLB->top, lprLB->right, lprLB->bottom );

}

/***********************************************************************
 *           CBGetDroppedControlRect32
 */
static void CBGetDroppedControlRect32( LPHEADCOMBO lphc, LPRECT32 lpRect)
{
   lpRect->left = lphc->RectCombo.left +
                      (lphc->wState & CBF_EDIT) ? CBitOffset : 0;
   lpRect->top = lphc->RectCombo.top + lphc->RectEdit.bottom -
                                             SYSMETRICS_CYBORDER;
   lpRect->right = lphc->RectCombo.right;
   lpRect->bottom = lphc->RectCombo.bottom - SYSMETRICS_CYBORDER;
}

/***********************************************************************
 *           COMBO_Create
 */
static LRESULT COMBO_Create( LPHEADCOMBO lphc, WND* wnd, LPARAM lParam)
{
  static char clbName[] = "ComboLBox";
  static char editName[] = "Edit";

  LPCREATESTRUCT32A  lpcs = (CREATESTRUCT32A*)lParam;
  
  if( !CB_GETTYPE(lphc) ) lphc->dwStyle |= CBS_SIMPLE;
  else if( CB_GETTYPE(lphc) != CBS_DROPDOWNLIST ) lphc->wState |= CBF_EDIT;

  lphc->self  = wnd;
  lphc->owner = lpcs->hwndParent;

  /* M$ IE 3.01 actually creates (and rapidly destroys) an ownerless combobox */

  if( lphc->owner || !(lpcs->style & WS_VISIBLE) )
  {
      UINT32	lbeStyle;
      RECT16	editRect, btnRect, lbRect;

      GetWindowRect16( wnd->hwndSelf, &lphc->RectCombo );

      lphc->wState |= CBF_MEASUREITEM;
      CBCalcPlacement( lphc, &editRect, &btnRect, &lbRect );
      lphc->RectButton = btnRect;
      lphc->droppedWidth = lphc->editHeight = 0;

      /* create listbox popup */

      lbeStyle = (LBS_NOTIFY | WS_BORDER | WS_CLIPSIBLINGS) | 
                 (lpcs->style & (WS_VSCROLL | CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE));

      if( lphc->dwStyle & CBS_SORT )
	lbeStyle |= LBS_SORT;
      if( lphc->dwStyle & CBS_HASSTRINGS )
	lbeStyle |= LBS_HASSTRINGS;
      if( lphc->dwStyle & CBS_NOINTEGRALHEIGHT )
	lbeStyle |= LBS_NOINTEGRALHEIGHT;
      if( lphc->dwStyle & CBS_DISABLENOSCROLL )
	lbeStyle |= LBS_DISABLENOSCROLL;
  
      if( CB_GETTYPE(lphc) == CBS_SIMPLE ) 	/* child listbox */
	lbeStyle |= WS_CHILD | WS_VISIBLE;
      else					/* popup listbox */
      {
	lbeStyle |= WS_POPUP;
	OffsetRect16( &lbRect, lphc->RectCombo.left, lphc->RectCombo.top );
      }

     /* Dropdown ComboLBox is not a child window and we cannot pass 
      * ID_CB_LISTBOX directly because it will be treated as a menu handle.
      */

      lphc->hWndLBox = CreateWindowEx32A( 0, clbName, NULL, lbeStyle, 
		        lbRect.left + SYSMETRICS_CXBORDER, 
		        lbRect.top + SYSMETRICS_CYBORDER, 
			lbRect.right - lbRect.left - 2 * SYSMETRICS_CXBORDER, 
			lbRect.bottom - lbRect.top - 2 * SYSMETRICS_CYBORDER, 
			lphc->self->hwndSelf, 
		       (lphc->dwStyle & CBS_DROPDOWN)? (HMENU32)0 : (HMENU32)ID_CB_LISTBOX,
			lphc->self->hInstance, (LPVOID)lphc );
      if( lphc->hWndLBox )
      {
	  BOOL32	bEdit = TRUE;
	  lbeStyle = WS_CHILD | WS_VISIBLE | WS_BORDER | ES_NOHIDESEL | ES_LEFT;
	  if( lphc->wState & CBF_EDIT ) 
	  {
	      if( lphc->dwStyle & CBS_OEMCONVERT )
		  lbeStyle |= ES_OEMCONVERT;
	      if( lphc->dwStyle & CBS_AUTOHSCROLL )
		  lbeStyle |= ES_AUTOHSCROLL;
	      if( lphc->dwStyle & CBS_LOWERCASE )
		  lbeStyle |= ES_LOWERCASE;
	      else if( lphc->dwStyle & CBS_UPPERCASE )
		  lbeStyle |= ES_UPPERCASE;
	      lphc->hWndEdit = CreateWindowEx32A( 0, editName, NULL, lbeStyle,
		  	editRect.left, editRect.top, editRect.right - editRect.left,
			editRect.bottom - editRect.top, lphc->self->hwndSelf, 
			(HMENU32)ID_CB_EDIT, lphc->self->hInstance, NULL );
	      if( !lphc->hWndEdit ) bEdit = FALSE;
	  } 

          if( bEdit )
	  {
	      lphc->RectEdit = editRect;
	      if( CB_GETTYPE(lphc) != CBS_SIMPLE )
	      {
		lphc->wState |= CBF_NORESIZE;
		SetWindowPos32( wnd->hwndSelf, 0, 0, 0, 
				lphc->RectCombo.right - lphc->RectCombo.left,
				lphc->RectEdit.bottom - lphc->RectEdit.top,
				SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE );
		lphc->wState &= ~CBF_NORESIZE;
	      }
	      dprintf_combo(stddeb,"COMBO_Create: init done\n");
	      return wnd->hwndSelf;
	  }
	  dprintf_combo(stderr, "COMBO_Create: edit control failure.\n");
      } else dprintf_combo(stderr, "COMBO_Create: listbox failure.\n");
  } else dprintf_combo(stderr, "COMBO_Create: no owner for visible combo.\n");

  /* CreateWindow() will send WM_NCDESTROY to cleanup */

  return -1;
}

/***********************************************************************
 *           CBPaintButton
 *
 * Paint combo button (normal, pressed, and disabled states).
 */
static void CBPaintButton(LPHEADCOMBO lphc, HDC16 hdc)
{
    RECT32 	r;
    HBRUSH32 	hPrevBrush;
    UINT32 	x, y;
    BOOL32 	bBool;

    hPrevBrush = (HBRUSH32)SelectObject32(hdc, sysColorObjects.hbrushBtnFace);
    CONV_RECT16TO32( &lphc->RectButton, &r );

    Rectangle32(hdc, r.left, r.top, r.right, r.bottom );
    InflateRect32( &r, -1, -1 );
    if( (bBool = lphc->wState & CBF_BUTTONDOWN) )
    {
	GRAPH_DrawReliefRect(hdc, &r, 1, 0, TRUE);
	OffsetRect32( &r, 1, 1 );
    } else GRAPH_DrawReliefRect(hdc, &r, 1, 2, FALSE);

    x = (r.left + r.right - CBitWidth) >> 1;
    y = (r.top + r.bottom - CBitHeight) >> 1;

    InflateRect32( &r, -3, -3 );
    if( (bBool = CB_DISABLED(lphc)) )
    {
        GRAPH_SelectClipMask(hdc, hComboBmp, x + 1, y + 1 );
        FillRect32(hdc, &r, (HBRUSH32)GetStockObject32(WHITE_BRUSH));
    }

    GRAPH_SelectClipMask(hdc, hComboBmp, x, y );
    FillRect32(hdc, &r, (HBRUSH32)GetStockObject32((bBool) ? GRAY_BRUSH : BLACK_BRUSH));

    GRAPH_SelectClipMask(hdc, (HBITMAP32)0, 0, 0);
    SelectObject32( hdc, hPrevBrush );
}

/***********************************************************************
 *           CBPaintText
 *
 * Paint CBS_DROPDOWNLIST text field / update edit control contents.
 */
static void CBPaintText(LPHEADCOMBO lphc, HDC16 hdc)
{
   INT32	id, size = 0;
   LPSTR	pText = NULL;

   /* follow Windows combobox that sends a bunch of text 
    * inquiries to its listbox while processing WM_PAINT. */

   if( (id = SendMessage32A(lphc->hWndLBox, LB_GETCURSEL32, 0, 0) ) != LB_ERR )
   {
        size = SendMessage32A( lphc->hWndLBox, LB_GETTEXTLEN32, id, 0);
        if( (pText = HeapAlloc( GetProcessHeap(), 0, size + 1)) )
	{
	    SendMessage32A( lphc->hWndLBox, LB_GETTEXT32, (WPARAM32)id, (LPARAM)pText );
	    pText[size] = '\0';	/* just in case */
	} else return;
   }

   if( lphc->wState & CBF_EDIT )
   {
	if( CB_HASSTRINGS(lphc) ) SetWindowText32A( lphc->hWndEdit, pText );
	if( lphc->wState & CBF_FOCUSED ) 
	    SendMessage32A( lphc->hWndEdit, EM_SETSEL32, 0, (LPARAM)(-1));
   }
   else /* paint text field ourselves */
   {
        HBRUSH32 hPrevBrush = 0;
	HDC32	 hDC = hdc;

	if( !hDC ) 
	{
	    if ((hDC = GetDC32(lphc->self->hwndSelf)))
            {
                HBRUSH32 hBrush = SendMessage32A( lphc->owner,
                                                  WM_CTLCOLORLISTBOX, 
                                                  hDC, lphc->self->hwndSelf );
                hPrevBrush = SelectObject32( hDC, 
                           (hBrush) ? hBrush : GetStockObject32(WHITE_BRUSH) );
            }
	}
	if( hDC )
	{
	    RECT32	rect;
	    UINT16	itemState;
	    HFONT32	hPrevFont = (lphc->hFont) ? SelectObject32(hDC, lphc->hFont) : 0;

	    PatBlt32( hDC, (rect.left = lphc->RectEdit.left + SYSMETRICS_CXBORDER),
			   (rect.top = lphc->RectEdit.top + SYSMETRICS_CYBORDER),
			   (rect.right = lphc->RectEdit.right - SYSMETRICS_CXBORDER),
			   (rect.bottom = lphc->RectEdit.bottom - SYSMETRICS_CYBORDER) - 1, PATCOPY );
	    InflateRect32( &rect, -1, -1 );

	    if( lphc->wState & CBF_FOCUSED && 
	        !(lphc->wState & CBF_DROPPED) )
	    {
		/* highlight */

		FillRect32( hDC, &rect, sysColorObjects.hbrushHighlight );
                SetBkColor32( hDC, GetSysColor32( COLOR_HIGHLIGHT ) );
                SetTextColor32( hDC, GetSysColor32( COLOR_HIGHLIGHTTEXT ) );
		itemState = ODS_SELECTED | ODS_FOCUS;
	    } else itemState = 0;

	    if( CB_OWNERDRAWN(lphc) )
	    {
		DRAWITEMSTRUCT32 dis;

		if( lphc->self->dwStyle & WS_DISABLED ) itemState |= ODS_DISABLED;

		dis.CtlType	= ODT_COMBOBOX;
		dis.CtlID	= lphc->self->wIDmenu;
		dis.hwndItem	= lphc->self->hwndSelf;
		dis.itemAction	= ODA_DRAWENTIRE;
		dis.itemID	= id;
		dis.itemState	= itemState;
		dis.hDC		= hDC;
		dis.rcItem	= rect;
		dis.itemData	= SendMessage32A( lphc->hWndLBox, LB_GETITEMDATA32, 
						  		  (WPARAM32)id, 0 );
		SendMessage32A( lphc->owner, WM_DRAWITEM, 
				lphc->self->wIDmenu, (LPARAM)&dis );
	    }
	    else
	    {
		ExtTextOut32A( hDC, rect.left + 1, rect.top + 1,
                               ETO_OPAQUE | ETO_CLIPPED, &rect,
                               (pText) ? pText : "" , size, NULL );
		if(lphc->wState & CBF_FOCUSED && !(lphc->wState & CBF_DROPPED))
		    DrawFocusRect32( hDC, &rect );
	    }

	    if( hPrevFont ) SelectObject32(hDC, hPrevFont );
	    if( !hdc ) 
	    {
		if( hPrevBrush ) SelectObject32( hDC, hPrevBrush );
		ReleaseDC32( lphc->self->hwndSelf, hDC );
	    }
	}
   }
   HeapFree( GetProcessHeap(), 0, pText );
}

/***********************************************************************
 *           COMBO_Paint
 */
static LRESULT COMBO_Paint(LPHEADCOMBO lphc, HDC16 hParamDC)
{
  PAINTSTRUCT16 ps;
  HDC16 	hDC;
  
  hDC = (hParamDC) ? hParamDC
		   : BeginPaint16( lphc->self->hwndSelf, &ps);
  if( hDC && !(lphc->self->flags & WIN_NO_REDRAW) )
  {
      HBRUSH32	hPrevBrush, hBkgBrush;

      hBkgBrush = SendMessage32A( lphc->owner, WM_CTLCOLORLISTBOX,
				  hDC, lphc->self->hwndSelf );
      if( !hBkgBrush ) hBkgBrush = GetStockObject32(WHITE_BRUSH);

      hPrevBrush = SelectObject32( hDC, hBkgBrush );
      if( !IsRectEmpty16(&lphc->RectButton) )
      {
	  /* paint everything to the right of the text field */

	  PatBlt32( hDC, lphc->RectEdit.right, lphc->RectEdit.top,
			 lphc->RectButton.right - lphc->RectEdit.right,
			 lphc->RectEdit.bottom - lphc->RectEdit.top, PATCOPY );
          CBPaintButton( lphc, hDC );
      }

      if( !(lphc->wState & CBF_EDIT) )
      {
	  /* paint text field */

	  GRAPH_DrawRectangle( hDC, lphc->RectEdit.left, lphc->RectEdit.top,
				    lphc->RectEdit.right - lphc->RectEdit.left, 
				    lphc->RectButton.bottom - lphc->RectButton.top,
				    sysColorObjects.hpenWindowFrame ); 
	  CBPaintText( lphc, hDC );
      }
      if( hPrevBrush ) SelectObject32( hDC, hPrevBrush );
  }
  if( !hParamDC ) EndPaint16(lphc->self->hwndSelf, &ps);
  return 0;
}

/***********************************************************************
 *           CBUpdateLBox
 *
 * Select listbox entry according to the contents of the edit control.
 */
static INT32 CBUpdateLBox( LPHEADCOMBO lphc )
{
   INT32	length, idx, ret;
   LPSTR	pText = NULL;
   
   idx = ret = LB_ERR;
   length = CB_GETEDITTEXTLENGTH( lphc );
 
   if( length > 0 ) 
       pText = (LPSTR) HeapAlloc( GetProcessHeap(), 0, length + 1);

   dprintf_combo(stddeb,"\tCBUpdateLBox: edit text length %i\n", length );

   if( pText )
   {
       if( length ) GetWindowText32A( lphc->hWndEdit, pText, length + 1);
       else pText[0] = '\0';
       idx = SendMessage32A( lphc->hWndLBox, LB_FINDSTRING32, 
			     (WPARAM32)(-1), (LPARAM)pText );
       if( idx == LB_ERR ) idx = 0;	/* select first item */
       else ret = idx;
       HeapFree( GetProcessHeap(), 0, pText );
   }

   /* select entry */

   SendMessage32A( lphc->hWndLBox, LB_SETCURSEL32, (WPARAM32)idx, 0 );
   
   if( idx >= 0 )
   {
       SendMessage32A( lphc->hWndLBox, LB_SETTOPINDEX32, (WPARAM32)idx, 0 );
       /* probably superfluous but Windows sends this too */
       SendMessage32A( lphc->hWndLBox, LB_SETCARETINDEX32, (WPARAM32)idx, 0 );
   }
   return ret;
}

/***********************************************************************
 *           CBUpdateEdit
 *
 * Copy a listbox entry to the edit control.
 */
static void CBUpdateEdit( LPHEADCOMBO lphc , INT32 index )
{
   INT32	length;
   LPSTR	pText = NULL;

   dprintf_combo(stddeb,"\tCBUpdateEdit: %i\n", index );

   if( index == -1 )
   {
       length = CB_GETEDITTEXTLENGTH( lphc );
       if( length )
       {
           if( (pText = (LPSTR) HeapAlloc( GetProcessHeap(), 0, length + 1)) )
           {
 	   	GetWindowText32A( lphc->hWndEdit, pText, length + 1 );
	   	index = SendMessage32A( lphc->hWndLBox, LB_FINDSTRING32,
				        (WPARAM32)(-1), (LPARAM)pText );
	   	HeapFree( GetProcessHeap(), 0, pText );
           }
       }
   }

   if( index >= 0 ) /* got an entry */
   {
       length = SendMessage32A( lphc->hWndLBox, LB_GETTEXTLEN32, (WPARAM32)index, 0);
       if( length )
       {
	   if( (pText = (LPSTR) HeapAlloc( GetProcessHeap(), 0, length + 1)) )
	   {
		SendMessage32A( lphc->hWndLBox, LB_GETTEXT32, 
				(WPARAM32)index, (LPARAM)pText );
		SendMessage32A( lphc->hWndEdit, WM_SETTEXT, 0, (LPARAM)pText );
		SendMessage32A( lphc->hWndEdit, EM_SETSEL32, 0, (LPARAM)(-1) );
		HeapFree( GetProcessHeap(), 0, pText );
	   }
       }
   }
}

/***********************************************************************
 *           CBDropDown
 * 
 * Show listbox popup.
 */
static void CBDropDown( LPHEADCOMBO lphc )
{
   INT32	index;
   RECT16	rect;
   LPRECT16	pRect = NULL;

   dprintf_combo(stddeb,"Combo [%04x]: drop down\n", CB_HWND(lphc));

   CB_NOTIFY( lphc, CBN_DROPDOWN );

   /* set selection */

   lphc->wState |= CBF_DROPPED;
   if( CB_GETTYPE(lphc) == CBS_DROPDOWN )
   {
       index = CBUpdateLBox( lphc );
       if( !(lphc->wState & CBF_CAPTURE) ) CBUpdateEdit( lphc, index );
   }
   else
   {
       index = SendMessage32A( lphc->hWndLBox, LB_GETCURSEL32, 0, 0 );
       if( index == LB_ERR ) index = 0;
       SendMessage32A( lphc->hWndLBox, LB_SETTOPINDEX32, (WPARAM32)index, 0 );
       SendMessage32A( lphc->hWndLBox, LB_CARETON32, 0, 0 );
       pRect = &lphc->RectEdit;
   }

   /* now set popup position */

   GetWindowRect16( lphc->self->hwndSelf, &rect );
   
   rect.top += lphc->RectEdit.bottom - lphc->RectEdit.top - SYSMETRICS_CYBORDER;
   rect.bottom = rect.top + lphc->RectCombo.bottom - 
			    lphc->RectCombo.top - SYSMETRICS_CYBORDER;
   rect.right = rect.left + lphc->RectCombo.right - lphc->RectCombo.left;
   rect.left += ( CB_GETTYPE(lphc) == CBS_DROPDOWNLIST ) ? 0 : CBitOffset;

   SetWindowPos32( lphc->hWndLBox, HWND_TOP, rect.left, rect.top, 
		 rect.right - rect.left, rect.bottom - rect.top, 
		 SWP_NOACTIVATE | SWP_NOSIZE );
   if( pRect )
       RedrawWindow16( lphc->self->hwndSelf, pRect, 0, RDW_INVALIDATE | 
			   RDW_ERASE | RDW_UPDATENOW | RDW_NOCHILDREN );
   ShowWindow32( lphc->hWndLBox, SW_SHOWNA );
}

/***********************************************************************
 *           CBRollUp
 *
 * Hide listbox popup.
 */
static void CBRollUp( LPHEADCOMBO lphc, BOOL32 ok, BOOL32 bButton )
{
   HWND32	hWnd = lphc->self->hwndSelf;

   CB_NOTIFY( lphc, (ok) ? CBN_SELENDOK : CBN_SELENDCANCEL );

   if( IsWindow32( hWnd ) && CB_GETTYPE(lphc) != CBS_SIMPLE )
   {

       dprintf_combo(stddeb,"Combo [%04x]: roll up [%i]\n", CB_HWND(lphc), (INT32)ok );

       /* always send WM_LBUTTONUP? */
       SendMessage32A( lphc->hWndLBox, WM_LBUTTONUP, 0, (LPARAM)(-1) );

       if( lphc->wState & CBF_DROPPED ) 
       {
	   RECT16	rect;

	   lphc->wState &= ~CBF_DROPPED;
	   ShowWindow32( lphc->hWndLBox, SW_HIDE );

	   if( CB_GETTYPE(lphc) == CBS_DROPDOWN )
	   {
	       INT32 index = SendMessage32A( lphc->hWndLBox, LB_GETCURSEL32, 0, 0 );
	       CBUpdateEdit( lphc, index );
	       rect = lphc->RectButton;
	   }
	   else 
           {
	       if( bButton )
	           UnionRect16( &rect, &lphc->RectButton,
				       &lphc->RectEdit );
	       else
		   rect = lphc->RectEdit;
	       bButton = TRUE;
	   }

	   if( bButton )
	       RedrawWindow16( hWnd, &rect, 0, RDW_INVALIDATE | 
			       RDW_ERASE | RDW_UPDATENOW | RDW_NOCHILDREN );
	   CB_NOTIFY( lphc, CBN_CLOSEUP );
       }
   }
}

/***********************************************************************
 *           COMBO_FlipListbox
 *
 * Used by the ComboLBox to show/hide itself in response to VK_F4, etc...
 */
BOOL32 COMBO_FlipListbox( LPHEADCOMBO lphc, BOOL32 bRedrawButton )
{
   if( lphc->wState & CBF_DROPPED )
   {
       CBRollUp( lphc, TRUE, bRedrawButton );
       return FALSE;
   }

   CBDropDown( lphc );
   return TRUE;
}

/***********************************************************************
 *           COMBO_GetLBWindow
 *
 * Edit control helper.
 */
HWND32 COMBO_GetLBWindow( WND* pWnd )
{
  LPHEADCOMBO       lphc = CB_GETPTR(pWnd);
  if( lphc ) return lphc->hWndLBox;
  return 0;
}


/***********************************************************************
 *           CBRepaintButton
 */
static void CBRepaintButton( LPHEADCOMBO lphc )
{
   HDC32        hDC = GetDC32( lphc->self->hwndSelf );

   if( hDC )
   {
       CBPaintButton( lphc, (HDC16)hDC );
       ReleaseDC32( lphc->self->hwndSelf, hDC );
   }
}

/***********************************************************************
 *           COMBO_SetFocus
 */
static void COMBO_SetFocus( LPHEADCOMBO lphc )
{
   if( !(lphc->wState & CBF_FOCUSED) )
   {
       if( CB_GETTYPE(lphc) == CBS_DROPDOWNLIST )
           SendMessage32A( lphc->hWndLBox, LB_CARETON32, 0, 0 );

       if( lphc->wState & CBF_EDIT )
           SendMessage32A( lphc->hWndEdit, EM_SETSEL32, 0, (LPARAM)(-1) );
       lphc->wState |= CBF_FOCUSED;
       if( !(lphc->wState & CBF_EDIT) ) CBPaintText( lphc, 0 );

       CB_NOTIFY( lphc, CBN_SETFOCUS );
   }
}

/***********************************************************************
 *           COMBO_KillFocus
 */
static void COMBO_KillFocus( LPHEADCOMBO lphc )
{
   HWND32	hWnd = lphc->self->hwndSelf;

   if( lphc->wState & CBF_FOCUSED )
   {
       SendMessage32A( hWnd, WM_LBUTTONUP, 0, (LPARAM)(-1) );

       CBRollUp( lphc, FALSE, TRUE );
       if( IsWindow32( hWnd ) )
       {
           if( CB_GETTYPE(lphc) == CBS_DROPDOWNLIST )
               SendMessage32A( lphc->hWndLBox, LB_CARETOFF32, 0, 0 );

 	   lphc->wState &= ~CBF_FOCUSED;

           /* redraw text */
           if( lphc->wState & CBF_EDIT )
               SendMessage32A( lphc->hWndEdit, EM_SETSEL32, (WPARAM32)(-1), 0 );
           else CBPaintText( lphc, 0 );

           CB_NOTIFY( lphc, CBN_KILLFOCUS );
       }
   }
}

/***********************************************************************
 *           COMBO_Command
 */
static LRESULT COMBO_Command( LPHEADCOMBO lphc, WPARAM32 wParam, HWND32 hWnd )
{
   if( lphc->wState & CBF_EDIT && lphc->hWndEdit == hWnd )
   {
       /* ">> 8" makes gcc generate jump-table instead of cmp ladder */

       switch( HIWORD(wParam) >> 8 )
       {   
	   case (EN_SETFOCUS >> 8):

		dprintf_combo(stddeb,"Combo [%04x]: edit [%04x] got focus\n", 
				     CB_HWND(lphc), (HWND16)lphc->hWndEdit );

		if( !(lphc->wState & CBF_FOCUSED) ) COMBO_SetFocus( lphc );
	        break;

	   case (EN_KILLFOCUS >> 8):

		dprintf_combo(stddeb,"Combo [%04x]: edit [%04x] lost focus\n",
				      CB_HWND(lphc), (HWND16)lphc->hWndEdit );

		/* NOTE: it seems that Windows' edit control sends an
		 * undocumented message WM_USER + 0x1B instead of this
		 * notification (only when it happens to be a part of 
		 * the combo). ?? - AK.
		 */

		COMBO_KillFocus( lphc );
		break;


	   case (EN_CHANGE >> 8):
		CB_NOTIFY( lphc, CBN_EDITCHANGE );
		CBUpdateLBox( lphc );
		break;

	   case (EN_UPDATE >> 8):
		CB_NOTIFY( lphc, CBN_EDITUPDATE );
		break;

	   case (EN_ERRSPACE >> 8):
		CB_NOTIFY( lphc, CBN_ERRSPACE );
       }
   }
   else if( lphc->hWndLBox == hWnd )
   {
       switch( HIWORD(wParam) )
       {
	   case LBN_ERRSPACE:
		CB_NOTIFY( lphc, CBN_ERRSPACE );
		break;

	   case LBN_DBLCLK:
		CB_NOTIFY( lphc, CBN_DBLCLK );
		break;

	   case LBN_SELCHANGE:
	   case LBN_SELCANCEL:

		dprintf_combo(stddeb,"Combo [%04x]: lbox selection change [%04x]\n", 
						      CB_HWND(lphc), lphc->wState );

		/* do not roll up if selection is being tracked 
		 * by arrowkeys in the dropdown listbox */

		if( (lphc->wState & CBF_DROPPED) && !(lphc->wState & CBF_NOROLLUP) )
		     CBRollUp( lphc, (HIWORD(wParam) == LBN_SELCHANGE), TRUE );
		else lphc->wState &= ~CBF_NOROLLUP;

		CB_NOTIFY( lphc, CBN_SELCHANGE );
		CBPaintText( lphc, 0 );
		/* fall through */

	   case LBN_SETFOCUS:
	   case LBN_KILLFOCUS:
		/* nothing to do here since ComboLBox always resets the focus to its
		 * combo/edit counterpart */
		 break;
       }
   }
   return 0;
}

/***********************************************************************
 *           COMBO_ItemOp
 *
 * Fixup an ownerdrawn item operation and pass it up to the combobox owner.
 */
static LRESULT COMBO_ItemOp32( LPHEADCOMBO lphc, UINT32 msg, 
			       WPARAM32 wParam, LPARAM lParam ) 
{
   HWND32	hWnd = lphc->self->hwndSelf;

   dprintf_combo(stddeb,"Combo [%04x]: ownerdraw op %04x\n", 
				       CB_HWND(lphc), (UINT16)msg );

#define lpIS    ((LPDELETEITEMSTRUCT32)lParam)

   /* two first items are the same in all 4 structs */
   lpIS->CtlType = ODT_COMBOBOX;
   lpIS->CtlID   = lphc->self->wIDmenu;

   switch( msg )	/* patch window handle */
   {
	case WM_DELETEITEM: 
	     lpIS->hwndItem = hWnd; 
#undef  lpIS
	     break;
	case WM_DRAWITEM: 
#define lpIS    ((LPDRAWITEMSTRUCT32)lParam)
	     lpIS->hwndItem = hWnd; 
#undef  lpIS
	     break;
	case WM_COMPAREITEM: 
#define lpIS    ((LPCOMPAREITEMSTRUCT32)lParam)
	     lpIS->hwndItem = hWnd; 
#undef  lpIS
	     break;
   }

  return SendMessage32A( lphc->owner, msg, lphc->self->wIDmenu, lParam );
}

/***********************************************************************
 *           COMBO_GetText
 */
static LRESULT COMBO_GetText( LPHEADCOMBO lphc, UINT32 N, LPSTR lpText)
{
   INT32	idx;

   if( lphc->wState & CBF_EDIT )
       return SendMessage32A( lphc->hWndEdit, WM_GETTEXT, 
			     (WPARAM32)N, (LPARAM)lpText );     

   /* get it from the listbox */

   idx = SendMessage32A( lphc->hWndLBox, LB_GETCURSEL32, 0, 0 );
   if( idx != LB_ERR )
   {
       LPSTR        lpBuffer;
       INT32	    length = SendMessage32A( lphc->hWndLBox, LB_GETTEXTLEN32,
					    (WPARAM32)idx, 0 );

       /* 'length' is without the terminating character */
       if( length >= N )
	   lpBuffer = (LPSTR) HeapAlloc( GetProcessHeap(), 0, length + 1 );
       else 
	   lpBuffer = lpText;

       if( lpBuffer )
       {
	   INT32    n = SendMessage32A( lphc->hWndLBox, LB_GETTEXT32, 
				       (WPARAM32)idx, (LPARAM)lpText );

	   /* truncate if buffer is too short */

	   if( length >= N )
	   {
	       if( n != LB_ERR ) memcpy( lpText, lpBuffer, (N>n) ? n+1 : N-1 );
	       lpText[N - 1] = '\0';
	       HeapFree( GetProcessHeap(), 0, lpBuffer );
	   }
	   return (LRESULT)n;
       }
   }
   return 0;
}


/***********************************************************************
 *           CBResetPos
 *
 * This function sets window positions according to the updated 
 * component placement struct.
 */
static void CBResetPos( LPHEADCOMBO lphc, LPRECT16 lbRect, BOOL32 bRedraw )
{
   BOOL32	bDrop = (CB_GETTYPE(lphc) != CBS_SIMPLE);

   /* NOTE: logs sometimes have WM_LBUTTONUP before a cascade of
    * sizing messages */

   if( lphc->wState & CBF_EDIT )
       SetWindowPos32( lphc->hWndEdit, 0, lphc->RectEdit.left, lphc->RectEdit.top,
                       lphc->RectEdit.right - lphc->RectEdit.left,
                       lphc->RectEdit.bottom - lphc->RectEdit.top,
                       SWP_NOZORDER | SWP_NOACTIVATE | ((bDrop) ? SWP_NOREDRAW : 0) );

   if( bDrop )
       OffsetRect16( lbRect, lphc->RectCombo.left, lphc->RectCombo.top );

   lbRect->right -= lbRect->left;	/* convert to width */
   lbRect->bottom -= lbRect->top;
   SetWindowPos32( lphc->hWndLBox, 0, lbRect->left, lbRect->top,
                   lbRect->right, lbRect->bottom, 
		   SWP_NOACTIVATE | SWP_NOZORDER | ((bDrop) ? SWP_NOREDRAW : 0) );

   if( bDrop )
   {
       if( lphc->wState & CBF_DROPPED )
       {
           lphc->wState &= ~CBF_DROPPED;
           ShowWindow32( lphc->hWndLBox, SW_HIDE );
       }

       lphc->wState |= CBF_NORESIZE;
       SetWindowPos32( lphc->self->hwndSelf, 0, 0, 0,
                       lphc->RectCombo.right - lphc->RectCombo.left,
                       lphc->RectEdit.bottom - lphc->RectEdit.top,
                       SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW );
       lphc->wState &= ~CBF_NORESIZE;
       if( bRedraw )
           RedrawWindow32( lphc->self->hwndSelf, NULL, 0,
                           RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW );
   }
}


/***********************************************************************
 *           COMBO_Size
 */
static void COMBO_Size( LPHEADCOMBO lphc )
{
  RECT16	rect;
  INT16		w, h;

  GetWindowRect16( lphc->self->hwndSelf, &rect );
  w = rect.right - rect.left; h = rect.bottom - rect.top;

  dprintf_combo(stddeb,"COMBO_Size: w = %i, h = %i\n", w, h );

  /* CreateWindow() may send a bogus WM_SIZE, ignore it */

  if( w == (lphc->RectCombo.right - lphc->RectCombo.left) )
      if( (CB_GETTYPE(lphc) == CBS_SIMPLE) &&
	  (h == (lphc->RectCombo.bottom - lphc->RectCombo.top)) )
          return;
      else if( (lphc->dwStyle & CBS_DROPDOWN) &&
	       (h == (lphc->RectEdit.bottom - lphc->RectEdit.top))  )
	       return;
  
  lphc->RectCombo = rect;
  CBCalcPlacement( lphc, &lphc->RectEdit, &lphc->RectButton, &rect );
  CBResetPos( lphc, &rect, TRUE );
}


/***********************************************************************
 *           COMBO_Font
 */
static void COMBO_Font( LPHEADCOMBO lphc, HFONT16 hFont, BOOL32 bRedraw )
{
  RECT16        rect;

  lphc->hFont = hFont;

  if( lphc->wState & CBF_EDIT )
      SendMessage32A( lphc->hWndEdit, WM_SETFONT, (WPARAM32)hFont, bRedraw );
  SendMessage32A( lphc->hWndLBox, WM_SETFONT, (WPARAM32)hFont, bRedraw );

  GetWindowRect16( lphc->self->hwndSelf, &rect );
  OffsetRect16( &lphc->RectCombo, rect.left - lphc->RectCombo.left,
                                  rect.top - lphc->RectCombo.top );
  CBCalcPlacement( lphc, &lphc->RectEdit,
                         &lphc->RectButton, &rect );
  CBResetPos( lphc, &rect, bRedraw );
}


/***********************************************************************
 *           COMBO_SetItemHeight
 */
static LRESULT COMBO_SetItemHeight( LPHEADCOMBO lphc, INT32 index, INT32 height )
{
   LRESULT	lRet = CB_ERR;

   if( index == -1 ) /* set text field height */
   {
       if( height < 32768 )
       {
           RECT16	rect;

           lphc->editHeight = height;
           GetWindowRect16( lphc->self->hwndSelf, &rect );
           OffsetRect16( &lphc->RectCombo, rect.left - lphc->RectCombo.left,
				           rect.top - lphc->RectCombo.top );
           CBCalcPlacement( lphc, &lphc->RectEdit,
			          &lphc->RectButton, &rect );
           CBResetPos( lphc, &rect, TRUE );
	   lRet = height;
       }
   } 
   else if ( CB_OWNERDRAWN(lphc) )	/* set listbox item height */
	lRet = SendMessage32A( lphc->hWndLBox, LB_SETITEMHEIGHT32, 
			      (WPARAM32)index, (LPARAM)height );
   return lRet;
}

/***********************************************************************
 *           COMBO_SelectString
 */
static LRESULT COMBO_SelectString( LPHEADCOMBO lphc, INT32 start, LPCSTR pText )
{
   INT32 index = SendMessage32A( lphc->hWndLBox, CB_SELECTSTRING32, 
				 (WPARAM32)start, (LPARAM)pText );
   if( index >= 0 )
        if( lphc->wState & CBF_EDIT )
	    CBUpdateEdit( lphc, index );
	else
	    CBPaintText( lphc, 0 );
   return (LRESULT)index;
}

/***********************************************************************
 *           COMBO_LButtonDown
 */
static void COMBO_LButtonDown( LPHEADCOMBO lphc, LPARAM lParam )
{
   BOOL32      bButton = PtInRect16(&lphc->RectButton, MAKEPOINT16(lParam));
   HWND32      hWnd = lphc->self->hwndSelf;

   if( (CB_GETTYPE(lphc) == CBS_DROPDOWNLIST) ||
       (bButton && (CB_GETTYPE(lphc) == CBS_DROPDOWN)) )
   {
       lphc->wState |= CBF_BUTTONDOWN;
       if( lphc->wState & CBF_DROPPED )
       {
	   /* got a click to cancel selection */

           CBRollUp( lphc, TRUE, FALSE );
	   if( !IsWindow32( hWnd ) ) return;

           if( lphc->wState & CBF_CAPTURE )
           {
               lphc->wState &= ~CBF_CAPTURE;
               ReleaseCapture();
           }
           lphc->wState &= ~CBF_BUTTONDOWN;
       }
       else
       {
	   /* drop down the listbox and start tracking */

           lphc->wState |= CBF_CAPTURE;
           CBDropDown( lphc );
           SetCapture32( hWnd );
       }
       if( bButton ) CBRepaintButton( lphc );
   }
}

/***********************************************************************
 *           COMBO_LButtonUp
 *
 * Release capture and stop tracking if needed.
 */
static void COMBO_LButtonUp( LPHEADCOMBO lphc, LPARAM lParam )
{
   if( lphc->wState & CBF_CAPTURE )
   {
       lphc->wState &= ~CBF_CAPTURE;
       if( CB_GETTYPE(lphc) == CBS_DROPDOWN )
       {
	   INT32 index = CBUpdateLBox( lphc );
	   CBUpdateEdit( lphc, index );
       }
       ReleaseCapture();
   }

   if( lphc->wState & CBF_BUTTONDOWN )
   {
       lphc->wState &= ~CBF_BUTTONDOWN;
       CBRepaintButton( lphc );
   }
}

/***********************************************************************
 *           COMBO_MouseMove
 *
 * Two things to do - track combo button and release capture when
 * pointer goes into the listbox.
 */
static void COMBO_MouseMove( LPHEADCOMBO lphc, WPARAM32 wParam, LPARAM lParam )
{
   RECT16	lbRect;

   if( lphc->wState & CBF_BUTTONDOWN )
   {
       BOOL32	bButton = PtInRect16(&lphc->RectButton, MAKEPOINT16(lParam));

       if( !bButton )
       {
	   lphc->wState &= ~CBF_BUTTONDOWN;
	   CBRepaintButton( lphc );
       }
   }

   GetClientRect16( lphc->hWndLBox, &lbRect );
   MapWindowPoints16( lphc->self->hwndSelf, 
		      lphc->hWndLBox, (LPPOINT16)&lParam, 1 );
   if( PtInRect16(&lbRect, MAKEPOINT16(lParam)) )
   {
       lphc->wState &= ~CBF_CAPTURE;
       ReleaseCapture();
       if( CB_GETTYPE(lphc) == CBS_DROPDOWN ) CBUpdateLBox( lphc );

       /* hand over pointer tracking */
       SendMessage32A( lphc->hWndLBox, WM_LBUTTONDOWN, wParam, lParam );
   }
}


/***********************************************************************
 *           ComboWndProc
 *
 * http://www.microsoft.com/msdn/sdk/platforms/doc/sdk/win32/ctrl/src/combobox_15.htm
 */
LRESULT WINAPI ComboWndProc( HWND32 hwnd, UINT32 message,
                             WPARAM32 wParam, LPARAM lParam )
{
    WND*	pWnd = WIN_FindWndPtr(hwnd);
   
    if( pWnd )
    {
      LPHEADCOMBO	lphc = CB_GETPTR(pWnd);

      dprintf_combo( stddeb, "Combo [%04x]: msg %s wp %08x lp %08lx\n",
                     pWnd->hwndSelf, SPY_GetMsgName(message), wParam, lParam );

      if( lphc || message == WM_NCCREATE )
      switch(message) 
      {	

	/* System messages */

     	case WM_NCCREATE: 
		return COMBO_NCCreate(pWnd, lParam);

     	case WM_NCDESTROY: 
		COMBO_NCDestroy(lphc);
		break;

     	case WM_CREATE: 
		return COMBO_Create(lphc, pWnd, lParam);

     	case WM_PAINT:
		/* wParam may contain a valid HDC! */
		return COMBO_Paint(lphc, (HDC16)wParam);

	case WM_ERASEBKGND:
		return TRUE;

     	case WM_GETDLGCODE: 
		return (LRESULT)(DLGC_WANTARROWS | DLGC_WANTCHARS);

	case WM_SIZE:
	        if( lphc->hWndLBox && 
		  !(lphc->wState & CBF_NORESIZE) ) COMBO_Size( lphc );
		return TRUE;

	case WM_SETFONT:
		COMBO_Font( lphc, (HFONT16)wParam, (BOOL32)lParam );
		return TRUE;

	case WM_GETFONT:
		return (LRESULT)lphc->hFont;

	case WM_SETFOCUS:
		if( lphc->wState & CBF_EDIT )
		    SetFocus32( lphc->hWndEdit );
		else
		    COMBO_SetFocus( lphc );
		return TRUE;

	case WM_KILLFOCUS:
#define hwndFocus ((HWND16)wParam)
		if( !hwndFocus ||
		    (hwndFocus != lphc->hWndEdit && hwndFocus != lphc->hWndLBox ))
		    COMBO_KillFocus( lphc );
#undef hwndFocus
		return TRUE;

	case WM_COMMAND:
		return COMBO_Command( lphc, wParam, (HWND32)lParam );

	case WM_GETTEXT:
		return COMBO_GetText( lphc, (UINT32)wParam, (LPSTR)lParam );

	case WM_SETTEXT:
	case WM_GETTEXTLENGTH:
	case WM_CLEAR:
	case WM_CUT:
        case WM_PASTE:
	case WM_COPY:
		if( lphc->wState & CBF_EDIT )
		    return SendMessage32A( lphc->hWndEdit, message, wParam, lParam );
		return CB_ERR;

	case WM_DRAWITEM:
	case WM_DELETEITEM:
	case WM_COMPAREITEM:
	case WM_MEASUREITEM:
		return COMBO_ItemOp32( lphc, message, wParam, lParam );

	case WM_ENABLE:
		if( lphc->wState & CBF_EDIT )
		    EnableWindow32( lphc->hWndEdit, (BOOL32)wParam ); 
		EnableWindow32( lphc->hWndLBox, (BOOL32)wParam );
		return TRUE;

	case WM_SETREDRAW:
		if( lphc->wState & CBF_EDIT )
		    SendMessage32A( lphc->hWndEdit, message, wParam, lParam );
		SendMessage32A( lphc->hWndLBox, message, wParam, lParam );
		break;
		
	case WM_SYSKEYDOWN:
		if( KEYDATA_ALT & HIWORD(lParam) )
		    if( wParam == VK_UP || wParam == VK_DOWN )
			COMBO_FlipListbox( lphc, TRUE );
		break;

	case WM_CHAR:
	case WM_KEYDOWN:
		if( lphc->wState & CBF_EDIT )
		    return SendMessage32A( lphc->hWndEdit, message, wParam, lParam );
		else
		    return SendMessage32A( lphc->hWndLBox, message, wParam, lParam );

	case WM_LBUTTONDOWN: 
		if( !(lphc->wState & CBF_FOCUSED) ) SetFocus32( lphc->self->hwndSelf );
		if( lphc->wState & CBF_FOCUSED ) COMBO_LButtonDown( lphc, lParam );
		return TRUE;

	case WM_LBUTTONUP:
		COMBO_LButtonUp( lphc, lParam );
		return TRUE;

	case WM_MOUSEMOVE: 
		if( lphc->wState & CBF_CAPTURE ) 
		    COMBO_MouseMove( lphc, wParam, lParam );
		return TRUE;

	/* Combo messages */

	case CB_ADDSTRING16:
		if( CB_HASSTRINGS(lphc) ) lParam = (LPARAM)PTR_SEG_TO_LIN(lParam);
	case CB_ADDSTRING32:
		return SendMessage32A( lphc->hWndLBox, LB_ADDSTRING32, 0, lParam);

	case CB_INSERTSTRING16:
		wParam = (INT32)(INT16)wParam;
		if( CB_HASSTRINGS(lphc) ) lParam = (LPARAM)PTR_SEG_TO_LIN(lParam);
	case CB_INSERTSTRING32:
		return SendMessage32A( lphc->hWndLBox, LB_INSERTSTRING32, wParam, lParam);

	case CB_DELETESTRING16:
	case CB_DELETESTRING32:
		return SendMessage32A( lphc->hWndLBox, LB_DELETESTRING32, wParam, 0);

	case CB_SELECTSTRING16:
		wParam = (INT32)(INT16)wParam;
		if( CB_HASSTRINGS(lphc) ) lParam = (LPARAM)PTR_SEG_TO_LIN(lParam);
	case CB_SELECTSTRING32:
		return COMBO_SelectString( lphc, (INT32)wParam, (LPSTR)lParam );

	case CB_FINDSTRING16:
		wParam = (INT32)(INT16)wParam;
		if( CB_HASSTRINGS(lphc) ) lParam = (LPARAM)PTR_SEG_TO_LIN(lParam);
	case CB_FINDSTRING32:
		return SendMessage32A( lphc->hWndLBox, LB_FINDSTRING32, wParam, lParam);

	case CB_FINDSTRINGEXACT16:
		wParam = (INT32)(INT16)wParam;
		if( CB_HASSTRINGS(lphc) ) lParam = (LPARAM)PTR_SEG_TO_LIN(lParam);
	case CB_FINDSTRINGEXACT32:
		return SendMessage32A( lphc->hWndLBox, LB_FINDSTRINGEXACT32, 
						       wParam, lParam );
	case CB_SETITEMHEIGHT16:
		wParam = (INT32)(INT16)wParam;
	case CB_SETITEMHEIGHT32:
		return COMBO_SetItemHeight( lphc, (INT32)wParam, (INT32)lParam);

	case CB_RESETCONTENT16: 
	case CB_RESETCONTENT32:
		SendMessage32A( lphc->hWndLBox, LB_RESETCONTENT32, 0, 0 );
		CBPaintText( lphc, 0 );
		return TRUE;

	case CB_INITSTORAGE32:
		return SendMessage32A( lphc->hWndLBox, LB_INITSTORAGE32, wParam, lParam);

	case CB_GETHORIZONTALEXTENT32:
		return SendMessage32A( lphc->hWndLBox, LB_GETHORIZONTALEXTENT32, 0, 0);

	case CB_SETHORIZONTALEXTENT32:
		return SendMessage32A( lphc->hWndLBox, LB_SETHORIZONTALEXTENT32, wParam, 0);

	case CB_GETTOPINDEX32:
		return SendMessage32A( lphc->hWndLBox, LB_GETTOPINDEX32, 0, 0);

	case CB_GETLOCALE32:
		return SendMessage32A( lphc->hWndLBox, LB_GETLOCALE32, 0, 0);

	case CB_SETLOCALE32:
		return SendMessage32A( lphc->hWndLBox, LB_SETLOCALE32, wParam, 0);

	case CB_GETDROPPEDWIDTH32:
		if( lphc->droppedWidth )
		    return lphc->droppedWidth;
		return lphc->RectCombo.right - lphc->RectCombo.left - 
		           (lphc->wState & CBF_EDIT) ? CBitOffset : 0;

	case CB_SETDROPPEDWIDTH32:
		if( (CB_GETTYPE(lphc) != CBS_SIMPLE) &&
		    (INT32)wParam < 32768 ) lphc->droppedWidth = (INT32)wParam;
		return CB_ERR;

	case CB_GETDROPPEDCONTROLRECT16:
		lParam = (LPARAM)PTR_SEG_TO_LIN(lParam);
		if( lParam ) 
		{
		    RECT32	r;
		    CBGetDroppedControlRect32( lphc, &r );
		    CONV_RECT32TO16( &r, (LPRECT16)lParam );
		}
		return CB_OKAY;

	case CB_GETDROPPEDCONTROLRECT32:
		if( lParam ) CBGetDroppedControlRect32(lphc, (LPRECT32)lParam );
		return CB_OKAY;

	case CB_GETDROPPEDSTATE16:
	case CB_GETDROPPEDSTATE32:
		return (lphc->wState & CBF_DROPPED) ? TRUE : FALSE;

	case CB_DIR16: 
                lParam = (LPARAM)PTR_SEG_TO_LIN(lParam);
                /* fall through */
	case CB_DIR32:
		return COMBO_Directory( lphc, (UINT32)wParam, 
				       (LPSTR)lParam, (message == CB_DIR32));
	case CB_SHOWDROPDOWN16:
	case CB_SHOWDROPDOWN32:
		if( CB_GETTYPE(lphc) != CBS_SIMPLE )
		    if( wParam )
		    {
			if( !(lphc->wState & CBF_DROPPED) )
			    CBDropDown( lphc );
		    }
		    else 
			if( lphc->wState & CBF_DROPPED ) 
		            CBRollUp( lphc, FALSE, TRUE );
		return TRUE;

	case CB_GETCOUNT16: 
	case CB_GETCOUNT32:
		return SendMessage32A( lphc->hWndLBox, LB_GETCOUNT32, 0, 0);

	case CB_GETCURSEL16: 
	case CB_GETCURSEL32:
		return SendMessage32A( lphc->hWndLBox, LB_GETCURSEL32, 0, 0);

	case CB_SETCURSEL16:
		wParam = (INT32)(INT16)wParam;
	case CB_SETCURSEL32:
		return SendMessage32A( lphc->hWndLBox, LB_SETCURSEL32, wParam, 0);

	case CB_GETLBTEXT16: 
		wParam = (INT32)(INT16)wParam;
		lParam = (LPARAM)PTR_SEG_TO_LIN(lParam);
	case CB_GETLBTEXT32:
		return SendMessage32A( lphc->hWndLBox, LB_GETTEXT32, wParam, lParam);

	case CB_GETLBTEXTLEN16: 
		wParam = (INT32)(INT16)wParam;
	case CB_GETLBTEXTLEN32:
		return SendMessage32A( lphc->hWndLBox, LB_GETTEXTLEN32, wParam, 0);

	case CB_GETITEMDATA16:
		wParam = (INT32)(INT16)wParam;
	case CB_GETITEMDATA32:
		return SendMessage32A( lphc->hWndLBox, LB_GETITEMDATA32, wParam, 0);

	case CB_SETITEMDATA16:
		wParam = (INT32)(INT16)wParam;
	case CB_SETITEMDATA32:
		return SendMessage32A( lphc->hWndLBox, LB_SETITEMDATA32, wParam, lParam);

	case CB_GETEDITSEL16: 
		wParam = lParam = 0;   /* just in case */
	case CB_GETEDITSEL32:
		if( lphc->wState & CBF_EDIT )
		{
		    INT32	a, b;

		    return SendMessage32A( lphc->hWndEdit, EM_GETSEL32,
					   (wParam) ? wParam : (WPARAM32)&a,
					   (lParam) ? lParam : (LPARAM)&b );
		}
		return CB_ERR;

	case CB_SETEDITSEL16: 
	case CB_SETEDITSEL32:
		if( lphc->wState & CBF_EDIT ) 
		    return SendMessage32A( lphc->hWndEdit, EM_SETSEL32, 
			  (INT32)(INT16)LOWORD(lParam), (INT32)(INT16)HIWORD(lParam) );
		return CB_ERR;

	case CB_SETEXTENDEDUI16:
	case CB_SETEXTENDEDUI32:
		if( CB_GETTYPE(lphc) == CBS_SIMPLE ) return CB_ERR;

		if( wParam )
		    lphc->wState |= CBF_EUI;
		else lphc->wState &= ~CBF_EUI;
		return CB_OKAY;

	case CB_GETEXTENDEDUI16:
	case CB_GETEXTENDEDUI32:
		return (lphc->wState & CBF_EUI) ? TRUE : FALSE;

	case (WM_USER + 0x1B):
	        dprintf_combo(stddeb,"Combo [%04x]: undocumented msg!\n", (HWND16)hwnd );
    }
    return DefWindowProc32A(hwnd, message, wParam, lParam);
  }
  return CB_ERR;
}

