⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lion-tut-c31.htm

📁 内有一些代码
💻 HTM
📖 第 1 页 / 共 4 页
字号:
型结构体变量中的文件的名称放到pszText中。由于我们要完成对项目的排序,所以必须设置lParam的值,我把它设成行号值,这样我们可以根据索引值来查询项目。</P>
<P>&nbsp; invoke SendMessage,hList, LVM_INSERTITEM,0, addr lvi </P>
<P>设置完所有LV_ITEM型变量中的值后,我们发送LVM_INSERTITEM消息给列表视图控件来把项目插入到其中。</P>
<P>&nbsp; mov lvi.imask,LVIF_TEXT <BR>&nbsp; inc lvi.iSubItem <BR>&nbsp; invoke 
wsprintf,addr buffer, addr template,[edi].nFileSizeLow <BR>&nbsp; lea eax,buffer 
<BR>&nbsp; mov lvi.pszText,eax </P>
<P>我们将把子项目插入到第二列。一个子项目只能有一个标签。这样我们在iMask中指定LVIF_TEXT标志位。接着我们指定子项目所在的列,本例中我们通过将iSubItem加一使得该值等于1。标签值是文件的大小,为了转换成文本我们调用wsprintf函数,然后把文本的地址放到pszText中去。</P>
<P>&nbsp; invoke SendMessage,hList,LVM_SETITEM, 0,addr lvi <BR>&nbsp; assume 
edi:nothing <BR>&nbsp; ret <BR>ShowFileInfo endp <BR></P>
<P>当LV_ITEM型变量中的值设定好之后,我们向列表视图控件发送LVM_SETITEM消息,并一同把LV_ITEM变量的地址传过去。注意:发送的消息是LV_ITEM而不是LVM_INSERTITEM,因为我们插入的是子项目,子项目不是真正的项目而是主项目的属性。所以我们这时是在设定项目的属性,而不是加入一个项目。</P>
<P>当所有的项目都插入到列表视图控件后,我们设定它的文本和背景颜色。</P>
<P>&nbsp;&nbsp;&nbsp; RGB 255,255,255 <BR>&nbsp;&nbsp;&nbsp; invoke 
SendMessage,hList,LVM_SETTEXTCOLOR,0,eax <BR>&nbsp;&nbsp;&nbsp; RGB 0,0,0 
<BR>&nbsp;&nbsp;&nbsp; invoke SendMessage,hList,LVM_SETBKCOLOR,0,eax 
<BR>&nbsp;&nbsp;&nbsp; RGB 0,0,0 <BR>&nbsp;&nbsp;&nbsp; invoke 
SendMessage,hList,LVM_SETTEXTBKCOLOR,0,eax </P>
<P>我们用RGB(R---Red G---Green B---Blue)来把三色转换并放到eax中。我们通过发送LVM_SETTEXTCOLOR 和 
LVM_SETTEXTBKCOLOR 消息来设定文本的前景和背景色。</P>
<P>&nbsp;&nbsp;&nbsp; invoke GetMenu,hWnd <BR>&nbsp;&nbsp;&nbsp; mov hMenu,eax 
<BR>&nbsp;&nbsp;&nbsp; invoke CheckMenuRadioItem,hMenu,IDM_ICON,IDM_LIST, 
IDM_REPORT,MF_CHECKED </P>
<P>我们将让用户通过菜单来选择它想要的显示方式。这样我们必须先得到菜单的句柄。我了让用户跟踪当前的视图,我们在菜单中放入一组单选按钮。我们可以调用CheckMenuRadioItem函数,该函数将把一个单选按钮放到一个菜单项前。</P>
<P>注意我们创建列表视图控件时把它的宽度和高度都设成为0。当父窗口改变大小时,它将同时改变大小。这样我们可以让列表视图总是随着主窗口改变。子我们的例子中,我们让列表视图填充整个客户区。</P>
<P>&nbsp; .elseif uMsg==WM_SIZE<BR>&nbsp;&nbsp;&nbsp; mov eax,lParam 
<BR>&nbsp;&nbsp;&nbsp; mov edx,eax <BR>&nbsp;&nbsp;&nbsp; and eax,0ffffh 
<BR>&nbsp;&nbsp;&nbsp; shr edx,16 <BR>&nbsp;&nbsp;&nbsp; invoke 
MoveWindow,hList, 0, 0, eax,edx,TRUE </P>
<P>当父窗口接收到了WM_SIZE消息后,lParam的底字部分包含了客户区新的宽和高。让后我们调用MoveWindow来改变列表视图控件的大小使得它覆盖整个的客户区。</P>
<P>当用户通过菜单选择了一种选择方式,我们必须相应地改变列表视图中的显示方式。我们调用SetWindowLong函数来设定新的风格。</P>
<P>&nbsp; .elseif uMsg==WM_COMMAND <BR>&nbsp;&nbsp;&nbsp; .if lParam==0 
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke GetWindowLong,hList,GWL_STYLE 
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; and eax,not LVS_TYPEMASK </P>
<P>首先得到当前的风格,然后清除旧的风格。LVS_TYPEMASK 
是LVS_ICON+LVS_SMALLICON+LVS_LIST+LVS_REPORT四种风格的集合。这样当我们用当前的风格“与”“not 
LVS_TYPEMASK”就等于清除了当前的显示风格。</P>
<P>在设计菜单时,我们使用了一些小技巧。我们包显示风格的常数串当作菜单的ID号。</P>
<P>IDM_ICON equ LVS_ICON <BR>IDM_SMALLICON equ LVS_SMALLICON <BR>IDM_LIST equ 
LVS_LIST <BR>IDM_REPORT equ LVS_REPORT </P>
<P>这样当父窗口接收到WM_COMMAND消息时,希望显示的风格值会当成菜单的ID号传递过来。</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov edx,wParam 
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; and edx,0FFFFh </P>
<P>在wParam中的低字部分是欲显示的风格,我们所需要做的只是把高字部分清0。</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push edx <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; or 
eax,edx </P>
<P>我们把希望显示的风格加到列表视图的风格中去(已经去除了旧的风格)。</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke SetWindowLong,hList,GWL_STYLE,eax </P>
<P>调用SetWindowLong函数来设定新的风格。</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pop edx <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
invoke CheckMenuRadioItem,hMenu,IDM_ICON,IDM_LIST, edx,MF_CHECKED 
&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;.endif </P>
<P>我们需要在被选择的显示方式前放入单选按钮。如果要排序,我们必须处理WM_NOTIFY消息。</P>
<P>&nbsp; .elseif uMsg==WM_NOTIFY <BR>&nbsp;&nbsp;&nbsp; push edi 
<BR>&nbsp;&nbsp;&nbsp; mov edi,lParam <BR>&nbsp;&nbsp;&nbsp; assume edi:ptr 
NMHDR <BR>&nbsp;&nbsp;&nbsp; mov eax,[edi].hwndFrom <BR>&nbsp;&nbsp;&nbsp; .if 
eax==hList </P>
<P>当我们接收到了WM_NOTIFY 
消息后,lParam包含了指向NMHDR型结构体变量的指针。我们通过把列表视图控件的值和NMHDR型结构体变量中的hwndFrom成员变量的值比较来判断,如果相等的话我们就可以确定消息是列表视图控件发送的。</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .if [edi].code==LVN_COLUMNCLICK 
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; assume edi:ptr NM_LISTVIEW </P>
<P>如果通知消息是列表视图控件发送的,我们检测该消息是否是LVN_COLUMNCLICK。如果是,它意味着用户点击了列标题条。在接收到LVN_COLUMNCLICK消息后,我们假设lParam参数包含NM_LISTVIEW型结构体变量的指针,NM_LISTVIEW型结构体是NMHDR型结构体的扩展。我们需要知道用户单击了那一列,在iSubItem中的值即是列号,列的编号是从0开始的。</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .if [edi].iSubItem==1 
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .if SizeSortOrder==0 
|| SizeSortOrder==2 </P>
<P>在这里iSubItem的值是1,它表示用户点击的是第二列,即文件的大小。我们用状态变量来保持当前的排序顺序。0代表不用排序,1代表升序,2代表降序。如果该列中的项目/子项目以前没有排序或为降序,我们就把它设成升序。</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke 
SendMessage,hList,LVM_SORTITEMS,1,addr CompareFunc </P>
<P>我们发送消息LVM_SORTITEMS给列表视图控件,在wParam中传递1,在lParam中传递比较函数的参数。注意wParam中的值是用户定义的,用户可以按自己的需要来解释,这里我们把它用作排序的方法。我们先来看看比较函数:</P>
<P>CompareFunc proc uses edi lParam1:DWORD, lParam2:DWORD, SortType:DWORD 
<BR>&nbsp; LOCAL buffer[256]:BYTE <BR>&nbsp; LOCAL buffer1[256]:BYTE <BR>&nbsp; 
LOCAL lvi:LV_ITEM <BR><BR>&nbsp; mov lvi.imask,LVIF_TEXT <BR>&nbsp; lea 
eax,buffer <BR>&nbsp; mov lvi.pszText,eax <BR>&nbsp; mov lvi.cchTextMax,256 </P>
<P>列表视图控件将传递需要比较的两个项目的lParam(LV_ITEM型结构体变量的成员变量)比较函数。您还记得吗?我们在lParam中放置了醒目的索引号。这样我们利用这些索引号查询列表视图来得到项目信息。我们需要的消息是项目/子项目的标签文本。为此我们准备好LV_ITEM 
型结构体变量并在iMask中设置标志位LVIF_TEXT ,在pszText中设置缓冲区的地址,在cchTextMax中设置缓冲区的大小。</P>
<P>&nbsp; .if SortType==1 <BR>&nbsp;&nbsp;&nbsp; mov lvi.iSubItem,1 
<BR>&nbsp;&nbsp;&nbsp; invoke SendMessage,hList,LVM_GETITEMTEXT,lParam1,addr lvi 
</P>
<P>如果SortType的值为1或2,我们知道点击了那一列,1代表根据文件的大小按升序排列所有的项目。2的意思相反。这样我们指定iSubItem为1(代表文件大小列)然后发送LVM_GETITEMTEXT 
消息给列表视图控件来得到在项目的标签文本串。</P>
<P>&nbsp;&nbsp;&nbsp; invoke String2Dword,addr buffer <BR>&nbsp;&nbsp;&nbsp; mov 
edi,eax </P>
<P>调用子定义的String2Dword函数来把字符串转换成一个DWORD值。它将在eax中返回转换后的值,我们把它保存在edi中以便以后比较用。</P>
<P>&nbsp;&nbsp;&nbsp; invoke SendMessage,hList,LVM_GETITEMTEXT,lParam2,addr lvi 
<BR>&nbsp;&nbsp;&nbsp; invoke String2Dword,addr buffer <BR>&nbsp;&nbsp;&nbsp; 
sub edi,eax <BR>&nbsp;&nbsp;&nbsp; mov eax,edi </P>
<P>对lParam2 中的值做同样的操作。当我们得到了两个文件的大小后,就可以比较它们了。比较的规则如下:</P>
<UL>
  <LI>如果第一个项目放在前面,在eax中返回一个负值 
  <LI>如果第二个项目放在前面,在eax中返回一个正值 
  <LI>如果相等,在eax中返回0 </LI></UL>
<P>在我们这里,我们想按升序排列,所以我们只要简单地将第二个项目的文件大小减去第一个项目的文件大小,然后返回放在eax中的值。</P>
<P>&nbsp; .elseif SortType==3 <BR>&nbsp;&nbsp;&nbsp; mov lvi.iSubItem,0 
<BR>&nbsp;&nbsp;&nbsp; invoke SendMessage,hList,LVM_GETITEMTEXT,lParam1,addr lvi 
<BR>&nbsp;&nbsp;&nbsp; invoke lstrcpy,addr buffer1,addr buffer 
<BR>&nbsp;&nbsp;&nbsp; invoke SendMessage,hList,LVM_GETITEMTEXT,lParam2,addr lvi 
<BR>&nbsp;&nbsp;&nbsp; invoke lstrcmpi,addr buffer1,addr buffer <BR></P>
<P>当用户点击文件名字列时,我们必须比较文件的名字。我们先得到文件的名字,然后调用lstrcmpi函数来比较,然后只要简单返回lstrcmpi的值,因为该函数比较使用的规则和我们的相同。</P>
<P>当项目排序后,我们调用UpdateParam函数来更新所有项目的lParam的值来反应出最新的改变。</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke 
UpdatelParam 
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov 
SizeSortOrder,1 </P>
<P>该函数简单地枚举列表视图中所有的项目并且把它们lParam更新成项目的索引号。</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;.elseif [edi].code==NM_DBLCLK 
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke ShowCurrentFocus 
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .endif </P>
<P>如果用户双击某个项目时,我们将显示一个消息框,上面有该项目的有关标签值。我们必须检查NMHDR 中的code值是否是 
NM_DBLCLK。如果是,我们就得到它的标签值并显示在一个消息框中。</P>
<P>ShowCurrentFocus proc <BR>&nbsp;&nbsp; LOCAL lvi:LV_ITEM <BR>&nbsp;&nbsp; 
LOCAL buffer[256]:BYTE <BR><BR>&nbsp;&nbsp; invoke 
SendMessage,hList,LVM_GETNEXTITEM,-1, LVNI_FOCUSED</P>
<P>我们是增么怎么知道某个项目被双击的呢?当单击或双击某个项目时,它的状态被设成“焦点”。即使有多个项目被选中,也仅有一个项目有焦点。我们的工作就是去找到那个有焦点的项目。我们发送LVM_GETNEXTITEM消息给列表视图控件,在lParam中指定期望的状态。如果wParam中时-1的话,表示要搜索所有的项目。有焦点的项目第索引号在eax中返回。</P>
<P>&nbsp;&nbsp; mov lvi.iItem,eax <BR>&nbsp;&nbsp; mov lvi.iSubItem,0 
<BR>&nbsp;&nbsp; mov lvi.imask,LVIF_TEXT <BR>&nbsp;&nbsp; lea eax,buffer 
<BR>&nbsp;&nbsp; mov lvi.pszText,eax <BR>&nbsp;&nbsp;&nbsp;mov 
lvi.cchTextMax,256 <BR>&nbsp;&nbsp; invoke SendMessage,hList,LVM_GETITEM,0,addr 
lvi </P>
<P>发送LVM_GETITEM消息来得到标签。</P>
<P>&nbsp;&nbsp; invoke MessageBox,0, addr buffer,addr AppName,MB_OK </P>
<P>最后我们在一个消息框中显示标签。</P>
<P>如果想在列表视图控件中显示图标,您可以阅读关于树型视图控件的课程。它们的步骤基本上是一样的。</P>
<HR SIZE=1>
<DIV align=center> <font face="宋体"> 
  <SCRIPT language=JavaScript1.1 src="../lion-tut-c13.files/textclick"></SCRIPT>
  <BR>
  </font></DIV>
<font face="宋体"><!-- 10:1 文本广告交换 --> </font> 
<DIV align=center> <font face="宋体"> 
  <SCRIPT language=JavaScript1.1 src="../lion-tut-c13.files/c21.htm"></SCRIPT>
  <!-- 10:1 文本广告交换 --></font></DIV>
<HR SIZE=1>
<DIV align=center>翻译:Lxx.阿龙,校对:LuoYunBin's Win32 ASM Page, <A 
href="http://asm.yeah.net/">http://asm.yeah.net/</A></DIV></BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -