📄 tut31.html
字号:
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>
</font><font face="Fixedsys">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 </font></p>
<h3><font face="Arial, Helvetica, sans-serif">Analysis:</font></h3>
<p><font face="MS Sans Serif" size="-1">The first thing the program does when
the main window is created is to create a listview control.</font></p>
<p><font face="Fixedsys"> .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 </font></p>
<p><font face="MS Sans Serif" size="-1">We call <font color="#FFFFCC"><b>CreateWindowEx</b></font>,
passing itthe name of the window class "SysListView32". The default
view is the report view as specified by <font color="#CCFFCC"><b>LVS_REPORT</b></font>
style.</font></p>
<p><font face="Fixedsys"> invoke InsertColumn </font></p>
<p><font face="MS Sans Serif" size="-1">After the listview control is created,
we insert columns into it. </font></p>
<p><font face="Fixedsys"> 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</font></p>
<p><font face="MS Sans Serif" size="-1">We specify the label and the width of
the first column, for storing the names of the files, in <font color="#CCFFCC"><b>LV_COLUMN</b></font>
structure thus we need to set<font color="#FFFFCC"><b> imask</b></font> with
<font color="#CCFFCC"><b>LVCF_TEXT</b></font> and <font color="#CCFFCC"><b>LVCF_WIDTH</b></font>
flags. We fill <font color="#FFFFCC"><b>pszText</b></font> with the address
of the label and <font color="#FFFFCC"><b>lx</b></font> with the width of the
column, in pixels. When all is done, we send <font color="#CCFFCC"><b>LVM_INSERTCOLUMN</b></font>
message to the listview control, passing the structure to it.</font></p>
<p><font face="Fixedsys"> or lvc.imask,LVCF_FMT<br>
mov lvc.fmt,LVCFMT_RIGHT </font></p>
<p><font face="MS Sans Serif" size="-1">When we are done with the insertion of
the first column, we insert another column for storing the sizes of the files.
Since we need the sizes to right-align in the column, we need to specify a flag
in <font color="#FFFFCC"><b>fmt</b></font> member, <font color="#CCFFCC"><b>LVCFMT_RIGHT</b></font>.
We must also specify <font color="#CCFFCC"><b>LVCF_FMT</b></font> flag in imask,
in addition to <font color="#CCFFCC"><b>LVCF_TEXT</b></font> and <font color="#CCFFCC"><b>LVCF_WIDTH</b></font>.</font></p>
<p><font face="Fixedsys"> mov lvc.pszText,offset Heading2 <br>
mov lvc.lx,100<br>
invoke SendMessage,hList, LVM_INSERTCOLUMN, 1 ,addr lvc </font></p>
<p><font face="MS Sans Serif" size="-1">The remaining code is simple. Put the
address of the label in <font color="#FFFFCC"><b>pszText</b></font> and the
width in<font color="#FFFFCC"><b> lx</b></font>. Then send <font color="#CCFFCC"><b>LVM_INSERTCOLUMN</b></font>
message to the listview control, specifying the column number and the address
of the structure.</font></p>
<p><font face="MS Sans Serif" size="-1">When the columns are inserted, we can
fill items in the listview control.</font></p>
<p><font face="Fixedsys"> invoke FillFileInfo </font></p>
<p><font face="MS Sans Serif" size="-1">FillFileInfo has the following code.</font></p>
<p><font face="Fixedsys">FillFileInfo proc uses edi <br>
LOCAL finddata:WIN32_FIND_DATA <br>
LOCAL FHandle:DWORD <br>
<br>
invoke FindFirstFile,addr FileNamePattern,addr finddata </font></p>
<p><font face="MS Sans Serif" size="-1">We call FindFirstFile to obtain the information
of the first file that matches the search criteria. FindFirstFile has the following
prototype:</font></p>
<p><font face="MS Sans Serif" size="-1" color="#CCFFCC"><b>FindFirstFile proto
pFileName:DWORD, pWin32_Find_Data:DWORD</b></font></p>
<p><font face="MS Sans Serif" size="-1"><b><font color="#FFFFCC">pFileName</font></b>
is the address of the filename to search for. This string can contain wildcards.
In our example, we use *.*, which amounts to search for all the files in the
current folder.<br>
<font color="#FFFFCC"><b>pWin32_Find_Data</b></font> is the address of the <font color="#CCFFCC"><b>WIN32_FIND_DATA</b></font>
structure that will be filled with information about the file (if found). </font></p>
<p><font face="MS Sans Serif" size="-1">This function returns<font color="#CCFFCC"><b>
INVALID_HANDLE_VALUE</b></font> in eax if no matching file is found. Otherwise
it returns a search handle that will be used in subsequent <font color="#FFFFCC"><b>FindNextFile</b></font>
calls.</font></p>
<p><font face="Fixedsys"> .if eax!=INVALID_HANDLE_VALUE <br>
mov FHandle,eax <br>
xor edi,edi </font></p>
<p><font face="MS Sans Serif" size="-1">If a file is found, we store the search
handle in a variable and then zero out edi which will be used as the index into
the items (row number).</font></p>
<p> <font face="Fixedsys"> .while eax!=0<br>
test finddata.dwFileAttributes,FILE_ATTRIBUTE_DIRECTORY
<br>
.if ZERO?</font></p>
<p><font face="MS Sans Serif" size="-1">In this tutorial, I don't want to deal
with the folders yet so I filter them out by checking <font color="#CCFFCC"><b>dwFileAttributes</b></font>
for files which have <font color="#CCFFCC"><b>FILE_ATTRIBUTE_DIRECTORY</b></font>
flag set. If they are found, I skip to call FindNextFile.</font></p>
<p><font face="Fixedsys">
invoke ShowFileInfo,edi, addr finddata <br>
inc edi <br>
.endif</font><font face="Fixedsys"><br>
invoke FindNextFile,FHandle,addr finddata
<br>
.endw <br>
</font></p>
<p><font face="MS Sans Serif" size="-1"> We insert the name and size of the file
into the listview control by calling ShowFileInfo function. Then we increase
the current row number in edi. Lastly we proceed to call <font color="#FFFFCC"><b>FindNextFile</b></font>
to search for the next file in the current folder until <font color="#FFFFCC"><b>FindNextFile</b></font>
returns 0 (meaning no more file is found).</font></p>
<p><font face="Fixedsys"> invoke FindClose,FHandle <br>
.endif <br>
ret <br>
FillFileInfo endp </font></p>
<p><font face="MS Sans Serif" size="-1">When all files in the current folder are
enumerated, we must close the search handle.</font></p>
<p><font face="MS Sans Serif" size="-1">Now let's look at the <font color="#FFFFCC"><b>ShowFileInfo</b></font>
function. This function accepts two parameters, the index of the item (row number)
and the address of <font color="#CCFFCC"><b>WIN32_FIND_DATA</b></font> structure.</font></p>
<p><font face="Fixedsys">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 </font></p>
<p><font face="MS Sans Serif" size="-1">Store the address of <font color="#CCFFCC"><b>WIN32_FIND_DATA</b></font>
structure in edi.</font></p>
<p><font face="Fixedsys"> mov lvi.imask,LVIF_TEXT+LVIF_PARAM <br>
push row <br>
pop lvi.iItem <br>
mov lvi.iSubItem,0 </font></p>
<p><font face="MS Sans Serif" size="-1">We will supply the label of the item and
the value in lParam so we put <font color="#CCFFCC"><b>LVIF_TEXT</b></font>
and <font color="#CCFFCC"><b>LVIF_PARAM</b></font> flags into imask. Next we
set the iItem to the row number passed to the function and since this is the
main item, we must filliSubItem with 0 (column 0).</font></p>
<p><font face="Fixedsys"> lea eax,[edi].cFileName <br>
mov lvi.pszText,eax <br>
push row <br>
pop lvi.lParam </font></p>
<p><font face="MS Sans Serif" size="-1">Next we put the address of the label,
in this case, the name of the file in <font color="#CCFFCC"><b>WIN32_FIND_DATA</b></font>
structure, into <font color="#FFFFCC"><b>pszText</b></font>. Because we will
implement sorting in the listview control, we must fill <font color="#FFFFCC"><b>lParam</b></font>
with a value. I choose to put the row number into this member so I can retrieve
the item info by its index.</font></p>
<p><font face="Fixedsys"> invoke SendMessage,hList, LVM_INSERTITEM,0, addr
lvi </font></p>
<p><font face="MS Sans Serif" size="-1">When all necessary fields in <font color="#CCFFCC"><b>LV_ITEM</b></font>
are filled, we send <font color="#CCFFCC"><b>LVM_INSERTITEM</b></font> message
to the listview control to insert the item into it. </font></p>
<p><font face="Fixedsys"> mov lvi.imask,LVIF_TEXT <br>
inc lvi.iSubItem <br>
invoke wsprintf,addr buffer, addr template,[edi].nFileSizeLow <br>
lea eax,buffer <br>
mov lvi.pszText,eax </font></p>
<p><font face="MS Sans Serif" size="-1">We will set the subitem associated with
the item just inserted into the second column. A subitem can only have a label.
Thus we specify <font color="#CCFFCC"><b>LVIF_TEXT</b></font> in imask. Then
we specify the column that the subitem should reside in <font color="#FFFFCC"><b>iSubItem</b></font>.
In this case, we set it to 1 by incrementing <font color="#FFFFCC"><b>iSubItem</b></font>.
The label we will use is the size of the file. However, we must convert it to
a string first by calling <font color="#FFFFCC"><b>wsprintf</b></font>. Then
we put the address of the string into <font color="#FFFFCC"><b>pszText</b></font>.
</font></p>
<p><font face="Fixedsys"> invoke SendMessage,hList,LVM_SETITEM, 0,addr
lvi <br>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -