📄 lion-tutorial31.htm
字号:
.if SortType==1 <br>
mov lvi.iSubItem,1 <br>
invoke SendMessage,hList,LVM_GETITEMTEXT,lParam1,addr lvi
<br>
invoke String2Dword,addr buffer <br>
mov edi,eax <br>
invoke SendMessage,hList,LVM_GETITEMTEXT,lParam2,addr lvi
<br>
invoke String2Dword,addr buffer <br>
sub edi,eax <br>
mov eax,edi <br>
.elseif SortType==2 <br>
mov lvi.iSubItem,1 <br>
invoke SendMessage,hList,LVM_GETITEMTEXT,lParam1,addr lvi
<br>
invoke String2Dword,addr buffer <br>
mov edi,eax <br>
invoke SendMessage,hList,LVM_GETITEMTEXT,lParam2,addr lvi
<br>
invoke String2Dword,addr buffer <br>
sub eax,edi <br>
.elseif SortType==3 <br>
mov lvi.iSubItem,0 <br>
invoke SendMessage,hList,LVM_GETITEMTEXT,lParam1,addr lvi
<br>
invoke lstrcpy,addr buffer1,addr buffer <br>
invoke SendMessage,hList,LVM_GETITEMTEXT,lParam2,addr lvi
<br>
invoke lstrcmpi,addr buffer1,addr buffer <br>
.else <br>
mov lvi.iSubItem,0 <br>
invoke SendMessage,hList,LVM_GETITEMTEXT,lParam1,addr lvi
<br>
invoke lstrcpy,addr buffer1,addr buffer <br>
invoke SendMessage,hList,LVM_GETITEMTEXT,lParam2,addr lvi
<br>
invoke lstrcmpi,addr buffer,addr buffer1 <br>
.endif <br>
ret <br>
CompareFunc endp <br>
<br>
UpdatelParam proc uses edi <br>
LOCAL lvi:LV_ITEM <br>
<br>
invoke SendMessage,hList, LVM_GETITEMCOUNT,0,0 <br>
mov edi,eax <br>
mov lvi.imask,LVIF_PARAM <br>
mov lvi.iSubItem,0 <br>
mov lvi.iItem,0 <br>
.while edi>0 <br>
push lvi.iItem <br>
pop lvi.lParam <br>
invoke SendMessage,hList, LVM_SETITEM,0,addr lvi <br>
inc lvi.iItem <br>
dec edi <br>
.endw <br>
ret <br>
UpdatelParam endp <br>
<br>
ShowCurrentFocus proc <br>
LOCAL lvi:LV_ITEM <br>
LOCAL buffer[256]:BYTE <br>
<br>
invoke SendMessage,hList,LVM_GETNEXTITEM,-1, LVNI_FOCUSED<br>
mov lvi.iItem,eax <br>
mov lvi.iSubItem,0 <br>
mov lvi.imask,LVIF_TEXT <br>
lea eax,buffer <br>
mov lvi.pszText,eax <br>
mov lvi.cchTextMax,256 <br>
invoke SendMessage,hList,LVM_GETITEM,0,addr lvi <br>
invoke MessageBox,0, addr buffer,addr AppName,MB_OK <br>
ret <br>
ShowCurrentFocus endp <br>
<br>
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM <br>
.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 <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>Analysis:</h3>
<p>The first thing the program does when the main window is created is to create
a listview control.</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>We call <b>CreateWindowEx</b>, passing itthe name of the window class "SysListView32".
The default view is the report view as specified by <b>LVS_REPORT</b> style.</p>
<p> invoke InsertColumn </p>
<p>After the listview control is created, we insert columns into it. </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>We specify the label and the width of the first column, for storing the names
of the files, in <b>LV_COLUMN</b> structure thus we need to set<b> imask</b>
with <b>LVCF_TEXT</b> and <b>LVCF_WIDTH</b> flags. We fill <b>pszText</b> with
the address of the label and <b>lx</b> with the width of the column, in pixels.
When all is done, we send <b>LVM_INSERTCOLUMN</b> message to the listview control,
passing the structure to it.</p>
<p> or lvc.imask,LVCF_FMT<br>
mov lvc.fmt,LVCFMT_RIGHT </p>
<p>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 <b>fmt</b> member, <b>LVCFMT_RIGHT</b>.
We must also specify <b>LVCF_FMT</b> flag in imask, in addition to <b>LVCF_TEXT</b>
and <b>LVCF_WIDTH</b>.</p>
<p> mov lvc.pszText,offset Heading2 <br>
mov lvc.lx,100<br>
invoke SendMessage,hList, LVM_INSERTCOLUMN, 1 ,addr lvc </p>
<p>The remaining code is simple. Put the address of the label in <b>pszText</b>
and the width in<b> lx</b>. Then send <b>LVM_INSERTCOLUMN</b> message to the
listview control, specifying the column number and the address of the structure.</p>
<p>When the columns are inserted, we can fill items in the listview control.</p>
<p> invoke FillFileInfo </p>
<p>FillFileInfo has the following code.</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>We call FindFirstFile to obtain the information of the first file that matches
the search criteria. FindFirstFile has the following prototype:</p>
<p><b>FindFirstFile proto pFileName:DWORD, pWin32_Find_Data:DWORD</b></p>
<p><b>pFileName</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>
<b>pWin32_Find_Data</b> is the address of the <b>WIN32_FIND_DATA</b> structure
that will be filled with information about the file (if found). </p>
<p>This function returns<b> INVALID_HANDLE_VALUE</b> in eax if no matching file
is found. Otherwise it returns a search handle that will be used in subsequent
<b>FindNextFile</b> calls.</p>
<p> .if eax!=INVALID_HANDLE_VALUE <br>
mov FHandle,eax <br>
xor edi,edi </p>
<p>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).</p>
<p> .while eax!=0<br>
test finddata.dwFileAttributes,FILE_ATTRIBUTE_DIRECTORY
<br>
.if ZERO?</p>
<p>In this tutorial, I don't want to deal with the folders yet so I filter them
out by checking <b>dwFileAttributes</b> for files which have <b>FILE_ATTRIBUTE_DIRECTORY</b>
flag set. If they are found, I skip to call FindNextFile.</p>
<p> invoke ShowFileInfo,edi,
addr finddata <br>
inc edi <br>
.endif<br>
invoke FindNextFile,FHandle,addr finddata
<br>
.endw <br>
</p>
<p> 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 <b>FindNextFile</b> to search for the next file in the current
folder until <b>FindNextFile</b> returns 0 (meaning no more file is found).</p>
<p> invoke FindClose,FHandle <br>
.endif <br>
ret <br>
FillFileInfo endp </p>
<p>When all files in the current folder are enumerated, we must close the search
handle.</p>
<p>Now let's look at the <b>ShowFileInfo</b> function. This function accepts two
parameters, the index of the item (row number) and the address of <b>WIN32_FIND_DATA</b>
structure.</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>Store the address of <b>WIN32_FIND_DATA</b> structure in edi.</p>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -