Results 1 to 22 of 22

Thread: re: help with wallpaper changer code(changing reg and win.ini doesn't work properly)

  1. #1

    Thread Starter
    New Member
    Join Date
    May 2000
    Posts
    14

    Question

    i'm trying to write a wallpaper changer so that i can put it into the startup menu folder so that everytime it starts up the wallpaper will change next time to another one.

    I've tried to edit the reg but win 98 keeps updating the changes i've made to the "desktop folder", when i only want it to change next time i startup win. Instead i've tried to edit the win.ini file but for some reason win 98 doesn't want to load the part "wallpaper=.." so what's the point of having it? Maybe i can change the reg right b4 i shutdown? or else maybe there's some other win file that stores the current wallpaper options?

    Any suggestions would be appreciated

  2. #2
    Guru Yonatan's Avatar
    Join Date
    Apr 1999
    Location
    Israel
    Posts
    892

    Lightbulb In the registry, not in the INI files.

    Actually, the Wallpaper= thing in the INI Files is just there for compatibility with old programs. The wallpaper location is loaded from the registry:
    HKEY_CURRENT_USER\Control Panel\Desktop\Wallpaper
    This is set to the filename of the BMP thingie where your coolio wallpaper is.
    Almost every Monday there is also a neato thing there:
    HKEY_CURRENT_USER\Control Panel\Desktop\WallpaperStyle
    This can be "0" - Center or "1" - Tile. (Windows 98: "2" - Stretch)

    And finally, here is how to set these things:
    (This code really loves living in modules! So put it in a module and it will work happily!)
    Code:
    Declare Function RegCreateKey Lib "advapi32.dll" Alias "RegCreateKeyA" (ByVal hKey As Long, ByVal lpSubKey As String, phkResult As Long) As Long
    Declare Function RegSetValueEx Lib "advapi32.dll" Alias "RegSetValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal Reserved As Long, ByVal dwType As Long, lpData As Any, ByVal cbData As Long) As Long
    Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long
    
    Public Const HKEY_CURRENT_USER = &H80000001
    Public Const REG_SZ = 1
    
    Sub ChangeWallpaperThingie(ByVal sWhatToChange As String, ByVal sNewValue As String)
        Dim hKey As Long
        If Not RegCreateKey(HKEY_CURRENT_USER, "\Control Panel\Desktop", hKey) = 0 Then Exit Sub
        Call RegSetValueEx(hKey, sWhatToChange, 0, REG_SZ, ByVal sNewValue, Len(sNewValue))
        Call RegCloseKey(hKey)
    End Sub
    This should be enough to alter your registry. I would say don't try this at home but how would you get it to work otherwise? What I'm saying is, don't mess with the registry unless you know what you're doing or if you got the code from someone who told you to not mess with the registry unless you know what you're doing.

    This is how you use the code carefully without any crashes or anything weird hopefully:

    Call ChangeWallpaperThingie("Wallpaper", "C:\Windows\Clouds.bmp")
    This will set the wallpaper to Clouds.bmp.

    Call ChangeWallpaperThingie("WallpaperStyle", "1")
    This will set the wallpaper style to Tiled.
    Instead of "1", use "0" for Centered or "2" (Windows 98 and maybe other nifty versions of the somewhat-horrible OS) Stretch.

    To make the wallpaper and wallpaper style take effect, you must convince the user to restart. Or do it yourself:
    (Remember how my code loves modules!)
    Code:
    Declare Function ExitWindowsEx Lib "user32" Alias "ExitWindowsEx" (ByVal uFlags As Long, ByVal dwReserved As Long) As Long
    
    Public Const EWX_REBOOT = 2
    
    Sub RebootWindows()
        Call ExitWindowsEx(EWX_REBOOT, 0)
    End Sub
    Call RebootWindows
    This will do the job.

    P.S.
    About the whole "WallpaperStyle" thing... Maybe, I don't know anymore, nothing there works on versions earlier than 98. If that is the case, instead of "WallpaperStyle use "TileWallpaper" and make it "0" for Center or "1" for Tile.

  3. #3

    Thread Starter
    New Member
    Join Date
    May 2000
    Posts
    14

    re: thanks man!

    One word, "Superb!"

    Hoping that ur code would work and not stuff up the reg i decided to give it a go.

    What the code seems to do is edit the reg without windows update the changes, until it is rebooted.
    What I tried earlier to do was to change the reg key "HKEY_CURRENT_USER\Control Panel\Desktop\Wallpaper" using .reg and .inf files but then windows would notice the changes and after a while update the changes, without having to reboot(which is what i didn't want!). Also, i might as well remove the part abt modifying the win.ini as it's not commonly used.

    Thank you for ur code and now i can have random wallpaper images every time i reboot!

    Thanks heaps!
    Using VB5

  4. #4

    Thread Starter
    New Member
    Join Date
    May 2000
    Posts
    14

    Smile re: just to complicate matters

    Just to complicate matters how do i update the "active desktop" so i can display internet pictures(.jpg, .gif), instead of .bmp? I'm making a wallpaper changer and .bmp files works fine.
    Using VB5

  5. #5
    Hyperactive Member
    Join Date
    Jan 1999
    Location
    Rotterdam, Netherlands
    Posts
    386
    I don't have my code here, but you don't need to reboot to change the wallpaper! All you need to do after setting is send a global windowsmessage WM_WININICHANGED.
    If I remember it when I come home tonite I'll check my code and post it, I made a wallpaper changer which changed the wallpaper with a specified interval, and that worked perfectlty without rebooting.
    Oh and I think I used the SystemParametersInfo API to change the wallpaper, not writing directly in the registry (one of the constants you can use with that is SPI_SETDESKWALLPAPER, check MSDN for more info).
    Hope this helps

    Crazy D

  6. #6

    Thread Starter
    New Member
    Join Date
    May 2000
    Posts
    14
    Cripes!, now that i think abt it, whenever i startup "win 98" i should then randomly select a jpg and update the changes on the desktop straight away insead of future updating, sorry if this doesn't make sense, i was just thinking abt teh order of updating, it's clear to me now i should update straight away to a new jpg image whenever i boot up!

    Ok, so i've tried the following code right and that still isn't enough to make the changes straight away! It only changes whenever i refresh the desktop or open win explorer!

    Code:
    Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA" (ByVal uAction As Long, _
    ByVal uParam As Long, ByVal lpvParam As Any, ByVal fuWinIni As Long) As Long
    Declare Function RegCreateKey Lib "advapi32.dll" Alias "RegCreateKeyA" (ByVal hKey As Long, ByVal lpSubKey As String, phkResult As Long) As Long
    Declare Function RegSetValueEx Lib "advapi32.dll" Alias "RegSetValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal Reserved As Long, ByVal dwType As Long, lpData As Any, ByVal cbData As Long) As Long
    Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long
    
    Public Const SPIF_SENDWININICHANGE = &H2
    Public Const SPIF_UPDATEINIFILE = &H1
    Public Const SPI_SETDESKWALLPAPER = 20
    Public Const HKEY_CURRENT_USER = &H80000001
    Public Const REG_SZ = 1
    
    Sub ChangeWallpaperThingie(ByVal sWhatToChange As String, ByVal sNewValue As String)
        'Update the changes in the reg
        Dim hKey As Long
        If Not RegCreateKey(HKEY_CURRENT_USER, "\Control Panel\Desktop", hKey) = 0 Then Exit Sub
        Call RegSetValueEx(hKey, sWhatToChange, 0, REG_SZ, ByVal sNewValue, Len(sNewValue))
        Call RegCloseKey(hKey)
        
        'Update the changes on the desktop straight away
        If sWhatToChange = "Wallpaper" Then
         Dim LTemp As Long
         LTemp = SystemParametersInfo(SPI_SETDESKWALLPAPER, 0&, sNewValue, SPIF_UPDATEINIFILE Or SPIF_SENDWININICHANGE)
        End If
    End Sub
    Using VB5

  7. #7
    Hyperactive Member
    Join Date
    Jan 1999
    Location
    Rotterdam, Netherlands
    Posts
    386
    Check MSDN for WM_WININICHANGE (oh I just read that has been replaced by WM_SETTINGCHANGE). no time to try it, but it sounds like it is usefull
    Hope this helps

    Crazy D

  8. #8

    Thread Starter
    New Member
    Join Date
    May 2000
    Posts
    14
    Ok, so the wallpaper doesn't change when explorer was opened, but definately after refreshing the desktop. Is there a function i can call to refresh the desktop right after my changes? This would complete my code.

    Also, i'm trying to scan the number of picture files in a directory so that i can calculate the number of possible choosen wallpapers. I'm having to search for all the files, while counting each one. Then i find a random number and search the picture files again to see what that file was. I don't like having arrays where u have to guess the initial size b4 storing each file when i'm scanning. I could start off with an intial size of 1 then dynamically allocate new pics found again using temp arrays but that sux.

    So, i would like to know how to find the number of pic files by just doing what i could type in dos "*.jpg" and it returns the number of files!
    Unfortunately, i can't find anything that i can use(e.g. dir and shell don't return the number of files)!
    Using VB5

  9. #9
    Fanatic Member
    Join Date
    Jan 2000
    Location
    Nitro
    Posts
    633

    This will change your wall paper imediately!

    Here is a faster way to set the wall paper.

    Code:
    Option Explicit
    
    Public Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA" (ByVal uAction As Long, ByVal uParam As Long, ByVal lpvParam As Any, ByVal fuWinIni As Long) As Long
    Public Const SPI_SCREENSAVERRUNNING = 97
    Public Const SPI_SETDESKWALLPAPER = 20
    Public Const SPIF_SENDWININICHANGE = &H2
    Public Const SPIF_UPDATEINIFILE = &H1
    
    Sub p_WallPaper()
      ' PURPOSE: Send the current picture to the clipboard
      Clipboard.SetData LoadPicture("C:\Whatever.bmp"), vbCFBitmap
    
      DoEvents
      
      ' PURPOSE: Save the clipboard picture
      SavePicture Clipboard.GetData(vbCFBitmap), "C:\Test.bmp"
      
      ' PURPOSE:Change the wallpaper
      Call SystemParametersInfo(SPI_SETDESKWALLPAPER, True, "C:\Test.bmp", SPIF_UPDATEINIFILE Or SPIF_SENDWININICHANGE)
    End Sub
    If you want to load a jpg, load it into a image control and do a Savepicture.
    Chemically Formulated As:
    Dr. Nitro

  10. #10
    Hyperactive Member
    Join Date
    Jan 1999
    Location
    Rotterdam, Netherlands
    Posts
    386
    You can use a collection to store the names of the files.
    Or, use an array, redim it per 100 (or whatever number you want), use a counter, and at the end, redim the array again with the correct number of files (the counter). And you have the number of files too with that counter. If you don't want to store the filenames, but just want to count, you uhmm need the counter.... AFAIK there's no way to get a count (DOS uses a counter internal too).
    I'm going to forget... mail me at [email protected] and I'll check my code tonite, I don't understand why you're having problems with refreshing the desktop etc.
    Hope this helps

    Crazy D

  11. #11

    Thread Starter
    New Member
    Join Date
    May 2000
    Posts
    14
    I loaded a .jpg into the clipboard and it saved it as a bmp, but it's just that SystemParametersInfo function that's not updating the changes instantly, stil lneeds to refresh the wallpaper

    Code:
    Call SystemParametersInfo(SPI_SETDESKWALLPAPER, True, "C:\Test.bmp", SPIF_UPDATEINIFILE Or SPIF_SENDWININICHANGE)
    End Sub
    I've tried the following to try to update the desktop or whatever! but it doesn't work and it's just confusing!

    Code:
    Declare Function SendMessageTimeout Lib "user32" Alias "SendMessageTimeoutA" (ByVal hwnd As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long, ByVal fuFlags As Long, ByVal uTimeout As Long, lpdwResult As Long) As Long
    
    Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA" (ByVal uAction As Long, _
    ByVal uParam As Long, ByVal lpvParam As Any, ByVal fuWinIni As Long) As Long
    Declare Function RegCreateKey Lib "advapi32.dll" Alias "RegCreateKeyA" (ByVal hKey As Long, ByVal lpSubKey As String, phkResult As Long) As Long
    Declare Function RegSetValueEx Lib "advapi32.dll" Alias "RegSetValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal Reserved As Long, ByVal dwType As Long, lpData As Any, ByVal cbData As Long) As Long
    Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long
    
    Public Const HWND_BROADCAST = &HFFFF&
    Public Const SPI_SETNONCLIENTMETRICS = &H2A
    Public Const SMTO_ABORTIFHUNG = &H2
    Public Const SMTO_NORMAL = &H0
    
    Public Const WM_SETTINGCHANGE As Long = &H1A
    Public Const SPIF_UPDATEINIFILE = &H1
    Public Const SPI_SETDESKWALLPAPER = 20
    
    Public Const HKEY_CURRENT_USER = &H80000001
    Public Const REG_SZ = 1
    
    Sub ChangeWallpaperThingie(ByVal sWhatToChange As String, ByVal sNewValue As String)
        'Update the changes in the reg
        Dim hKey As Long
        If Not RegCreateKey(HKEY_CURRENT_USER, "\Control Panel\Desktop", hKey) = 0 Then Exit Sub
        Call RegSetValueEx(hKey, sWhatToChange, 0, REG_SZ, ByVal sNewValue, Len(sNewValue))
        Call RegCloseKey(hKey)
        
        'Update the changes on the desktop
        If sWhatToChange = "Wallpaper" Then
         Call SystemParametersInfo(SPI_SETDESKWALLPAPER, 0&, sNewValue, SPIF_UPDATEINIFILE Or WM_SETTINGCHANGE)
         
         ''''''''''''''''''''''''
         '6. broadcast the fact passing SPI_SETNONCLIENTMETRICS,
         'with a timeout of 10000 milliseconds (10 seconds)
         Call SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, SPI_SETDESKWALLPAPER, 0&, SMTO_ABORTIFHUNG, 10000&, success)
        End If
        
    End Sub
    Using VB5

  12. #12

    Thread Starter
    New Member
    Join Date
    May 2000
    Posts
    14
    Here is also my Form code if anyone is interested.
    I know it sux at this point but just trying to get the wallpaper to change instantly is a hassle.

    Code:
    Private Sub Form_Load()
    'Wallpaper Changer for Win 95/ and 98?
    'Only works if the desktop is refreshed
    '
    'Modifies the reg keys
    '
    '1)Put the ChangeWallpaper.exe into the directory of the pictures you want to show
    '2)In windows, make ChangeWallpaper.exe as a "shortcut" and place it in the "StartUp Menu"
    
    'Setup paths/file names
    currentPath$ = CurDir  ' Returns current path.
    
    'Global counter for all picture files found in current directory
    c = 0
    
    'Find all .jpg files in the current directory
    jpgFile$ = Dir(currentPath + "\*.JPG")
    If jpgFile$ <> "" Then c = 1
    Do
     jpgFile$ = Dir
     If jpgFile$ = "" Then Exit Do
     c = c + 1
    Loop
    
    'Check if any picture files were found.
    'Otherwise don't continue
    If c = 0 Then
     Response = MsgBox("No picture files found in" + currentPath + " !", vbCritical)
     End
    End If
    
    'Randomly choose a wallpaper
    Randomize
    rWallpaper = Int(Rnd * c) + 1 Mod (997)
    
    
    'Find all .jpg files in the current directory
    'where w$ is the wallpaper selected
    jpgFile$ = Dir(currentPath + "\*.JPG")
    If jpgFile$ <> "" And rWallpaper = 1 Then
     w$ = jpgFile$
    Else
     For i = 2 To rWallpaper
      jpgFile$ = Dir
      w$ = jpgFile$
     Next
    End If
    
    Call ChangeWallpaperThingie("Wallpaper", currentPath + "\" + w$)
    'Call ChangeWallpaperThingie("WallpaperStyle", "2") '2 = stretch(win98)
    
    'End
    End Sub


    Using VB5

  13. #13

    Thread Starter
    New Member
    Join Date
    May 2000
    Posts
    14

    Unhappy oh man!

    actually, i've noticed more of an instant change with the wallpaper by refreshing it manually after i've set the reg keys. Just calling the SystemParametersInfo function is not enough. So close, yet so far...
    Using VB5

  14. #14

    Thread Starter
    New Member
    Join Date
    May 2000
    Posts
    14
    Sorry abt that Nitro, ur code does work without having to touch the reg directly but there's still no instant change after i ran the code.

    Using VB5

  15. #15

    Thread Starter
    New Member
    Join Date
    May 2000
    Posts
    14
    Cripes man, now the bastard works. Oh gez i must be going nuts! I just redid the code using nitros with some of mine and now it works for some reason.

    anyway here's why it works now:

    Code:
    Option Explicit
    
    Public Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA" (ByVal uAction As Long, ByVal uParam As Long, ByVal lpvParam As Any, ByVal fuWinIni As Long) As Long
    Public Const SPI_SETDESKWALLPAPER = 20
    Public Const SPIF_SENDWININICHANGE = &H2
    Public Const SPIF_UPDATEINIFILE = &H1
    
    Sub changeWallpaper(ByVal wallPaperPath As String, ByVal wallPaper As String)
      'Send the current picture to the clipboard
      Clipboard.SetData LoadPicture(wallPaperPath + "\" + wallPaper), vbCFBitmap
    
      DoEvents
      
      'Save the clipboard picture
      SavePicture Clipboard.GetData(vbCFBitmap), wallPaperPath + "\newWallPaper.bmp"
      
      'Change the wallpaper
      Call SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, wallPaperPath + "\newWallPaper.bmp", SPIF_UPDATEINIFILE Or SPIF_SENDWININICHANGE)
    End Sub
    In other words, it's very difficult to update the changes without using bmp files. u have to set the reg and then refresh somehow. What nitro has done is convert this .jpg baby to a bmp so then now it's easier for win to make the changes. Nitro left out some key code though. He forgot to add the line:

    Code:
    Call SystemParametersInfo(20, 0, wallPaperPath + "\newWallPaper.bmp", SPIF_UPDATEINIFILE Or SPIF_SENDWININICHANGE)
    Instead of:

    Code:
    Call SystemParametersInfo(20, 0, wallPaperPath + "\newWallPaper.bmp", 1)
    That "1" is incomplete and will not update the changes instantly unless u refresh the desktop.

    Anyway, thanks Nitro, good short prog stuff!

    I'll see if it still works tmr and the following weeks after that!



    Using VB5

  16. #16

    Thread Starter
    New Member
    Join Date
    May 2000
    Posts
    14
    Thanx all u guys for helping me out! REALLY appreciate that!
    If u want my help u can ask but i'm not very good in vb, mainly java.

    It's been a while trying to program in basic!
    Using VB5

  17. #17
    Fanatic Member
    Join Date
    Jan 2000
    Location
    Nitro
    Posts
    633

    You Welcome!

    You don't need to refresh anything using the method I posted earlier. It change on a fly.

    If you are trying to load a jpg file, load it into an image control first.

    Use the "SavePicture" function against the image control. It will be save as a bmp file.

    Then use the api to load the new bmp file.
    Chemically Formulated As:
    Dr. Nitro

  18. #18

    Thread Starter
    New Member
    Join Date
    May 2000
    Posts
    14
    Yup i've definitely shortened the searching methods for pictures right down!

    Just want to ask abt that "DoEvents" thing in your code. What does it do? Is it some sort of multitask thing?
    Using VB5

  19. #19

    Thread Starter
    New Member
    Join Date
    May 2000
    Posts
    14
    an image control? does it make the change abit faster?

    i used ur original code earlier on but just replaced the file to load as a jpg, saved to a bmp format. Kinda is a bit slow when converting to a 17" screen though.

    How would i implement this image control?
    Using VB5

  20. #20
    Fanatic Member
    Join Date
    Jan 2000
    Location
    Nitro
    Posts
    633
    Hello Sygon!

    The code that I posted was something I researched months ago. At the time, I was trying to get WYSIWYG on the screen using with an api "Key_event". However, api are sometime slow and the "SavePicture" function will just go ahead and process. This will give you an error. That is the reason why I used "Doevents" to slow down the process.

    I will search for my original codes tonight and post it. You can run it and take the "Doevents" out and you will see what I mean.

    See you in a few hours!
    Chemically Formulated As:
    Dr. Nitro

  21. #21
    Fanatic Member
    Join Date
    Jan 2000
    Location
    Nitro
    Posts
    633

    Here are my original codes!

    Code:
    Option Explicit
    
    Public Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA" (ByVal uAction As Long, ByVal uParam As Long, ByVal lpvParam As Any, ByVal fuWinIni As Long) As Long
    Public Const SPI_SCREENSAVERRUNNING = 97
    Public Const SPI_SETDESKWALLPAPER = 20
    Public Const SPIF_SENDWININICHANGE = &H2
    Public Const SPIF_UPDATEINIFILE = &H1
    
    Public Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
    
    Sub p_WallPaper()
      ' PURPOSE: Send the current picture to the clipboard
      Clipboard.SetData LoadPicture(frmMain_Directory.File1.List(frmView.imgStretch.Tag)), vbCFBitmap
    
      ' PURPOSE: Send the Entire Screen to the clipboard
      'Call keybd_event(vbKeySnapshot, 1, 0, 0)
    
      ' PURPOSE: Send the Active Window to the clipboard
      'Call keybd_event(vbKeySnapshot, 0, 0, 0)
      
      DoEvents
      
      ' PURPOSE: Save the clipboard picture
      SavePicture Clipboard.GetData(vbCFBitmap), "C:\Test.bmp"
      
      ' PURPOSE:Change the wallpaper
      Call SystemParametersInfo(SPI_SETDESKWALLPAPER, True, "C:\Test.bmp", SPIF_UPDATEINIFILE Or SPIF_SENDWININICHANGE)
    End Sub
    Chemically Formulated As:
    Dr. Nitro

  22. #22

    Thread Starter
    New Member
    Join Date
    May 2000
    Posts
    14

    thnx man

    ic what u mean.

    Well, i'm quite happy now so thanx. I've got exams in 2 weeks so i'm going to be really busy. After that will be the holidays

    Good luck to you in you career!
    Using VB5

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width