当前位置: 源码素材网 » VC++教程 » 详情页

汇编语言模拟Windows记事本,包括工具栏和颜色及所有功能

  •   时间:2020-02-07
  • 概述:汇编语言 记事本

一个值得看的代码,采用汇编语言模拟Windows记事本,包括工具栏和颜色及所有功能,核心代码如下:

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 模拟XP自带记事本,未实现打印功能,拖放文件功能
; richEdit控件未实现右键菜单 Download by http://www.srcfans.com
; 基本实现所有功能,添加了工具栏和状态栏,增加颜色功能
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 学习罗云彬《windows环境下32位汇编语言程序设计》一个月记
; By 白吃 QQ:898599527 09-08-11
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 使用 nmake 或下列命令进行编译和链接:
; ml /c /coff Menu.asm
; rc Menu.rc
; Link /subsystem:windows Menu.obj Menu.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 comdlg32.inc
includelib comdlg32.lib
include Comctl32.inc
includelib Comctl32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Equ 等值定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
DEBUG equ 0 ;用于测试
IDR_MENU equ 104 ;菜单
IDA_MENU equ 104 ;加速键
DLG_ABOUT equ 105 ;对话框
DLG_GOTOLINE equ 106
ICO_MAIN equ 10000 ;图标
IDC_LINE equ 1014
IDM_REDO equ 40001
IDM_NEW equ 40002
IDM_OPEN equ 40003
IDM_SAVE equ 40005
IDM_SAVEAS equ 40006
IDM_PAGESETUP equ 40007
IDM_PRINT equ 40008
IDM_EXIT equ 40009
IDM_UNDO equ 40010
IDM_CUT equ 40011
IDM_PASTE equ 40012
IDM_COPY equ 40013
IDM_DELETE equ 40014
IDM_FIND equ 40015
IDM_FINDNEXT equ 40016
IDM_REPLACE equ 40017
IDM_GOTO equ 40018
IDM_SELECTALL equ 40019
IDM_DATETIME equ 40020
IDM_LINEWRAP equ 40021
IDM_FONT equ 40022
IDM_STATUSBAR equ 40023
IDM_HELP equ 40024
IDM_ABOUT equ 40025
IDM_SELCOLOR equ 40026
IDM_TOOLBAR equ 40027
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
hInstance dd ?
hWinMain dd ?
hMenu dd ?
hSubMenu dd ?
hIcon dd ?
hWinToolbar dd ?
hWinStatus dd ?
hWinEdit dd ?
hFile dd ?
hFindDialog dd ?
hReplaceDialog dd ?
dwFontColor dd ?
dwBackColor dd ?
dwFontEffect dd ?
dwOption dd ?
dwBoolean dd ?
dwCustColors dd 16 dup (?)
stLogFont LOGFONT <?>
F_STATUSBAR equ 00000001h ;用于显示和隐藏状态栏
F_TOOLBAR equ 00000002h

szFileName db MAX_PATH dup (?)

szBuffer db 1024 dup (?)
;********************************************************************
; 查找替换对话框使用
;********************************************************************
idFindMessage dd ?
szFindText db 100 dup (?)
szReplaceText db 100 dup (?)

.data
stFind FINDREPLACE <sizeof FINDREPLACE,0,0,FR_DOWN,szFindText,\
0,sizeof szFindText,0,0,0,0>

.const
FINDMSGSTRING db 'commdlg_FindReplace',0
szSaveCaption db '请输入文件名',0
szClassName db 'Notepad',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
szOverLine 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
szFormat db '您选择了菜单命令:%08x',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_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_PRINTPRE,IDM_PAGESETUP,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,-1>
TBBUTTON <STD_PRINT,IDM_PRINT,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_FIND,IDM_FIND,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,-1>
TBBUTTON <STD_REPLACE,IDM_REPLACE,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,-1>
TBBUTTON <0,0,TBSTATE_ENABLED,TBSTYLE_SEP,0,0,-1>
TBBUTTON <STD_HELP,IDM_HELP,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,-1>
TBBUTTON <0,0,TBSTATE_ENABLED,TBSTYLE_SEP,0,0,-1>
NUM_BUTTONS EQU 16

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 自动换行
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_LINEWRAP proc _dwCommandID,_hWinEdit
pushad
mov ebx,_dwCommandID
invoke GetMenuState,hMenu,ebx,MF_BYCOMMAND
.if eax == MF_CHECKED
mov eax,MF_UNCHECKED
invoke CheckMenuItem,hMenu,ebx,eax
invoke GetDC,_hWinEdit
invoke SendMessage,_hWinEdit,EM_SETTARGETDEVICE,0,1
invoke ReleaseDC,_hWinEdit,eax
.else
mov eax,MF_CHECKED
invoke CheckMenuItem,hMenu,ebx,eax
invoke GetDC,_hWinEdit
invoke SendMessage,_hWinEdit,EM_SETTARGETDEVICE,eax,0
invoke ReleaseDC,_hWinEdit,eax
.endif
popad
ret
_LINEWRAP 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
_SetCaption endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 设置字体及字体颜色
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_SetFont proc _lpszFont,_dwFontSize,_dwColor,_dwFontEffect
local @stCf:CHARFORMAT2

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 or CFM_ITALIC or CFM_UNDERLINE or CFM_STRIKEOUT
push _dwFontSize
pop @stCf.yHeight
push _dwColor
pop @stCf.crTextColor
push _dwFontEffect
pop @stCf.dwEffects
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
.elseif hReplaceDialog
mov ecx,hReplaceDialog
.endif
mov eax,0
mov dwBoolean,eax
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
mov eax,1
mov dwBoolean,eax
ret

_FindText endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 替换文本
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ReplaceText proc
local @stFindText:FINDTEXTEX

.if dwBoolean != 1
invoke _FindText
.endif
.if dwBoolean
mov @stFindText.lpstrText,offset szReplaceText
invoke SendMessage,hWinEdit,EM_REPLACESEL,TRUE,addr szReplaceText
call _FindText
.endif
ret
_ReplaceText endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 替换全部
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ReplaceAll proc
local @stFindText:FINDTEXTEX

;********************************************************************
; 设置替换范围
;********************************************************************
mov @stFindText.chrg.cpMax,-1
mov @stFindText.chrg.cpMin,0
;********************************************************************
mov @stFindText.lpstrText,offset szReplaceText
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
.elseif hReplaceDialog
mov ecx,hReplaceDialog
.endif
invoke MessageBox,ecx,addr szNotFound,NULL,MB_OK or MB_ICONINFORMATION
mov eax,0
mov dwBoolean,eax
ret
.endif
.repeat
invoke SendMessage,hWinEdit,EM_EXSETSEL,0,addr @stFindText.chrgText
invoke SendMessage,hWinEdit,EM_REPLACESEL,TRUE,addr szReplaceText
invoke SendMessage,hWinEdit,EM_FINDTEXTEX,ecx,addr @stFindText
.break .if eax == -1
.until eax == -1
ret
_ReplaceAll endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 设置菜单项、工具栏、状态栏的状态和信息
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_SetStatus proc
local @stRange:CHARRANGE
local @dwLines,@dwLine,@dwLineStart
local @szBuffer[256]:byte

;********************************************************************
; 在状态栏显示行、列信息
;********************************************************************
invoke GetWindowTextLength,hWinEdit
invoke wsprintf,addr @szBuffer,addr szCharsFormat,eax
invoke SendMessage,hWinStatus,SB_SETTEXT,3,addr @szBuffer
invoke SendMessage,hWinEdit,EM_GETLINECOUNT,0,0
invoke wsprintf,addr @szBuffer,addr szLinesFormat,eax
invoke SendMessage,hWinStatus,SB_SETTEXT,2,addr @szBuffer
invoke SendMessage,hWinEdit,EM_EXGETSEL,0,addr @stRange
invoke SendMessage,hWinEdit,EM_EXLINEFROMCHAR,0,-1
mov @dwLine,eax
invoke SendMessage,hWinEdit,EM_LINEINDEX,eax,0
mov ecx,@stRange.cpMin
sub ecx,eax
inc ecx
invoke wsprintf,addr @szBuffer,addr szColFormat,ecx
invoke SendMessage,hWinStatus,SB_SETTEXT,1,addr @szBuffer
inc @dwLine
invoke wsprintf,addr @szBuffer,addr szLineFormat,@dwLine
invoke SendMessage,hWinStatus,SB_SETTEXT,0,addr @szBuffer
;********************************************************************
; 根据选择情况改变菜单项、工具栏按钮状态
;********************************************************************
mov eax,@stRange.cpMin
.if eax == @stRange.cpMax
invoke EnableMenuItem,hMenu,IDM_COPY,MF_GRAYED
invoke EnableMenuItem,hMenu,IDM_CUT,MF_GRAYED
invoke EnableMenuItem,hMenu,IDM_DELETE,MF_GRAYED
invoke SendMessage,hWinToolbar,TB_ENABLEBUTTON,IDM_COPY,FALSE
invoke SendMessage,hWinToolbar,TB_ENABLEBUTTON,IDM_CUT,FALSE
invoke SendMessage,hWinToolbar,TB_ENABLEBUTTON,IDM_DELETE,FALSE
.else
invoke EnableMenuItem,hMenu,IDM_COPY,MF_ENABLED
invoke EnableMenuItem,hMenu,IDM_CUT,MF_ENABLED
invoke EnableMenuItem,hMenu,IDM_DELETE,MF_ENABLED
invoke SendMessage,hWinToolbar,TB_ENABLEBUTTON,IDM_COPY,TRUE
invoke SendMessage,hWinToolbar,TB_ENABLEBUTTON,IDM_CUT,TRUE
invoke SendMessage,hWinToolbar,TB_ENABLEBUTTON,IDM_DELETE,TRUE
.endif
;********************************************************************
invoke IsClipboardFormatAvailable,CF_TEXT
.if eax
invoke EnableMenuItem,hMenu,IDM_PASTE,MF_ENABLED
invoke SendMessage,hWinToolbar,TB_ENABLEBUTTON,IDM_PASTE,TRUE
.else
invoke EnableMenuItem,hMenu,IDM_PASTE,MF_GRAYED
invoke SendMessage,hWinToolbar,TB_ENABLEBUTTON,IDM_PASTE,FALSE
.endif
;********************************************************************
invoke SendMessage,hWinEdit,EM_CANREDO,0,0
.if eax
invoke EnableMenuItem,hMenu,IDM_REDO,MF_ENABLED
invoke SendMessage,hWinToolbar,TB_ENABLEBUTTON,IDM_REDO,TRUE
.else
invoke EnableMenuItem,hMenu,IDM_REDO,MF_GRAYED
invoke SendMessage,hWinToolbar,TB_ENABLEBUTTON,IDM_REDO,FALSE
.endif
;********************************************************************
invoke SendMessage,hWinEdit,EM_CANUNDO,0,0
.if eax
invoke EnableMenuItem,hMenu,IDM_UNDO,MF_ENABLED
invoke SendMessage,hWinToolbar,TB_ENABLEBUTTON,IDM_UNDO,TRUE
.else
invoke EnableMenuItem,hMenu,IDM_UNDO,MF_GRAYED
invoke SendMessage,hWinToolbar,TB_ENABLEBUTTON,IDM_UNDO,FALSE
.endif
;********************************************************************
invoke GetWindowTextLength,hWinEdit
.if eax
invoke EnableMenuItem,hMenu,IDM_SELECTALL,MF_ENABLED
.else
invoke EnableMenuItem,hMenu,IDM_SELECTALL,MF_GRAYED
.endif
;********************************************************************
invoke SendMessage,hWinEdit,EM_GETMODIFY,0,0
.if eax
invoke EnableMenuItem,hMenu,IDM_SAVE,MF_ENABLED
invoke SendMessage,hWinToolbar,TB_ENABLEBUTTON,IDM_SAVE,TRUE
invoke SendMessage,hWinStatus,SB_SETTEXT,4,addr szHasModify
.else
invoke EnableMenuItem,hMenu,IDM_SAVE,MF_GRAYED
invoke SendMessage,hWinToolbar,TB_ENABLEBUTTON,IDM_SAVE,FALSE
invoke SendMessage,hWinStatus,SB_SETTEXT,4,addr szNotModify
.endif
;********************************************************************
.if szFindText
invoke EnableMenuItem,hMenu,IDM_FINDNEXT,MF_ENABLED
invoke SendMessage,hWinToolbar,TB_ENABLEBUTTON,IDM_FINDNEXT,TRUE
.else
invoke EnableMenuItem,hMenu,IDM_FINDNEXT,MF_GRAYED
invoke SendMessage,hWinToolbar,TB_ENABLEBUTTON,IDM_FINDNEXT,FALSE
.endif
;********************************************************************
.if dwOption & F_STATUSBAR
invoke CheckMenuItem,hMenu,IDM_STATUSBAR,MF_CHECKED
.else
invoke CheckMenuItem,hMenu,IDM_STATUSBAR,MF_UNCHECKED
.endif
;********************************************************************
.if dwOption & F_TOOLBAR
invoke CheckMenuItem,hMenu,IDM_TOOLBAR,MF_CHECKED
.else
invoke CheckMenuItem,hMenu,IDM_TOOLBAR,MF_UNCHECKED
.endif
ret

_SetStatus endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 重新排列窗口位置
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ResizeWindow proc
local @stRect:RECT
local @stRectTemp:RECT
local @dwWidth,@dwHeight

invoke GetClientRect,hWinMain,addr @stRect
mov eax,@stRect.right
sub eax,@stRect.left
mov @dwWidth,eax
mov eax,@stRect.bottom
sub eax,@stRect.top
mov @dwHeight,eax
;********************************************************************
; 计算及调整状态栏
;********************************************************************
.if dwOption & F_STATUSBAR
invoke ShowWindow,hWinStatus,SW_SHOW
invoke MoveWindow,hWinStatus,0,0,0,0,TRUE
invoke GetWindowRect,hWinStatus,addr @stRectTemp
mov eax,@stRectTemp.bottom
sub eax,@stRectTemp.top
sub @dwHeight,eax
.else
invoke ShowWindow,hWinStatus,SW_HIDE
.endif
;********************************************************************
; 计算及调整工具栏
;********************************************************************
.if dwOption & F_TOOLBAR
invoke ShowWindow,hWinToolbar,SW_SHOW
invoke GetWindowRect,hWinToolbar,addr @stRectTemp
mov eax,@stRectTemp.bottom
sub eax,@stRectTemp.top
push eax
invoke MoveWindow,hWinToolbar,0,0,@dwWidth,eax,TRUE
pop eax
sub @dwHeight,eax
mov @stRect.top,eax
.else
invoke ShowWindow,hWinToolbar,SW_HIDE
.endif
;********************************************************************
; 调整Richedit控件位置
;********************************************************************
invoke MoveWindow,hWinEdit,@stRect.left,@stRect.top,\
@dwWidth,@dwHeight,TRUE
ret

_ResizeWindow endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; ——————用于测试——————
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
if DEBUG
_DisplayMenuItem proc _dwCommandID
local @szBuffer[256]:byte

pushad
invoke wsprintf,addr @szBuffer,addr szFormat,_dwCommandID
invoke MessageBox,hWinMain,addr @szBuffer,offset szCaption,MB_OK
popad
ret

_DisplayMenuItem endp
endif
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_Quit proc

invoke DestroyWindow,hWinMain
invoke PostQuitMessage,NULL
ret

_Quit endp

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 初始化
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_Init proc
local @stCf:CHARFORMAT
pushad
;********************************************************************
; 注册“查找”对话框消息,初始化“查找”对话框的结构
;********************************************************************
push hWinMain
pop stFind.hwndOwner
mov stFind.lStructSize,sizeof stFind
mov stFind.Flags,FR_DOWN or FR_NOWHOLEWORD
mov stFind.lpstrFindWhat,offset szFindText
mov stFind.wFindWhatLen,sizeof szFindText
mov stFind.lpstrReplaceWith,offset szReplaceText
mov stFind.wReplaceWithLen,sizeof szReplaceText
invoke RegisterWindowMessage,addr FINDMSGSTRING
mov idFindMessage,eax
;********************************************************************
; 建立工具栏
;********************************************************************
invoke CreateToolbarEx,hWinMain,\
WS_VISIBLE or WS_CHILD or TBSTYLE_FLAT,\
1,0,HINST_COMMCTRL,IDB_STD_SMALL_COLOR,offset stToolbar,\
NUM_BUTTONS,0,0,0,0,sizeof TBBUTTON
mov hWinToolbar,eax
;********************************************************************
; 建立状态栏
;********************************************************************
invoke CreateStatusWindow,WS_CHILD OR WS_VISIBLE OR \
SBS_SIZEGRIP,NULL,hWinMain,2
mov hWinStatus,eax
invoke SendMessage,hWinStatus,SB_SETPARTS,6,offset dwStatusWidth
;********************************************************************
; 建立输出文本窗口
;********************************************************************
invoke CreateWindowEx,WS_EX_CLIENTEDGE,offset szClassEdit,NULL,\
WS_CHILD OR WS_VISIBLE OR WS_VSCROLL OR WS_HSCROLL \
OR ES_MULTILINE or ES_NOHIDESEL,\
0,0,0,0,\
hWinMain,0,hInstance,NULL
mov hWinEdit,eax
or dwOption,F_STATUSBAR or F_TOOLBAR
invoke _SetCaption
invoke _SetStatus
invoke _SetFont,addr szFontFace,10 * 20,0,0
invoke SendMessage,hWinEdit,EM_SETEVENTMASK,0,ENM_MOUSEEVENTS or ENM_CHANGE \
or ENM_KEYEVENTS or ENM_SCROLL or ENM_DROPFILES
invoke SendMessage,hWinEdit,EM_EXLIMITTEXT,0,-1
ret

_Init endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 页面设置对话框
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_PageSetup proc
local @stPS:PAGESETUPDLG

invoke RtlZeroMemory,addr @stPS,sizeof @stPS
mov @stPS.lStructSize,sizeof @stPS
push hWinMain
pop @stPS.hwndOwner
invoke PageSetupDlg,addr @stPS
;功能未实现
ret

_PageSetup 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
.endif
.endif
ret

_SaveAs endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 保存文件,如果没有打开或创建文件则调用“另存为”子程序
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_SaveFile proc
local @stES:EDITSTREAM

.if ! hFile
call _SaveAs
.if ! eax
ret
.endif
.endif
invoke SetFilePointer,hFile,0,0,FILE_BEGIN
invoke SetEndOfFile,hFile

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


;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 打开及输入文件
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_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
.if stLogFont.lfUnderline
or dwFontEffect,CFE_UNDERLINE
.endif
.if stLogFont.lfItalic
or dwFontEffect,CFE_ITALIC
.endif
.if stLogFont.lfStrikeOut
or dwFontEffect,CFE_STRIKEOUT
.endif
.if stLogFont.lfWeight == 700
or dwFontEffect,CFE_BOLD
.endif
push @stCF.rgbColors
pop dwFontColor
mov eax,@stCF.iPointSize
shl eax,1
invoke _SetFont,addr stLogFont.lfFaceName,eax,@stCF.rgbColors,dwFontEffect
.endif
ret

_ChooseFont endp

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 允许继续操作则返回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
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 转到对话框过程
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcDlgGotoLine proc uses ebx edi esi hWnd,wMsg,wParam,lParam
local @szBuffer[128]:dword
local @LinePos:CHARRANGE

mov eax,wMsg
.if eax == WM_CLOSE
invoke EndDialog,hWnd,NULL
.elseif eax == WM_COMMAND
mov eax,wParam
.if ax == IDC_LINE
.elseif ax == IDOK
invoke GetDlgItemInt,hWnd,IDC_LINE,NULL,FALSE
mov ebx,eax
invoke SendMessage,hWinEdit,EM_LINEINDEX,ebx,0
.if eax == -1
invoke MessageBox,hWinMain,addr szOverLine,addr szCaption,MB_OK
.else
mov @LinePos.cpMax,eax
sub ebx,1
invoke SendMessage,hWinEdit,EM_LINEINDEX,ebx,0
mov @LinePos.cpMin,eax
invoke SendMessage,hWinEdit,EM_EXSETSEL,0,addr @LinePos
invoke SendMessage,hWinEdit,EM_SCROLLCARET,NULL,NULL
.endif
invoke EndDialog,hWnd,NULL
.elseif ax == IDCANCEL
invoke EndDialog,hWnd,NULL
.endif
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
_ProcDlgGotoLine endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;对话框过程
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcDlgMain proc uses ebx edi esi hWnd,wMsg,wParam,lParam

mov eax,wMsg
.if eax == WM_CLOSE
invoke EndDialog,hWnd,NULL
.elseif eax == WM_INITDIALOG
invoke LoadIcon,hInstance,ICO_MAIN
invoke SendMessage,hWnd,WM_SETICON,ICON_BIG,eax
.elseif eax == WM_COMMAND
mov eax,wParam
.if ax == IDOK
invoke EndDialog,hWnd,NULL
.endif
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret

_ProcDlgMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 窗口过程
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcWinMain proc uses ebx edi esi hWnd,uMsg,wParam,lParam
local @stPos:POINT
local @hSysMenu
local @stRange:CHARRANGE

mov eax,hWnd
mov hWinMain,eax
mov eax,uMsg
.if eax == WM_SIZE
invoke _ResizeWindow

;********************************************************************
.elseif eax == WM_CREATE
invoke GetSubMenu,hMenu,1
mov hSubMenu,eax
push hWnd
pop hWinMain
invoke _Init
;********************************************************************
.elseif eax == WM_INITMENU
call _SetStatus
;********************************************************************
.elseif eax == WM_ACTIVATE
mov eax,wParam
.if (ax == WA_CLICKACTIVE ) || (ax == WA_ACTIVE)
invoke SetFocus,hWinEdit
.endif
;********************************************************************
; 处理菜单及加速键消息
;********************************************************************
.elseif eax == WM_COMMAND
mov eax,wParam
movzx eax,ax
.if eax == IDM_EXIT
invoke _CheckModify
.if eax
call _Quit
.endif
.elseif eax == IDM_LINEWRAP
invoke _LINEWRAP,eax,hWinEdit
.elseif eax == IDM_ABOUT
invoke DialogBoxParam,hInstance,DLG_ABOUT,NULL,offset _ProcDlgMain,NULL
.elseif eax == IDM_OPEN
invoke _CheckModify
.if eax
call _OpenFile
.endif
.elseif eax == IDM_NEW
invoke _CheckModify
.if eax
.if hFile
invoke CloseHandle,hFile
mov hFile,0
.endif
mov szFileName,0
invoke SetWindowText,hWinEdit,NULL
invoke _SetCaption
invoke _SetStatus
.endif
.elseif eax == IDM_UNDO
invoke SendMessage,hWinEdit,EM_UNDO,0,0
.elseif eax == IDM_REDO
invoke SendMessage,hWinEdit,EM_REDO,0,0
.elseif eax == IDM_COPY
invoke SendMessage,hWinEdit,WM_COPY,0,0
.elseif eax == IDM_CUT
invoke SendMessage,hWinEdit,WM_CUT,0,0
.elseif eax == IDM_PASTE
invoke SendMessage,hWinEdit,WM_PASTE,0,0
.elseif eax == IDM_GOTO
invoke DialogBoxParam,hInstance,DLG_GOTOLINE,hWinMain,offset _ProcDlgGotoLine,NULL
.elseif eax == IDM_DELETE
invoke SendMessage,hWinEdit,WM_CLEAR,0,0
.elseif eax == IDM_SELECTALL
mov @stRange.cpMin,0
mov @stRange.cpMax,-1
invoke SendMessage,hWinEdit,EM_EXSETSEL,0,addr @stRange
.elseif eax == IDM_SAVE
invoke _SaveFile
.elseif eax == IDM_SAVEAS
invoke _SaveAs
.elseif eax == IDM_PAGESETUP
invoke _PageSetup
.elseif eax == IDM_FIND
and stFind.Flags,not FR_DIALOGTERM
invoke FindText,addr stFind
.if eax
mov hFindDialog,eax
.endif
.elseif eax == IDM_FINDNEXT
or stFind.Flags,FR_DOWN
invoke _FindText
.elseif eax == IDM_REPLACE
and stFind.Flags,not FR_DIALOGTERM
invoke ReplaceText,addr stFind
.if eax
mov hReplaceDialog,eax
.endif
.elseif eax == IDM_FONT
invoke _ChooseFont
.elseif ax == IDM_SELCOLOR
invoke _ChooseColor
.elseif eax == IDM_TOOLBAR
xor dwOption,F_TOOLBAR
invoke _ResizeWindow
.elseif eax == IDM_STATUSBAR
xor dwOption,F_STATUSBAR
invoke _ResizeWindow
.endif

;********************************************************************
.elseif eax == idFindMessage
xor ecx,ecx
.if stFind.Flags & FR_FINDNEXT
invoke _FindText
.elseif stFind.Flags & FR_DIALOGTERM
mov hFindDialog,0
.elseif stFind.Flags & FR_REPLACE
invoke _ReplaceText
.elseif stFind.Flags & FR_REPLACEALL
invoke _ReplaceAll
.endif
.elseif eax == WM_NOTIFY
mov eax,lParam
mov eax,[eax + NMHDR.hwndFrom]
.if eax == hWinEdit
invoke _SetStatus
.endif
mov eax,lParam
mov eax,[eax + NMHDR.code]
;********************************************************************
;弹出右键菜单-----失败,在RichEdit控件上响应不了NM_RCLICK消息(????)
;********************************************************************
.if eax == NM_RCLICK
invoke GetCursorPos,addr @stPos
invoke TrackPopupMenu,hSubMenu,TPM_LEFTALIGN,@stPos.x,@stPos.y,NULL,hWinEdit,NULL
.endif
;********************************************************************
.elseif eax == WM_CLOSE
call _Quit
;********************************************************************
.else
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.endif
;********************************************************************
xor eax,eax
ret

_ProcWinMain endp

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_WinMain proc
local @stWndClass:WNDCLASSEX
local @stMsg:MSG
local @hAccelerator,@hRichEdit

invoke LoadLibrary,offset szDllEdit
mov @hRichEdit,eax
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke LoadMenu,hInstance,IDR_MENU
mov hMenu,eax
invoke LoadAccelerators,hInstance,IDA_MENU
mov @hAccelerator,eax
;********************************************************************
; 注册窗口类
;********************************************************************
invoke RtlZeroMemory,addr @stWndClass,sizeof @stWndClass
invoke LoadIcon,hInstance,ICO_MAIN
mov @stWndClass.hIcon,eax
mov @stWndClass.hIconSm,eax
push hInstance
pop @stWndClass.hInstance
mov @stWndClass.cbSize,sizeof WNDCLASSEX
mov @stWndClass.style,CS_HREDRAW or CS_VREDRAW
mov @stWndClass.lpfnWndProc,offset _ProcWinMain
mov @stWndClass.hbrBackground,COLOR_WINDOW + 1
mov @stWndClass.lpszClassName,offset szClassName
invoke RegisterClassEx,addr @stWndClass
;********************************************************************
; 建立并显示窗口
;********************************************************************
invoke CreateWindowEx,WS_EX_CLIENTEDGE,\
offset szClassName,offset szTitleFormat,\
WS_OVERLAPPEDWINDOW,\
200,160,600,400,\
NULL,hMenu,hInstance,NULL
mov hWinMain,eax
invoke ShowWindow,hWinMain,SW_SHOWNORMAL
invoke UpdateWindow,hWinMain
;********************************************************************
; 消息循环
;********************************************************************
.while TRUE
invoke GetMessage,addr @stMsg,NULL,0,0
.break .if eax == 0
invoke TranslateAccelerator,hWinMain,@hAccelerator,addr @stMsg
.if eax == 0
invoke TranslateMessage,addr @stMsg
invoke DispatchMessage,addr @stMsg
.endif
.endw
invoke FreeLibrary,@hRichEdit
ret

_WinMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
call _WinMain
invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start
 

    相关声明:

      若“汇编语言模拟Windows记事本,包括工具栏和颜色及所有功能”有损您的权益,请告之我们删除内容。
      部分文章来源于网络,版权归原作者所有。