📄 lion-tutorial34.htm
字号:
<html><head><title>Iczelion's Win32 Assembly Tutorial No.34: RichEdit Control: More Text Operations</title><meta http-equiv="Content-Type" content="text/html; charset="></head><body bgcolor="#FFFFFF"><h1 align="center"><font face="Tahoma" color="#0000FF">Tutorial 34: RichEdit Control: More Text Operations</font></h1><p align="left"><font face="Tahoma" size="-1">You'll learn more about text operations under RichEdit control. Specifically, you'll know how to search for/replace text, jumping to specific line number.</font></p><p align="left"><font face="Tahoma" size="-1">Download <a href="files/tut34.zip">the example</a>.</font></p><h3 align="left"><font face="Times New Roman, Times, serif" color="#0000FF">Theory</font></h3><h3 align="left"><font face="Arial, Helvetica, sans-serif" color="#990099">Searching for Text</font></h3><p align="left"><font face="Tahoma" size="-1">There are several text operations under RichEdit control. Searching for text is one such operation. Searching for text is done by sending <font color="#006666"><b>EM_FINDTEXT</b></font> or <font color="#006666"><b>EM_FINDTEXTEX</b></font>. These messages has a small difference.</font></p><blockquote> <pre align="left"><font face="Tahoma"><b><font color="#006666">EM_FINDTEXT</font></b><font color="#000099"><b>wParam</b></font> == Search options. Can be any combination of the values in the table below.These options are identical for both <font color="#006666"><b>EM_FINDTEXT</b></font> and <font color="#006666"><b>EM_FINDTEXTEX</b></font></font></pre> <table cellpadding="3" border="1" align="center"> <tr bgcolor="#FFFFCC"> <td><b><font face="MS Sans Serif" size="-1">FR_DOWN</font></b></td> <td><font face="MS Sans Serif" size="-1">If this flag is specified, the search starts from the <font color="#0000CC"><b>end</b></font> of the current selection to the <font color="#0000CC"><b>end</b></font> of the text in the control (<font color="#0000FF"><b>downward</b></font>). This flag has effect only for RichEdit 2.0 or later: <font color="#CC00CC"><b>This behavior is the default for RichEdit 1.0</b></font>. The default behavior of RichEdit 2.0 or later is to search from the end of the current selection to the beginning of the text (<font color="#0000FF"><b>upward</b></font>).<br> In summary, if you use RichEdit 1.0, you can't do anything about the search direction: it always searches downward. If you use RichEdit 2.0 and you want to search downward, you <font color="#CC00CC"><b>must</b></font> specify this flag else the search would be upward.</font></td> </tr> <tr bgcolor="#FFFFCC"> <td><b><font face="MS Sans Serif" size="-1">FR_MATCHCASE</font></b></td> <td><font face="MS Sans Serif" size="-1">If this flag is specified, the search is case-sensitive.</font></td> </tr> <tr bgcolor="#FFFFCC"> <td><b><font face="MS Sans Serif" size="-1">FR_WHOLEWORD</font></b></td> <td><font face="MS Sans Serif" size="-1">If this flag is set, the search finds the whole word that matches the specified search string.</font></td> </tr> </table> <pre><font face="Tahoma">Actually, there are a few more flags but they are relevant to non-English languages.lParam == pointer to the <font color="#006666"><b>FINDTEXT</b></font> structure.<font color="#990099"><b> FINDTEXT <font color="#0000CC">STRUCT</font> chrg <font color="#0000CC">CHARRANGE</font> <> lpstrText <font color="#0000CC">DWORD</font> ? FINDTEXT <font color="#0000CC">ENDS</font></b></font><font color="#990099"><b>chrg</b></font> is a <font color="#006666"><b>CHARRANGE</b></font> structure which is defined as follows:<font color="#CC00CC"><b> CHARRANGE <font color="#0000CC">STRUCT</font> cpMin <font color="#0000CC">DWORD</font> ? cpMax <font color="#0000CC">DWORD</font> ? CHARRANGE <font color="#0000CC">ENDS</font></b></font><font color="#0000CC"><b>cpMin</b></font> contains the character index of the first character in the character array (range).<font color="#0000CC"><b>cpMax</b></font> contains the character index of the character immediately following the last character in the character array.In essence, to search for a text string, you have to specify the character range in which to search. <font color="#CC0033"><b>The meaning of <font color="#0000CC">cpMin</font> and <font color="#0000CC">cpMax</font> differ according to whether the search is downward or upward</b></font>. If the search is downward, <font color="#0033CC"><b>cpMin</b></font> specifies the starting character index to search in and <font color="#0000CC"><b>cpMax</b></font> the ending character index. If the search is upward, the reverse is true, ie. <font color="#0000CC"><b>cpMin</b></font> contains the ending character index while <font color="#0000CC"><b>cpMax</b></font> the starting character index.<font color="#CC00CC"><b>lpstrText</b></font> is the pointer to the text string to search for.<font color="#0000CC"><b>EM_FINDTEXT</b></font> returns the character index of the first character in the matching text string in the richedit control. It returns -1 ifno match is found.<font color="#006666"><b>EM_FINDTEXTEX</b></font><font color="#0000CC"><b>wParam</b></font> == the search options. Same as those of <font color="#006666"><b>EM_FINDTEXT</b></font>.<font color="#000099"><b>lParam</b></font> == pointer to the <font color="#006666"><b>FINDTEXTEX</b></font> structure.<font color="#990099"><b> FINDTEXTEX <font color="#0000CC">STRUCT</font> chrg <font color="#0000CC">CHARRANGE</font> <> lpstrText <font color="#0000CC">DWORD</font> ? chrgText <font color="#0000CC">CHARRANGE</font> <> FINDTEXTEX <font color="#0000CC">ENDS</font></b></font>The first two members of <font color="#006666"><b>FINDTEXTEX</b></font> are identical to those of <font color="#006666"><b>FINDTEXT</b></font> structure. chrgText is a <font color="#006666"><b>CHARRANGE</b></font> structure that willbe filled with the starting/ending characterindices if a match is found.The return value of <font color="#006666"><b>EM_FINDTEXTEX</b></font> is the same as that of <font color="#006666"><b>EM_FINDTEXT</b></font>.The difference between <font color="#006666"><b>EM_FINDTEXT </b></font>and<font color="#006666"><b> EM_FINDTEXTEX</b></font> is that the <font color="#006666"><b>FINDTEXTEX</b></font> structure has an additional member, <font color="#006666"><b>chrgText</b></font>, which will be filled with the starting/ending character indices if a match is found. This is convenient if we want to do more text operations on the string.</font></pre></blockquote><h3><font face="Arial, Helvetica, sans-serif" color="#990099">Replace/Insert Text</font><font face="Tahoma"> </font></h3><p><font face="Tahoma" size="-1">RichEdit control provides <font color="#006666"><b>EM_SETTEXTEX</b></font> for replacing/inserting text. This message combines the functionality of <font color="#006666"><b>WM_SETTEXT</b></font> and <font color="#006666"><b>EM_REPLACESEL</b></font>. It has the following syntax:</font></p><pre><font face="Tahoma"> <font color="#006666"><b>EM_SETTEXTEX</b></font> <font color="#0000CC"><b>wParam</b></font> == pointer to <font color="#006666"><b>SETTEXTEX</b></font> structure.<font color="#990099"><b> SETTEXTEX <font color="#0000CC">STRUCT</font> flags <font color="#0000CC">DWORD</font> ? codepage <font color="#0000CC">DWORD</font> ? SETTEXTEX <font color="#0000CC">ENDS</font></b></font> <font color="#990099"><b>flags</b></font> can be the combination of the following values:</font></pre><table cellpadding="3" border="1" align="center"> <tr bgcolor="#FFFFCC"> <td><b><font face="MS Sans Serif" size="-1">ST_DEFAULT</font></b></td> <td><font face="MS Sans Serif" size="-1">Deletes the undo stack, discards rich-text formatting, replaces all text.</font></td> </tr> <tr bgcolor="#FFFFCC"> <td><b><font face="MS Sans Serif" size="-1">ST_KEEPUNDO</font></b></td> <td><font face="MS Sans Serif" size="-1">Keeps the undo stack</font></td> </tr> <tr bgcolor="#FFFFCC"> <td><b><font face="MS Sans Serif" size="-1">ST_SELECTION</font></b></td> <td><font face="MS Sans Serif" size="-1">Replaces selection and keeps rich-text formatting</font></td> </tr></table><pre><font face="Tahoma"> <font color="#990099"><b>codepage</b></font> is the constant that specifies the code page you want to text to be. Usually, we simply use <font color="#006666"><b>CP_ACP</b></font>.</font></pre><h3><font face="Tahoma" color="#990099">Text Selection</font></h3><p><font face="Tahoma" size="-1">We can select the text programmatically with <font color="#000099"> <b><font color="#006666">EM_SETSEL</font></b></font> or <font color="#006666"><b>EM_EXSETSEL</b></font>. Either one works fine. Choosing which message to use depends on the available format of the character indices. If they are already stored in a <font color="#006666"><b>CHARRANGE</b></font> structure, it's easier to use <font color="#006666"><b>EM_EXSETSEL</b></font>.</font><font face="Tahoma"><br> </font></p><pre><font face="Tahoma"> <font color="#006666"><b>EM_EXSETSEL</b></font> <font color="#0000CC"><b>wParam</b></font> == not used. Must be 0 <font color="#0000CC"><b>lParam</b></font> == pointer to a <font color="#006666"><b>CHARRANGE</b></font> structure that contains the character range to be selected.</font></pre><h3><font face="Tahoma" color="#990099">Event Notification</font></h3><p><font face="Tahoma" size="-1">In the case of a multiline edit control, you have to subclass it in order to obtain the input messages such as mouse/keyboard events. RichEdit control provides a better scheme that will notify the parent window of such events. In order to register for notifications, the parent window sends <font color="#006666"><b>EM_SETEVENTMASK</b></font> message to the RichEdit control, specifying which events it's interested in. <font color="#006666"><b>EM_SETEVENTMASK </b></font>has the following syntax:</font></p><pre><font face="Tahoma"> <b><font color="#006666">EM_SETEVENTMASK</font></b> <font color="#000099"><b>wParam</b></font> == not used. Must be 0 <font color="#0000CC"><b>lParam</b></font> == event mask value. It can be the combination of the flags in the table below.</font></pre><table cellpadding="3" align="center" border="1"> <tr bgcolor="#FFFFCC"> <td><b><font face="MS Sans Serif" size="-1">ENM_CHANGE</font></b></td> <td><font face="MS Sans Serif" size="-1">Sends <font color="#000099"><b>EN_CHANGE</b></font> notifications</font></td> </tr> <tr bgcolor="#FFFFCC"> <td><b><font face="MS Sans Serif" size="-1">ENM_CORRECTTEXT</font></b></td> <td><font face="MS Sans Serif" size="-1">Sends <font color="#000099"><b>EN_CORRECTTEXT</b></font> notifications</font></td> </tr> <tr bgcolor="#FFFFCC"> <td><b><font face="MS Sans Serif" size="-1">ENM_DRAGDROPDONE</font></b></td> <td><font face="MS Sans Serif" size="-1">Sends <font color="#0000CC"><b>EN_DRAGDROPDONE</b></font> notifications</font></td> </tr> <tr bgcolor="#FFFFCC"> <td><b><font face="MS Sans Serif" size="-1">ENM_DROPFILES</font></b></td> <td><font face="MS Sans Serif" size="-1">Sends <font color="#0000CC"><b>EN_DROPFILES</b></font> notifications.</font></td> </tr> <tr bgcolor="#FFFFCC"> <td><b><font face="MS Sans Serif" size="-1">ENM_KEYEVENTS</font></b></td> <td><font face="MS Sans Serif" size="-1">Sends <font color="#0000CC"><b>EN_MSGFILTER </b></font>notifications for keyboard events</font></td> </tr> <tr bgcolor="#FFFFCC"> <td><b><font face="MS Sans Serif" size="-1">ENM_LINK</font></b></td> <td><font face="MS Sans Serif" size="-1"><b>Rich Edit 2.0 and later:</b> Sends <font color="#0000CC"> <b>EN_LINK</b></font> notifications when the mouse pointer is over text that has the <font color="#990099"><b>CFE_LINK</b></font> and one of several mouse actions is performed.</font></td> </tr> <tr bgcolor="#FFFFCC"> <td><b><font face="MS Sans Serif" size="-1">ENM_MOUSEEVENTS</font></b></td> <td><font face="MS Sans Serif" size="-1">Sends <font color="#0000CC"><b>EN_MSGFILTER</b></font> notifications for mouse events</font></td> </tr> <tr bgcolor="#FFFFCC"> <td><b><font face="MS Sans Serif" size="-1">ENM_OBJECTPOSITIONS</font></b></td> <td><font face="MS Sans Serif" size="-1">Sends <font color="#0000CC"><b>EN_OBJECTPOSITIONS</b></font> notifications</font></td> </tr> <tr bgcolor="#FFFFCC"> <td><b><font face="MS Sans Serif" size="-1">ENM_PROTECTED</font></b></td> <td><font face="MS Sans Serif" size="-1">Sends<font color="#0000CC"><b> EN_PROTECTED</b></font> notifications</font></td> </tr> <tr bgcolor="#FFFFCC"> <td><b><font face="MS Sans Serif" size="-1">ENM_REQUESTRESIZE</font></b></td> <td><font face="MS Sans Serif" size="-1">Sends<font color="#0000CC"><b> EN_REQUESTRESIZE</b></font> notifications</font></td> </tr> <tr bgcolor="#FFFFCC"> <td><b><font face="MS Sans Serif" size="-1">ENM_SCROLL</font></b></td> <td><font face="MS Sans Serif" size="-1">Sends <font color="#0000CC"><b>EN_HSCROLL</b></font> and <font color="#000099"><b>EN_VSCROLL</b></font> notifications</font></td> </tr> <tr bgcolor="#FFFFCC"> <td><b><font face="MS Sans Serif" size="-1">ENM_SCROLLEVENTS</font></b></td> <td><font face="MS Sans Serif" size="-1">Sends <font color="#0000CC"><b>EN_MSGFILTER</b></font> notifications for mouse wheel events</font></td> </tr> <tr bgcolor="#FFFFCC"> <td><b><font face="MS Sans Serif" size="-1">ENM_SELCHANGE</font></b></td> <td><font face="MS Sans Serif" size="-1">Sends <font color="#000099"><b>EN_SELCHANGE</b></font> notifications</font></td> </tr> <tr bgcolor="#FFFFCC"> <td><font face="MS Sans Serif" size="-1"><b>ENM_UPDATE</b></font></td> <td> <p><font face="MS Sans Serif" size="-1">Sends <font color="#0000CC"><b>EN_UPDATE </b></font>notifications.<br> <b>Rich Edit 2.0 and later: </b>this flag is ignored and the <font color="#0000CC"><b>EN_UPDATE</b></font> notifications are always sent. However, if Rich Edit 3.0 emulates Rich Edit 1.0, you must use this flag to send <font color="#000099"><b>EN_UPDATE</b></font> notifications </font></p> </td> </tr></table><p><font face="Tahoma" size="-1">All the above notifications will be sent as <font color="#006666"><b>WM_NOTIFY </b></font>message: you have to check the code member of <font color="#006666"><b>NMHDR</b></font> structure for the notification message. For example, if you want to register for mouse events (eg. you want to provide a context sensitive popup menu), you must do something like this:</font></p><pre><font face="Tahoma"><b> invoke SendMessage,hwndRichEdit,<font color="#006666">EM_SETEVENTMASK</font>,0,<font color="#0000FF">ENM_MOUSEEVENTS</font> ..... ..... WndProc proc hWnd:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD ..... .... .elseif uMsg==WM_NOTIFY push esi mov esi,lParam assume esi:ptr NMHDR <font color="#FF0033">.if [esi].code==EN_MSGFILTER</font> .... [ do something here] .... .endif pop esi</b></font></pre><h3><font face="Times New Roman, Times, serif">Example:</font></h3><p><font face="Tahoma" size="-1">The following example is the update of IczEdit in tutorial no. 33. It adds search/replace functionality and accelerator keys to the program. It also processes the mouse events and provides a popup menu on right mouse click.</font></p><pre><font face="Tahoma"><b>.386.model flat,stdcalloption casemap:noneinclude \masm32\include\windows.incinclude \masm32\include\user32.incinclude \masm32\include\comdlg32.incinclude \masm32\include\gdi32.incinclude \masm32\include\kernel32.incincludelib \masm32\lib\gdi32.libincludelib \masm32\lib\comdlg32.libincludelib \masm32\lib\user32.lib
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -