📄 tut33.html
字号:
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_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
;===================================================================
; The resource file
;===================================================================
#include "resource.h"
#define IDR_MAINMENU 101
#define IDD_OPTIONDLG 101
#define IDC_BACKCOLORBOX 1000
#define IDC_TEXTCOLORBOX 1001
#define IDM_OPEN 40001
#define IDM_SAVE 40002
#define IDM_CLOSE 40003
#define IDM_SAVEAS 40004
#define IDM_EXIT 40005
#define IDM_COPY 40006
#define IDM_CUT 40007
#define IDM_PASTE 40008
#define IDM_DELETE 40009
#define IDM_SELECTALL 40010
#define IDM_OPTION 40011
#define IDM_UNDO 40012
#define IDM_REDO 40013
IDR_MAINMENU MENU DISCARDABLE
BEGIN
POPUP "&File"
BEGIN
MENUITEM "&Open", IDM_OPEN
MENUITEM "&Close", IDM_CLOSE
MENUITEM "&Save", IDM_SAVE
MENUITEM "Save &As", IDM_SAVEAS
MENUITEM SEPARATOR
MENUITEM "E&xit", IDM_EXIT
END
POPUP "&Edit"
BEGIN
MENUITEM "&Undo", IDM_UNDO
MENUITEM "&Redo", IDM_REDO
MENUITEM "&Copy", IDM_COPY
MENUITEM "C&ut", IDM_CUT
MENUITEM "&Paste", IDM_PASTE
MENUITEM SEPARATOR
MENUITEM "&Delete", IDM_DELETE
MENUITEM SEPARATOR
MENUITEM "Select &All", IDM_SELECTALL
END
MENUITEM "Options", IDM_OPTION
END
IDD_OPTIONDLG DIALOG DISCARDABLE 0, 0, 183, 54
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_CENTER
CAPTION "Options"
FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,137,7,39,14
PUSHBUTTON "Cancel",IDCANCEL,137,25,39,14
GROUPBOX "",IDC_STATIC,5,0,124,49
LTEXT "Background Color:",IDC_STATIC,20,14,60,8
LTEXT "",IDC_BACKCOLORBOX,85,11,28,14,SS_NOTIFY | WS_BORDER
LTEXT "Text Color:",IDC_STATIC,20,33,35,8
LTEXT "",IDC_TEXTCOLORBOX,85,29,28,14,SS_NOTIFY | WS_BORDER
END</font></b></pre>
<hr noshade>
<h3 align="left"><font face="Times New Roman, Times, serif" color="#0000CC">Analysis:</font></h3>
<p align="left"><font face="Tahoma" size="-1">The program first loads the richedit
dll, which in this case is riched20.dll. If the dll cannot be loaded, it exits
to Windows.</font><br>
</p>
<pre align="left"><b><font face="Tahoma"><font color="#FF0033">invoke LoadLibrary,addr RichEditDLL</font>
.if eax!=0
mov hRichEdit,eax
invoke WinMain,hInstance,0,0, SW_SHOWDEFAULT
invoke FreeLibrary,hRichEdit
.else
invoke MessageBox,0,addr NoRichEdit,addr AppName,MB_OK or MB_ICONERROR
.endif
invoke ExitProcess,eax</font></b></pre>
<p align="left"><font face="Tahoma" size="-1">After the dll is loaded successfully,
we proceed to create a normal window which will be the parent of the richedit
control. Within the <font color="#006666"><b>WM_CREATE</b></font> handler, we
create the richedit control:</font></p>
<pre align="left"><b><font face="Tahoma"> invoke CreateWindowEx,WS_EX_CLIENTEDGE,addr RichEditClass,0,WS_CHILD or WS_VISIBLE or ES_MULTILINE or WS_VSCROLL or WS_HSCROLL or ES_NOHIDESEL,\
CW_USEDEFAULT,CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,hWnd,RichEditID,hInstance,0
mov hwndRichEdit,eax</font></b></pre>
<p align="left"><font face="Tahoma" size="-1">Note that we specify<font color="#006666"><b>
ES_MULTILINE</b></font> style else the control will be a single-lined one.</font><b><font face="Tahoma" size="-1">
<br>
</font></b></p>
<pre align="left"><b><font face="Tahoma"> invoke SendMessage,hwndRichEdit,EM_LIMITTEXT,-1,0</font></b></pre>
<p align="left"><font face="Tahoma" size="-1">After the richedit control is created,
we must set the new text limit on it. By default, the richedit control has 64K
text limit, the same as a simple multi-line edit control. We must extend this
limit to allow it to operate with larger files. In the above line, I specify
-1 which amounts to 0FFFFFFFFh, a very large value.</font></p>
<pre align="left"><font face="Tahoma"> </font><b><font face="Tahoma"> </font></b><b><font face="Tahoma"> invoke SetColor</font></b></pre>
<p align="left"><b><font face="Tahoma"><br>
</font></b><font face="Tahoma" size="-1">Next, we set the text/background </font><font face="Tahoma" size="-1">color.
Since this operation can be performed in other part of the program, I put the
code in a function named SetColor.</font><b><font face="Tahoma" size="-1"> <br>
</font></b></p>
<pre align="left"><b><font face="Tahoma"><font color="#003399">SetColor</font> proc
LOCAL cfm:CHARFORMAT
invoke SendMessage,hwndRichEdit,EM_SETBKGNDCOLOR,0,BackgroundColor</font></b></pre>
<p align="left"><font face="Tahoma" size="-1">Setting the background color of
the richedit control is a straightforward operation: just send <font color="#006666"><b>EM_SETBKGNDCOLOR</b></font>
message to the richedit control. (If you use a multi-line edit control, you
have to process <font color="#006666"><b>WM_CTLCOLOREDIT</b></font>). The default
background color is white. </font><b><font face="Tahoma" size="-1"> <br>
</font></b></p>
<pre align="left"><b><font face="Tahoma"> invoke RtlZeroMemory,addr cfm,sizeof cfm
mov cfm.cbSize,sizeof cfm
mov cfm.dwMask,CFM_COLOR
push TextColor
pop cfm.crTextColor</font></b></pre>
<p align="left"><font face="Tahoma" size="-1">After the background color is set,
we fill in the members of <font color="#006666"><b>CHARFORMAT</b></font> in
order to set the text color. Note that we fill <font color="#006666"><b>cbSize</b></font>
with the size of the structure so the richedit control knows we are sending
it <font color="#006666"><b>CHARFORMAT</b></font>, not <font color="#006666"><b>CHARFORMAT2</b></font>.
<font color="#006666"> <b>dwMask</b></font> has only one flag, <font color="#0000CC"><b>CFM_COLOR</b></font>,
because we only want to set the text color and <font color="#006666"><b>crTextColor</b></font>
is filled with the value of the desired text color. </font></p>
<pre align="left"><b><font face="Tahoma"> invoke SendMessage,hwndRichEdit,EM_SETCHARFORMAT,SCF_ALL,addr cfm
ret
<font color="#003399">SetColor</font> endp</font></b></pre>
<p align="left"><font face="Tahoma" size="-1">After settting the color, you have
to empty undo buffer simply because the act of changing text/background color
is undo-able. We send <font color="#006666"><b>EM_EMPTYUNDOBUFFER</b></font>
message to achieve this.</font></p>
<pre align="left"><font face="Tahoma" size="-1"><b> invoke SendMessage,hwndRichEdit,EM_EMPTYUNDOBUFFER,0,0</b></font><b><font face="Tahoma"> </font></b></pre>
<p align="left"><font face="Tahoma" size="-1">After filling the <font color="#006666"><b>CHARFORMAT</b></font>
structure, we send <font color="#006666"><b>EM_SETCHARFORMAT</b></font> to the
richedit control, specifying <font color="#0000CC"><b>SCF_ALL</b></font> flag
in <font color="#CC0033"><b>wParam</b></font> to indicate that we want the text
formatting to be applied to all text in the control.</font><b><font face="Tahoma" size="-1">
</font></b></p>
<p><font face="Tahoma" size="-1">Note that when we first created the richedit
control, we didn't specify its size/position at that time. That's because we
want it to cover the whole client area of the parent window. We resize it whenever
the size of the parent window changes.</font></p>
<pre><b><font face="Tahoma"> .elseif uMsg==WM_SIZE
mov eax,lParam
mov edx,eax
and eax,0FFFFh
shr edx,16
invoke MoveWindow,hwndRichEdit,0,0,eax,edx,TRUE</font></b></pre>
<p><font face="Tahoma" size="-1">In the above code snippet, we use the new dimension
of the client area passed in <font color="#0000CC"><b>lParam</b></font> to resize
the richedit control with <font color="#009999"><b><font color="#006666">MoveWindow</font></b></font>.</font></p>
<p><font face="Tahoma" size="-1">When the user clicks on the File/Edit menu bar,
we process <font color="#006666"><b>WM_INITPOPUPMENU</b></font> so that we can
prepare the states of the menuitems in the submenu before displaying it to the
user. For example, if a file is already opened in the richedit control, we want
to disable the open menuitem and enable all the remaining menuitems.</font></p>
<p><font face="Tahoma" size="-1">In the case of the File menu bar, we use the
variable <font color="#0000CC"><b>FileOpened</b></font> as the flag to determine
whether a file is already opened. If the value in this variable is TRUE, we
know that a file is already opened.</font></p>
<pre><b><font face="Tahoma"> .elseif uMsg==WM_INITMENUPOPUP
mov eax,lParam
.if ax==0 ; file menu
.if FileOpened==TRUE ; a file is already opened
invoke EnableMenuItem,wParam,IDM_OPEN,MF_GRAYED
invoke EnableMenuItem,wParam,IDM_CLOSE,MF_ENABLED
invoke EnableMenuItem,wParam,IDM_SAVE,MF_ENABLED
invoke EnableMenuItem,wParam,IDM_SAVEAS,MF_ENABLED
.else
invoke EnableMenuItem,wParam,IDM_OPEN,MF_ENABLED
invoke EnableMenuItem,wParam,IDM_CLOSE,MF_GRAYED
invoke EnableMenuItem,wParam,IDM_SAVE,MF_GRAYED
invoke EnableMenuItem,wParam,IDM_SAVEAS,MF_GRAYED
.endif</font></b></pre>
<p><font face="Tahoma" size="-1">As you can see, if a file is already opened,
we gray out the open menuitem and enable the remaining menuitems. The reverse
is true of <font color="#0000CC"><b>FileOpened</b></font> is false.</font></p>
<p><font face="Tahoma" size="-1">In the case of the edit menu bar, we need to
check the state of the richedit control/clipboard first.</font></p>
<pre><b><font face="Tahoma"> invoke SendMessage,hwndRichEdit,EM_CANPASTE,CF_TEXT,0
.if eax==0 ; no text in the clipboard
invoke EnableMenuItem,wParam,IDM_PASTE,MF_GRAYED
.else
invoke EnableMenuItem,wParam,IDM_PASTE,MF_ENABLED
.endif</font></b></pre>
<p><font face="Tahoma" size="-1">We first check whether some text is available
in the clipboard by sending <font color="#006666"><b>EM_CANPASTE</b></font>
message. If some text is available, <font color="#0000CC"><b>SendMessage</b></font>
returns TRUE and we enable the paste menuitem. If not, we gray out the menuitem.
</font></p>
<pre><b><font face="Tahoma"> invoke SendMessage,hwndRichEdit,EM_CANUNDO,0,0
.if eax==0
invoke EnableMenuItem,wParam,IDM_UNDO,MF_GRAYED
.else
invoke EnableMenuItem,wParam,IDM_UNDO,MF_ENABLED
.endif</font></b></pre>
<p><font face="Tahoma" size="-1">Next, we check whether the undo buffer is empty
by sending <font color="#006666"><b>EM_CANUNDO</b></font> message.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -