Sign in to follow this  
Followers 0

Sending WM_SETTINGCHANGE message to refresh desktop

9 posts in this topic

Hello everybody, this is my first post and I'm quite new to the world of AutoIt.

I already manage to change programmatically my desktop background via this one-liner:

DllCall("user32.dll", "int", "SystemParametersInfo", "int", 20, "int", 0, "str", $CmdLine[1], "int", 0)

(via drag 'n' drop of the desired wallpaper onto the compiled script).

However, this code does even too much for my needs. In fact I have another software that changes the desktop but, for some unknown-to-me reasons, fails to send the WM_SETTINGCHANGE message (I can see the key HKCU\Control Panel\Desktop\Wallpaper getting updated in fact, by the way).

So I ask you: how can I write a simple script that sends this message and thus triggers the wallpaper refresh? And will it work or the first script is the only "real"/"correct" way to proceed programmatically?

I tried this but it doesn't work:


Global $MAX_VALUE_NAME = 1024
Global $HWND_BROADCAST = 0xffff
Global $SMTO_ABORTIFHUNG = 0x0002
Global $SMTO_NORMAL = 0x0000
Global $MSG_TIMEOUT = 5000

DllCall("user32.dll", "lresult", "SendMessageTimeoutW", _
"hwnd", $HWND_BROADCAST, _
"ptr", 0, _
"wstr", "Environment", _
"dword", $MSG_TIMEOUT, _
"dword_ptr*", 0)

Many thanks in advance to whomever will help me!

Share this post

Link to post
Share on other sites

#3 ·  Posted (edited)

Ok, that works fine, but is a full-fledged script well beyond my needs, as I wrote above even that one-liner does too much for me.

I'm just interested in sending the WM_SETTINGCHANGE message. Unfortunately these pages and are a bit too technical for me...

Edited by Marcooo

Share this post

Link to post
Share on other sites

I see I could use the function SendMessage function, too. However this code does nothing:

DllCall("user32.dll", "lresult", "SendMessage", _
"int", 0xffff, _
"int", 0x001a, _
"int", 0x0014, _
"str", "HKCUControl Panel")

0xffff is for broadcasting the message to every window, 0x001a stands for WM_SETTINGCHANGE, 0x0014 is the code for spi_setdeskwallpaper. The taskbar in Windows 7 flickers a little but the wallpaper doesn't change, why?

Share this post

Link to post
Share on other sites


Share this post

Link to post
Share on other sites

Why int int int str?

Why not hwnd uint wparam lparam?

Because it gives a parsing error

Share this post

Link to post
Share on other sites

I tried checking the error code with this:

$aResult = DllCall("user32.dll", "int", "PostMessage", "int", 0xffff, "int", 0x001a, "int", 0x0014, "str", "HKCUControl PanelDesktop")


and it returns 0.

So I should assume that WM_SETTINGCHANGE is really sent, yet it doesn't produce the effect I expect?

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  
Followers 0

  • Similar Content

    • elsemieni
      By elsemieni
      Hey hello.
      I came here with maybe too specific questions about uncommon things, but as people says, I don't lose anything trying to asking here 
      There's long time that I have a little "experimental" idea: Use windows desktop and it icon system like old videogame consoles (where "sprites" are used to draw things on screen, can be manipulated/animated to make interesting things happen). Some of that inspiration came from another experiments from demoscene.
      Researching the possibilities of doing something like that (maybe not so intense) I found that the Windows Desktop uses a GuiListView to show and arrange icons (and of course, AutoIt provides UDF's for that  ). So, I'm used that UDF to create dummy icons (not putting files on Desktop, just modifiying the "GUI layer" of desktop for put non-working icons), setting custom values like coordinates, name and Icon (from a list of loaded icons in the GuiListView).  As you can see in next image works well in Windows XP... even in Windows 95 (that's not the case from Windows Vista to 10, but I already posted another question here about that... anyways, for now I'm working that with a isolated XP machine... sigh).

      Another video doing an animation with that:
      How I make that custom icons? Here:
      $hWnd = ControlGetHandle("Program Manager", "", "[CLASS:SysListView32; INSTANCE:1]") $newItem = _GUICtrlListView_AddItem ( $hWnd, "TEST", 32 ) ; with an icon of index 32 _GUICtrlListView_SetItemPosition ( $hWnd, $newItem, 300, 300 ) ; set some example property. Put in X=300 Y=300 Okay, so the next phase was changing the icons with custom ones. And here starts the issues. As AutoIT help says, icons from GuiListView came from a loaded GUIImageList, which, seeing past images I conclude that it's already preloaded with some sort of most used icons (something like an icon cache?). But If I modify it (or create another GUIImageList and then put into the GuiListView) the icons became corrupted and replaced with blank ones. (can be reverted deleting IconCache.db, just like when windows shows wrong icons in desktop).
      How I change icons? Here
      $hImage = _GUIImageList_Create(48, 48, 5) ; create an image list for 48x48 icons $newIcon = _GUIImageList_AddIcon($imageList, @SystemDir & "\shell32.dll", 110) ; just adding a new icon in the image list _GUICtrlListView_SetImageList($hWnd, $hImage, 0) ; $hwnd is the desktop hwnd Another option as workaround for setting icons was getting the desktop GUIImageList, and modifiyng it directly. I otbtain a GUIImageList handle, but ... without any images inside! (That's strange beacuse, when I set desktop item icons without altering the GUIImageList, it applies correctly). And finally if I try to add new ones, it returns -1 with @error setted.
      How I'm trying to get  desktop GUIImageList? Here.
      $imageList = _GUICtrlListView_GetImageList ( $hWnd, 0 ) MsgBox(0,_GUIImageList_GetImageCount ( $imageList ), $imageList) ; getting image count and GUIImageList handle $newIcon = _GUIImageList_AddIcon($imageList, @SystemDir & "\shell32.dll", 110) ; adding icons without success So, what is the question? There's something wrong I'm doing while trying to set the new icon set on desktop? Or desktop icons work in different way than the rest of the GuiListView's? Or there's something really stupid that I can't saw before that corrupts the icons? 
      Also... if there's not known solution for that, do you have some idea for doing a workaround for that? Or another crazy idea? (Maybe putting real files instead dummy icons could be a solution ... a very slow one). Or even maybe (maybe not, I sure about that xD) do you want to help with this "experiment".
      Thanks in advance, have a good day  
    • Edie
      By Edie
      I'm using this method to draw a transparent image inside my window. It works, but not as expected. With that example - without minimize button or anything else and the _GDIPlus_GraphicsDrawImageRect inside the main loop -, it works, but when you need to refresh the window, like restoring it after minimized or when you drag some window above your autoit window, the draw just gone. How can I refresh the image, for example, when I display one MsgBox and minimize and restore the window with the MsgBox opened?
      Try the example below. Run the script and the image will show, then minimize and restore. Then click on the button, keep the MsgBox opened, minimize and restore... The image just disappears. How can I keep it?
    • k4rl3on
      By k4rl3on
      How can i make function _ExplorerGetSelectedItems get selecteds items on the Desktop?
      Func _ExplorerGetSelectedItems($sCabinetWClass="[CLASS:CabinetWClass]") Local $Ret = "" Local $aIndexes, $sSelected, $sSelected_Path Local $hSearch, $sCurrentFile $sSelected_Path = ControlGetText($sCabinetWClass, "", "Edit1") ConsoleWrite($sSelected_Path&@CRLF) $aIndexes = StringSplit(ControlListView($sCabinetWClass, "", "SysListView321", "GetSelected", 1), "|") If $aIndexes[0] = 1 And ($aIndexes[1] == "" Or $aIndexes[1] = 0) Then Return SetError(1, 0, 0) For $i = 1 To $aIndexes[0] $sSelected = ControlListView($sCabinetWClass, "", "SysListView321", "GetText", $aIndexes[$i]) $sCurrentFile = StringRegExpReplace($sSelected_Path, "\\+$", "") & "\" & $sSelected If Not FileExists($sCurrentFile) Then ;Search the extension for file... $hSearch = FileFindFirstFile($sCurrentFile & ".*") If $hSearch <> -1 Then $sSelected = FileFindNextFile($hSearch) FileClose($hSearch) EndIf EndIf ;Check if item is a directory If StringInStr(FileGetAttrib($sCurrentFile), "D") > 0 Then $sSelected = "*"&$sSelected $Ret = $Ret&$sSelected&Chr(10) Sleep(1) Next Return $Ret EndFunc  
    • Carm01
      By Carm01
      I have windows 10 64 bit pro with the latest versions of scite and installed. Not that it matters for this instance.
      My monitor resolution is 1920 x 1080 progressive with a refresh rate of 64 HZ ( more in a min on that )
      I have a Nvida gtx 960 card and an HP monitor
      Since moving to Windows 10 and this configuration ( latest drivers of course ) I am unable to see the " ControlSetText " being displayed under the standard 60HZ refresh rate in WIndows 10. On Windows 7 machines this is flawless and always had been. The ControlSetText is updated at an extremely fast rate. IF I change the resolution one notch lower in windows 10 the display displays the text like in Windows 7 60HZ refresh. IF I user the max resolution 1920 x 1080 @ 60 HZ nothing is displayed in Windows 10. IF I create a custom resolution profile and just change the refresh rate to 64HZ it displays normally in Windows 10.
      If I enable " GUIGetMsg() " it displays fine but processes very slow fyi
      I will place the relevant code below. I am wondering:
      1) what is the max refresh/update rate for ControlSetText ( fasted it can be updated )
      2) Could this be adjusted either in code without hampering processing speed
      3) Does this need to be addressed in AutoIT program itself as a bug ?
      #include <Array.au3> #include <File.au3> Local $aRetArray, $aArray local $sFilePath = @ScriptDir & "\info.txt" _FileReadToArray($sFilePath, $aRetArray) Local $aArray[UBound($aRetArray)] SplashTextOn("Percent Complete", "", 130, 40, -1, -1, 16, "") Local $a = 0 Local $hTimer = TimerInit() $bb = UBound($aRetArray) - 1 For $i = 1 To UBound($aRetArray) - 1 ; ;GUIGetMsg();prevent high cpu usage $line = $aRetArray[$i] If StringRight($line, 2) = " X" Then If $i = 1 Then $line1 = StringLen($line) - StringLen($aRetArray[$i]) $line2 = StringRight($line, $line1) $line3 = $aRetArray[$i] $line4 = $aRetArray[$i + 1] Else $line1 = StringLen($line) - StringLen($aRetArray[$i - 1]) $line2 = StringRight($line, $line1) $line3 = $aRetArray[$i - 1]; $line4 = $aRetArray[$i + 1]; EndIf $aArray[$a] = $i & "| " & $line3 & "| " & $line2 & "| " & $line4 $a = $a + 1 EndIf ControlSetText("Percent Complete", "", "Static1", Round((($i / $bb) * 100), 2)) Next Thanks in advance
    • ozmike
      By ozmike
      Hey could be interesting to the AutoIt devs out there 
      Will win32  apps (autoit apps)  work in the new windows 10 store? 
      Early days yet won't be in the initial win 10 release...
      Note  win32 apps are now called many things
      - desktop apps
      - CWA ( Classic Windows Apps - not country womens ..assoc. ) 
      - Project C(entenial) apps 
      These apps will not be sandboxed but NOT be allowed to run as admin , all files will be sandboxed installation handled through the store..
      blog link
      How does this affect autoit - ?
       following as not supported in Project C apps:
      “Windows NT Services”, “Things running in the kernel” (device drivers) “System Level Software” (anything not running in the user context) “Elevation”, meaning anything that causes a standard user to get a UAC prompt “will be blocked”. Using parts of other apps in your app, at least in version 1. John indicated that they would like to support extensibility and plug-ins, just probably not initially. The implication was that this might be a direct UWA thing and not specific to Project C, but we can’t be sure.
       following as supported in Project C apps:
      “COM” “WMI” “Networking” “Anything else a standard app does that isn’t in the system space”. I am guessing that there are a lot of other things that might end up in the ‘not supported’ list that you might have thought falls under the last item in the supported list but turns out is not supported, but we just don’t know yet:
      WMI Providers Windows Timed and Triggered Events (but they can write new UWA background triggers) Custom ETW Providers COM localsystem (out of process) running as the system to avoid UAC prompts Maybe DCOM Software Clients, Application Capabilities Shell Extensions, Browser Helper Objects, and the like