⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lion-tut-c33.htm

📁 内有一些代码
💻 HTM
📖 第 1 页 / 共 5 页
字号:
				.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

;===================================================================
; 资源文件
;===================================================================
#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 color=#0000cc 
face="Times New Roman, Times, serif">分析:</FONT></H3>
<P align=left><FONT face=Tahoma size=-1>例子程序首先载入RichEdit DLL, 在这里是 riched20.dll. 如果DLL载入失败,就返回 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>成功载入DLL后,我们继续创建一个常规窗口,作为RichEdit的父窗口。在 <FONT color=#006666><B>WM_CREATE</B></FONT> 处理函数里,我们创建一个RichEdit控件:</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>注意在这里我们指定了<FONT color=#006666><B> ES_MULTILINE</B></FONT> 风格,否则创建的会是一个单行的控件。</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>创建了RichEdit控件之后,我们必须设置新的正文大小。缺省时,RichEdit控件具有64K的正文大小限制,跟简单的多行Edit控件相同。我们需要扩展这个限制,允许用来操作更大的文件。在上一个代码行里,我们指定了大小为 -1, 大小总计为 0FFFFFFFFh 字节, 是一个很大的数值了。</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>下一步,我们设置正文/背景色 。</FONT><FONT face=Tahoma size=-1> 
因为这个操作可以在程序中的其他部分执行,我把这些代码放到一个叫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>设置RichEdit控件的背景色是一个很简单的操作:只需发送
<FONT color=#006666><B>EM_SETBKGNDCOLOR</B></FONT> 信息给RIchEdit控件就行了。(如果你使用多行Edit控件,你必须处理 <FONT color=#006666><B>WM_CTLCOLOREDIT</B></FONT> 消息)。缺省的背景色是白色的。 </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>设置好背景色之后,我们填充 <FONT color=#006666><B>CHARFORMAT</B></FONT> 的成员,以便用来设置设置正文颜色。应该注意的是我们使用该结构的大小来填充<FONT color=#006666><B>cbSize</B></FONT> 成员,这样RichEdit 控件就知道我们发送的是<FONT color=#006666><B>CHARFORMAT</B></FONT>, 而不是 <FONT 
color=#006666><B>CHARFORMAT2</B></FONT>。 <FONT color=#006666><B>dwMask</B></FONT> 只使用了一个 <FONT 
color=#0000cc><B>CFM_COLOR</B></FONT> 标志, 因为我们只想设置正文颜色,同时往 <FONT color=#006666><B>crTextColor</B></FONT> 里填入我们想要的正文颜色值. </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>设置好颜色后,你必须要清空 Undo 缓冲区,因为更改正文/背景颜色的操作是可撤消的(Undo-able),更改颜色时在缓冲区里留下了Undo信息。我们可以发送 <FONT color=#006666><B>EM_EMPTYUNDOBUFFER</B></FONT> 消息来实现这个操作。</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>填充好 <FONT 
color=#006666><B>CHARFORMAT</B></FONT> 结构, 我们发送 <FONT 
color=#006666><B>EM_SETCHARFORMAT</B></FONT> 消息给RichEdit控件,在<FONT 
color=#cc0033><B>wParam</B></FONT>中指定 <FONT color=#0000cc><B>SCF_ALL</B></FONT> 标志,说明我们想把正文格式应用于控件中的所有正文。</FONT><B><FONT face=Tahoma size=-1> 
</FONT></B></P>
<P><FONT face=Tahoma size=-1>注意在我们第一次创建RichEdit控件时,我们没有指定它的大小/位置。这是因为我们想它覆盖父窗口的全部客户区。当父窗口大小改变时,我们就跟着改变RichEdit控件的大小。</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>在上面的程序片段, 我们使用了在 <FONT color=#0000cc><B>lParam</B></FONT>中的客户区的新尺寸,通过 <FONT color=#009999><B><FONT color=#006666>MoveWindow</FONT></B></FONT>来改变RichEdit的大小
。</FONT></P>
<P><FONT face=Tahoma size=-1>当用户点击文件 File/Edit 菜单条时,我们处理 <FONT color=#006666><B>WM_INITPOPUPMENU</B></FONT> 消息,因此我们可以在显示子菜单给用户之前准备好各个子菜单项的状态。譬如,如果已经有一个文件在RichEdit控件中打开了,我们想禁止Open菜单项同时使能其他的菜单项。</FONT></P>
<P><FONT face=Tahoma size=-1>对于这种情况下的File菜单条, 我们使用变量 <FONT color=#0000cc><B>FileOpened</B></FONT> 来作为标志表示是否有一个文件已经打开了。如果这个变量是TRUE值,我们知道已经有一个文件被打开了。</FONT></P><PRE><B><FONT face=Tahoma>	.elseif uMsg==WM_INITMENUPOPUP
		mov eax,lParam
		.if ax==0		; file 菜单
			.if FileOpened==TRUE	; 已经打开了一个文件
				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>正如你所见的,如果有一个文件已经打开了,我们将Open菜单项变灰禁止并将其他菜单项都使能。跟TRUE值相反的是 <FONT color=#0000cc><B>FileOpened</B></FONT> 值为FALSE.</FONT></P>
<P><FONT face=Tahoma size=-1>在这种情况下的EDIT菜单条我们需要先检查RichEdit控件/剪贴板的状态。</FONT></P><PRE><B><FONT face=Tahoma>			invoke SendMessage,hwndRichEdit,EM_CANPASTE,CF_TEXT,0
			.if eax==0		; 剪贴板里没有正文
				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>我们首先发送 <FONT color=#006666><B>EM_CANPASTE</B></FONT> 消息,来检查剪贴板里是否存在可用的正文。如果有的话,<FONT color=#0000cc><B>SendMessage</B></FONT> 返回 TRUE ,我们就将 Paste 菜单项使能。如果没有的话,我们将该菜单项变灰禁止。
</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>跟着,我们通过发送 <FONT color=#006666><B>EM_CANUNDO</B></FONT> 消息来检查Undo 缓冲区是否为空,如果不空,<FONT color=#0000cc><B>SendMessage</B></FONT> 返回 TRUE ,我们就使能 Undo 菜单项。</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>我们通过发送 <FONT color=#006666><B>EM_CANREDO</B></FONT> 消息给 RichEdit 控件来检查 Redo 缓冲区。如果不空的话,<FONT color=#0000cc><B>SendMessage</B></FONT> 返回 TRUE,我们就使能 Redo 菜单项。</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		; 没有当前选定正文
				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>最后,我们通过发送 <FONT color=#006666><B>EM_EXGETSEL</B></FONT> 消息来检查是否存在当前选定的正文,该消息使用一个 <FONT color=#990099><B>CHARRANGE</B></FONT> 结构,定义如下:</FONT></P><PRE><FONT face=Tahoma><B>CHARRANGE STRUCT
  cpMin  DWORD      ?
  cpMax  DWORD      ?
CHARRANGE ENDS</B></FONT></PRE>
<P><FONT face=Tahoma size=-1><B><FONT color=#0000cc>cpMin</FONT></B> 包含紧接在范围中的第一个字符之前的字符的位置索引。
<BR><FONT color=#0000cc><B>cpMax</B></FONT> 包含紧跟在范围中的最后一个字符之后的的字符的位置索引。</FONT></P>
<P><FONT face=Tahoma size=-1><FONT color=#006666><B>EM_EXGETSEL</B></FONT> 返回后,<FONT color=#990099><B>CHARRANGE</B></FONT> 结构就会被用选择范围的开始和结束位置索引所填充。如果没有当前选定,<FONT color=#0000cc><B>cpMin</B></FONT> 和 <FONT color=#0000cc><B>cpMax</B></FONT> 就会是同样的数值,我们就将 Cut/Copy/Delete 菜单项变灰禁止。</FONT><FONT face=Tahoma size=-1><B></B></FONT></P>
<P><FONT face=Tahoma size=-1>当用户点击 Open 菜单项,我们就显示一个打开文件的对话框,如果用户选择了一个文件,我们就打开该文件并将其内容流入RichEdit 控件中。</FONT></P><PRE><B><FONT face=Tahoma>					invoke CreateFile,addr FileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0
					.if eax!=INVALID_HANDLE_VALUE
						mov hFile,eax

						mov editstream.dwCookie,eax
						mov editstream.pfnCallback,offset StreamInProc
						invoke SendMessage,hwndRichEdit,EM_STREAMIN,SF_TEXT,addr editstream</FONT></B></PRE>
<P><FONT face=Tahoma size=-1>使用 <FONT color=#666600><B>CreateFile</B></FONT>成功打开文件后,我们填充<FONT 
color=#cc0033><B>EDITSTREAM</B></FONT> 结构,以便准备发送 <FONT color=#006666><B>EM_STREAMIN</B></FONT> 消息我们选择通过 <FONT color=#006666><B>dwCookie</B></FONT> 成员发送打开文件的句柄,并在
<FONT color=#006666><B>pfnCallback</B></FONT> 成员中传递流回调函数的地址。</FONT></P>
<P><FONT face=Tahoma size=-1>流回调函数本身是简单基本的。</FONT></P><PRE><FONT face=Tahoma><B><FONT face=Tahoma><FONT color=#003399>StreamInProc</FONT> proc hFile:DWORD,pBuffer:DWORD, NumBytes:DWORD, pBytesRead:DWORD
	invoke ReadFile,hFile,pBuffer,NumBytes,pBytesRead,0
	xor eax,1
	ret
<FONT color=#003399>StreamInProc</FONT> endp</FONT></B><B></B></FONT></PRE>
<P><FONT face=Tahoma size=-1><B><FONT face=Tahoma size=-1></FONT></B>你可以看到流回调函数的所有参数跟 <FONT color=#006666><B>ReadFile</B></FONT> 函数 </FONT><FONT face=Tahoma size=-1>完美匹配。而且<FONT color=#

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -