📄 lion-tut-c31.htm
字号:
NULL, LVS_REPORT+WS_CHILD+WS_VISIBLE, 0,0,0,0,hWnd, NULL, hInstance, NULL
<BR> mov hList, eax <BR> invoke
InsertColumn <BR> invoke FillFileInfo <BR>
RGB 255,255,255 <BR> invoke
SendMessage,hList,LVM_SETTEXTCOLOR,0,eax <BR> RGB 0,0,0
<BR> invoke SendMessage,hList,LVM_SETBKCOLOR,0,eax
<BR> RGB 0,0,0 <BR> invoke
SendMessage,hList,LVM_SETTEXTBKCOLOR,0,eax <BR> invoke
GetMenu,hWnd <BR> mov hMenu,eax <BR> invoke
CheckMenuRadioItem,hMenu,IDM_ICON,IDM_LIST, IDM_REPORT,MF_CHECKED <BR>
.elseif uMsg==WM_COMMAND <BR> .if lParam==0
<BR> invoke GetWindowLong,hList,GWL_STYLE
<BR> and eax,not LVS_TYPEMASK
<BR> mov edx,wParam
<BR> and edx,0FFFFh
<BR> push edx <BR>
or eax,edx <BR> invoke
SetWindowLong,hList,GWL_STYLE,eax <BR> pop edx
<BR> invoke
CheckMenuRadioItem,hMenu,IDM_ICON,IDM_LIST, edx,MF_CHECKED
<BR> .endif <BR> .elseif uMsg==WM_NOTIFY
<BR> push edi <BR> mov edi,lParam
<BR> assume edi:ptr NMHDR <BR> mov
eax,[edi].hwndFrom <BR> .if eax==hList
<BR> .if [edi].code==LVN_COLUMNCLICK
<BR> assume edi:ptr NM_LISTVIEW
<BR> .if [edi].iSubItem==1
<BR> .if SizeSortOrder==0
|| SizeSortOrder==2
<BR> invoke
SendMessage,hList,LVM_SORTITEMS,1,addr CompareFunc
<BR> invoke
UpdatelParam
<BR> mov
SizeSortOrder,1 <BR> .else
<BR> invoke
SendMessage,hList,LVM_SORTITEMS,2,addr CompareFunc
<BR> invoke
UpdatelParam
<BR> mov
SizeSortOrder,2 <BR>
.endif <BR> .else
<BR> .if
FileNameSortOrder==0 || FileNameSortOrder==4
<BR> invoke
SendMessage,hList,LVM_SORTITEMS,3,addr CompareFunc
<BR> invoke
UpdatelParam
<BR> mov
FileNameSortOrder,3 <BR>
.else <BR>
invoke SendMessage,hList,LVM_SORTITEMS,4,addr CompareFunc
<BR> invoke
UpdatelParam
<BR> mov
FileNameSortOrder,4 <BR>
.endif <BR> .endif
<BR> assume edi:ptr NMHDR
<BR> .elseif [edi].code==NM_DBLCLK
<BR> invoke ShowCurrentFocus
<BR> .endif <BR> .endif
<BR> pop edi <BR> .elseif
uMsg==WM_SIZE<BR> mov eax,lParam <BR> mov
edx,eax <BR> and eax,0ffffh <BR> shr edx,16
<BR> invoke MoveWindow,hList, 0, 0, eax,edx,TRUE <BR>
.elseif uMsg==WM_DESTROY <BR> invoke PostQuitMessage,NULL
<BR> .else <BR> invoke
DefWindowProc,hWnd,uMsg,wParam,lParam <BR> ret <BR>
.endif <BR> xor eax,eax <BR> ret <BR>WndProc endp <BR>end start </P>
<H3><FONT color=#ff0000>分析:</FONT></H3>
<P>当主窗口创建后要做的第一件事是创建一个列表视图控件应用程序。</P>
<P> .if uMsg==WM_CREATE <BR> invoke CreateWindowEx,
NULL, addr ListViewClassName, NULL, LVS_REPORT+WS_CHILD+WS_VISIBLE,
0,0,0,0,hWnd, NULL, hInstance, NULL <BR> mov hList, eax </P>
<P>我们调用CreateWindowEx来创建窗口,并把窗口类的名称“SysListView32”传给它。缺省的显示方式是报告方式,因为您指定了LVS_REPORT标志作为它的风格。</P>
<P> invoke InsertColumn </P>
<P>创建列表视图控件后,我们向其中插入列。 </P>
<P> LOCAL lvc:LV_COLUMN <BR><BR> mov
lvc.imask,LVCF_TEXT+LVCF_WIDTH <BR> mov lvc.pszText,offset Heading1
<BR> mov lvc.lx,150 <BR> invoke SendMessage,hList, LVM_INSERTCOLUMN,
0, addr lvc</P>
<P>我们指定第一列的宽度和列的标题条,为了在该列中显示文件的名称,我们需要在LV_COLUMN 型结构体变量的成员变量iMask中设定标志位LVCF_TEXT
或
LVCF_WIDTH。我们设定pszText为列标题条文本字符串的值,lx设定为列的宽度(以像素点为单位)。然后我们发送LVM_INSERTCOLUMN消息给列表视图控件,并把该结构体变量传递给它。</P>
<P> or lvc.imask,LVCF_FMT<BR> mov lvc.fmt,LVCFMT_RIGHT </P>
<P>插入完第一列后,我们再插入第二列,单击该列的标题条可以按文件的大小排序。因为我们需要右对齐文本,我们需要在成员变量fmt中指定标志位LVCFMT_RIGHT。我们还必须在成员变量iMask中除了标志位LVCF_TEXT
和 LVCF_WIDTH外还需要指定标志位LVCF_FMT。</P>
<P> mov lvc.pszText,offset Heading2 <BR> mov lvc.lx,100<BR>
invoke SendMessage,hList, LVM_INSERTCOLUMN, 1 ,addr lvc </P>
<P>剩余的代码比较简单。在pszText中放入文本字符串的地址,在lx中放入列的宽度。然后发送消息LVM_INSERTCOLUMN
给列表视图控件,在参数中同时传递列号和结构体变量的地址。</P>
<P>当插入完列后,我们向列表控件中加入项目。</P>
<P> invoke FillFileInfo </P>
<P>FillFileInfo 的代码如下:</P>
<P>FillFileInfo proc uses edi <BR> LOCAL finddata:WIN32_FIND_DATA
<BR> LOCAL FHandle:DWORD <BR><BR> invoke FindFirstFile,addr
FileNamePattern,addr finddata </P>
<P>我们调用FindFirstFile来得到第一个符合搜索标准的的文件的信息。FindFirstFile函数的原型如下</P>
<P><B>FindFirstFile proto pFileName:DWORD, pWin32_Find_Data:DWORD</B></P>
<P><B>pFileName</B>
是用来匹配搜索的文件名的地址。该字符串包含了通配符。在我们的例子中是*.*,这样会搜索当前文件夹中所有的文件。<BR><B>pWin32_Find_Data</B>
是WIN32_FIND_DATA 型的结构体变量的地址,WIN32_FIND_DATA型的结构体变量将用来保存返回的文件的信息。 </P>
<P>如果没有找到匹配的文件,该函数将在eax中返回INVALID_HANDLE_VALUE
。否则将返回一个搜索句柄,您可以用该句柄在FindNextFile函数中来搜索下一个符合条件的文件。</P>
<P> .if eax!=INVALID_HANDLE_VALUE <BR> mov FHandle,eax
<BR> xor edi,edi </P>
<P>如果找到了一个文件,我们在一个变量中保存搜索句柄,并把寄存器edi清零,该寄存器将用作项目的索引号。</P>
<P> .while eax!=0<BR> test
finddata.dwFileAttributes,FILE_ATTRIBUTE_DIRECTORY
<BR> .if ZERO?</P>
<P>在本课中,我们将不处理文件夹,所以我们检查dwFileAttributes成员变量的值是否有FILE_ATTRIBUTE_DIRECTORY
标志,如果有,我们就忽略掉它,然后调用FindNextFile。</P>
<P> invoke
ShowFileInfo,edi, addr finddata
<BR> inc edi
<BR> .endif<BR>
invoke FindNextFile,FHandle,addr finddata
<BR> .endw <BR></P>
<P>我们调用ShowFileInfo函数包文件的名称和大小信息加到列表视图控件中去。然后让edi寄存器加一来增加项目的行号。最后我们调用FindNextFile函数在当前文件夹中继续搜索文件一直到该函数返回0为止(这意味着没有可供搜索的文件了)。
</P>
<P> invoke FindClose,FHandle <BR> .endif <BR> ret
<BR>FillFileInfo endp </P>
<P>当前文件夹中的文件枚举完毕后,我们必须关闭搜索句柄。</P>
<P>先在我们看一下ShowFileInfo函数。该函数由两个参数,一个是项目的索引号(也即行号),另一个是WIN32_FIND_DATA型结构体变量的地址。</P>
<P>ShowFileInfo proc uses edi row:DWORD, lpFind:DWORD <BR> LOCAL
lvi:LV_ITEM <BR> LOCAL buffer[20]:BYTE <BR> mov edi,lpFind
<BR> assume edi:ptr WIN32_FIND_DATA </P>
<P>把WIN32_FIND_DATA 型结构体变量的值放到寄存器edi中。</P>
<P> mov lvi.imask,LVIF_TEXT+LVIF_PARAM <BR> push row <BR> pop
lvi.iItem <BR> mov lvi.iSubItem,0 </P>
<P>我们将传递项目的名称和lParam的值,所以我们在iMask中放入标志位LVIF_TEXT
和LVIF_PARAM。接下来我们在iItem中放入传递进来的行号,另外由于这是主项目我们必须设置iSubItem的值等于0。</P>
<P> lea eax,[edi].cFileName <BR> mov lvi.pszText,eax <BR> push
row <BR> pop lvi.lParam </P>
<P>我们现在要把标签字符串的地址,在这里也就是WIN32_FIND_DATA
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -