用RadASM开发记事本程序.docx
《用RadASM开发记事本程序.docx》由会员分享,可在线阅读,更多相关《用RadASM开发记事本程序.docx(14页珍藏版)》请在冰豆网上搜索。
用RadASM开发记事本程序
用RadASM开发记事本程序
此记事本程序用普通的Edit控件实现,还有一些小小的bug,不完美的地方,在选
择文本的时候,行号未能更新重画,现在也正在思考,水平不够,用RichEdit控件
能达到更好的效果,修复一些小的BUG.
;--------------------------------------------------------------------------------
;程序作者:
维唯为为
;开发日期:
2011-03-08
;文件描述:
我的应用程序模板
;注意事项:
此份代码使用586指令集
;更新历史:
;--------------------------------------------------------------------------------
.586
.model flat,stdcall
option casemap:
none
include windows.inc
include user32.inc
include kernel32.inc
include comdlg32.inc
include gdi32.inc
includelib user32.lib
includelib kernel32.lib
includelib comdlg32.lib
includelib gdi32.lib
WinMain proto :
DWORD,:
DWORD,:
DWORD,:
DWORD
.data
ClassName db "MainWinClass",0 ;窗口类名
AppName db "My Win32ASM Application",0 ;应用程序标题名
editClass db "edit",0
aboutApp db "小记事本,维唯为为,汇编语言编写",0
;exitStr db "是否要退出程序?
",0
;remind db "提示",0
;调用公共对话框所要的信息
szFilter db "Text File(*.txt)",0,"*.txt",0,"All File(*.*)",0,"*.*",0,0
szDefExt db "txt",0
strFileBuf db 8192 dup(?
)
;有待改善,可通过获取要打开的文件的大小属性动态的分配内存空间
;用GlobalAlloc函数动态分配,GetFileSize获取文件大小后,再用GlobalReAlloc重新分配缓冲区内存
.data?
hInstance HINSTANCE ?
;应用程序的句柄
CommandLine LPSTR ?
;程序的命令行参数字符串
hEdit HWND ?
;文本编辑框的窗口句柄
strFile db MAX_PATH dup (?
) ;保存公共对话框中获取的文件名
lpEditProc HWND ?
.const
APP_ICON equ 1200 ;应用程序的图标
;Res\MainMenu.mnu
IDR_MENU equ 10000
IDM_FILE equ 10001
IDM_FILE_OPEN equ 10002
IDM_FILE_SAVE equ 10003
IDM_LINE1 equ 10004
IDM_FILE_EXIT equ 10005
IDM_EDIT equ 10006
IDM_EDIT_UNDO equ 10007
IDM_EDIT_REDO equ 10008
IDM_LINE2 equ 10009
IDM_EDIT_CUT equ 10010
IDM_EDIT_COPY equ 10011
IDM_EDIT_PASTE equ 10012
IDM_HELP equ 10013
IDM_HELP_ABOUT equ 10014
.code
; ---------------------------------------------------------------------------
;程序入口点
start:
;为程序生成一个实例句柄
invoke GetModuleHandle, NULL
mov hInstance,eax
;为程序获取一个命令行参数
invoke GetCommandLine
mov CommandLine,eax
;调用windows的主函数
invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT
invoke ExitProcess,eax
_ShowLineNum proc hwndEdit:
HWND
;功能:
显示文本的总行数
;参数:
; hEdit:
要显示行号的文本框,这里用RichEdit测试
;返回值:
没有
LOCAL @stClientRect:
RECT ;RichEdit的客户区大小
LOCAL @hDcEdit ;RichEdit的DC(设备环境)
LOCAL @Char_Height ;文本总行数
LOCAL @Line_Count ;字符高度
LOCAL @ClientHeight ;RichEdit的客户区高度
LOCAL @hdcBmp ;与RichEdit兼容的位图dc
LOCAL @hdcCpb ;与RichEdit兼容的Dc
LOCAL @CharFmt:
CHARFORMAT ;RichEdit中的一个结构,用于获取字符的一系列信息
LOCAL @stBuf[10]:
byte ;显示行号的缓冲区
LOCAL @szTest[64]:
byte ;Test
LOCAL tm:
TEXTMETRIC
pushad ;保存一下所有的寄存器
;获取RichEdit的Dc
invoke GetDC,hEdit
mov @hDcEdit,eax
;获取RichEdit的客户区高度
invoke GetClientRect,hEdit,addr @stClientRect
mov ebx, @stClientRect.bottom
sub ebx, @stClientRect.top
mov @ClientHeight, ebx
;创建与RichEdit兼容的Dc
invoke CreateCompatibleDC,@hDcEdit
mov @hdcCpb, eax
;创建与RichEdit兼容的位图Dc,
invoke CreateCompatibleBitmap,@hDcEdit,40,@ClientHeight
mov @hdcBmp,eax
;将位图dc选入RichEdit环境中
invoke SelectObject,@hdcCpb,@hdcBmp
;创建一个实心画刷,用于下面的FillRect函数。
invoke CreateSolidBrush,0000a0ffh ;设置画刷的颜色
;填充显示行号的dc的背景颜色。
invoke FillRect, @hdcCpb,addr @stClientRect,eax
invoke SetBkMode, @hdcCpb,TRANSPARENT
;获取当前RichEdit文本中的总行数
invoke SendMessage, hEdit,EM_GETLINECOUNT,0,0
mov @Line_Count, eax
;获取字符高度
invoke RtlZeroMemory, addr tm,sizeof tm
invoke GetTextMetrics, @hDcEdit,addr tm
push tm.tmHeight
pop @Char_Height
.data
charFmt byte "%4u",0
.code
invoke RtlZeroMemory,addr @stBuf,sizeof @stBuf
;设置显示行号的前景色
invoke SetTextColor,@hdcCpb,0000000h
mov ebx, @Char_Height
mov @Char_Height,1
;获取文本框中第一个可见的行号,没有这个行号显示不会跟着文本的滚动而滚动
invoke SendMessage,hEdit,EM_GETFIRSTVISIBLELINE,0,0
mov edi, eax
inc edi
;在位图dc中循环输出行号
.while edi<=@Line_Count
invoke wsprintf,addr @stBuf,addr charFmt,edi
;int wsprintf,lpout(输出缓冲区),lpFmt(格式字符串),...(需要输出的参数),返回值是写入的长度
invoke TextOut,@hdcCpb,1,@Char_Height,addr @stBuf,eax
mov edx,@Char_Height
add edx,ebx
;add edx, 4 ;这里加上行间距,并不精确。
mov @Char_Height, edx
inc edi
.break .if edx>@ClientHeight
.endw
;将已“画好”位图真正“贴”到RichEdit中
invoke BitBlt,@hDcEdit,0,0,40,@ClientHeight,@hdcCpb,0,0,SRCCOPY
invoke DeleteDC,@hdcCpb
invoke ReleaseDC,hEdit,@hDcEdit
invoke DeleteObject,@hdcBmp
popad
ret
_ShowLineNum endp
COMMENT #
;--------------------------------------------------------------------------------
BitBlt
The BitBlt function performs a bit-block transfer of the color data corresponding to a rectangle
of pixels from the specified source device context into a destination device context.
BOOL BitBlt(
HDC hdcDest, // handle to destination device context
int nXDest, // x-coordinate of destination rectangle's upper-left
// corner
int nYDest, // y-coordinate of destination rectangle's upper-left
// corner
int nWidth, // width of destination rectangle
int nHeight, // height of destination rectangle
HDC hdcSrc, // handle to source device context
int nXSrc, // x-coordinate of source rectangle's upper-left
// corner
int nYSrc, // y-coordinate of source rectangle's upper-left
// corner
DWORD dwRop // raster operation code
);
;--------------------------------------------------------------------------------
#
_SubProcEdit proc hWnd,uMsg,wParam,lParam
;功能:
截获RichEdit的WM_PAINT消息,用于当RichEdit刷新时显示行号。
;参数:
; hWnd,uMsg,wParam,lParam 都为原有Windows发给RichEdit的消息和参数
;返回值:
没有
;说明:
当消息处理完毕后必须把消息回送给默认的RichEdit的窗口过程
; lpEditProc为RichEdit的旧窗口地址
;--------------------------------------------------------------------------------
LOCAL @stPS:
PAINTSTRUCT
LOCAL @stEditRect:
RECT
.if uMsg==WM_PAINT
invoke CallWindowProc,lpEditProc,hWnd,uMsg,wParam,lParam
invoke BeginPaint,hEdit,addr @stPS
;这个函数实现显示行号
invoke _ShowLineNum,hEdit
invoke EndPaint,hEdit,addr @stPS
ret
.elseif uMsg==WM_KEYUP || uMsg==WM_KEYDOWN
invoke GetClientRect,hEdit,addr @stEditRect
mov @stEditRect.right,45
invoke InvalidateRect,hEdit,addr @stEditRect,TRUE
.endif
invoke CallWindowProc,lpEditProc,hWnd,uMsg,wParam,lParam
ret
_SubProcEdit endp
WinMain proc hInst:
HINSTANCE,hPrevInst:
HINSTANCE,CmdLine:
LPSTR,CmdShow:
DWORD
LOCAL wc:
WNDCLASSEX
LOCAL msg:
MSG
LOCAL hwnd:
HWND
;填充windows的窗口结构体
mov wc.cbSize,SIZEOF WNDCLASSEX ;表示窗口结构体的总大小
mov wc.style, CS_HREDRAW or CS_VREDRAW ;窗口类型
mov wc.lpfnWndProc, OFFSET WndProc ;OFFSET表示这个函数的首地址,相当于传指针
mov wc.cbClsExtra,NULL ;窗口类的附加数据
mov wc.cbWndExtra,NULL ;窗口类的附加数据
push hInstance ;传递程序的实例句柄给窗口类
pop wc.hInstance
mov wc.hbrBackground,COLOR_BTNFACE+1 ;创建窗口的背景
mov wc.lpszMenuName,IDR_MENU ;为此窗口建立一个主菜单
mov wc.lpszClassName,OFFSET ClassName ;窗口类的名称
invoke LoadIcon,NULL,APP_ICON ;为此窗口建立一个图标
mov wc.hIcon,eax
mov wc.hIconSm,eax
invoke LoadCursor,NULL,IDC_ARROW ;指定窗口上的鼠标指针类型
mov wc.hCursor,eax
;向Windows注册一个窗口
invoke RegisterClassEx, addr wc ;注册窗口类
;创建一个窗口
INVOKE CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\
WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\
hInst,NULL
mov hwnd,eax ;把窗口句柄赋值给hwnd变量
invoke ShowWindow, hwnd,SW_SHOWNORMAL ;显示窗口
invoke UpdateWindow, hwnd ;刷新一个窗口
;消息循环
.WHILE TRUE
invoke GetMessage, ADDR msg,NULL,0,0
.BREAK .IF (!
eax) ;如果获取的消息的返回值为空
invoke TranslateMessage, ADDR msg ;转换消息
invoke DispatchMessage, ADDR msg ;分发消息
.ENDW
mov eax,msg.wParam
ret
WinMain endp
WndProc proc hWnd:
HWND, uMsg:
UINT, wParam:
WPARAM, lParam:
LPARAM
LOCAL winRect:
RECT
LOCAL editWidth:
DWORD
LOCAL editHeight:
DWORD
LOCAL ofn:
OPENFILENAME ;定义一个打开文件的结构体
LOCAL hFile:
HANDLE
LOCAL bytesRead:
DWORD
LOCAL bytesWrite:
DWORD
LOCAL textLen:
DWORD
.IF uMsg==WM_DESTROY
invoke PostQuitMessage,NULL
.ELSEIF uMsg==WM_CREATE
;为窗口建立一个图标
invoke LoadIcon,hInstance,APP_ICON
invoke SendMessage,hWnd,WM_SETICON,ICON_BIG,eax ;发送设置图标消息
;创建一个文本编辑框
invoke CreateWindowEx,WS_EX_CLIENTEDGE,offset editClass,\
NULL,WS_CHILDWINDOW OR WS_VISIBLE OR WS_VSCROLL OR WS_HSCRO