/******************************************************************************\
* file   : ListCtrlEx.cpp
* created: 1997.09.22
*
* Zafir Anjum   - Original author.
* Mark Findlay  - IE4 fixes.
* Matthew Bells - Better TitleTips.
*
* description:
* A super CListControl.
* <P>features:
* <UL>
*   <LI>Title Tip item expantion
*   <LI>full row selection<BR>
*       <I>Note:</I> this is also a feature in IE 4.0 with
*       LVS_EX_FULLROWSELECT.
*   <LI>notifies parent selection has changed
*   <LI>supports column dragging (with IE4) which changes the column order
* </UL>
*
\******************************************************************************/
// ListCtrlEx.cpp : implementation of the CListCtrlEx class

#include "stdafx.h"
#include <assert.h>
#include "ListCtrlEx.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CListCtrlEx

IMPLEMENT_DYNCREATE(CListCtrlEx, CListCtrl)

BEGIN_MESSAGE_MAP(CListCtrlEx, CListCtrl)
	//{{AFX_MSG_MAP(CListCtrlEx)
	ON_WM_PAINT()
	ON_WM_SETFOCUS()
	ON_WM_KILLFOCUS()
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONDOWN()
	ON_WM_KEYDOWN()
	ON_WM_DESTROY()
	ON_WM_MEASUREITEM()
	//}}AFX_MSG_MAP
	ON_MESSAGE(LVM_SETTEXTCOLOR, OnSetTextColor)
	ON_MESSAGE(LVM_SETTEXTBKCOLOR, OnSetTextBkColor)
	ON_MESSAGE(LVM_SETBKCOLOR, OnSetBkColor)
	ON_WM_MEASUREITEM_REFLECT( )

END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CListCtrlEx construction/destruction

CListCtrlEx::CListCtrlEx()
{
	m_bFullRowSel = FALSE;
	m_bClientWidthSel = TRUE;

	m_clrText = ::GetSysColor(COLOR_WINDOWTEXT);
	m_clrTextBk = ::GetSysColor(COLOR_WINDOW);
	m_clrBkgnd = ::GetSysColor(COLOR_WINDOW);

	bShowLine		= true;
	nFontHeight		= -1;
	nTxtColor		= 0;
}

CListCtrlEx::~CListCtrlEx()
{
}
/*
BOOL CListCtrlEx::OnEraseBkgnd(CDC* pDC)
{
	CBitmap bmp;
	CBitmap *ptrBmpOld;
	CDC dcMemory;
	BITMAP bm;
	CRect rect;
	int i, j;
	int nHor, nVer;

	bmp.LoadBitmap("BackGround");
	bmp.GetBitmap(&bm);
	GetClientRect(rect);
	nHor=rect.Width()/bm.bmWidth+1;
	nVer=rect.Height()/bm.bmHeight+1;
	dcMemory.CreateCompatibleDC(pDC);
	ptrBmpOld=dcMemory.SelectObject(&bmp);
	for(i=0; i<nHor; i++)
	{
		for(j=0; j<nVer; j++)
		{
			pDC->BitBlt
			(
				i*bm.bmWidth,
				j*bm.bmHeight,
				bm.bmWidth,
				bm.bmHeight,
				&dcMemory,
				0,
				0,
				SRCCOPY
			);
		}
	}
	dcMemory.SelectObject(ptrBmpOld);

	return true;
}
//*/
// Make sure the control is owner drawn
BOOL CListCtrlEx::PreCreateWindow(CREATESTRUCT& cs)
{
	// default is report view and full row selection
	cs.style &= ~LVS_TYPEMASK;
	cs.style |= LVS_REPORT | LVS_OWNERDRAWFIXED;
	m_bFullRowSel = TRUE;

	return(CListCtrl::PreCreateWindow(cs));
}

BOOL CListCtrlEx::SetFullRowSel(BOOL bFullRowSel)
{
	// no painting during change
	LockWindowUpdate();

	m_bFullRowSel = bFullRowSel;

	BOOL bRet;

	if (m_bFullRowSel)
		bRet = ModifyStyle(0L, LVS_OWNERDRAWFIXED);
	else
		bRet = ModifyStyle(LVS_OWNERDRAWFIXED, 0L);

	// repaint window if we are not changing view type
	if (bRet && (GetStyle() & LVS_TYPEMASK) == LVS_REPORT)
		Invalidate();

	// repaint changes
	UnlockWindowUpdate();

	return(bRet);
}

BOOL CListCtrlEx::GetFullRowSel()
{
	return(m_bFullRowSel);
}

/////////////////////////////////////////////////////////////////////////////
// CListCtrlEx drawing

/*
* DrawItem() is called by the framework whenever an item needs to be drawn
* for owner drawn controls.
* Note:
* <UL>
*   <LI>LVS_SHOWSELALWAYS: non owner drawn controls show an item is
*     highlighted when the control does not have focus with a different
*     highlight color is (usually gray). This is not supported for
*     this control.
* </UL>
*/


void CListCtrlEx::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
	CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
	int iSavedDC = pDC->SaveDC();             // Save DC state
//*
	CFont *pOldFont = NULL;
	CFont font;
	if( nFontHeight != -1 )
	{
		CFont* ptf = GetFont(); // �õ�ԭ��������
		LOGFONT lf; 
		ptf->GetLogFont(&lf); 
		lf.lfHeight = nFontHeight; // �ı�����߶� 
		//strcpy (lf.lfFaceName, "Arial Black"); // �ı��������� 
		strcpy (lf.lfFaceName, "Arial"); // �ı��������� 
		lf.lfWeight = 700;
		lf.lfCharSet = DEFAULT_CHARSET;	//DEFAULT_CHARSET  ANSI_CHARSET  GB2312_CHARSET
		font.CreateFontIndirect(&lf); 
		pOldFont = (CFont *)pDC->SelectObject(&font);

//		LOGFONT lf;//����
//		lf.lfStrikeOut=0;//ɾ����
//		lf.lfCharSet = DEFAULT_CHARSET ;//�ַ���
//		lf.lfEscapement =0;//�Ƕ�
//		lf.lfItalic = 0 ;//��б
//		lf.lfUnderline = 0;//�»���
//		lf.lfHeight = nFontHeight;//�ֺ�
		//strcpy( lf.lfFaceName, "����" );
//		font.CreateFontIndirect(&lf);
//		CFont *pOldFont = (CFont *)pDC->SelectObject(&font);
	}
//*/
	
	int iItem = lpDrawItemStruct->itemID;

	// Get item image and state info
	LV_ITEM lvi;
	lvi.mask = LVIF_IMAGE | LVIF_STATE;
	lvi.iItem = iItem;
	lvi.iSubItem = 0;
	lvi.stateMask = 0xFFFF;		// get all state flags
	GetItem(&lvi);

	bool bHighlight = (
		(lvi.state & LVIS_DROPHILITED) ||
		((lvi.state & LVIS_SELECTED) && ((GetFocus() == this) || (GetStyle() & LVS_SHOWSELALWAYS)))
		);

	// Get rectangles for drawing
	CRect rcBounds;
	CRect rcLabel;
	CRect rcIcon;
	GetItemRect(iItem, rcBounds, LVIR_BOUNDS);
	GetItemRect(iItem, rcLabel, LVIR_LABEL);
	GetItemRect(iItem, rcIcon, LVIR_ICON);
	CRect rcItem(rcBounds);

	CString sLabel = GetItemText(iItem, 0);

	// Labels are offset by a certain amount  
	// This offset is related to the width of a space character
	int offset = pDC->GetTextExtent(_T(" "), 1 ).cx*2;

	rcBounds.left = rcLabel.left;
	CRect rcWnd;
	GetClientRect(&rcWnd);
	if(m_bClientWidthSel && rcBounds.right<rcWnd.right)
		rcBounds.right = rcWnd.right;

	// Draw the background
	if(bHighlight)
	{
		pDC->SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));
		pDC->SetBkColor(::GetSysColor(COLOR_HIGHLIGHT));
		pDC->FillRect(rcBounds, &CBrush(::GetSysColor(COLOR_HIGHLIGHT)));
	}
	else
	{
		if( nTxtColor != 0 )
			pDC->SetTextColor( nTxtColor );

		if( bShowLine )
		{
			if( iItem%2 )
				pDC->FillRect(rcBounds, &CBrush(m_clrTextBk));
			else
				pDC->FillRect(rcBounds, &CBrush(RGB(212,212,212)));
		}
		else
		{
			DWORD_PTR pRGB = GetItemData(iItem);
			COLORREF color = (COLORREF)pRGB;
			COLORREF white(RGB(255, 255, 255));
			if(color != RGB(0, 0, 0))
				pDC->FillRect(rcBounds, &CBrush(color));
			else
				pDC->FillRect(rcBounds, &CBrush(white));
			//pDC->FillRect(rcBounds, &CBrush(m_clrTextBk));
		}
	}

	// Set clip region
	rcItem.right = rcItem.left + GetColumnWidth(0);

	// Draw state icon
	if(lvi.state & LVIS_STATEIMAGEMASK)
	{
		int nImage = ((lvi.state & LVIS_STATEIMAGEMASK)>>12) - 1;
		CImageList* pImageList = GetImageList(LVSIL_STATE);
		if(pImageList)
		{
			pImageList->Draw(pDC, nImage,
				CPoint(rcItem.left, rcItem.top), ILD_TRANSPARENT);
		}
	}

	// Draw normal and overlay icon
	CImageList* pImageList = GetImageList(LVSIL_SMALL);
	if(pImageList)
	{
		UINT nOvlImageMask = lvi.state & LVIS_OVERLAYMASK;
		pImageList->Draw(pDC, lvi.iImage, 
			CPoint(rcIcon.left, rcIcon.top),
			(bHighlight?ILD_BLEND50:0) | ILD_TRANSPARENT | nOvlImageMask );
	}

	// Draw item label - Column 0
	rcLabel.left += offset/2-1;
	rcLabel.right -= offset;
	pDC->DrawText(sLabel,-1,rcLabel,DT_LEFT | DT_SINGLELINE | DT_NOPREFIX
		| DT_VCENTER | DT_END_ELLIPSIS);

	// Draw labels for remaining columns
	LV_COLUMN lvc;
	lvc.mask = LVCF_FMT | LVCF_WIDTH;

/*
// set clip region
 	rcBounds.right = rcHighlight.right > rcBounds.right ? rcHighlight.right :
	rcBounds.right;
	rgn.CreateRectRgnIndirect(&rcBounds);
	pDC->SelectClipRgn(&rgn);
*/
	for(int nColumn = 1; GetColumn(nColumn, &lvc); nColumn++)
	{
		rcItem.left = rcItem.right;
		rcItem.right += lvc.cx;

		sLabel = GetItemText(iItem, nColumn);

		// Get the text just ification
		UINT nJustify = DT_LEFT;
		switch(lvc.fmt & LVCFMT_JUSTIFYMASK)
		{
		case LVCFMT_RIGHT:
			nJustify = DT_RIGHT;
			break;
		case LVCFMT_CENTER:
			nJustify = DT_CENTER;
			break;
		default:
			break;
		}

		rcLabel = rcItem;
		rcLabel.left += offset;
		rcLabel.right -= offset;

		pDC->DrawText(sLabel, -1, rcLabel,
			nJustify | DT_SINGLELINE | DT_NOPREFIX | DT_VCENTER | DT_END_ELLIPSIS);
	}

	// draw focus rectangle if item has focus
	if ((lvi.state & LVIS_FOCUSED) && (GetFocus() == this))
		pDC->DrawFocusRect(rcBounds);
//*
	if( pOldFont != NULL )
		pDC->SelectObject( pOldFont );
	if( nFontHeight != -1 )
		font.DeleteObject();
//*/

	pDC->RestoreDC(iSavedDC);                 // Restore DC.
}

/////////////////////////////////////////////////////////////////////////////
// CListCtrlEx diagnostics

#ifdef _DEBUG

void CListCtrlEx::Dump(CDumpContext& dc) const
{
	CListCtrl::Dump(dc);

	dc << "m_bFullRowSel = " << m_bFullRowSel;
	dc << "\n";
}

#endif //_DEBUG


/**
* @param iRow    [in] row of cell
* @param iColunm [in] column of cell
* @return Rectangle corresponding to the given cell.
*/

CRect CListCtrlEx::GetCellRect(int iRow, int iColumn)const
{
	// Make sure that the ListView is in LVS_REPORT
	if((GetStyle() & LVS_TYPEMASK) != LVS_REPORT)
		return CRect(0,0,0,0);

	// Get the number of columns
	{
		CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0);
		int iColumnCount = pHeader->GetItemCount();
		assert(iColumn < iColumnCount);
	}

	CRect rect;
	GetItemRect(iRow, &rect, LVIR_BOUNDS);
	// Now find the column
	for(int colnum = 0; colnum < iColumn; colnum++)
	{
		rect.left += GetTrueColumnWidth(colnum);
	}

	// Found the column
	rect.right = rect.left + GetTrueColumnWidth(iColumn);

	RECT rectClient;
	GetClientRect(&rectClient);
	if(rect.right > rectClient.right)
		rect.right = rectClient.right;

	return rect;
}

/**
* @author Mark Findlay
*/

CString CListCtrlEx::GetTrueItemText(int row, int col)const
{
	// Get the header control 
	CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0);
	_ASSERTE(pHeader);
	
	// get the current number of columns 
	int nCount = pHeader->GetItemCount();
	
	// find the actual column requested. We will compare
	// against hi.iOrder
	for (int x=0; x< nCount; x++)
	{
		HD_ITEM hi = {0};
		hi.mask = HDI_ORDER;
		
		BOOL bRet = pHeader->GetItem(x,&hi);
		_ASSERTE(bRet);
		if (hi.iOrder == col)
		{
			// Found it, get the associated text
			return GetItemText(row,x);
		}
	}
	
	_ASSERTE(FALSE);
	return "We better never fall through to here!";
}

/**
* @author Mark Findlay
*/

int CListCtrlEx::GetTrueColumnWidth(int nCurrentPosition)const
{
	CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0);
	_ASSERTE(pHeader);
	
	int nCount = pHeader->GetItemCount();
	
	for (int x=0; x< nCount; x++)
	{
		HD_ITEM hi = {0};
		hi.mask = HDI_WIDTH | HDI_ORDER;
		
		BOOL bRet = pHeader->GetItem(x,&hi);
		_ASSERTE(bRet);
		if (hi.iOrder == nCurrentPosition)
			return hi.cxy;
	}
	
	_ASSERTE(FALSE);
	return 0; // We would never fall through to here!
}

void CListCtrlEx::HideTitleTip()
{
	m_titletip.ShowWindow(SW_HIDE);
}

/**
* @param point   [in]  point in client coordinates
* @param iRow    [out] row containing the point
* @param iColunm [out] column containing the point
*
* @author Matthew Bells
*/

bool CListCtrlEx::HitTestRowCol(CPoint& point, int& iRow, int& iColumn)const
{
	// Make sure that the ListView is in LVS_REPORT
	if((GetStyle() & LVS_TYPEMASK) != LVS_REPORT)
		return false;

	int iPosX = point.x;
	iRow = HitTest(point);

	// Get the number of columns
	CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0);
	int iColumnCount = pHeader->GetItemCount();

	for(iColumn = 0; iColumn < iColumnCount; ++iColumn)
	{
		iPosX -= GetTrueColumnWidth(iColumn);
		if(iPosX < 0)
			break;
	}
	if(iColumn == iColumnCount)
		iColumn = -1;

	return (iRow != -1 && iColumn != -1);
}

void CListCtrlEx::RepaintSelectedItems()
{
	CRect rcItem;
	CRect rcLabel;

	// Invalidate focused item so it can repaint

	int iItem = GetNextItem(-1, LVNI_FOCUSED);

	if(iItem != -1)
	{
		GetItemRect(iItem, rcItem, LVIR_BOUNDS);
		GetItemRect(iItem, rcLabel, LVIR_LABEL);
		rcItem.left = rcLabel.left;

		InvalidateRect(rcItem, FALSE);
	}

	// Invalidate selected items depending on LVS_SHOWSELALWAYS

	if(!(GetStyle() & LVS_SHOWSELALWAYS))
	{
		for(iItem = GetNextItem(-1, LVNI_SELECTED);
			iItem != -1; iItem = GetNextItem(iItem, LVNI_SELECTED))
		{
			GetItemRect(iItem, rcItem, LVIR_BOUNDS);
			GetItemRect(iItem, rcLabel, LVIR_LABEL);
			rcItem.left = rcLabel.left;

			InvalidateRect(rcItem, FALSE);
		}
	}

	UpdateWindow();
}

/////////////////////////////////////////////////////////////////////////////
// CListCtrlEx message handlers

void CListCtrlEx::OnDestroy() 
{
	m_titletip.DestroyWindow();

	CListCtrl::OnDestroy();
}

void CListCtrlEx::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
	inherited::OnChar(nChar, nRepCnt, nFlags);
	HideTitleTip();
	SendSelChangedNotification();
}

void CListCtrlEx::OnKillFocus(CWnd* pNewWnd) 
{
	CListCtrl::OnKillFocus(pNewWnd);

	// This should be hidden no matter if another control is getting focus
	// or the edit box.
	HideTitleTip();

	// this really still has focus if one of its chilren (ie. the edit box)
	// has focus
	if(pNewWnd != NULL && pNewWnd->GetParent() == this)
		return;

	// repaint items that should change appearance
	if(m_bFullRowSel && (GetStyle() & LVS_TYPEMASK) == LVS_REPORT)
		RepaintSelectedItems();
}

void CListCtrlEx::OnLButtonDown(UINT nFlags, CPoint point)
{
	int iTest = GetKeyState(VK_LMENU);
	// Shortcut to editing.
	if((GetKeyState(VK_LMENU) & 0x8000) || (GetKeyState(VK_RMENU) & 0x8000))
	{
		int iRow;
		int iColumn;
		if(HitTestRowCol(point, iRow, iColumn))
		{
			SetFocus();
			PostMessage(LVM_EDITLABEL, (WPARAM)iRow, 0);
		}
	}
	else
	{
		inherited::OnLButtonDown(nFlags, point);
		ShowTitleTip(point);                    // Make sure TitleTip changes if needed.
		SendSelChangedNotification();
	}
}

void CListCtrlEx::OnMouseMove(UINT nFlags, CPoint point)
{
	if( nFlags == 0 )
	{
		ShowTitleTip(point);                    // Make sure TitleTip changes if needed.
	}
	
	CListCtrl::OnMouseMove(nFlags, point);
}

/*
* When the regular list view control repaints an item, it repaints only the
* area occupied by defined columns. If the last column does not extend to the
* end of the client area, then the space to the right of the last column is
* not repainted. If we are highlighting the full row then this area also needs
* to be invalidated so that the code in DrawItem() can add or remove the
* highlighting from this area.
*/

void CListCtrlEx::OnPaint() 
{
/*for test  ������װ��Header��ͼƬ
CHeaderCtrl* pHeader = GetHeaderCtrl();

HD_ITEM Item;	
pHeader->GetItem( 0, &Item );
CRect ItemRect;
pHeader->GetItemRect( 0, &ItemRect );
CDC *pTmpDC = pHeader->GetDC();
pTmpDC->FillRect( ItemRect, &CBrush(RGB(255,0,0)));
ReleaseDC( pTmpDC );
//for test*/

	// in full row select mode, we need to extend the clipping region
	// so we can paint a selection all the way to the right
	if (m_bClientWidthSel &&
		(GetStyle() & LVS_TYPEMASK) == LVS_REPORT && GetFullRowSel())
	{
		CRect rcAllLabels;
		GetItemRect(0, rcAllLabels, LVIR_BOUNDS);

		CRect rcClient;
		GetClientRect(&rcClient);
		if(rcAllLabels.right < rcClient.right)
		{
			// need to call BeginPaint (in CPaintDC c-tor)
			// to get correct clipping rect
			CPaintDC dc(this);

			CRect rcClip;
			dc.GetClipBox(rcClip);

			rcClip.left = min(rcAllLabels.right-1, rcClip.left);
			rcClip.right = rcClient.right;

			InvalidateRect(rcClip, FALSE);
			// EndPaint will be called in CPaintDC d-tor
		}
	}

	CListCtrl::OnPaint();
}

LRESULT CListCtrlEx::OnSetBkColor(WPARAM wParam, LPARAM lParam)
{
	m_clrBkgnd = (COLORREF)lParam;
	return(Default());
}

/*
* This is another step to mimic the default behaviour of the list view
* control. When the control loses focus, the focus rectangle around the
* selected (focus) item has to be removed. When the control gets back
* focus, then the focus rectangle has to be redrawn. Both these handlers
* call the RepaintSelectedItems() helper function. 
*/

void CListCtrlEx::OnSetFocus(CWnd* pOldWnd) 
{
	CListCtrl::OnSetFocus(pOldWnd);

	// check if we are getting focus from label edit box
//	if(pOldWnd!=NULL && pOldWnd->GetParent()==this)
//		return;

	// repaint items that should change appearance
	if(m_bFullRowSel && (GetStyle() & LVS_TYPEMASK)==LVS_REPORT)
		RepaintSelectedItems();
}

LRESULT CListCtrlEx::OnSetTextBkColor(WPARAM wParam, LPARAM lParam)
{
	m_clrTextBk = (COLORREF)lParam;
	return(Default());
}

LRESULT CListCtrlEx::OnSetTextColor(WPARAM wParam, LPARAM lParam)
{
	m_clrText = (COLORREF)lParam;
	return(Default());
}

void CListCtrlEx::PreSubclassWindow() 
{
	CListCtrl::PreSubclassWindow();

	m_titletip.Create(this);
	m_titletip.SetBackground(CBrush(GetBkColor()));
}

void CListCtrlEx::SendSelChangedNotification()
{
	NMHDR nmh;
	nmh.hwndFrom = *this;
	nmh.idFrom = GetDlgCtrlID();
	nmh.code = LVNU_SELCHANGED;
	GetParent()->SendMessage(WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&nmh);
}

void CListCtrlEx::ShowTitleTip(CPoint point)
{
	int iRow;
	int iCol;

	if(HitTestRowCol(point, iRow, iCol))
	{
		CRect cellrect = GetCellRect(iRow, iCol);
		// offset is equal to TextExtent of 2 space characters.
		// Make sure you have the right font selected into the
		// device context before calling GetTextExtent.
		// You can save this value as a member variable.
		// offset = pDC->GetTextExtent(_T(" "), 1 ).cx*2;
		int offset = 6;
		/*if(iCol == 0)
		{
			CRect rcLabel;
			GetItemRect(iRow, &rcLabel, LVIR_LABEL );
			offset = rcLabel.left - cellrect.left + offset / 2 - 1;
		}*/

		if(iCol == 0)					// TBD: test this with IE4
			cellrect.left -= 2;	// Does it also move the first column???

		cellrect.top--;

		if(GetItemState(iRow, LVIS_SELECTED))
		{
			m_titletip.SetBkColor(::GetSysColor(COLOR_HIGHLIGHT));
			m_titletip.SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));
		}
		else
		{
			m_titletip.SetBkColor(m_clrTextBk);
			m_titletip.SetTextColor(m_clrText);
		}

		m_titletip.Show(cellrect, GetTrueItemText(iRow, iCol), offset-1);
	}
}

void CListCtrlEx::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct) 
{
	if( nFontHeight != -1 )
	{
		lpMeasureItemStruct->itemHeight = nFontHeight + 4 ;
	}
	
	CListCtrl::OnMeasureItem(nIDCtl, lpMeasureItemStruct);
}

void CListCtrlEx::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
	if( nFontHeight != -1 )
	{
		lpMeasureItemStruct->itemHeight = nFontHeight + 4 ;
	}
/*
	logfont lf;
	getfont()->getlogfont( &lf );

	if( lf.lfheight <0 ) lpmeasureitemstruct->itemheight = -lf.lfheight; 
	else
		lpmeasureitemstruct->itemheight = lf.lfheight; 
//*/
}

//sendmessage( wm_windowposchanged, 0, (lparam)&wp );