This is a little snippet for getting and setting the desktop wallpaper using the IActiveDesktop interface. It is written in GoAsm syntax and uses my CoInvoke macro which is attached to the snippet. The major advantage to using COM to do it instead of trying to change the value directly in the registry is that you can apply the changes immediately, something that cannot easily be done with a registry hack. Anyway thought there might be someone who found it interesting...

// declarations needed for the routines
IID_IActiveDesktop GUID <0f490eb00h, 01240h, 011d1h, 098h, 088h, 000h, 060h, 097h, 0deh, 0ach, 0f9h>
CLSID_ActiveDesktop GUID <075048700h, 0ef1fh, 011d0h, 098h, 088h, 000h, 060h, 097h, 0deh, 0ach, 0f9h>

SetDesktopWallpaperA FRAME pWallpaper,dwOptions
LOCAL pActiveDesktop :D
LOCAL swzBuffer[260] :W
LOCAL WPOptions[2] :D ;WALLPAPEROPT

/*
dwOptions should be one of the following values or -1 for no change
WPSTYLE_CENTER
WPSTYLE_TILE
WPSTYLE_STRETCH
*/

invoke MultiByteToWideChar,CP_ACP,0,,-1,ADDR swzBuffer,260

// Create an instance of the IActiveDesktop interface
invoke CoCreateInstance,ADDR CLSID_ActiveDesktop,0,CLSCTX_INPROC_SERVER, \
ADDR IID_IActiveDesktop,ADDR pActiveDesktop
test eax,eax
jnz >.ERROR

mov D, 8 ; SIZEOF WALLPAPEROPT
mov eax,
mov ,eax
test eax,eax
js >
CoInvoke(pActiveDesktop, IActiveDesktop.SetWallpaperOptions, offset WPOptions, 0)
:
CoInvoke(pActiveDesktop, IActiveDesktop.SetWallpaper, ADDR swzBuffer, 0)
CoInvoke(pActiveDesktop, IActiveDesktop.ApplyChanges, AD_APPLY_ALL)
CoInvoke(pActiveDesktop, IActiveDesktop.IUnknown.Release)

xor eax,eax ; return 0 (success)
RET

.ERROR
mov eax,-1 ; return error
RET
ENDF

GetDesktopWallpaperA FRAME lpOutput
LOCAL pActiveDesktop :D
LOCAL szBuffer[260] :B
LOCAL swzBuffer[260] :W
LOCAL WPOptions[2] :D ;WALLPAPEROPT

// Create an instance of the IActiveDesktop interface
invoke CoCreateInstance,ADDR CLSID_ActiveDesktop,0,CLSCTX_INPROC_SERVER, \
ADDR IID_IActiveDesktop,ADDR pActiveDesktop
test eax,eax
jnz >.ERROR

CoInvoke(pActiveDesktop, IActiveDesktop.GetWallpaper,offset swzBuffer,260,0)

mov D, 8
CoInvoke(pActiveDesktop, IActiveDesktop.GetWallpaperOptions,offset WPOptions,0)

invoke WideCharToMultiByte,CP_ACP,0,OFFSET swzBuffer,-1,,260,0,0

CoInvoke(pActiveDesktop, IActiveDesktop.IUnknown.Release)

mov eax, ; return the wallpaper options
RET

.ERROR
mov eax,-1 ; return error
RET
ENDF

// CoInvoke macro declaration
CoInvoke(%pInterface,%Method,%0,%1,%2,%3,%4,%5,%6,%7,%8,%9) = \
#IF ARGCOUNT = 12 \
push %9 \
#ENDIF \
#IF ARGCOUNT > 10 \
push %8 \
#ENDIF \
#IF ARGCOUNT > 9 \
push %7 \
#ENDIF \
#IF ARGCOUNT > 8 \
push %6 \
#ENDIF \
#IF ARGCOUNT > 7 \
push %5 \
#ENDIF \
#IF ARGCOUNT > 6 \
push %4 \
#ENDIF \
#IF ARGCOUNT > 5 \
push %3 \
#ENDIF \
#IF ARGCOUNT > 4 \
push %2 \
#ENDIF \
#IF ARGCOUNT > 3 \
push %1 \
#ENDIF \
#IF ARGCOUNT > 2 \
push %0 \
#ENDIF \
push [%pInterface] \
mov eax, [%pInterface] \
mov eax, \
add eax, %Method \
call

Posted on 2006-06-04 08:45:43 by donkey
Forgot to include the vtables...

Unknown STRUCT
  QueryInterface DD ?
  AddRef DD ?
  Release DD ?
Unknown ends

IActiveDesktop STRUCT
IUnknown Unknown <>

ApplyChanges DD ?
GetWallpaper DD ?
SetWallpaper DD ?
GetWallpaperOptions DD ?
SetWallpaperOptions DD ?
GetPattern DD ?
SetPattern DD ?
GetDesktopItemOptions DD ?
SetDesktopItemOptions DD ?
AddDesktopItem DD ?
AddDesktopItemWithUI DD ?
ModifyDesktopItem DD ?
RemoveDesktopItem DD ?
GetDesktopItemCount DD ?
GetDesktopItem DD ?
GetDesktopItemByID DD ?
GenerateDesktopItemHtml DD ?
AddUrl DD ?
GetDesktopItemBySource DD ?
ENDS
Posted on 2006-06-04 09:53:47 by donkey
Or you can just do this:

invoke SystemParametersInfo, SPI_SETDESKWALLPAPER, 0, offset strFile, SPIF_UPDATEINIFILE

The drawback - I guess it only accepts BMP pictures.

Can you work with other picture formats using your procedures?
Posted on 2006-06-04 14:25:43 by Milos
Hi Milos,

The major drawback with SystemParametersInfo is there is no SPI_GETDESKWALLPAPER for any of the 9x versions or NT, also I do not think it is possible to change the styles (stretch etc..) with SPI. I have not tried with anything but bitmaps.
Posted on 2006-06-04 14:29:56 by donkey