Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Refreshing the Desktop?? 1

Status
Not open for further replies.

MOP

IS-IT--Management
May 30, 2000
18
0
0
AU
I have a program that changes the wallpaper and other display settings via the registry, but cannot work out how to refresh the desktop to reflect the changes. I need the operation to be transparent to the user, so displaying the properties box is no good.

Any suggestions?
 
Get a handle to the desktop window using the GetDesktopWindow api call, then call the UpdateWindow api call with the window handle. It should repaint (haven't tested this personally).

I don't think you need to call CloseHandle afterwards. The MSDN docs don't mention it as being required.

Chip H.
 
Thanks Chip, Its amazing the info in MSDN when you find the right keyword.
RefreshWindow <> Updatewindow unless of course it's declared as such.

Your comments were also appreciated Alt255.
 
ChipH, this is probably a no-brainer but I can't get it to work with W98SE.

GetDesktopWindow returns a handle (128) and UpdateWindow returns a &quot;1&quot; (which I assume is an error condition, since the desktop doesn't refresh with the new wallpaper). I know that the registry has been modified properly (the control panel verifies that by showing a thumbnail of the new wallpaper) but the settings don't take effect unless I reboot the computer or click &quot;Ok&quot; in the Desktop Control Panel.

Are there any special considerations for using these API calls? Is there any way to force a refresh against the will of the Windows &quot;Active Desktop&quot; settings?

Really scratchin' my head now...
spineyes.gif
 
I'm still having the same problem on W95. I also get handle 128 and update 1. I've tried UpdateWindow, RepaintWindow, OpenDesktop, CloseDesktop and PaintDesktop to no avail.
Alt255, Can you repost your alternative from your last message as it disappeared before I could try it.

I'm glad I'm not alone in my lack of success in this supposedly simple concept.
 
I'm sorry about that MOP. I Red Flagged my own post because I considered it inferior to ChipH's solution. It really was inferior (it represented a sloppy programming practice I am trying to eliminate from my skill set) but since neither of us has had any luck with the &quot;correct&quot; solution I'll try to reconstruct the code. Hopefully, ChipH will post some good code. In the mean time...

If I remember correctly, I showed a way to shell to CONTROL.EXE with DESK.CPL as a command parameter and then used an arbitrary interval value in a timer to send an ENTER key to the control panel (assuming it was open by then). That was a little too sloppy. The following code shells to CONTROL.EXE and then checks to see if it has finished loading before it sends an ENTER key.

Place the following function and declarations in a module:[tt]
Public Declare Function GetWindowText Lib &quot;user32&quot; _
Alias &quot;GetWindowTextA&quot; (ByVal hwnd As Long, _
ByVal lpString As String, ByVal cch As Long) As Long
Public Declare Function EnumWindows Lib &quot;user32&quot; _
(ByVal lpEnumFunc As Any, ByVal lParam As Long) As Long

Public Function EnumProc(ByVal app_hwnd As Long, _
ByVal lParam As Long) As Boolean
Dim buf As String * 1024
Dim title As String
Dim length As Long
length = GetWindowText(app_hwnd, buf, Len(buf))
title = Left$(buf, length)
If InStr(title, &quot;Display Properties&quot;) > 0 Then
SendKeys &quot;{ENTER}&quot;
Form1.Timer1.Enabled = False
EnumProc = 0
Else
EnumProc = 1
End If
End Function[/tt]

Place the Command1 code wherever you need to activate the registry changes:[tt]
Private Sub Command1_Click()
Form1.Hide
Shell (&quot;c:\windows\control.exe c:\windows\system\desk.cpl&quot;)
Timer1.Enabled = True
End Sub[/tt]

Set the interval for Timer1 to any non-zero value. It will enumerate all windows until the function EnumProc finds one with &quot;Display Settings&quot; in the title and sends an ENTER key.
[tt]
Private Sub Timer1_Timer()
EnumWindows AddressOf EnumProc, 0
End Sub
[/tt]
Like I said, this is a really sloppy way of doing business and, hopefully, one of the gurus in this forum will shed a little more light on the topic.

Good luck.

 
Thanks Alt255, I will keep it in reserve for want of something better. I have tried many techniques including Showwindow, Closedesktop, opendesktop, paintdesktop and redraw window but all with no success. The only success I've had is using SystemParametersInfo to remove the wallpaper but it doesn't put it back. It is a Windows 3.0 command after all, so I didn't expect to much.

Searching for clues last night I found a reference to WS_EX_TRANSPARENT as the new method someone was using to refresh the desktop/background but I have not been able to follow it up yet.

I think that the mistake I am making is trying to refresh the desktop when I need to update the background. I have some code which adds a shortcut to the desktop and refreshes the desktop but this does not update the background, only the shortcut icons.

Looking forward to a solution.

 
Alt255,
Worked it out, I was on the right track systemparametersinfo. Just had the syntax wrong. The following code will do the trick on 95. Will test on NT tommorow

Public Declare Function SystemParametersInfo Lib &quot;user32&quot; Alias &quot;SystemParametersInfoA&quot; (ByVal uAction As Long, ByVal uParam As Long, ByVal lpvParam As String, ByVal fuWinIni As Long) As Long

Private Sub Command1_Click()
Dim x As Long
x = SystemParametersInfo(20, 0, &quot;(None)&quot;, 1)
End Sub


Private Sub Command2_Click()
Dim FileName As String
Dim x As Long
FileName = &quot;c:\windows\setup.bmp&quot;
x = SystemParametersInfo(20, 0, FileName, 1)
End Sub
Now all I need to do is learn to redflag my last post.

Thanks for the help.
 
Hmmm, it doesn't appear to work on Windows 98. It changes the reg entry, the desktop icons flash for a second and the background wallpaper stays the same.

The display control panel shows a thumbnail of the new wallpaper but it doesn't take effect unless I click Ok.

Good research, MOP, but something tells me that if we are going to find a solution that works across the Windows versions we may be looking for a different approach.
 
Ouch! We have to be careful with that call! I tried it three times and within a few minutes of each try I received a blue screen of death (one I had never seen before) warning that Windows was out of available stack pages and that I should increase the value of MinSPs in SYSTEM.INI.

Something tells me that SystemParametersInfo isn't fully supported under W98.

Scratching my head deeply now
explode.gif
.
 
Alt255,
Thanks for the warning, I was overdue for a backup of the registry and an ERD for NT so I did that before testing on NT. The results however were excellent. Worked perfectly for 50+ wallpaper changes without a problem.
I unfortunately do not have a Win98 machine in the building as I prefer NT for network security and 95 for those people who have special needs that NT can't do.

Do you have any other 98 machine? Are there any restrictions on the user account that you are using. Just trying to eliminate something that may be conflicting on your machine.
I will research compatibility of this command with 98 and post later if I find a problem.
If there are different commands then it should simply be a matter of determining the winver to allocate the correct command.

 
Got it. But I don't understand why it works. I made the last parameter a negative value and the function works like a champ.

x = SystemParametersInfo(20, 0, FileName, -1)

I am unclear why 1 as a &quot;user profile update option&quot; worked under W95 and NT but not on my W98 home machine (I haven't had access to any other machines, due to the holiday weekend).

My problem with the blue screens probably wasn't a direct result of using SystemParametersInfo. I have a terrible internet connection here so I wrote a little app that uses a timer to check for a connection. If it doesn't find one it automatically connects. It worked fine until I started fiddling with SystemParametersInfo. I stopped running the app and the blue screens went away.

MOP, I know you were the one to ask the question but I think you deserve all the credit for finding the solution. Funny how that works, isn't it?

Thanks for helping me sort this through.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top