MFC界面美化第四篇----自绘list列表(重绘列表)

1.前言

最近发现读者对我的mfc美化的专栏比较感兴趣,因此在这里进行续写,这里我会计划写几个连续的篇章,包括对MFC按钮的美化,菜单栏的美化,标题栏的美化,list列表的美化,直到最后形成一个完整的成品效果。

2.最终效果展示

3.思路分析

1.编写mfc的list的派生类对 列表进行重绘

2.list和其他的空间有些区别,要分别对标题栏,和内容栏进行重绘。

4.实现的过程

1.在mfc界面,增加空间list

2.修改list的属性

边框:false
静态边缘:false
视图:Reporte
无滚动:true
 

3.声明list的变量

public:CListCtrlComboEx  m_list;

4.OnInitDialog 里面的核心代码

BOOL CCustomListDlg::OnInitDialog()
{CDialogEx::OnInitDialog();// 将“关于...”菜单项添加到系统菜单中。// IDM_ABOUTBOX 必须在系统命令范围内。ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);ASSERT(IDM_ABOUTBOX < 0xF000);CMenu* pSysMenu = GetSystemMenu(FALSE);if (pSysMenu != nullptr){BOOL bNameValid;CString strAboutMenu;bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);ASSERT(bNameValid);if (!strAboutMenu.IsEmpty()){pSysMenu->AppendMenu(MF_SEPARATOR);pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);}}// 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动//  执行此操作SetIcon(m_hIcon, TRUE);			// 设置大图标SetIcon(m_hIcon, FALSE);		// 设置小图标//LIST CRect rect;m_list.GetClientRect(&rect);DWORD dwStyle = m_list.GetExtendedStyle();//dwStyle = (dwStyle | LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER);dwStyle |= dwStyle | LVS_REPORT & ~LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT | LVS_SHOWSELALWAYS | LVS_EX_HEADERDRAGDROP;m_list.SetExtendedStyle(dwStyle);//m_list.SetBom_list.SetItemHeight(25);m_list.SetFontSize(17);m_list.InsertColumn(0, _T("编号"), LVCFMT_CENTER, (rect.Width() / 3) + 30, 0);m_list.InsertColumn(1, _T("菜谱"), LVCFMT_CENTER, (rect.Width() - (rect.Width() / 3) - 30), 1);m_list.InsertColumn(2, _T(""), LVCFMT_CENTER, 1000, 2);m_list.InsertItem(0, _T("1"));m_list.InsertItem(1, _T("2"));m_list.InsertItem(2, _T("3"));m_list.InsertItem(3, _T("4"));m_list.InsertItem(4, _T("5"));m_list.InsertItem(5, _T("6"));m_list.InsertItem(6, _T("7"));m_list.InsertItem(7, _T("8"));m_list.InsertItem(8, _T("9"));m_list.InsertItem(9, _T(""));m_list.InsertItem(10, _T(""));m_list.InsertItem(11, _T(""));// TODO: 在此添加额外的初始化代码return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

5.list重写的对应封装代码

BitMark.h

#pragma once#define BITMARK_MAX			(2500)#define BITMARK_ROWS_DEF		(100)
#define BITMARK_COLS_DEF		(20)class BitMark
{
public:BitMark(void);virtual ~BitMark(void);virtual BOOL	Seek(DWORD uRows, DWORD uCols);virtual void	Set(DWORD uRow, DWORD uCol, BOOL bValid);virtual BOOL	IsValid(DWORD uRow, DWORD uCol);virtual void	Clear();
protected:DWORD	m_uRows, m_uCols;BYTE	m_aBit[BITMARK_MAX];
};

BitMark.cpp

#include "pch.h"
#include "BitMark.h"#ifdef _AFX
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static const char THIS_FILE[] = __FILE__;
#endif
#endifBitMark::BitMark(void)
{ZeroMemory(m_aBit, BITMARK_MAX);
}BitMark::~BitMark(void)
{
}BOOL BitMark::Seek(DWORD uRows, DWORD uCols)
{if((uRows*uCols) > BITMARK_MAX)return FALSE;m_uRows = uRows;m_uCols = uCols;return TRUE;
}void BitMark::Set(DWORD uRow, DWORD uCol, BOOL bValid)
{if((uRow*m_uCols + uCol) >= BITMARK_MAX)return;m_aBit[uRow*m_uCols+ uCol] = ( bValid ? 1 : 0 );
}BOOL BitMark::IsValid(DWORD uRow, DWORD uCol)
{BOOL bValid =FALSE;if((uRow*m_uCols + uCol) >= BITMARK_MAX)return FALSE;if(0 != m_aBit[uRow*m_uCols + uCol])bValid = TRUE;return bValid;
}void BitMark::Clear()
{ZeroMemory(m_aBit, BITMARK_MAX);
}

HeaderCtrlEx.h

#pragma once
#include <afxcmn.h>class HeaderCtrlEx :public CHeaderCtrl
{DECLARE_DYNAMIC(HeaderCtrlEx)protected:DECLARE_MESSAGE_MAP()void OnNMCustomdraw(NMHDR* pNMHDR, LRESULT* pResult);LRESULT OnLayout(WPARAM wParam, LPARAM lParam);afx_msg BOOL OnEraseBkgnd(CDC* pDC);
};

HeaderCtrlEx.cpp

#include "pch.h"
#include "HeaderCtrlEx.h"IMPLEMENT_DYNAMIC(HeaderCtrlEx, CHeaderCtrl)BEGIN_MESSAGE_MAP(HeaderCtrlEx, CHeaderCtrl)ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, &HeaderCtrlEx::OnNMCustomdraw)ON_MESSAGE(HDM_LAYOUT, &HeaderCtrlEx::OnLayout)ON_WM_ERASEBKGND()
END_MESSAGE_MAP()void HeaderCtrlEx::OnNMCustomdraw(NMHDR* pNMHDR, LRESULT* pResult)
{// ref: https://stackoverflow.com/questions/28766659/changing-mfc-list-control-header-colorLPNMCUSTOMDRAW pNMCD = reinterpret_cast<LPNMCUSTOMDRAW>(pNMHDR);// TODO: Add your control notification handler code here*pResult = CDRF_DODEFAULT;if (pNMCD->dwDrawStage == CDDS_PREPAINT){CDC* pDC = CDC::FromHandle(pNMCD->hdc);CRect rect(0, 0, 0, 0);GetClientRect(&rect);//pDC->FillSolidRect(&rect, RGB(215, 235, 226));pDC->FillSolidRect(&rect, RGB(30, 34, 39));*pResult = CDRF_NOTIFYITEMDRAW;}else if (pNMCD->dwDrawStage == CDDS_ITEMPREPAINT){HDITEM hditem;TCHAR buffer[MAX_PATH] = { 0 };SecureZeroMemory(&hditem, sizeof(HDITEM));hditem.mask = HDI_TEXT;hditem.pszText = buffer;hditem.cchTextMax = MAX_PATH;GetItem(pNMCD->dwItemSpec, &hditem);CDC* pDC = CDC::FromHandle(pNMCD->hdc);//pDC->SetTextColor(RGB(0, 0, 0));pDC->SetTextColor(RGB(255, 255, 255));//pDC->SetBkColor(RGB(215, 235, 226));pDC->SetBkColor(RGB(30, 34, 39));//CFont m_pFont;//m_pFont.CreateFont(ConvertWithDPIRatio(31),//    0, 0, 0, FW_MEDIUM,//    FALSE, FALSE,//    0,//    ANSI_CHARSET,              // nCharSet//    OUT_DEFAULT_PRECIS,        // nOutPrecision//    CLIP_DEFAULT_PRECIS,       // nClipPrecision//    DEFAULT_QUALITY,           // nQuality//    DEFAULT_PITCH | FF_SWISS, _T("Arial"));//pDC->SelectObject(m_pFont);CString str(buffer);CRect rect = pNMCD->rc;rect.OffsetRect(6, 0);pDC->DrawText(str, CRect(rect), DT_SINGLELINE | DT_VCENTER);*pResult = CDRF_SKIPDEFAULT;}
}/*
*   Describe: Change the height of table header
*   Author  : Canliang Wu
*   Date    : 2021/12/15
*/
LRESULT HeaderCtrlEx::OnLayout(WPARAM wParam, LPARAM lParam)
{LRESULT lResult = CHeaderCtrl::DefWindowProc(HDM_LAYOUT, 0, lParam);HD_LAYOUT& hdl = *(HD_LAYOUT*)lParam;RECT* prc = hdl.prc;            // The table list rectangleWINDOWPOS* pwpos = hdl.pwpos;   // The table header rectangleint nHeight = (int)(pwpos->cy * 1.3);pwpos->cy = nHeight;            // New table header height//pwpos->x += 3;prc->top = nHeight;             // Decreases the table list height on the table header heightreturn lResult;
}BOOL HeaderCtrlEx::OnEraseBkgnd(CDC* pDC)
{// TODO: Add your message handler code here and/or call default//return CListCtrl::OnEraseBkgnd(pDC);return FALSE;
}

ListControlDefine.h

#pragma once#define ListCtrlMask_Rows			(500)
#define ListCtrlMask_Cols			(20)
#define ListCtrlMask_Max			(ListCtrlMask_Rows * ListCtrlMask_Cols)
typedef struct ListCtrlMask {BYTE	Bit[ListCtrlMask_Max];
} ListCtrlMask;

ListControlDefine.cpp

#include "pch.h"
#include "ListControlDefine.h"

ListCtrlComboEx.h

#if !defined(AFX_LISTCTRLCOMBOEX_H__CF78F101_D071_46A3_BCA8_CB30861448F1__INCLUDED_)
#define AFX_LISTCTRLCOMBOEX_H__CF78F101_D071_46A3_BCA8_CB30861448F1__INCLUDED_#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// ListCtrlComboEx.h : header file#include "ListControlDefine.h"
#include "BitMark.h"
#include "HeaderCtrlEx.h"
#include <afxcmn.h>
#define cgCComboBox CComboBox  //you can use yourself defined combobox
/
// CListCtrlComboEx window
#include <vector>
using namespace std;
struct stEditAble
{int nRow;int nCol;
};struct stComboAble
{int nRow;int nCol;cgCComboBox *pCombo;
};#define IDCB_ONLISTCONTROL			9001#define CListCtrlComboEx_ColumnMax		(200)
class CListCtrlComboEx : public CListCtrl
{
// Construction
public:CListCtrlComboEx();public:UINT	m_nMsgComboSelChange;BitMark	m_oBm;int		m_nRowDblClk;int		m_nColDblClk;int InsertColumn(int nCol, LPCTSTR lpszColumnHeading,int nFormat = LVCFMT_LEFT, int nWidth = -1, int nSubItem = -1);void SetItemWarning(int nItem, int nSubItem, BOOL bValid);int m_anFormat[CListCtrlComboEx_ColumnMax];void	CreateComboBox(UINT nMsgComboSelChange);void	CreateEditBox();CComboBox*	GetCombo();
protected:CComboBox*	m_pcbListCtrl;HeaderCtrlEx m_HeaderCtrl;
protected:vector<stEditAble> m_EditAbleArray;vector<stComboAble> m_ComboAbleArray;int m_iRow;int m_iCol;CEdit *m_pEdit;int m_iHeight;CFont m_oFont;// Attributes
public:void SetEditAble(int nRow,int nCol);void SetComboAble(int nRow,int nCol,cgCComboBox *pCombo);void SetItemHeight(int nHeight);COLORREF GetTableItemColor(int nRow, int nCol, COLORREF clrDef);void ClearAllAbles();BOOL GetCellRect(int nRow, int nCol, CRect& rect);void SetFontSize(int cHeight = 18);BOOL m_bFontSeted;
// Operations
public:virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);
// Overrides// ClassWizard generated virtual function overrides//{{AFX_VIRTUAL(CListCtrlComboEx)//}}AFX_VIRTUAL// Implementation
public:virtual ~CListCtrlComboEx();// Generated message map functions
protected:BOOL IsEditAble(int nRow,int nCol);BOOL IsComboAble(int nRow,int nCol);virtual void PreSubclassWindow();LPCTSTR MakeShortString(CDC *pDC,LPCTSTR lpszLong,int nColumnLen,int nOffset);protected://{{AFX_MSG(CListCtrlComboEx)// NOTE - the ClassWizard will add and remove member functions here.virtual afx_msg void OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult);virtual afx_msg void OnLButtonDown(UINT nFlags, CPoint point);virtual afx_msg BOOL OnHeaderEndResize(UINT, NMHDR* pNMHDR, LRESULT* pResult);afx_msg void OnCbnKillfocusCombo();afx_msg void OnCbnSelchangeCombo();afx_msg BOOL OnEraseBkgnd(CDC* pDC);//}}AFX_MSGDECLARE_DYNAMIC(CListCtrlComboEx)DECLARE_MESSAGE_MAP()
public:afx_msg void OnPaint();
public:afx_msg BOOL OnNMDblclk(NMHDR *pNMHDR, LRESULT *pResult);
};///{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_LISTCTRLCOMBOEX_H__CF78F101_D071_46A3_BCA8_CB30861448F1__INCLUDED_)

ListCtrlComboEx.cpp

// ListCtrlComboEx.cpp : implementation file
//#include "pch.h"
//#include "cgListComboTest.h"
#include "ListCtrlComboEx.h"
//#include "resource.h"#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif/
// CListCtrlComboExCListCtrlComboEx::CListCtrlComboEx()
{m_pcbListCtrl = NULL;m_nRowDblClk = 0;m_nColDblClk = 0;m_bFontSeted = FALSE;m_EditAbleArray.clear();m_ComboAbleArray.clear();m_iRow = -1;m_iCol = -1;m_iHeight = 0;m_pEdit = NULL;m_nMsgComboSelChange = 0;ZeroMemory(&m_anFormat, sizeof(m_anFormat));//m_pListCtrlMask = NULL;
}CListCtrlComboEx::~CListCtrlComboEx()
{if(m_pcbListCtrl) {m_pcbListCtrl->DestroyWindow();delete m_pcbListCtrl;m_pcbListCtrl = NULL;}
}int CListCtrlComboEx::InsertColumn(int nCol, LPCTSTR lpszColumnHeading,int nFormat /*= LVCFMT_LEFT*/, int nWidth /*= -1*/, int nSubItem /*= -1*/)
{if(nCol>=0)m_anFormat[nCol] = nFormat;return CListCtrl::InsertColumn(nCol, lpszColumnHeading, nFormat, nWidth, nSubItem);
}void CListCtrlComboEx::SetItemWarning(int nItem, int nSubItem, BOOL bValid)
{//return;m_oBm.Set(nItem, nSubItem, bValid);
}void CListCtrlComboEx::CreateComboBox(UINT nMsgComboSelChange)
{m_nMsgComboSelChange = nMsgComboSelChange;CFont* cf = GetFont();CComboBox *pCombo;pCombo = new CComboBox();CRect rect;GetCellRect(0,1,rect);pCombo->Create(WS_CHILD/*|WS_VISIBLE*/|CBS_AUTOHSCROLL|CBS_DROPDOWNLIST,rect,(CWnd*)this, IDCB_ONLISTCONTROL);pCombo->SetFont(cf);m_pcbListCtrl = pCombo;
}CComboBox* CListCtrlComboEx::GetCombo()
{return m_pcbListCtrl;
}COLORREF CListCtrlComboEx::GetTableItemColor(int nRow, int nCol, COLORREF clrDef)
{COLORREF clr;clr = clrDef; //RGB(0, 0, 0);//if((nRow*nCol) >= ListCtrlMask_Max)//	return clr;//if(!m_pListCtrlMask)//	return clr;//if(m_pListCtrlMask->Bit[nRow*ListCtrlMask_Cols + nCol])//	clr = RGB(255, 0, 0);if(m_oBm.IsValid(nRow, nCol))clr = RGB(255, 0, 0);//if(myutil::GetBit(m_oWarningBitMark.bit[nRow], nCol))//{//	clr = RGB(255, 0, 0);//}//if(myutil::GetBit(theApp.m_pYmVoltTblRow[nRow].upper_warning_bit, nCol))//{//	clr = RGB(255, 0, 0);//}//if(myutil::GetBit(theApp.m_pYmVoltTblRow[nRow].lower_warning_bit, nCol))//{//	clr = RGB(255, 0, 0);//}//if(m_oVoltTbl.v_row[nRow].v[nCol] > m_nUpper)//{//	clr = RGB(255, 0, 0);//}//if(m_oVoltTbl.v_row[nRow].v[nCol] < m_nLower)//{//	clr = RGB(255, 0, 0);//}//if(theApp.m_pYmVoltTblRow[nRow].V.volt[nCol] < theApp.m_pYmVoltTblRow[nRow].Lower)//{//	clr = RGB(255, 0, 0);//}return clr;
}void CListCtrlComboEx::ClearAllAbles()
{m_EditAbleArray.clear();m_ComboAbleArray.clear();m_iRow = -1;m_iCol = -1;m_pEdit = NULL;
}IMPLEMENT_DYNAMIC(CListCtrlComboEx, CListCtrl)BEGIN_MESSAGE_MAP(CListCtrlComboEx, CListCtrl)//{{AFX_MSG_MAP(CListCtrlComboEx)// NOTE - the ClassWizard will add and remove mapping macros here.ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw)ON_NOTIFY_EX(HDN_ENDTRACKA, 0, OnHeaderEndResize)ON_NOTIFY_EX(HDN_ENDTRACKW, 0, OnHeaderEndResize)ON_WM_MEASUREITEM_REFLECT()ON_WM_LBUTTONDOWN()ON_WM_ERASEBKGND()ON_CBN_KILLFOCUS(IDCB_ONLISTCONTROL, &CListCtrlComboEx::OnCbnKillfocusCombo)ON_CBN_SELCHANGE(IDCB_ONLISTCONTROL, &CListCtrlComboEx::OnCbnSelchangeCombo)//}}AFX_MSG_MAPON_WM_PAINT()ON_NOTIFY_REFLECT_EX(NM_DBLCLK, &CListCtrlComboEx::OnNMDblclk)
END_MESSAGE_MAP()/
// CListCtrlComboEx message handlersvoid CListCtrlComboEx::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult)
{NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>(pNMHDR);int nRow = (int)pLVCD->nmcd.dwItemSpec;pResult = CDRF_DODEFAULT;/*	// Allow column-traits to perform their custom drawingif (pLVCD->nmcd.dwDrawStage & CDDS_SUBITEM){CComboBox* pCombo = GetCellColumnTrait(nRow, pLVCD->iSubItem);if (pCombo != NULL)return;	// Everything is handled by the column-trait}// Always perform drawing of cell-focus rectangleswitch (pLVCD->nmcd.dwDrawStage){case CDDS_PREPAINT:*pResult |= CDRF_NOTIFYITEMDRAW;break;// Before painting a rowcase CDDS_ITEMPREPAINT:{*pResult |= CDRF_NOTIFYPOSTPAINT;	// Ensure row-traits gets called*pResult |= CDRF_NOTIFYSUBITEMDRAW;	// Ensure column-traits gets called} break;// After painting the entire rowcase CDDS_ITEMPOSTPAINT:{;} break;}*/}BOOL CListCtrlComboEx::OnHeaderEndResize(UINT, NMHDR* pNMHDR, LRESULT* pResult)
{int size = m_ComboAbleArray.size();int i;for(i=0;i<size;i++){int nRow = m_ComboAbleArray[i].nRow;int nCol = m_ComboAbleArray[i].nCol;cgCComboBox *pCombo = m_ComboAbleArray[i].pCombo;CRect rect;GetCellRect(nRow,nCol,rect);rect.bottom -=  2*::GetSystemMetrics(SM_CXEDGE);pCombo->MoveWindow(rect);pCombo->SetWindowPos(NULL,		// not relative to any other windows0, 0,		// TopLeft corner doesn't changerect.Width(), (pCombo->GetCount()+1)*rect.Height(),   // existing width, new heightSWP_NOMOVE | SWP_NOZORDER	// don't move box or change z-ordering.);pCombo->ShowWindow(TRUE);}Invalidate(FALSE);return FALSE;
}void CListCtrlComboEx::OnCbnKillfocusCombo()
{int size = m_ComboAbleArray.size();int i;for(i=0;i<size;i++){int nRow = m_ComboAbleArray[i].nRow;int nCol = m_ComboAbleArray[i].nCol;cgCComboBox *pCombo = m_ComboAbleArray[i].pCombo;pCombo->ShowWindow(FALSE);}Invalidate(FALSE);
}void CListCtrlComboEx::OnCbnSelchangeCombo()
{CWnd* P = this->GetParent();if(m_nMsgComboSelChange)P->PostMessage(m_nMsgComboSelChange);int size = m_ComboAbleArray.size();int i;for(i=0;i<size;i++){int nRow = m_ComboAbleArray[i].nRow;int nCol = m_ComboAbleArray[i].nCol;cgCComboBox *pCombo = m_ComboAbleArray[i].pCombo;pCombo->ShowWindow(FALSE);}Invalidate(FALSE);
}void CListCtrlComboEx::SetItemHeight(int nHeight)
{m_iHeight = nHeight;CRect rcWin;GetWindowRect(&rcWin);WINDOWPOS wp;wp.hwnd = m_hWnd;wp.cx = rcWin.Width();wp.cy = rcWin.Height();wp.flags = SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOOWNERZORDER|SWP_NOZORDER;SendMessage(WM_WINDOWPOSCHANGED,0,(LPARAM)&wp);
}BOOL CListCtrlComboEx::GetCellRect(int nRow, int nCol,CRect& rect)
{if (GetSubItemRect(nRow, nCol, LVIR_BOUNDS, rect)==FALSE)return FALSE;CRect colRect;if (GetHeaderCtrl()->GetItemRect(nCol, colRect)==FALSE)return FALSE;if (nCol==0){// Fix bug where LVIR_BOUNDS gives the entire row for nCol==0CRect labelRect;if (GetSubItemRect(nRow, nCol, LVIR_LABEL, labelRect)==FALSE)return FALSE;rect.right = labelRect.right; rect.left  = labelRect.right - colRect.Width();}else{// Fix bug when width is smaller than subitem image widthrect.right = rect.left + colRect.Width();}return TRUE;
}void CListCtrlComboEx::SetFontSize(int cHeight)
{if(m_bFontSeted)return;m_bFontSeted = TRUE;m_oFont.CreateFont(cHeight,                        // nHeight0,                         // nWidth0,                         // nEscapement0,                         // nOrientationFW_NORMAL,                 // nWeightFALSE,                     // bItalicFALSE,                     // bUnderline0,                         // cStrikeOutANSI_CHARSET,              // nCharSetOUT_DEFAULT_PRECIS,        // nOutPrecisionCLIP_DEFAULT_PRECIS,       // nClipPrecisionDEFAULT_QUALITY,           // nQualityDEFAULT_PITCH | FF_SWISS,  // nPitchAndFamily_T("Arial"));                 // lpszFacenameSetFont(&m_oFont, TRUE);}BOOL CListCtrlComboEx::IsEditAble(int nRow,int nCol)
{int i;int size = m_EditAbleArray.size();if(size > 0){for(i=0;i<size;i++){if(m_EditAbleArray[i].nRow == nRow && m_EditAbleArray[i].nCol == nCol)return TRUE;}}return FALSE;
}BOOL CListCtrlComboEx::IsComboAble(int nRow,int nCol)
{int i;int size = m_ComboAbleArray.size();if(size > 0){for(i=0;i<size;i++){if(m_ComboAbleArray[i].nRow == nRow && m_ComboAbleArray[i].nCol == nCol)return TRUE;}}return FALSE;
}void CListCtrlComboEx::SetEditAble(int nRow,int nCol)
{stEditAble sam;sam.nRow = nRow;sam.nCol = nCol;m_EditAbleArray.push_back(sam);
}void CListCtrlComboEx::SetComboAble(int nRow,int nCol,cgCComboBox *pCombo)
{stComboAble sam;sam.nRow = nRow;sam.nCol = nCol;sam.pCombo = pCombo;m_ComboAbleArray.push_back(sam);CRect rect;GetCellRect(nRow,nCol,rect);rect.bottom -=  2*::GetSystemMetrics(SM_CXEDGE);pCombo->SetWindowPos(NULL,		// not relative to any other windows0, 0,		// TopLeft corner doesn't changerect.Width(), (pCombo->GetCount()+1)*rect.Height(),   // existing width, new heightSWP_NOMOVE | SWP_NOZORDER	// don't move box or change z-ordering.);pCombo->ShowWindow(TRUE);pCombo->SetFocus();
}void CListCtrlComboEx::OnLButtonDown(UINT nFlags, CPoint point)
{int nRow, nCol;if(m_pEdit != NULL){CString str;m_pEdit->GetWindowText(str);SetItemText(m_iRow,m_iCol,str);m_iRow = -1;m_iCol = -1;delete m_pEdit;//	m_pEdit->PostMessage(WM_CLOSE);m_pEdit = NULL;}LVHITTESTINFO lvhti = {0};lvhti.pt = point;nRow = ListView_SubItemHitTest(m_hWnd, &lvhti);	// SubItemHitTest is non-constnCol = lvhti.iSubItem;if (!(lvhti.flags & LVHT_ONITEM))nRow = -1;if(nRow == -1 || nCol == -1){CListCtrl::OnLButtonDown(nFlags, point);return;}if(IsEditAble(nRow,nCol)){m_iRow = nRow;m_iCol = nCol;CRect rect;GetCellRect(nRow,nCol,rect);m_pEdit = new CEdit();m_pEdit->Create(WS_CHILD|ES_LEFT|ES_AUTOHSCROLL,rect,this,0);CString str;str = GetItemText(nRow,nCol);m_pEdit->SetWindowText(str);m_pEdit->ShowWindow(SW_SHOW);m_pEdit->SetFocus();return;}CListCtrl::OnLButtonDown(nFlags,point);}void CListCtrlComboEx::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{if(m_iHeight>0){lpMeasureItemStruct->itemHeight = m_iHeight;}}void CListCtrlComboEx::PreSubclassWindow()
{ModifyStyle(0,LVS_OWNERDRAWFIXED);//CListCtrl::PreSubclassWindow();CHeaderCtrl* pHeader = GetHeaderCtrl();if (pHeader != NULL) { VERIFY(m_HeaderCtrl.SubclassWindow(pHeader->m_hWnd)); }CListCtrl::PreSubclassWindow();}void CListCtrlComboEx::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{int nItem = lpDrawItemStruct->itemID;if(nItem == -1)return;CRect rcCol = lpDrawItemStruct->rcItem;CString sText;CDC *pDC = CDC::FromHandle(lpDrawItemStruct->hDC);int nOldDCMode = pDC->SaveDC();LVITEM item;item.iItem = nItem;item.iSubItem = 0;item.mask = LVIF_IMAGE|LVIF_STATE;item.stateMask = 0xFFFF;GetItem(&item);BOOL bSelected = item.state & LVIS_SELECTED;COLORREF color = RGB(30, 34, 39);if(bSelected){pDC->SetBkColor(RGB(30, 34, 39));pDC->SetTextColor(RGB(255,255,255)/*::GetSysColor(COLOR_HIGHLIGHTTEXT)*//*GetTableItemColor(nItem, item.iSubItem)*/);color = RGB(30, 34, 39);}else{pDC->SetBkColor(RGB(30, 34, 39));pDC->SetTextColor(RGB(255,255,255)/*::GetSysColor(COLOR_WINDOWTEXT)*//*GetTableItemColor(nItem, item.iSubItem)*/);}LV_COLUMN lvc;lvc.mask = LVCF_FMT|LVCF_WIDTH;rcCol.right = rcCol.left;for(int nCol=0;GetColumn(nCol,&lvc);nCol++){rcCol.left = rcCol.right;rcCol.right = rcCol.left + GetColumnWidth(nCol);HPEN hOldPen = (HPEN)::SelectObject(lpDrawItemStruct->hDC,::CreatePen(PS_SOLID,1,color));HBRUSH hOldBrush = (HBRUSH)::SelectObject(lpDrawItemStruct->hDC,::CreateSolidBrush(color));::Rectangle(lpDrawItemStruct->hDC,rcCol.left-1,rcCol.top-1,rcCol.right,rcCol.bottom);::DeleteObject(SelectObject(lpDrawItemStruct->hDC,hOldBrush));::DeleteObject(SelectObject(lpDrawItemStruct->hDC,hOldPen));sText = MakeShortString(pDC,GetItemText(nItem,nCol),rcCol.Width(),3);if(bSelected){pDC->SetBkColor(RGB(30, 34, 39));//pDC->SetTextColor(GetTableItemColor(nItem, nCol, ::GetSysColor(COLOR_HIGHLIGHTTEXT)));pDC->SetTextColor(GetTableItemColor(nItem, nCol, RGB(255, 255, 255)));color = RGB(30, 34, 39);}else{pDC->SetBkColor(RGB(30, 34, 39));pDC->SetTextColor(GetTableItemColor(nItem, nCol, RGB(255, 255, 255)));}//在这里进行测试//在这里进行测试UINT format = DT_CENTER;switch(/*lvc.fmt*/m_anFormat[nCol] & (LVCFMT_LEFT | LVCFMT_CENTER | LVCFMT_RIGHT)){case LVCFMT_LEFT:format = DT_LEFT;break;case LVCFMT_CENTER:format = DT_CENTER;break;case LVCFMT_RIGHT:format = DT_RIGHT;break;default:break;}pDC->DrawText(sText,CRect::CRect(rcCol.left+3,rcCol.top,rcCol.right,rcCol.bottom), format/*DT_CENTER*//*format*//*DT_LEFT*/|DT_VCENTER|DT_SINGLELINE );}pDC->RestoreDC(nOldDCMode);}LPCTSTR CListCtrlComboEx::MakeShortString(CDC *pDC,LPCTSTR lpszLong,int nColumnLen,int nOffset)
{static const _TCHAR szThreeDots[] = _T("...");int nStringLen = lstrlen(lpszLong);if(nStringLen == 0 ||(pDC->GetTextExtent(lpszLong,nStringLen).cx+nOffset) <= nColumnLen){return(lpszLong);}static _TCHAR szShort[MAX_PATH];lstrcpy(szShort,lpszLong);int nAddLen = pDC->GetTextExtent(szThreeDots,sizeof(szThreeDots)).cx;for(int i=nStringLen-1; i>0; i--){szShort[i] = 0;if((pDC->GetTextExtent(szShort,i).cx+nAddLen+nOffset) <= nColumnLen){break;}}lstrcat(szShort,szThreeDots);return(szShort);
}
void CListCtrlComboEx::OnPaint()
{//CPaintDC dc(this); // device context for paintingTODO: 在此处添加消息处理程序代码不为绘图消息调用 CListCtrl::OnPaint()////CPaintDC dc(this); // device context for painting//const MSG *msg = GetCurrentMessage();//DefWindowProc( msg->message, msg->wParam, msg->lParam ); //这两句不能省,否则程序会因消息循环出现异常Draw the lines only for LVS_REPORT mode//if( (GetStyle() & LVS_TYPEMASK) == LVS_REPORT )//{//	// Get the number of columns//	CClientDC dc(this );//	CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0);//	int nColumnCount = pHeader->GetItemCount();//	// The bottom of the header corresponds to the top of the line//	RECT rect;//	pHeader->GetClientRect( &rect );//	int top = rect.bottom;//	// Now get the client rect so we know the line length and//	// when to stop//	GetClientRect( &rect );//	// The border of the column is offset by the horz scroll//	int borderx = 0 - GetScrollPos( SB_HORZ ); //	CPen listSepPen(PS_SOLID, 1, RGB(201, 213, 240)); //定制你的分割线的颜色//	//CPen listSepPen(PS_SOLID, 1, RGB(30, 34, 39));//	CPen *pOldPen = dc.SelectObject(&listSepPen);//	for( int i = 0; i < nColumnCount; i++ )//	{//		// Get the next border//		borderx += GetColumnWidth( i );//		// if next border is outside client area, break out//		if( borderx >= rect.right ) break;//		// Draw the line.//		dc.MoveTo( borderx, top);//		dc.LineTo( borderx, rect.bottom );//	}//	// Draw the horizontal grid lines//	// First get the height//	if( !GetItemRect( 0, &rect, LVIR_BOUNDS ))//		return;//	int height = rect.bottom - rect.top;//	GetClientRect( &rect );//	int width = rect.right;//	for(int i = 1; i <= GetCountPerPage(); i++ )//	{//		dc.MoveTo( 0, top + height*i);//		dc.LineTo( width, top + height*i );//	}//	dc.SelectObject(pOldPen);//	//} //-------------------------------替换const MSG* msg = GetCurrentMessage();DefWindowProc(msg->message, msg->wParam, msg->lParam);CClientDC dc(this);CRect rect;GetClientRect(&rect);CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0);int nColumnCount = pHeader->GetItemCount();CRect rectHead;pHeader->GetClientRect(&rectHead);// 画边框//CPen penBorder(PS_SOLID, 1, RGB(0, 66, 66));//CPen* pOldPen = dc->SelectObject(&penBorder);//dc.MoveTo(rect.left, rect.top );//dc.LineTo(rect.left, rect.bottom);//dc.MoveTo(rect.right - 1, rect.top );//dc.LineTo(rect.right - 1, rect.bottom)if ((GetStyle() & LVS_TYPEMASK) == LVS_REPORT){CPen penGrid;//penGrid.CreatePen(PS_SOLID, 1, RGB(0, 66, 66));//颜色penGrid.CreatePen(PS_SOLID, 1, RGB(48, 48, 48));//颜色CPen* oldPen = dc.SelectObject(&penGrid);int borderx = 0 - GetScrollPos(SB_HORZ);//画边框//dc.MoveTo(rect.right, rect.top);//dc.LineTo(rect.left, rect.top);//dc.MoveTo(rect.right, rect.bottom);//dc.LineTo(rect.left, rect.bottom);//dc.MoveTo(rect.left, rect.top);//dc.LineTo(rect.left, rect.bottom);//dc.MoveTo(rect.right, rect.top);//dc.LineTo(rect.right, rect.bottom);//取客户区域CRect item;int nHightPerLine = 18;if (GetItemRect(0, &item, LVIR_BOUNDS)){nHightPerLine = item.bottom - item.top;}//画纵向线for (int i = 0; i < nColumnCount; i++){borderx += GetColumnWidth(i);if (borderx > rect.right){break;}dc.MoveTo(borderx, rectHead.bottom);dc.LineTo(borderx, rect.bottom);}//画横向线for (int i = 0; i <= GetCountPerPage(); i++){dc.MoveTo(rect.left, rectHead.bottom + nHightPerLine * i + 1);dc.LineTo(borderx, rectHead.bottom + nHightPerLine * i + 1);}dc.SelectObject(penGrid);penGrid.DeleteObject();}}BOOL CListCtrlComboEx::OnNMDblclk(NMHDR *pNMHDR, LRESULT *pResult)
{// TODO: 在此添加控件通知处理程序代码*pResult = 0;NM_LISTVIEW* pNMListView=(NM_LISTVIEW*)pNMHDR;m_nRowDblClk=pNMListView->iItem;//m_row为被选中行的行序号(int类型成员变量)m_nColDblClk=pNMListView->iSubItem;//m_column为被选中行的列序号(int类型成员变量)return FALSE;
}BOOL CListCtrlComboEx::OnEraseBkgnd(CDC* pDC)
{// TODO: Add your message handler code here and/or call default//return CListCtrl::OnEraseBkgnd(pDC);return FALSE;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/757797.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Codeforces Round 935 (Div. 3)(A,B,C,D,E,F)

比赛链接 阳间场&#xff0c;阴间题&#xff0c;最考阅读理解的一场。题目本身的难度不大。 A. Setting up Camp 题意&#xff1a; 组委会计划在奥运会结束后带领参赛者进行一次徒步旅行。目前&#xff0c;需要携带的帐篷数量正在计算中。据了解&#xff0c;每个帐篷最多可容…

前端vue3-手动设置滚动条位置/自动定位

从B页面进行xx操作后需要跳转到A页面&#xff0c;并定位到AA职位&#xff0c;上图为A页面。 A页面的左侧是div&#xff0c;内层包裹List组件 给div定义refleftRef,在代码中写如下&#xff1a; function scrollTop() {if (leftRef.value) {console.log(99, leftRef.value);next…

0基础 三个月掌握C语言(13)

数据在内存中的存储 整数在内存中的存储 在讲解操作符时 我们就已经学习了该部分的内容 这里我们回顾一下 整数的二进制表示方法有三种&#xff1a;原码 反码 补码 有符号的整数&#xff08;unsigned&#xff09; 三种表达方式均有符号位和数值位两部分 最高位的一位被当…

文件包含漏洞之包含SESSION(CTF题目)

这次使用的环境是ubuntunginxphpmysql 首先四个文件源码在以下链接中&#xff1a; 一道CTF题&#xff1a;PHP文件包含 | Chybeta 我们注册一个用户名111密码111&#xff0c;然后登录查看cookie和linux的session&#xff0c;因为我们的de服务器 是手动搭建的&#xff0c;所以…

Java IO模型

NIO Java IO 模型1. 什么是IO计算机结构角度应用程序角度 2. 常见的内存模型3. Java中常见的IO模型3.1 BIO&#xff08;Blocking I/O&#xff09;3.2 NIO&#xff08;Non-blocking/New I/O&#xff09;同步非阻塞 IO 模型I/O 多路复用模型 3.3 AIO&#xff08;Asynchronous I/O…

Spring6.1新特性,四种方式调用REST接口(RestClient、WebClient、RestTemplate、HTTP Interface)

个人博客&#xff1a;无奈何杨&#xff08;wnhyang&#xff09; 个人语雀&#xff1a;wnhyang 共享语雀&#xff1a;在线知识共享 Github&#xff1a;wnhyang - Overview 官网 REST Clients :: Spring Framework The Spring Framework provides the following choices for…

电子元器件批发采购中的供应链透明度与可追溯性

电子元器件批发采购中的供应链透明度与可追溯性是非常重要的&#xff0c;特别是考虑到供应链的复杂性和全球化。以下是一些关于如何增强供应链透明度和可追溯性的建议&#xff1a; 供应商审核与选择&#xff1a;对潜在的供应商进行全面的审核和评估&#xff0c;了解其供应链结构…

【Leetcode】1793. 好子数组的最大分数

文章目录 题目思路代码复杂度分析时间复杂度空间复杂度 结果总结 题目 题目链接&#x1f517; 给你一个整数数组 n u m s nums nums &#xff08;下标从 0 0 0 开始&#xff09;和一个整数 k k k 。 一个子数组 ( i , j ) (i, j) (i,j) 的 分数 定义为 m i n ( n u m s …

ROS2从入门到精通0-3:VSCode 搭建 ROS2 工程环境

目录 0 专栏介绍1 Ubuntu下安装VSCode1.1 基本安装1.2 将VSCode添加到侧边栏 2 VSCode集成相关插件3 VSCode运行ROS2环境步骤3.1 安装编译依赖项3.2 创建工作空间和源码空间3.3 启动VSCode与配置 4 测试工程环境4.1 C版本4.2 Python版本 0 专栏介绍 本专栏旨在通过对ROS2的系统…

一、初识 web3

瑾以此系列文章&#xff0c;献给那些出于好奇并且想要学习这方面知识的开发者们 在多数时间里&#xff0c;我们对 web3 的理解是非常模糊的 就好比提及什么是 web1 以及 web2&#xff0c;相关概念的解释是&#xff1a; 1. 从 Web3 的开始 Web3&#xff0c;也被称为Web3.0&…

idea error java:compilation failed:internal java compiler error

idea中编译运行maven项目报错如下 idea error java:compilation failed:internal java compiler error 尝试如下操作 注意&#xff1a;jdk8 需要设置4个地方 1.首先打开File->Project Structure中的Project&#xff0c;将SDK和language level都设置一致&#xff0c;如下…

基于Java的考研专业课程管理系统(Vue.js+SpringBoot)

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 考研高校模块2.3 高校教师管理模块2.4 考研专业模块2.5 考研政策模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 考研高校表3.2.2 高校教师表3.2.3 考研专业表3.2.4 考研政策表 四、系统展示五、核…

文件操作:文本文件(写/读)

文件操作可以将数据永久化&#xff0c;C中对文件操作需要包含头文件 < fstream > 文件类型分为两种&#xff1a; 1. 文本文件&#xff1a;文件以文本的ASCII码形式存储在计算机中 2. 二进制文件&#xff1a;文件以文本的二进制形式存储在计算机中&#xff0c;…

matplotlib绘制统计特征图和分布特征图

文章目录 一、统计特征图绘制1.需求2.代码方法一方法二总结 二、分布特征图绘制1.需求2.代码 一、统计特征图绘制 1.需求 我现在有两个数据集Pdata和Cdata分别在DataFrame对象中&#xff0c;我现在想对这两个数据集进行统计特征分析&#xff0c;并用直方图展示出来。 2.代码…

CSS学习(3)-浮动和定位

一、浮动 1. 元素浮动后的特点 脱离文档流。不管浮动前是什么元素&#xff0c;浮动后&#xff1a;默认宽与高都是被内容撑开&#xff08;尽可能小&#xff09;&#xff0c;而且可以设置宽 高。不会独占一行&#xff0c;可以与其他元素共用一行。不会 margin 合并&#xff0c;…

护眼大路灯好不好用?中国路灯排行榜

护眼大路灯好不好用&#xff1f;关于这个问题一直有争议&#xff0c;一部分人觉得大路灯不好用&#xff0c;而且会增加支出&#xff0c;绝大多数人则认为大路灯特别好用&#xff0c;之所以会有不同的看法&#xff0c;小编觉得&#xff0c;还是大家使用的大路灯不同&#xff0c;…

[C语言]——函数递归

目录 一.什么是递归 1.递归的思想&#xff1a; 二.递归的限制条件 三.递归举例 1.举例1&#xff1a;求n的阶乘 1.1分析和代码实现 1.2画图推演 2.举例2&#xff1a;顺序打印⼀个整数的每⼀位 2.1分析和代码实现 2.2画图推演 四.递归与迭代 1.举例3&#xff1a;求第…

分页多线程处理大批量数据

1.业务场景 因为需要从一个返利明细表中获取大量的数据&#xff0c;生成返利报告&#xff0c;耗时相对较久&#xff0c;作为后台任务执行。但是后台任务如果不用多线程处理&#xff0c;也会要很长时间才能处理完。 另外考虑到数据量大&#xff0c;不能一次查询所有数据在内存…

ROS建模:从零手写机械臂的URDF模型

上一篇博客为【ROS建模&#xff1a;一起从零手写URDF模型】&#xff1a; https://blog.csdn.net/qq_54900679/article/details/135726348?csdn_share_tail%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22135726348%22%2C%22source%22%3A%22qq_5…

EMCC 13.5 完整安装详细版

参考文档&#xff1a; Cloud Control Basic Installation Guide 13.5Overview of the Enterprise Manager Proactive Patch Program (Doc ID 822485.1)Enterprise Manager Cloud Control Management Agent 13.5 Release Update (RU) 19 Bug List (Doc ID 2996590.1)13.5: How …