MFC---List Control的用法总结

  List Control是MFC中经常用到的控件,但是可惜该控件并不支持键盘输入、添加各种控件(Button、ComboBox...)等功能,说白了基本功能就是一个用于显示数据的表格性质控件。那么,对于键盘输入的支持以及控件的添加等功能具体如何实现,在下文中一一详述。

一、基本的使用

1.初始化风格

对于style的(报表风格、单选模式等)设置;对于ExtendedStyle(网格添加、item前添加check box等)的设置;例:

对于一个关联变量为m_Errorlist的List Control初始化:

        LONG lStyle;
	lStyle = GetWindowLong(m_Errorlist.m_hWnd, GWL_STYLE);//获取当前窗口style
	lStyle &= ~LVS_TYPEMASK; //清除显示方式位
	lStyle |= LVS_REPORT; //设置style
	lStyle |= LVS_SINGLESEL;//单选模式
	SetWindowLong(m_Errorlist.m_hWnd, GWL_STYLE, lStyle);//设置style

	DWORD dwStyle = m_Errorlist.GetExtendedStyle();
	dwStyle |= LVS_EX_FULLROWSELECT;//选中某行使整行高亮(只适用与report风格的listctrl)
	dwStyle |= LVS_EX_GRIDLINES;//网格线(只适用与report风格的listctrl)
	dwStyle |= LVS_EX_CHECKBOXES;//item前生成checkbox控件
	m_Errorlist.SetExtendedStyle(dwStyle); //设置扩展风格

2.插入列、行

插入列:参数分别为(列位置0、列标题为Amp Enable、位置居中、列宽度、列索引号0)

m_ErrorList.InsertColumn(0, "Amp Enable", LVCFMT_CENTER, EnableListCtrlRect.Width() * 1 / 1, 0);

插入行:参数分别为(行索引0、行标题)

m_Errorlist.InsertItem(0, "caption");

3.插入子项:参数分别为(行索引号、列索引号、子项内容)

m_ListCtr.SetItemText(0,1,"content");

以上,基本功能结束。

二、Edit Control的添加(键盘输入的支持)

完成效果:双击List Control的子项,会在子项处出现编辑框;输入焦点消失后,将编辑后的内容更新到子项处。实现List Control的可编辑功能。

1.在List Control所在对话框内添加一个编辑框控件,并设为不可见;

2.对List Control添加控件的双击事件NM_DBLCLK,在触发函数内写:

void CAboutListControlDlg::OnNMDblclkList1(NMHDR *pNMHDR, LRESULT *pResult)
{
	LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast(pNMHDR);
	// TODO: 在此添加控件通知处理程序代码
	NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
	CRect rc;
	m_Row = pNMListView->iItem;//获得选中的行  
	m_Col = pNMListView->iSubItem;//获得选中列  


	if (pNMListView->iSubItem != 0) //如果选择的是子项;  
	{
		m_ListControl.GetSubItemRect(m_Row, m_Col, LVIR_LABEL, rc);//获得子项的RECT;  
		m_edit.SetParent(&m_ListControl);//转换坐标为列表框中的坐标  
		m_edit.MoveWindow(rc);//移动Edit到RECT坐在的位置;  
		m_edit.SetWindowText(m_ListControl.GetItemText(m_Row, m_Col));//将该子项中的值放在Edit控件中;  
		m_edit.ShowWindow(SW_SHOW);//显示Edit控件;  
		m_edit.SetFocus();//设置Edit焦点  
		m_edit.ShowCaret();//显示光标  
		m_edit.SetSel(-1);//将光标移动到最后  
	}
	*pResult = 0;
}

以上完成了双击显示编辑框控件,并将原子项内容更新到编辑框内;那么接下来要是实现,输入焦点消失后,编辑框的内容更新到子项内,并隐藏编辑框等待下一次双击动作。

3.给Edit Control添加KillFocus事件,并在触发函数内写:

void CAboutListControlDlg::OnEnKillfocusEdit1()
{
	// TODO: 在此添加控件通知处理程序代码
	CString tem;
	m_edit.GetWindowText(tem);    //得到用户输入的新的内容  
	m_ListControl.SetItemText(m_Row, m_Col, tem);   //设置编辑框的新内容  
	m_edit.ShowWindow(SW_HIDE);                //应藏编辑框 
}

以上,List Control的可编辑功能完成!

三、List Control对于任意控件添加的支持(重点来了!)

以CButton类控件的添加为例!

基本思路:1.生成控件(静态/动态)2.将控件贴到List Control的指定位置 3.如有滚动条,跟随滚动条实现位置更新,且不屏闪(很重要)

1.生成控件:动态控件的生成在下一篇博客:MFC---动态生成任意数量的控件并添加消息响应  会具体介绍;

2.贴控件到指定位置处:(两种方式)

第一种:(只针对动态生成)生成时,将父窗口指针定义为ListControl且Rect为目标处的位置;

CButton *btn = new CButton();
btn->Create(str, bn_dwStyle, Rect, GetDlgItem(IDC_LIST1), IDC_Dynamic_Button0 + ButtonNum);
第二种:(动态/静态都可)控件生成后,这里 rect1同上;
btn->SetParent(&m_ListCtr);//将button设为list ctr的子窗口,即转换为list ctr的坐标!
btn->MoveWindow(rect1);//将button移动到对应位置处

3.List Control存在滚动条情况下,保证贴上去的控件位置跟随滚动条刷新,且防止屏闪

位置刷新:试了很多方法,但其实最简单实用的就是开一个Timer,在OnTimer()中对所贴上去的所有控件,调用 MoveWindow()+Invalidate()函数即可实时重绘/更新窗口;

防屏闪:为了防止重绘一直在进行,导致屏幕的闪烁,最好的办法就是在合适的条件下开启和关闭位置刷新的Timer;

展开来说就是:对ListControl添加触发函数(LVN_BEGINSCROLL),在函数体内Set上述的位置刷新Timer;也即只有在拖动滚动条时才会触发位置刷新,这是在合适的时候开启Timer;

再开一个一直在工作的Timer,在此Timer内不停获取滚动条(水平/垂直)的位置,并不断判断本次触发与上次触发时滚动条位置的变化;如果没有产生变化,则意味着滚动条的拖动停止,此时Kill位置刷新的Timer即可,这是在合适的时间关闭Timer。

附上获取滚动条位置的函数:

m_ListCtr.GetScrollPos(SB_HORZ)//水平滚动条
m_ListCtr.GetScrollPos(SB_VERT)//垂直滚动条

当然,贴上去的控件还得添加消息响应,这部分工作才算完成,见下一篇博客:MFC---动态生成任意数量的控件并添加消息响应 。


以上。



你可能感兴趣的:(MFC)