📄 lion-tutorial34.htm
字号:
mov editstream.dwCookie,eax mov editstream.pfnCallback,offset StreamOutProc invoke SendMessage,hwndRichEdit,EM_STREAMOUT,SF_TEXT,addr editstream ;========================================================== ; Initialize the modify state to false ;========================================================== invoke SendMessage,hwndRichEdit,EM_SETMODIFY,FALSE,0 invoke CloseHandle,hFile .else invoke MessageBox,hWnd,addr OpenFileFail,addr AppName,MB_OK or MB_ICONERROR .endif .elseif ax==IDM_COPY invoke SendMessage,hwndRichEdit,WM_COPY,0,0 .elseif ax==IDM_CUT invoke SendMessage,hwndRichEdit,WM_CUT,0,0 .elseif ax==IDM_PASTE invoke SendMessage,hwndRichEdit,WM_PASTE,0,0 .elseif ax==IDM_DELETE invoke SendMessage,hwndRichEdit,EM_REPLACESEL,TRUE,0 .elseif ax==IDM_SELECTALL mov chrg.cpMin,0 mov chrg.cpMax,-1 invoke SendMessage,hwndRichEdit,EM_EXSETSEL,0,addr chrg .elseif ax==IDM_UNDO invoke SendMessage,hwndRichEdit,EM_UNDO,0,0 .elseif ax==IDM_REDO invoke SendMessage,hwndRichEdit,EM_REDO,0,0 .elseif ax==IDM_OPTION invoke DialogBoxParam,hInstance,IDD_OPTIONDLG,hWnd,addr OptionProc,0 .elseif ax==IDM_SAVEAS invoke RtlZeroMemory,addr ofn,sizeof ofn mov ofn.lStructSize,sizeof ofn push hWnd pop ofn.hwndOwner push hInstance pop ofn.hInstance mov ofn.lpstrFilter,offset ASMFilterString mov ofn.lpstrFile,offset AlternateFileName mov byte ptr [AlternateFileName],0 mov ofn.nMaxFile,sizeof AlternateFileName mov ofn.Flags,OFN_FILEMUSTEXIST or OFN_HIDEREADONLY or OFN_PATHMUSTEXIST invoke GetSaveFileName,addr ofn .if eax!=0 invoke CreateFile,addr AlternateFileName,GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0 .if eax!=INVALID_HANDLE_VALUE jmp @B .endif .endif .elseif ax==IDM_FIND .if hSearch==0 invoke CreateDialogParam,hInstance,IDD_FINDDLG,hWnd,addr SearchProc,0 .endif .elseif ax==IDM_REPLACE .if hSearch==0 invoke CreateDialogParam,hInstance,IDD_REPLACEDLG,hWnd,addr ReplaceProc,0 .endif .elseif ax==IDM_GOTOLINE .if hSearch==0 invoke CreateDialogParam,hInstance,IDD_GOTODLG,hWnd,addr GoToProc,0 .endif .elseif ax==IDM_FINDNEXT invoke lstrlen,addr FindBuffer .if eax!=0 invoke SendMessage,hwndRichEdit,EM_EXGETSEL,0,addr findtext.chrg mov eax,findtext.chrg.cpMin .if eax!=findtext.chrg.cpMax push findtext.chrg.cpMax pop findtext.chrg.cpMin .endif mov findtext.chrg.cpMax,-1 mov findtext.lpstrText,offset FindBuffer invoke SendMessage,hwndRichEdit,EM_FINDTEXTEX,FR_DOWN,addr findtext .if eax!=-1 invoke SendMessage,hwndRichEdit,EM_EXSETSEL,0,addr findtext.chrgText .endif .endif .elseif ax==IDM_FINDPREV invoke lstrlen,addr FindBuffer .if eax!=0 invoke SendMessage,hwndRichEdit,EM_EXGETSEL,0,addr findtext.chrg mov findtext.chrg.cpMax,0 mov findtext.lpstrText,offset FindBuffer invoke SendMessage,hwndRichEdit,EM_FINDTEXTEX,0,addr findtext .if eax!=-1 invoke SendMessage,hwndRichEdit,EM_EXSETSEL,0,addr findtext.chrgText .endif .endif .elseif ax==IDM_EXIT invoke SendMessage,hWnd,WM_CLOSE,0,0 .endif .endif .elseif uMsg==WM_CLOSE invoke CheckModifyState,hWnd .if eax==TRUE invoke DestroyWindow,hWnd .endif .elseif uMsg==WM_SIZE mov eax,lParam mov edx,eax and eax,0FFFFh shr edx,16 invoke MoveWindow,hwndRichEdit,0,0,eax,edx,TRUE .elseif uMsg==WM_DESTROY invoke PostQuitMessage,NULL .else invoke DefWindowProc,hWnd,uMsg,wParam,lParam ret .endif xor eax,eax retWndProc endpend start</b></font></pre><h3><font face="Times New Roman, Times, serif" color="#0000CC">Analysis</font></h3><p><font face="Tahoma" size="-1">The search-for-text capability is implemented with <font color="#006666"><b>EM_FINDTEXTEX</b></font>. When the user clicks on Find menuitem, <font color="#000099"><b>IDM_FIND</b></font> message is sent and the Find dialog box is displayed.</font></p><p align="center"><img src="images/find.jpg" width="285" height="120"></p><pre><font face="Tahoma"><b></b></font><font face="Tahoma"><b> invoke GetDlgItemText,hWnd,IDC_FINDEDIT,addr FindBuffer,sizeof FindBuffer .if eax!=0</b></font><font face="Tahoma"><b></b></font></pre><p><font face="Tahoma"><font face="Tahoma" size="-1">When the user types the text to search for and then press OK button, we get the text to be searched for into FindBuffer. </font></font><font face="Tahoma"><b></b></font></p><pre><font face="Tahoma"><b> mov uFlags,0 invoke SendMessage,hwndRichEdit,EM_EXGETSEL,0,addr findtext.chrg</b></font><font face="Tahoma"><b></b></font></pre><p><font face="Tahoma"><font face="Tahoma"><font face="Tahoma" size="-1">If the text string is not null, we continue to initialize <font color="#0000CC"><b>uFlags</b></font> variable to 0.</font></font><font face="Tahoma" size="-1">This variable is used to store the search flags used with<font color="#006666"> <b>EM_FINDTEXTEX</b></font>. After that, we obtain the current selection with <font color="#006666"><b>EM_EXGETSEL</b></font> because we need to know the starting point of the search operation.</font><b><br> </b></font></p><pre> <font face="Tahoma"><b>invoke IsDlgButtonChecked,hWnd,IDC_DOWN .if eax==BST_CHECKED or uFlags,FR_DOWN mov eax,findtext.chrg.cpMin .if eax!=findtext.chrg.cpMax push findtext.chrg.cpMax pop findtext.chrg.cpMin .endif mov findtext.chrg.cpMax,-1 .else mov findtext.chrg.cpMax,0 .endif</b></font></pre><p><font face="Tahoma"><font size="-1">The next part is a little tricky. We check the direction radio button to ascertain which direction the search should go. If the downward search is indicated, we set <font color="#006666"><b>FR_DOWN</b></font> flag to <font color="#0000CC"><b>uFlags</b></font>. After that, we check whether a selection is currently in effect by comparing the values of <font color="#0000CC"><b>cpMin</b></font> and <font color="#0000CC"><b>cpMax</b></font>. If both values are not equal, it means there is a current selection and we must continue the search from the end of that selection to the end of text in the control. Thus we need to replace the value of <font color="#0000CC"><b>cpMax</b></font> with that of <font color="#0000CC"><b>cpMin</b></font> and change the value of <font color="#0000CC"><b>cpMax</b></font> to -1 (0FFFFFFFFh). If there is no current selection, the range to search is from the current caret position to the end of text.</font></font></p><p><font face="Tahoma" size="-1">If the user chooses to search upward, we use the range from the start of the selection to the beginning of the text in the control. That's why we only modify the value of <font color="#0000CC"><b>cpMax</b></font> to 0. In the case of upward search, <font color="#0000CC"><b>cpMin</b></font> contains the character index of the last character in the search range and <font color="#0000CC"><b>cpMax</b></font> the character index of the first char in the search range. It's the inverse of the downward search.</font><font face="Tahoma"><b><br> </b></font></p><pre><font face="Tahoma"><b> invoke IsDlgButtonChecked,hWnd,IDC_MATCHCASE .if eax==BST_CHECKED or uFlags,FR_MATCHCASE .endif invoke IsDlgButtonChecked,hWnd,IDC_WHOLEWORD .if eax==BST_CHECKED or uFlags,FR_WHOLEWORD .endif mov findtext.lpstrText,offset FindBuffer</b></font></pre><p><font face="Tahoma"><font size="-1">We continue to check the checkboxes for the search flags, ie,<font color="#006666"><b> FR_MATCHCASE</b></font> and <font color="#006666"><b>FR_WHOLEWORD</b></font>. Lastly, we put the offset of the text to search for in <font color="#006666"><b>lpstrText</b></font> member.<br> </font><b> </b></font></p><pre><font face="Tahoma"><b> invoke SendMessage,hwndRichEdit,EM_FINDTEXTEX,uFlags,addr findtext .if eax!=-1 invoke SendMessage,hwndRichEdit,EM_EXSETSEL,0,addr findtext.chrgText .endif .endif</b></font></pre><p><font face="Tahoma" size="-1">We are now ready to issue <font color="#006666"><b>EM_FINDTEXTEX</b></font>. After that, we examine the search result returned by <font color="#990099"><b>SendMessage</b></font>. If the return value is -1, no match is found in the search range. Otherwise, <font color="#0000CC"> <b>chrgText</b></font> member of <font color="#006666"><b>FINDTEXTEX</b></font> structure is filled with the character indices of the matching text. We thus proceed to select it with<font color="#006666"><b> EM_EXSETSEL</b></font></font><font face="Tahoma"><b>.</b></font></p><p><font face="Tahoma" size="-1">The replace operation is done in much the same manner.</font></p><pre><font face="Tahoma"><b> invoke GetDlgItemText,hWnd,IDC_FINDEDIT,addr FindBuffer,sizeof FindBuffer invoke GetDlgItemText,hWnd,IDC_REPLACEEDIT,addr ReplaceBuffer,sizeof ReplaceBuffer</b></font></pre><p><font face="Tahoma"><font size="-1">We retrieve the text to search for and the text used to replace.</font><b><br> </b></font></p><pre><font face="Tahoma"><b> mov findtext.chrg.cpMin,0 mov findtext.chrg.cpMax,-1 mov findtext.lpstrText,offset FindBuffer</b></font></pre><p><font face="Tahoma"><font size="-1">To make it easy, the replace operation affects all the text in the control. Thus the starting index is 0 and the ending index is -1.</font><b><br> </b></font></p><pre><font face="Tahoma"><b> mov settext.flags,ST_SELECTION mov settext.codepage,CP_ACP</b></font></pre><p><font face="Tahoma"><font size="-1">We initialize <font color="#006666"><b>SETTEXTEX</b></font> structure to indicate that we want to replace the current selection and use the default system code page.</font><b><br> </b></font></p><pre><font face="Tahoma"><b> .while TRUE invoke SendMessage,hwndRichEdit,EM_FINDTEXTEX,FR_DOWN,addr findtext .if eax==-1 .break .else invoke SendMessage,hwndRichEdit,EM_EXSETSEL,0,addr findtext.chrgText invoke SendMessage,hwndRichEdit,EM_SETTEXTEX,addr settext,addr ReplaceBuffer .endif .endw</b></font></pre><p><font face="Tahoma" size="-1">We enter an infinite loop, searching for the matching text. If one is found, we select it with <font color="#006666"><b>EM_EXSETSEL</b></font> and replace it with <font color="#006666"><b>EM_SETTEXTEX</b></font>. When no more match is found, we exit the loop.</font></p><p><font face="Tahoma" size="-1"><b><font color="#006666">Find Next </font></b>and <font color="#006666"> <b>Find Prev.</b></font> features use <font color="#006666"><b>EM_FINDTEXTEX</b></font> message in the similar manner to the find operation.</font></p><p><font face="Tahoma" size="-1">We will examine the Go to Line feature next. When the user clicks Go To Line menuitem, we display a dialog box below:</font></p><p align="center"><img src="images/gotoline.jpg" width="165" height="75"></p><p align="left"><font face="Tahoma" size="-1">When the user types a line number and presses Ok button, we begin the operation.</font></p><pre align="left"><font face="Tahoma"><b> invoke GetDlgItemInt,hWnd,IDC_LINENO,NULL,FALSE mov LineNo,eax</b></font></pre><p align="left"><font face="Tahoma"><font size="-1">Obtain the line number from the edit control</font><b><br> </b></font></p><pre align="left"><font face="Tahoma"><b> invoke SendMessage,hwndRichEdit,EM_GETLINECOUNT,0,0 .if eax>LineNo</b></font></pre><p align="left"><font face="Tahoma"><font size="-1">Obtain the number of lines in the control. Check whether the user specifies the line number that is out of the range.</font><b><br> </b></font></p><pre align="left"><font face="Tahoma"><b> invoke SendMessage,hwndRichEdit,EM_LINEINDEX,LineNo,0</b></font></pre><p align="left"><font face="Tahoma"><font size="-1">If the line number is valid, we want to move the caret to the first character of that line. So we send <font color="#006666"><b>EM_LINEINDEX</b></font> message to the richedit control. This message returns the character index of the first character in the specified line. We send the line number in wParam and in return, we has the character index.</font><b><br> </b></font></p><pre align="left"><font face="Tahoma"><b> invoke SendMessage,hwndRichEdit,EM_SETSEL,eax,eax</b></font></pre><p align="left"><font face="Tahoma"><font size="-1">To set the current selection, this time we use<font color="#006666"><b> EM_SETSEL</b></font> because the character indices are not already in a <font color="#006666"><b>CHARRANGE</b></font> structure thus it saves us two instructions (to put those indices into a <font color="#006666"><b>CHARRANGE</b></font> structure).</font><b> </b></font></p><pre align="left"><font face="Tahoma"><b> invoke SetFocus,hwndRichEdit .endif</b></font></pre><p align="left"><font face="Tahoma" size="-1">The caret will not be displayed unless the richedit control has the focus. So we call <font color="#006666"><b>SetFocus</b></font> on it.</font><font face="Tahoma"><b> </b></font></p><hr><p align="center"><font face="Tahoma"><b><font size="-1">[<a href="http://win32asm.cjb.net">Iczelion's Win32 Assembly Homepage</a>]</font><br> </b></font></p><pre align="left"><font face="Tahoma"><b> </b></font></pre><pre><font face="Tahoma"></font></pre></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -