用汇编编写屏幕保护程序
2008-04-28 09:33:10 来源:WEB开发网综上所述,屏幕保护程序的两个部分即窗口过程和设置对话框过程是在不同的地方被执行的,所以在编程中要注意不要在两个过程中传递变量,这就意味着屏幕保护程序的设置要被输出到 .ini 或注册表中保存,在窗口过程中的 WM_CREATE 消息中再读入,因为你无法把它保留在内存中。同样窗口过程和设置对话框过程中的变量或资源的初始化也要分别进行,比如说两者都要用到同一个图片,那就在自己的 WM_CREATE 消息中分别 LoadBitmap,总之要时刻认为你是在编写两个“独立的程序”。
下面是一个屏幕保护程序的资源定义例子:
#include <resource.h>
#define ICO_MAIN 100
#define DLG_SETUP 2003
ICO_MAIN ICON "Resource\Main.ico"
DLG_SETUP DIALOG DISCARDABLE 0, 0, 300, 120
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "屏幕保护程序"
FONT 9, "宋体"
BEGIN
...
...
DEFPUSHBUTTON "确定(&O)", IDOK, 240,10,50,14
PUSHBUTTON "取消(&C)", IDCANCEL, 240,29,50,14
END
STRINGTABLE DISCARDABLE
BEGIN
100 "保护程序"
END
.def 文件例子:
EXPORTS
ScreenSaverProc
ScreenSaverConfigureDialog
RegisterDialogClasses
源代码例子:
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Programmed by 罗云彬, bigluo@telekbird.com.cn
; Website: http://asm.yeah.net
; LuoYunBin's Win32 ASM page (罗云彬的编程乐园)
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 版本信息
; 屏幕保护程序模板
; Ver 1.0 - 2000.07.15
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386
.model flat, stdcall
option casemap :none ; case sensitive
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 数据
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include windows.inc
include user32.inc
include kernel32.inc
include comctl32.inc
include comdlg32.inc
include gdi32.inc
include advapi32.inc
include shell32.inc
include scrnsave.inc
includelib user32.lib
includelib kernel32.lib
includelib comctl32.lib
includelib comdlg32.lib
includelib gdi32.lib
includelib advapi32.lib
includelib shell32.lib
includelib scrnsave.lib
includelib msvcrt.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Equ 数据
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ICO_MAIN equ 100 ;Must be 100
DLG_SETUP equ 2003 ;Must be 2003
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
hInstance dd ?
hWinMain dd ?
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 设置对话框过程
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ScreenSaverConfigureDialog proc uses ebx edi esi, \
hWnd:DWORD,wMsg:DWORD,wParam:DWORD,lParam:DWORD
mov eax,wMsg
;********************************************************************
.elseif eax == WM_CLOSE
invoke EndDialog,hWnd,NULL
;********************************************************************
.elseif eax == WM_COMMAND
mov eax,wParam
.if eax == IDOK
... 在此保存设置 ...
invoke EndDialog,hWnd,NULL
.elseif eax == IDCANCEL
invoke EndDialog,hWnd,NULL
.endif
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
ScreenSaverConfigureDialog endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 主程序窗口过程
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ScreenSaverProc proc uses ebx edi esi, \
hWnd:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
mov eax,uMsg
.if eax == WM_CREATE
invoke GetModuleHandle,NULL
mov hInstance,eax
mov eax,hWnd
mov hWinMain,eax ...
在此初始化,包括定义一个定时器 ...
invoke SetTimer,hWinMain,TIMER_MOON,100,NULL
.elseif eax == WM_DESTROY
call _Quit
;********************************************************************
.elseif eax == WM_TIMER
...
在此画屏幕动画 ...
xor eax,eax
ret
;********************************************************************
; .elseif eax == WM_ERASEBKGND
;********************************************************************
; 以下黑屏的代码在 DefScreenSaverProc 中已经包括,如果自己要处理
; 屏幕,可以把它去掉。
;********************************************************************
; invoke GetDC,hWnd
; mov @hDc,eax
; invoke GetClientRect,hWnd,addr @stRc
; invoke GetStockObject,BLACK_BRUSH
; invoke FillRect,@hDc,addr @stRc,eax
; invoke ReleaseDC,hWnd,@hDc
; xor eax,eax
; ret
.endif
;********************************************************************
invoke DefScreenSaverProc,hWnd,uMsg,wParam,lParam
ret
ScreenSaverProc endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 注册设置对话框窗口Class过程
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
RegisterDialogClasses proc uses ebx edi esi, hInst:DWORD
mov eax,TRUE
ret
RegisterDialogClasses endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end WinMain
以上是一个屏幕保护程序的框架结构,其实编写一个屏幕保护程序的大部分工作量在于 WM_TIMER 消息的处理,也就是说对动画的处理,如果就把上面的程序编译,那么你就会得到一个最简单的“黑屏”屏保。这里是我编写的一个屏保月下情人,是用 Win32Asm 编写的。
更多精彩
赞助商链接