最近发现,虽然有一段时间没有写代码了,但是以前积累的经验对解决现在的一些问题,还是挺有益处的。以前一直打算深入理解下windows系统,但这个需要很多的时间和精力,所以没有尝试。最近打开书柜,发现很久以前买了《windows环境下32位汇编语言程序设计》第三版(后来好像还出第四版了),罗云彬写的。这本书其实以前也看过,但现在已经没什么印象了,打算拿来重新翻看一下,进一步掌握 windows编程的一些细节。
当然,要掌握 windows编程,本人又在网上买了一本《windows程序设计》第五版(珍藏版),这本书提供了windows编程的基础知识,很有用,虽然是1998年写的。
在此不打算细列windows的各个技术知识细节,因为实在是太多了,还是列一个实际的例子吧。一个win32开发的记事本程序。
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Sample code for < Win32ASM Programming 4th Edition>
; by 罗云彬, luoyunbin@hotmail.com
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Richedit.asm
; “丰富编辑”控件的使用例子
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 使用 nmake 或下列命令进行编译和链接:
; ml /c /coff Richedit.asm
; rc Richedit.rc
; Link /subsystem:windows Richedit.obj Richedit.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
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 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_EXIT equ 2105
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_Help equ 3101
IDM_ABOUT equ 3102
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
hInstance dd ?
hWinMain dd ?
hMenu dd ?
hWinEdit dd ?
hFile dd ?
hFindDialog dd ?
idFindMessage dd ?
szFileName db MAX_PATH dup (?)
szFindText 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
szClassName db 'Wordpad',0
szCaptionMain db '记事本',0
szDllEdit db 'RichEd20.dll',0
szClassEdit db 'RichEdit20A',0
szNotFound db '字符串未找到!',0
szFilter db 'Text Files(*.txt)',0,'*.txt',0
db 'All Files(*.*)',0,'*.*',0,0
szDefaultExt db 'txt',0
szDefExt db 'txt',0
szErrOpenFile db '无法打开文件!',0
szErrCreateFile db '无法建立文件!',0
szModify db '文件已修改,是否保存?',0
szFont db '宋体',0
szCaption db '提问',0
szSaveCaption db '请输入保存的文件名',0
szTitleFormat db '记事本 - [%s]',0
szNoName db '未命名的文件',0
szAboutName db '关于本程序',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 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
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 保存文件,如果没有打开或创建文件则调用“另存为”子程序
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_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
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 另存为
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_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
mov @stOF.lpstrDefExt,offset szDefaultExt
invoke GetOpenFileName,addr @stOF
.if eax
;********************************************************************
; 创建文件
;********************************************************************
invoke CreateFile,addr szFileName,GENERIC_READ or GENERIC_WRITE,\
FILE_SHARE_READ or FILE_SHARE_WRITE,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.pfnCallback,offset _ProcStream
invoke SendMessage,hWinEdit,EM_STREAMIN,SF_TEXT,addr @stES
invoke SendMessage,hWinEdit,EM_SETMODIFY,FALSE,0
call _SetCaption
.endif
ret
_OpenFile 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
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 查找文字
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_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
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_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
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;关于对话框 消息处理过程
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcDlgAbout proc uses ebx edi esi hWnd,wMsg,wParam,lParam
mov eax,wMsg
.if eax == WM_CLOSE
invoke EndDialog,hWnd,NULL
.elseif eax == WM_INITDIALOG
mov eax,TRUE
.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
_ProcDlgAbout endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 关于对话框
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_About proc
invoke DialogBoxParam,hInstance,IDM_ABOUT,hWinMain,offset _ProcDlgAbout,NULL
ret
_About endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 根据情况改变菜单项状态
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_SetStatus proc
local @stRange:CHARRANGE
invoke SendMessage,hWinEdit,EM_EXGETSEL,0,addr @stRange
;********************************************************************
mov eax,@stRange.cpMin
.if eax == @stRange.cpMax
invoke EnableMenuItem,hMenu,IDM_COPY,MF_GRAYED
invoke EnableMenuItem,hMenu,IDM_CUT,MF_GRAYED
.else
invoke EnableMenuItem,hMenu,IDM_COPY,MF_ENABLED
invoke EnableMenuItem,hMenu,IDM_CUT,MF_ENABLED
.endif
;********************************************************************
invoke SendMessage,hWinEdit,EM_CANPASTE,0,0
.if eax
invoke EnableMenuItem,hMenu,IDM_PASTE,MF_ENABLED
.else
invoke EnableMenuItem,hMenu,IDM_PASTE,MF_GRAYED
.endif
;********************************************************************
invoke SendMessage,hWinEdit,EM_CANREDO,0,0
.if eax
invoke EnableMenuItem,hMenu,IDM_REDO,MF_ENABLED
.else
invoke EnableMenuItem,hMenu,IDM_REDO,MF_GRAYED
.endif
;********************************************************************
invoke SendMessage,hWinEdit,EM_CANUNDO,0,0
.if eax
invoke EnableMenuItem,hMenu,IDM_UNDO,MF_ENABLED
.else
invoke EnableMenuItem,hMenu,IDM_UNDO,MF_GRAYED
.endif
;********************************************************************
invoke GetWindowTextLength,hWinEdit
.if eax
invoke EnableMenuItem,hMenu,IDM_SELALL,MF_ENABLED
.else
invoke EnableMenuItem,hMenu,IDM_SELALL,MF_GRAYED
.endif
;********************************************************************
invoke SendMessage,hWinEdit,EM_GETMODIFY,0,0
.if eax
invoke EnableMenuItem,hMenu,IDM_SAVE,MF_ENABLED
.else
invoke EnableMenuItem,hMenu,IDM_SAVE,MF_GRAYED
.endif
;********************************************************************
.if szFindText
invoke EnableMenuItem,hMenu,IDM_FINDNEXT,MF_ENABLED
invoke EnableMenuItem,hMenu,IDM_FINDPREV,MF_ENABLED
.else
invoke EnableMenuItem,hMenu,IDM_FINDNEXT,MF_GRAYED
invoke EnableMenuItem,hMenu,IDM_FINDPREV,MF_GRAYED
.endif
;********************************************************************
ret
_SetStatus endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_Init proc
local @stCf:CHARFORMAT
;********************************************************************
; 注册“查找”对话框消息,初始化“查找”对话框的结构
;********************************************************************
push hWinMain
pop stFind.hwndOwner
invoke RegisterWindowMessage,addr FINDMSGSTRING
mov idFindMessage,eax
;********************************************************************
; 建立输出文本窗口
;********************************************************************
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
invoke SendMessage,hWinEdit,EM_SETTEXTMODE,TM_PLAINTEXT,0
invoke RtlZeroMemory,addr @stCf,sizeof @stCf
mov @stCf.cbSize,sizeof @stCf
mov @stCf.yHeight,9 * 20
mov @stCf.dwMask,CFM_FACE or CFM_SIZE or CFM_BOLD
invoke _SetCaption
invoke lstrcpy,addr @stCf.szFaceName,addr szFont
invoke SendMessage,hWinEdit,EM_SETCHARFORMAT,0,addr @stCf
invoke SendMessage,hWinEdit,EM_EXLIMITTEXT,0,-1
ret
_Init endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_Quit proc
invoke _CheckModify
.if eax
invoke DestroyWindow,hWinMain
invoke PostQuitMessage,NULL
.if hFile
invoke CloseHandle,hFile
.endif
.endif
ret
_Quit endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcWinMain proc uses ebx edi esi hWnd,uMsg,wParam,lParam
local @stRange:CHARRANGE
local @stRect:RECT
mov eax,uMsg
.if eax == WM_SIZE
invoke GetClientRect,hWinMain,addr @stRect
invoke MoveWindow,hWinEdit,0,0,@stRect.right,@stRect.bottom,TRUE
;********************************************************************
; 处理菜单、加速键及工具栏消息
;********************************************************************
.elseif eax == WM_COMMAND
mov eax,wParam
movzx eax,ax
.if 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_OPEN
invoke _CheckModify
.if eax
call _OpenFile
.endif
.elseif eax == IDM_SAVE
call _SaveFile
.elseif eax == IDM_SAVEAS
call _SaveAs
.elseif eax == IDM_EXIT
invoke _Quit
.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_ABOUT
invoke _About
.elseif eax == IDM_SELALL
mov @stRange.cpMin,0
mov @stRange.cpMax,-1
invoke SendMessage,hWinEdit,EM_EXSETSEL,0,addr @stRange
.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_FIND
and stFind.Flags,not FR_DIALOGTERM
invoke FindText,addr stFind
.if eax
mov hFindDialog,eax
.endif
.elseif eax == IDM_FINDPREV
and stFind.Flags,not FR_DOWN
invoke _FindText
.elseif eax == IDM_FINDNEXT
or stFind.Flags,FR_DOWN
invoke _FindText
.endif
;********************************************************************
.elseif eax == WM_INITMENU
call _SetStatus
.elseif eax == idFindMessage
.if stFind.Flags & FR_DIALOGTERM
mov hFindDialog,0
.else
invoke _FindText
.endif
;********************************************************************
.elseif eax == WM_ACTIVATE
mov eax,wParam
.if (ax == WA_CLICKACTIVE ) || (ax == WA_ACTIVE)
invoke SetFocus,hWinEdit
.endif
;********************************************************************
.elseif eax == WM_CREATE
push hWnd
pop hWinMain
invoke _Init
;********************************************************************
.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,IDM_MAIN
mov hMenu,eax
invoke LoadAccelerators,hInstance,IDA_MAIN
mov @hAccelerator,eax
;********************************************************************
; 注册窗口类
;********************************************************************
invoke RtlZeroMemory,addr @stWndClass,sizeof @stWndClass
invoke LoadIcon,hInstance,ICO_MAIN
mov @stWndClass.hIcon,eax
mov @stWndClass.hIconSm,eax
invoke LoadCursor,0,IDC_ARROW
mov @stWndClass.hCursor,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_BTNFACE+1
mov @stWndClass.lpszClassName,offset szClassName
invoke RegisterClassEx,addr @stWndClass
;********************************************************************
; 建立并显示窗口
;********************************************************************
invoke CreateWindowEx,NULL,\
offset szClassName,offset szCaptionMain,\
WS_OVERLAPPEDWINDOW,\
CW_USEDEFAULT,CW_USEDEFAULT,700,500,\
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
实现效果如下
“
当然上面的程序还涉及到资源文件,内容如下:
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#include <resource.h>
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#define ICO_MAIN 1000
#define IDA_MAIN 2000
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#define IDM_MAIN 2000
#define IDM_NEW 2101
#define IDM_OPEN 2102
#define IDM_SAVE 2103
#define IDM_SAVEAS 2104
#define IDM_EXIT 2105
#define IDM_UNDO 2201
#define IDM_REDO 2202
#define IDM_SELALL 2203
#define IDM_COPY 2204
#define IDM_CUT 2205
#define IDM_PASTE 2206
#define IDM_FIND 2207
#define IDM_FINDPREV 2208
#define IDM_FINDNEXT 2209
#define IDM_HELP 3101
#define IDM_ABOUT 3102
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ICO_MAIN ICON "Main.ico"
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
IDM_MAIN menu discardable
BEGIN
popup "文件(&F)"
BEGIN
menuitem "新建文件(&N)...\tCtrl+N", IDM_NEW
menuitem "打开文件(&O)...\tCtrl+O", IDM_OPEN
menuitem "保存文件(&S)\tCtrl+S", IDM_SAVE
menuitem "文件另存为(&A)...\tCtrl+Alt+S",IDM_SAVEAS
menuitem separator
menuitem "退出(&X)", IDM_EXIT
END
popup "编辑(&E)"
BEGIN
menuitem "撤销(&Z)\tCtrl+Z", IDM_UNDO
menuitem "恢复(&Y)\tCtrl+Y", IDM_REDO
menuitem separator
menuitem "全选(&A)\tCtrl+A", IDM_SELALL
menuitem "拷贝(&C)\tCtrl+C", IDM_COPY
menuitem "剪切(&X)\tCtrl+X", IDM_CUT
menuitem "粘贴(&V)\tCtrl+V", IDM_PASTE
menuitem separator
menuitem "查找(&F)...\tCtrl+F", IDM_FIND
menuitem "查找上一个(&P)\tF2", IDM_FINDPREV
menuitem "查找下一个(&N)\tF3", IDM_FINDNEXT
END
popup "帮助(&H)"
BEGIN
menuitem "关于(&A)", IDM_ABOUT
END
END
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
IDA_MAIN accelerators
BEGIN
VK_F2, IDM_FINDPREV,VIRTKEY
VK_F3, IDM_FINDNEXT,VIRTKEY
"N", IDM_NEW,VIRTKEY,CONTROL
"O", IDM_OPEN,VIRTKEY,CONTROL
"S", IDM_SAVE,VIRTKEY,CONTROL
"S", IDM_SAVEAS,VIRTKEY,CONTROL,ALT
"Z", IDM_UNDO,VIRTKEY,CONTROL
"Y", IDM_REDO,VIRTKEY,CONTROL
"A", IDM_SELALL,VIRTKEY,CONTROL
"C", IDM_COPY,VIRTKEY,CONTROL
"X", IDM_CUT,VIRTKEY,CONTROL
"V", IDM_PASTE,VIRTKEY,CONTROL
"F", IDM_FIND,VIRTKEY,CONTROL
END
IDM_ABOUT DIALOG DISCARDABLE 32, 32, 180, 102
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
CAPTION "关于记事本"
FONT 11, "宋体"
BEGIN
DEFPUSHBUTTON "确定",IDOK,66,81,50,14
ICON ICO_MAIN,-1,7,7,21,20
CTEXT "关于本程序",-1,40,12,100,8
CTEXT "这是一个记事本程序!",-1,7,40,166,8
CTEXT "采用win32汇编语言编写",-1,7,52,166,8
END
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
这个程序看起来,很复杂,实际上,整个exe文件只有10kB,代码细节不想多说,因为涉及面相当广,实现的需求功能如下:
1.文件方面,有新建、保存、另存为、退出。如果内容没有变化,保存菜单呈灰色状态;如果新建文本没有保存时,退出或打开其它文件,提示用户先保存。
2.编辑方面,有撤销、恢复、全选、拷贝、粘贴、查找;
3.帮助方面,只有一个菜单“关于”。
4.当新建文本时,标题栏显示“未命名文件”,如果是打开的文件,则显示此文件路径及文件名。
win32汇编虽然不及现在的web编程那么流行,但对操作系统的理解却很有帮助,有利于解决一些电脑上出现的问题,特别是系统安全方面,如病毒、软件破解这些。