/* Treeview control
 *
 * Copyright 1998 Eric Kohl <ekohl@abo.rhein-zeitung.de>
 * Copyright 1998,1999 Alex Priem <alexp@sci.kun.nl>
 * Copyright 1999 Sylvain St-Germain
 *
 *
 * TODO:
 *   Using DPA to store the item ptr would be good.
 *   Node label edition is implemented but something happened in wine in the
 *   two last weeks of march 99 that broke it.
 *   refreshtreeview: 	
		-small array containing info about positions.
 		-better implementation of RefreshItem:
              1) draw lines between parents
              2) draw items
			  3) draw lines from parent<->items.
		-implement partial drawing?
 *  -drag&drop: TVM_CREATEDRAGIMAGE should create drag bitmap.
 *  -scrollbars: horizontal scrollbar doesn't work.
 *  -Unicode messages
 *  -check custom draw
 *  -I_CHILDRENCALLBACK
 *   FIXME: check fontsize. (uRealItemHeight)
 *          test focusItem  (redraw in different color)
			uHotItem
			Edit: needs timer
				  better implementation.
 *   WM_HSCROLL is broken.
 *   use separate routine to get item text/image.
 *  
 *   Separate drawing/calculation.
 *
 * FIXMEs  (for personal use)
    Expand:		-ctlmacro expands twice ->toggle.
   -DblClick:	ctlmacro.exe's NM_DBLCLK seems to go wrong (returns FALSE).
   -treehelper: stack corruption makes big window. 
	     
 */


#include <string.h>
#include "winbase.h"
#include "wingdi.h"
#include "commctrl.h"
#include "comctl32.h"
#include "debugtools.h"

DEFAULT_DEBUG_CHANNEL(treeview);

/* ffs should be in <string.h>. */

/* Defines, since they do not need to return previous state, and nr
 * has no side effects in this file.
 */
#define tv_test_bit(nr,bf)	(((LPBYTE)bf)[nr>>3]&(1<<(nr&7)))
#define tv_set_bit(nr,bf)	((LPBYTE)bf)[nr>>3]|=(1<<(nr&7))
#define tv_clear_bit(nr,bf)	((LPBYTE)bf)[nr>>3]&=~(1<<(nr&7))

#define MINIMUM_INDENT 10
#define TV_REFRESH_DELAY 100     /* 100 ms delay between two refreshes */
#define TV_DEFAULTITEMHEIGHT 16
#define TVITEM_ALLOC	16	/* default nr of items to allocate at first try */


/* internal structures */

typedef struct {
  UINT      mask;
  HTREEITEM hItem;
  UINT      state;
  UINT      stateMask;
  LPSTR     pszText;
  int       cchTextMax;
  int       iImage;
  int       iSelectedImage;
  int       cChildren;
  LPARAM    lParam;
  int       iIntegral;
  int       iLevel;         /* indentation level:0=root level */
  COLORREF  clrText;
  HTREEITEM parent;         /* handle to parent or 0 if at root*/
  HTREEITEM firstChild;     /* handle to first child or 0 if no child*/
  HTREEITEM sibling;        /* handle to next item in list, 0 if last */
  HTREEITEM upsibling;      /* handle to previous item in list, 0 if first */
  int       visible;
  RECT      rect;
  RECT      text;
  RECT      expandBox;      /* expand box (+/-) coordinate */
  RECT		bitmap;
  RECT      statebitmap;
} TREEVIEW_ITEM;


typedef struct
{
  UINT          uInternalStatus;    
  UINT          bAutoSize;      /* merge with uInternalStatus */
  INT           Timer;
  UINT          uNumItems;      /* number of valid TREEVIEW_ITEMs */
  UINT          uNumPtrsAlloced; 
  HTREEITEM     uMaxHandle;     /* needed for delete_item */
  HTREEITEM     TopRootItem;    /* handle to first item in treeview */
  INT           cdmode;         /* last custom draw setting */
  UINT          uScrollTime;	/* max. time for scrolling in milliseconds*/
  UINT          uItemHeight;    /* item height, -1 for default item height */
  UINT          uRealItemHeight;/* current item height in pixels */
  UINT          uVisibleHeight; /* visible height of treeview in pixels */
  UINT          uTotalHeight;   /* total height of treeview in pixels */
  UINT          uVisibleWidth;      
  UINT          uTotalWidth;  
  UINT          uIndent;        /* indentation in pixels */
  HTREEITEM     selectedItem;   /* handle to selected item or 0 if none */
  HTREEITEM     focusItem;      /* handle to item that has focus, 0 if none */
  HTREEITEM     hotItem;        /* handle currently under cursor, 0 if none */
  HTREEITEM     editItem;       /* handle to item currently editted, 0 if none */
  HTREEITEM     firstVisible;   /* handle to first visible item */
  HTREEITEM     dropItem;       /* handle to item selected by drag cursor */
  HTREEITEM     insertMarkItem; /* item after which insertion mark is placed */
  BOOL			insertBeforeorAfter; /* flag used by TVM_SETINSERTMARK */
  HIMAGELIST    dragList;       /* Bitmap of dragged item */
  INT           cx,cy;          /* current x/y place in list */
  COLORREF      clrBk;    
  COLORREF      clrText;
  COLORREF      clrLine;
  COLORREF  	clrInsertMark;
  HFONT         hFont;
  HFONT         hBoldFont;
  HWND          hwndToolTip;
  HWND          hwndEdit;
  WNDPROC       wpEditOrig;     /* needed for subclassing edit control */
  HIMAGELIST    himlNormal;  
  HIMAGELIST    himlState;
  LPTVSORTCB    pCallBackSort; /* ptr to TVSORTCB struct for callback sorting */
  TREEVIEW_ITEM *items;        /* itemlist */
  INT           *freeList;     /* bitmap indicating which elements are valid */
                               /* 1=valid, 0=free;   */
                               /* size of list= uNumPtrsAlloced/32 */
} TREEVIEW_INFO;


/* bitflags for infoPtr->uInternalStatus */

#define TV_HSCROLL 	0x01    /* treeview too large to fit in window */
#define TV_VSCROLL 	0x02	/* (horizontal/vertical) */
#define TV_LDRAG		0x04	/* Lbutton pushed to start drag */
#define TV_LDRAGGING	0x08	/* Lbutton pushed, mouse moved.  */
#define TV_RDRAG		0x10	/* dito Rbutton */
#define TV_RDRAGGING	0x20	

/* bitflags for infoPtr->timer */

#define TV_REFRESH_TIMER 1	
#define TV_EDIT_TIMER    2
#define TV_REFRESH_TIMER_SET 1  
#define TV_EDIT_TIMER_SET 2  

#define TREEVIEW_GetInfoPtr(hwnd) \
  ((TREEVIEW_INFO *) GetWindowLongA( hwnd, 0))

#define FOCUS_BORDER 3

static BOOL
TREEVIEW_SendSimpleNotify (HWND hwnd, UINT code);
static BOOL
TREEVIEW_SendTreeviewNotify (HWND hwnd, UINT code, UINT action, 
			HTREEITEM oldItem, HTREEITEM newItem);
static BOOL
TREEVIEW_SendTreeviewDnDNotify (HWND hwnd, UINT code, HTREEITEM dragItem, 
			POINT pt);
static BOOL
TREEVIEW_SendDispInfoNotify (HWND hwnd, TREEVIEW_ITEM *wineItem, 
			UINT code, UINT what);
static BOOL
TREEVIEW_SendCustomDrawNotify (HWND hwnd, DWORD dwDrawStage, HDC hdc,
			RECT rc);
static BOOL
TREEVIEW_SendCustomDrawItemNotify (HWND hwnd, HDC hdc,
            TREEVIEW_ITEM *tvItem, UINT uItemDrawState);
static LRESULT
TREEVIEW_DoSelectItem (HWND hwnd, INT action, HTREEITEM newSelect, INT cause);
static void
TREEVIEW_Refresh (HWND hwnd, HDC hdc);

static LRESULT CALLBACK
TREEVIEW_Edit_SubclassProc (HWND hwnd, UINT uMsg, WPARAM wParam, 
							LPARAM lParam);

static LRESULT
TREEVIEW_EditLabelA (HWND hwnd, WPARAM wParam, LPARAM lParam);

static LRESULT
TREEVIEW_EndEditLabelNow (HWND hwnd, WPARAM wParam, LPARAM lParam);




/* helper functions. Work with the assumption that validity of operands 
   is checked beforehand, and that tree state is valid.  */

/* FIXME: MS documentation says `GetNextVisibleItem' returns NULL 
   if not successfull. Probably only applies to dereferencing infoPtr
   (i.e. we are offered a valid treeview structure)
   and not whether there is a next `visible' child. 
   FIXME: check other failures.
 */

/***************************************************************************
 * This method returns the TREEVIEW_ITEM object given the handle
 */
static TREEVIEW_ITEM* TREEVIEW_ValidItem(
  TREEVIEW_INFO *infoPtr,
  HTREEITEM  handle)
{
  if ((!handle) || (handle>infoPtr->uMaxHandle)) 
    return NULL;

  if (tv_test_bit ((INT)handle, infoPtr->freeList)) 
    return NULL;

  return &infoPtr->items[(INT)handle];
}

/***************************************************************************
 * This method returns the last expanded child item of a tree node
 */
static TREEVIEW_ITEM *TREEVIEW_GetLastListItem(
  TREEVIEW_INFO *infoPtr,
  TREEVIEW_ITEM *tvItem)
{
  TREEVIEW_ITEM *wineItem = tvItem;

  /* 
   * Get this item last sibling 
   */
  while (wineItem->sibling) 
 	  wineItem=& infoPtr->items [(INT)wineItem->sibling];

  /* 
   * If the last sibling has expanded children, restart.
   */
  if ( ( wineItem->cChildren > 0 ) && ( wineItem->state & TVIS_EXPANDED) )
    return TREEVIEW_GetLastListItem(
             infoPtr, 
             &(infoPtr->items[(INT)wineItem->firstChild]));

  return wineItem;
}

/***************************************************************************
 * This method returns the previous physical item in the list not 
 * considering the tree hierarchy.
 */
static TREEVIEW_ITEM *TREEVIEW_GetPrevListItem(
  TREEVIEW_INFO *infoPtr, 
  TREEVIEW_ITEM *tvItem)
{
  if (tvItem->upsibling) 
  {
    /* 
     * This item has a upsibling, get the last item.  Since, GetLastListItem
     * first looks at siblings, we must feed it with the first child.
     */
    TREEVIEW_ITEM *upItem = &infoPtr->items[(INT)tvItem->upsibling];
    
    if ( ( upItem->cChildren > 0 ) && ( upItem->state & TVIS_EXPANDED) )
      return TREEVIEW_GetLastListItem( 
               infoPtr, 
               &infoPtr->items[(INT)upItem->firstChild]);
    else
      return upItem;
  }
  else
  {
    /*
     * this item does not have a upsibling, get the parent
     */
    if (tvItem->parent) 
      return &infoPtr->items[(INT)tvItem->parent];
  }

  return NULL;
}


/***************************************************************************
 * This method returns the next physical item in the treeview not 
 * considering the tree hierarchy.
 */
static TREEVIEW_ITEM *TREEVIEW_GetNextListItem(
  TREEVIEW_INFO *infoPtr, 
  TREEVIEW_ITEM *tvItem)
{
  TREEVIEW_ITEM *wineItem = NULL;

  /* 
   * If this item has children and is expanded, return the first child
   */
  if ((tvItem->firstChild) && (tvItem->state & TVIS_EXPANDED)) 
		return (& infoPtr->items[(INT)tvItem->firstChild]);


  /*
   * try to get the sibling
   */
  if (tvItem->sibling) 
		return (& infoPtr->items[(INT)tvItem->sibling]);

  /*
   * Otherwise, get the parent's sibling.
   */
  wineItem=tvItem;
  while (wineItem->parent) {
    wineItem=& infoPtr->items [(INT)wineItem->parent];
  	if (wineItem->sibling) 
      return (& infoPtr->items [(INT)wineItem->sibling]);
  } 

  return NULL;  
}

/***************************************************************************
 * This method returns the nth item starting at the given item.  It returns 
 * the last item (or first) we we run out of items.
 *
 * Will scroll backward if count is <0.
 *             forward if count is >0.
 */
static TREEVIEW_ITEM *TREEVIEW_GetListItem(
  TREEVIEW_INFO *infoPtr, 
  TREEVIEW_ITEM *tvItem,
  LONG          count)
{
  TREEVIEW_ITEM *previousItem = NULL;
  TREEVIEW_ITEM *wineItem     = tvItem;
  LONG          iter          = 0;

  if      (count > 0)
  {
    /* Find count item downward */
    while ((iter++ < count) && (wineItem != NULL))
    {
      /* Keep a pointer to the previous in case we ask for more than we got */
      previousItem = wineItem; 
      wineItem     = TREEVIEW_GetNextListItem(infoPtr, wineItem);
    } 

    if (wineItem == NULL)
      wineItem = previousItem;
  }
  else if (count < 0)
  {
    /* Find count item upward */
    while ((iter-- > count) && (wineItem != NULL))
    {
      /* Keep a pointer to the previous in case we ask for more than we got */
      previousItem = wineItem; 
      wineItem = TREEVIEW_GetPrevListItem(infoPtr, wineItem);
    }

    if (wineItem == NULL)
      wineItem = previousItem;
  }
  else
    wineItem = NULL;

  return wineItem;
}

 
/***************************************************************************
 * This method 
 */
static void TREEVIEW_RemoveAllChildren(
  HWND hwnd,
  TREEVIEW_ITEM *parentItem)
{
 TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
 TREEVIEW_ITEM *killItem;
 INT	kill;
 
 kill=(INT)parentItem->firstChild;
 while (kill) {
 	tv_set_bit ( kill, infoPtr->freeList);
 	killItem=& infoPtr->items[kill];
	if (killItem->pszText!=LPSTR_TEXTCALLBACKA) 
		COMCTL32_Free (killItem->pszText);
 	TREEVIEW_SendTreeviewNotify (hwnd, TVN_DELETEITEMA, 0, (HTREEITEM)kill, 0);
	if (killItem->firstChild) 
			TREEVIEW_RemoveAllChildren (hwnd, killItem);
	kill=(INT)killItem->sibling;
 }

 if (parentItem->cChildren>0) {
 	infoPtr->uNumItems -= parentItem->cChildren;
 	parentItem->firstChild = 0;
 	parentItem->cChildren  = 0;
 }

}


static void
TREEVIEW_RemoveItem (HWND hwnd, TREEVIEW_ITEM *wineItem)

{
 TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
 TREEVIEW_ITEM *parentItem, *upsiblingItem, *siblingItem;
 INT iItem;

 iItem=(INT)wineItem->hItem;
 tv_set_bit(iItem,infoPtr->freeList);
 infoPtr->uNumItems--;
 parentItem=NULL;
 if (wineItem->pszText!=LPSTR_TEXTCALLBACKA) 
	COMCTL32_Free (wineItem->pszText);

 TREEVIEW_SendTreeviewNotify (hwnd, TVN_DELETEITEMA, 0, (HTREEITEM)iItem, 0);

 if (wineItem->firstChild) 
 	TREEVIEW_RemoveAllChildren (hwnd,wineItem);

 if (wineItem->parent) {
	parentItem=& infoPtr->items [(INT)wineItem->parent];
	switch (parentItem->cChildren) {
		case I_CHILDRENCALLBACK: 
				FIXME("we don't handle I_CHILDRENCALLBACK yet\n");
				break;
		case 1:
			parentItem->cChildren=0;
			parentItem->firstChild=0;    
			return;
		default:
			parentItem->cChildren--;
			if ((INT)parentItem->firstChild==iItem) 
				parentItem->firstChild=wineItem->sibling;
		}
 }

 if (iItem==(INT)infoPtr->TopRootItem) 
	infoPtr->TopRootItem=(HTREEITEM)wineItem->sibling;
 if (wineItem->upsibling) {
	upsiblingItem=& infoPtr->items [(INT)wineItem->upsibling];
	upsiblingItem->sibling=wineItem->sibling;
 }
 if (wineItem->sibling) {
	siblingItem=& infoPtr->items [(INT)wineItem->sibling];
	siblingItem->upsibling=wineItem->upsibling;
 }
}





/* Note:TREEVIEW_RemoveTree doesn't remove infoPtr itself */

static void TREEVIEW_RemoveTree (HWND hwnd)
					   
{
  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
  TREEVIEW_ITEM *killItem;
  int i;

  for (i = 1; i <= (INT)infoPtr->uMaxHandle; i++) 
    if (!tv_test_bit (i, infoPtr->freeList)) {
      killItem = &infoPtr->items[i];	
      if (killItem->pszText != LPSTR_TEXTCALLBACKA)
	COMCTL32_Free (killItem->pszText);
      TREEVIEW_SendTreeviewNotify(hwnd, TVN_DELETEITEMA, 0,
				  killItem->hItem, 0);
    } 
  if (infoPtr->uNumPtrsAlloced) {
    COMCTL32_Free (infoPtr->items);
    COMCTL32_Free (infoPtr->freeList);
    infoPtr->uNumItems = 0;
    infoPtr->uNumPtrsAlloced = 0;
    infoPtr->uMaxHandle = 0;
    infoPtr->TopRootItem = 0;
  }   
}







static LRESULT
TREEVIEW_GetImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);

  TRACE("\n");

  if ((INT)wParam == TVSIL_NORMAL) 
	return (LRESULT) infoPtr->himlNormal;
  if ((INT)wParam == TVSIL_STATE) 
	return (LRESULT) infoPtr->himlState;

  return 0;
}

static LRESULT
TREEVIEW_SetImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
    HIMAGELIST himlTemp;

    TRACE("%x,%lx\n", wParam, lParam);
    switch ((INT)wParam) {
	case TVSIL_NORMAL:
	    himlTemp = infoPtr->himlNormal;
	    infoPtr->himlNormal = (HIMAGELIST)lParam;
	    return (LRESULT)himlTemp;

	case TVSIL_STATE:
	    himlTemp = infoPtr->himlState;
	    infoPtr->himlState = (HIMAGELIST)lParam;
	    return (LRESULT)himlTemp;
    }

    return (LRESULT)NULL;
}



static LRESULT
TREEVIEW_SetItemHeight (HWND hwnd, WPARAM wParam)
{
  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
  INT cx,cy,prevHeight=infoPtr->uItemHeight;

  TRACE("\n");
  if (wParam==-1) {
	infoPtr->uItemHeight=-1;
	return prevHeight;
  }

  ImageList_GetIconSize (infoPtr->himlNormal, &cx, &cy);

  if (wParam>cy) cy=wParam;
  infoPtr->uItemHeight=cy;

  if (!( GetWindowLongA( hwnd, GWL_STYLE) & TVS_NONEVENHEIGHT))
	infoPtr->uItemHeight = (INT) wParam & 0xfffffffe;
  return prevHeight;
}

static LRESULT
TREEVIEW_GetItemHeight (HWND hwnd)
{
  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
  
  TRACE("\n");
  return infoPtr->uItemHeight;
}
  
static LRESULT
TREEVIEW_GetLineColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);

  TRACE("\n");
  return (LRESULT) infoPtr->clrLine;
}

static LRESULT
TREEVIEW_SetLineColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
  COLORREF prevColor=infoPtr->clrLine;

  TRACE("\n");
  infoPtr->clrLine=(COLORREF) lParam;
  return (LRESULT) prevColor;
}

static LRESULT
TREEVIEW_GetInsertMarkColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);

  TRACE("\n");
  return (LRESULT) infoPtr->clrInsertMark;
}

static LRESULT
TREEVIEW_SetInsertMarkColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
  COLORREF prevColor=infoPtr->clrInsertMark;

  TRACE("%d %ld\n",wParam,lParam);
  infoPtr->clrInsertMark=(COLORREF) lParam;
  return (LRESULT) prevColor;
}

static LRESULT
TREEVIEW_SetInsertMark (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);

  FIXME("%d %ld\n",wParam,lParam);
  if (!TREEVIEW_ValidItem (infoPtr, (HTREEITEM)lParam)) return 0;
  FIXME("%d %ld\n",wParam,lParam);

  infoPtr->insertBeforeorAfter=(BOOL) wParam;
  infoPtr->insertMarkItem=(HTREEITEM) lParam;
  
  InvalidateRect(hwnd, NULL, FALSE);

  return 1;
}

static LRESULT
TREEVIEW_SetTextColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
  COLORREF prevColor=infoPtr->clrText;

  TRACE("\n");
  infoPtr->clrText=(COLORREF) lParam;
  return (LRESULT) prevColor;
}

static LRESULT
TREEVIEW_GetBkColor (HWND hwnd)
{
  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
	
  TRACE("\n");
  return (LRESULT) infoPtr->clrBk;
}

static LRESULT
TREEVIEW_SetBkColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
  COLORREF prevColor=infoPtr->clrBk;

  TRACE("\n");
  infoPtr->clrBk=(COLORREF) lParam;
  return (LRESULT) prevColor;
}

static LRESULT
TREEVIEW_GetTextColor (HWND hwnd)
{
  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
	
  TRACE("\n");
  return (LRESULT) infoPtr->clrText;
}


/* cdmode: custom draw mode as received from app. in first NMCUSTOMDRAW 
           notification */

#define TREEVIEW_LEFT_MARGIN 8


static void
TREEVIEW_DrawItem (HWND hwnd, HDC hdc, TREEVIEW_ITEM *wineItem)
{
  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
  DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
  INT   center,xpos,cx,cy, cditem;
  HFONT hOldFont;
  UINT  uTextJustify = DT_LEFT;
  RECT  r;

 
  if (wineItem->state & TVIS_BOLD) 
  	hOldFont = SelectObject (hdc, infoPtr->hBoldFont);
  else 
  	hOldFont = SelectObject (hdc, infoPtr->hFont);

  cditem=0;
  TRACE ("cdmode:%x\n",infoPtr->cdmode);
  if (infoPtr->cdmode & CDRF_NOTIFYITEMDRAW) {
		cditem=TREEVIEW_SendCustomDrawItemNotify 
 					(hwnd, hdc, wineItem, CDDS_ITEMPREPAINT);
		TRACE("prepaint:cditem-app returns 0x%x\n",cditem);

		if (cditem & CDRF_SKIPDEFAULT) 
			return;
	}

  /* 
   * Set drawing starting points 
   */
  r      = wineItem->rect;               /* this item rectangle */
  center = (r.top+r.bottom)/2;           /* this item vertical center */
  xpos   = r.left + TREEVIEW_LEFT_MARGIN;/* horizontal starting point */

  /* 
   * Display the tree hierarchy 
   */
  if ( dwStyle & TVS_HASLINES) 
  {
    /* 
     * Write links to parent node 
     * we draw the L starting from the child to the parent
     *
     * points[0] is attached to the current item
     * points[1] is the L corner
     * points[2] is attached to the parent or the up sibling
     */
    if ( dwStyle & TVS_LINESATROOT) 
    {
      TREEVIEW_ITEM *upNode    = NULL;
     	BOOL  hasParentOrSibling = TRUE;
      RECT  upRect             = {0,0,0,0};
      HPEN  hOldPen, hNewPen;
    	POINT points[3];
      /* 
       * determine the target location of the line at root, either be linked
       * to the up sibling or to the parent node.
       */
      if (wineItem->upsibling)
      	upNode  = TREEVIEW_ValidItem (infoPtr, wineItem->upsibling);
      else if (wineItem->parent)
      	upNode  = TREEVIEW_ValidItem (infoPtr, wineItem->parent);
      else
        hasParentOrSibling = FALSE;

      if (upNode)
        upRect = upNode->rect;

      if ( wineItem->iLevel == 0 )
      {
        points[2].x = points[1].x = upRect.left+8;
        points[0].x = points[2].x + 10;
        points[2].y = upRect.bottom-3;      
        points[1].y = points[0].y = center;
      }
      else
      {
        points[2].x = points[1].x = 8 + (20*wineItem->iLevel); 
        points[2].y = ( upNode->cChildren == 0) ? 
                        upRect.top :        /* is linked to the "L" above */
                        ( wineItem->upsibling != NULL) ? 
                          upRect.bottom-3:  /* is linked to an icon       */
                          upRect.bottom+1;  /* is linked to a +/- box     */
        points[1].y = points[0].y = center;
        points[0].x = points[1].x + 10; 
      }
    
      /* 
       * Get a dotted pen
       */ 
      hNewPen = CreatePen(PS_DOT, 0, infoPtr->clrLine);
      hOldPen = SelectObject( hdc, hNewPen );
  
      if (hasParentOrSibling)
        Polyline (hdc,points,3); 
      else
        Polyline (hdc,points,2); 
      
      DeleteObject(hNewPen);
      SelectObject(hdc, hOldPen);
    }
  }

  /* 
   * Display the (+/-) signs
   */
  if (wineItem->iLevel != 0)/*  update position only for non root node */
    xpos+=(5*wineItem->iLevel);

  if (( dwStyle & TVS_HASBUTTONS) && ( dwStyle & TVS_HASLINES))
  {
	  if ( (wineItem->cChildren) ||
	       (wineItem->cChildren == I_CHILDRENCALLBACK))
    {
      /* Setup expand box coordinate to facilitate the LMBClick handling */
      wineItem->expandBox.left   = xpos-4;
      wineItem->expandBox.top    = center-4;
      wineItem->expandBox.right  = xpos+5;
      wineItem->expandBox.bottom = center+5;

  		Rectangle (
        hdc, 
        wineItem->expandBox.left, 
        wineItem->expandBox.top , 
        wineItem->expandBox.right, 
        wineItem->expandBox.bottom);

  		MoveToEx (hdc, xpos-2, center, NULL);
  		LineTo   (hdc, xpos+3, center);
  
  		if (!(wineItem->state & TVIS_EXPANDED)) {
  			MoveToEx (hdc, xpos,   center-2, NULL);
  			LineTo   (hdc, xpos,   center+3);
  	  }
    }
  }

  /* 
   * Display the image associated with this item
   */
  xpos += 13; /* update position */
  if (wineItem->mask & (TVIF_IMAGE|TVIF_SELECTEDIMAGE)) {
    INT        imageIndex;
    HIMAGELIST *himlp = NULL;

   /* State images are displayed to the left of the Normal image
    * image number is in state; zero should be `display no image'.
    * FIXME: that last sentence looks like it needs some checking.
    */
   	if (infoPtr->himlState) 
        himlp=&infoPtr->himlState;
	imageIndex=wineItem->state>>12;
	imageIndex++;          /* yeah, right */
	TRACE ("imindex:%d\n",imageIndex);
    if ((himlp) && (imageIndex))
    { 
	  imageIndex--;       /* see FIXME */
      ImageList_Draw ( *himlp, imageIndex, hdc, xpos-2, r.top+1, ILD_NORMAL);
   	  ImageList_GetIconSize (*himlp, &cx, &cy);
	  wineItem->statebitmap.left=xpos-2;
	  wineItem->statebitmap.right=xpos-2+cx;
	  wineItem->statebitmap.top=r.top+1;
	  wineItem->statebitmap.bottom=r.top+1+cy;
   	  xpos+=cx;
    }
	
		/* Now, draw the normal image; can be either selected or
		 * non-selected image. 
		 */

	himlp=NULL;
  	if (infoPtr->himlNormal) 
      himlp=&infoPtr->himlNormal; /* get the image list */

    imageIndex = wineItem->iImage;
  	if ( (wineItem->state & TVIS_SELECTED) && 
         (wineItem->iSelectedImage)) { 
        
      /* The item is curently selected */
		  if (wineItem->iSelectedImage == I_IMAGECALLBACK) 
  			TREEVIEW_SendDispInfoNotify 
					(hwnd, wineItem, TVN_GETDISPINFOA, TVIF_SELECTEDIMAGE);

      	  imageIndex = wineItem->iSelectedImage;
	  } else { 
      /* The item is not selected */
		  if (wineItem->iImage == I_IMAGECALLBACK) 
			  TREEVIEW_SendDispInfoNotify 
					(hwnd, wineItem, TVN_GETDISPINFOA, TVIF_IMAGE);

      imageIndex = wineItem->iImage;
  	}
 
    if (himlp)         
    { 
	int ovlIdx = 0;

	if(wineItem->stateMask & TVIS_OVERLAYMASK)
        	ovlIdx = wineItem->state & TVIS_OVERLAYMASK;

	ImageList_Draw ( *himlp, imageIndex, hdc, xpos-2, r.top+1, ILD_NORMAL|ovlIdx);
	ImageList_GetIconSize (*himlp, &cx, &cy);
	wineItem->bitmap.left=xpos-2;
	wineItem->bitmap.right=xpos-2+cx;
	wineItem->bitmap.top=r.top+1;
	wineItem->bitmap.bottom=r.top+1+cy;
	xpos+=cx;
    }
  }


  /* 
   * Display the text associated with this item
   */
  r.left=xpos;
  if ((wineItem->mask & TVIF_TEXT) && (wineItem->pszText)) 
  {
    COLORREF oldTextColor = 0;
    INT      oldBkMode;
    HBRUSH   hbrBk = 0;
    BOOL     inFocus = GetFocus() == hwnd;

    TREEVIEW_ITEM tmpItem;
    char  buf[128];

    if (wineItem->pszText == LPSTR_TEXTCALLBACKA) 
    {
        tmpItem.hItem      = wineItem->hItem;
        tmpItem.state      = wineItem->state;
        tmpItem.lParam     = wineItem->lParam;
        tmpItem.pszText    = buf;
        tmpItem.cchTextMax = sizeof(buf);

        TREEVIEW_SendDispInfoNotify(hwnd, &tmpItem, TVN_GETDISPINFOA, TVIF_TEXT);
    }

    r.left += 3;
    r.right -= 3;

    wineItem->text.left  = r.left;  
    wineItem->text.right = r.right;
    wineItem->text.top   = r.top;
    wineItem->text.bottom= r.bottom;

    oldBkMode = SetBkMode(hdc, TRANSPARENT);

    /* - If item is drop target or it is selected and window is in focus -
     * use blue background (COLOR_HIGHLIGHT).
     * - If item is selected, window is not in focus, but it has style
     * TVS_SHOWSELALWAYS - use grey background (COLOR_BTNFACE)
     * - Otherwise - don't fill background
     */
    if ((wineItem->state & TVIS_DROPHILITED) ||
        ((wineItem->state & TVIS_SELECTED) &&
        (inFocus || (GetWindowLongA( hwnd, GWL_STYLE) & TVS_SHOWSELALWAYS))))
    {
       if ((wineItem->state & TVIS_DROPHILITED) || inFocus)
       {
          hbrBk = CreateSolidBrush(GetSysColor( COLOR_HIGHLIGHT));
          oldTextColor = SetTextColor(hdc, GetSysColor( COLOR_HIGHLIGHTTEXT));
       }
       else
       {
          hbrBk = CreateSolidBrush(GetSysColor( COLOR_BTNFACE));

          if (infoPtr->clrText == -1)
             oldTextColor = SetTextColor(hdc, GetSysColor( COLOR_WINDOWTEXT));
          else
             oldTextColor = SetTextColor(hdc, infoPtr->clrText);
       }
    } 
    else 
    {
       if (infoPtr->clrText == -1)
          oldTextColor = SetTextColor(hdc, GetSysColor( COLOR_WINDOWTEXT));
       else
          oldTextColor = SetTextColor(hdc, infoPtr->clrText);
    }

    if (wineItem->pszText != LPSTR_TEXTCALLBACKA)
       tmpItem.pszText = wineItem->pszText;

    /* Obtain the text coordinate */
    DrawTextA (
         hdc,
         tmpItem.pszText,
         lstrlenA(tmpItem.pszText),
         &wineItem->text,
         uTextJustify | DT_VCENTER | DT_SINGLELINE | DT_CALCRECT | DT_NOPREFIX);

    /* We need to reset it to items height */
    wineItem->text.top = r.top;
    wineItem->text.bottom = r.bottom;
    wineItem->text.right += 4; /* This is extra for focus rectangle */

    if (hbrBk)
    {
       FillRect(hdc, &wineItem->text, hbrBk);
       DeleteObject(hbrBk);
    }

    wineItem->text.left += 2;

    /* Draw it */
    DrawTextA ( hdc, 
      tmpItem.pszText, 
      lstrlenA(tmpItem.pszText), 
      &wineItem->text, 
      uTextJustify | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX); 

    wineItem->text.left -=2;

    /* Restore the hdc state */
    SetTextColor( hdc, oldTextColor);

    /* Draw the box arround the selected item */
    if (wineItem->state & TVIS_SELECTED && inFocus) 
    {
      HPEN  hNewPen     = CreatePen(PS_DOT, 0, GetSysColor(COLOR_WINDOWTEXT) );
      HPEN  hOldPen     = SelectObject( hdc, hNewPen );
      INT   rop         = SetROP2(hdc, R2_XORPEN);
      POINT points[5];

      points[4].x = points[0].x = wineItem->text.left;
      points[4].y = points[0].y = wineItem->text.top; 
      points[1].x = wineItem->text.right-1 ;
      points[1].y = wineItem->text.top; 
      points[2].x = wineItem->text.right-1;
      points[2].y = wineItem->text.bottom-1; 
      points[3].x = wineItem->text.left;
      points[3].y = wineItem->text.bottom-1;

      Polyline (hdc,points,5); 

      SetROP2(hdc, rop);
      DeleteObject(hNewPen);
      SelectObject(hdc, hOldPen);
    }

    if (oldBkMode != TRANSPARENT)
       SetBkMode(hdc, oldBkMode);
  }

  /* Draw insertion mark if necessary */

  if (infoPtr->insertMarkItem) 
		TRACE ("item:%d,mark:%d\n", (int)wineItem->hItem,
                               (int) infoPtr->insertMarkItem);
  if (wineItem->hItem==infoPtr->insertMarkItem) {
		HPEN hNewPen, hOldPen;
		int offset;

		hNewPen = CreatePen(PS_SOLID, 2, infoPtr->clrInsertMark);
		hOldPen = SelectObject( hdc, hNewPen );
	
		if (infoPtr->insertBeforeorAfter)
			offset=wineItem->text.top+1;
		else
			offset=wineItem->text.bottom-1;

		MoveToEx (hdc, wineItem->text.left, offset-3, NULL);
		LineTo (hdc, wineItem->text.left, offset+3);

		MoveToEx (hdc, wineItem->text.left, offset, NULL);
		LineTo (hdc, r.right-2, offset);

		MoveToEx (hdc, r.right-2, offset+3, NULL);
		LineTo (hdc, r.right-2, offset-3);

      	DeleteObject(hNewPen);

      	SelectObject(hdc, hOldPen);
	}

  if (cditem & CDRF_NOTIFYPOSTPAINT) {
		cditem=TREEVIEW_SendCustomDrawItemNotify 
                       (hwnd, hdc, wineItem, CDDS_ITEMPOSTPAINT);
		TRACE("postpaint:cditem-app returns 0x%x\n",cditem);
	}

  SelectObject (hdc, hOldFont);
}

static LRESULT
TREEVIEW_GetItemRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
  TREEVIEW_ITEM *wineItem;
  HTREEITEM     *iItem;
  LPRECT        lpRect   = (LPRECT)lParam;

  TRACE("\n");
  /* 
   * validate parameters
   */
  if (lpRect == NULL)
    return FALSE;

  if (infoPtr->Timer & TV_REFRESH_TIMER_SET) {
	InvalidateRect(hwnd, NULL, FALSE);  	
   }


  /* 
   * retrieve the item ptr
   */ 
  iItem = (HTREEITEM *) lParam;
  wineItem = TREEVIEW_ValidItem (infoPtr, *iItem);
  if ((!wineItem) || (!wineItem->visible)) 
    return FALSE;

  /* 
   * If wParam is TRUE return the text size otherwise return 
   * the whole item size	
   */
  if ((INT) wParam) {
  	lpRect->left	  = wineItem->text.left;
    lpRect->right	  = wineItem->text.right;
    lpRect->bottom	= wineItem->text.bottom;
    lpRect->top	    = wineItem->text.top;
  } else {
    lpRect->left 	  = wineItem->rect.left;
    lpRect->right	  = wineItem->rect.right;
    lpRect->bottom  = wineItem->rect.bottom;
    lpRect->top	    = wineItem->rect.top;
  }

  TRACE("[L:%d R:%d T:%d B:%d]\n", 
      lpRect->left,lpRect->right,
			lpRect->top,lpRect->bottom);

  return TRUE;
}

static LRESULT
TREEVIEW_GetVisibleCount (HWND hwnd,  WPARAM wParam, LPARAM lParam)

{
  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);

  return (LRESULT) infoPtr->uVisibleHeight / infoPtr->uRealItemHeight;
}



static LRESULT
TREEVIEW_SetItemA (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
  TREEVIEW_ITEM *wineItem;
  TVITEMEXA *tvItem;
  INT iItem,len;

  tvItem=(LPTVITEMEXA) lParam;
  iItem=(INT)tvItem->hItem;
  TRACE("item %d,mask %x\n",iItem,tvItem->mask);

  wineItem = TREEVIEW_ValidItem (infoPtr, (HTREEITEM)iItem);
  if (!wineItem) return FALSE;

  if (tvItem->mask & TVIF_CHILDREN) {
        wineItem->cChildren=tvItem->cChildren;
  }

  if (tvItem->mask & TVIF_IMAGE) {
       wineItem->iImage=tvItem->iImage;
  }

  if (tvItem->mask & TVIF_INTEGRAL) {
        wineItem->iIntegral=tvItem->iIntegral; 
  }

  if (tvItem->mask & TVIF_PARAM) {
        wineItem->lParam=tvItem->lParam;
  }

  if (tvItem->mask & TVIF_SELECTEDIMAGE) {
        wineItem->iSelectedImage=tvItem->iSelectedImage;
  }

  if (tvItem->mask & TVIF_STATE) {
		TRACE ("prevstate,state,mask:%x,%x,%x\n",wineItem->state,tvItem->state,
tvItem->stateMask);
        wineItem->state&= ~tvItem->stateMask;
		wineItem->state|= (tvItem->state & tvItem->stateMask);
		wineItem->stateMask|= tvItem->stateMask;  
  }

  if (tvItem->mask & TVIF_TEXT)
  {
    if (tvItem->pszText!=LPSTR_TEXTCALLBACKA)
    {
      len=lstrlenA (tvItem->pszText) + 1;
      if (len>wineItem->cchTextMax)
      {
        wineItem->pszText= COMCTL32_ReAlloc (wineItem->pszText, len);
        wineItem->cchTextMax = len;
      }

      lstrcpynA (wineItem->pszText, tvItem->pszText,len);
    }
    else
    {
      if (wineItem->cchTextMax)
      {
        COMCTL32_Free (wineItem->pszText);
	    wineItem->cchTextMax=0;
      }
      wineItem->pszText=LPSTR_TEXTCALLBACKA;
    }
  }

  wineItem->mask |= tvItem->mask;

  return TRUE;
}

static LRESULT
TREEVIEW_GetItemState (HWND hwnd, WPARAM wParam, LPARAM lParam)

{
    TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
	TREEVIEW_ITEM *wineItem;
	
    TRACE("\n");
  	wineItem = TREEVIEW_ValidItem (infoPtr, (HTREEITEM)wParam);
	if (!wineItem) return 0;
	
	return (wineItem->state & lParam);
}




static void
TREEVIEW_Refresh (HWND hwnd, HDC hdc)
{
    TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
	TEXTMETRICA tm;
	HBRUSH hbrBk;
    HFONT hOldFont;

    RECT rect;
    INT iItem, indent, x, y, height, itemHeight;
    INT viewtop,viewbottom,viewleft,viewright;
    TREEVIEW_ITEM *wineItem, *prevItem;

    TRACE("\n");


    if (infoPtr->Timer & TV_REFRESH_TIMER_SET) {
		KillTimer (hwnd, TV_REFRESH_TIMER);
		infoPtr->Timer &= ~TV_REFRESH_TIMER_SET;
    }

    
    GetClientRect (hwnd, &rect);
    if ((rect.left >= rect.right) || (rect.top >= rect.bottom)) return;

    infoPtr->cdmode=TREEVIEW_SendCustomDrawNotify(hwnd,CDDS_PREPAINT,hdc,rect);

    if (infoPtr->cdmode==CDRF_SKIPDEFAULT) return;

    infoPtr->uVisibleHeight= rect.bottom-rect.top + 1;
    infoPtr->uVisibleWidth= rect.right-rect.left + 1;

    viewtop=infoPtr->cy;
    viewbottom=infoPtr->cy + rect.bottom-rect.top;
    viewleft=infoPtr->cx;
    viewright=infoPtr->cx + rect.right-rect.left;

    TRACE("[%d %d %d %d]\n",viewtop,viewbottom,viewleft,viewright);

    /* draw background */
    
    hbrBk = CreateSolidBrush (infoPtr->clrBk);
    FillRect(hdc, &rect, hbrBk);
    DeleteObject(hbrBk);

    ImageList_GetIconSize (infoPtr->himlNormal, &x, &itemHeight);
    if (infoPtr->uItemHeight>itemHeight)
	itemHeight=infoPtr->uItemHeight;

    // assume that bold and normal fonts have same height
    hOldFont = SelectObject (hdc, infoPtr->hBoldFont);
    GetTextMetricsA (hdc, &tm);
    if ((tm.tmHeight + tm.tmExternalLeading + FOCUS_BORDER) > itemHeight)
	 itemHeight=tm.tmHeight + tm.tmExternalLeading + FOCUS_BORDER;
    SelectObject (hdc, hOldFont);

    infoPtr->uRealItemHeight=itemHeight;

    iItem=(INT)infoPtr->TopRootItem;
    infoPtr->firstVisible=0;
    wineItem=NULL;
    indent=0;
    x=y=0;

    while (iItem) {
	prevItem=wineItem;
        wineItem= & infoPtr->items[iItem];
	wineItem->iLevel=indent;

/* FIXME: remove this in later stage  */
/*
		if (wineItem->pszText!=LPSTR_TEXTCALLBACK32A) 
		TRACE (treeview, "%d %d [%d %d %d %d] (%s)\n",y,x,
			wineItem->rect.top, wineItem->rect.bottom,
			wineItem->rect.left, wineItem->rect.right,
			wineItem->pszText);
		else 
		TRACE (treeview, "%d [%d %d %d %d] (CALLBACK)\n",
				wineItem->hItem,
				wineItem->rect.top, wineItem->rect.bottom,
				wineItem->rect.left, wineItem->rect.right);
*/

		height=itemHeight * wineItem->iIntegral; 
		if ((y >= viewtop) && (y <= viewbottom) &&
	    	(x >= viewleft  ) && (x <= viewright)) {
				wineItem->visible = TRUE;
        		wineItem->rect.top = y - infoPtr->cy + rect.top;
        		wineItem->rect.bottom = wineItem->rect.top + height-1;
         		wineItem->rect.left = x - infoPtr->cx + rect.left;
        		wineItem->rect.right = rect.right;
			if (!infoPtr->firstVisible)
				infoPtr->firstVisible=wineItem->hItem;
       		TREEVIEW_DrawItem (hwnd, hdc, wineItem);
		}
		else {
			wineItem->visible   = FALSE;
			wineItem->rect.left = wineItem->rect.top    = 0;
			wineItem->rect.right= wineItem->rect.bottom = 0;
			wineItem->text.left = wineItem->text.top    = 0;
			wineItem->text.right= wineItem->text.bottom = 0;
 		}

		/* look up next item */
	
		if ((wineItem->firstChild) && (wineItem->state & TVIS_EXPANDED)) {
			iItem=(INT)wineItem->firstChild;
			indent++;
			x+=infoPtr->uIndent;
			if (x>infoPtr->uTotalWidth) 	
				infoPtr->uTotalWidth=x;
		}
		else {
			iItem=(INT)wineItem->sibling;
			while ((!iItem) && (indent>0)) {
				indent--;
				x-=infoPtr->uIndent;
				wineItem=&infoPtr->items[(INT)wineItem->parent];
				iItem=(INT)wineItem->sibling;
			}
		}
        y +=height;
    }				/* while */

/* FIXME: infoPtr->uTotalWidth should also take item label into account */
/* FIXME: or should query item sizes (ie check CDRF_NEWFONT) */

    infoPtr->uTotalHeight=y;
    if (y >= (viewbottom-viewtop)) {
 		if (!(infoPtr->uInternalStatus & TV_VSCROLL))
			ShowScrollBar (hwnd, SB_VERT, TRUE);
		infoPtr->uInternalStatus |=TV_VSCROLL;
 		SetScrollRange (hwnd, SB_VERT, 0, 
					y - infoPtr->uVisibleHeight, FALSE);
		SetScrollPos (hwnd, SB_VERT, infoPtr->cy, TRUE);
	}
    else {
		if (infoPtr->uInternalStatus & TV_VSCROLL) 
			ShowScrollBar (hwnd, SB_VERT, FALSE);
		infoPtr->uInternalStatus &= ~TV_VSCROLL;
	}


	if (infoPtr->cdmode & CDRF_NOTIFYPOSTPAINT) 
    	infoPtr->cdmode=TREEVIEW_SendCustomDrawNotify 
								(hwnd, CDDS_POSTPAINT, hdc, rect);

    TRACE("done\n");
}


static LRESULT 
TREEVIEW_HandleTimer (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);

  TRACE(" %d\n",wParam);

  switch (wParam) {
	case TV_REFRESH_TIMER:
		KillTimer (hwnd, TV_REFRESH_TIMER);
		infoPtr->Timer &= ~TV_REFRESH_TIMER_SET;
		InvalidateRect(hwnd, NULL, FALSE);
		return 0;
	case TV_EDIT_TIMER:
		KillTimer (hwnd, TV_EDIT_TIMER);
		infoPtr->Timer &= ~TV_EDIT_TIMER_SET;
		return 0;
	default:
		ERR("got unknown timer\n");
 }
		
 return 1;
}


static void
TREEVIEW_QueueRefresh (HWND hwnd)

{
 TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);

 TRACE("\n");
 if (infoPtr->Timer & TV_REFRESH_TIMER_SET) {
	KillTimer (hwnd, TV_REFRESH_TIMER);
 }

 SetTimer (hwnd, TV_REFRESH_TIMER, TV_REFRESH_DELAY, 0);
 infoPtr->Timer|=TV_REFRESH_TIMER_SET;
}



static LRESULT
TREEVIEW_GetItemA (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
  LPTVITEMEXA    tvItem;
  TREEVIEW_ITEM *wineItem;
  INT         iItem;

  tvItem=(LPTVITEMEXA) lParam;
  iItem=(INT)tvItem->hItem;

  wineItem = TREEVIEW_ValidItem (infoPtr, (HTREEITEM)iItem);
  if (!wineItem) return FALSE;

   if (tvItem->mask & TVIF_CHILDREN) {
		if (TVIF_CHILDREN==I_CHILDRENCALLBACK) 
			FIXME("I_CHILDRENCALLBACK not supported\n");
        tvItem->cChildren=wineItem->cChildren;
   }

   if (tvItem->mask & TVIF_HANDLE) {
        tvItem->hItem=wineItem->hItem;
   }

   if (tvItem->mask & TVIF_IMAGE) {
        tvItem->iImage=wineItem->iImage;
   }

   if (tvItem->mask & TVIF_INTEGRAL) {
        tvItem->iIntegral=wineItem->iIntegral; 
   }

   /* undocumented: windows ignores TVIF_PARAM and
	 * always sets lParam
	 */
   tvItem->lParam=wineItem->lParam;

   if (tvItem->mask & TVIF_SELECTEDIMAGE) {
        tvItem->iSelectedImage=wineItem->iSelectedImage;
   }

   if (tvItem->mask & TVIF_STATE) {
        tvItem->state=wineItem->state & tvItem->stateMask;
   }

   if (tvItem->mask & TVIF_TEXT) {
	if (wineItem->pszText == LPSTR_TEXTCALLBACKA) {
	    tvItem->pszText = LPSTR_TEXTCALLBACKA;  /* FIXME:send notification? */
		ERR(" GetItem called with LPSTR_TEXTCALLBACK\n");
	}
	else if (wineItem->pszText) {
	    lstrcpynA (tvItem->pszText, wineItem->pszText, tvItem->cchTextMax);
	}
   }

  TRACE("item %d<%p>, txt %p, img %p, action %x\n", 
    iItem, tvItem, tvItem->pszText, &tvItem->iImage, tvItem->mask);

  return TRUE;
}


static LRESULT
TREEVIEW_GetItemW (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
  LPTVITEMEXA    tvItem;
  TREEVIEW_ITEM *wineItem;
  INT         iItem;

  tvItem=(LPTVITEMEXA) lParam;
  iItem=(INT)tvItem->hItem;

  wineItem = TREEVIEW_ValidItem (infoPtr, (HTREEITEM)iItem);
  if (!wineItem) return FALSE;

   if (tvItem->mask & TVIF_CHILDREN) {
		if (TVIF_CHILDREN==I_CHILDRENCALLBACK)
			FIXME("I_CHILDRENCALLBACK not supported\n");
        tvItem->cChildren=wineItem->cChildren;
   }

   if (tvItem->mask & TVIF_HANDLE) {
        tvItem->hItem=wineItem->hItem;
   }

   if (tvItem->mask & TVIF_IMAGE) {
        tvItem->iImage=wineItem->iImage;
   }

   if (tvItem->mask & TVIF_INTEGRAL) {
        tvItem->iIntegral=wineItem->iIntegral;
   }

   /* undocumented: windows ignores TVIF_PARAM and
	 * always sets lParam
	 */
   tvItem->lParam=wineItem->lParam;

   if (tvItem->mask & TVIF_SELECTEDIMAGE) {
        tvItem->iSelectedImage=wineItem->iSelectedImage;
   }

   if (tvItem->mask & TVIF_STATE) {
        tvItem->state=wineItem->state & tvItem->stateMask;
   }

#if 0
   if (tvItem->mask & TVIF_TEXT) {
	if (wineItem->pszText == LPSTR_TEXTCALLBACKW) {
	    tvItem->pszText = LPSTR_TEXTCALLBACKW;  /* FIXME:send notification? */
		ERR(" GetItem called with LPSTR_TEXTCALLBACK\n");
	}
	else if (wineItem->pszText) {
	    lstrcpynAtoW (tvItem->pszText, wineItem->pszText, tvItem->cchTextMax);
	}
   }
#endif
  wineItem->pszText = NULL;

  TRACE("item %d<%p>, txt %p, img %p, action %x\n",
    iItem, tvItem, tvItem->pszText, &tvItem->iImage, tvItem->mask);

  return TRUE;
}



/* FIXME: check implementation of TVGN_NEXT/TVGN_NEXTVISIBLE */

static LRESULT
TREEVIEW_GetNextItem (HWND hwnd, WPARAM wParam, LPARAM lParam)

{
  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
  TREEVIEW_ITEM *wineItem, *returnItem;
  INT iItem = (INT)lParam, retval = 0, flag  = (INT)wParam;

  switch (flag) {
  case TVGN_ROOT:
    retval = (INT)infoPtr->TopRootItem;
    break;

  case TVGN_CARET:
    retval = (INT)infoPtr->selectedItem;
    break;

  case TVGN_FIRSTVISIBLE: /* FIXME:we should only recalculate, not redraw */
    InvalidateRect(hwnd, NULL, FALSE);
    retval = (INT)infoPtr->firstVisible;
    break;

  case TVGN_DROPHILITE:
    retval = (INT)infoPtr->dropItem;
    break;
 
  case TVGN_NEXT:
    wineItem = TREEVIEW_ValidItem (infoPtr, (HTREEITEM)iItem);
    retval = wineItem ? (INT)wineItem->sibling : 0;
    break;

  case TVGN_PREVIOUS:	
    wineItem = TREEVIEW_ValidItem (infoPtr, (HTREEITEM)iItem);
    retval = wineItem ? (INT)wineItem->upsibling : 0;
    break;

  case TVGN_PARENT:
    wineItem = TREEVIEW_ValidItem (infoPtr, (HTREEITEM)iItem);
    retval = wineItem ? (INT)wineItem->parent : 0;
    break;

  case TVGN_CHILD:
    wineItem = TREEVIEW_ValidItem (infoPtr, (HTREEITEM)iItem);
    retval = wineItem ? (INT)wineItem->firstChild : 0;
    break;

  case TVGN_LASTVISIBLE:  
    if((wineItem = TREEVIEW_ValidItem (infoPtr, (HTREEITEM)iItem))) {
      returnItem = TREEVIEW_GetLastListItem (infoPtr,wineItem);
      retval = returnItem ? (INT)returnItem->hItem : 0;
    }
    break;

  case TVGN_NEXTVISIBLE:  
    if((wineItem = TREEVIEW_ValidItem (infoPtr, (HTREEITEM)iItem))) {
      returnItem = TREEVIEW_GetNextListItem (infoPtr,wineItem);
      retval = returnItem ? (INT)returnItem->hItem : 0;
    }
    break;

  case TVGN_PREVIOUSVISIBLE: 
    if((wineItem = TREEVIEW_ValidItem (infoPtr, (HTREEITEM)iItem))) {
      returnItem = TREEVIEW_GetPrevListItem (infoPtr, wineItem);
      retval = returnItem ? (INT)returnItem->hItem : 0;
    }
    break;

  default:
    FIXME("Unknown msg %x,item %x\n", flag,iItem);
    break;
  }

  TRACE("flags %x, item %d returns %d\n", flag, iItem, retval);
  return retval;
}


static LRESULT
TREEVIEW_GetCount (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
 TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);

 TRACE(" %d\n",infoPtr->uNumItems);
 return (LRESULT) infoPtr->uNumItems;
}

/***************************************************************************
 * This method does the chaining of the insertion of a treeview item 
 * before an item.
 * If parent is NULL, we're inserting at the root of the list.
 */
static void TREEVIEW_InsertBefore(
    TREEVIEW_INFO *infoPtr,
    TREEVIEW_ITEM *newItem, 
    TREEVIEW_ITEM *sibling,
    TREEVIEW_ITEM *parent)
{
  HTREEITEM     siblingHandle   = 0;
  HTREEITEM     upSiblingHandle = 0;
  TREEVIEW_ITEM *upSibling      = NULL;

  if (newItem == NULL)
    ERR("NULL newItem, impossible condition\n");

  if (sibling != NULL) /* Insert before this sibling for this parent */
  { 
    /* Store the new item sibling up sibling and sibling tem handle */
    siblingHandle   = sibling->hItem;
    upSiblingHandle = sibling->upsibling;
    /* As well as a pointer to the upsibling sibling object */
    if ( (INT)sibling->upsibling != 0 )
      upSibling = &infoPtr->items[(INT)sibling->upsibling];
  
    /* Adjust the sibling pointer */
    sibling->upsibling = newItem->hItem;
    
    /* Adjust the new item pointers */
    newItem->upsibling = upSiblingHandle;
    newItem->sibling   = siblingHandle;
    
    /* Adjust the up sibling pointer */
    if ( upSibling != NULL )        
      upSibling->sibling = newItem->hItem;
    else
      /* this item is the first child of this parent, adjust parent pointers */
	  if (parent)
      	parent->firstChild = newItem->hItem;
	  else 
		infoPtr->TopRootItem= newItem->hItem;
  }
  else /* Insert as first child of this parent */
	if (parent)
    	parent->firstChild = newItem->hItem;
}

/***************************************************************************
 * This method does the chaining of the insertion of a treeview item 
 * after an item.
 * If parent is NULL, we're inserting at the root of the list.
 */
static void TREEVIEW_InsertAfter(
    TREEVIEW_INFO *infoPtr,
    TREEVIEW_ITEM *newItem, 
    TREEVIEW_ITEM *upSibling,
    TREEVIEW_ITEM *parent)
{
  HTREEITEM     upSiblingHandle = 0;
  HTREEITEM     siblingHandle   = 0;
  TREEVIEW_ITEM *sibling        = NULL;


  if (newItem == NULL)
    ERR("NULL newItem, impossible condition\n");

  if (upSibling != NULL) /* Insert after this upsibling for this parent */
  { 
    /* Store the new item up sibling and sibling item handle */
    upSiblingHandle = upSibling->hItem;
    siblingHandle   = upSibling->sibling;
    /* As well as a pointer to the upsibling sibling object */
    if ( (INT)upSibling->sibling != 0 )
      sibling = &infoPtr->items[(INT)upSibling->sibling];
  
    /* Adjust the up sibling pointer */
    upSibling->sibling = newItem->hItem;
    
    /* Adjust the new item pointers */
    newItem->upsibling = upSiblingHandle;
    newItem->sibling   = siblingHandle;
    
    /* Adjust the sibling pointer */
    if ( sibling != NULL )        
      sibling->upsibling = newItem->hItem; 
    /*
    else 
      newItem is the last of the level, nothing else to do 
    */
  }
  else /* Insert as first child of this parent */
	if (parent)
    	parent->firstChild = newItem->hItem;
}

/***************************************************************************
 * Forward the DPA local callback to the treeview owner callback
 */
static INT WINAPI TREEVIEW_CallBackCompare( 
  LPVOID first, 
  LPVOID second, 
  LPARAM tvInfoPtr)
{
  /* Forward the call to the client define callback */
  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr((HWND)tvInfoPtr);
  return (infoPtr->pCallBackSort->lpfnCompare)(
    ((TREEVIEW_ITEM*)first)->lParam,
    ((TREEVIEW_ITEM*)second)->lParam,
    infoPtr->pCallBackSort->lParam);
}

/***************************************************************************
 * Treeview native sort routine: sort on item text.
 */
static INT WINAPI TREEVIEW_SortOnName ( 
  LPVOID first, 
  LPVOID second, 
  LPARAM tvInfoPtr)
{
  HWND hwnd=(HWND) tvInfoPtr;
  char *txt1, *txt2;
  TREEVIEW_ITEM *item;

	
  item=(TREEVIEW_ITEM *) first;
  if (item->pszText==LPSTR_TEXTCALLBACKA)  {
	 TREEVIEW_SendDispInfoNotify (hwnd, item, TVN_GETDISPINFOA, TVIF_TEXT);
	}
  txt1=item->pszText;

  item=(TREEVIEW_ITEM *) second;
  if (item->pszText==LPSTR_TEXTCALLBACKA)  {
	 TREEVIEW_SendDispInfoNotify (hwnd, item, TVN_GETDISPINFOA, TVIF_TEXT);
	}
  txt2=item->pszText;

  return -strcmp (txt1,txt2);
}

/***************************************************************************
 * Setup the treeview structure with regards of the sort method
 * and sort the children of the TV item specified in lParam
 * fRecurse: currently unused. Should be zero.
 * parent: if pSort!=NULL, should equal pSort->hParent.
 *         otherwise, item which child items are to be sorted.
 * pSort:  sort method info. if NULL, sort on item text.
 *         if non-NULL, sort on item's lParam content, and let the
 *         application decide what that means. See also TVM_SORTCHILDRENCB.
 */

static LRESULT WINAPI TREEVIEW_Sort (
  HWND   hwnd, 
  BOOL   fRecurse, 
  HTREEITEM parent,
  LPTVSORTCB pSort 
  )
{
  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
  TREEVIEW_ITEM *sortMe  = NULL; /* Node for which we sort the children */

  /* Obtain the TVSORTBC struct */
  infoPtr->pCallBackSort = pSort;

	/* undocumented feature: TVI_ROOT means `sort the whole tree' */

  if (parent==TVI_ROOT)
    parent=infoPtr->TopRootItem;

  /* Check for a valid handle to the parent item */
  if (!TREEVIEW_ValidItem(infoPtr, parent))
  {
    ERR ("invalid item hParent=%x\n", (INT)parent);
    return FALSE;
  }

  /* Obtain the parent node to sort */  
  sortMe = &infoPtr->items[ (INT)parent ];

  /* Make sure there is something to sort */
  if ( sortMe->cChildren > 1 ) 
  {
    /* pointer organization */
    HDPA          sortList   = DPA_Create(sortMe->cChildren);
    HTREEITEM     itemHandle = sortMe->firstChild;
    TREEVIEW_ITEM *itemPtr   = & infoPtr->items[ (INT)itemHandle ];

    /* TREEVIEW_ITEM rechaining */
    INT  count     = 0;
    VOID *item     = 0;
    VOID *nextItem = 0;
    VOID *prevItem = 0;

    /* Build the list of item to sort */
    do 
    {
      DPA_InsertPtr(
        sortList,              /* the list */
        sortMe->cChildren+1,   /* force the insertion to be an append */
        itemPtr);              /* the ptr to store */   

      /* Get the next sibling */
      itemHandle = itemPtr->sibling;
      itemPtr    = & infoPtr->items[ (INT)itemHandle ];
    } while ( itemHandle != NULL );

    /* let DPA perform the sort activity */
	if (pSort) 
    	DPA_Sort(
      		sortList,                  /* what  */ 
      		TREEVIEW_CallBackCompare,  /* how   */
      		hwnd);                     /* owner */
	else 
		DPA_Sort (
			sortList,                  /* what  */
      		TREEVIEW_SortOnName,       /* how   */
			hwnd);                     /* owner */

    /* 
     * Reorganized TREEVIEW_ITEM structures. 
     * Note that we know we have at least two elements.
     */

    /* Get the first item and get ready to start... */
    item = DPA_GetPtr(sortList, count++);    
    while ( (nextItem = DPA_GetPtr(sortList, count++)) != NULL )
    {
      /* link the two current item toghether */
      ((TREEVIEW_ITEM*)item)->sibling       = ((TREEVIEW_ITEM*)nextItem)->hItem;
      ((TREEVIEW_ITEM*)nextItem)->upsibling = ((TREEVIEW_ITEM*)item)->hItem;

      if (prevItem == NULL) /* this is the first item, update the parent */
      {
        sortMe->firstChild                = ((TREEVIEW_ITEM*)item)->hItem;
        ((TREEVIEW_ITEM*)item)->upsibling = NULL;
      }
      else                  /* fix the back chaining */
      {
        ((TREEVIEW_ITEM*)item)->upsibling = ((TREEVIEW_ITEM*)prevItem)->hItem;
      }

      /* get ready for the next one */
      prevItem = item; 
      item     = nextItem;
    }

    /* the last item is pointed to by item and never has a sibling */
    ((TREEVIEW_ITEM*)item)->sibling = NULL; 

    DPA_Destroy(sortList);

    return TRUE;
  }
  return FALSE;
}


/***************************************************************************
 * Setup the treeview structure with regards of the sort method
 * and sort the children of the TV item specified in lParam
 */
static LRESULT WINAPI TREEVIEW_SortChildrenCB(
  HWND   hwnd, 
  WPARAM wParam, 
  LPARAM lParam
  )
{
 LPTVSORTCB pSort=(LPTVSORTCB) lParam;

 return TREEVIEW_Sort (hwnd, wParam, pSort->hParent, pSort);
}


/***************************************************************************
 * Sort the children of the TV item specified in lParam.
 */
static LRESULT WINAPI TREEVIEW_SortChildren (
  HWND   hwnd, 
  WPARAM wParam, 
  LPARAM lParam)
{
 return TREEVIEW_Sort (hwnd, (BOOL) wParam, (HTREEITEM) lParam, NULL);
}



/* the method used below isn't the most memory-friendly, but it avoids 
   a lot of memory reallocations */ 

/* BTW: we waste handle 0; 0 is not an allowed handle. */

static LRESULT
TREEVIEW_InsertItemA (HWND hwnd, WPARAM wParam, LPARAM lParam)

{
  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
  TVINSERTSTRUCTA  *ptdi;
  TVITEMEXA 	*tvItem;
  TREEVIEW_ITEM *wineItem, *parentItem, *prevsib, *sibItem;
  INT		iItem,listItems,i,len;
 
  /* Item to insert */
  ptdi = (LPTVINSERTSTRUCTA) lParam;

	/* check if memory is available */

  if (infoPtr->uNumPtrsAlloced==0) {
        infoPtr->items = COMCTL32_Alloc (TVITEM_ALLOC*sizeof (TREEVIEW_ITEM));
        infoPtr->freeList= COMCTL32_Alloc ((1+(TVITEM_ALLOC>>5)) * sizeof (INT));
        infoPtr->uNumPtrsAlloced=TVITEM_ALLOC;
	infoPtr->TopRootItem=(HTREEITEM)1;
   }

  /* 
   * Reallocate contiguous space for items 
   */
  if (infoPtr->uNumItems == (infoPtr->uNumPtrsAlloced-1) ) {
   	TREEVIEW_ITEM *oldItems = infoPtr->items;
	INT *oldfreeList = infoPtr->freeList;

	infoPtr->uNumPtrsAlloced*=2;
    infoPtr->items = COMCTL32_Alloc (infoPtr->uNumPtrsAlloced*sizeof (TREEVIEW_ITEM));
    infoPtr->freeList= COMCTL32_Alloc ((1+(infoPtr->uNumPtrsAlloced>>5))*sizeof (INT));

    memcpy (&infoPtr->items[0], &oldItems[0],
                    infoPtr->uNumPtrsAlloced/2 * sizeof(TREEVIEW_ITEM));
    memcpy (&infoPtr->freeList[0], &oldfreeList[0],
                    (infoPtr->uNumPtrsAlloced>>6) * sizeof(INT));

    COMCTL32_Free (oldItems);  
    COMCTL32_Free (oldfreeList);  
   }

  /* 
   * Reset infoPtr structure with new stat according to current TV picture
   */
  iItem=0;
  infoPtr->uNumItems++;
  if ((INT)infoPtr->uMaxHandle==(infoPtr->uNumItems-1))  { 
  	iItem=infoPtr->uNumItems;
  	infoPtr->uMaxHandle = (HTREEITEM)((INT)infoPtr->uMaxHandle + 1);
  } else {					 /* check freelist */
  	for (i=0; i<=infoPtr->uNumPtrsAlloced>>5; i++) {
  		if (infoPtr->freeList[i]) {
  			iItem=ffs (infoPtr->freeList[i])-1;
  			tv_clear_bit(iItem,&infoPtr->freeList[i]);
   			iItem+=i<<5;
  			break;
  		}
    } 
  }

  if (TRACE_ON(treeview)) { 
    for (i=0; i<=infoPtr->uNumPtrsAlloced>>5; i++) 
	    TRACE("%8x\n",infoPtr->freeList[i]);
  }

  if (!iItem) ERR("Argh -- can't find free item.\n");

  /* 
   * Find the parent item of the new item 
   */  
  tvItem= & ptdi->DUMMYUNIONNAME.itemex;
  wineItem=& infoPtr->items[iItem];

  if ((ptdi->hParent==TVI_ROOT) || (ptdi->hParent==0)) {
    parentItem       = NULL;
    wineItem->parent = 0; 
    sibItem          = &infoPtr->items [(INT)infoPtr->TopRootItem];
    listItems        = infoPtr->uNumItems;
  }
  else  {
  	parentItem = &infoPtr->items[(INT)ptdi->hParent];
  
    /* Do the insertion here it if it's the only item of this parent */
  	if (!parentItem->firstChild) 
  		parentItem->firstChild=(HTREEITEM)iItem;
  
  	wineItem->parent = ptdi->hParent;
  	sibItem          = &infoPtr->items [(INT)parentItem->firstChild];
  	listItems        = parentItem->cChildren;
  	parentItem->cChildren++;
  }

  
  /* NOTE: I am moving some setup of the wineItem object that was initialy 
   *       done at the end of the function since some of the values are 
   *       required by the Callback sorting 
   */

  if (tvItem->mask & TVIF_TEXT) 
  {
    /*
     * Setup the item text stuff here since it's required by the Sort method
     * when the insertion are ordered
     */
    if (tvItem->pszText!=LPSTR_TEXTCALLBACKA) 
    {
      TRACE("(%p,%s)\n", &tvItem->pszText, tvItem->pszText); 
      len = lstrlenA (tvItem->pszText)+1;
      wineItem->pszText= COMCTL32_Alloc (len+1);
      strcpy (wineItem->pszText, tvItem->pszText);
      wineItem->cchTextMax=len;
    }
    else 
    {
      TRACE("LPSTR_TEXTCALLBACK\n");
      wineItem->pszText = LPSTR_TEXTCALLBACKA;
      wineItem->cchTextMax = 0;
    }
  }

  if (tvItem->mask & TVIF_PARAM) 
    wineItem->lParam=tvItem->lParam;


  wineItem->upsibling=0;  /* needed in case we're the first item in a list */ 
  wineItem->sibling=0;     
  wineItem->firstChild=0;
  wineItem->hItem=(HTREEITEM)iItem;

  if (listItems!=0) {
     prevsib=NULL;

     switch ((DWORD) ptdi->hInsertAfter) {
		case (DWORD) TVI_FIRST: 
			if (sibItem==wineItem) break;
			if (wineItem->parent) {
				wineItem->sibling=parentItem->firstChild;
				parentItem->firstChild=(HTREEITEM)iItem;
			} else {
				wineItem->sibling=infoPtr->TopRootItem;
				infoPtr->TopRootItem=(HTREEITEM)iItem;
			}
			sibItem->upsibling=(HTREEITEM)iItem;
			break;

		case (DWORD) TVI_SORT:  
  	  if (sibItem==wineItem) 
        /* 
         * This item is the first child of the level and it 
         * has already been inserted 
         */                
        break; 
      else
      {
        TREEVIEW_ITEM *aChild;
		  
  
        TREEVIEW_ITEM *previousChild = NULL;
        BOOL bItemInserted           = FALSE;

	    if (parentItem)
          aChild = &infoPtr->items[(INT)parentItem->firstChild];
		else 
          aChild = &infoPtr->items[(INT)infoPtr->TopRootItem];
  
        /* lookup the text if using LPSTR_TEXTCALLBACKs */
        if (wineItem->pszText==LPSTR_TEXTCALLBACKA) {
          TREEVIEW_SendDispInfoNotify (hwnd, wineItem, TVN_GETDISPINFOA, TVIF_TEXT);
        }
    
        /* Iterate the parent children to see where we fit in */
        while ( aChild != NULL )
        {
          INT comp;

          /* lookup the text if using LPSTR_TEXTCALLBACKs */
          if (aChild->pszText==LPSTR_TEXTCALLBACKA) {
            TREEVIEW_SendDispInfoNotify (hwnd, aChild, TVN_GETDISPINFOA, TVIF_TEXT);
	  }

          comp = strcmp(wineItem->pszText, aChild->pszText);
          if ( comp < 0 )  /* we are smaller than the current one */
          {
            TREEVIEW_InsertBefore(infoPtr, wineItem, aChild, parentItem);
            bItemInserted = TRUE;
            break;
          }
          else if ( comp > 0 )  /* we are bigger than the current one */
          {
            previousChild = aChild;
            aChild = (aChild->sibling == 0)  /* This will help us to exit   */
                        ? NULL               /* if there is no more sibling */
                        : &infoPtr->items[(INT)aChild->sibling];
  
            /* Look at the next item */
            continue;
          }
          else if ( comp == 0 )
          {
            /* 
             * An item with this name is already existing, therefore,  
             * we add after the one we found 
             */
            TREEVIEW_InsertAfter(infoPtr, wineItem, aChild, parentItem);
            bItemInserted = TRUE;
            break;
          }
        }
      
        /* 
         * we reach the end of the child list and the item as not
         * yet been inserted, therefore, insert it after the last child.
         */
        if ( (! bItemInserted ) && (aChild == NULL) )
          TREEVIEW_InsertAfter(infoPtr, wineItem, previousChild, parentItem);
  
        break;
      }


		case (DWORD) TVI_LAST:  
			if (sibItem==wineItem) break;
			while (sibItem->sibling) {
				prevsib=sibItem;
				sibItem=&infoPtr->items [(INT)sibItem->sibling];
			}
			sibItem->sibling=(HTREEITEM)iItem;
			wineItem->upsibling=sibItem->hItem;
			break;
		default:
                    {
                        TREEVIEW_ITEM  *localsibItem = sibItem;
			while ((localsibItem->sibling) && 
                               (localsibItem->hItem!=ptdi->hInsertAfter))
				{
				prevsib=localsibItem;
                localsibItem=&infoPtr->items [(INT)localsibItem->sibling];
              }
			if (localsibItem->hItem!=ptdi->hInsertAfter) {
			 WARN("tried to insert item after nonexisting handle %d treating as TVI_LAST.\n",
                      (INT) ptdi->hInsertAfter);
                       /* 
                        * retry placing it last 
                        */
			if (sibItem==wineItem) break;
			 while (sibItem->sibling) {
				 prevsib=sibItem;
				 sibItem=&infoPtr->items [(INT)sibItem->sibling];
			 }
			 sibItem->sibling=(HTREEITEM)iItem;
			 wineItem->upsibling=sibItem->hItem;
              		  break;
			}
			prevsib=localsibItem;
			if (localsibItem->sibling) {
            	localsibItem=&infoPtr->items [(INT)localsibItem->sibling];
				localsibItem->upsibling=(HTREEITEM)iItem;
				wineItem->sibling=localsibItem->hItem;
			}
			prevsib->sibling=(HTREEITEM)iItem;
			wineItem->upsibling=prevsib->hItem;
			break;
             }
   	}
   }	


/* Fill in info structure */

   TRACE("new item %d; parent %d, mask %x\n", iItem, 
			(INT)wineItem->parent,tvItem->mask);

   wineItem->mask=tvItem->mask;
   wineItem->iIntegral=1; 

   if (tvItem->mask & TVIF_CHILDREN) {
	 wineItem->cChildren=tvItem->cChildren;
	 if (tvItem->cChildren==I_CHILDRENCALLBACK) 
			FIXME(" I_CHILDRENCALLBACK not supported\n");
	}

  wineItem->expandBox.left   = 0; /* Initialize the expandBox */
  wineItem->expandBox.top    = 0;
  wineItem->expandBox.right  = 0;
  wineItem->expandBox.bottom = 0;

   if (tvItem->mask & TVIF_IMAGE) 
	wineItem->iImage=tvItem->iImage;

		/* If the application sets TVIF_INTEGRAL without
			supplying a TVITEMEX structure, it's toast */

   if (tvItem->mask & TVIF_INTEGRAL) 
   		wineItem->iIntegral=tvItem->iIntegral;   

   if (tvItem->mask & TVIF_SELECTEDIMAGE) 
	wineItem->iSelectedImage=tvItem->iSelectedImage;

   if (tvItem->mask & TVIF_STATE) {
     TRACE("item state: %x ->%x\n", wineItem->state, tvItem->state);
     TRACE("statemask: %x ->%x\n", wineItem->stateMask, tvItem->stateMask);
	wineItem->state=tvItem->state;
	wineItem->stateMask=tvItem->stateMask;
   }

   TREEVIEW_QueueRefresh (hwnd);

   return (LRESULT) iItem;
}


static LRESULT
TREEVIEW_InsertItemW(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TVINSERTSTRUCTW *tvisW;
    TVINSERTSTRUCTA tvisA;
    LRESULT lRes;

    tvisW = (LPTVINSERTSTRUCTW)lParam;

    tvisA.hParent = tvisW->hParent;
    tvisA.hInsertAfter = tvisW->hInsertAfter;

    tvisA.DUMMYUNIONNAME.item.mask           = tvisW->DUMMYUNIONNAME.item.mask;
    tvisA.DUMMYUNIONNAME.item.hItem          = tvisW->DUMMYUNIONNAME.item.hItem;
    tvisA.DUMMYUNIONNAME.item.state          = tvisW->DUMMYUNIONNAME.item.state;
    tvisA.DUMMYUNIONNAME.item.stateMask      = tvisW->DUMMYUNIONNAME.item.stateMask;
    tvisA.DUMMYUNIONNAME.item.cchTextMax     = tvisW->DUMMYUNIONNAME.item.cchTextMax;

    if(tvisW->DUMMYUNIONNAME.item.pszText)
    {
	if (tvisW->DUMMYUNIONNAME.item.pszText!=LPSTR_TEXTCALLBACKW) 
	{ 
	    int len = lstrlenW (tvisW->DUMMYUNIONNAME.item.pszText)+1;
	    tvisA.DUMMYUNIONNAME.item.pszText = COMCTL32_Alloc (len);
	    lstrcpyWtoA (tvisA.DUMMYUNIONNAME.item.pszText,
			 tvisW->DUMMYUNIONNAME.item.pszText );
	}
	else 
	{
	    tvisA.DUMMYUNIONNAME.item.pszText = LPSTR_TEXTCALLBACKA;
	    tvisA.DUMMYUNIONNAME.item.cchTextMax = 0;
	}
    }

    tvisA.DUMMYUNIONNAME.item.iImage         = tvisW->DUMMYUNIONNAME.item.iImage;
    tvisA.DUMMYUNIONNAME.item.iSelectedImage = tvisW->DUMMYUNIONNAME.item.iSelectedImage;
    tvisA.DUMMYUNIONNAME.item.cChildren      = tvisW->DUMMYUNIONNAME.item.cChildren;
    tvisA.DUMMYUNIONNAME.item.lParam         = tvisW->DUMMYUNIONNAME.item.lParam;

    lRes = TREEVIEW_InsertItemA(hwnd,wParam,(LPARAM)&tvisA);

    if (tvisA.DUMMYUNIONNAME.item.pszText!=LPSTR_TEXTCALLBACKA) 
    {
	COMCTL32_Free(tvisA.DUMMYUNIONNAME.item.pszText);
    }

    return lRes;

}


static LRESULT
TREEVIEW_DeleteItem (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
  INT iItem;
  TREEVIEW_ITEM *wineItem;

  TRACE("item = %08lx\n", lParam);

  if (lParam == (INT)TVI_ROOT) {
	TREEVIEW_RemoveTree (hwnd);
  } else {
  	iItem= (INT) lParam;
  	wineItem = TREEVIEW_ValidItem (infoPtr, (HTREEITEM)iItem);
  	if (!wineItem) return FALSE;

        if (wineItem->pszText==LPSTR_TEXTCALLBACKA)
           TRACE("LPSTR_TEXTCALLBACK\n");
	else
           TRACE("%s\n",wineItem->pszText);
	TREEVIEW_RemoveItem (hwnd, wineItem);
  }

  TREEVIEW_QueueRefresh (hwnd);

  return TRUE;
}



static LRESULT
TREEVIEW_GetIndent (HWND hwnd)
{
 TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);

 TRACE("\n");
 return infoPtr->uIndent;
}

static LRESULT
TREEVIEW_SetIndent (HWND hwnd, WPARAM wParam)
{
  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
  INT newIndent;
   
  TRACE("\n");
  newIndent=(INT) wParam;
  if (newIndent < MINIMUM_INDENT) newIndent=MINIMUM_INDENT;
  infoPtr->uIndent=newIndent;
  
  return 0;
}

static LRESULT
TREEVIEW_GetToolTips (HWND hwnd)

{
 TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);

 TRACE("\n");
 return infoPtr->hwndToolTip;
}


static LRESULT
TREEVIEW_SetToolTips (HWND hwnd, WPARAM wParam)

{
 TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
 HWND prevToolTip;

 TRACE("\n");
 prevToolTip=infoPtr->hwndToolTip;
 infoPtr->hwndToolTip= (HWND) wParam;

 return prevToolTip;
}


static LRESULT CALLBACK
TREEVIEW_GetEditControl (HWND hwnd)

{
 TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);

 return infoPtr->hwndEdit;
}

LRESULT CALLBACK
TREEVIEW_Edit_SubclassProc (HWND hwnd, UINT uMsg, WPARAM wParam, 
							LPARAM lParam)
{
  switch (uMsg) 
  {
    case WM_ERASEBKGND: 
    {
      RECT rc;
      HDC  hdc = (HDC) wParam;
      GetClientRect (hwnd, &rc);
      Rectangle (hdc, rc.left, rc.top, rc.right, rc.bottom);
      return -1;
    }

    case WM_GETDLGCODE:
    {
      return DLGC_WANTARROWS | DLGC_WANTALLKEYS;
    }

    case WM_KEYDOWN:
        if (wParam == VK_ESCAPE)
{
            TREEVIEW_EndEditLabelNow(GetParent(hwnd), (WPARAM)TRUE, 0); 
            return 1;
}
        else if (wParam == VK_RETURN)
            TREEVIEW_EndEditLabelNow(GetParent(hwnd), (WPARAM)FALSE, 0); 
    break; 



    default:
    {
      TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(GetParent(hwnd));
	  if (infoPtr!=NULL)
       return CallWindowProcA (infoPtr->wpEditOrig, hwnd, uMsg, wParam, lParam);
	  else 
		break;
		
    }
  }

  return 0;
}


/* should handle edit control messages here */

static LRESULT
TREEVIEW_Command (HWND hwnd, WPARAM wParam, LPARAM lParam)

{
  TRACE("%x %ld\n",wParam, lParam);
 
  switch (HIWORD(wParam)) 
  {
		case EN_UPDATE:
    {
      /* 
       * Adjust the edit window size 
       */
      TREEVIEW_INFO *infoPtr  = TREEVIEW_GetInfoPtr(hwnd);
      TREEVIEW_ITEM *editItem = TREEVIEW_ValidItem(infoPtr, infoPtr->editItem);
      INT           iLength   = GetWindowTextLengthA(infoPtr->hwndEdit);
      HDC           hdc       = GetDC(infoPtr->hwndEdit);
      TEXTMETRICA   tm;

      if ( GetTextMetricsA(hdc, &tm) )
      {
        LONG newWidth = (iLength * tm.tmAveCharWidth) + 15;
            
    		SetWindowPos ( 
          infoPtr->hwndEdit,
          HWND_TOP, 
          editItem->text.left - 2, 
          editItem->text.top  - 1,
          newWidth,
          editItem->text.bottom - editItem->text.top  + 3,
          SWP_DRAWFRAME );
      }
      ReleaseDC(hwnd, hdc);

      break;
    }

    case EN_KILLFOCUS:
/*      TREEVIEW_EndEditLabelNow(hwnd, (WPARAM)FALSE, 0); 
*/
      break;

    default:
      return SendMessageA (GetParent (hwnd), WM_COMMAND, wParam, lParam);
  }

  return 0;
}

static LRESULT
TREEVIEW_Size (HWND hwnd, WPARAM wParam, LPARAM lParam)

{
  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);

  if (infoPtr->bAutoSize) 
  {
    infoPtr->bAutoSize = FALSE;
    return 0;
  }
  infoPtr->bAutoSize = TRUE;

  if (wParam == SIZE_RESTORED)  
  {
    infoPtr->uTotalWidth  = LOWORD (lParam);
  	infoPtr->uTotalHeight = HIWORD (lParam);
  } else {
  	FIXME("WM_SIZE flag %x %lx not handled\n", wParam, lParam);
  }

  TREEVIEW_QueueRefresh (hwnd);
  return 0;
}



static LRESULT
TREEVIEW_StyleChanged (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  TRACE("(%x %lx)\n",wParam,lParam);

  InvalidateRect(hwnd, NULL, FALSE);  

  return 0;
}

static LRESULT
TREEVIEW_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TREEVIEW_INFO *infoPtr;
	DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
 	LOGFONTA logFont;
    TEXTMETRICA tm;
	HDC hdc;
  
    TRACE("wnd %x, style %lx\n",hwnd,dwStyle);
      /* allocate memory for info structure */
    infoPtr = (TREEVIEW_INFO *) COMCTL32_Alloc (sizeof(TREEVIEW_INFO));

    SetWindowLongA( hwnd, 0, (DWORD)infoPtr);

    if (infoPtr == NULL) {
		ERR("could not allocate info memory!\n");
		return 0;
    }

    if ((TREEVIEW_INFO*) GetWindowLongA( hwnd, 0) != infoPtr) {
		ERR("pointer assignment error!\n");
		return 0;
    }

	hdc=GetDC (hwnd);

    /* set default settings */
    infoPtr->uInternalStatus=0;
    infoPtr->uNumItems=0;
    infoPtr->clrBk   = GetSysColor (COLOR_WINDOW);
    infoPtr->clrText = GetSysColor (COLOR_WINDOWTEXT);
    infoPtr->clrLine = GetSysColor (COLOR_WINDOWTEXT);
    infoPtr->clrInsertMark = GetSysColor (COLOR_BTNTEXT);
    infoPtr->cy = 0;
    infoPtr->cx = 0;
    infoPtr->uIndent = 15;
    infoPtr->himlNormal = NULL;
    infoPtr->himlState = NULL;
	infoPtr->uItemHeight = -1;
    GetTextMetricsA (hdc, &tm);
    infoPtr->hFont = GetStockObject (DEFAULT_GUI_FONT);
	GetObjectA (infoPtr->hFont, sizeof (LOGFONTA), &logFont);
	logFont.lfWeight=FW_BOLD;
    infoPtr->hBoldFont = CreateFontIndirectA (&logFont);
    
    infoPtr->items = NULL;
    infoPtr->selectedItem=0;
    infoPtr->clrText=-1;	/* use system color */
    infoPtr->dropItem=0;
	infoPtr->insertMarkItem=0;
	infoPtr->insertBeforeorAfter=0;
    infoPtr->pCallBackSort=NULL;
    infoPtr->uScrollTime = 300;  /* milliseconds */
	infoPtr->wpEditOrig = NULL; /* we haven't subclassed anything yet */

	infoPtr->hwndToolTip=0;
    if (!(dwStyle & TVS_NOTOOLTIPS)) {   /* Create tooltip control */
		TTTOOLINFOA ti;

		infoPtr->hwndToolTip =  
			CreateWindowExA (0, TOOLTIPS_CLASSA, NULL, 0,
                   CW_USEDEFAULT, CW_USEDEFAULT,
                   CW_USEDEFAULT, CW_USEDEFAULT,
                   hwnd, 0, 0, 0);

        /* Send NM_TOOLTIPSCREATED notification */
        if (infoPtr->hwndToolTip) {
            NMTOOLTIPSCREATED nmttc;

            nmttc.hdr.hwndFrom = hwnd;
            nmttc.hdr.idFrom =  GetWindowLongA( hwnd, GWL_ID);
            nmttc.hdr.code = NM_TOOLTIPSCREATED;
            nmttc.hwndToolTips = infoPtr->hwndToolTip;

            SendMessageA (GetParent (hwnd), WM_NOTIFY,
                (WPARAM) GetWindowLongA( hwnd, GWL_ID), (LPARAM)&nmttc);
        }

		ZeroMemory (&ti, sizeof(TTTOOLINFOA));
        ti.cbSize   = sizeof(TTTOOLINFOA);
        ti.uFlags   = TTF_IDISHWND | TTF_TRACK | TTF_TRANSPARENT ;
        ti.hwnd     = hwnd;
        ti.uId      = 0;
        ti.lpszText = "Test"; /* LPSTR_TEXTCALLBACK; */
        SetRectEmpty (&ti.rect);

        SendMessageA (infoPtr->hwndToolTip, TTM_ADDTOOLA, 0, (LPARAM)&ti);
    }

 	infoPtr->hwndEdit = CreateWindowExA ( 
                          WS_EX_LEFT, 
                          "EDIT",
                          0,
                          WS_CHILD | WS_BORDER | ES_AUTOHSCROLL | 
                          ES_WANTRETURN | ES_LEFT,
                          0, 0, 0, 0,
                          hwnd, 
                          0,0,0); /* FIXME: (HMENU)IDTVEDIT,pcs->hInstance,0);*/

  SendMessageA ( infoPtr->hwndEdit, WM_SETFONT, infoPtr->hFont, FALSE);
	infoPtr->wpEditOrig = (WNDPROC)SetWindowLongA (
                                    infoPtr->hwndEdit,
                                    GWL_WNDPROC, 
                           					(LONG) TREEVIEW_Edit_SubclassProc);

  if (dwStyle & TVS_CHECKBOXES) {	
		HBITMAP hbmLoad;
		int nIndex;

		infoPtr->himlState = 
             ImageList_Create (16, 16,ILC_COLOR|ILC_MASK, 15, 1);

		hbmLoad = LoadBitmapA (COMCTL32_hModule, MAKEINTRESOURCEA(IDT_CHECK));
		TRACE ("%x\n",hbmLoad);
        nIndex = ImageList_AddMasked (infoPtr->himlState, hbmLoad, CLR_DEFAULT);
		TRACE ("%d\n",nIndex);
		DeleteObject (hbmLoad);
	}
  ReleaseDC (hwnd, hdc);
  return 0;
}



static LRESULT 
TREEVIEW_Destroy (HWND hwnd) 
{
  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
     
  TRACE("\n");
  TREEVIEW_RemoveTree (hwnd);
  SetWindowLongA (hwnd, 0, (DWORD)NULL);

  if (infoPtr->Timer & TV_REFRESH_TIMER_SET) 
        KillTimer (hwnd, TV_REFRESH_TIMER);
  if (infoPtr->hwndToolTip) 
		DestroyWindow (infoPtr->hwndToolTip);

  COMCTL32_Free (infoPtr);
  return 0;
}


static LRESULT
TREEVIEW_Paint (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  HDC hdc;
  PAINTSTRUCT ps;

  TRACE("\n");
  hdc = wParam==0 ? BeginPaint (hwnd, &ps) : (HDC)wParam;
  TREEVIEW_Refresh (hwnd, hdc);
  if(!wParam) EndPaint (hwnd, &ps);
  TRACE("done\n");
      
  return 0;
}

static LRESULT
TREEVIEW_SetFocus (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
   TREEVIEW_SendSimpleNotify (hwnd, NM_SETFOCUS);
   InvalidateRect(hwnd, NULL, FALSE);
   return 0;
}

static LRESULT
TREEVIEW_KillFocus (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
   TREEVIEW_SendSimpleNotify (hwnd, NM_KILLFOCUS);
   InvalidateRect(hwnd, NULL, FALSE);
   return 0;
}

static LRESULT
TREEVIEW_EraseBackground (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
    HBRUSH hBrush = CreateSolidBrush (infoPtr->clrBk);
    RECT rect;

    TRACE("\n");
    GetClientRect (hwnd, &rect);
    FillRect ((HDC)wParam, &rect, hBrush);
    DeleteObject (hBrush);
    return TRUE;
}





  
/* Notifications */

  



static BOOL
TREEVIEW_SendSimpleNotify (HWND hwnd, UINT code)
{
    NMHDR nmhdr;

    TRACE("%x\n",code);
    nmhdr.hwndFrom = hwnd;
    nmhdr.idFrom   = GetWindowLongA( hwnd, GWL_ID);
    nmhdr.code     = code;

    return (BOOL) SendMessageA (GetParent (hwnd), WM_NOTIFY,
                                   (WPARAM)nmhdr.idFrom, (LPARAM)&nmhdr);
}



static BOOL
TREEVIEW_SendTreeviewNotify (HWND hwnd, UINT code, UINT action, 
			HTREEITEM oldItem, HTREEITEM newItem)

{
  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
  NMTREEVIEWA nmhdr;
  TREEVIEW_ITEM  *wineItem;

  TRACE("code:%x action:%x olditem:%x newitem:%x\n",
		  code,action,(INT)oldItem,(INT)newItem);
  nmhdr.hdr.hwndFrom = hwnd;
  nmhdr.hdr.idFrom =  GetWindowLongA( hwnd, GWL_ID);
  nmhdr.hdr.code = code;
  nmhdr.action = action;
  if (oldItem) {
  	wineItem=& infoPtr->items[(INT)oldItem];
  	nmhdr.itemOld.mask 		= wineItem->mask;
  	nmhdr.itemOld.hItem		= wineItem->hItem;
  	nmhdr.itemOld.state		= wineItem->state;
  	nmhdr.itemOld.stateMask	= wineItem->stateMask;
  	nmhdr.itemOld.iImage 	= wineItem->iImage;
  	nmhdr.itemOld.pszText 	= wineItem->pszText;
  	nmhdr.itemOld.cchTextMax= wineItem->cchTextMax;
  	nmhdr.itemOld.iImage 	= wineItem->iImage;
  	nmhdr.itemOld.iSelectedImage 	= wineItem->iSelectedImage;
  	nmhdr.itemOld.cChildren = wineItem->cChildren;
  	nmhdr.itemOld.lParam	= wineItem->lParam;
  }

  if (newItem) {
  	wineItem=& infoPtr->items[(INT)newItem];
  	nmhdr.itemNew.mask 		= wineItem->mask;
  	nmhdr.itemNew.hItem		= wineItem->hItem;
  	nmhdr.itemNew.state		= wineItem->state;
  	nmhdr.itemNew.stateMask	= wineItem->stateMask;
  	nmhdr.itemNew.iImage 	= wineItem->iImage;
  	nmhdr.itemNew.pszText 	= wineItem->pszText;
  	nmhdr.itemNew.cchTextMax= wineItem->cchTextMax;
  	nmhdr.itemNew.iImage 	= wineItem->iImage;
  	nmhdr.itemNew.iSelectedImage 	= wineItem->iSelectedImage;
  	nmhdr.itemNew.cChildren = wineItem->cChildren;
  	nmhdr.itemNew.lParam	= wineItem->lParam;
  }

  nmhdr.ptDrag.x = 0;
  nmhdr.ptDrag.y = 0;

  return (BOOL)SendMessageA (GetParent (hwnd), WM_NOTIFY,
                                   (WPARAM) GetWindowLongA( hwnd, GWL_ID), (LPARAM)&nmhdr);

}

static BOOL
TREEVIEW_SendTreeviewDnDNotify (HWND hwnd, UINT code, HTREEITEM dragItem, 
								POINT pt)
{
  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
  NMTREEVIEWA nmhdr;
  TREEVIEW_ITEM  *wineItem;

  TRACE("code:%x dragitem:%x\n", code,(INT)dragItem);

  nmhdr.hdr.hwndFrom = hwnd;
  nmhdr.hdr.idFrom =  GetWindowLongA( hwnd, GWL_ID);
  nmhdr.hdr.code = code;
  nmhdr.action = 0;
  wineItem=& infoPtr->items[(INT)dragItem];
  nmhdr.itemNew.mask 	= wineItem->mask;
  nmhdr.itemNew.hItem	= wineItem->hItem;
  nmhdr.itemNew.state	= wineItem->state;
  nmhdr.itemNew.lParam	= wineItem->lParam;

  nmhdr.ptDrag.x = pt.x;
  nmhdr.ptDrag.y = pt.y;

  return (BOOL)SendMessageA (GetParent (hwnd), WM_NOTIFY,
                                   (WPARAM) GetWindowLongA( hwnd, GWL_ID), (LPARAM)&nmhdr);

}



static BOOL
TREEVIEW_SendDispInfoNotify (HWND hwnd, TREEVIEW_ITEM *wineItem, 
								UINT code, UINT what)
{
  NMTVDISPINFOA tvdi;
  BOOL retval;
  char *buf;

  TRACE("item %d, action %x, state %d\n",
    (INT)wineItem->hItem,
    what,
    (INT)wineItem->state);

  tvdi.hdr.hwndFrom	= hwnd;
  tvdi.hdr.idFrom	=  GetWindowLongA( hwnd, GWL_ID);
  tvdi.hdr.code		= code;
  tvdi.item.mask	= what;
  tvdi.item.hItem	= wineItem->hItem;
  tvdi.item.state	= wineItem->state;
  tvdi.item.lParam	= wineItem->lParam;
  tvdi.item.pszText = COMCTL32_Alloc (128*sizeof(char));
  tvdi.item.cchTextMax  = 128;
  buf = tvdi.item.pszText;

  retval=(BOOL)SendMessageA (
                  GetParent(hwnd), 
                  WM_NOTIFY,
                  (WPARAM)tvdi.hdr.idFrom, 
                  (LPARAM)&tvdi);

  if (what & TVIF_TEXT) {
		wineItem->pszText        = tvdi.item.pszText;
		if (buf==tvdi.item.pszText) {
			wineItem->cchTextMax = 128;
		} else { 
			TRACE("user-supplied buffer\n");
			COMCTL32_Free (buf);
			wineItem->cchTextMax = 0;
		}
	}
  if (what & TVIF_SELECTEDIMAGE) 
		wineItem->iSelectedImage = tvdi.item.iSelectedImage;
  if (what & TVIF_IMAGE) 
		wineItem->iImage         = tvdi.item.iImage;
  if (what & TVIF_CHILDREN) 
		wineItem->cChildren      = tvdi.item.cChildren;

 return retval;
}



static BOOL
TREEVIEW_SendCustomDrawNotify (HWND hwnd, DWORD dwDrawStage, HDC hdc,
			RECT rc)
{
  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
  NMTVCUSTOMDRAW nmcdhdr;
  LPNMCUSTOMDRAW nmcd;

  TRACE("drawstage:%lx hdc:%x\n", dwDrawStage, hdc);

  nmcd= & nmcdhdr.nmcd;
  nmcd->hdr.hwndFrom = hwnd;
  nmcd->hdr.idFrom =  GetWindowLongA( hwnd, GWL_ID);
  nmcd->hdr.code   = NM_CUSTOMDRAW;
  nmcd->dwDrawStage= dwDrawStage;
  nmcd->hdc		   = hdc;
  nmcd->rc.left    = rc.left;
  nmcd->rc.right   = rc.right;
  nmcd->rc.bottom  = rc.bottom;
  nmcd->rc.top     = rc.top;
  nmcd->dwItemSpec = 0;
  nmcd->uItemState = 0;
  nmcd->lItemlParam= 0;
  nmcdhdr.clrText  = infoPtr->clrText;
  nmcdhdr.clrTextBk= infoPtr->clrBk;
  nmcdhdr.iLevel   = 0;

  return (BOOL)SendMessageA (GetParent (hwnd), WM_NOTIFY,
                               (WPARAM) GetWindowLongA( hwnd, GWL_ID), (LPARAM)&nmcdhdr);

}



/* FIXME: need to find out when the flags in uItemState need to be set */

static BOOL
TREEVIEW_SendCustomDrawItemNotify (HWND hwnd, HDC hdc,
  			TREEVIEW_ITEM *wineItem, UINT uItemDrawState)
{
 TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
 NMTVCUSTOMDRAW nmcdhdr;
 LPNMCUSTOMDRAW nmcd;
 DWORD dwDrawStage,dwItemSpec;
 UINT uItemState;
 INT retval;
 
 dwDrawStage=CDDS_ITEM | uItemDrawState;
 dwItemSpec=(DWORD)wineItem->hItem;
 uItemState=0;
 if (wineItem->hItem==infoPtr->selectedItem) uItemState|=CDIS_SELECTED;
 if (wineItem->hItem==infoPtr->focusItem)	 uItemState|=CDIS_FOCUS;
 if (wineItem->hItem==infoPtr->hotItem)      uItemState|=CDIS_HOT;

 nmcd= & nmcdhdr.nmcd;
 nmcd->hdr.hwndFrom = hwnd;
 nmcd->hdr.idFrom =  GetWindowLongA( hwnd, GWL_ID);
 nmcd->hdr.code   = NM_CUSTOMDRAW;
 nmcd->dwDrawStage= dwDrawStage;
 nmcd->hdc		  = hdc;
 nmcd->rc.left    = wineItem->rect.left;
 nmcd->rc.right   = wineItem->rect.right;
 nmcd->rc.bottom  = wineItem->rect.bottom;
 nmcd->rc.top     = wineItem->rect.top;
 nmcd->dwItemSpec = dwItemSpec;
 nmcd->uItemState = uItemState;
 nmcd->lItemlParam= wineItem->lParam;
 nmcdhdr.clrText  = infoPtr->clrText;
 nmcdhdr.clrTextBk= infoPtr->clrBk;
 nmcdhdr.iLevel   = wineItem->iLevel;

 TRACE("drawstage:%lx hdc:%x item:%lx, itemstate:%x, lItemlParam:%lx\n",
		  nmcd->dwDrawStage, nmcd->hdc, nmcd->dwItemSpec, 
          nmcd->uItemState, nmcd->lItemlParam);

 retval=SendMessageA (GetParent (hwnd), WM_NOTIFY,
                 (WPARAM) GetWindowLongA( hwnd, GWL_ID), (LPARAM)&nmcdhdr);

 infoPtr->clrText=nmcdhdr.clrText;
 infoPtr->clrBk  =nmcdhdr.clrTextBk;
 return (BOOL) retval;
}



/* Note:If the specified item is the child of a collapsed parent item,
   the parent's list of child items is (recursively) expanded to reveal the 
   specified item. This is mentioned for TREEVIEW_SelectItem; don't 
   know if it also applies here.
*/

static LRESULT
TREEVIEW_Expand (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
  TREEVIEW_ITEM *wineItem;
  UINT flag;
  INT expand;
  
  flag = (UINT) wParam;
  expand = (INT) lParam;

  wineItem = TREEVIEW_ValidItem (infoPtr, (HTREEITEM)expand);

  if (!wineItem) 
    return 0;
  if (!wineItem->cChildren) 
    return 0;

	if (wineItem->pszText==LPSTR_TEXTCALLBACKA) 
		TRACE ("For item %d, flags %d, state %d\n",
				expand, flag, wineItem->state);
	else
  		TRACE("For (%s) item:%d, flags %x, state:%d\n", 
                wineItem->pszText, flag, expand, wineItem->state);

  if (wineItem->cChildren==I_CHILDRENCALLBACK) {
    FIXME("we don't handle I_CHILDRENCALLBACK yet\n");
    return 0;
  }

  if (flag == TVE_TOGGLE) {    /* FIXME: check exact behaviour here */
   flag &= ~TVE_TOGGLE;    /* ie: bitwise ops or 'case' ops */
   if (wineItem->state & TVIS_EXPANDED) 
     flag |= TVE_COLLAPSE;
   else
     flag |= TVE_EXPAND;
  }

  switch (flag) 
  {
    case TVE_COLLAPSERESET: 
      TRACE("  case TVE_COLLAPSERESET\n");
      if (!wineItem->state & TVIS_EXPANDED) 
        return 0;

       wineItem->state &= ~(TVIS_EXPANDEDONCE | TVIS_EXPANDED);
       TREEVIEW_RemoveAllChildren (hwnd, wineItem);
       break;

    case TVE_COLLAPSE: 
      TRACE("  case TVE_COLLAPSE\n");
      if (!wineItem->state & TVIS_EXPANDED) 
        return 0;

      wineItem->state &= ~TVIS_EXPANDED;
      break;

    case TVE_EXPAND: 
      TRACE("  case TVE_EXPAND\n");
      if (wineItem->state & TVIS_EXPANDED) 
        return 0;

      TRACE("  is not expanded...\n");
     
      if (!(wineItem->state & TVIS_EXPANDEDONCE))  
      { 
        TRACE("  and has never been expanded...\n");
        wineItem->state |= TVIS_EXPANDED;

        /* this item has never been expanded */
        if (TREEVIEW_SendTreeviewNotify (
              hwnd, 
              TVN_ITEMEXPANDINGA, 
              TVE_EXPAND, 
              0, 
              (HTREEITEM)expand))
        {
          TRACE("  TVN_ITEMEXPANDINGA returned TRUE, exiting...\n");
          return FALSE;   
        }

        /* FIXME
         * Since the TVN_ITEMEXPANDINGA message may has caused the parent to
         * insert new items which in turn may have cause items placeholder 
         * reallocation, I reassign the current item pointer so we have 
         * something valid to work with... 
         * However, this should not be necessary, 
         * investigation required in TREEVIEW_InsertItemA
         */
        wineItem = TREEVIEW_ValidItem (infoPtr, (HTREEITEM)expand);
        if (! wineItem) 
        { 
          ERR(
            "Catastropic situation, cannot retreive item #%d\n",
            expand);
          return FALSE;
        }

        wineItem->state |= TVIS_EXPANDEDONCE;
        TRACE("  TVN_ITEMEXPANDINGA sent...\n");

        TREEVIEW_SendTreeviewNotify (
          hwnd, 
          TVN_ITEMEXPANDEDA, 
          TVE_EXPAND, 
          0, 
          (HTREEITEM)expand);

        TRACE("  TVN_ITEMEXPANDEDA sent...\n");

      }
      else
      {
        /* this item has already been expanded */
        wineItem->state |= TVIS_EXPANDED;
      }
      break;

    case TVE_EXPANDPARTIAL:
      TRACE("  case TVE_EXPANDPARTIAL\n");
      FIXME("TVE_EXPANDPARTIAL not implemented\n");
      wineItem->state ^=TVIS_EXPANDED;
      wineItem->state |=TVIS_EXPANDEDONCE;
      break;
  }

  TRACE("Exiting, Item %d state is now %d...\n", 
    expand, 
    wineItem->state);
  
  TREEVIEW_QueueRefresh (hwnd);
  return TRUE;
}



static TREEVIEW_ITEM *
TREEVIEW_HitTestPoint (HWND hwnd, POINT pt)
{
 TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
 TREEVIEW_ITEM *wineItem;
 RECT rect;

 GetClientRect (hwnd, &rect);

 if (!infoPtr->firstVisible) return NULL;

 wineItem=&infoPtr->items [(INT)infoPtr->firstVisible];

 while ((wineItem!=NULL) && (pt.y > wineItem->rect.bottom))
       wineItem=TREEVIEW_GetNextListItem (infoPtr,wineItem);
	
 if (!wineItem) 
	return NULL;

 return wineItem;
}




static LRESULT
TREEVIEW_HitTest (HWND hwnd, LPARAM lParam)
{
  LPTVHITTESTINFO lpht=(LPTVHITTESTINFO) lParam;
  TREEVIEW_ITEM *wineItem;
  RECT rect;
  UINT status,x,y;

  GetClientRect (hwnd, &rect);
  status=0;
  x=lpht->pt.x;
  y=lpht->pt.y;
  if (x < rect.left)  status|=TVHT_TOLEFT;
  if (x > rect.right) status|=TVHT_TORIGHT;
  if (y < rect.top )  status|=TVHT_ABOVE;
  if (y > rect.bottom) status|=TVHT_BELOW;

  if (status) {
    lpht->flags=status;
    return 0;
  }

  wineItem=TREEVIEW_HitTestPoint (hwnd, lpht->pt);
  if (!wineItem) {  
    lpht->flags=TVHT_NOWHERE;
    return 0;
  }

  lpht->flags=0;

  if (x < wineItem->expandBox.left) {
    lpht->flags |= TVHT_ONITEMINDENT;
	goto done;
  } 
  if ( PtInRect ( &wineItem->expandBox, lpht->pt)) {
    lpht->flags |= TVHT_ONITEMBUTTON;
	goto done;
  }
  if ( PtInRect ( &wineItem->bitmap, lpht->pt)) {
	lpht->flags |= TVHT_ONITEMICON;
    goto done;
  }
  if ( PtInRect ( &wineItem->statebitmap, lpht->pt)) {
	lpht->flags |= TVHT_ONITEMSTATEICON;
    goto done;
  }
  if ( PtInRect ( &wineItem->text, lpht->pt)) {
    lpht->flags |= TVHT_ONITEMLABEL;    
	goto done;
  } 
  
  lpht->flags|=TVHT_ONITEMRIGHT;
 

done:
  lpht->hItem=wineItem->hItem;
  TRACE ("(%ld,%ld):result %x\n",lpht->pt.x,lpht->pt.y,lpht->flags);

  return (LRESULT) wineItem->hItem;
}

static LRESULT
TREEVIEW_EditLabelA (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  TREEVIEW_INFO *infoPtr      = TREEVIEW_GetInfoPtr(hwnd);
  TREEVIEW_ITEM *wineItem;

  /*
   * If the style allow editing...
   */
  if ( GetWindowLongA( hwnd, GWL_STYLE) & TVS_EDITLABELS )
  {

    if ( infoPtr->editItem == 0 ) /* If we are not curently editing */
    {
      wineItem = TREEVIEW_ValidItem(infoPtr,(HTREEITEM) lParam);
      if ( wineItem == NULL )
        {
        ERR("Cannot get valid TREEVIEW_ITEM for lParam\n");
        return 0;
        }

      TRACE("Edit started for %s.\n", wineItem->pszText);
      infoPtr->editItem = wineItem->hItem;


      /*
       * It is common practice for a windows program to get this
       * edit control and then subclass it. It is assumed that a
       * new edit control is given every time.
       *
       * As a result some programs really mess up the edit control
       * so we need to destory our old edit control and create a new
       * one. Recycling would be nice but we would need to reset
       * everything. So recreating may just be easyier
       *
       */
	  DestroyWindow(infoPtr->hwndEdit);
 	  infoPtr->hwndEdit = CreateWindowExA (
                          WS_EX_LEFT,
                          "EDIT",
                          0,
                          WS_CHILD | WS_BORDER | ES_AUTOHSCROLL |
                          ES_WANTRETURN | ES_LEFT,
                          0, 0, 0, 0,
                          hwnd,
                          0,0,0); /* FIXME: (HMENU)IDTVEDIT,pcs->hInstance,0);*/

 	  SetWindowLongA (
      infoPtr->hwndEdit,
      GWL_WNDPROC,
      (LONG) TREEVIEW_Edit_SubclassProc);


      SendMessageA ( infoPtr->hwndEdit, WM_SETFONT, infoPtr->hFont, FALSE);

      SetWindowTextA( infoPtr->hwndEdit, wineItem->pszText );
      SendMessageA  ( infoPtr->hwndEdit, EM_SETSEL, 0, -1 );

      /*
      ** NOTE: this must be after the edit control is created
      ** (according to TVN_BEGINLABELEDITA docs), before position is set.
      */
      if ( TREEVIEW_SendDispInfoNotify(  /* Return true to cancel edition */
              hwnd,
              wineItem,
              TVN_BEGINLABELEDITA,
              0))
      {
        /*
        ** FIXME: Is this right, should we return a handle even though edit was cancelled?
        */
        TRACE("Edit cancelled by TVN_BEGINLABELEDITA for %s.\n", wineItem->pszText);

        TREEVIEW_EndEditLabelNow(hwnd, (WPARAM)TRUE, 0);

        return 0;
      }

      SetWindowPos (
        infoPtr->hwndEdit,
        HWND_TOP,
        wineItem->text.left - 2,
        wineItem->text.top  - 1,
        wineItem->text.right  - wineItem->text.left + 20 ,
        wineItem->text.bottom - wineItem->text.top  + 3,
        SWP_DRAWFRAME );

      SetFocus      ( infoPtr->hwndEdit);
      ShowWindow    ( infoPtr->hwndEdit, SW_SHOW);
    }
  }
  else
  {
  /*
  ** return NULL since we cannot edit this.
  */

    return 0;
  }

  return infoPtr->hwndEdit;
}

static LRESULT
TREEVIEW_EndEditLabelNow (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  TREEVIEW_INFO *infoPtr    = TREEVIEW_GetInfoPtr(hwnd);
  TREEVIEW_ITEM *editedItem = TREEVIEW_ValidItem (infoPtr, infoPtr->editItem);
  BOOL          bRevert     = (BOOL)wParam;
  NMTVDISPINFOA tvdi;
  RECT          itemRect;
  LPSTR         oldText;
  LPSTR         newText;
  int           iLength;

  /*
  ** NOTE: we have to get the new text before calling TVN_ENDLABELEDITA
  ** since some apps(eg regedit, win98) validate the text in TVN_ENDLABELEDITA.
  */

  oldText = editedItem->pszText;

  if ( !bRevert ) /* wParam is set to true to cancel the edition */
  {

    iLength = GetWindowTextLengthA( infoPtr->hwndEdit );
    if (iLength == 0)
    {
      WARN("Zero length string for new label(not changing).");
      bRevert=TRUE;
    }

    newText = COMCTL32_Alloc( iLength+1 );
    if( newText == NULL )
      {
      ERR("OutOfMemory, cannot allocate space for label");
      return FALSE;
      }
    GetWindowTextA( infoPtr->hwndEdit, newText, iLength+1);
  }
  else
  {
  newText=NULL;
  }


  /*
  * notify our parent with the new string(or NULL if wParam==TRUE)
  */
  tvdi.hdr.hwndFrom	= hwnd;
  tvdi.hdr.idFrom	= GetWindowLongA( hwnd, GWL_ID);
  tvdi.hdr.code     = TVN_ENDLABELEDITA;
  tvdi.item.hItem 	= editedItem->hItem;
  tvdi.item.lParam 	= editedItem->lParam;
  tvdi.item.mask	= TVIF_TEXT|TVIF_HANDLE|TVIF_PARAM;
  tvdi.item.pszText	= newText;

  if(!SendMessageA (                /* return false to cancel edition */
              GetParent(hwnd),
              WM_NOTIFY,
              (WPARAM)tvdi.hdr.idFrom,
              (LPARAM)&tvdi))
  {
  if( newText == NULL )  /*we are supposed to ignore the return if (and pszText==NULL), MSDOCs */
    bRevert=TRUE;
  }

  if (oldText != LPSTR_TEXTCALLBACKA)
  {

    if( bRevert )
    {
    if( newText != NULL )
      COMCTL32_Free(newText);

    editedItem->pszText=oldText; /* revert back to the old label */
    }
    else
    {
    COMCTL32_Free(oldText);

    editedItem->pszText=newText; /* use the new label */
    }
  }
  else if( newText!=NULL )
  {
    /*
    ** Is really this necessary? shouldnt an app update its internal data in TVN_ENDLABELEDITA?
    */
    if( !bRevert )
    {
      /*
      * This is a callback string so we need
      * to inform the parent that the string
      * has changed
      *
      */
      tvdi.hdr.hwndFrom	= hwnd;
      tvdi.hdr.idFrom	= GetWindowLongA( hwnd, GWL_ID);
      tvdi.hdr.code	    = TVN_SETDISPINFOA;
      tvdi.item.mask	= TVIF_TEXT;
      tvdi.item.pszText	= newText;

      SendMessageA (
              GetParent(hwnd),
              WM_NOTIFY,
              (WPARAM)tvdi.hdr.idFrom,
              (LPARAM)&tvdi);

    }

  COMCTL32_Free(newText);
  }
	

  ShowWindow(infoPtr->hwndEdit, SW_HIDE);
  EnableWindow(infoPtr->hwndEdit, FALSE);

  /* update the window to eliminate fragments and the like */
  TreeView_GetItemRect(hwnd,infoPtr->editItem,&itemRect,FALSE);
  RedrawWindow(hwnd,&itemRect,0,RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW);

  infoPtr->editItem = 0;

  return !bRevert; /* return true if label edit succesful, otherwise false */
}



static LRESULT
TREEVIEW_LButtonDoubleClick (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  TREEVIEW_ITEM *wineItem;
  POINT pt;

  TRACE("\n");
  pt.x = (INT)LOWORD(lParam);
  pt.y = (INT)HIWORD(lParam);
  SetFocus (hwnd);

  wineItem=TREEVIEW_HitTestPoint (hwnd, pt);
  if (!wineItem) return 0;
  TRACE("item %d \n",(INT)wineItem->hItem);
 
  if (TREEVIEW_SendSimpleNotify (hwnd, NM_DBLCLK)!=TRUE) {     /* FIXME!*/
  	TREEVIEW_Expand (hwnd, (WPARAM) TVE_TOGGLE, (LPARAM) wineItem->hItem);
 }
 return TRUE;
}


static LRESULT
TREEVIEW_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
  INT iItem;
  TVHITTESTINFO ht;

  ht.pt.x = (INT)LOWORD(lParam);
  ht.pt.y = (INT)HIWORD(lParam);

  SetFocus (hwnd);
  iItem=TREEVIEW_HitTest (hwnd, (LPARAM) &ht);
  TRACE("item %d \n",iItem);

  if (ht.flags & TVHT_ONITEMBUTTON) {
    TREEVIEW_Expand (hwnd, (WPARAM) TVE_TOGGLE, (LPARAM) iItem);
  }
  else
  {
    infoPtr->uInternalStatus|=TV_LDRAG;
  }
  
  return 0;
}

static LRESULT
TREEVIEW_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
  INT           iItem;
  TREEVIEW_ITEM *wineItem;
  TVHITTESTINFO ht;
  DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
 
  ht.pt.x = (INT)LOWORD(lParam);
  ht.pt.y = (INT)HIWORD(lParam);
 
  TRACE("\n");

  /* Return true to cancel default behaviour */
  if ( TREEVIEW_SendSimpleNotify (hwnd, NM_CLICK) )
    return 0;

  /* Get the item */
  iItem = TREEVIEW_HitTest (hwnd, (LPARAM) &ht);
  TRACE ("%d\n",iItem);
  if (!iItem) 
    return 0;

  wineItem = TREEVIEW_ValidItem(infoPtr, (HTREEITEM)iItem);
 
  /* 
   * if we are TVS_SINGLEEXPAND then we want this single click to 
   * do a bunch of things.
   */
  if ((dwStyle & TVS_SINGLEEXPAND)&&
      ( ht.flags & (TVHT_ONITEMLABEL | TVHT_ONITEMICON))&&
      ( infoPtr->editItem == 0 ))
  {
    TREEVIEW_ITEM *SelItem;
    /*
     * Send the notification
     */
    TREEVIEW_SendTreeviewNotify (hwnd,TVN_SINGLEEXPAND,0,
                                 (HTREEITEM)iItem,0);
    /*
     * Close the previous selection all the way to the root
     * as long as the new selection is not a child
     */
    
    if ((infoPtr->selectedItem)&&(infoPtr->selectedItem != (HTREEITEM)iItem))
    {
      BOOL closeit = TRUE;
      SelItem = wineItem;

      while (closeit && SelItem)
      {
        closeit = (SelItem->hItem != infoPtr->selectedItem);
        SelItem = TREEVIEW_ValidItem(infoPtr,SelItem->parent);
      }

      if (closeit)
      {
        SelItem = TREEVIEW_ValidItem(infoPtr,infoPtr->selectedItem);
        while ((SelItem)&&(SelItem->hItem != wineItem->hItem))
        {
          TREEVIEW_Expand (hwnd,(WPARAM)TVE_COLLAPSE,(LPARAM)SelItem->hItem);
          SelItem = TREEVIEW_ValidItem(infoPtr,SelItem->parent);
        }
      }
    }
   
    /*
     * Expand the current item 
     */
    TREEVIEW_Expand (hwnd, (WPARAM) TVE_TOGGLE, (LPARAM) wineItem->hItem);
  }

  infoPtr->uInternalStatus &= ~(TV_LDRAG | TV_LDRAGGING);

  /* 
   * If the style allow editing and the node is already selected 
   * and the click occured on the item label...
   */
  if ( ( GetWindowLongA( hwnd, GWL_STYLE) & TVS_EDITLABELS ) && 
       ( wineItem->state & TVIS_SELECTED ) &&
       ( ht.flags & TVHT_ONITEMLABEL ))
  {
    if ( infoPtr->editItem == 0 ) /* If we are not curently editing */
    {
    if( SendMessageA(hwnd, TVM_EDITLABELA, 0, (LPARAM)iItem) == 0)
        return 0;
    }
  }
  else if ( infoPtr->editItem != 0 ) /* If we are curently editing */
  {
    TREEVIEW_EndEditLabelNow(hwnd, (WPARAM)FALSE, 0);
  }
  else if ( ht.flags & (TVHT_ONITEMLABEL | TVHT_ONITEMICON))
  {
    TREEVIEW_DoSelectItem ( hwnd, TVGN_CARET, (HTREEITEM)iItem, TVC_BYMOUSE);
  }

  if (ht.flags & TVHT_ONITEMSTATEICON) {

	
	if (dwStyle & TVS_CHECKBOXES) {      /* TVS_CHECKBOXES requires _us_ */
			int state;					 /* to toggle the current state */
			state=1-(wineItem->state>>12);
			TRACE ("state:%x\n", state);
			wineItem->state&= ~TVIS_STATEIMAGEMASK;
			wineItem->state|=state<<12;
			TRACE ("state:%x\n", wineItem->state);
			TREEVIEW_QueueRefresh (hwnd);
		}
  }
  return 0;
}


static LRESULT
TREEVIEW_RButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
 TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);

 TRACE("\n");
 infoPtr->uInternalStatus|=TV_RDRAG;
 return 0;
}

static LRESULT
TREEVIEW_RButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
 TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);

 TRACE("\n");
 if (TREEVIEW_SendSimpleNotify (hwnd, NM_RCLICK)) return 0;
 infoPtr->uInternalStatus&= ~(TV_RDRAG | TV_RDRAGGING);
 return 0;
}


static LRESULT
TREEVIEW_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
 TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
 TREEVIEW_ITEM *hotItem;
 POINT pt;

 pt.x=(INT) LOWORD (lParam);
 pt.y=(INT) HIWORD (lParam);
 hotItem=TREEVIEW_HitTestPoint (hwnd, pt);
 if (!hotItem) return 0;
 infoPtr->focusItem=hotItem->hItem;

 if ( GetWindowLongA( hwnd, GWL_STYLE) & TVS_DISABLEDRAGDROP) return 0;

 if (infoPtr->uInternalStatus & TV_LDRAG) {
	TREEVIEW_SendTreeviewDnDNotify (hwnd, TVN_BEGINDRAGA, hotItem->hItem, pt);
	infoPtr->uInternalStatus &= ~TV_LDRAG;
	infoPtr->uInternalStatus |= TV_LDRAGGING;
	infoPtr->dropItem=hotItem->hItem;
	return 0;
 }

 if (infoPtr->uInternalStatus & TV_RDRAG) {
	TREEVIEW_SendTreeviewDnDNotify (hwnd, TVN_BEGINRDRAGA, hotItem->hItem, pt);
	infoPtr->uInternalStatus &= ~TV_RDRAG;
	infoPtr->uInternalStatus |= TV_RDRAGGING;
	infoPtr->dropItem=hotItem->hItem;
	return 0;
 }
 
 return 0;
}


static LRESULT
TREEVIEW_CreateDragImage (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
 TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
 TREEVIEW_ITEM *dragItem;
 INT cx,cy;
 HDC    hdc,htopdc;
 HWND hwtop;
 HBITMAP hbmp,hOldbmp;
 SIZE  size;
 RECT  rc;
 HFONT hOldFont;
 char    *itemtxt;
 
 TRACE("\n");
 if (!(infoPtr->himlNormal))  return 0;
 dragItem=TREEVIEW_ValidItem (infoPtr, (HTREEITEM) lParam);
 
 if (!dragItem) return 0;

 if (dragItem->pszText==LPSTR_TEXTCALLBACKA) {
     TREEVIEW_SendDispInfoNotify (hwnd, dragItem, TVN_GETDISPINFOA, TVIF_TEXT);
 }
 itemtxt=dragItem->pszText;

 hwtop=GetDesktopWindow ();
 htopdc= GetDC (hwtop);
 hdc=CreateCompatibleDC (htopdc); 
 
 hOldFont=SelectObject (hdc, infoPtr->hFont);
 GetTextExtentPoint32A (hdc, itemtxt, lstrlenA (itemtxt), &size);
 TRACE("%d %d %s %d\n",size.cx,size.cy,itemtxt,lstrlenA(itemtxt));
 hbmp=CreateCompatibleBitmap (htopdc, size.cx, size.cy);
 hOldbmp=SelectObject (hdc, hbmp);

 ImageList_GetIconSize (infoPtr->himlNormal, &cx, &cy);
 size.cx+=cx;
 if (cy>size.cy) size.cy=cy;

 infoPtr->dragList=ImageList_Create (size.cx, size.cy, ILC_COLOR, 10, 10);
 ImageList_Draw (infoPtr->himlNormal, dragItem->iImage, hdc, 0, 0, ILD_NORMAL);

/*
 ImageList_GetImageInfo (infoPtr->himlNormal, dragItem->hItem, &iminfo);
 ImageList_AddMasked (infoPtr->dragList, iminfo.hbmImage, CLR_DEFAULT);
*/

/* draw item text */

 SetRect (&rc, cx, 0, size.cx,size.cy);
 DrawTextA (hdc, itemtxt, lstrlenA (itemtxt), &rc, DT_LEFT);
 SelectObject (hdc, hOldFont);
 SelectObject (hdc, hOldbmp);

 ImageList_Add (infoPtr->dragList, hbmp, 0);

 DeleteDC (hdc);
 DeleteObject (hbmp);
 ReleaseDC (hwtop, htopdc);

 return (LRESULT)infoPtr->dragList;
}


static LRESULT
TREEVIEW_DoSelectItem (HWND hwnd, INT action, HTREEITEM newSelect, INT cause)

{
  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
  TREEVIEW_ITEM *prevItem,*wineItem;
  INT prevSelect;

  wineItem = TREEVIEW_ValidItem (infoPtr, (HTREEITEM)newSelect);

  TRACE("Entering item %d, flag %x, cause %x, state %d\n", 
	(INT)newSelect, 
	action, 
	cause,
	wineItem->state);

  if ( (wineItem) && (wineItem->parent))
  {
	/* 
	 * If the item has a collapse parent expand the parent so he 
	 * can expose the item 
	 */
	TREEVIEW_ITEM *parentItem = TREEVIEW_ValidItem (infoPtr, wineItem->parent);
	if ( !(parentItem->state & TVIS_EXPANDED)) 
	  TREEVIEW_Expand (hwnd, TVE_EXPAND, (LPARAM) wineItem->parent);
  }

  switch (action) 
  {
	case TVGN_CARET: 
	  prevSelect=(INT)infoPtr->selectedItem;

	  if ((HTREEITEM)prevSelect==newSelect) 
		return FALSE;

	  prevItem= TREEVIEW_ValidItem (infoPtr, (HTREEITEM)prevSelect);

	  if (newSelect) 
		if (TREEVIEW_SendTreeviewNotify(
			  hwnd, 
			  TVN_SELCHANGINGA, 
			  cause, 
			  (HTREEITEM)prevSelect, 
			  (HTREEITEM)newSelect)) 
		  return FALSE;       /* FIXME: OK? */
	
	  if (prevItem) 
		prevItem->state &= ~TVIS_SELECTED;
	  if (wineItem) 
		wineItem->state |=  TVIS_SELECTED;

	  infoPtr->selectedItem=(HTREEITEM)newSelect;

	  TREEVIEW_SendTreeviewNotify(
		hwnd, 
		TVN_SELCHANGEDA, 
		cause,
		(HTREEITEM)prevSelect,
		(HTREEITEM)newSelect);

	  break;

	case TVGN_DROPHILITE: 
	  prevItem= TREEVIEW_ValidItem (infoPtr, infoPtr->dropItem);

	  if (prevItem) 
		prevItem->state &= ~TVIS_DROPHILITED;

	  infoPtr->dropItem=(HTREEITEM)newSelect;

	  if (wineItem) 
		wineItem->state |=TVIS_DROPHILITED;

	  break;

	case TVGN_FIRSTVISIBLE:
	  FIXME("FIRSTVISIBLE not implemented\n");
	  break;
 }
 
 TREEVIEW_QueueRefresh (hwnd);

 TRACE("Leaving state %d\n", wineItem->state);
 return TRUE;
}

/* FIXME: handle NM_KILLFocus etc */
static LRESULT
TREEVIEW_SelectItem (HWND hwnd, WPARAM wParam, LPARAM lParam)

{
 return TREEVIEW_DoSelectItem (hwnd, wParam, (HTREEITEM) lParam, TVC_UNKNOWN);
}



   
static LRESULT
TREEVIEW_GetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)

{
 TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);

 TRACE("%x\n",infoPtr->hFont);
 return infoPtr->hFont;
}

static LRESULT
TREEVIEW_SetFont (HWND hwnd, WPARAM wParam, LPARAM lParam)

{
 TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
 TEXTMETRICA tm;
 LOGFONTA logFont;
 HFONT hFont, hOldFont;
 INT height;
 HDC hdc;

 TRACE("%x %lx\n",wParam, lParam);
 
 infoPtr->hFont = (HFONT)wParam;

 hFont = infoPtr->hFont ? infoPtr->hFont : GetStockObject (SYSTEM_FONT);

 GetObjectA (infoPtr->hFont, sizeof (LOGFONTA), &logFont);
 logFont.lfWeight=FW_BOLD;
 infoPtr->hBoldFont = CreateFontIndirectA (&logFont);

 hdc = GetDC (0);
 hOldFont = SelectObject (hdc, hFont);
 GetTextMetricsA (hdc, &tm);
 height= tm.tmHeight + tm.tmExternalLeading + FOCUS_BORDER;
 if (height>infoPtr->uRealItemHeight) 
 	infoPtr->uRealItemHeight=height;
 SelectObject (hdc, hOldFont);
 ReleaseDC (0, hdc);

 if (lParam) 	
 	TREEVIEW_QueueRefresh (hwnd);
 
 return 0;
}



static LRESULT
TREEVIEW_VScroll (HWND hwnd, WPARAM wParam, LPARAM lParam)

{
  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
  WORD nVisibleItems;
  int maxHeight;

  TRACE("wp %x, lp %lx\n", wParam, lParam);
  if (!infoPtr->uInternalStatus & TV_VSCROLL) return FALSE;

  switch (LOWORD (wParam)) {
	case SB_LINEUP: 
			if (!infoPtr->cy) return FALSE;
			infoPtr->cy -= infoPtr->uRealItemHeight;
			if (infoPtr->cy < 0) infoPtr->cy=0;
			break;
	case SB_LINEDOWN: 
			nVisibleItems = infoPtr->uVisibleHeight / infoPtr->uRealItemHeight;
			maxHeight=infoPtr->uTotalHeight - nVisibleItems * infoPtr->uRealItemHeight;
			if (infoPtr->cy >= maxHeight) return FALSE;
			infoPtr->cy += infoPtr->uRealItemHeight;
			if (infoPtr->cy >= maxHeight) 
				infoPtr->cy = maxHeight;
			break;
	case SB_PAGEUP:	
			if (!infoPtr->cy) return FALSE;
			infoPtr->cy -= infoPtr->uVisibleHeight;
			if (infoPtr->cy < 0) infoPtr->cy=0;
			break;
	case SB_PAGEDOWN:
			nVisibleItems = infoPtr->uVisibleHeight / infoPtr->uRealItemHeight;
			maxHeight=infoPtr->uTotalHeight - nVisibleItems * infoPtr->uRealItemHeight;
			if (infoPtr->cy == maxHeight) return FALSE;
			infoPtr->cy += infoPtr->uVisibleHeight;
            		if (infoPtr->cy >= maxHeight)
                		infoPtr->cy = maxHeight;
			break;
	case SB_THUMBTRACK: 
			infoPtr->cy = HIWORD (wParam);
			break;
			
  }
  
  TREEVIEW_QueueRefresh (hwnd);
  return TRUE;
}

static LRESULT
TREEVIEW_HScroll (HWND hwnd, WPARAM wParam, LPARAM lParam) 
{
  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
  int maxWidth;

  TRACE("wp %lx, lp %x\n", lParam, wParam);
	
  if (!infoPtr->uInternalStatus & TV_HSCROLL) return FALSE;

  switch (LOWORD (wParam)) {
	case SB_LINEUP: 
			if (!infoPtr->cx) return FALSE;
			infoPtr->cx -= infoPtr->uRealItemHeight;
			if (infoPtr->cx < 0) infoPtr->cx=0;
			break;
	case SB_LINEDOWN: 
			maxWidth=infoPtr->uTotalWidth-infoPtr->uVisibleWidth;
			if (infoPtr->cx == maxWidth) return FALSE;
			infoPtr->cx += infoPtr->uRealItemHeight; /*FIXME */
			if (infoPtr->cx > maxWidth) 
				infoPtr->cx = maxWidth;
			break;
	case SB_PAGEUP:	
			if (!infoPtr->cx) return FALSE;
			infoPtr->cx -= infoPtr->uVisibleWidth;
			if (infoPtr->cx < 0) infoPtr->cx=0;
			break;
	case SB_PAGEDOWN:
			maxWidth=infoPtr->uTotalWidth-infoPtr->uVisibleWidth;
			if (infoPtr->cx == maxWidth) return FALSE;
			infoPtr->cx += infoPtr->uVisibleWidth;
            if (infoPtr->cx > maxWidth)
                infoPtr->cx = maxWidth;
			break;
	case SB_THUMBTRACK: 
			infoPtr->cx = HIWORD (wParam);
			break;
			
  }
  
  TREEVIEW_QueueRefresh (hwnd);
  return TRUE;
}

static LRESULT TREEVIEW_MouseWheel (HWND hwnd, WPARAM wParam, LPARAM lParam)
{

    TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
    short gcWheelDelta = 0;
    UINT pulScrollLines = 3;

    SystemParametersInfoW(SPI_GETWHEELSCROLLLINES,0, &pulScrollLines, 0);

    gcWheelDelta -= (short) HIWORD(wParam);
    pulScrollLines *= (gcWheelDelta / WHEEL_DELTA);

    if (abs(gcWheelDelta) >= WHEEL_DELTA && pulScrollLines)
    {
        int wheelDy = pulScrollLines * infoPtr->uRealItemHeight;
        int newDy = infoPtr->cy + wheelDy;
        int maxDy = infoPtr->uTotalHeight - infoPtr->uVisibleHeight;

        if (newDy > maxDy) newDy = maxDy;
        if (newDy < 0) newDy = 0;

        if (newDy == infoPtr->cy) return TRUE;

        TREEVIEW_VScroll(hwnd, MAKEWPARAM(SB_THUMBTRACK,newDy),0);
    }
  return TRUE;
}

static LRESULT
TREEVIEW_KeyDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
 TREEVIEW_INFO *infoPtr        = TREEVIEW_GetInfoPtr(hwnd);
 HTREEITEM     hNewSelection   = 0;
 INT           scrollNeeds     = -1;
 INT           cyChangeNeeds   = -1;
 INT           prevSelect      = (INT)infoPtr->selectedItem;

 TREEVIEW_ITEM *prevItem       = 
    (prevSelect != 0 ) ? 
      TREEVIEW_ValidItem (infoPtr, (HTREEITEM)prevSelect) :
      NULL;

 TREEVIEW_ITEM *newItem        = NULL;

 TRACE("%x %lx\n",wParam, lParam);

 if (prevSelect == 0) 
   return FALSE;

 switch (wParam) {
	case VK_UP: 
		newItem=TREEVIEW_GetPrevListItem (infoPtr, prevItem);

		if (!newItem) 
			newItem=& infoPtr->items[(INT)infoPtr->TopRootItem];

    	hNewSelection = newItem->hItem;

    	if (! newItem->visible)
      		scrollNeeds = SB_LINEUP;
		break;

	case VK_DOWN: 
		newItem=TREEVIEW_GetNextListItem (infoPtr, prevItem);

		if (!newItem) 
      newItem=prevItem;

    hNewSelection = newItem->hItem;

    if (! newItem->visible)
      scrollNeeds = SB_LINEDOWN;

		break;

	case VK_HOME:
		newItem       = &infoPtr->items[(INT)infoPtr->TopRootItem];
    hNewSelection = newItem->hItem;
    cyChangeNeeds = 0;
		break;

	case VK_END:
		newItem       = &infoPtr->items[(INT)infoPtr->TopRootItem];
		newItem       = TREEVIEW_GetLastListItem (infoPtr, newItem);
    hNewSelection = newItem->hItem;

    if (! newItem->visible)
      cyChangeNeeds = infoPtr->uTotalHeight-infoPtr->uVisibleHeight;

		break;

	case VK_LEFT:
    if ( (prevItem->cChildren > 0) && (prevItem->state & TVIS_EXPANDED) )
    {
      TREEVIEW_Expand(hwnd, TVE_COLLAPSE, prevSelect );
    }
    else if ((INT)prevItem->parent) 
    {
      newItem = (& infoPtr->items[(INT)prevItem->parent]);
      if (! newItem->visible) 
        /* FIXME find a way to make this item the first visible... */
        newItem = NULL; 

      hNewSelection = newItem->hItem;
    }

    break;

	case VK_RIGHT:
    if ( ( prevItem->cChildren > 0)  || 
         ( prevItem->cChildren == I_CHILDRENCALLBACK))
    {
      if (! (prevItem->state & TVIS_EXPANDED))
        TREEVIEW_Expand(hwnd, TVE_EXPAND, prevSelect );
      else
      {
        newItem = (& infoPtr->items[(INT)prevItem->firstChild]);
        hNewSelection = newItem->hItem;
      }
    }

    break;

  case VK_ADD:
    if (! (prevItem->state & TVIS_EXPANDED))
      TREEVIEW_Expand(hwnd, TVE_EXPAND, prevSelect );
    break;

  case VK_SUBTRACT:
    if (prevItem->state & TVIS_EXPANDED)
      TREEVIEW_Expand(hwnd, TVE_COLLAPSE, prevSelect );
    break;

  case VK_PRIOR:
    
		newItem=TREEVIEW_GetListItem(
              infoPtr, 
              prevItem,
              -1*(TREEVIEW_GetVisibleCount(hwnd,0,0)-3));
		if (!newItem) 
      newItem=prevItem;
  
    hNewSelection = newItem->hItem;

    if (! newItem->visible)
      scrollNeeds = SB_PAGEUP;

		break;

  case VK_NEXT:
		newItem=TREEVIEW_GetListItem(
              infoPtr, 
              prevItem,
              TREEVIEW_GetVisibleCount(hwnd,0,0)-3);

		if (!newItem) 
      newItem=prevItem;

    hNewSelection = newItem->hItem;

    if (! newItem->visible)
      scrollNeeds = SB_PAGEDOWN;

		break;

	case VK_BACK:

	case VK_RETURN:

  default:
		FIXME("%x not implemented\n", wParam);
		break;
 }

  if (hNewSelection) 
  {
/* 
    This works but does not send notification...

    prevItem->state      &= ~TVIS_SELECTED;
    newItem->state       |=  TVIS_SELECTED;
    infoPtr->selectedItem = hNewSelection;
    TREEVIEW_QueueRefresh (hwnd);
*/

    if ( TREEVIEW_DoSelectItem( 
           hwnd, 
           TVGN_CARET, 
           (HTREEITEM)hNewSelection, 
           TVC_BYKEYBOARD))
    {
      /* If selection change is allowed for the new item, perform scrolling */
      if (scrollNeeds != -1)
        TREEVIEW_VScroll(hwnd, scrollNeeds, 0);
  
      if (cyChangeNeeds != -1)
        infoPtr->cy = cyChangeNeeds;

      /* FIXME: Something happen in the load the in the two weeks before 
         april 1st 1999 which makes this SetFocus mandatory otherwise, the focus 
         is lost... However the SetFocus should not be required...*/
               
      SetFocus(hwnd);
    }
  }

  return FALSE;
}


static LRESULT
TREEVIEW_GetScrollTime (HWND hwnd)
{
  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);

  return infoPtr->uScrollTime;
}


static LRESULT
TREEVIEW_SetScrollTime (HWND hwnd, UINT uScrollTime)
{
  TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
  UINT uOldScrollTime = infoPtr->uScrollTime;

  infoPtr->uScrollTime = min (uScrollTime, 100);

  return uOldScrollTime;
}


static LRESULT WINAPI
TREEVIEW_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
   TREEVIEW_INFO *infoPtr;
   if (uMsg==WM_CREATE)
		return TREEVIEW_Create (hwnd, wParam, lParam);
   
   if (!(infoPtr = TREEVIEW_GetInfoPtr(hwnd)))
       return DefWindowProcA (hwnd, uMsg, wParam, lParam);

   switch (uMsg) {
  
    	case TVM_INSERTITEMA:
          return TREEVIEW_InsertItemA (hwnd, wParam, lParam);

    	case TVM_INSERTITEMW:
      		return TREEVIEW_InsertItemW(hwnd,wParam,lParam);;

    	case TVM_DELETEITEM:
      		return TREEVIEW_DeleteItem (hwnd, wParam, lParam);

    	case TVM_EXPAND:
      		return TREEVIEW_Expand (hwnd, wParam, lParam);

    	case TVM_GETITEMRECT:
      		return TREEVIEW_GetItemRect (hwnd, wParam, lParam);

    	case TVM_GETCOUNT:
      		return TREEVIEW_GetCount (hwnd, wParam, lParam);

    	case TVM_GETINDENT:
      		return TREEVIEW_GetIndent (hwnd);

    	case TVM_SETINDENT:
      		return TREEVIEW_SetIndent (hwnd, wParam);

    	case TVM_GETIMAGELIST:
      		return TREEVIEW_GetImageList (hwnd, wParam, lParam);

		case TVM_SETIMAGELIST:
	    	return TREEVIEW_SetImageList (hwnd, wParam, lParam);

    	case TVM_GETNEXTITEM:
      		return TREEVIEW_GetNextItem (hwnd, wParam, lParam);

    	case TVM_SELECTITEM:
      		return TREEVIEW_SelectItem (hwnd, wParam, lParam);

    	case TVM_GETITEMA:
      		return TREEVIEW_GetItemA (hwnd, wParam, lParam);

    	case TVM_GETITEMW:
      		return TREEVIEW_GetItemW (hwnd, wParam, lParam);

    	case TVM_SETITEMA:
      		return TREEVIEW_SetItemA (hwnd, wParam, lParam);

    	case TVM_SETITEMW:
      		FIXME("Unimplemented msg TVM_SETITEMW\n");
      		return 0;

    	case TVM_EDITLABELA:
    	    return TREEVIEW_EditLabelA(hwnd, wParam, lParam);

    	case TVM_EDITLABELW:
      		FIXME("Unimplemented msg TVM_EDITLABELW \n");
      		return 0;

    	case TVM_GETEDITCONTROL:
      		return TREEVIEW_GetEditControl (hwnd);

    	case TVM_GETVISIBLECOUNT:
      		return TREEVIEW_GetVisibleCount (hwnd, wParam, lParam);

    	case TVM_HITTEST:
      		return TREEVIEW_HitTest (hwnd, lParam);

    	case TVM_CREATEDRAGIMAGE:
      		return TREEVIEW_CreateDragImage (hwnd, wParam, lParam);
  
    	case TVM_SORTCHILDREN:
      		return TREEVIEW_SortChildren (hwnd, wParam, lParam);
  
    	case TVM_ENSUREVISIBLE:
      		FIXME("Unimplemented msg TVM_ENSUREVISIBLE\n");
      		return 0;
  
    	case TVM_SORTCHILDRENCB:
      		return TREEVIEW_SortChildrenCB(hwnd, wParam, lParam);
  
    	case TVM_ENDEDITLABELNOW:
                if (infoPtr->editItem)
      		    return TREEVIEW_EndEditLabelNow (hwnd, wParam, lParam);
  
    	case TVM_GETISEARCHSTRINGA:
      		FIXME("Unimplemented msg TVM_GETISEARCHSTRINGA\n");
      		return 0;
  
    	case TVM_GETISEARCHSTRINGW:
      		FIXME("Unimplemented msg TVM_GETISEARCHSTRINGW\n");
      		return 0;
  
    	case TVM_GETTOOLTIPS:
      		return TREEVIEW_GetToolTips (hwnd);

    	case TVM_SETTOOLTIPS:
      		return TREEVIEW_SetToolTips (hwnd, wParam);
  
    	case TVM_SETINSERTMARK:
      		return TREEVIEW_SetInsertMark (hwnd,wParam, lParam);
  
    	case TVM_SETITEMHEIGHT:
      		return TREEVIEW_SetItemHeight (hwnd, wParam);
  
    	case TVM_GETITEMHEIGHT:
      		return TREEVIEW_GetItemHeight (hwnd);
  
    	case TVM_SETBKCOLOR:
      		return TREEVIEW_SetBkColor (hwnd, wParam, lParam);
	
    	case TVM_SETTEXTCOLOR:
      		return TREEVIEW_SetTextColor (hwnd, wParam, lParam);
  
    	case TVM_GETBKCOLOR:
      		return TREEVIEW_GetBkColor (hwnd);
  
    	case TVM_GETTEXTCOLOR:
      		return TREEVIEW_GetTextColor (hwnd);
  
    	case TVM_SETSCROLLTIME:
      		return TREEVIEW_SetScrollTime (hwnd, (UINT)wParam);
  
    	case TVM_GETSCROLLTIME:
      		return TREEVIEW_GetScrollTime (hwnd);

    	case TVM_GETITEMSTATE:
      		return TREEVIEW_GetItemState (hwnd,wParam, lParam);

    	case TVM_GETLINECOLOR:
      		return TREEVIEW_GetLineColor (hwnd,wParam, lParam);

    	case TVM_SETLINECOLOR:
      		return TREEVIEW_SetLineColor (hwnd,wParam, lParam);
  
    	case TVM_SETINSERTMARKCOLOR:
      		return TREEVIEW_SetInsertMarkColor (hwnd,wParam, lParam);
  
    	case TVM_GETINSERTMARKCOLOR:
      		return TREEVIEW_GetInsertMarkColor (hwnd,wParam, lParam);
  
    	case TVM_SETUNICODEFORMAT:
      		FIXME("Unimplemented msg TVM_SETUNICODEFORMAT\n");
      		return 0;
  
    	case TVM_GETUNICODEFORMAT:
      		FIXME("Unimplemented msg TVM_GETUNICODEFORMAT\n");
      		return 0;
  
		case WM_COMMAND: 
			 return TREEVIEW_Command (hwnd, wParam, lParam);
  
		case WM_DESTROY:
			return TREEVIEW_Destroy (hwnd);
  
/*		case WM_ENABLE: */
  
		case WM_ERASEBKGND:
			return TREEVIEW_EraseBackground (hwnd, wParam, lParam);
  
		case WM_GETDLGCODE:
	    	return DLGC_WANTARROWS | DLGC_WANTCHARS;
  
		case WM_PAINT:
	    	return TREEVIEW_Paint (hwnd, wParam, lParam);
  
		case WM_GETFONT:
	    	return TREEVIEW_GetFont (hwnd, wParam, lParam);

		case WM_SETFONT:
	    	return TREEVIEW_SetFont (hwnd, wParam, lParam);
  
		case WM_KEYDOWN:
			return TREEVIEW_KeyDown (hwnd, wParam, lParam);
  
		case WM_SETFOCUS: 
			return TREEVIEW_SetFocus (hwnd, wParam, lParam);

		case WM_KILLFOCUS: 
			return TREEVIEW_KillFocus (hwnd, wParam, lParam);
  
		case WM_LBUTTONDOWN:
			return TREEVIEW_LButtonDown (hwnd, wParam, lParam);

		case WM_LBUTTONUP:
			return TREEVIEW_LButtonUp (hwnd, wParam, lParam);
  
		case WM_LBUTTONDBLCLK:
			return TREEVIEW_LButtonDoubleClick (hwnd, wParam, lParam);
  
		case WM_RBUTTONDOWN:
			return TREEVIEW_RButtonDown (hwnd, wParam, lParam);

		case WM_RBUTTONUP:
			return TREEVIEW_RButtonUp (hwnd, wParam, lParam);

		case WM_MOUSEMOVE:
			return TREEVIEW_MouseMove (hwnd, wParam, lParam);
  
		case WM_STYLECHANGED: 
			return TREEVIEW_StyleChanged (hwnd, wParam, lParam);

/*		case WM_SYSCOLORCHANGE: */
/*		case WM_SETREDRAW: */
  
		case WM_TIMER:
			return TREEVIEW_HandleTimer (hwnd, wParam, lParam);
 
		case WM_SIZE: 
			return TREEVIEW_Size (hwnd, wParam,lParam);

		case WM_HSCROLL: 
			return TREEVIEW_HScroll (hwnd, wParam, lParam);
		case WM_VSCROLL: 
			return TREEVIEW_VScroll (hwnd, wParam, lParam);
  
                case WM_MOUSEWHEEL:
                    if (wParam & (MK_SHIFT | MK_CONTROL))
                        return DefWindowProcA( hwnd, uMsg, wParam, lParam );
                    return TREEVIEW_MouseWheel (hwnd, wParam, lParam);

		case WM_DRAWITEM:
			TRACE ("drawItem\n");
			return DefWindowProcA (hwnd, uMsg, wParam, lParam);
  
		default:
	    	if (uMsg >= WM_USER)
		FIXME("Unknown msg %04x wp=%08x lp=%08lx\n",
  		     uMsg, wParam, lParam);
  	    return DefWindowProcA (hwnd, uMsg, wParam, lParam);
      }
    return 0;
}


VOID
TREEVIEW_Register (void)
{
    WNDCLASSA wndClass;

    TRACE("\n");

    ZeroMemory (&wndClass, sizeof(WNDCLASSA));
    wndClass.style         = CS_GLOBALCLASS | CS_DBLCLKS;
    wndClass.lpfnWndProc   = (WNDPROC)TREEVIEW_WindowProc;
    wndClass.cbClsExtra    = 0;
    wndClass.cbWndExtra    = sizeof(TREEVIEW_INFO *);
    wndClass.hCursor       = LoadCursorA (0, IDC_ARROWA);
    wndClass.hbrBackground = 0;
    wndClass.lpszClassName = WC_TREEVIEWA;
 
    RegisterClassA (&wndClass);
}


VOID
TREEVIEW_Unregister (void)
{
    UnregisterClassA (WC_TREEVIEWA, (HINSTANCE)NULL);
}



