使用SystemParametersInfo桌面的时候,用法如下:

invoke SystemParametersInfo,SPI_SETDESKWALLPAPER,0,offset szPath,SPIF_UPDATEINIFILE



最近帮朋友写了一个随机换桌面背景的小程序,发现这个函数一个很关键的问题,需要了解的朋友接着往下看,高手安静的飘过吧,别说我垃圾就行……哈哈



程序源代码如下(使用win32汇编,IDE是RADASM):

  .386
  .model flat,stdcall
  option casemap:none
;※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
include  windows.inc
include  kernel32.inc
includelib kernel32.lib
include  user32.inc
includelib user32.lib
include  Stdlib.Inc
includelib Stdlib.lib
;※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
ICO_MAIN equ 1000h
;※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
  .const
szPathBmp db 'C:/DesktopWall/*.bmp',0
szPathJpg db 'C:/DesktopWall/*.jpg',0

;szPathBmp db '*.bmp',0
;szPathJpg db '*.jpg',0
szError  db '未找到任何bmp和jpg的文件',0dh,0ah,
   '程序将退出',0dh,0ah,
   '谢谢使用',0dh,0ah,
   'BY:GLCWOLF',0
szErrorCap db '查找图片失败',0
  .data
szTest1  db '%d',0
szTest2  db '%s',0
szBufferTest db 128 dup (?)
szPath  db 'C:/DesktopWall/',0
  .data?
dwCount  dd ?
hFindFile  dd ?
szBuffer  db 256  dup (?)
szName  db MAX_PATH dup (?)
szBufferName db 100000 dup(?)
dwRand  dd ?
dwFileCount dd ?
dwAddr  dd ?
stWin32FindData WIN32_FIND_DATA <?>
dwNameAddr dd ?
  .code
_FindBmpFiles proc uses esi;查找bmp文件
  invoke FindFirstFile,offset szPathBmp,offset stWin32FindData 
  .if eax != INVALID_HANDLE_VALUE ;如果找到第一个bmp文件,保存句柄,进行FindNextFile
   mov hFindFile,eax
   mov esi,offset szBufferName
   .while TRUE
    inc dwCount
    invoke StrCpy,esi,offset stWin32FindData.cFileName   ;把找到的文件的文件名拼接到缓存区里
    add esi,sizeof stWin32FindData.cFileName
    mov dwNameAddr,esi
    invoke FindNextFile,hFindFile,offset stWin32FindData
    .break .if  eax ==  FALSE
   .endw
   invoke FindClose,hFindFile ;关闭文件句柄
  .endif
  ret
_FindBmpFiles  endp
;※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
_FindJpgFiles proc uses esi;注释类似与_FindBmpFiles
  .if dwCount ==0
   mov esi,offset szBufferName    ;如果没找到BMP图片,那么把缓存区的地址给esi
  .else
   mov esi,dwNameAddr  ;如果找到了BMP,那么接着找到的BMP文件的后面放置JPG的文件名
  .endif
  invoke FindFirstFile,offset szPathJpg,offset stWin32FindData 
  .if eax != INVALID_HANDLE_VALUE
   mov hFindFile,eax
   .while TRUE
    inc dwCount
    invoke StrCpy,esi,offset stWin32FindData.cFileName
    add esi,sizeof stWin32FindData.cFileName
    invoke FindNextFile,hFindFile,offset stWin32FindData
    .break .if  eax ==  FALSE
   .endw
   invoke FindClose,hFindFile 
  .endif
  
  ret
_FindJpgFiles  endp
;※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
_ChangeWall proc
  invoke Randomize
  invoke Random,dwCount                   ;产生随机数
  mov ebx,sizeof stWin32FindData.cFileName
  mul ebx   ;这里有个问题:我把MAX_PATH长度的文件名,放到缓存区里面,但是缓存区是以实际长度来
  mov ebx,offset szBufferName ;存储文件名的,不是以MAX_PATH长度来存储的,那么,想取出缓存区里任意一个文件名的
  add eax,ebx   ;的话,应该如何操作呢?想了一天了,还是没想明白……初学者……
;  push eax
;  invoke wsprintf,offset szBufferTest,offset szTest2,eax
;  invoke MessageBoxA,NULL,offset szBufferTest,0,MB_OK
;  pop eax
  invoke StrCat,offset szPath,eax
  invoke SystemParametersInfo,SPI_SETDESKWALLPAPER,0,offset szPath,SPIF_UPDATEINIFILE
  ret
_ChangeWall  endp
_ErrorInfo proc
  invoke MessageBox,NULL,offset szError,offset szErrorCap,MB_OK
  invoke ExitProcess,NULL 
  ret
_ErrorInfo  endp
;※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※

;※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
start:  invoke LoadIcon,NULL,ICO_MAIN
  invoke SendMessage,NULL,WM_SETICON,ICON_BIG or ICON_SMALL,eax
  call _FindBmpFiles
  call _FindJpgFiles
  .if dwCount > 0
   call _ChangeWall
  .else
   call _ErrorInfo
  .endif
  invoke ExitProcess,NULL 
;  invoke OleLoadPicture,
;  invoke CopyImage,
  end start



程序很小,也没什么技术含量,主要说一下SystemParametersInfo函数在设置桌面背景的时候一点注意事项。

用法已经在文章开始的时候说明,其中szPath是程序中用FindFirstFile以及FindNextFile找到的文件名,然后我把这些文件名保存到了一个缓存区中,不过,这里要注意,这里保存的仅仅是文件名,不包含文件路径,但是使用SystemParametersInfo函数设置桌面的时候,文件名需要是完整的,也就是说要包含路径,所以,在使用文件名的设置背景的时候,先要用如下代码进行字符串的拼接:

invoke StrCat,offset szPath,eax

这样才可以正确设置桌面。



当然,如果你只是查找和你的EXE文件在相同目录的图片文件时,可以不使用字符串拼接。



这个小屁程序,在XP系统中只支持BMP图片,不过在win7系统中,还是支持的,应该是win7系统帮我们把jpb等文件自动转换成BMP了吧,只是猜测,呵呵……



在网上看到了如何让程序支持JPG等文件的方法,不过,看不懂,呵呵,刚接触程序,以后再慢慢学吧。

还遇到一个问题是关于Random这个函数,当给它参数是2的时候,只产生1,没有0,或许可能出现0吧,但是几率很小吧,反正我实验了上百次,都没有出现0的情况……很神奇的函数。看雪的朋友也帮说了半天,不过才疏学浅,实在搞不懂……邪恶的数学啊!!!唉!!!



希望这篇文章对和我一样的小鸟们有帮助!!大牛们多多关照哦,哈哈!!!

  • 标 题:关于使用SystemParametersInfo设置背景桌面的问题一点点心得
  • 作 者:GLCWOLF
  • 时 间:2011-10-07 10:47:35

使用SystemParametersInfo桌面的时候,用法如下:

invoke SystemParametersInfo,SPI_SETDESKWALLPAPER,0,offset szPath,SPIF_UPDATEINIFILE



最近帮朋友写了一个随机换桌面背景的小程序,发现这个函数一个很关键的问题,需要了解的朋友接着往下看,高手安静的飘过吧,别说我垃圾就行……哈哈



程序源代码如下(使用win32汇编,IDE是RADASM):

  .386
  .model flat,stdcall
  option casemap:none
;※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
include  windows.inc
include  kernel32.inc
includelib kernel32.lib
include  user32.inc
includelib user32.lib
include  Stdlib.Inc
includelib Stdlib.lib
;※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
ICO_MAIN equ 1000h
;※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
  .const
szPathBmp db 'C:/DesktopWall/*.bmp',0
szPathJpg db 'C:/DesktopWall/*.jpg',0

;szPathBmp db '*.bmp',0
;szPathJpg db '*.jpg',0
szError  db '未找到任何bmp和jpg的文件',0dh,0ah,
   '程序将退出',0dh,0ah,
   '谢谢使用',0dh,0ah,
   'BY:GLCWOLF',0
szErrorCap db '查找图片失败',0
  .data
szTest1  db '%d',0
szTest2  db '%s',0
szBufferTest db 128 dup (?)
szPath  db 'C:/DesktopWall/',0
  .data?
dwCount  dd ?
hFindFile  dd ?
szBuffer  db 256  dup (?)
szName  db MAX_PATH dup (?)
szBufferName db 100000 dup(?)
dwRand  dd ?
dwFileCount dd ?
dwAddr  dd ?
stWin32FindData WIN32_FIND_DATA <?>
dwNameAddr dd ?
  .code
_FindBmpFiles proc uses esi;查找bmp文件
  invoke FindFirstFile,offset szPathBmp,offset stWin32FindData 
  .if eax != INVALID_HANDLE_VALUE ;如果找到第一个bmp文件,保存句柄,进行FindNextFile
   mov hFindFile,eax
   mov esi,offset szBufferName
   .while TRUE
    inc dwCount
    invoke StrCpy,esi,offset stWin32FindData.cFileName   ;把找到的文件的文件名拼接到缓存区里
    add esi,sizeof stWin32FindData.cFileName
    mov dwNameAddr,esi
    invoke FindNextFile,hFindFile,offset stWin32FindData
    .break .if  eax ==  FALSE
   .endw
   invoke FindClose,hFindFile ;关闭文件句柄
  .endif
  ret
_FindBmpFiles  endp
;※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
_FindJpgFiles proc uses esi;注释类似与_FindBmpFiles
  .if dwCount ==0
   mov esi,offset szBufferName    ;如果没找到BMP图片,那么把缓存区的地址给esi
  .else
   mov esi,dwNameAddr  ;如果找到了BMP,那么接着找到的BMP文件的后面放置JPG的文件名
  .endif
  invoke FindFirstFile,offset szPathJpg,offset stWin32FindData 
  .if eax != INVALID_HANDLE_VALUE
   mov hFindFile,eax
   .while TRUE
    inc dwCount
    invoke StrCpy,esi,offset stWin32FindData.cFileName
    add esi,sizeof stWin32FindData.cFileName
    invoke FindNextFile,hFindFile,offset stWin32FindData
    .break .if  eax ==  FALSE
   .endw
   invoke FindClose,hFindFile 
  .endif
  
  ret
_FindJpgFiles  endp
;※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
_ChangeWall proc
  invoke Randomize
  invoke Random,dwCount                   ;产生随机数
  mov ebx,sizeof stWin32FindData.cFileName
  mul ebx   ;这里有个问题:我把MAX_PATH长度的文件名,放到缓存区里面,但是缓存区是以实际长度来
  mov ebx,offset szBufferName ;存储文件名的,不是以MAX_PATH长度来存储的,那么,想取出缓存区里任意一个文件名的
  add eax,ebx   ;的话,应该如何操作呢?想了一天了,还是没想明白……初学者……
;  push eax
;  invoke wsprintf,offset szBufferTest,offset szTest2,eax
;  invoke MessageBoxA,NULL,offset szBufferTest,0,MB_OK
;  pop eax
  invoke StrCat,offset szPath,eax
  invoke SystemParametersInfo,SPI_SETDESKWALLPAPER,0,offset szPath,SPIF_UPDATEINIFILE
  ret
_ChangeWall  endp
_ErrorInfo proc
  invoke MessageBox,NULL,offset szError,offset szErrorCap,MB_OK
  invoke ExitProcess,NULL 
  ret
_ErrorInfo  endp
;※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※

;※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
start:  invoke LoadIcon,NULL,ICO_MAIN
  invoke SendMessage,NULL,WM_SETICON,ICON_BIG or ICON_SMALL,eax
  call _FindBmpFiles
  call _FindJpgFiles
  .if dwCount > 0
   call _ChangeWall
  .else
   call _ErrorInfo
  .endif
  invoke ExitProcess,NULL 
;  invoke OleLoadPicture,
;  invoke CopyImage,
  end start



程序很小,也没什么技术含量,主要说一下SystemParametersInfo函数在设置桌面背景的时候一点注意事项。

用法已经在文章开始的时候说明,其中szPath是程序中用FindFirstFile以及FindNextFile找到的文件名,然后我把这些文件名保存到了一个缓存区中,不过,这里要注意,这里保存的仅仅是文件名,不包含文件路径,但是使用SystemParametersInfo函数设置桌面的时候,文件名需要是完整的,也就是说要包含路径,所以,在使用文件名的设置背景的时候,先要用如下代码进行字符串的拼接:

invoke StrCat,offset szPath,eax

这样才可以正确设置桌面。



当然,如果你只是查找和你的EXE文件在相同目录的图片文件时,可以不使用字符串拼接。



这个小屁程序,在XP系统中只支持BMP图片,不过在win7系统中,还是支持的,应该是win7系统帮我们把jpb等文件自动转换成BMP了吧,只是猜测,呵呵……



在网上看到了如何让程序支持JPG等文件的方法,不过,看不懂,呵呵,刚接触程序,以后再慢慢学吧。

还遇到一个问题是关于Random这个函数,当给它参数是2的时候,只产生1,没有0,或许可能出现0吧,但是几率很小吧,反正我实验了上百次,都没有出现0的情况……很神奇的函数。看雪的朋友也帮说了半天,不过才疏学浅,实在搞不懂……邪恶的数学啊!!!唉!!!



希望这篇文章对和我一样的小鸟们有帮助!!大牛们多多关照哦,哈哈!!!