// MyHeaderListCtrl.cpp : 实现文件
//
/*
采用自绘的方法如何改变行高(该方法必需要自绘属性):
1)手动添加响应消息 ON_WM_MEASUREITEM_REFLECT() 及消息响应函数 MeasureItem,注意此函数并不是OnMeasureItem函数
2)在MeasureItem函数中更改结构体itemHeight的行高值
3)如何触发该消息,一种简单的调用方法是SendMessage(WM_WINDOWPOSCHANGED, 0, (LPARAM)&wp)发送这个消息,具体的请看
SetRowHeigt函数
*/
#include "stdafx.h"
#include "VEHICLEbusSPY.h"
#include "MyDrawOpaintListCtrl.h"
IMPLEMENT_DYNAMIC(CMyDrawOpaintListCtrl, CListCtrl)
CMyDrawOpaintListCtrl::CMyDrawOpaintListCtrl()
{
m_ItemHeight=-1;
m_MovePos.SetPoint(-1,-1);
m_DragOrgPos.SetPoint(-1,-1);
m_ClikSubitem.SetPoint(-1,-1);
m_DClikItem.SetPoint(-1,-1);
m_bLbuttonDbl=false;
m_bDrag=false;
m_ListSysFont= new CFont;
m_ListSysFont->CreatePointFont(85,_T("Arial"));
m_ListStyle=STYLE_FULLSELECT; //默认整行选中
m_BlkClr=RGB(255,255,255); //背景色默认白色
//左边固定的宽度
m_LeftFixedAreaWidth=20;
m_LeftFixedAreaClr=RGB(236,233,216);
m_EditType=-1;
m_DropDownFrameHeight=0;
m_EditSelStartPos=-1;
m_EditSelEndPos=-1;
m_FullSelectBlkClr=RGB(200,255,200);
m_SelectRectBlkClr=RGB(255,255,255);//白色的
m_MoveSelectBlkClr=RGB(49,106,197);
m_HotSelectBlkClr=RGB(236,233,216);
m_HotNotSelectBlkClr=RGB(49,106,197);
m_NoSelectDrawRow=-1;
m_NoSelectFontHeight=-1;
m_3DSubitem=0;
m_3DSubitemBlkClr=RGB(236,233,216);
m_Not3DsubitemSelClr=RGB(49,106,197);
m_Not3DSubitemBlkClr=RGB(255,255,255);
}
CMyDrawOpaintListCtrl::~CMyDrawOpaintListCtrl()
{
DeleteAllPtr();
DeleteAllSubitemInfo();
}
BEGIN_MESSAGE_MAP(CMyDrawOpaintListCtrl, CListCtrl)
ON_WM_MEASUREITEM_REFLECT()
ON_WM_LBUTTONDBLCLK()
ON_WM_LBUTTONDOWN()
ON_NOTIFY(HDN_BEGINTRACKA, 0, &CMyDrawOpaintListCtrl::OnHdnBegintrack)
ON_NOTIFY(HDN_BEGINTRACKW, 0, &CMyDrawOpaintListCtrl::OnHdnBegintrack)
ON_WM_HSCROLL()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_ERASEBKGND()
ON_WM_PAINT()
ON_EN_KILLFOCUS(IDC_EDIT, &CMyDrawOpaintListCtrl::OnEnKillfocusEdit)
ON_CBN_KILLFOCUS(IDC_COMBOBOX, &CMyDrawOpaintListCtrl::OnCbnKillfocusCombo)
ON_WM_MOUSEWHEEL()
//ON_WM_KILLFOCUS()
ON_WM_CHAR()
ON_WM_RBUTTONDOWN()
ON_WM_VSCROLL()
ON_WM_SIZE()
ON_WM_NCCALCSIZE()
ON_WM_SETFOCUS()
ON_WM_CREATE()
END_MESSAGE_MAP()
BOOL CMyDrawOpaintListCtrl::DeleteAllItems()
{
OnMyDestroyEdit();
OnMyDestroyCombobox();
m_ClikSubitem.SetPoint(-1,-1);
m_DClikItem.SetPoint(-1,-1);
return CListCtrl::DeleteAllItems();
}
void CMyDrawOpaintListCtrl::PreSubclassWindow()
{
// TODO: 在此添加专用代码和/或调用基类
ModifyStyle(0,LVS_OWNERDRAWFIXED);
CListCtrl::PreSubclassWindow();
CHeaderCtrl *pHeader = GetHeaderCtrl();
m_MyHeaderCtrl.SubclassWindow(pHeader->GetSafeHwnd()); //替换旧的表头
m_MyHeaderCtrl.OnMySetParentWnd(this);
if(m_ListStyle & STYLE_NOSCROLL)
{//不需要滚动条
InitializeFlatSB(this->m_hWnd);
FlatSB_EnableScrollBar(this->m_hWnd, SB_BOTH, ESB_DISABLE_BOTH);
}
else if(m_ListStyle & STYLE_NOVRESCROLL)
{
InitializeFlatSB(this->m_hWnd);
FlatSB_EnableScrollBar(this->m_hWnd, SB_BOTH, ESB_DISABLE_BOTH);
}
else if(m_ListStyle & STYLE_NOHORNSCROLL)
{
InitializeFlatSB(this->m_hWnd);
FlatSB_EnableScrollBar(this->m_hWnd, SB_BOTH, ESB_DISABLE_BOTH);
}
}
int CMyDrawOpaintListCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CListCtrl::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: 在此添加您专用的创建代码
return 0;
}
BOOL CMyDrawOpaintListCtrl::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID)
{
// TODO: 在此添加专用代码和/或调用基类
bool bCreateOk=CListCtrl::Create(dwStyle, rect, pParentWnd, nID);
if(m_MyHeaderCtrl.m_hWnd==NULL)
{
CHeaderCtrl *pHeader = GetHeaderCtrl();
m_MyHeaderCtrl.SubclassWindow(pHeader->GetSafeHwnd()); //替换旧的表头
m_MyHeaderCtrl.OnMySetParentWnd(this);
}
return bCreateOk;
}
void CMyDrawOpaintListCtrl::OnMySetRcvHeaderMsgWnd(HWND ihwnd)
{
m_MyHeaderCtrl.m_RcvMsgWnd=ihwnd;
}
//在此更改高度,但该函数是由SendMessage(WM_WINDOWPOSCHANGED, 0, (LPARAM)&wp)消息触发的
void CMyDrawOpaintListCtrl::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
if(m_ItemHeight>0)
lpMeasureItemStruct->itemHeight = m_ItemHeight;
}
BOOL CMyDrawOpaintListCtrl::OnEraseBkgnd(CDC* pDC)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
return true;
return CListCtrl::OnEraseBkgnd(pDC);
}
void CMyDrawOpaintListCtrl::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: 在此处添加消息处理程序代码
// 不为绘图消息调用 CListCtrl::OnPaint()
CRect iClientRect,iHeaderRect;
GetClientRect(&iClientRect); //获得客户区大小
GetDlgItem(0)->GetClientRect(&iHeaderRect);
GetDlgItem(0)->SetRedraw(false);
//创建内存DC
CDC iMemDC;
CBitmap bitmap;
if(iMemDC.GetSafeHdc()!=NULL)
iMemDC.DeleteDC();
iMemDC.CreateCompatibleDC(&dc);
bitmap.CreateCompatibleBitmap(&dc,iClientRect.Width(),iClientRect.Height());
iMemDC.SelectObject(&bitmap);
iMemDC.SelectObject(m_ListSysFont);
iMemDC.FillSolidRect(&iClientRect,m_BlkClr);
DefWindowProc(WM_PAINT,(WPARAM)iMemDC.m_hDC,0);
int iCount=GetItemCount();
if((iCount==0) && (STYLE_FIXEDAREA & m_ListStyle))
{
OnMyReDrawHeaderFixedArea();
iMemDC.FillSolidRect(CRect(0,iHeaderRect.Height(),m_LeftFixedAreaWidth,iClientRect.bottom),m_LeftFixedAreaClr);
iMemDC.MoveTo(0,iHeaderRect.Height());
iMemDC.LineTo(0,iClientRect.bottom);
}
dc.BitBlt(0,iHeaderRect.Height(),iClientRect.Width(),iClientRect.Height(),&iMemDC,0,iHeaderRect.Height(),SRCCOPY);
GetDlgItem(0)->SetRedraw(true);
GetDlgItem(0)->Invalidate();
iMemDC.DeleteDC();
bitmap.DeleteObject();
}
void CMyDrawOpaintListCtrl::OnMySetHeaderUpdate(bool bUpadate)
{
m_MyHeaderCtrl.SetRedraw(bUpadate);
}
//自绘都是一行一行的绘制
void CMyDrawOpaintListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
// TODO: 添加您的代码以绘制指定项
// CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
CDC *pDC;
pDC = CDC::FromHandle(lpDrawItemStruct->hDC); //获得绘制的DC
if(!lpDrawItemStruct)
return;
CRect iClientRect; //客户区大小
CRect iItemRect; //单元格大小
CRect iFrameRect; //画网格线的大小
CRect iDotRect; //画虚框的大小
CRect iTextRect; //输入文字的区域
CRect iAllItemRect; //一整行可输入文字区域的总和
CRect iAllFrameRect;
CPen* pOldPen = NULL;
ITEM_INFO iItemInfo; //主要是按键及整行自绘的参数,如果整行一起绘制则它的字符串只在第0列中,其它列即使有文字也不显示
int iItemDraw=0; //参数值初始为0;
int iItem=lpDrawItemStruct->itemID; //得到自绘的行号
int iColumnCount=GetHeaderCtrl()->GetItemCount(); //得到列数
int iItemCount=GetItemCount();
if(iItem>iItemCount)
return;
//获得按键及整行同时输出的参数
int iSize=m_iItemInfoData.GetSize();
if(iItem<iSize)
iItemDraw=m_iItemInfoData.GetAt(iItem);
else
iItemDraw=0;
iItemInfo.iItemData=iItemDraw;
pDC->SetBkMode(TRANSPARENT); //背景透明
GetClientRect(&iClientRect); //获得DC客户区大小
ITEMS_INFO iItemsInfo;
bool bGetiItemsInfo=false;
int iSubitemCount=0;
if(m_ListStyle & STYLE_SUBITEMCLR)
{
bGetiItemsInfo=OnMyGetiItemInfo(iItem,iItemsInfo); //此处只通过iItem
if(bGetiItemsInfo)
{
if(iItemsInfo.iSubitemInfo!=NULL)
{
iSubitemCount=iItemsInfo.iSubitemInfo->GetSize();
if(iSubitemCount)
{
SUBITEM_INFO SubitemInfo;
SubitemInfo=iItemsInfo.iSubitemInfo->GetAt(0);
}
}
}
}
CPoint iSelectItemArea(-1,-1),iSelectSubitemArea(-1,-1);
if(m_ListStyle & STYLE_MOVESELECT)
{
OnMyGetDragSelectArea(iSelectItemArea,iSelectSubitemArea);
}
//整行是否自绘....iItemInfo.iItemInfo.ItemDraw=0表示不自绘
if((STYLE_ITEMDRAW & m_ListStyle) && iItemInfo.iItemInfo.ItemDraw)
{