?? lion-tutorial33.htm
字號:
.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 retWndProc endpend 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 40013IDR_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_OPTIONENDIDD_OPTIONDLG DIALOG DISCARDABLE 0, 0, 183, 54STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_CENTERCAPTION "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_BORDEREND</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. If it's not empty, <font color="#0000CC"><b>SendMessage</b></font> returns TRUE and we enable the undo menuitem. </font></p><pre><b><font face="Tahoma"> invoke SendMessage,hwndRichEdit,EM_CANREDO,0,0 .if eax==0 invoke EnableMenuItem,wParam,IDM_REDO,MF_GRAYED .else invoke EnableMenuItem,wParam,IDM_REDO,MF_ENABLED .endif</font></b></pre><p><font face="Tahoma" size="-1">We check the redo buffer by sending <font color="#006666"><b>EM_CANREDO</b></font> message to the richedit control. If it's not empty, <font color="#0000CC"><b>SendMessage</b></font> returns TRUE and we enable the redo menuitem. </font><b><font face="Tahoma" size="-1"> </font></b></p><pre><b><font face="Tahoma"> invoke SendMessage,hwndRichEdit,EM_EXGETSEL,0,addr chrg mov eax,chrg.cpMin .if eax==chrg.cpMax ; no current selection invoke EnableMenuItem,wParam,IDM_COPY,MF_GRAYED invoke EnableMenuItem,wParam,IDM_CUT,MF_GRAYED invoke EnableMenuItem,wParam,IDM_DELETE,MF_GRAYED .else invoke EnableMenuItem,wParam,IDM_COPY,MF_ENABLED invoke EnableMenuItem,wParam,IDM_CUT,MF_ENABLED invoke EnableMenuItem,wParam,IDM_DELETE,MF_ENABLED .endif</font></b></pre><p><font face="Tahoma" size="-1">Lastly, we check whether a current selection exists by sending <font color="#006666"><b>EM_EX
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -