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

📄 tut31.html

📁 WINDOWS程序员使用指南--汇编基础
💻 HTML
📖 第 1 页 / 共 5 页
字号:
  &nbsp; assume edi:nothing <br>
  &nbsp; ret <br>
  ShowFileInfo endp <br>
  </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_SETITEM</b></font> 
  message to the listview control, passing to it the address of the <font color="#CCFFCC"><b>LV_ITEM</b></font> 
  structure. Note that we use <font color="#CCFFCC"><b>LVM_SETITEM</b></font>, 
  not <font color="#CCFFCC"><b>LVM_INSERTITEM</b></font> because a subitem is 
  considered as a property of an item. Thus we *set* the property of the item, 
  not inserting a new item.</font></p>
<p><font face="MS Sans Serif" size="-1">When all items are inserted into the listview 
  control, we set the text and background colors of the listview control.</font></p>
<p><font face="Fixedsys"> &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 </font></p>
<p><font face="MS Sans Serif" size="-1">I use RGB macro to convert the red, green,blue 
  values into eax and use it to specify the color we need. We set the foreground 
  and background colors of the text with <font color="#CCFFCC"><b>LVM_SETTEXTCOLOR 
  </b></font>and <font color="#CCFFCC"><b>LVM_SETTEXTBKCOLOR</b></font> messages. 
  We set the background color of the listview control by sending <font color="#CCFFCC"><b>LVM_SETBKCOLOR</b></font> 
  message to the listview control.</font></p>
<p><font face="Fixedsys"> &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 
  </font></p>
<p><font face="MS Sans Serif" size="-1">We will let the user chooses the views 
  he wants via the menu. Thus we must obtain the menu handle first. To help the 
  user track the current view, we put a radio button system in our menu. The menu 
  item that reflects the current view will be preceded by a radio button. That's 
  why we call <font color="#FFFFCC"><b>CheckMenuRadioItem</b></font>. This function 
  will put a radio button before a menu item.</font></p>
<p><font face="MS Sans Serif" size="-1">Note that we create the listview control 
  with width and height equal to 0. It will be resized later whenever the parent 
  window is resized. This way, we can ensure that the size of the listview control 
  will always match that of the parent window. In our example, we want the listview 
  control to fill the whole client area of the parent window.</font></p>
<p><font face="Fixedsys">&nbsp; .elseif uMsg==WM_SIZE<br>
  &nbsp;&nbsp;&nbsp; </font><font face="Fixedsys">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 </font></p>
<p><font face="MS Sans Serif" size="-1">When the parent window receives WM_SIZE 
  message, the low word of lParam contains the new width of the client area and 
  the high word the new height. Then we call<font color="#FFFFCC"><b> MoveWindow</b></font> 
  to resize the listview control to cover the whole client area of the parent 
  window.</font></p>
<p><font face="MS Sans Serif" size="-1">When the user selects a view in the menu. 
  We must change the view in the listview control accordingly. We accomplish this 
  by setting a new style in the listview control with <font color="#FFFFCC"><b>SetWindowLong</b></font>.</font></p>
<p><font face="Fixedsys">&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 </font></p>
<p><font face="MS Sans Serif" size="-1">The first thing we do is to obtain the 
  current styles of the listview control. Then we clear the old view style from 
  the returned style flags. <font color="#CCFFCC"><b>LVS_TYPEMASK</b></font> is 
  a constant that is the combined value of all 4 view style constants (<font color="#CCFFCC"><b>LVS_ICON+LVS_SMALLICON+LVS_LIST+LVS_REPORT</b></font>). 
  Thus when we perform <font color="#FFCCCC"><b>and</b></font> operation on the 
  current style flags with the value &quot;not LVS_TYPEMASK&quot;, it amounts 
  to clearing away the current view style.</font></p>
<p><font face="MS Sans Serif" size="-1">In designing the menu, I cheat a little. 
  I use the view style constants as the menu IDs.</font></p>
<p><font face="Fixedsys">IDM_ICON equ LVS_ICON <br>
  IDM_SMALLICON equ LVS_SMALLICON <br>
  IDM_LIST equ LVS_LIST <br>
  IDM_REPORT equ LVS_REPORT </font></p>
<p><font face="MS Sans Serif" size="-1">Thus when the parent window receives WM_COMMAND 
  message, the desired view style is in the low word of wParam as the menu ID.</font></p>
<p><font face="Fixedsys"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov edx,wParam <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; and edx,0FFFFh </font></p>
<p><font face="MS Sans Serif" size="-1">We have the desired view style in the 
  low word of wParam. All we have to do is to zero out the high word.</font></p>
<p><font face="Fixedsys"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push edx <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; or eax,edx </font></p>
<p><font face="MS Sans Serif" size="-1">And add the desired view style to the 
  existing styles (minus the current view style) of the listview control.</font></p>
<p><font face="Fixedsys"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke SetWindowLong,hList,GWL_STYLE,eax 
  </font></p>
<p><font face="MS Sans Serif" size="-1">And set the new styles with <font color="#FFFFCC"><b>SetWindowLong</b></font>.</font></p>
<p><font face="Fixedsys"> &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 </font></p>
<p><font face="MS Sans Serif" size="-1">We also need to put the radio button in 
  front of the selected view menu item. Thus we call <font color="#FFFFCC"><b>CheckMenuRadioItem</b></font>, 
  passing the current view style (double as menu ID) to it.</font></p>
<p><font face="MS Sans Serif" size="-1">When the user clicks on the column headers 
  in the report view, we want to sort the items in the listview control. We must 
  respond to <font color="#CCFFCC"><b>WM_NOTIFY</b></font> message.</font></p>
<p><font face="Fixedsys">&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 </font></p>
<p><font face="MS Sans Serif" size="-1">When we receive <font color="#CCFFCC"><b>WM_NOTIFY</b></font> 
  message, lParam contains the pointer to an <font color="#CCFFCC"><b>NMHDR</b></font> 
  structure. We can check if this message is from the listview control by comparing 
  the<font color="#FFFFCC"><b> hwndFrom</b></font> member of <font color="#CCFFCC"><b>NMHDR</b></font> 
  to the handle to the listview control. If they match, we can assume that the 
  notification came from the listview control.</font></p>
<p><font face="Fixedsys"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .if [edi].code==LVN_COLUMNCLICK 
  <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; assume edi:ptr NM_LISTVIEW </font></p>
<p><font face="MS Sans Serif" size="-1">If the notification is from the listview 
  control, we check if the code is <font color="#CCFFCC"><b>LVN_COLUMNCLICK</b></font>. 
  If it is, it means the user clicks on a column header. In the case that the 
  code is <font color="#CCFFCC"><b>LVN_COLUMNCLICK</b></font>, we can assume that 
  lParam contains the pointer to an <font color="#CCFFCC"><b>NM_LISTVIEW</b></font> 
  structure which is a superset of the <font color="#CCFFCC"><b>NMHDR</b></font> 
  structure. We then need to know on which column header the user clicks. Examination 
  of <font color="#FFFFCC"><b>iSubItem</b></font> member reveals this info. The 
  value in iSubItem can be treated as the column number, starting from 0.</font></p>
<p><font face="Fixedsys"> &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 </font></p>
<p><font face="MS Sans Serif" size="-1">In the case iSubItem is 1, it means the 
  user clicks on the second column, size. We use state variables to keep the current 
  status of the sorting order. 0 means &quot;no sorting yet&quot;, 1 means &quot;sort 
  ascending&quot;, 2 means &quot;sort descending&quot;. If the items/subitems 
  in the column are not sorted before, or sorted descending, we set the sorting 
  order to ascending.</font></p>
<p><font face="Fixedsys"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  invoke SendMessage,hList,LVM_SORTITEMS,1,addr CompareFunc </font></p>
<p><font face="Fixedsys"> </font><font face="MS Sans Serif" size="-1">We send 
  <font color="#CCFFCC"><b>LVM_SORTITEMS</b></font> message to the listview control, 
  passing 1 in wParam and the address of our comparison function in lParam. Note 
  that the value in wParam is user-defined, you can use it in any way you like. 
  I use it as the sorting method in this example. We will take a look at the comparison 
  function first.</font></p>
<p><font face="Fixedsys">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 </font></p>
<p><font face="MS Sans Serif" size="-1">In the comparison function, the listview 
  control will pass lParams (in LV_ITEM) of the two items it needs to compare 
  to us in lParam1 and lParam2. You'll recall that we put the index of the item 
  in lParam. Thus we can obtain information about the items by querying the listview 
  control using the indexes. The info we need is the labels of the items/subitems 
  being sorted. Thus we prepare an<font color="#CCFFCC"><b> LV_ITEM</b></font> 
  structure for such purpose, specifying <font color="#CCFFCC"><b>LVIF_TEXT</b></font> 
  in <font color="#FFFFCC"><b>imask</b></font> and the address of the buffer in 
  <font color="#FFFFCC"><b>pszText</b></font> and the size of the buffer in <font color="#FFFFCC"><b>cchTextMax</b></font>.</font></p>
<p><font face="Fixedsys"> &nbsp; .if SortType==1 <br>
  &nbsp;&nbsp;&nbsp; mov lvi.iSubItem,1 <br>
  &nbsp;&nbsp;&nbsp; invoke SendMessage,hList,LVM_GETITEMTEXT,lParam1,addr lvi 
  </font></p>
<p><font face="MS Sans Serif" size="-1">If the value in SortType is 1 or 2, we 
  know that the size column is clicked. 1 means sort the items according to their 
  sizes in ascending order. 2 means the reverse. Thus we specify<font color="#FFFFCC"><b> 
  iSubItem</b></font> as 1 ( to specify the size column) and send <font color="#CCFFCC"><b>LVM_GETITEMTEXT</b></font> 
  message to the listview control to obtain the label (size string) of the subitem.</font></p>
<p><font face="Fixedsys"> &nbsp;&nbsp;&nbsp; invoke String2Dword,addr buffer <br>
  &nbsp;&nbsp;&nbsp; mov edi,eax </font></p>
<p><font face="MS Sans Serif" size="-1">Covert the size string into a dword value 
  with String2Dword which is the function I wrote. It returns the dword value 
  in eax. We store it in edi for comparison later.</font></p>
<p><font face="Fixedsys"> &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 </font></p>
<p><font face="MS Sans Serif" size="-1">Do likewise with the value in lParam2. 
  When we have the sizes of the two files, we can then compare them.<br>
  The rule of the comparison function is as follows:</font></p>
<ul>
  <li><font face="MS Sans Serif" size="-1">If the first item should precede the 
    other, you must return a negative value in eax</font></li>
  <li><font face="MS Sans Serif" size="-1">If the second item should precede the 
    first one, you must return a positive value in eax</font></li>
  <li><font face="MS Sans Serif" size="-1">If both items are equal, you must return 
    zero in eax.</font></li>
</ul>
<p><font face="MS Sans Serif" size="-1">In this case, we want to sort the items 
  according to their sizes in ascending order. Thus we can simply subtract the 
  size of the first item with that of the second one and return the result in 
  eax.</font></p>
<p><font face="Fixedsys">&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>
  </font></p>
<p><font face="MS Sans Serif" size="-1">In case the user clicks the filename column, 
  we must compare the names of the files. We first obtain the filenames and then 
  compare them with lstrcmpi function. We can return the return value of lstrcmpi 
  without any modification since it also uses the same rule of comparison, eg. 
  negative value in eax if the first string is less than the second string.</font></p>
<p><font face="MS Sans Serif" size="-1"> When the items were sorted, we need to 
  update the lParam values of all items to reflect the new indexes by calling 
  UpdatelParam function.</font></p>
<p><font face="Fixedsys">&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 
  </font></p>
<p><font face="MS Sans Serif" size="-1">This function simply enumerates all items 
  in the listview control and updates the values in lParam with the new indexes. 
  We need to do this else the next sort will not work as expected because our 
  assumption is that the value in lParam is the index of the item.</font></p>
<p><font face="Fixedsys">&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 </font></p>
<p><font face="MS Sans Serif" size="-1">When the user double-clicks at an item, 
  we want to display a message box w

⌨️ 快捷键说明

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