屏幕保护程序的编写
相关的例子:下载>>> 作者:谢平 于2008-7-19上传 

                                                                by 谢平

记得一两年之前试着用汇编语言编写屏幕保护程序的时候,本人还是一个菜菜的单细胞生物,当然现在也只是一个菜菜的多细胞生物而已0_0.

 

因为那时候比较的菜,所以当时我没有成功。其实问题出在程序中用到的ScrnSave.Lib文件,这次我用的是从vc 6.0COPY过来的,在附件里的ScrnSave.Libmasm中的要大的多,我们需要用附件中的替换掉masn中的那个lib文件。

 

关于屏幕保护的编写,罗老师在n (n>=6)年之前就已经专门作文阐述,这篇文章现在在网络上广为流传,家喻户晓,地址是http://211.90.241.130:22366/view.asp?file=71

 

本文不想浪费口水并污染大家的耳朵,其实是眼睛啦!~~附件里实现的是半个XP系统附带的那个图片浏览幻灯片屏幕保护程序,由于牵涉到图片的处理,所以偷懒使用了aogo.yeah.net 上的image.lib,这个库“灰常”好用,省了我不少功夫。

 

附件里一共包括screen.asm, screen.scr, screen.rc, image.inc, image.lib, scrnsave.lib等六个文件。代码没有什么技术含量,相信聪明的你肯定可以看明白的,目前程序只能显示jpgbmp两种最常见的图像文件。由于本两人没有足够的艺术头脑,所以做出的东东往往不够美观。您可以任意修改程序以使其臻于完美。

 

程序的具体思路如下,你应当先看罗老师的那篇教程,我的代码都是在他的基础上修改的。哎呀又要贴代码啦:

1.RegisterDialogClasses保持罗的代码不变化。

 

2.ScreenSaverConfigureDialog函数中,打开文件,保存设置的结果。设置对话框的运行效果如下,可以在文本框中输入合法的包含图片的路径。

 

 

 

结果保存在config.ini文件中,这个文件是由我们自己创建的,你也可以通过注册表传递设置的信息。

 

3.修改ScreenSaverProc函数代码

其中WM_CREATE消息响应中设置一个定时器

.elseif       eax ==     WM_CREATE

invoke     SetTimer,hWnd,TIMER,3000,NULL           ;set the timer

WM_DESTORY中,取消这个定时器,并退出程序

.elseif       eax ==     WM_DESTROY

invoke     KillTimer,hWnd,TIMER                      ;Kill the timer

invoke     ExitProcess,NULL

WM_TIMER消息响应中添加如下代码

.if     eax ==    WM_TIMER

                     ;擦除上次图片显示的矩形区域,不擦除影响美观

                     mov stRect.left,0     stRecr是一个结构,每次在WM_TIMER的最后修改

                     mov stRect.top,0     dwHeightdwWidth

                     push dwWidth

                  pop  stRect.right

                  push dwHeight

                  pop  stRect.bottom

                  invoke      GetDC,hWnd

                     mov hDC,eax

                     invoke     GetClientRect,hWnd,addr stRect

                     invoke     GetStockObject,BLACK_BRUSH ;使用黑画刷

                     invoke     FillRect,hDC,addr stRect,eax

                     invoke     ReleaseDC,hWnd,hDC

                    

                     config.ini中读取设置的路径

                     invoke     CreateFile,addr szConfigFile,GENERIC_READ,FILE_SHARE_READ,\

                                   0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0

                     .if    eax != INVALID_HANDLE_VALUE

                            mov @hNewFile,eax

                            invoke     ReadFile,@hNewFile,addr szPath,dwBufferSize,\

                                          addr @nNumOfBytesRead,NULL               

                            invoke     CloseHandle,@hNewFile

                     .endif

                    

                     ;先搜索所有的jpg文件,然后是bmp文件,这段代码出自罗的教材

                     .if    dwFlag == FIND_JPG

                            ;find every jpg file in the directory

                            .if    hFindFile == 0

                                   invoke     lstrlen,addr szPath

                                   .if    eax == 0   ;if the directory NULL,use the current directory

                                          invoke     GetCurrentDirectory,dwBufferSize,addr szPath

                                   .endif

                                   invoke     SetCurrentDirectory,addr szPath   ;this line is needed!!!

                                   mov dwFlag,FIND_JPG

                                   invoke     FindFirstFile,addr szFindJpg,addr stFindFileData

                                   .if    eax != INVALID_HANDLE_VALUE

                                          mov hFindFile,eax                              

                                   .endif             

                            .else

@@:

                                   invoke     FindNextFile,hFindFile,addr stFindFileData

                                   .if    eax == FALSE                                   

                                          invoke     FindClose,hFindFile

                                          mov hFindFile,0

                                          mov dwFlag,FIND_BMP

                                   .endif

                            .endif

                     .else               

                            ;find every bmp file in the directory

                            .if    hFindFile == 0

                                   invoke     lstrlen,addr szPath ;if the directory NULL,use the current directory

                                   .if    eax == 0

                                          invoke     GetCurrentDirectory,dwBufferSize,addr szPath

                                   .endif

                                   invoke     SetCurrentDirectory,addr szPath   ;this line is needed!!!

                                   mov dwFlag,FIND_JPG

                                   invoke     FindFirstFile,addr szFindBmp,addr stFindFileData

                                   .if    eax != INVALID_HANDLE_VALUE

                                          mov hFindFile,eax                              

                                   .endif             

                            .else

@@:

                                   invoke     FindNextFile,hFindFile,addr stFindFileData

                                   .if    eax == FALSE                                   

                                          invoke     FindClose,hFindFile

                                          mov hFindFile,0

                                          mov dwFlag,FIND_JPG

                                   .endif

                            .endif

                     .endif

                    

                     .if    stFindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY

                            jmp  @B          ;if a directory continue

                     .endif

                    

                     ;得到文件的全路径

                     invoke     lstrcpy,addr szPic,addr szPath

                     invoke     lstrcat,addr szPic,addr szSUB

                     invoke     lstrcat,addr szPic,addr stFindFileData.cFileName

                    

;加载图片文件

                     invoke BitmapFromFile,addr szPic        ;using the image.lib from aogo.yeah.net

                     .if eax!=0

                            mov hPic,eax

                     .endif

                    

                     ;显示图片

                     invoke     GetDC,hWnd

                     mov hDC,eax

                     invoke     CreateCompatibleDC,hDC

                     mov DC,eax

                     invoke     SelectObject,DC,hPic

                  invoke      GetObject,hPic, sizeof stBMP,addr stBMP

                  invoke      BitBlt,hDC,0,0,stBMP.bmWidth, \

stBMP.bmHeight,DC,0,0,SRCCOPY

                  invoke      ReleaseDC,hWnd,hDC

 

                  ;保存显示当前图片的矩形区域,待下次擦除

                  push stBMP.bmWidth

                  pop  dwWidth

                  push stBMP.bmHeight

                  pop  dwHeight

使用生成常规可执行程序的方式编译链接,生成后将.exe文件的扩展名改为.scr,点右键选择配置将会出现上图的配置对话框,设置合法的路径保存会生成config.ini配置文件。程序运行的结果当然是显示指定目录下的图片文件,顺便提一下,可以使用以下代码激活屏幕保护程序:

                     .386

                     .model flat,stdcall

                     option casemap:none

include            windows.inc

include            user32.inc

includelib               user32.lib

include            kernel32.inc

includelib               kernel32.lib

                     .code

start:       

                     invoke    SendMessage, HWND_BROADCAST,\

WM_SYSCOMMAND,SC_SCREENSAVE,0

                     invoke     ExitProcess,0

end  start

 

PS

由于image.Lib是专门为masm32 v8而写的,作者的源代码中包含头文件的部分是这样子写的:

Include    \masm32\lib\user32.lib

Include    \masm32\lib\masm32.lib

Include    \masm32\lib\kernel32.lib

Include    \masm32\lib\gdi32.lib

Include    \masm32\lib\ole32.lib

Include    \masm32\lib\oleaut32.lib

Include    \masm32\lib\COMCTL32.LIB\masm32\lib\user32.lib

\masm32\lib\masm32.lib

\masm32\lib\kernel32.lib

\masm32\lib\gdi32.lib

\masm32\lib\ole32.lib

\masm32\lib\oleaut32.lib

\masm32\lib\COMCTL32.LIB

\masm32\lib\user32.lib

\masm32\lib\masm32.lib

\masm32\lib\kernel32.lib

\masm32\lib\gdi32.lib

\masm32\lib\ole32.lib

\masm32\lib\oleaut32.lib

\masm32\lib\COMCTL32.LIB

 

其实这种写法是和路径有一定关系的,因为必须存在\masm32\lib目录,如果没有这个目录会出现麻烦。

所以我一般的写法是这样的

Include    user32.lib

Include    masm32.lib

Include    kernel32.lib

Include    gdi32.lib

Include    ole32.lib

Include    oleaut32.lib

Include    COMCTL32.LIB\masm32\lib\user32.lib

\masm32\lib\masm32.lib

\masm32\lib\kernel32.lib

\masm32\lib\gdi32.lib

\masm32\lib\ole32.lib

\masm32\lib\oleaut32.lib

\masm32\lib\COMCTL32.LIB

\masm32\lib\user32.lib

\masm32\lib\masm32.lib

\masm32\lib\kernel32.lib

\masm32\lib\gdi32.lib

\masm32\lib\ole32.lib

\masm32\lib\oleaut32.lib

\masm32\lib\COMCTL32.LIB

 

这样的话就和路径无关了,(因为使用的是当前目录)。

这个问题产生的后果是,使用masmPlus无法正常链接。感谢Ziv同志发现这个问题。

 

这个问题的解决办法是:

1.        我尝试给作者(ernie@surfree.com)发信件,请求作者修改源代码并重新build,可是系统提示“发送失败“。

2.        无奈之下,我只好手动修改image.lib文件,希望作者不要因为版权的问题给我发来一份法院的传单^_^。如果懂得lib文件格式的话其实修改很容易。在这里略去。在附件里有image.lib和修改之前的image.Lib文件,有兴趣可以比较一下这两个文件。

 



<<<上一篇
欢迎访问AoGo汇编小站:http://www.aogosoft.com
下一篇>>>