📄 tut34.html
字号:
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
ret
WndProc endp
end 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 + -