?? 多個文件的工程---增強poppad.txt
字號:
mov eax,offset szReplText
mov frReplaceDlg.lpstrReplaceWith,eax
mov frReplaceDlg.wFindWhatLen,MAX_STRING_LEN ;
mov frReplaceDlg.wReplaceWithLen,MAX_STRING_LEN ;
mov frReplaceDlg.lCustData,0 ;
mov frReplaceDlg.lpfnHook,NULL ;
mov frReplaceDlg.lpTemplateName,NULL ;
invoke ReplaceText,addr frReplaceDlg
ret
PopFindReplaceDlg endp
PopFindFindText proc hwndEdit:HWND,piSearchOffset:DWORD, pfr:DWORD
;FINDREPLACEA STRUCT
; lStructSize DWORD ?
; hwndOwner DWORD ?
; hInstance DWORD ?
; Flags DWORD ?
; lpstrFindWhat DWORD ?
; lpstrReplaceWith DWORD ?
; wFindWhatLen WORD ?
; wReplaceWithLen WORD ?
; lCustData DWORD ?
; lpfnHook DWORD ?
; lpTemplateName DWORD ?
;FINDREPLACEA ENDS
LOCAL iLength, iPos:DWORD
LOCAL pstrDoc, pstrPos:PTSTR
;Read in the edit document
invoke GetWindowTextLength,hwndEdit
mov iLength,eax
inc eax
mov ecx,sizeof (TCHAR)
mul ecx
invoke LocalAlloc,LMEM_FIXED or LMEM_ZEROINIT,eax
.if eax==NULL
mov eax,FALSE
ret
.else
mov pstrDoc,eax
.endif
invoke GetWindowText,hwndEdit, pstrDoc, iLength + 1
;Search the document for the find string
mov esi,pfr
mov eax,[esi+16] ;pfr->lpstrFindWhat
mov esi,piSearchOffset
mov ebx,[esi]
add ebx,pstrDoc
invoke StrStr,ebx,eax
;pstrPos = _tcsstr (pstrDoc + * piSearchOffset, eax) ;
mov pstrPos,eax
invoke LocalFree,pstrDoc
;Return an error code if the string cannot be found
.if (pstrPos == NULL)
mov eax,FALSE
ret
.endif
;Find the position in the document and the new start offset
mov eax,pstrPos
sub eax,pstrDoc
mov iPos,eax
;invoke wsprintf,addr szReplText,CTEXT("%d"),iPos
;invoke MessageBox,hwndEdit,addr szReplText,NULL,MB_OK
mov esi,pfr
mov eax,[esi+16] ;pfr->lpstrFindWhat
invoke lstrlen,eax
add eax,iPos
mov esi,piSearchOffset
mov [esi],eax
;Select the found text
invoke SendMessage,hwndEdit, EM_SETSEL, iPos,eax
invoke SendMessage,hwndEdit, EM_SCROLLCARET, 0, 0
mov eax,TRUE
ret
PopFindFindText endp
PopFindNextText proc hwndEdit:HWND, piSearchOffset:DWORD
LOCAL fr:FINDREPLACE
mov eax,offset szFindText
mov fr.lpstrFindWhat,eax
invoke PopFindFindText,hwndEdit, piSearchOffset,addr fr
ret
PopFindNextText endp
PopFindReplaceText proc hwndEdit:HWND,piSearchOffset:DWORD, pfr:DWORD
;Find the text
invoke PopFindFindText,hwndEdit, piSearchOffset, pfr
.if (eax==FALSE)
mov eax,FALSE
ret
.endif
;Replace it
mov esi,pfr
invoke SendMessage,hwndEdit, EM_REPLACESEL, 0, [esi+20]
mov eax,TRUE
ret
PopFindReplaceText endp
PopFindValidFind proc
mov eax,TRUE
mov bl,szFindText[0]
cmp bl,0
jz @f
mov eax,FALSE
@@:
ret
PopFindValidFind endp
end
POPPAD.RC
#include "resource.h"
#define IDC_FILENAME 1000
#define IDM_FILE_NEW 40001
#define IDM_FILE_OPEN 40002
#define IDM_FILE_SAVE 40003
#define IDM_FILE_SAVE_AS 40004
#define IDM_FILE_PRINT 40005
#define IDM_APP_EXIT 40006
#define IDM_EDIT_UNDO 40007
#define IDM_EDIT_CUT 40008
#define IDM_EDIT_COPY 40009
#define IDM_EDIT_PASTE 40010
#define IDM_EDIT_CLEAR 40011
#define IDM_EDIT_SELECT_ALL 40012
#define IDM_SEARCH_FIND 40013
#define IDM_SEARCH_NEXT 40014
#define IDM_SEARCH_REPLACE 40015
#define IDM_FORMAT_FONT 40016
#define IDM_HELP 40017
#define IDM_APP_ABOUT 40018
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
ABOUTBOX DIALOG DISCARDABLE 32, 32, 180, 100
STYLE DS_MODALFRAME | WS_POPUP
FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,66,80,50,14
ICON "POPPAD",IDC_STATIC,7,7,20,20
CTEXT "PopPad",IDC_STATIC,40,12,100,8
CTEXT "Popup Editor for Windows",IDC_STATIC,7,40,166,8
CTEXT "(c) Charles Petzold, 1998",IDC_STATIC,7,52,166,8
END
PRINTDLGBOX DIALOG DISCARDABLE 32, 32, 186, 95
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "PopPad"
FONT 8, "MS Sans Serif"
BEGIN
PUSHBUTTON "Cancel",IDCANCEL,67,74,50,14
CTEXT "Sending",IDC_STATIC,8,8,172,8
CTEXT "",IDC_FILENAME,8,28,172,8
CTEXT "to print spooler.",IDC_STATIC,8,48,172,8
END
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
POPPAD MENU DISCARDABLE
BEGIN
POPUP "&File"
BEGIN
MENUITEM "&New\tCtrl+N", IDM_FILE_NEW
MENUITEM "&Open...\tCtrl+O", IDM_FILE_OPEN
MENUITEM "&Save\tCtrl+S", IDM_FILE_SAVE
MENUITEM "Save &As...", IDM_FILE_SAVE_AS
MENUITEM SEPARATOR
MENUITEM "&Print\tCtrl+P", IDM_FILE_PRINT
MENUITEM SEPARATOR
MENUITEM "E&xit", IDM_APP_EXIT
END
POPUP "&Edit"
BEGIN
MENUITEM "&Undo\tCtrl+Z", IDM_EDIT_UNDO
MENUITEM SEPARATOR
MENUITEM "Cu&t\tCtrl+X", IDM_EDIT_CUT
MENUITEM "&Copy\tCtrl+C", IDM_EDIT_COPY
MENUITEM "&Paste\tCtrl+V", IDM_EDIT_PASTE
MENUITEM "De&lete\tDel", IDM_EDIT_CLEAR
MENUITEM SEPARATOR
MENUITEM "&Select All", IDM_EDIT_SELECT_ALL
END
POPUP "&Search"
BEGIN
MENUITEM "&Find...\tCtrl+F", IDM_SEARCH_FIND
MENUITEM "Find &Next\tF3", IDM_SEARCH_NEXT
MENUITEM "&Replace...\tCtrl+R", IDM_SEARCH_REPLACE
END
POPUP "F&ormat"
BEGIN
MENUITEM "&Font...", IDM_FORMAT_FONT
END
POPUP "&Help"
BEGIN
MENUITEM "&Help", IDM_HELP
MENUITEM "&About PopPad...", IDM_APP_ABOUT
END
END
/////////////////////////////////////////////////////////////////////////////
//
// Accelerator
//
POPPAD ACCELERATORS DISCARDABLE
BEGIN
VK_BACK, IDM_EDIT_UNDO, VIRTKEY, ALT, NOINVERT
VK_DELETE, IDM_EDIT_CLEAR, VIRTKEY, NOINVERT
VK_DELETE, IDM_EDIT_CUT, VIRTKEY, SHIFT, NOINVERT
VK_F1, IDM_HELP, VIRTKEY, NOINVERT
VK_F3, IDM_SEARCH_NEXT, VIRTKEY, NOINVERT
VK_INSERT, IDM_EDIT_COPY, VIRTKEY, CONTROL, NOINVERT
VK_INSERT, IDM_EDIT_PASTE, VIRTKEY, SHIFT, NOINVERT
"^C", IDM_EDIT_COPY, ASCII, NOINVERT
"^F", IDM_SEARCH_FIND, ASCII, NOINVERT
"^N", IDM_FILE_NEW, ASCII, NOINVERT
"^O", IDM_FILE_OPEN, ASCII, NOINVERT
"^P", IDM_FILE_PRINT, ASCII, NOINVERT
"^R", IDM_SEARCH_REPLACE, ASCII, NOINVERT
"^S", IDM_FILE_SAVE, ASCII, NOINVERT
"^V", IDM_EDIT_PASTE, ASCII, NOINVERT
"^X", IDM_EDIT_CUT, ASCII, NOINVERT
"^Z", IDM_EDIT_UNDO, ASCII, NOINVERT
END
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
POPPAD ICON DISCARDABLE "poppad.ico"
POPPAD.ICO
POPPAD.ASM 包含了程序中所有的基本原始碼。POPFILE.ASM 具有啟動File Open和File Save對話框的程序代碼,它還包含文件I/O例程。POPFIND.ASM 中包含了搜尋和替換文字功能。POPFONT.ASM 包含了字體選擇功能。
讓我們先來看一看POPPAD.ASM 。POPPAD.ASM 含有兩個文件名字符串:第一個,儲存在WndProc,名稱為szFileName,含有詳細的驅動器名稱、路徑名稱和文件名稱;第二個,儲存為szTitleName,是程序本身的文件名稱。它用在POPPAD3的DoCaption函數中,以便將文件名稱顯示在窗口的標題列上;也用在OKMessage函數和AskAboutSave函數中,以便向使用者顯示消息框。
POPFILE.ASM 包含了幾個顯示「File Open」和「File Save」對話框以及實際執行文件I/O的函數。對話框是使用函數GetOpenFileName和GetSaveFileName來顯示的。這兩個函數都使用一個型態為OPENFILENAME的結構,這個結構在WINDOWS.INC中定義。在POPFILE.ASM中,使用了一個該結構型態的整體變量,取名為ofn。ofn的大多數字段在PopFileInitialize函數中被初始化,POPPAD.ASM在WndProc中處理WM_CREATE消息時呼叫該函數。
將ofn作為靜態整體結構變量會比較方便,因為GetOpenFileName和GetSaveFileName給該結構傳回的一些信息,并將在以后呼叫這些函數時用到。
盡管通用對話框具有許多選項-包括設定自己的對話框模板,以及為對話框程序增加「掛勾(hook)」-POPFILE.ASM中使用的「File Open」和「File Save」對話框是最基本的。OPENFILENAME結構中被設定的字段只有lStructSize(結構的長度)、hwndOwner(對話框擁有者)、lpstrFilter(下面將簡要討論)、lpstrFile和nMaxFile(指向接收完整文件名稱的緩沖區指標和該緩沖區的大小)、lpstrFileTitle和nMaxFileTitle(文件名稱緩沖區及其大小)、Flags(設定對話框的選項)和lpstrDefExt(如果使用者在對話框中輸入文件名時不指定文件擴展名,那么它就是內定的文件擴展名)。
當使用者在「File」菜單中選擇「Open」時,POPPAD3呼叫POPFILE的PopFileOpenDlg函數,將窗口句柄、一個指向文件名稱緩沖區的指標和一個指向文件標題緩沖區的指標傳給它。PopFileOpenDlg恰當地設定OPENFILENAME結構的hwndOwner、lpstrFile和lpstrFileTitle字段,將Flags設定為OFN_ CREATEPROMPT,然后呼叫GetOpenFileName,顯示如圖11-6所示的普通對話框。
圖11-6 「File Open」對話框
當使用者結束這個對話框時,GetOpenFileName函數傳回。OFN_CREATEPROMPT旗標指示GetOpenFileName顯示一個消息框,詢問使用者如果所選文件不存在,是否要建立該文件。
左下角的下拉式清單方塊列出了將要顯示在文件列表中的文件型態,此清單方塊被稱為「篩選清單」。使用者可以通過從下拉式清單方塊列表中選擇另一種文件型態,來改變篩選條件。在POPFILE.ASM的PopFileInitialize函數中,我在變量szFilter(一個字符串數組)中為三種型態的文件定義了一個篩檢清單:帶有.TXT擴展名的文本文件、帶有.ASC擴展名的ASCII文件和所有文件。OPENFILENAME結構的lpstrFilter字段儲存指向此數組第一個字符串的指針。
如果使用者在對話框處于活動狀態時改變了篩選條件,那么OPENFILENAME的nFilterIndex字段反映出使用者的選擇。由于該結構是靜態變量,下次啟動對話框時,篩選條件將被設定為選中的文件型態。
POPFILE.C中的PopFileSaveDlg函數與此類似,它將Flags參數設定為OFN_OVERWRITEPROMPT,并呼叫GetSaveFileName啟動「File Save」對話框。OFN_OVERWRITEPROMPT旗標導致顯示一個消息框,如果被選文件已經存在,那么將詢問使用者是否覆蓋該文件。
Unicode文件I/O
對于本書中的大多數程序,您都不必注意Unicode和非Unicode版的區別。例如,在POPPAD3的Unicode中,編輯控件將保留Unicode文字和使用Unicode字符串的所有通用對話框。例如,當程序需要搜索和替換時,所有的操作都會處理Unicode字符串,而不需要轉換。
不過,POPPAD3得處理文件I/O,也就是說,程序不能閉門造車。如果Unicode版的POPPAD3獲得了編輯緩沖區的內容并將其寫入磁盤,文件將是使用Unicode存放的。如果非Unicode版的POPPAD3讀取了該文件,并將其寫入編輯緩沖區,其結果將是一堆垃圾。Unicode版讀取由非Unicode版儲存的文件時也會這樣。
解決的辦法在于辨別和轉換。首先,在POPFILE.C的PopFileWrite函數中,您將看到Unicode版的程序將在文件的開始位置寫入0xFEFF。這定義為字節順序標記,以表示文本文件含有Unicode文字。
其次,在PopFileRead函數中,程序用IsTextUnicode函數來決定文件是否含有字節順序標記。此函數甚至檢測字節順序標記是否反向了,亦即Unicode文本文件在Macintosh或者其它使用與Intel處理器相反的字節順序的機器上建立的。這時,字節的順序都經過翻轉。如果文件是Unicode版,但是被非Unicode版的POPPAD3讀取,這時,文字將被WideCharToMultiChar轉換。WideCharToMultiChar實際上是一個寬字符ANSI函數(除非您執行遠東版的Windows)。只有這時文字才能放入編輯緩沖區。
同樣地,如果文件是非Unicode文本文件,而執行的是Unicode版的程序,那么文字必須用MultiCharToWideChar轉換。
改變字體
我們將在后面一期中詳細討論字體,但那些都不能代替通用對話框函數來選擇字體。
在WM_CREATE消息處理期間,POPFONT.C中的POPPAD呼叫PopFontInitialize。這個函數取得一個依據系統字體建立的LOGFONT結構,由此建立一種字體,并向編輯控件發送一個WM_SETFONT消息來設定一種新的字體(內定編輯控件字體是系統字體,而PopFontInitialize為編輯控件建立一種新的字體,因為最終該字體將被刪除,而刪除現有系統字體是不明智的)。
當POPPAD收到來自程序的字體選項的WM_COMMAND消息時,它呼叫PopFontChooseFont。這個函數初始化一個CHOOSEFONT結構,然后呼叫ChooseFont顯示字體選擇對話框。如果使用者按下「OK」按鈕,那么ChooseFont將傳回TRUE。隨后,POPPAD呼叫PopFontSetFont來設定編輯控件中的新字體,舊字體將被刪除。
最后,在WM_DESTROY消息處理期間,POPPAD呼叫PopFontDeinitialize來刪除最近一次由PopFontSetFont建立的字體。
搜尋與替換
通用對話框鏈接庫也提供兩個用于文字搜尋和替換函數的對話框,這兩個函數(FindText和ReplaceText)使用一個型態為FINDREPLACE的結構。圖10-11中所示的POPFIND.ASM文件有兩個例程(PopFindFindDlg和PopFindReplaceDlg)呼叫這些函數,還有兩個函數在編輯控件中搜尋和替換文字。
使用搜尋和替換函數有一些考慮。首先,它們啟動的對話框是非模態對話框,這意味著必須改寫消息循環,以便在對話框活動時呼叫IsDialogMessage。第二,傳送給FindText和ReplaceText的FINDREPLACE結構必須是一個靜態變量,因為對話框是模態的,函數在對話框顯示之后傳回,而不是在對話框結束之后傳回;而對話框程序必須仍然能夠存取該結構。
第三,在顯示FindText和ReplaceText對話框時,它們通過一條特殊消息與擁有者窗口聯絡,消息編號可以通過以FINDMSGSTRING為參數呼叫RegisterWindowMessage函數來獲得。這是在WndProc中處理WM_CREATE消息時完成的,消息號存放在靜態變量中。
在處理內定消息時,WndProc將消息變量與RegisterWindowMessage傳回的值相比較。lParam消息參數是一個指向FINDREPLACE結構的指針,Flags字段指示使用者使用對話框是為了搜尋文字還是替換文字,以及是否要終止對話框。POPPAD3是呼叫POPFIND.ASM中的PopFindFindText和PopFindReplaceText函數來執行搜尋和替換功能的。
--------------------------------------------------------------------------------
<<<上一篇 歡迎訪問AoGo匯編小站:http://www.aogosoft.com 下一篇>>>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -