📄 vc中使用listctrl经验总结(1.htm
字号:
i=0;i<2;i++)<BR> {<BR> lvcolumn.mask = LVCF_FMT | LVCF_SUBITEM |
LVCF_TEXT <BR> | LVCF_WIDTH |
LVCF_ORDER;<BR> lvcolumn.fmt = LVCFMT_LEFT;<BR> lvcolumn.pszText =
rgtsz[i];<BR> lvcolumn.iSubItem = i;<BR> lvcolumn.iOrder =
i;<BR> if(i==0)<BR> {<BR> lvcolumn.cx =
rect.Width()*3/5 ; <BR> }<BR> else<BR> lvcolumn.cx =
rect.Width()*2/5;<BR> </P>
<P> m_listctrl.InsertColumn(i, &lvcolumn);<BR> }</P>
<P>这是插入两列的做法,你要插入20列??随便你,依样画葫芦~~</P>
<P> lvcolumn.mask 中那个mask可以有各种属性,具体去看msdn吧,</P>
<P> </P>
<P>条款三:把记录,插入列表框中</P>
<P> int nIndex = m_listctrl.GetItemCount();</P>
<P> LV_ITEM lvitemAdd = {0};<BR> lvitemAdd.mask =
LVIF_TEXT;<BR> lvitemAdd.iItem = nIndex ;<BR> lvitemAdd.iSubItem =
0;<BR> lvitemAdd.pszText =_T("毛毛1");;</P>
<P> <BR> if (m_listctrl.InsertItem(&lvitemAdd) != -1)<BR> {
<BR> LV_ITEM lvitem = {0};<BR> lvitem.mask =
LVIF_TEXT;<BR> lvitem.iItem = nIndex ;<BR>
lvitem.iSubItem = 1;<BR> <BR> lvitem.pszText
=_T("毛毛2");<BR> m_listctrl.SetItem(&lvitem);<BR>
<BR> }</P>
<P>nIndex 是当前的行数,然后把新的一行,插在最下面,</P>
<P> </P>
<P>条款四:给列表中插入图标</P>
<P> 在report格式中,也能插入图标</P>
<P> 继续代码说话</P>
<P> m_image是个CImageList对象</P>
<P> m_image.Create(16,16, TRUE|ILC_COLOR24, 3, 1);</P>
<P> m_listctrl.SetImageList(&m_image,LVSIL_SMALL);</P>
<P>然后调用CImageList的成员函数int CImageList::Add( HICON hIcon );</P>
<P>把ICON插入到imagelist,</P>
<P> 然后在插入记录的时候</P>
<P> lvitemAdd.mask = LVIF_TEXT; -》 lvitemAdd.mask = </P>
<P>LVIF_TEXT|LVIF_IMAGE</P>
<P> 然后添加一个lvitemAdd.iImage = n;</P>
<P> 这个n是imagelist中的序号,表示是具体的哪一个图标,list么,呵呵</P>
<P> </P>
<P>条款五: 插入记录时使用额外的信息,lParam 的使用</P>
<P> 有时候,你想对于某一行,加入一些额外的信息,那么就可以使用这个</P>
<P>lParam </P>
<P> msdn是这么描述的Specifies the 32-bit value of the item</P>
<P> 我上次是为了在某一行加入一个信息,窗口句柄,然后是这么加的,</P>
<P> int nIndex = m_listctrl.GetItemCount();</P>
<P> LV_ITEM lvitemAdd = {0};<BR> lvitemAdd.mask =
LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM;<BR> lvitemAdd.iItem = nIndex ;<BR>
lvitemAdd.iSubItem = 0;<BR> lvitemAdd.pszText =_T("毛毛1");;</P>
<P> lvitemAdd.iImage = n;<BR> lvitemAdd.lParam =
(LPARAM)hwnd;(某个窗口的窗口句柄)</P>
<P><BR> if (m_listctrl.InsertItem(&lvitemAdd) != -1)<BR> {
<BR> LV_ITEM lvitem = {0};<BR> lvitem.mask =
LVIF_TEXT;<BR> lvitem.iItem = nIndex ;<BR>
lvitem.iSubItem = 1;<BR> <BR> lvitem.pszText
=_T("毛毛2");<BR> m_listctrl.SetItem(&lvitem);<BR>
<BR> }</P>
<P>ok,这是一个比较全的例子的,又插ICON,又使用PARAM的</P>
<P>条款六 : 点击列表框,获取选中行信息</P>
<P> 响应NM_CLICK消息,如果你有MSDN,可以看到,有专门关于listview的</P>
<P>NM_CLICK的介绍</P>
<P>void CMyDlg::OnItemClick(NMHDR* pNMHDR, LRESULT* pResult) <BR>{<BR> //
TODO: Add your control notification handler code here<BR> int nItem =
-1;<BR> <BR> LPNMITEMACTIVATE lpNMItemActivate =
(LPNMITEMACTIVATE)pNMHDR;</P>
<P> if(lpNMItemActivate != NULL)<BR> {<BR>
nItem = lpNMItemActivate->iItem;<BR> }</P>
<P>} </P>
<P>现在nItem就是点击选中那行的index了,有了index,获取那行的信息还难吗</P>
<P>?</P>
<P>懒汉说:难,因为你还没讲,晕,那就继续说</P>
<P> </P>
<P>条款七: 根据行的index,获取该行的信息</P>
<P> 直接上代码吧</P>
<P> LV_ITEM lvitem = {0};<BR> lvitem.iItem = nIndex;<BR>
lvitem.iSubItem = 0;<BR> lvitem.mask =
LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM;</P>
<P>m_listctrl.GetItem(&lvitem)</P>
<P>这样,就把nindex,第一列的信息取出来了,包括刚才我们加入的ICON,和那个</P>
<P>额外信息(窗口句柄),</P>
<P>比如我要获取窗口句柄,就可以hwnd = (HWND)lvitem.lParam; </P>
<P>mask 用来指明你想获取那些信息</P>
<P>具体可以查msdn中LVITEM Structure的定义和CListCtrl::GetItem</P>
<P> </P>
<P>条款八:用程序选中某一行,使之选中</P>
<P>选中之 </P>
<P>m_listctrl.SetItemState</P>
<P>(nIndex,LVIS_SELECTED|LVIS_FOCUSED,LVIS_SELECTED|LVIS_FOCUSED);</P>
<P>不选中,取消选中之</P>
<P>m_listctrl.SetItemState(nIndex,0,LVIS_SELECTED|LVIS_FOCUSED);</P>
<P> </P>
<P>条款九:获取当前所有选中的行(多选)</P>
<P> 这个,俺就比较懒了,抄msdn的代码吧,反正很简单</P>
<P> </P>
<P>Example<BR>// CListCtrl* pListCtrl = (CListCtrl*) GetDlgItem</P>
<P>(IDC_YOURLISTCONTROL);<BR>ASSERT(pListCtrl != NULL);</P>
<P>POSITION pos = pList->GetFirstSelectedItemPosition();<BR>if (pos ==
NULL)<BR> TRACE0("No items were
selected!\n");<BR>else<BR>{<BR> while (pos)<BR>
{<BR> int nItem =
pList->GetNextSelectedItem(pos);<BR> TRACE1("Item %d
was selected!\n", nItem);<BR> // you could do your own
processing on nItem here<BR> }<BR>}</P>
<P> </P>
<P>条款十:删除条款九中选中的行</P>
<P> 这个相对前面九个条款是比较麻烦的,因为如果你要删除多行的话。往往要出错</P>
<P> 比如,我现在要删除第0行和第1行(列表的行序列是从0开始的)</P>
<P> 那么好啊。我来删了</P>
<P> m_listctrl.DeleteItem(0)</P>
<P> m_listctrl.DeleteItem(1)</P>
<P> 恭喜你,错了,我好开心啊 :)</P>
<P> 因为你删除第0行以后,下面的行会往上移,那么原来的第1行就变成了第0行,那么你再
m_listctrl.DeleteItem(1),那么删除的是原来的第2行,真麻烦,</P>
<P> 所以,只有从下往上删,才是安全的,先删的,不会影响后面的操作,</P>
<P> m_listctrl.DeleteItem(1)</P>
<P> m_listctrl.DeleteItem(0)</P>
<P> 但有时候,我们也不知道要删除哪些行,只知道要删除选中的那些行,像条款九中的那些</P>
<P> 如果我们还是用</P>
<P> </P>
<P>POSITION pos = m_listctrl.GetFirstSelectedItemPosition();<BR>if (pos ==
NULL)<BR> TRACE0("No items were
selected!\n");<BR>else<BR>{<BR> while (pos)<BR>
{<BR> int nItem =
m_listctrl.GetNextSelectedItem(pos);<BR> </P>
<P> m_listctrl.DeleteItem(nItem );</P>
<P> }<BR>}</P>
<P>你就等着收尸吧</P>
<P>这时候我们就要B4微软了,为虾米木有GetLastselectedItemPosition 和GetPrevSelectedItem</P>
<P>多写一对成员函数会死啊 :(</P>
<P> 没办法,办法自己想,这里有个笨办法</P>
<P> POSITION sSelPos = NULL;</P>
<P> while(sSelPos =
m_listctrl.GetFirstSelectedItemPosition())<BR> {<BR>
int nSelItem = -1;<BR>
nSelItem = m_listctrl.GetNextSelectedItem(sSelPos);</P>
<P> if(nSelItem >= 0
&&
nSelItem<m_listctrl.GetItemCount())<BR>
{</P>
<P>
好了,这个nSelItem 就是我们要的DD</P>
<P> }</P>
<P>}</P>
<P>GetNextSelectedItem这个函数,看msdn的用法,其实是返回第一个的index,然后走到下一个选中的行去,所以这么做也是安全的,在实际中,俺也是这么做的,测试也通过,没问题的</P>
<P>当然,还有个办法,先通过GetFirstSelectedItemPosition和GetNextSelectedItem</P>
<P>来获取所有的选中行的index,然后把这些index放到一个数组里,然后再从下往上删</P>
<P>唉真麻烦啊,还要不定数组,不说用new在堆上开吧,那么一个vector总是要的吧,麻烦啊</P>
<P>所以我暂时是用上述的办法来删除,也供大家参考,希望能找到更好的办法。</P>
<P> </P>
<P>好了,今天就暂时先整理上述十点。listctrl其他高级的用法,网上资料也很多,我也暂时不总结,以后有机会再说吧。</P>
<P>搞了好长时间啊,要睡觉去了,累死了 :)</P><BR><BR>
<P id=TBPingURL>Trackback:
http://tb.blog.csdn.net/TrackBack.aspx?PostId=662462</P><BR></DIV>
<DIV class=postFoot>
<SCRIPT src=""></SCRIPT>
[<A title=功能强大的网络收藏夹,一秒钟操作就可以轻松实现保存带来的价值、分享带来的快乐
href="javascript:d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(saveit=window.open('http://wz.csdn.net/storeit.aspx?t='+escape(d.title)+'&u='+escape(d.location.href)+'&c='+escape(t),'keyit','scrollbars=no,width=590,height=300,left=75,top=20,status=no,resizable=yes'));saveit.focus();">收藏到我的网摘</A>]
毛毛发表于 2006年04月13日 23:32:00 </DIV></DIV><LINK
href="http://blog.csdn.net/handsomerun/Services/Pingback.aspx" rel=pingback><!--<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"xmlns:dc="http://purl.org/dc/elements/1.1/"xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/"><rdf:Descriptionrdf:about="http://blog.csdn.net/handsomerun/archive/2006/04/13/662462.aspx"dc:identifier="http://blog.csdn.net/handsomerun/archive/2006/04/13/662462.aspx"dc:title="VC中使用ListCtrl经验总结(1)"trackback:ping="http://tb.blog.csdn.net/TrackBack.aspx?PostId=662462" /></rdf:RDF>-->
<SCRIPT>function hide(){showComment();}</SCRIPT>
<BR>
<DIV class=post>
<DIV class=postTitle>相关文章:</DIV>
<UL class=postText>
<LI><A href="http://blog.csdn.net/lixiaosan/archive/2006/04/07/653563.aspx"
target=_blank>【原】CListCtrl 使用技巧</A> 2006-04-07 <A
href="http://blog.csdn.net/lixiaosan/" target=_blank>lixiaosan</A>
<LI><A href="http://blog.csdn.net/bluelambo/archive/2005/09/14/480505.aspx"
target=_blank>在项目中对CList Ctrl的学习</A> 2005-09-14 <A
href="http://blog.csdn.net/bluelambo/" target=_blank>bluelambo</A>
<LI><A href="http://blog.csdn.net/fairness/archive/2005/03/07/314051.aspx"
target=_blank>CListCtrl使用详解</A> 2005-03-07 <A
href="http://blog.csdn.net/fairness/" target=_blank>fairness</A>
<LI><A href="http://blog.csdn.net/wfongcn/archive/2006/04/05/652096.aspx"
target=_blank>List ctrl 使用笔记</A> 2006-04-05 <A
href="http://blog.csdn.net/wfongcn/" target=_blank>wfongcn</A>
<LI><A href="http://blog.csdn.net/xmlscript/archive/2004/11/11/177068.aspx"
target=_blank>C++控件之 CList</A> 2004-11-11 <A
href="http://blog.csdn.net/xmlscript/"
target=_blank>xmlscript</A></LI></UL></DIV><BR><BR>
<DIV class=post id=csdn_zhaig_ad_yahoo></DIV><SPAN
id=Anthem_Comments.ascx_ltlComments__><SPAN id=Comments.ascx_ltlComments><BR>
<DIV id=comments>
<H3></H3>
<DIV class=post>
<DIV class=postTitle><A title="permalink: 回复:VC中使用ListCtrl经验总结(1)"
href="http://blog.csdn.net/handsomerun/archive/2006/04/13/662462.aspx#433823">#</A> <A
name=433823> </A><A href="http://blog.sina.com.cn/u/1162579663"
target=_blank rel=nofollow>PPG</A> 发表于2006-04-14 22:50:00 IP:
222.94.6.*</DIV>
<DIV class=postText>好文章,收藏一下</DIV></DIV><BR>
<DIV class=post>
<DIV class=postTitle><A title="permalink: 回复:VC中使用ListCtrl经验总结(1)"
href="http://blog.csdn.net/handsomerun/archive/2006/04/13/662462.aspx#455464">#</A> <A
name=455464> </A>yyh9186 发表于2006-06-20 17:11:00 IP:
221.122.51.*</DIV>
<DIV
class=postText>您好,我最近遇到个难缠的问题,看了您的文章后,我想您在listctrl方面一定了解很透彻,希望您能帮我解决这个问题。描述如下:listctrl的托选功能,类似于windows托选功能。我分析分为两种情况:(1)按住鼠标左键进行托选;(2)按住鼠标左键,并按下ctrl键进行托选。
<BR>这个问题我自己实在是搞不定了,希望高手您给出代码,我的邮箱:
<BR>yyh9186@163.com;msn:yyh9186@hotmail.com</DIV></DIV><BR>
<DIV class=post>
<DIV class=postTitle><A title="permalink: 回复:VC中使用ListCtrl经验总结(1)"
href="http://blog.csdn.net/handsomerun/archive/2006/04/13/662462.aspx#455697">#</A> <A
name=455697> </A>毛毛 发表于2006-06-21 10:38:00 IP:
218.4.149.*</DIV>
<DIV class=postText>托选是什么,多选吗??晕
<BR><BR>现在的listctrl,如果选择那个多选的属性(控件属性里有),那么就是;(2)按住鼠标左键,并按下ctrl键进行多选。
<BR><BR>如果你想只是左键多选,那么 <BR>自己模拟的,首先判断鼠标左键单击在了listCtrl里面,然后就截获这个消息,修改消息参数
<BR>WM_LBUTTONDOWN <BR><BR>WPARAM wParam <BR>LPARAM lParam; <BR>wParam
<BR>MK_CONTROL <BR>The CTRL key is down. <BR>wParam=MK_CONTROL <BR>然后继续传递这个消息就得了
<BR><BR>俺没试过,8知道行不行</DIV></DIV><BR>
<DIV class=post>
<DIV class=postTitle><A title="permalink: 回复:VC中使用ListCtrl经验总结(1)"
href="http://blog.csdn.net/handsomerun/archive/2006/04/13/662462.aspx#504119">#</A> <A
name=504119> </A>liuxein 发表于2006-10-19 17:23:00 IP:
61.185.204.*</DIV>
<DIV class=postText>我用你条款一的方法加CheckBox怎么加不上啊</DIV></DIV><BR>
<DIV class=post>
<DIV class=postTitle><A title="permalink: 回复:VC中使用ListCtrl经验总结(1)"
href="http://blog.csdn.net/handsomerun/archive/2006/04/13/662462.aspx#504506">#</A> <A
name=504506> </A>毛毛 发表于2006-10-19 18:42:00 IP:
218.4.149.*</DIV>
<DIV class=postText>to liuxein : <BR>是可以的,注意设成report风格 <BR>另外,只有查出数据以后,才会显示,
<BR><BR>实例代码 <BR><BR>//获得原有风格 <BR>DWORD dwStyle =
::GetWindowLong(plist->m_hWnd, GWL_STYLE); <BR>dwStyle &=
~(LVS_TYPEMASK); <BR>dwStyle &= ~(LVS_EDITLABELS); <BR><BR>//设置新风格
<BR>::SetWindowLong(plist->m_hWnd, GWL_STYLE,
<BR>dwStyle|LVS_REPORT|LVS_NOLABELWRAP|LVS_SHOWSELALWAYS); <BR><BR>//设置扩展风格
<BR>DWORD styles = LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES|LVS_EX_CHECKBOXES;
<BR><BR>ListView_SetExtendedListViewStyleEx(plist->m_hWnd, styles, styles );
<BR><BR>plist->SetExtendedStyle(plist->GetExtendedStyle()|LVS_EX_SUBITEMIMAGES);
<BR><BR><BR>你运气还不错,最近难得上自己的博客,进来来查个东西,正好看到了你的留言,哈哈</DIV></DIV><BR></DIV></SPAN></SPAN>
<SCRIPT language=javascript>
ad_width=468;
ad_height=60;
adcss=2;
unionuser=19;
ad_type='j';
count=5;
</SCRIPT>
<SCRIPT language=javascript src="VC中使用ListCtrl经验总结(1.files/showads.js"
type=text/javascript></SCRIPT>
<SCRIPT language=javascript src="VC中使用ListCtrl经验总结(1.files/showgm.js"
type=text/javascript></SCRIPT>
<SCRIPT type=text/javascript>document.write("<img src=http://counter.csdn.net/pv.aspx?id=24 border=0 width=0 height=0>");</SCRIPT>
<DIV class=CommentForm id=commentform>
<H3>发表评论</H3>
<DIV id=Anthem_PostComment.ascx_UpdatePanel1__>
<DIV id=PostComment.ascx_UpdatePanel1>
<TABLE class=CommentForm>
<TBODY>
<TR>
<TD width=69 height=0></TD>
<TD></TD></TR>
<TR>
<TD width=70>大名:</TD>
<TD align=left><INPUT id=PostComment.ascx_tbName style="WIDTH: 300px"
disabled size=40 name=PostComment.ascx:tbName> <SPAN
id=PostComment.ascx_RequiredFieldValidator2
style="DISPLAY: none; COLOR: red" initialvalue=""
evaluationfunction="RequiredFieldValidatorEvaluateIsValid"
display="Dynamic" errormessage="<br>请输入尊姓大名"
controltovalidate="PostComment.ascx_tbName"><BR>请输入尊姓大名</SPAN> </TD></TR>
<TR>
<TD width=70>网址:</TD>
<TD align=left><INPUT id=PostComment.ascx_tbUrl style="WIDTH: 300px"
disabled size=40 name=PostComment.ascx:tbUrl> </TD></TR>
<TR>
<TD colSpan=3>评论 <SPAN id=PostComment.ascx_RequiredFieldValidator3
style="DISPLAY: none; COLOR: red" initialvalue=""
evaluationfunction="RequiredFieldValidatorEvaluateIsValid"
display="Dynamic" errormessage="<br>请输入评论"
controltovalidate="PostComment.ascx_tbComment"><BR>请输入评论</SPAN> <BR><TEXTAREA id=PostComment.ascx_tbComment style="WIDTH: 381px; HEIGHT: 193px" disabled name=PostComment.ascx:tbComment rows=10 cols=50></TEXTAREA>
</TD></TR>
<TR>
<TD colSpan=3><SPAN
id=Anthem_PostComment.ascx_btnSubmit__></SPAN> </TD></TR>
<TR>
<TD colSpan=3><SPAN id=PostComment.ascx_Message
style="COLOR: red">注册用户才能发表评论。如果你没有登录,请点击<A
href="http://passport.csdn.net/member/UserLogin.aspx?from=http://blog.csdn.net/handsomerun/archive/2006/04/13/662462.aspx">登录</A></SPAN>
</TD></TR></TBODY></TABLE></DIV></DIV></DIV></DIV>
<P id=footer>Powered by: <BR><A id=Footer1_Hyperlink2
href="http://scottwater.com/blog" name=Hyperlink1><IMG
src="VC中使用ListCtrl经验总结(1.files/100x30_Logo.gif" border=0></A> <A
id=Footer1_Hyperlink3 href="http://asp.net/" name=Hyperlink1><IMG
src="VC中使用ListCtrl经验总结(1.files/PoweredByAsp.Net.gif" border=0></A> <BR>Copyright
© 毛毛 </P>
<SCRIPT src="VC中使用ListCtrl经验总结(1.files/counter.js"></SCRIPT>
<SCRIPT type=text/javascript>
<!--
var Page_Validators = new Array(document.getElementById("PostComment.ascx_RequiredFieldValidator2"), document.getElementById("PostComment.ascx_RequiredFieldValidator3"));
// -->
</SCRIPT>
<INPUT id=__EVENTVALIDATION type=hidden
value=/wEWBAL+raDpAgKqtOi0AwLAsuLbDAKi687YCaEdUuRgIvhS8PYPDsd5LslVNRL0
name=__EVENTVALIDATION>
<SCRIPT type=text/javascript>
<!--
var Page_ValidationActive = false;
if (typeof(ValidatorOnLoad) == "function") {
ValidatorOnLoad();
}
function ValidatorOnSubmit() {
if (Page_ValidationActive) {
return ValidatorCommonOnSubmit();
}
else {
return true;
}
}
// -->
</SCRIPT>
</FORM>
<SCRIPT language=javascript type=text/javascript>
<!--
try{
hide();
}
catch(e){
}
//-->
</SCRIPT>
</BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -