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

📄 lion-tut-c34.htm

📁 内有一些代码
💻 HTM
📖 第 1 页 / 共 3 页
字号:
		invoke SendMessage,hwndRichEdit,EM_LIMITTEXT,-1,0
		invoke SetColor
		invoke SendMessage,hwndRichEdit,EM_SETMODIFY,FALSE,0
		invoke SendMessage,hwndRichEdit,EM_SETEVENTMASK,0,ENM_MOUSEEVENTS
		invoke SendMessage,hwndRichEdit,EM_EMPTYUNDOBUFFER,0,0
	.elseif uMsg==WM_NOTIFY
		push esi
		mov esi,lParam
		assume esi:ptr NMHDR
		.if [esi].code==EN_MSGFILTER
			assume esi:ptr MSGFILTER
			.if [esi].msg==WM_RBUTTONDOWN
				invoke GetMenu,hWnd
				invoke GetSubMenu,eax,1
				mov hPopup,eax
				invoke PrepareEditMenu,hPopup
				mov edx,[esi].lParam
				mov ecx,edx
				and edx,0FFFFh
				shr ecx,16
				mov pt.x,edx
				mov pt.y,ecx
				invoke ClientToScreen,hWnd,addr pt
				invoke TrackPopupMenu,hPopup,TPM_LEFTALIGN or TPM_BOTTOMALIGN,pt.x,pt.y,NULL,hWnd,NULL
			.endif
		.endif
		pop esi
	.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
		.elseif ax==1	; edit menu
			invoke PrepareEditMenu,wParam
		.elseif ax==2		; search menu bar
			.if FileOpened==TRUE
				invoke EnableMenuItem,wParam,IDM_FIND,MF_ENABLED
				invoke EnableMenuItem,wParam,IDM_FINDNEXT,MF_ENABLED
				invoke EnableMenuItem,wParam,IDM_FINDPREV,MF_ENABLED
				invoke EnableMenuItem,wParam,IDM_REPLACE,MF_ENABLED
				invoke EnableMenuItem,wParam,IDM_GOTOLINE,MF_ENABLED
			.else
				invoke EnableMenuItem,wParam,IDM_FIND,MF_GRAYED
				invoke EnableMenuItem,wParam,IDM_FINDNEXT,MF_GRAYED
				invoke EnableMenuItem,wParam,IDM_FINDPREV,MF_GRAYED
				invoke EnableMenuItem,wParam,IDM_REPLACE,MF_GRAYED
				invoke EnableMenuItem,wParam,IDM_GOTOLINE,MF_GRAYED
			.endif
		.endif
	.elseif uMsg==WM_COMMAND
		.if lParam==0		; menu commands
			mov eax,wParam
			.if ax==IDM_OPEN
				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 FileName
				mov byte ptr [FileName],0
				mov ofn.nMaxFile,sizeof FileName
				mov ofn.Flags,OFN_FILEMUSTEXIST or OFN_HIDEREADONLY or OFN_PATHMUSTEXIST
				invoke GetOpenFileName,addr ofn
				.if eax!=0
					invoke CreateFile,addr FileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0
					.if eax!=INVALID_HANDLE_VALUE
						mov hFile,eax
						;================================================================
						; stream the text into the richedit control
						;================================================================						
						mov editstream.dwCookie,eax
						mov editstream.pfnCallback,offset StreamInProc
						invoke SendMessage,hwndRichEdit,EM_STREAMIN,SF_TEXT,addr editstream
						;==========================================================
						; Initialize the modify state to false
						;==========================================================
						invoke SendMessage,hwndRichEdit,EM_SETMODIFY,FALSE,0
						invoke CloseHandle,hFile
						mov FileOpened,TRUE
					.else
						invoke MessageBox,hWnd,addr OpenFileFail,addr AppName,MB_OK or MB_ICONERROR
					.endif
				.endif
			.elseif ax==IDM_CLOSE
				invoke CheckModifyState,hWnd
				.if eax==TRUE
					invoke SetWindowText,hwndRichEdit,0
					mov FileOpened,FALSE
				.endif
			.elseif ax==IDM_SAVE
				invoke CreateFile,addr FileName,GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0
				.if eax!=INVALID_HANDLE_VALUE
@@:				
					mov hFile,eax
					;================================================================
					; stream the text to the file
					;================================================================						
					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 color=#0000cc 
face="Times New Roman, Times, serif">分析</FONT></H3>
<P><FONT face=Tahoma size=-1>文本搜索功能是使用<FONT color=#006666><B>EM_FINDTEXTEX</B></FONT> 来实现的。当用户点击Find菜单项时,<FONT color=#000099><B>IDM_FIND</B></FONT> 消息就会被发送,并显示一个 搜索 对话框。</FONT></P>
<P align=center><IMG height=120 src="" width=285></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>当用户输入搜索正文,按下Ok按钮后,我们从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>如果正文串不为空,我们就继续初始化<FONT color=#0000cc><B>uFlags</B></FONT> 变量为 0 。</FONT></FONT><FONT face=Tahoma 
size=-1>这个变量被用来保存跟<FONT color=#006666> <B>EM_FINDTEXTEX</B></FONT> 一起使用的搜索标志。之后,通过 <FONT color=#006666><B>EM_EXGETSEL</B></FONT> ,我们得到当前选定的正文,因为我们需要知道搜索操作的开始位置。</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>下一步就有一点精巧了。我们检查搜索方向Radio按钮来得到要按什么方向进行搜索。如果是向下搜索,我们设置 <FONT color=#0000cc><B>uFlags</B></FONT> 为<FONT color=#006666><B>FR_DOWN</B></FONT> 标志值。然后我们比较 <FONT color=#0000cc><B>cpMin</B></FONT> 和 <FONT color=#0000cc><B>cpMax</B></FONT>,检查是否要在选定的正文里搜索。
如果两者的值不相等,说明有当前选定正文,我们需要从选定正文的结尾开始搜索,到控件中的正文的结尾结束。从而我们需要替换 <FONT color=#0000cc><B>cpMax</B></FONT> 的值为 <FONT 
color=#0000cc><B>cpMin</B></FONT> ,并改变 <FONT 
color=#0000cc><B>cpMax</B></FONT> 的值为 -1 (0FFFFFFFFh)。如果没有当前选定正文,搜索的范围是从当前插入点(光标)到所有正文的结尾。</FONT></FONT></P>
<P><FONT face=Tahoma size=-1>如果用户选择了向前搜索,我们使用的范围是从选定正文的开始到控件中正文的开始处。这个就是我们只改变 <FONT color=#0000cc><B>cpMax</B></FONT> 的值为 0 原因。在使用向前搜索的情况下,<FONT color=#0000cc><B>cpMin</B></FONT> 包含搜索范围中最后一个字符的的字符索引。而<FONT color=#0000cc><B>cpMax</B></FONT> 则是搜索范围中第一个字符的字符索引。向后搜索则刚刚相反。</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>我们继续检查搜索标志的检查框,也就是 <FONT color=#006666><B> FR_MATCHCASE</B></FONT> and <FONT color=#006666><B>FR_WHOLEWORD</B></FONT>。最后,我们把要搜索的正文串的偏移量放入 <FONT color=#006666><B>lpstrText</B></FONT> 成员中。<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>现在我们已经准备好发送 <FONT color=#006666><B>EM_FINDTEXTEX</B></FONT> 消息了。之后,我们检查通过 <FONT color=#990099><B>SendMessage</B></FONT> 返回的搜索结果。如果返回 -1, 表示没有找到匹配的正文串。否则,<FONT 
color=#006666><B>FINDTEXTEX</B></FONT> 结构的 <FONT color=#0000cc><B>chrgText</B></FONT> 成员里会被填入匹配正文串的字符索引。因此我们继续使用 <FONT 
color=#006666><B> EM_EXSETSEL</B></FONT></FONT><FONT 
face=Tahoma><B> 消息来选定该正文串。</B></FONT></P>
<P><FONT face=Tahoma size=-1>替换操作也是以差不多的方式来完成。</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>我们先找到要搜索的正文串和用来替换的正文串。</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>为容易起见,替换操作在整个控件的所有正文中进行。因此开始索引为 0 ,结束索引为 -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>我们初始化 <FONT 
color=#006666><B>SETTEXTEX</B></FONT> 结构来表明我们想替换当前选定的文本和使用系统缺省的代码页。</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>我们进入无限循环,来搜索匹配的正文。如果找到一个,我们就通过<FONT 
color=#006666><B>EM_EXSETSEL</B></FONT> 来选定它,并通过<FONT 
color=#006666><B>EM_SETTEXTEX</B></FONT> 替换它。当没找到其他匹配串时,我们就退出循环体。</FONT></P>
<P><FONT face=Tahoma size=-1><B><FONT color=#006666>Find Next </FONT></B>和 
<FONT color=#006666><B>Find Prev.</B></FONT> 以跟Find操作相似方式使用 <FONT 
color=#006666><B>EM_FINDTEXTEX</B></FONT> 消息实现的功能。
find operation.</FONT></P>
<P><FONT face=Tahoma size=-1>下一步我们检查 Go to Line 功能。当用户点击 Go To Line 菜单项,我们显示如下的对话框:</FONT></P>
<P align=center><IMG height=75 src="" width=165></P>
<P align=left><FONT face=Tahoma size=-1>用户输入行号并按下OK按钮后,我们就开始处理。</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>从Edit控件中取得行号</FONT><B><BR></B></FONT></P><PRE align="left"><FONT face=Tahoma><B>	invoke SendMessage,hwndRichEdit,EM_GETLINECOUNT,0,0
	.if eax&gt;LineNo</B></FONT></PRE>
<P align=left><FONT face=Tahoma><FONT size=-1>从Edit控件中取得行号并检查用户指定的行号是否超出发范围。</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>如果是有效行号,我们要移动插入点到该行的第一个字符处。因此我们发送 <FONT color=#006666><B>EM_LINEINDEX</B></FONT> 消息给RichEdit控件。这个消息返回指定行的第一个字母的字符索引。我们把行号放到wParam中发送消息,返回后我们就得到了该字符索引。</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>设置选择正文,这次我们使用 <FONT color=#006666><B> EM_SETSEL</B></FONT> ,因为字符索引已经保存在 <FONT color=#006666><B>CHARRANGE</B></FONT> 
结构中,因而省了两个结构(要将那些索引放入一个 <FONT color=#006666><B>CHARRANGE</B></FONT> 结构)。</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>除非RichEdit控件得到焦点,否则插入点将不会显示。因此我们调用 <FONT color=#006666><B>SetFocus</B></FONT> 使它得到焦点.</FONT><FONT face=Tahoma><B> 
</B></FONT></P>
<HR SIZE=1>
<DIV align=center> <font face="宋体"> 
  <SCRIPT language=JavaScript1.1 src="../lion-tut-c13.files/textclick"></SCRIPT>
  <BR>
  </font></DIV>
<font face="宋体"><!-- 10:1 文本广告交换 --> </font> 
<DIV align=center> <font face="宋体"> 
  <SCRIPT language=JavaScript1.1 src="../lion-tut-c13.files/c21.htm"></SCRIPT>
  <!-- 10:1 文本广告交换 --></font></DIV>
<HR SIZE=1>
<P align=center><FONT face=Tahoma size=-1><B>翻译:farsky 来源:[<A 
href="http://win32asm.cjb.net/">Iczelion's Win32 Assembly Homepage</A>]<br>
  LuoYunBin's Win32 ASM Page, <a 
href="http://asm.yeah.net/">http://asm.yeah.net</a></B></FONT></P>
<br>
</BODY></HTML>

⌨️ 快捷键说明

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