⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 richedit.asm

📁 该程序是用汇编语言win32编制的文本编辑器,具有一般文本编辑器的增,删,该,查,复制,粘贴,打开,保存等功能
💻 ASM
📖 第 1 页 / 共 2 页
字号:
; 版本5,用RichEdit流式操作实现文件的打开与保存
;        响应 UNDO、REDO、CUT、PASTE、DEL菜单项
; 版本4,增加文件打开、文件保存、文件另存为、退出菜单的响应
; 版本3,增加了菜单显示
; 版本2,增加了图标显示
; 版本1,增加了RichEdit控件,可以进行文本编辑
; 版本0,仅显示一个窗口
    .386
    .model flat,stdcall
    option casemap:none
    
;----------------------------------------------
; Include 文件定义
;----------------------------------------------
include richedit.inc   ; 自定义的头文件,包含函数说明

include		windows.inc
include		gdi32.inc
includelib	gdi32.lib
include		user32.inc
includelib	user32.lib
include		kernel32.inc
includelib	kernel32.lib
include		comdlg32.inc
includelib	comdlg32.lib
include         comctl32.inc      ;  工具栏等通用控件
includelib      comctl32.lib

;----------------------------------------------
; 数据段
;----------------------------------------------
.data
   hInstance      dd	?
   hWinMain	  dd	?
   CommandLine    dd    ?
   szFileName     db    MAX_PATH dup (?)   ; 文件名缓冲区(包括路径在内)
                                           ; MAX_PATH 在 Windows.inc中定义
   hWinEdit       dd    ?                  ; RichEdit控件句柄
   hFile          dd    0                  ; 文件句柄
   hAccelerator   dd    ?
   hMenu          dd    ? 		   ; 菜单句柄
   hToolBar       dd    ?                  ; 工具栏句柄
   hTbBmp         dd    ?                  ; 工具栏上的位图句柄
   hWinStatus     dd    ?                  ; 状态栏句柄
   hFindDialog    dd    0                  ; 查找与替换对话框的句柄
   stFind         FINDREPLACE  <?>         ; 查找与替换结构变量
   szFindText     db    100 dup(0)         ; 查找字符串的缓冲区
   idFindMessage  dd    0                  ; 查找和替换对话框的消息
  
   

.const
   szClassName	  db	'Rich_Edit_Class',0
   szCaptionMain  db	'Richedit',0
   szClassEdit    db    'RichEdit20A',0       
   szDllEdit      db    'RichEd20.dll',0      

   szFilter	  db	'Text Files(*.txt)',0,'*.txt',0
	          db	'All Files(*.*)',0,'*.*',0,0
   szDefaultExt   db	'txt',0
   szErrOpenFile  db    '无法打开文件!',0
   szClassTool    db    'ToolbarWindow32',0  ; 工具栏的类名
   szDisplayName db "MASM32 Richedit",0
    
   dwStatusWidth  dd  50,150,300,-1          ; 状态栏的分隔点的坐标
   szStatusFormat db ' 行 %d  列 %d',0
   
   szFindMessage db 'commdlg_FindReplace',0
   szFindCaption db '查找字符串',0
   szNotFound    db '字符串搜索完毕',0

    TBSE equ TBSTATE_ENABLED
    TBSB equ TBSTYLE_BUTTON
lpButtons equ this byte
TBBUTTON <0,0,TBSTATE_ENABLED,TBSTYLE_SEP,0,0,-1>
TBBUTTON <STD_FILENEW,IDM_NEW,TBSE,TBSB,0,0,-1>
TBBUTTON <STD_FILEOPEN,IDM_OPEN,TBSE,TBSB,0,0,-1>
TBBUTTON <STD_FILESAVE,IDM_SAVE,TBSE,TBSB,0,0,-1>
TBBUTTON <0,0,TBSTATE_ENABLED,TBSTYLE_SEP,0,0,-1>
TBBUTTON <STD_CUT,IDM_CUT,TBSE,TBSB,0,0,-1>
TBBUTTON <STD_COPY,IDM_COPY,TBSE,TBSB,0,0,-1>
TBBUTTON <STD_PASTE,IDM_PASTE,TBSE,TBSB,0,0,-1>
TBBUTTON <STD_UNDO,IDM_UNDO,TBSE,TBSB,0,0,-1>
TBBUTTON <0,0,TBSTATE_ENABLED,TBSTYLE_SEP,0,0,-1>
TBBUTTON <STD_FIND,IDM_FIND,TBSE,TBSB,0,0,-1>
TBBUTTON <STD_REPLACE,IDM_FINDNEXT,TBSE,TBSB,0,0,-1>
TBBUTTON <0,0,TBSTATE_ENABLED,TBSTYLE_SEP,0,0,-1>
TBBUTTON <STD_DELETE,IDM_DEL,TBSE,TBSB,0,0,-1>

;TBBUTTON <0,0,TBSTATE_ENABLED,TBSTYLE_SEP,0,0,-1>
;TBBUTTON <0,IDM_NEW,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,-1>
;TBBUTTON <1,IDM_OPEN,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,-1>
;TBBUTTON <2,IDM_SAVE,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,-1>
;TBBUTTON <0,0,TBSTATE_ENABLED,TBSTYLE_SEP,0,0,-1>
;TBBUTTON <3,IDM_CUT,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,-1>
;TBBUTTON <4,IDM_COPY,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,-1>
;TBBUTTON <5,IDM_PASTE,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,-1>
;TBBUTTON <6,IDM_UNDO,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,-1>
;TBBUTTON <0,0,TBSTATE_ENABLED,TBSTYLE_SEP,0,0,-1>
;TBBUTTON <7,IDM_FIND,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,-1>
;TBBUTTON <8,IDM_FINDNEXT,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,-1>
;TBBUTTON <0,0,TBSTATE_ENABLED,TBSTYLE_SEP,0,0,-1>
;TBBUTTON <9,IDM_DEL,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,-1>


;----------------------------------------------
; 代码段
;----------------------------------------------
.code

;----------------------------------------------
; 主程序
;----------------------------------------------
start:
      invoke GetModuleHandle, NULL  ; 获得实例句柄
      mov    hInstance, eax
      invoke GetCommandLine         ; 获得命令行地址
      mov    CommandLine, eax

      invoke WinMain,hInstance,NULL,CommandLine,SW_SHOWDEFAULT
                                    ; 进入窗口主程序函数
      invoke ExitProcess,eax        ; 退出并返回操作系统

;----------------------------------------------
;  窗口主程序
;----------------------------------------------
WinMain proc hInst     :DWORD,
             hPrevInst :DWORD,
             CmdLine   :DWORD,
             CmdShow   :DWORD

      LOCAL Wwd  :DWORD    ; 窗口的宽度
      LOCAL Wht  :DWORD    ; 窗口的高度
      LOCAL Wtx  :DWORD    ; 窗口的左上角在屏幕上的水平坐标
      LOCAL Wty  :DWORD    ; 窗口的左上角在屏幕上的纵坐标
      LOCAL wc   :WNDCLASSEX   ; 窗口结构变量,存放创建窗口时需要的信息
      LOCAL msg  :MSG      ; 消息结构变量,存放获取的消息
 
      LOCAL hRichEdit:DWORD    ; RichEdit库句柄
      
      
      invoke LoadLibrary,offset szDllEdit   ; 装入RichEdit20.dll库
      mov    hRichEdit,eax

      invoke RtlZeroMemory,addr wc, sizeof wc ; 将结构变量wc中的各项清0
      mov    wc.cbSize,   sizeof WNDCLASSEX
      mov    wc.style,    CS_HREDRAW or CS_VREDRAW
      mov    wc.lpfnWndProc, offset WndProc
      push   hInst
      pop    wc.hInstance
      mov    wc.lpszClassName,  offset szClassName
      mov    wc.hbrBackground,COLOR_WINDOW + 1
      invoke LoadCursor,NULL,IDC_ARROW
      mov    wc.hCursor, eax

      invoke LoadIcon,hInst,MAIN_ICON   ; 从资源节区装入图标
      mov    wc.hIcon,eax
      
      invoke RegisterClassEx, ADDR wc   ; 注册窗口

      invoke LoadMenu,hInst,IDM_MAIN
      mov    hMenu,eax

     
        ; 计算主窗口的大小及显示位置
      invoke WindowSizePosition, addr Wtx,addr Wty,addr Wwd, addr Wht
        
                                        ; 创建可显示窗口
      invoke CreateWindowEx,WS_EX_CLIENTEDGE,
                            ADDR szClassName,
                            ADDR szCaptionMain,
                            WS_OVERLAPPEDWINDOW,
                            Wtx,Wty,Wwd,Wht,
                            NULL,hMenu,
                            hInst,NULL
      mov   hWinMain,eax        ; 保存窗口句柄

      invoke ShowWindow,hWinMain,SW_SHOWNORMAL   ; 显示窗口
      invoke UpdateWindow,hWinMain
      
      invoke LoadAccelerators,hInstance,IDA_MAIN ;建立快捷键表
      mov    hAccelerator, eax       
           
      
 
  StartLoop:        ; 消息循环
      invoke GetMessage,ADDR msg,NULL,0,0     ; 获取消息
      cmp eax, 0                              ; 0,表示是退出消息
      je  ExitLoop
      invoke TranslateAccelerator,hWinMain,hAccelerator,ADDR msg
      invoke TranslateMessage, ADDR msg       ; 转换消息
      invoke DispatchMessage,  ADDR msg       ; 分发到窗口消息处理程序
      jmp StartLoop
  ExitLoop:
      invoke FreeLibrary,hRichEdit            ; 释放RichEdit库
      mov eax, msg.wParam
      ret
WinMain endp

; ---------------------------------------------
; 窗口消息处理程序
; ---------------------------------------------
WndProc  proc uses ebx edx esi hWnd,uMsg,wParam,lParam
	local	stRange:CHARRANGE
	local	stPos:POINT

	mov	eax,uMsg
	.if	eax ==	WM_CLOSE
	        invoke  Quit
	.elseif eax == WM_CREATE
	        invoke  Init , hWnd
	.elseif eax == WM_SIZE
	        invoke AdjustLayout   ; 调整工具栏、RichEdit控件、状态栏的显示位置和大小
         
	.elseif eax == WM_NOTIFY
                mov ebx, lParam
                mov ecx, [ebx+NMHDR.hwndFrom]
                .if [ebx+NMHDR.code] == TTN_NEEDTEXT    ;显示工具的提示
                   assume ebx:ptr TOOLTIPTEXT
                    mov eax, [ebx].hdr.idFrom
                    mov [ebx].lpszText, eax
                    push hInstance
                    pop  [ebx].hInst
                    assume ebx:nothing
                .elseif ecx == hWinEdit
 			invoke	DisplayStatusBarInfo
 			invoke  DisplayFacet
                .endif      
	.elseif	eax ==	WM_COMMAND
		mov	eax,wParam
		movzx	eax,ax
		.if	eax ==	IDM_OPEN
		        invoke  Confirmation
			invoke	OpenTextFile
			.if hFile   ; 显示打开的文件名
			    invoke  SetWindowText,hWnd,offset szFileName
			.endif	
				
		.elseif eax ==  IDM_NEW
		        invoke  Confirmation
		        invoke	SetWindowText,hWinEdit,NULL
		        invoke  SetWindowText,hWnd,offset szCaptionMain
		        invoke  DisplayFacet
			
		.elseif	eax ==	IDM_SAVE
			invoke  SaveFile			
                .elseif eax ==  IDM_SAVEAS
                        invoke  SaveFileAs                       
                .elseif eax ==  IDM_EXIT
                        invoke Quit
                .elseif eax ==  IDM_UNDO
                        invoke SendMessage,hWinEdit,EM_UNDO,0,0
                .elseif eax ==  IDM_CUT
                        invoke SendMessage,hWinEdit,WM_CUT,0,0
                .elseif eax ==  IDM_COPY
                        invoke SendMessage,hWinEdit,WM_COPY,0,0
                .elseif eax ==  IDM_PASTE
                        invoke SendMessage,hWinEdit,EM_PASTESPECIAL,CF_TEXT,0
                .elseif eax ==  IDM_DEL
                        invoke SendMessage,hWinEdit,WM_CLEAR,0,0
		.elseif  eax == IDM_SELECT    
 		mov	stRange.cpMin,0
		mov	stRange.cpMax,-1
		invoke	SendMessage,hWinEdit,EM_EXSETSEL,0,addr stRange


                .elseif eax == IDM_FIND
                        .if hFindDialog == 0
                            mov stFind.lStructSize,sizeof FINDREPLACE
                            push hWnd
                            pop  stFind.hwndOwner
                            push hInstance
                            pop  stFind.hInstance
                            mov  stFind.Flags,FR_DOWN
                            mov  stFind.lpstrFindWhat,offset szFindText
		            mov  stFind.wFindWhatLen,sizeof szFindText
 
                            invoke FindText,offset stFind
                            mov	   hFindDialog,eax
                         .endif

                .endif
        .elseif eax == idFindMessage
                .if     stFind.Flags & FR_FINDNEXT
                        invoke	SearchString

                .elseif stFind.Flags & FR_DIALOGTERM
                        mov   hFindDialog, 0 
                .endif  
	
; 按下右键时弹出一个POPUP菜单
	.elseif eax==WM_RBUTTONDOWN
		invoke  GetCursorPos,addr stPos
		invoke  TrackPopupMenu,hWinEdit,TPM_LEFTALIGN,stPos.x,stPos.y,NULL,hWnd,NULL         
                
	
	.else
		invoke	DefWindowProc,hWnd,uMsg,wParam,lParam
		ret
	.endif
	xor	eax,eax
	ret
WndProc endp


; --------------------------------------------------------------
; 计算窗口大小和显示位置
;     窗口大小为屏幕的 3/4, 显示位置在中间,即屏幕宽、高的 1/8
; --------------------------------------------------------------
WindowSizePosition PROC  lpx,lpy,lpwidth,lphight
        LOCAL x,y,w,h
        invoke GetSystemMetrics,SM_CXSCREEN  ; 获取屏幕宽度
        mov    w,  eax
        mov    x,  eax
        shr    eax, 2
        sub    w,   eax         ; 主窗口宽度为屏幕原宽度的 3/4
        shr    x,   3           ; 左上角的x坐标

        invoke GetSystemMetrics,SM_CYSCREEN   ; 获取屏幕高度
        mov    h, eax
        mov    y, eax   

        shr    eax, 2
        sub    h, eax           ; 主窗口高度为屏幕原高度的 3/4
        shr    y, 3

        push   x
        push   y
        push   w
        push   h
        mov    ebx, lphight
        pop    dword ptr [ebx]
        mov    ebx, lpwidth
        pop    dword ptr [ebx]
        mov    ebx, lpy
        pop    dword ptr [ebx]
        mov    ebx, lpx
        pop    dword ptr [ebx]

        ret
WindowSizePosition endp

; ---------------------------------------------
; 窗口初始化,WM_CREATE消息的处理程序
; ---------------------------------------------
Init  Proc  hWin
	invoke  LoadToolBar,hWin
	invoke  LoadStatusBar,hWin
        ; 注意:调整了RichEdit控件子窗的纵向显示位置,在前面留出了菜单栏大小

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -