多个文件的工程---增强POPPAD
相关的例子:下载>>> 作者:Zoologist 于2008-8-17上传 

我们之前编写的程序都是非常简单的单文件,下面的程序是稍微复杂的结构:一个主程序和若干个完成不同功能的程序。

首先,还是选择建立Win32 EXE 程序。

wpe1.jpg (18810 字节)

然后给工程命名,这几步同普通的程序没有差别。

wpe2.jpg (19277 字节)

建立成功之后,写好主程序,再逐步添加其余各个文件,第一种方法是,从新文件中创建,

wpe1.jpg (8869 字节)

将会新建出来一个空白文档:

wpe2.jpg (4990 字节)

在新建的文档中选择参数设置:

wpe3.jpg (6207 字节)

设置为下面这个样子:

wpe4.jpg (20413 字节)

之后,新建立的文件就可以先编译为OBJ文件,再同主文件一起编译生成需要的结果了。

wpe5.jpg (37888 字节)

如果你已经有了文件,打算加入工程中,请选择“导入文件”

wpe6.jpg (7645 字节)

选择你想加入的文件即可,加入新文件之后,按照上面提到的,设置相同的参数即可。

增强POPPAD

当我们向前面一期POPPAD中增加菜单时,还有几个标准菜单项没有做完。现在我们已经准备好在POPPAD中加入打开文件、读入文件以及在磁盘上储存编辑过文件的功能。在处理中,我们还将在POPPAD中加入字体选择和搜索替换功能。

实作POPPAD3程序的文件如程序11-6所示。

程序11-6 POPPAD3

        
POPPAD.ASM
        
;MASMPlus 代码模板 - 普通的 Windows 程序代码

.386
.Model Flat, StdCall
Option Casemap :None

Include windows.inc
Include user32.inc
Include kernel32.inc
Include gdi32.inc

includelib gdi32.lib
IncludeLib user32.lib
IncludeLib kernel32.lib
include macro.asm
	
	WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
	AboutDlgProc PROTO :HWND,:UINT,:WPARAM,:LPARAM
;Functions in POPFILE.ASM
PopFileInitialize       PROTO :HWND
PopFileOpenDlg          PROTO :HWND, :PTSTR, :PTSTR
PopFileSaveDlg          PROTO :HWND, :PTSTR, :PTSTR
PopFileRead             PROTO :HWND, :PTSTR
PopFileWrite            PROTO :HWND, :PTSTR

;Functions in POPFIND.ASM
PopFindFindDlg          PROTO :HWND
PopFindReplaceDlg       PROTO :HWND
PopFindFindText         PROTO :HWND,:DWORD, :DWORD
PopFindReplaceText      PROTO :HWND,:DWORD, :DWORD
PopFindNextText         PROTO :HWND,:DWORD
PopFindValidFind        PROTO 

;Functions in POPFONT.ASM
PopFontInitialize	PROTO :HWND
PopFontChooseFont	PROTO :HWND
PopFontSetFont		PROTO :HWND
PopFontDeinitialize 	PROTO

;Functions in POPPRNT.ASM
;BOOL PopPrntPrintFile (HINSTANCE, HWND, HWND, PTSTR) ;

	EDITID   equ	1

IDC_FILENAME     equ     1000
IDM_FILE_NEW     equ     40001
IDM_FILE_OPEN    equ     40002
IDM_FILE_SAVE    equ     40003
IDM_FILE_SAVE_AS equ     40004
IDM_FILE_PRINT   equ     40005
IDM_APP_EXIT     equ     40006
IDM_EDIT_UNDO    equ     40007
IDM_EDIT_CUT     equ     40008
IDM_EDIT_COPY    equ     40009
IDM_EDIT_PASTE   equ     40010
IDM_EDIT_CLEAR   equ     40011
IDM_EDIT_SELECT_ALL equ  40012
IDM_SEARCH_FIND  equ     40013
IDM_SEARCH_NEXT  equ     40014
IDM_SEARCH_REPLACE  equ   40015
IDM_FORMAT_FONT   equ    40016
IDM_HELP         equ     40017
IDM_APP_ABOUT    equ     40018
	

.DATA
	UNTITLED    db "(untitled)",0
	szAppName   db "PopPad",0
        bNeedSave   BOOL	FALSE
        FINDMSGSTRING  db	"commdlg_FindReplace",0
        nullStr	    db	0
.DATA?
        hwndEdit    HWND	?
        hInst       HINSTANCE	?
        iOffset     DWORD	?
        szFileName  db	MAX_PATH	dup(?)
        szTitleName db	MAX_PATH	dup(?)
        messageFindReplace UINT	?        
        hDlgModeless HWND  	?
.CODE
START:

	invoke GetModuleHandle,NULL
	invoke WinMain,eax,NULL,NULL,SW_SHOWDEFAULT
	invoke ExitProcess,0

WinMain proc hInstance:DWORD,hPrevInst:DWORD,szCmdLine:DWORD,iCmdShow:DWORD
	LOCAL msg  :MSG
	local hwnd :HWND
	LOCAL wndclass   :WNDCLASSEX
	LOCAL hAccel:HACCEL
	
	mov wndclass.cbSize,sizeof WNDCLASSEX	
	mov wndclass.style,CS_HREDRAW or CS_VREDRAW	
	mov wndclass.lpfnWndProc,offset WndProc

	mov wndclass.cbClsExtra,0
	mov wndclass.cbWndExtra,0
	
	push hInstance
	pop wndclass.hInstance
	
	invoke LoadIcon,NULL,IDI_APPLICATION
	mov wndclass.hIcon,eax	
	
	invoke LoadCursor,NULL,IDC_ARROW
	mov wndclass.hCursor,eax	
	
	invoke GetStockObject,WHITE_BRUSH
	mov wndclass.hbrBackground,EAX
	
	mov wndclass.lpszMenuName,offset szAppName
	mov wndclass.lpszClassName,offset szAppName

	mov wndclass.hIconSm,0
	
	invoke RegisterClassEx, ADDR wndclass
	.if (EAX==0)
		 invoke MessageBox,NULL,CTXT("This program requires Windows NT!"),addr szAppName,MB_ICONERROR 		
		 ret
	.endif
        
	invoke CreateWindowEx,
					NULL,
					ADDR szAppName, 					;window class name
					ADDR szAppName, 
					WS_OVERLAPPEDWINDOW,					;window style
					CW_USEDEFAULT,						;initial x position
					CW_USEDEFAULT,						;initial y position
					CW_USEDEFAULT, 						;initial x size
					CW_USEDEFAULT,						;initial y size
					NULL,							;parent window handle
					NULL,							;window menu handle
					hInstance,							;program instance handle
					szCmdLine										;creation parameters
	mov hwnd,eax
	
	invoke ShowWindow,hwnd,iCmdShow
	invoke UpdateWindow,hwnd
	
	StartLoop:
		invoke GetMessage,ADDR msg,NULL,0,0
			cmp eax, 0
			je ExitLoop
				invoke IsDialogMessage,hDlgModeless,addr msg
				.if	(eax!=TRUE)||hDlgModeless==NULL
					invoke	TranslateAccelerator,hwnd, hAccel,addr msg
					.if	(eax!=TRUE)
						invoke TranslateMessage, ADDR msg
						invoke DispatchMessage,  ADDR msg
					.endif
				.endif	
			jmp StartLoop
	ExitLoop:
	
	mov eax,msg.wParam
	ret

WinMain endp

DoCaption	proc hwnd:HWND,szTName:DWORD
	LOCAL	szCaption[64 + MAX_PATH]:TCHAR
	mov	esi,szTName
	mov	al,[esi]
	.if	al == FALSE
           	mov	ebx,offset UNTITLED 
        .else	
           	mov	ebx,szTName
        .endif
        invoke	wsprintf,addr szCaption, CTXT("%s - %s"),addr szAppName,ebx
        invoke	SetWindowText,hwnd, addr szCaption
        ret
DoCaption	endp

OkMessage	proc	hwnd:HWND,szMessage:DWORD,szTName:DWORD
        LOCAL	szBuffer[64 + MAX_PATH]:TCHAR 
        mov	esi,szTName
        mov	al,[esi]
        .if	al == FALSE
           	mov	ebx,offset UNTITLED 
        .else	
           	mov	ebx,szTName
        .endif           
        invoke	wsprintf,addr szBuffer,szMessage,ebx
	invoke	MessageBox,hwnd,addr szBuffer,addr szAppName, MB_OK or MB_ICONEXCLAMATION
        ret
OkMessage	endp

AskAboutSave	proc hwnd:HWND , szTName:DWORD
	LOCAL	szBuffer[64 + MAX_PATH]:TCHAR
        LOCAL	iReturn:DWORD

        mov	esi,szTName
        mov	al,[esi]
        .if	al ==FALSE
           	mov	ebx,offset UNTITLED 
        .else	
           	mov	ebx,szTName
        .endif
           
        invoke	wsprintf,addr szBuffer, CTXT ("Save current changes in %s?"),ebx
        invoke	MessageBox,hwnd,addr szBuffer,addr szAppName,MB_YESNOCANCEL or MB_ICONQUESTION
        mov	iReturn,eax
        .if (iReturn == IDYES)
          	invoke	SendMessage,hwnd, WM_COMMAND, IDM_FILE_SAVE, 0
               .if	(eax==FALSE)
                    	mov	eax,IDCANCEL
                    	mov	iReturn,eax
		.endif
	.endif
	mov	eax,iReturn 
        ret
AskAboutSave	endp
        
PopPrntPrintFile	proc	hInstPRN:HINSTANCE,hwnd:HWND,hwndEditPRN:HWND, pstrTitleName:PTSTR
	mov	eax,FALSE
	ret
PopPrntPrintFile	endp

WndProc proc hwnd:DWORD,message:DWORD,wParam :DWORD,lParam :DWORD
         LOCAL	iSelBeg, iSelEnd, iEnable:DWORD
         LOCAL	pfr:DWORD	;LPFINDREPLACE
;LPFINDREPLACE 是指向如下结构体的指针    
;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

	.if message==WM_CREATE
		mov	esi,lParam
		mov	eax,[esi+4]
		mov	hInst,eax
               ;Create the edit control child window
        
                invoke  CreateWindowEx,NULL,CTXT ("edit"), NULL,
                        WS_CHILD or WS_VISIBLE or WS_HSCROLL or WS_VSCROLL or \
                        WS_BORDER or ES_LEFT or ES_MULTILINE or \
                        ES_NOHIDESEL or ES_AUTOHSCROLL or ES_AUTOVSCROLL,
                        0, 0, 0, 0,
                        hwnd, EDITID, hInst, NULL
		mov	hwndEdit,eax

                invoke	SendMessage,hwndEdit, EM_LIMITTEXT, 32000, 0
        
                ;Initialize common dialog box stuff
        
                invoke PopFileInitialize,hwnd
                invoke PopFontInitialize,hwndEdit
                invoke RegisterWindowMessage,addr	FINDMSGSTRING
                mov	messageFindReplace,eax
                invoke DoCaption,hwnd,addr szTitleName

	        xor	eax,eax
	        ret
	.elseif message ==  WM_SETFOCUS
		invoke	SetFocus,hwndEdit
                xor	eax,eax
	        ret	        
	.elseif message ==  WM_SIZE
		mov	eax,lParam
		and	eax,0FFFFh
		mov	ebx,lParam
		shr	ebx,16
                invoke	MoveWindow,hwndEdit, 0, 0, eax,ebx, TRUE
                xor	eax,eax
	        ret
	.elseif message == WM_INITMENUPOPUP
        	mov	eax,lParam
		.if	eax==1      ; Edit menu
                                    ; Enable Undo if edit control can do it
                        invoke	 SendMessage,hwndEdit, EM_CANUNDO, 0, 0            
                        .if	eax==FALSE
                        	mov	ebx,MF_GRAYED
                        .else
                        	mov	ebx,MF_ENABLED
                        .endif
                        invoke	EnableMenuItem,wParam, IDM_EDIT_UNDO,ebx
                        
        			    ; Enable Paste if text is in the clipboard
        		invoke	 IsClipboardFormatAvailable,CF_TEXT
                        .if	eax==FALSE
                        	mov	ebx,MF_GRAYED
                        .else
                        	mov	ebx,MF_ENABLED
                        .endif        		
                        invoke	EnableMenuItem,wParam, IDM_EDIT_PASTE,ebx
                        	    ; Enable Cut, Copy, and Del if text is selected
                        invoke  SendMessage,hwndEdit, EM_GETSEL, addr iSelBeg,addr iSelEnd

                        .if	iSelEnd==FALSE
                        	mov	ebx,MF_GRAYED
                        .else
                        	mov	ebx,MF_ENABLED
                        .endif        
                        mov	iEnable ,ebx
                        mov	iSelBeg ,ebx
                       invoke   EnableMenuItem,wParam, IDM_EDIT_CUT,   iEnable
                       invoke   EnableMenuItem,wParam, IDM_EDIT_COPY,   iEnable
                       invoke   EnableMenuItem,wParam, IDM_EDIT_CLEAR,   iEnable                       
		.elseif	eax==2    ;Search menu
			; Enable Find, Next, and Replace if modeless
        		; dialogs are not already active
			.if	(hDlgModeless == NULL)
                        	mov	ebx,MF_ENABLED
                        .else
                        	mov	ebx,MF_GRAYED
			.endif	
                         mov	iEnable , ebx
        		invoke	EnableMenuItem ,wParam, IDM_SEARCH_FIND,        iEnable
        		invoke	EnableMenuItem ,wParam, IDM_SEARCH_NEXT,        iEnable
        		invoke	EnableMenuItem ,wParam, IDM_SEARCH_REPLACE,        iEnable        		
		.endif        
                xor	eax,eax
                ret
	.elseif message == WM_COMMAND
		; Messages from edit control
		mov	eax,wParam
		.if	(lParam!=FALSE)&&(ax==EDITID)
			mov	eax,wParam
			shr	eax,16
			.if	eax==EN_UPDATE
				mov	bNeedSave,TRUE
				xor	eax,eax
				ret
			.elseif (eax==EN_ERRSPACE)||(eax==EN_MAXTEXT)
				invoke MessageBox,hwnd, CTXT ("Edit control out of space."),addr szAppName, MB_OK or MB_ICONSTOP
				xor	eax,eax
				ret
			.endif
	        xor	eax,eax
	        ret				
		.endif
		
		; Messages from File menu
		mov	eax,wParam
		.if	ax==IDM_FILE_NEW
			.if	(bNeedSave!=FALSE)
				invoke	AskAboutSave,hwnd,addr szTitleName
				.if	(eax==IDCANCEL)
					xor	eax,eax
					ret
				.endif
			.endif
			invoke	 SetWindowText,hwndEdit,addr nullStr
			lea	esi,szFileName
			mov	BYTE ptr [esi],0
			lea	esi,szTitleName
			mov	BYTE ptr [esi],0
                        invoke	DoCaption,hwnd,addr szTitleName
        		mov	bNeedSave,FALSE ;
			xor	eax,eax
			ret
		.elseif	ax==IDM_FILE_OPEN
			.if	(bNeedSave!=FALSE)
				invoke	AskAboutSave,hwnd, addr szTitleName
        			.if 	(eax==IDCANCEL)
	        			xor	eax,eax
        				ret
        			.endif	
        		.endif	
        		invoke	PopFileOpenDlg,hwnd,addr szFileName,addr szTitleName
        		.if 	(eax!=FALSE)
       				invoke	PopFileRead,hwndEdit,addr szFileName
              			.if 	(eax==FALSE)
		               		invoke	OkMessage,hwnd, CTEXT ("Could not read file %s!"),addr szTitleName
	                          	mov	szFileName[0],0
					mov	szTitleName[0],0
                                 .endif
                         .endif
                        invoke	DoCaption,hwnd,addr szTitleName
                        mov	eax,FALSE
        		mov	bNeedSave,eax
        		xor	eax,eax
            		ret
		.elseif eax==IDM_FILE_SAVE
			mov	al,szFileName[0]
           		.if     (al!=FALSE)
           			invoke	PopFileWrite,hwndEdit, szFileName
                   		.if 	(eax!=FALSE)
                                   	mov	bNeedSave,FALSE
        				mov	eax,1
        				ret
                   		.else
                                invoke	OkMessage,hwnd, CTEXT ("Could not write file %s"),addr szTitleName
                                xor	eax,eax
                                ret
                   		.endif                                
                        .endif
                   ;fall through
            		jmp	@f	
		.elseif eax==IDM_FILE_SAVE_AS 
		@@:	
			invoke	PopFileSaveDlg,hwnd,addr szFileName,addr szTitleName
                        .if 	(eax!=FALSE)
	               		invoke	DoCaption,hwnd,addr szTitleName
	               		invoke	PopFileWrite,hwndEdit,addr szFileName
                                .if 	eax!=FALSE
                                	mov	eax,FALSE
					mov	bNeedSave,eax
        				mov	eax,1
        				ret
                                 .else
		                      	invoke	OkMessage,hwnd, CTEXT ("Could not write file %s"),addr szTitleName
        				xor	eax,eax
        				ret
                                 .endif
			.endif
			xor	eax,eax
			ret
		.elseif eax==IDM_FILE_PRINT
        		invoke	PopPrntPrintFile,hInst, hwnd, hwndEdit,addr szTitleName
                        .if 	eax==FALSE        
                   		invoke	OkMessage,hwnd, CTEXT ("Could not print file %s"),addr szTitleName
        		.endif
			xor	eax,eax
			ret
		.elseif eax==IDM_APP_EXIT
                        invoke	SendMessage,hwnd, WM_CLOSE, 0, 0
			xor	eax,eax
			ret
                       ; Messages from Edit menu
		.elseif eax==IDM_EDIT_UNDO
                        invoke	SendMessage,hwndEdit, WM_UNDO, 0, 0
			xor	eax,eax
			ret
		.elseif eax==IDM_EDIT_CUT
                        invoke	SendMessage,hwndEdit, WM_CUT, 0, 0
			xor	eax,eax
			ret
		.elseif eax==IDM_EDIT_COPY
                        invoke	SendMessage,hwndEdit, WM_COPY, 0, 0
			xor	eax,eax
			ret
		.elseif eax==IDM_EDIT_PASTE
                        invoke	SendMessage,hwndEdit, WM_PASTE, 0, 0
			xor	eax,eax
			ret
		.elseif eax==IDM_EDIT_CLEAR
                        invoke	SendMessage,hwndEdit, WM_CLEAR, 0, 0
			xor	eax,eax
			ret			
		.elseif eax==IDM_EDIT_SELECT_ALL
                        invoke	SendMessage,hwndEdit, EM_SETSEL, 0, -1
        		xor	eax,eax
        		ret			
			; Messages from Search menu
		.elseif eax==IDM_SEARCH_FIND
                        invoke	SendMessage,hwndEdit, EM_GETSEL, 0, addr iOffset
        		invoke	PopFindFindDlg,hwnd
                        mov	hDlgModeless,eax
       		 	xor	eax,eax
			ret
		.elseif eax==IDM_SEARCH_NEXT
               		invoke	SendMessage,hwndEdit, EM_GETSEL, 0,addr iOffset
               		invoke	PopFindValidFind
               		.if 	(eax!=FALSE)
                    		invoke	PopFindNextText,hwndEdit,addr iOffset
               		.else
               			invoke	PopFindFindDlg,hwnd
                    		mov	hDlgModeless,eax
               		.endif
       		 	xor	eax,eax
			ret		
		.elseif eax==IDM_SEARCH_REPLACE
        		invoke	SendMessage,hwndEdit, EM_GETSEL, 0,addr iOffset
        		invoke	PopFindReplaceDlg,hwnd
                        mov	hDlgModeless,eax
			xor	eax,eax
			ret
		.elseif eax==IDM_FORMAT_FONT
			invoke	PopFontChooseFont,hwnd
                        .if 	eax!=FALSE
                        	invoke	PopFontSetFont,hwndEdit
			.endif                        	
        		xor	eax,eax
        		ret
		.elseif eax==IDM_HELP
                        invoke	OkMessage,hwnd,CTXT ("Help not yet implemented!"),CTXT(" ")
        		xor	eax,eax
        		ret			
		.elseif eax==IDM_APP_ABOUT
                        invoke	DialogBoxParam,hInst, CTXT ("AboutBox"), hwnd,addr AboutDlgProc,0
        		xor	eax,eax
        		ret
		.endif	
	.elseif message ==  WM_CLOSE 
		.if	(bNeedSave==FALSE)
			invoke	DestroyWindow,hwnd
		.else	
			invoke	AskAboutSave,hwnd,addr szTitleName
			.if	(eax!=IDCANCEL)
				invoke	DestroyWindow,hwnd
			.endif	
		.endif
		xor	eax,eax
	        ret	
	        
	.elseif message == WM_QUERYENDSESSION 
		.if	(bNeedSave==FALSE)
			mov	eax,1
			ret			
		.else		
		invoke	AskAboutSave,hwnd,addr szTitleName
		.if	(eax!=IDCANCEL)
			mov	eax,1
			ret
		.else	
			xor	eax,eax
		.endif				
		.endif
	        ret		
	.elseif message == WM_DESTROY
		invoke  PopFontDeinitialize
	        invoke 	PostQuitMessage,NULL
	        xor	eax,eax
	        ret
        .else  
                ; Process "Find-Replace" messages      
                mov	eax,message
          	.if	(eax == messageFindReplace)
         	
          		mov	eax,lParam
          		mov	pfr,eax
          		mov	esi,eax
          		mov	eax,[esi+12]
          		and	eax,FR_DIALOGTERM
			.if 	(eax!=FALSE)
	                    	mov	hDlgModeless,NULL
	                .endif    
          		mov	esi,pfr
          		mov	eax,[esi+12]
          		and	eax,FR_FINDNEXT
	      
			.if 	(eax!=FALSE)
			invoke	wsprintf,addr szTitleName,CTEXT("%d"),iOffset	
			invoke	MessageBox,hwnd,addr szTitleName,NULL,MB_OK      
	                	invoke	PopFindFindText,hwndEdit,addr iOffset,pfr
				.if (eax==FALSE)
	                         	invoke	OkMessage,hwnd, CTEXT ("Text not found!"),addr nullStr
	                     	.endif    
	                .endif
	                
          		mov	esi,pfr
          		mov	eax,[esi+12]
          		and	eax,FR_REPLACE
          		mov	ebx,[esi+12]
          		and	ebx,FR_REPLACE          		
			.if 	(eax!=FALSE) || (ebx!=FALSE)
				invoke	PopFindReplaceText,hwndEdit,addr iOffset, pfr
				.if (eax==FALSE)
	                         	invoke	OkMessage,hwnd, CTEXT ("Text not found!"),addr nullStr
	                    	.endif
	                .endif    
	                
          		mov	esi,pfr
          		mov	eax,[esi+12]	                
          		and	eax,FR_REPLACEALL
			.if 	(eax!=FALSE)
	                    @@:	
	                    	invoke	PopFindReplaceText,hwndEdit,addr iOffset, pfr
	                    	cmp	eax,FALSE
	                    	jNz	@b
	                .endif              
	                xor	eax,eax
	                ret
	         .endif	        
	.endif
	invoke DefWindowProc,hwnd,message,wParam,lParam

	ret
WndProc endp

AboutDlgProc proc	hDlg:HWND,message:UINT,wParam:WPARAM,lParam:LPARAM
        
        mov	eax,message
        .if	eax==WM_INITDIALOG
 		mov	eax,TRUE
 		ret
        .elseif	eax==WM_COMMAND
        	mov	eax,wParam
        	and	eax,0FFFFh
        	.if	eax==IDOK
                        invoke	EndDialog,hDlg, 0
        		mov	eax,TRUE
        	.endif
        .endif
        
           mov	eax,FALSE
           ret
AboutDlgProc	endp

END START
        

POPFILE.ASM

.386
.Model Flat, StdCall
Option Casemap :None
include windows.inc
include comdlg32.inc
include gdi32.inc
include user32.inc
include    kernel32.inc
include    shlwapi.inc
include    advapi32.inc
includelib advapi32.lib
includelib comdlg32.lib
includelib shlwapi.lib

CTEXT macro Text
local szText
.data
szText byte Text, 0
.code
exitm <offset szText>
endm
.data
szFilter    db "Text Files (*.TXT)",0,"*.txt",0,\
"ASCII Files (*.ASC)",0,"*.asc",0,\
"All Files (*.*)",0,"*.*",0,0
.data?
    szBuffer    db    1000 dup(0)
ofn    OPENFILENAME <?>

.code
PopFileInitialize    proc    hwnd:HWND
    mov    ofn.lStructSize,sizeof (OPENFILENAME) ;
    mov    eax, hwnd
    mov    ofn.hwndOwner,eax
    mov    ofn.hInstance,NULL ;
    mov    eax,offset szFilter
    mov    ofn.lpstrFilter,eax
    mov    ofn.lpstrCustomFilter,NULL
    mov    ofn.nMaxCustFilter,0
    mov    ofn.nFilterIndex,0
    mov    ofn.lpstrFile,NULL ; // Set in Open and Close functions
    mov    ofn.nMaxFile,MAX_PATH
    mov    ofn.lpstrFileTitle,NULL ; // Set in Open and Close functions
    mov    ofn.nMaxFileTitle,MAX_PATH
    mov    ofn.lpstrInitialDir,NULL ;

    mov    ofn.lpstrTitle,NULL ;
    mov    ofn.Flags,0 ; // Set in Open and Close functions
    mov    ofn.nFileOffset,0 ;
    mov    ofn.nFileExtension,0 ;
    mov    ofn.lpstrDefExt,CTEXT ("txt")
    mov    ofn.lCustData,0
    mov    ofn.lpfnHook,NULL
    mov    ofn.lpTemplateName,NULL
    ret
PopFileInitialize    endp

PopFileOpenDlg     proc    hwnd:HWND,pstrFileName:PTSTR , pstrTitleName:PTSTR
    mov    eax,hwnd
    mov    ofn.hwndOwner,eax
    mov    eax,pstrFileName
mov    ofn.lpstrFile,eax
mov    eax,pstrTitleName
mov    ofn.lpstrFileTitle,eax
mov    ofn.Flags,OFN_HIDEREADONLY or OFN_CREATEPROMPT
invoke    GetOpenFileName,addr ofn
    ret   
PopFileOpenDlg    endp

PopFileRead    proc    hwndEdit:HWND,pstrFileName:PTSTR

LOCAL    bySwap:BYTE
LOCAL    dwBytesRead:DWORD
LOCAL    hFile:HANDLE
LOCAL    i, iFileLength, iUniTest:DWORD
LOCAL    pBuffer, pText, pConv:PBYTE


; Open the file.
invoke    CreateFile,pstrFileName, GENERIC_READ, FILE_SHARE_READ,NULL, OPEN_EXISTING, 0, NULL
mov    hFile,eax
.if     (eax==INVALID_HANDLE_VALUE)
        mov    eax,FALSE
        ret
.endif
    ; Get file size in bytes and allocate memory for read.
    ; Add an extra two bytes for zero termination.
invoke    GetFileSize,hFile, NULL
mov    iFileLength,eax
add    eax,2
    invoke    LocalAlloc,LMEM_FIXED or LMEM_ZEROINIT,eax
    mov    pBuffer,eax

    ; Read file and put terminating zeros at end.

invoke ReadFile,hFile, pBuffer, iFileLength,addr dwBytesRead, NULL
invoke    CloseHandle,hFile


mov    ebx,iFileLength
mov    esi,pBuffer
add    esi,ebx
xor    ax,ax
mov    [esi],ax
;invoke MessageBox,hwndEdit, CTEXT ("33333333333"),NULL, MB_OK

; Test to see if the text is Unicode
mov    iUniTest,IS_TEXT_UNICODE_SIGNATURE or IS_TEXT_UNICODE_REVERSE_SIGNATURE
invoke    IsTextUnicode,pBuffer,iFileLength,addr iUniTest
    .if     (eax!=FALSE)
invoke MessageBox,hwndEdit, CTEXT ("1111111111"),NULL, MB_OK     
        mov    eax,pBuffer
        add    eax,2
mov    pText,eax
       
        sub    iFileLength,2
        mov    eax,iUniTest
        and     eax,IS_TEXT_UNICODE_REVERSE_SIGNATURE
    .if     eax!=FALSE

mov    i,0
nexti:
    mov    esi,pText
    mov    ebx,i
    shl    ebx,1
    add    esi,ebx
    mov    al,[esi]
    mov    bySwap,al
    mov    eax,[esi+1]
    mov    [esi],eax
    mov    al,bySwap
    mov    [esi+1],al
   
mov    eax,iFileLength
shr    eax,1
.if    (eax>i)
    jmp    nexti
.endif

        .endif


;Allocate memory for possibly converted string
    invoke    LocalAlloc,LMEM_FIXED or LMEM_ZEROINIT,iFileLength + 2
        mov    pConv,eax

; If the edit control is not Unicode, convert Unicode text to
    ; non-Unicode (i.e., in general, wide character).

;#ifndef UNICODE
; WideCharToMultiByte (CP_ACP, 0, (PWSTR) pText, -1, pConv,
; iFileLength + 2, NULL, NULL) ;
; // If the edit control is Unicode, just copy the string
;#else
; lstrcpy ((PTSTR) pConv, (PTSTR) pText) ;
;#endif
       

.else ; the file is not Unicode
invoke MessageBox,hwndEdit, CTEXT ("2222222222"),NULL, MB_OK
    mov    eax,pBuffer
    mov pText,eax

; Allocate memory for possibly converted string.
mov    eax,iFileLength
shl    eax,1
add    eax,2
invoke    LocalAlloc,LMEM_FIXED or LMEM_ZEROINIT,eax
mov    pConv,eax

; If the edit control is Unicode, convert ASCII text.

    mov    eax,iFileLength
    inc    eax
    shl    eax,1
invoke MultiByteToWideChar,CP_ACP, 0,pText, -1,pConv, eax
       
;#ifdef UNICODE
; MultiByteToWideChar (CP_ACP, 0, pText, -1, (PTSTR) pConv,
; iFileLength + 1) ;
; // If not, just copy buffer
;#else
; lstrcpy ((PTSTR) pConv, (PTSTR) pText) ;
;#endif

.endif



invoke    SetWindowTextW,hwndEdit,pConv
invoke    LocalFree,pBuffer
invoke    LocalFree,pConv
mov    eax,TRUE
ret

PopFileRead    endp


PopFileSaveDlg     proc    hwnd:HWND, pstrFileName:PTSTR, pstrTitleName:PTSTR
    mov    eax,hwnd
    mov    ofn.hwndOwner,eax
    mov    eax,pstrFileName
mov    ofn.lpstrFile,eax
mov    eax,pstrTitleName
mov    ofn.lpstrFileTitle,eax
mov    ofn.Flags,OFN_OVERWRITEPROMPT ;
invoke    GetSaveFileName,addr ofn
ret
PopFileSaveDlg    endp

PopFileWrite    proc    hwndEdit:HWND, pstrFileName:PTSTR
LOCAL    dwBytesWritten:DWORD
LOCAL    hFile:HANDLE
LOCAL    iLength:DWORD
LOCAL    pstrBuffer:PTSTR
wByteOrderMark    =    0FEFFh

invoke    CreateFile,pstrFileName, GENERIC_WRITE, 0,NULL, CREATE_ALWAYS, 0, NULL
mov    hFile,eax
    ;Open the file, creating it if necessary
.if     (eax==INVALID_HANDLE_VALUE)
    mov    eax,FALSE
        ret
    .endif       
    ;Get the number of characters in the edit control and allocate
    ;memory for them.
    invoke    GetWindowTextLength,hwndEdit
    mov    iLength,eax
    inc    eax
    mov    ecx,sizeof (TCHAR)
    mul    ecx
    invoke    LocalAlloc,LMEM_FIXED or LMEM_ZEROINIT,eax
    mov    pstrBuffer,eax
    .if    (eax==FALSE)
invoke    CloseHandle,hFile
mov    eax,FALSE
ret
.endif
;If the edit control will return Unicode text, write the
        ;byte order mark to the file.
;#ifdef UNICODE
; WriteFile (hFile, &wByteOrderMark, 2, &dwBytesWritten, NULL) ;
;#endif
;Get the edit buffer and write that out to the file.
invoke    GetWindowText,hwndEdit, pstrBuffer, iLength + 1
mov    iLength,eax
    mov    ecx,sizeof (TCHAR)
    mul    ecx    
    mov    ecx,eax
    push    ecx
invoke    WriteFile,hFile, pstrBuffer, ecx,addr dwBytesWritten, NULL
pop    ecx
   
.if (ecx!= dwBytesWritten)
invoke    CloseHandle,hFile
    invoke    LocalFree,pstrBuffer    
        mov    eax,FALSE
ret
    .endif
invoke    CloseHandle,hFile
invoke    LocalFree,pstrBuffer
    mov    eax,TRUE
ret
PopFileWrite    endp


end

        

POPFONT.ASM

.386
.Model Flat, StdCall
Option Casemap :None
include windows.inc
include comdlg32.inc
include gdi32.inc
include user32.inc
includelib comdlg32.lib
.data?
logfont LOGFONT    <?>
hFont     HFONT    ?
.code


PopFontChooseFont    proc    hwnd:HWND
    LOCAL    cf:CHOOSEFONTA

    mov    cf.lStructSize,sizeof (CHOOSEFONT)
    mov    eax,hwnd
mov    cf.hwndOwner,eax
mov    cf.hDC,NULL
mov    eax,offset logfont
mov    cf.lpLogFont,eax
mov    cf.iPointSize,0 ;
mov    cf.Flags,CF_INITTOLOGFONTSTRUCT or CF_SCREENFONTS or CF_EFFECTS ;
mov    cf.rgbColors,0 ;
mov    cf.lCustData,0 ;
mov    cf.lpfnHook,NULL ;
mov    cf.lpTemplateName,NULL ;
mov    cf.hInstance,NULL ;
mov    cf.lpszStyle,NULL ;
mov    cf.nFontType,0 ; // Returned from ChooseFont
mov    cf.nSizeMin,0 ;
mov    cf.nSizeMax,0 ;
invoke ChooseFont,addr cf
ret
PopFontChooseFont    endp


PopFontInitialize    proc    hwndEdit:HWND
    invoke    GetStockObject,SYSTEM_FONT
    mov    ebx,eax
invoke    GetObject,ebx, sizeof(LOGFONT),addr logfont
invoke    CreateFontIndirect,addr logfont
mov    hFont,eax
invoke    SendMessage,hwndEdit, WM_SETFONT, hFont, 0
ret
PopFontInitialize    endp

PopFontSetFont    proc    hwndEdit:HWND
    LOCAL    hFontNew:HFONT
LOCAL    rect:RECT

invoke    CreateFontIndirect,addr logfont
    mov    hFontNew,eax
invoke    SendMessage,hwndEdit, WM_SETFONT,hFontNew, 0
invoke    DeleteObject,hFont
mov    eax,hFontNew
mov hFont,eax
invoke    GetClientRect,hwndEdit,addr rect
invoke    InvalidateRect,hwndEdit,addr rect, TRUE
ret
PopFontSetFont    endp


PopFontDeinitialize    proc
    invoke    DeleteObject,hFont
ret
PopFontDeinitialize    endp

end

        

POPFIND.ASM

.386
.Model Flat, StdCall
Option Casemap :None
include windows.inc
include comdlg32.inc
include gdi32.inc
include user32.inc
include    kernel32.inc
include    shlwapi.inc
includelib comdlg32.lib
includelib shlwapi.lib

CTEXT macro Text
local szText
.data
szText byte Text, 0
.code
exitm <offset szText>
endm

MAX_STRING_LEN equ    256
.data?
szFindText TCHAR    MAX_STRING_LEN    dup(?)
szReplText TCHAR    MAX_STRING_LEN    dup(?)
frFindDlg FINDREPLACE <?> ; // must be static for modeless dialog!!!
frReplaceDlg FINDREPLACE <?> ; // must be static for modeless dialog!!!
.code
PopFindFindDlg    proc    hwnd:HWND
    mov    frFindDlg.lStructSize,sizeof (FINDREPLACE)
    mov    eax,hwnd
    mov    frFindDlg.hwndOwner,eax
mov    frFindDlg.hInstance,NULL
mov    frFindDlg.Flags,FR_HIDEUPDOWN or FR_HIDEMATCHCASE or FR_HIDEWHOLEWORD
mov    eax,offset    szFindText
mov    frFindDlg.lpstrFindWhat,eax
mov    frFindDlg.lpstrReplaceWith,NULL
mov    frFindDlg.wFindWhatLen,MAX_STRING_LEN
mov    frFindDlg.wReplaceWithLen,0
mov    frFindDlg.lCustData,0
    mov    frFindDlg.lpfnHook,NULL
mov    frFindDlg.lpTemplateName,NULL
invoke    FindText,addr frFindDlg
    ret
PopFindFindDlg    endp


PopFindReplaceDlg    proc    hwnd:HWND
    mov    frReplaceDlg.lStructSize,sizeof (FINDREPLACE)
    mov    eax,hwnd
mov    frReplaceDlg.hwndOwner,eax
mov    frReplaceDlg.hInstance,NULL ;
mov    frReplaceDlg.Flags,FR_HIDEUPDOWN or FR_HIDEMATCHCASE or FR_HIDEWHOLEWORD
mov    eax,offset    szFindText
mov    frReplaceDlg.lpstrFindWhat,eax
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


 

wpe2.jpg (12048 字节)


 

wpe3.jpg (6533 字节)

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所示的普通对话框。


 

wpe4.jpg (41597 字节)

图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
下一篇>>>