📄 wordpad.asm
字号:
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Sample code for < Win32ASM Programming >
; by 罗云彬, http://asm.yeah.net
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Wordpad.asm
; 文本编辑器例子 —— 综合使用Richedit、工具栏、状态栏控件
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 使用 nmake 或下列命令进行编译和链接:
; ml /c /coff Wordpad.asm
; rc Wordpad.rc
; Link /subsystem:windows Wordpad.obj Wordpad.res
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386
.model flat, stdcall
option casemap :none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
include comctl32.inc
includelib comctl32.lib
include comdlg32.inc
includelib comdlg32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Equ 等值定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ICO_MAIN equ 1000
IDA_MAIN equ 2000
IDM_MAIN equ 2000
IDM_NEW equ 2101
IDM_OPEN equ 2102
IDM_SAVE equ 2103
IDM_SAVEAS equ 2104
IDM_PAGESETUP equ 2105
IDM_EXIT equ 2106
IDM_UNDO equ 2201
IDM_REDO equ 2202
IDM_SELALL equ 2203
IDM_COPY equ 2204
IDM_CUT equ 2205
IDM_PASTE equ 2206
IDM_FIND equ 2207
IDM_FINDPREV equ 2208
IDM_FINDNEXT equ 2209
IDM_FONT equ 2301
IDM_BKCOLOR equ 2302
IDM_TOOLBAR equ 2303
IDM_STATUSBAR equ 2304
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
hInstance dd ?
hWinMain dd ?
hMenu dd ?
hWinStatus dd ?
hWinToolbar dd ?
hWinEdit dd ?
hFile dd ?
hFindDialog dd ?
dwFontColor dd ?
dwBackColor dd ?
idFindMessage dd ?
dwCustColors dd 16 dup (?)
szFileName db MAX_PATH dup (?)
szFindText db 100 dup (?)
stLogFont LOGFONT <?>
stFind FINDREPLACE <?>
dwOption dd ?
F_STATUSBAR equ 00000001h
F_TOOLBAR equ 00000002h
.const
FINDMSGSTRING db 'commdlg_FindReplace',0
szClassName db 'Wordpad',0
szCaptionMain db '记事本',0
szDllEdit db 'RichEd20.dll',0
szClassEdit db 'RichEdit20A',0
dwStatusWidth dd 50,100,200,300,350,-1
szFontFace db '宋体',0
szCharsFormat db '总长度:%d',0
szLinesFormat db '总行数:%d',0
szLineFormat db '行:%d',0
szColFormat db '列:%d',0
szTitleFormat db '记事本 - [%s]',0
szNotFound db '字符串未找到!',0
szNoName db '未命名的文件',0
szFilter db 'Text Files(*.txt)',0,'*.txt',0,'All Files(*.*)',0,'*.*',0,0
szDefExt db 'txt',0
szErrOpenFile db '无法打开文件!',0
szErrCreateFile db '无法建立文件!',0
szModify db '文件已修改,是否保存?',0
szHasModify db '已修改',0
szNotModify db '未修改',0
szCaption db '提问',0
szSaveCaption db '请输入保存的文件名',0
stToolbar equ this byte
TBBUTTON <STD_FILENEW,IDM_NEW,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,-1>
TBBUTTON <STD_FILEOPEN,IDM_OPEN,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,-1>
TBBUTTON <STD_FILESAVE,IDM_SAVE,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,-1>
TBBUTTON <0,0,TBSTATE_ENABLED,TBSTYLE_SEP,0,0,-1>
TBBUTTON <STD_COPY,IDM_COPY,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,-1>
TBBUTTON <STD_CUT,IDM_CUT,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,-1>
TBBUTTON <STD_PASTE,IDM_PASTE,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,-1>
TBBUTTON <0,0,TBSTATE_ENABLED,TBSTYLE_SEP,0,0,-1>
TBBUTTON <STD_UNDO,IDM_UNDO,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,-1>
TBBUTTON <STD_REDOW,IDM_REDO,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,-1>
TBBUTTON <0,0,TBSTATE_ENABLED,TBSTYLE_SEP,0,0,-1>
TBBUTTON <STD_FIND,IDM_FIND,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,-1>
TBBUTTON <0,0,TBSTATE_ENABLED,TBSTYLE_SEP,0,0,-1>
NUM_BUTTONS EQU 13
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 允许继续操作则返回TRUE
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_CheckModify proc
invoke SendMessage,hWinEdit,EM_GETMODIFY,0,0
.if eax
invoke MessageBox,hWinMain,addr szModify,addr szCaption,\
MB_YESNOCANCEL or MB_ICONQUESTION
.if eax == IDYES
call _SaveFile
.elseif eax == IDNO
mov eax,TRUE
.elseif eax == IDCANCEL
xor eax,eax
.endif
.else
mov eax,TRUE
.endif
ret
_CheckModify endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Richedit的流操作
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcStream proc uses ebx edi esi _dwCookie,_lpBuffer,_dwBytes,_lpBytes
.if _dwCookie
invoke ReadFile,hFile,_lpBuffer,_dwBytes,_lpBytes,0
.else
invoke WriteFile,hFile,_lpBuffer,_dwBytes,_lpBytes,0
.endif
xor eax,eax
ret
_ProcStream endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 设置字体及字体颜色
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_SetFont proc _lpszFont,_dwFontSize,_dwColor
local @stCf:CHARFORMAT
invoke RtlZeroMemory,addr @stCf,sizeof @stCf
mov @stCf.cbSize,sizeof @stCf
mov @stCf.dwMask,CFM_SIZE or CFM_FACE or CFM_BOLD or CFM_COLOR
push _dwFontSize
pop @stCf.yHeight
push _dwColor
pop @stCf.crTextColor
mov @stCf.dwEffects,0
invoke lstrcpy,addr @stCf.szFaceName,_lpszFont
invoke SendMessage,hWinEdit,EM_SETTEXTMODE,1,0
invoke SendMessage,hWinEdit,EM_SETCHARFORMAT,SCF_ALL,addr @stCf
ret
_SetFont endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 查找文字
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_FindText proc
local @stFindText:FINDTEXTEX
;********************************************************************
; 设置查找范围
;********************************************************************
invoke SendMessage,hWinEdit,EM_EXGETSEL,0,addr @stFindText.chrg
.if stFind.Flags & FR_DOWN
push @stFindText.chrg.cpMax
pop @stFindText.chrg.cpMin
.endif
mov @stFindText.chrg.cpMax,-1
;********************************************************************
; 设置查找选项
;********************************************************************
mov @stFindText.lpstrText,offset szFindText
mov ecx,stFind.Flags
and ecx,FR_MATCHCASE or FR_DOWN or FR_WHOLEWORD
;********************************************************************
; 查找并把光标设置到找到的文本上
;********************************************************************
invoke SendMessage,hWinEdit,EM_FINDTEXTEX,ecx,addr @stFindText
.if eax == -1
mov ecx,hWinMain
.if hFindDialog
mov ecx,hFindDialog
.endif
invoke MessageBox,ecx,addr szNotFound,NULL,MB_OK or MB_ICONINFORMATION
ret
.endif
invoke SendMessage,hWinEdit,EM_EXSETSEL,0,addr @stFindText.chrgText
invoke SendMessage,hWinEdit,EM_SCROLLCARET,NULL,NULL
ret
_FindText endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 页面设置对话框
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_PageSetup proc
local @stPS:PAGESETUPDLG
invoke RtlZeroMemory,addr @stPS,sizeof @stPS
mov @stPS.lStructSize,sizeof @stPS
mov @stPS.Flags,PSD_DISABLEMARGINS or PSD_DISABLEORIENTATION or PSD_DISABLEPAGEPAINTING
push hWinMain
pop @stPS.hwndOwner
invoke PageSetupDlg,addr @stPS
ret
_PageSetup endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 保存文件,如果没有打开或创建文件则调用“另存为”子程序
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_SaveFile proc
local @stES:EDITSTREAM
.if ! hFile
call _SaveAs
.if ! eax
ret
.endif
.endif
mov @stES.dwCookie,FALSE
mov @stES.dwError,NULL
mov @stES.pfnCallback,offset _ProcStream
invoke SendMessage,hWinEdit,EM_STREAMOUT,SF_TEXT,addr @stES
invoke SendMessage,hWinEdit,EM_SETMODIFY,FALSE,0
mov eax,TRUE
ret
_SaveFile endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 另存为
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_SaveAs proc
local @stOF:OPENFILENAME
local @stES:EDITSTREAM
invoke RtlZeroMemory,addr @stOF,sizeof @stOF
;********************************************************************
; 显示“保存文件”对话框
;********************************************************************
mov @stOF.lStructSize,sizeof @stOF
push hWinMain
pop @stOF.hwndOwner
mov @stOF.lpstrFilter,offset szFilter
mov @stOF.lpstrFile,offset szFileName
mov @stOF.nMaxFile,MAX_PATH
mov @stOF.Flags,OFN_PATHMUSTEXIST
mov @stOF.lpstrDefExt,offset szDefExt
mov @stOF.lpstrTitle,offset szSaveCaption
invoke GetSaveFileName,addr @stOF
.if eax
;********************************************************************
; 创建新文件
;********************************************************************
invoke CreateFile,addr szFileName,GENERIC_READ or GENERIC_WRITE,\
FILE_SHARE_READ,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0
.if eax != INVALID_HANDLE_VALUE
push eax
.if hFile
invoke CloseHandle,hFile
.endif
pop eax
;********************************************************************
; 保存文件
;********************************************************************
mov hFile,eax
call _SaveFile
call _SetCaption
call _SetStatus
mov eax,TRUE
ret
.else
invoke MessageBox,hWinMain,addr szErrCreateFile,NULL,MB_OK or MB_ICONERROR
.endif
.endif
mov eax,FALSE
ret
_SaveAs endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 打开及输入文件
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_OpenFile proc
local @stOF:OPENFILENAME
local @stES:EDITSTREAM
;********************************************************************
; 显示“打开文件”对话框
;********************************************************************
invoke RtlZeroMemory,addr @stOF,sizeof @stOF
mov @stOF.lStructSize,sizeof @stOF
push hWinMain
pop @stOF.hwndOwner
mov @stOF.lpstrFilter,offset szFilter
mov @stOF.lpstrFile,offset szFileName
mov @stOF.nMaxFile,MAX_PATH
mov @stOF.Flags,OFN_FILEMUSTEXIST or OFN_PATHMUSTEXIST
invoke GetOpenFileName,addr @stOF
.if eax
;********************************************************************
; 创建文件
;********************************************************************
invoke CreateFile,addr szFileName,GENERIC_READ or GENERIC_WRITE,\
FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0
.if eax == INVALID_HANDLE_VALUE
invoke MessageBox,hWinMain,addr szErrOpenFile,NULL,MB_OK or MB_ICONSTOP
ret
.endif
push eax
.if hFile
invoke CloseHandle,hFile
.endif
pop eax
mov hFile,eax
;********************************************************************
; 读入文件
;********************************************************************
mov @stES.dwCookie,TRUE
mov @stES.dwError,NULL
mov @stES.pfnCallback,offset _ProcStream
invoke SendMessage,hWinEdit,EM_STREAMIN,SF_TEXT,addr @stES
invoke SendMessage,hWinEdit,EM_SETMODIFY,FALSE,0
call _SetCaption
call _SetStatus
.endif
ret
_OpenFile endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 选择背景色
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ChooseColor proc
local @stCC:CHOOSECOLOR
invoke RtlZeroMemory,addr @stCC,sizeof @stCC
mov @stCC.lStructSize,sizeof @stCC
push hWinMain
pop @stCC.hwndOwner
push dwBackColor
pop @stCC.rgbResult
mov @stCC.Flags,CC_RGBINIT or CC_FULLOPEN
mov @stCC.lpCustColors,offset dwCustColors
invoke ChooseColor,addr @stCC
.if eax
push @stCC.rgbResult
pop dwBackColor
invoke SendMessage,hWinEdit,EM_SETBKGNDCOLOR,0,dwBackColor
.endif
ret
_ChooseColor endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 选择字体
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ChooseFont proc
local @stCF:CHOOSEFONT
invoke RtlZeroMemory,addr @stCF,sizeof @stCF
mov @stCF.lStructSize,sizeof @stCF
push hWinMain
pop @stCF.hwndOwner
mov @stCF.lpLogFont,offset stLogFont
push dwFontColor
pop @stCF.rgbColors
mov @stCF.Flags,CF_SCREENFONTS or CF_INITTOLOGFONTSTRUCT or CF_EFFECTS
invoke ChooseFont,addr @stCF
.if eax
push @stCF.rgbColors
pop dwFontColor
mov eax,@stCF.iPointSize
shl eax,1
invoke _SetFont,addr stLogFont.lfFaceName,eax,@stCF.rgbColors
.endif
ret
_ChooseFont endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_SetCaption proc
local @szBuffer[1024]:byte
.if szFileName
mov eax,offset szFileName
.else
mov eax,offset szNoName
.endif
invoke wsprintf,addr @szBuffer,addr szTitleFormat,eax
invoke SetWindowText,hWinMain,addr @szBuffer
ret
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -