18第三十三課 RichEdit 控件基礎(chǔ)知識_第1頁
18第三十三課 RichEdit 控件基礎(chǔ)知識_第2頁
18第三十三課 RichEdit 控件基礎(chǔ)知識_第3頁
18第三十三課 RichEdit 控件基礎(chǔ)知識_第4頁
18第三十三課 RichEdit 控件基礎(chǔ)知識_第5頁
已閱讀5頁,還剩26頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

第三十三課:RichEdit控件基礎(chǔ)知識有很多人要求我提供關(guān)于RichEdit控件的指南,經(jīng)過這方面的大量編程實踐,我想我終于可以開寫關(guān)于RichEdit控件的指南了。諾,這個就是第一篇RichEdit指南。本指南將會描述涉及到RichEdit的幾乎所有方面,起碼是我所知道的關(guān)于它的所有方面。因為指南的信息量相當相當?shù)拇?,所以我將它分成了幾個部分,本篇是第一部分。在這篇指南里,你將會了解到什么是RichEdit控件,怎樣創(chuàng)建它,怎樣往里面載入數(shù)據(jù)和保存里面的數(shù)據(jù)。例子理論Aricheditcontrolcanbethoughtofasasouped-upeditcontrol.它提供了普通簡單Edit控件所缺少的很多令人合意的功能,譬如可以使用多種字體和字體大小,多級Undo/Redo,文本搜索,內(nèi)嵌OLE對象,編輯的拖放支持等等。由于RichEdit控件有這么多功能,因此它獨存于一個單獨的DLL文件。這個意味著如果你要使用RichEdit控件,就不能象使用其他普通控件那樣只調(diào)用InitCommonControls函數(shù)。你必須先使用LoadLibrary來載入RichEditDLL文件。這里有個問題,就是至今為止RichEdit控件共有3個版本,版本1,2和3。下面的表格顯示了每個版本的相應(yīng)的DLL文件名。DLLNameRichEditversionRicheditClassNameRiched32.dll1.0RICHEDITRichEd20.dll2.0RICHEDIT20ARichEd20.dll3.0RICHEDIT20A你會注意到版本2和3都使用了相同的DLL文件名,而且它們也使用了相同的類名!這樣在你想要明確的使用RichEdit3.0的功能的時候就會產(chǎn)生問題.到目前為止,我還找到一個正式的方法來區(qū)分版本2.0和3.0.不過,有個解決方法工作良好,我會在后面演示給你看..dataRichEditDLLdb"RichEd20.dll",0 ......data? hRichEditDLLdd?.code invokeLoadLibrary,addrRichEditDLL movhRichEditDLL,eax ...... invokeFreeLibrary,hRichEditDLL當RicheditDLL文件被載入時,它會注冊RichEdit窗口類,因此需要在你創(chuàng)建Richedit控件之前必須先要載入DLL.Richedit控件的類名是不同的?,F(xiàn)在你可能會有一個問題要提:我怎么樣才能夠知道我要使用哪個版本的Richedit控件?如果你不需要使用那些特別的功能,使用最新的版本也不定是最適宜的.下面的表格列出了每個RichEdit版本提供的功能.功能版本1.0版本2.0版本3.0選擇條xxxUnicode編輯

xx字符段落格式xxx文本搜索向前搜索向前/向后搜索向前/向后搜索內(nèi)嵌OLExxx拖放編輯xxxUndo/Redo單級多級多級自動URL識別

xx加速鍵支持

xx非窗口操作

xx分行符CRLFCRCR(可以模擬1.0版本)Zoom

xParagraphnumbering

xsimpletable

xnormalandheadingstyles

xunderlinecoloring

xhiddentext

xfontbinding

x上面的表格不是全面的:我只是列出了那些重要的功能.創(chuàng)建RchEdit控件載入DLL文件后,你可以調(diào)用CreateWindowEx來創(chuàng)建RichEdit控件,創(chuàng)建控件時你可以使用Edit控件風(fēng)格和普通窗口風(fēng)格,但是ES_LOWERCASE,ES_UPPERCASE和ES_OEMCONVERT風(fēng)格除外..const RichEditIDequ300.data RichEditDLLdb"RichEd20.dll",0 RichEditClassdb"RichEdit20A",0 ....data? hRichEditDLLdd? hwndRichEditdd?.code ..... invokeLoadLibrary,addrRichEditDLL movhRichEditDLL,eax invokeCreateWindowEx,0,addrRichEditClass,WS_VISIBLEorES_MULTILINEorWS_CHILDorWS_VSCROLLorWS_HSCROLL,\ CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,hWnd,RichEditID,hInstance,0 movhwndRichEdit,eax設(shè)置缺省的文本和背景顏色在使用Edit控件時設(shè)置文本和背景顏色可能有點問題,但是在RichEdit控件中已經(jīng)修正了這個問題.要設(shè)置RichEdit的背景色,你要發(fā)送EM_SETBKGNDCOLOR消息給RichEdit控件.這個消息具有以下語法.wParam==顏色選項.如果是0說明Windows使用lParam中的顏色值作為背景色.如果該參數(shù)不為0,Windows使用系統(tǒng)背景色.因為我們要發(fā)送該消息來改變背景色,所以我們必須令wParam為0.

lParam==指定要設(shè)置的顏色的COLORREF結(jié)構(gòu),僅當wParam為0時才有效.譬如,如果我要設(shè)置背景為純藍色,我需要寫入以下代碼: invokeSendMessage,hwndRichEdit,EM_SETBKGNDCOLOR,0,0FF0000h要設(shè)置文本顏色,RichEdit控件提供了另外的新消息,EM_SETCHARFORMAT來做這個工作.這個消息控制控件中一段選定的文本或者全部正文的格式.這個消息的語法如下:wParam==格式選項:SCF_ALL本次操作影響控件中全部文本.SCF_SELECTION本次操作僅影響選定的文本SCF_WORDorSCF_SELECTION本次操作僅影響所選定的那個單詞.如果選定是空的話,僅將插入點(光標)設(shè)置到指定字的位置.SCF_WORD標志必須跟SCF_SELECTION一起使用.lParam==CHARFORMAT或者CHARFORMAT2結(jié)構(gòu)的指針,說明要使用的正文格式.CHARFORMAT2只在Richedit2.0和更高版本才提供.這個不是說在RichEdit2.0以后你一定要使用CHARFORMAT2.如果你不需要使用到CHARFORMAT2中新加的功能,你仍然可以使用CHARFORMAT.CHARFORMATASTRUCT cbSizeDWORD? dwMaskDWORD? dwEffectsDWORD? yHeightDWORD? yOffsetDWORD? crTextColorCOLORREF? bCharSetBYTE? bPitchAndFamilyBYTE? szFaceNameBYTELF_FACESIZEdup(?) _wPad2WORD?CHARFORMATAENDSFieldNameDescriptioncbSize該結(jié)構(gòu)的大小.RichEdit控件使用該域來判斷該結(jié)構(gòu)的版本是CHARFORMAT還是CHARFORMAT2dwMask位標記,用來指定下面的那些成員是有效的.CFM_BOLDdwEffects成語中的CFE_BOLD值是有效的.CFM_CHARSETbCharSet成員是有效的。CFM_COLORcrTextColor成員跟dwEffects中的CFE_AUTOCOLOR值是有效的.CFM_FACEszFaceName成員是有效的.CFM_ITALICdwEffects成員中的CFE_ITALIC值是有效的.CFM_OFFSETyOffset成員是有效的.CFM_PROTECTEDdwEffects成員中的CFE_PROTECTED值是有效的.CFM_SIZEyHeight成員是有效的.CFM_STRIKEOUTdwEffects成員中的CFE_STRIKEOUT值是有效的.CFM_UNDERLINEdwEffects成員中的CFE_UNDERLINE值是有效的.dwEffects字符效果.可以是以下值的組合CFE_AUTOCOLOR使用系統(tǒng)正文顏色CFE_BOLD粗體字符CFE_ITALIC斜體字符CFE_STRIKEOUT字符帶刪除線CFE_UNDERLINE字符帶下劃線CFE_PROTECTED字符是受保護的;企圖改變字體會產(chǎn)生一個EN_PROTECTED通知消息.yHeight字符高度,單位是twips(1/1440英寸或者1/20的打印機的打印點).yOffset字符偏移,單位是twips,從基線算起.如果該成員是正值,字符是下標,如果負值,字符是下標.crTextColor正文顏色.如果指定了CFE_AUTOCOLOR字符效果,這個值會被忽略.bCharSet字符集bPitchAndFamilyFontfamilyandpitch.szFaceName字體名字,是一個空字符結(jié)尾的字符數(shù)組._wPad2填充通過檢查這個結(jié)構(gòu),你會發(fā)現(xiàn)我們可以改變正文效果(粗體,斜體,刪除線,下劃線),正文顏色(crTextColor)和字體外觀/大小/字符集.值得注意的是CFE_RPOTECTED標志.具有該標志的正文會被標志上受保護標志,意味著當用戶試圖改變它時,EN_PROTECTED這個通知消息會被發(fā)送到父窗口.同時你可以允許該更改是是否可以進行.CHARFORMAT2增加更多的正文風(fēng)格,象字體權(quán)值,間距,正文背景色,字距調(diào)整等等.如果你不需要這些額外的功能,只要使用CHARFORMAT即可.要設(shè)置正文格式,你必須考慮你想要該格式應(yīng)用到的正文的范圍.RichEdit控件引入了字符正文范圍的概念.RichEdit分派給每個字符一個從0開始數(shù)字值:控件中的第一個字符具有數(shù)字ID值為0,第二個為1...等等。要說明一個正文范圍,你必須提供給RichEdit控件兩個數(shù)值:范圍的第一個和最后一個字符的ID值。要跟EM_SETCHARFORMAT一起應(yīng)用字符格式,你有最多3種選擇:應(yīng)用于控件中的所有正文。(SCF_ALL)應(yīng)用于當前選定的正文。(SCF_SELECTION)應(yīng)用于當前選定的一個單詞。(SCF_WORD或者SCF_SELECTION)第一、二種情況是直觀的,最后一個選擇需要一點解釋。如果當前選擇只覆蓋了詞中的一個或多個字符但是不是整個詞,指定SCF_WORD+SCF_SELECTION標志將正文格式應(yīng)用于整個單詞。即使沒有當前選定,只有插入點(光標)位于單詞中,第三種情況下仍然會將正文格式應(yīng)用到整個單詞中。要使用EM_SETCHARFORMAT,你需要填充CHARFORMAT(或者CHARFORMAT2)結(jié)構(gòu)的結(jié)果成員。譬如,如果我們要設(shè)置正文顏色,需要如下一樣填充CHARFORMAT結(jié)構(gòu):.data? cfCHARFORMAT<>.....code movcf.cbSize,sizeofcf movcf.dwMask,CFM_COLOR movcf.crTextColor,0FF0000h invokeSendMessage,hwndRichEdit,EM_SETCHARFORMAT,SCF_ALL,addrcf以上的代碼片段設(shè)置RichEdit控件的正文顏色為純藍色。注意當EM_SETCHARFORMAT發(fā)生時,如果控件中沒有正文,在這個消息之后鍵入的正文將會使用消息EM_SETCHARFORMAT中指定的正文格式。設(shè)置正文/保存正文對于那些經(jīng)常使用Edit控件的人來說,你們肯定對使用WM_GETTEXT/WM_SETTEXT來設(shè)置/保存控制中的正文的方法很熟悉。這個方法對RichEdit仍然適用,但是如果文件很大的話這個方法不再是最有效的。Edit控件限制了正文長度,可以輸入最多64K的正文。但是RichEdit控件可以接受比這個限制大的多的正文數(shù)據(jù)。要分配一個很大的內(nèi)存塊(譬如大約10MB)來接受來自來自WM_GETTEXT消息的正文是一件很麻煩的事.Richedit控件為此提供了一個新的方法,就是正文流(TextStreaming)。要設(shè)置RichEdit文本,你只需給RichEdit簡單的提供一個回調(diào)函數(shù)的地址,當一切準備好時,RichEdit會調(diào)用回調(diào)函數(shù),并將正文緩沖區(qū)的地址傳遞給它?;卣{(diào)函數(shù)會將要發(fā)送給RichEdit的數(shù)據(jù)填入緩沖區(qū)或者將緩沖區(qū)的數(shù)據(jù)讀出,然后等待下一次調(diào)用自到操作完成。范例程序是流入(設(shè)置正文)和流出(取出正文)兩者的例子。你將會發(fā)現(xiàn)這個方法更加有效:這個緩沖區(qū)是RichEdit控件自己提供的,因此數(shù)據(jù)被分成了幾個大塊。這個操作包括兩條消息:EM_STREAMIN和EM_STREAMOUT。EM_STREAMIN和EM_STREAMOUT兩者使用同一個語法:wParam==格式選項.SF_RTF數(shù)據(jù)是RTF格式。SF_TEXT數(shù)據(jù)是簡單正文格式。SFF_PLAINRTF只有那些對所有語系都共有的關(guān)鍵詞才流入。SFF_SELECTION如果指定這個標志,流操作的目標就是當前選定的正文。如果你將正文流入,當前正文就會被替換,如果是流出,則只有那些當前選定的正文才流出。如果沒有指定這個標志,操作就會影響到控件中的所有正文。SF_UNICODE(RichEdit2.0或更高版本才提供)指定的是Unicode正文。lParam==指向一個EDITSTREAM結(jié)構(gòu),該結(jié)構(gòu)定義如下:EDITSTREAMSTRUCT dwCookieDWORD? dwErrorDWORD? pfnCallbackDWORD?EDITSTREAMENDSdwCookie應(yīng)用程序定義的數(shù)值,將會被傳遞給由pfnCallback成員說明的回調(diào)函數(shù)。通常地我們傳遞一些重要的參數(shù)值給回調(diào)函數(shù),譬如流入/流出處理中使用到的文件句柄。dwError指示流入(讀)或流出(寫)操作的結(jié)果。0說明沒有錯誤。非0值可以是EditStreamCallback函數(shù)的返回值或者說明控件遇到了錯誤。pfnCallback指向EditStreamCallback函數(shù)的指針,該函數(shù)是由用戶定義,由RichEdit調(diào)用來傳輸數(shù)據(jù)的。RichEdit將數(shù)據(jù)分開多個部分,重復(fù)地調(diào)用該函數(shù),一次一部分地進行數(shù)據(jù)傳輸。EditStream回調(diào)函數(shù)具有以下定義: EditStreamCallbackprotodwCookie:DWORD, pBuffer:DWORD, NumBytes:DWORD, pBytesTransferred:DWORD你必須在程序中按照以上原型來創(chuàng)建回調(diào)函數(shù)。然后將函數(shù)地址通過EDITSTREAM結(jié)構(gòu)傳遞給EM_STREAMIN或者EM_STREAMOUT。對流入操作(設(shè)置RichEdit控件中的正文): dwCookie:應(yīng)用程序定義的數(shù)值,通過EDITSTREAM結(jié)構(gòu)傳遞給EM_STREAMIN。在這里我們幾乎全部都是將用其內(nèi)容來設(shè)置RichEdit正文的文件的句柄傳給這個參數(shù)。 pBuffer:指向RichEdit提供的緩沖區(qū)。用來接受回調(diào)函數(shù)中提供的正文數(shù)據(jù)。 NumBytes:本次調(diào)用中你可以寫入緩沖區(qū)(pBuffer)的最大正文字節(jié)數(shù)。你必須遵守這個限制,也就是說你發(fā)送的數(shù)據(jù)的大小可以比NumBytes指定要小,但是不能大于這個值。你可以將這個數(shù)值當作pBuffer緩沖區(qū)的大小。pBytesTransferred:指向一個雙字(DWORD),你必須設(shè)置這個值來指示你實際上傳輸了多少字節(jié)數(shù)據(jù)到緩沖區(qū)。這個值通常跟NumBytes中的值是相等的.唯一的例外是當要傳送的數(shù)據(jù)少于緩沖區(qū)提供的大小時,譬如到達文件尾時就是了。對流出操作(讀出RichEdit控件的正文): dwCookie:跟流入操作相同.我們一般傳遞想要將數(shù)據(jù)寫入的文件的句柄給這個參數(shù)。 pBuffer:指向由RichEdit提供的緩沖區(qū),里面的是RichEdit的正文。要得到其大小,你必須檢查NumBytes的知. NumBytes:pBuffer指向的緩沖區(qū)的的數(shù)據(jù)的大小。 pBytesTransferred:指向一個雙字(DWORD),你必須設(shè)置這個值來指示你實際上從緩沖區(qū)里讀出了多少字節(jié)數(shù)據(jù)?;卣{(diào)函數(shù)返回0說明操作成功,而且如果還有數(shù)據(jù)需要讀/寫的話,RichEdit控件會繼續(xù)調(diào)用它。如果操作中發(fā)生了錯誤,而且你想停止操作的話,你可以返回一個非0值,這樣RichEdit就會丟棄pBuffer指向的數(shù)據(jù)。錯誤/成功返回值會在EDITSTREAM的dwError成員中返回,你可以在SendMessage返回后檢查流操作的錯誤/成功狀態(tài)。.例子:下面的例子是一個簡單的編輯器,你可以用來打開一個asm源文件,編輯它,然后保存。它使用了RichEdit控件2.0或者更高的版本..386.modelflat,stdcalloptioncasemap: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.libincludelib\masm32\lib\kernel32.libWinMainproto:DWORD,:DWORD,:DWORD,:DWORD.constIDR_MAINMENUequ101IDM_OPENequ40001IDM_SAVEequ40002IDM_CLOSEequ40003IDM_SAVEASequ40004IDM_EXITequ40005IDM_COPYequ40006IDM_CUTequ40007IDM_PASTEequ40008IDM_DELETEequ40009IDM_SELECTALLequ40010IDM_OPTION equ40011IDM_UNDO equ40012IDM_REDO equ40013IDD_OPTIONDLGequ101IDC_BACKCOLORBOXequ1000IDC_TEXTCOLORBOXequ1001RichEditID equ300.dataClassNamedb"IczEditClass",0AppNamedb"IczEditversion1.0",0RichEditDLLdb"riched20.dll",0RichEditClassdb"RichEdit20A",0NoRichEditdb"Cannotfindriched20.dll",0ASMFilterString db"ASMSourcecode(*.asm)",0,"*.asm",0 db"AllFiles(*.*)",0,"*.*",0,0OpenFileFaildb"Cannotopenthefile",0WannaSavedb"Thedatainthecontrolismodified.Wanttosaveit?",0FileOpenedddFALSEBackgroundColordd0FFFFFFh ;缺省為白色TextColordd0 ;缺省為黑色.data?hInstancedd?hRichEditdd?hwndRichEditdd?FileNamedb256dup(?)AlternateFileNamedb256dup(?)CustomColorsdd16dup(?).codestart: invokeGetModuleHandle,NULL movhInstance,eax invokeLoadLibrary,addrRichEditDLL .ifeax!=0 movhRichEdit,eax invokeWinMain,hInstance,0,0,SW_SHOWDEFAULT invokeFreeLibrary,hRichEdit .else invokeMessageBox,0,addrNoRichEdit,addrAppName,MB_OKorMB_ICONERROR .endif invokeExitProcess,eax WinMainprochInst:DWORD,hPrevInst:DWORD,CmdLine:DWORD,CmdShow:DWORD LOCALwc:WNDCLASSEX LOCALmsg:MSG LOCALhwnd:DWORD movwc.cbSize,SIZEOFWNDCLASSEX movwc.style,CS_HREDRAWorCS_VREDRAW movwc.lpfnWndProc,OFFSETWndProc movwc.cbClsExtra,NULL movwc.cbWndExtra,NULL pushhInst popwc.hInstance movwc.hbrBackground,COLOR_WINDOW+1 movwc.lpszMenuName,IDR_MAINMENU movwc.lpszClassName,OFFSETClassName invokeLoadIcon,NULL,IDI_APPLICATION movwc.hIcon,eax movwc.hIconSm,eax invokeLoadCursor,NULL,IDC_ARROW movwc.hCursor,eax invokeRegisterClassEx,addrwc INVOKECreateWindowEx,NULL,ADDRClassName,ADDRAppName,\WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\hInst,NULL movhwnd,eax invokeShowWindow,hwnd,SW_SHOWNORMAL invokeUpdateWindow,hwnd .whileTRUE invokeGetMessage,ADDRmsg,0,0,0 .break.if(!eax) invokeTranslateMessage,ADDRmsg invokeDispatchMessage,ADDRmsg .endw moveax,msg.wParam retWinMainendpStreamInProcprochFile:DWORD,pBuffer:DWORD,NumBytes:DWORD,pBytesRead:DWORD invokeReadFile,hFile,pBuffer,NumBytes,pBytesRead,0 xoreax,1 retStreamInProcendpStreamOutProcprochFile:DWORD,pBuffer:DWORD,NumBytes:DWORD,pBytesWritten:DWORD invokeWriteFile,hFile,pBuffer,NumBytes,pBytesWritten,0 xoreax,1 retStreamOutProcendpCheckModifyStateprochWnd:DWORD invokeSendMessage,hwndRichEdit,EM_GETMODIFY,0,0 .ifeax!=0 invokeMessageBox,hWnd,addrWannaSave,addrAppName,MB_YESNOCANCEL .ifeax==IDYES invokeSendMessage,hWnd,WM_COMMAND,IDM_SAVE,0 .elseifeax==IDCANCEL moveax,FALSE ret .endif .endif moveax,TRUE retCheckModifyStateendpSetColorproc LOCALcfm:CHARFORMAT invokeSendMessage,hwndRichEdit,EM_SETBKGNDCOLOR,0,BackgroundColor invokeRtlZeroMemory,addrcfm,sizeofcfm movcfm.cbSize,sizeofcfm movcfm.dwMask,CFM_COLOR pushTextColor popcfm.crTextColor invokeSendMessage,hwndRichEdit,EM_SETCHARFORMAT,SCF_ALL,addrcfm retSetColorendpOptionProcprochWnd:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD LOCALclr:CHOOSECOLOR .ifuMsg==WM_INITDIALOG .elseifuMsg==WM_COMMAND moveax,wParam shreax,16 .ifax==BN_CLICKED moveax,wParam .ifax==IDCANCEL invokeSendMessage,hWnd,WM_CLOSE,0,0 .elseifax==IDC_BACKCOLORBOX invokeRtlZeroMemory,addrclr,sizeofclr movclr.lStructSize,sizeofclr pushhWnd popclr.hwndOwner pushhInstance popclr.hInstance pushBackgroundColor popclr.rgbResult movclr.lpCustColors,offsetCustomColors movclr.Flags,CC_ANYCOLORorCC_RGBINIT invokeChooseColor,addrclr .ifeax!=0 pushclr.rgbResult popBackgroundColor invokeGetDlgItem,hWnd,IDC_BACKCOLORBOX invokeInvalidateRect,eax,0,TRUE .endif .elseifax==IDC_TEXTCOLORBOX invokeRtlZeroMemory,addrclr,sizeofclr movclr.lStructSize,sizeofclr pushhWnd popclr.hwndOwner pushhInstance popclr.hInstance pushTextColor popclr.rgbResult movclr.lpCustColors,offsetCustomColors movclr.Flags,CC_ANYCOLORorCC_RGBINIT invokeChooseColor,addrclr .ifeax!=0 pushclr.rgbResult popTextColor invokeGetDlgItem,hWnd,IDC_TEXTCOLORBOX invokeInvalidateRect,eax,0,TRUE .endif .elseifax==IDOK ;================================================================================== ;保存RichEdit控件的修改狀態(tài),因為更改正文顏色時改變了RichEdit控件的修改狀態(tài)。 ; ;================================================================================== invokeSendMessage,hwndRichEdit,EM_GETMODIFY,0,0 pusheax invokeSetColor popeax invokeSendMessage,hwndRichEdit,EM_SETMODIFY,eax,0 invokeEndDialog,hWnd,0 .endif .endif .elseifuMsg==WM_CTLCOLORSTATIC invokeGetDlgItem,hWnd,IDC_BACKCOLORBOX .ifeax==lParam invokeCreateSolidBrush,BackgroundColor ret .else invokeGetDlgItem,hWnd,IDC_TEXTCOLORBOX .ifeax==lParam invokeCreateSolidBrush,TextColor ret .endif .endif moveax,FALSE ret .elseifuMsg==WM_CLOSE invokeEndDialog,hWnd,0 .else moveax,FALSE ret .endif moveax,TRUE retOptionProcendpWndProcprochWnd:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD LOCALchrg:CHARRANGE LOCALofn:OPENFILENAME LOCALbuffer[256]:BYTE LOCALeditstream:EDITSTREAM LOCALhFile:DWORD .ifuMsg==WM_CREATE invokeCreateWindowEx,WS_EX_CLIENTEDGE,addrRichEditClass,0,WS_CHILDorWS_VISIBLEorES_MULTILINEorWS_VSCROLLorWS_HSCROLLorES_NOHIDESEL,\ CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,hWnd,RichEditID,hInstance,0 movhwndRichEdit,eax ;============================================================= ;設(shè)置正文長度限制,缺省是64K ;============================================================= invokeSendMessage,hwndRichEdit,EM_LIMITTEXT,-1,0 ;============================================================= ;Setthedefaulttext/backgroundcolor ;============================================================= invokeSetColor invokeSendMessage,hwndRichEdit,EM_SETMODIFY,FALSE,0 invokeSendMessage,hwndRichEdit,EM_EMPTYUNDOBUFFER,0,0 .elseifuMsg==WM_INITMENUPOPUP moveax,lParam .ifax==0 ;filemenu .ifFileOpened==TRUE ;afileisalreadyopened invokeEnableMenuItem,wParam,IDM_OPEN,MF_GRAYED invokeEnableMenuItem,wParam,IDM_CLOSE,MF_ENABLED invokeEnableMenuItem,wParam,IDM_SAVE,MF_ENABLED invokeEnableMenuItem,wParam,IDM_SAVEAS,MF_ENABLED .else invokeEnableMenuItem,wParam,IDM_OPEN,MF_ENABLED invokeEnableMenuItem,wParam,IDM_CLOSE,MF_GRAYED invokeEnableMenuItem,wParam,IDM_SAVE,MF_GRAYED invokeEnableMenuItem,wParam,IDM_SAVEAS,MF_GRAYED .endif .elseifax==1 ;edit菜單 ;============================================================================= ;檢查剪貼板里是否有正文,如果有的話我們就使能Paste菜單項。 ;============================================================================= invokeSendMessage,hwndRichEdit,EM_CANPASTE,CF_TEXT,0 .ifeax==0 ;notextintheclipboard invokeEnableMenuItem,wParam,IDM_PASTE,MF_GRAYED .else invokeEnableMenuItem,wParam,IDM_PASTE,MF_ENABLED .endif ;========================================================== ;檢查Undo隊列時是否為空 ;========================================================== invokeSendMessage,hwndRichEdit,EM_CANUNDO,0,0 .ifeax==0 invokeEnableMenuItem,wParam,IDM_UNDO,MF_GRAYED .else invokeEnableMenuItem,wParam,IDM_UNDO,MF_ENABLED .endif ;========================================================= ;檢查Redo隊列時是否為空 ;========================================================= invokeSendMessage,hwndRichEdit,EM_CANREDO,0,0 .ifeax==0 invokeEnableMenuItem,wParam,IDM_REDO,MF_GRAYED .else invokeEnableMenuItem,wParam,IDM_REDO,MF_ENABLED .endif ;========================================================= ;檢查RichEdit控件中是否有當前選定正文,有的話就使能 ;cut/copy/delete菜單項。 ;========================================================= invokeSendMessage,hwndRichEdit,EM_EXGETSEL,0,addrchrg moveax,chrg.cpMin .ifeax==chrg.cpMax ;沒有當前選定 invokeEnableMenuItem,wParam,IDM_COPY,MF_GRAYED invokeEnableMenuItem,wParam,IDM_CUT,MF_GRAYED invokeEnableMenuItem,wParam,IDM_DELETE,MF_GRAYED .else invokeEnableMenuItem,wParam,IDM_COPY,MF_ENABLED invokeEnableMenuItem,wParam,IDM_CUT,MF_ENABLED invokeEnableMenuItem,wParam,IDM_DELETE,MF_ENABLED .endif .endif .elseifuMsg==WM_COMMAND .iflParam==0 ;命令菜單 moveax,wParam .ifax==IDM_OPEN invokeRtlZeroMemory,addrofn,sizeofofn movofn.lStructSize,sizeofofn pushhWnd popofn.hwndOwner pushhInstance popofn.hInstance movofn.lpstrFilter,offsetASMFilterString movofn.lpstrFile,offsetFileName movbyteptr[FileName],0 movofn.nMaxFile,sizeofFileName movofn.Flags,OFN_FILEMUSTEXISTorOFN_HIDEREADONLYorOFN_PATHMUSTEXIST invokeGetOpenFileName,addrofn .ifeax!=0 invokeCreateFile,addrFileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0 .ifeax!=INVALID_HANDLE_VALUE movhFile,eax ;================================================================ ;將正文流入RichEdit控件。 ;================================================================ moveditstream.dwCookie,eax moveditstream.pfnCallback,offsetStreamInProc invokeSendMessage,hwndRichEdit,EM_STREAMIN,SF_TEXT,addreditstream ;========================================================== ;初始化修改狀態(tài)為FALSE ;========================================================== invokeSendMessage,hwndRichEdit,EM_SETMODIFY,FALSE,0 invokeCloseHandle,hFile movFileOpened,TRUE .else invokeMessageBox,hWnd,addrOpenFileFail,addrAppName,MB_OKorMB_ICONERROR .endif .endif .elseifax==IDM_CLOSE invokeCheckModifyState,hWnd .ifeax==TRUE invokeSetWindowText,hwndRichEdit,0 movFileOpened,FALSE .endif .elseifax==IDM_SAVE invokeCreateFile,addrFileName,GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0 .ifeax!=INVALID_HANDLE_VALUE@@: movhFile,eax ;================================================================ ;將RichEdit中的正文流出到文件中。 ;================================================================ moveditstream.dwCookie,eax moveditstream.pfnCallback,offsetStreamOutProc invokeSendMessage,hwndRichEdit,EM_STREAMOUT,SF_TEXT,addreditstream ;========================================================== ;初始化修改狀態(tài)為FALSE ;========================================================== invokeSendMessage,hwndRichEdit,EM_SETMODIFY,FALSE,0 invokeCloseHandle,hFile .else invokeMessageBox,hWnd,addrOpenFileFail,addrAppName,MB_OKorMB_ICONERROR .endif .elseifax==IDM_COPY invokeSendMessage,hwndRichEdit,WM_COPY,0,0 .elseifax==IDM_CUT invokeSendMessage,hwndRichEdit,WM_CUT,0,0 .elseifax==IDM_PASTE invokeSendMessage,hwndRichEdit,WM_PASTE,0,0 .elseifax==IDM_DELETE invokeSendMessage,hwndRichEdit,EM_REPLACESEL,TRUE,0 .elseifax==IDM_SELECTALL movchrg.cpMin,0 movchrg.cpMax,-1 invokeSendMessage,hwndRichEdit,EM_EXSETSEL,0,addrchrg .elseifax==IDM_UNDO invokeSendMessage,hwndRichEdit,EM_UNDO,0,0 .elseifax==IDM_REDO invokeSendMessage,hwndRichEdit,EM_REDO,0,0 .elseifax==IDM_OPTION invokeDialogBoxParam,hInstance,IDD_OPTIONDLG,hWnd,addrOptionProc,0 .elseifax==IDM_SAVEAS invokeRtlZeroMemory,addrofn,sizeofofn movofn.lStructSize,sizeofofn pushhWnd popofn.hwndOwner pushhInstance popofn.hInstance movofn.lpstrFilter,offsetASMFilterString movofn.lpstrFile,offsetAlternateFileName movbyteptr[AlternateFileName],0 movofn.nMaxFile,sizeofAlternateFileName movofn.Flags,OFN_FILEMUSTEXISTorOFN_HIDEREADONLYorOFN_PATHMUSTEXIST invokeGetSaveFileName,addrofn .ifeax!=0 invokeCreateFile,addrAlternateFileName,GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0 .ifeax!=INVALID_HANDLE_VALUE jmp@B .endif .endif .elseifax==IDM_EXIT invokeSendMessage,hWnd,WM_CLOSE,0,0 .endif .endif .elseifuMsg==WM_CLOSE invokeCheckModifyState,hWnd .ifeax==TRUE invokeDestroyWindow,hWnd .endif .elseifuMsg==WM_SIZE moveax,lParam movedx,eax andeax,0FFFFh shredx,16 invokeMoveWindow,hwndRichEdit,0,0,eax,edx,TRUE .elseifuMsg==WM_DESTROY invokePostQuitMessage,NULL .else invokeDefWindowProc,hWnd,uMsg,wParam,lParam ret .endif xoreax,eax retWndProcendpendstart;===================================================================;資源文件;===================================================================#include"resource.h"#defineIDR_MAINMENU101#defineIDD_OPTIONDLG101#defineIDC_BACKCOLORBOX1000#defineIDC_TEXTCOLORBOX1001#defineIDM_OPEN40001#defineIDM_SAVE40002#defineIDM_CLOSE40003#defineIDM_SAVEAS40004#defineIDM_EXIT40005#defineIDM_COPY40006#defineIDM_CUT40007#defineIDM_PASTE40008#defineIDM_DELETE40009#defineIDM_SELECTALL40010#defineIDM_OPTION40011#defineIDM_UNDO40012#defineIDM_REDO40013IDR_MAINMENUMENUDISCARDABLEBEGINPOPUP"&File"BEGINMENUITEM"&Open",IDM_OPENMENUITEM"&Close",IDM_CLOSEMENUITEM"&Save",IDM_SAVEMENUITEM"Save&As",IDM_SAVEASMENUITEMSEPARATORMENUITEM"E&xit",IDM_EXITENDPOPUP"&Edit"BEGINMENUITEM"&Undo",IDM_UNDOMENUITEM"&Redo",IDM_REDOMENUITEM"&Copy",IDM_COPYMENUITEM"C&ut",IDM_CUTMENUITEM"&Paste",IDM_PASTEMENUITEMSEPARATORMENUITEM"&Delete",IDM_DELETEMENUITEMSEPARATORMENUITEM"Select&All",IDM_SELECTALLENDMENUITEM"Options",IDM_OPTIONENDIDD_OPTIONDLGDIALOGDISCARDABLE0,0,183,54STYLEDS_MODALFRAME|WS_POPUP|WS_VISIBLE|WS_CAPTION|WS_SYSMENU|DS_CENTERCAPTION"Options"FONT8,"MSSansSerif"BEGINDEFPUSHBUTTON"OK",IDOK,137,7,39,14PUSHBUTTON"Cancel",IDCANCEL,137,25,39,14GROUPBOX"",IDC_STATIC,5,0,124,49LTEXT"BackgroundColor:",IDC_STATIC,20,14,60,8LTEXT"",IDC_BACKCOLORBOX,85,11,28,14,SS_NOTIFY|WS_BORDERLTEXT"TextColor:",IDC_STATIC,20,33,35,8LTEXT"",IDC_TEXTCOLORBOX,85,29,28,14,SS_NOTIFY|WS_BORDEREND分析:例子程序首先載入RichEditDLL,在這里是riched20.dll.如果DLL載入失敗,就返回Windows.invokeLoadLibrary,addrRichEditDLL.ifeax!=0 movhRichEdit,eax invokeWinMain,hInstance,0,0,SW_SHOWDEFAULT invokeFreeLibrary,hRichEdit.else invokeMessageBox,0,addrNoRichEdit,addrAppName,MB_OKorMB_ICONERROR.endifinvokeExitProcess,eax成功載入DLL后,我們繼續(xù)創(chuàng)建一個常規(guī)窗口,作為RichEdit的父窗口。在WM_CREATE處理函數(shù)里,我們創(chuàng)建一個RichEdit控件: invokeCreateWindowEx,WS_EX_CLIENTEDGE,addrRichEditClass,0,WS_CHILDorWS_VISIBLEorES_MULTILINEorWS_VSCROLLorWS_HSCROLLorES_NOHIDESEL,\ CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,hWnd,RichEditID,hInstance,0 movhwndRichEdit,eax注意在這里我們指定了ES_MULTILINE風(fēng)格,否則創(chuàng)建的會是一個單行的控件。 invokeSendMessage,hwndRichEdit,EM_LIMITTEXT,-1,0創(chuàng)建了RichEdit控件之后,我們必須設(shè)置新的正文大小。缺省時,RichEdit控件具有64K的正文大小限制,跟簡單的多行Edit控件相同。我們需要擴展這個限制,允許用來操作更大的文件。在上一個代碼行里,我們指定了大小為-1,大小總計為0FFFFFFFFh字節(jié),是一個很大的數(shù)值了。invokeSetColor

下一步,我們設(shè)置正文/背景色。因為這個操作可以在程序中的其他部分執(zhí)行,我把這些代碼放到一個叫SetColor的函數(shù)里。SetColorproc LOCALcfm:CHARFORMAT invokeSendMessage,hwndRichEdit,EM_SETBKGNDCOLOR,0,BackgroundColor設(shè)置RichEdit控件的背景色是一個很簡單的操作:只需發(fā)送EM_SETBKGNDCOLOR信息給RIchEdit控件就行了。(如果你使用多行Edit控件,你必須處理WM_CTLCOLOREDIT消息)。缺省的背景色是白色的。 invokeRtlZeroMemory,addrcfm,sizeofcfm movcfm.cbSize,sizeofcfm movcfm.dwMask,CFM_COLOR pushTextColor popcfm.crTextColor設(shè)置好背景色之后,我們填充CHARFORMAT的成員,以便用來設(shè)置設(shè)置正文顏色。應(yīng)該注意的是我們使用該結(jié)構(gòu)的大小來填充cbSize成員,這樣RichEdit控件就知道我們發(fā)送的是CHARFORMAT,而不是CHARFORMAT2。dwMask只使用了一個CFM_COLOR標志,因為我們只想設(shè)置正文顏色,同時往crTextColor里填入我們想要的正文顏色值. invokeSendMessage,hwndRichEdit,EM_SETCHARFORMAT,SCF_ALL,addrcfm retSetColorendp設(shè)置好顏色后,你必須要清空Undo緩沖區(qū),因為更改正文/背景顏色的操作是可撤消的(Undo-able),更改顏色時在緩沖區(qū)里留下了Undo信息。我們可以發(fā)送EM_EMPTYUNDOBUFFER消息來實現(xiàn)這個操作。 invokeSendMessage,hwndRichEdit,EM_EMPTYUNDOBUFFER,0,0填充好CHARFORMAT結(jié)構(gòu),我們發(fā)送EM_SETCHARFORMAT消息給RichEdit控件,在wParam中指定SCF_ALL標志,說明我們想把正文格式應(yīng)用于控件中的所有正文。注意在我們第一次創(chuàng)建RichEdit控件時,我們沒有指定它的大小/位置。這是因為我們想它覆蓋父窗口的全部客戶區(qū)。當父窗口大小改變時,我們就跟著改變RichEdit控件的大小。 .elseifuMsg==WM_SIZE moveax,lParam movedx,eax andeax,0FFFFh shredx,16 invokeMoveWindow,hwndRichEdit,0,0,eax,edx,TRUE在上面的程序片段,我們使用了在lParam中的客戶區(qū)的新尺寸,通過MoveWindow來改變RichEdit的大小。當用戶點擊文件File/Edit菜單條時,我們處理WM_INITPOPUPMENU消息,因此我們可以在顯示子菜單給用戶之前準備好各個子菜單項的狀態(tài)。譬如,如果已經(jīng)有一個文件在RichEdit控件中打開了,我們想禁止Open菜單項同時使能其他的菜單項。對于這種情況下的File菜單條,我們使用變量FileOpened來作為標志表示是否有一個文件已經(jīng)打開了。如果這個變量是TRUE值,我們知道已經(jīng)有一個文件被打開了。 .elseifuMsg==WM_INITMENUPOPUP moveax,lParam .ifax==0 ;file菜單 .ifFileOpened==TRUE ;已經(jīng)打開了一個文件 invokeEnableMenuItem,wParam,IDM_OPEN,MF_GRAYED invokeEnableMenuItem,wParam,IDM_CLOSE,MF_ENABLED invokeEnableMenuItem,wParam,IDM_SAVE,MF_ENABLED invokeEnableMenuItem,wParam,IDM_SAVEAS,MF_ENABLED .else invokeEnableMenuItem,wParam,IDM_OPEN,MF_ENABLED invokeEnableMenuItem,wParam,IDM_CLOSE,MF_GRAYED invokeEnableMenuItem,wParam,IDM_SAVE,MF_GRAYED invokeEnableMenuItem,wParam,IDM_SAVEAS,MF_GRAYED .endif正如你所見的,如果有一個文件已經(jīng)打開了,我們將Open菜單項變灰禁止并將其他菜單項都使能。跟TRUE值相反的是FileOpened值為FALSE.在這種情況下的EDIT菜單條我們需要先檢查RichEdit控件/剪貼板的狀態(tài)。 invokeSendMessage,hwndRichEdit,EM_CANPASTE,CF_TEXT,0 .ifeax==0 ;剪貼板里沒有正文 invokeEnableMenuItem,wParam,IDM_PASTE,MF_GRAYED .else invokeEnableMenuItem,wParam,IDM_PASTE,MF_ENABLED .endif我們首先發(fā)送EM_CANPASTE消息,來檢查剪貼板里是否存在可用的正文。如果有的話,SendMessage返回TRUE,我們就將Paste菜單項使能。如果沒有的話,我們將該菜單項變灰禁止。 invokeSendMessage,hwndRichEdit,EM_CANUNDO,0,0 .ifeax==0 invokeEnableMenuItem,wParam,IDM_UNDO,MF_GRAYED .else invokeEnableMenuItem,wParam,IDM_UNDO,MF_ENABLED .endif跟著,我們通過發(fā)送EM_CANUNDO消息來檢查Undo緩沖區(qū)是否為空,如果不空,SendMessage返回TRUE,我們就使能Undo菜單項。 invokeSendMessage,hwndRichEdit,EM_CANREDO,0,0 .ifeax==0 invokeEnableMenuItem,wParam,IDM_REDO,MF_GRAYED .

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論