|
H/PC Philosopher Posts: | 471 |
Location: | Europe | Status: | |
| I'm having a startup application write the registry key that defines a certain wallpaper, but it evidently happens too late, as only the default wallpaper loads. Right clicking the desktop and selecting "properties" shows though that the change was registered, it just wasn't applied. Clicking "ok" applies it.
Is there a way to call for this update manually?  |
|
|
|
Administrator H/PC Oracle Posts: | 17,449 |
Location: | United Kingdom | Status: | |
| |
|
|
|
H/PC Philosopher Posts: | 471 |
Location: | Europe | Status: | |
| Thank you! Does anyone know how this could possible be called from an eVB application? |
|
|
|
Administrator H/PC Oracle Posts: | 17,449 |
Location: | United Kingdom | Status: | |
| You'll have to try and import its dispatch function from (probably ) coredll
Public Const HWND_BROADCAST As Long = &HFFFF&
Public Const WM_SETTINGCHANGE As Long = &H1A
Public Declare Function PostMessage Lib "coredll" _
Alias "PostMessageA" _
(ByVal hwnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
lParam As Any) As Long
Call PostMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0&, ByVal 0&)
|
|
|
|
H/PC Philosopher Posts: | 471 |
Location: | Europe | Status: | |
| I wasn't able to get it to work at all unfortunately.. Do you know how I would call for that in C#? I apologize for asking again, I'm not that good with coding yet  |
|
|
|
Factorite (Junior) Posts: | 26 |
Location: | Europe | Status: | |
| Hi,
I think there are some small errors in C:Amie's function declaration that may prevent it from working.
I modified a couple of things, could you try it again with this code?
Public Const HWND_BROADCAST As Long = &HFFFF&
Public Const WM_SETTINGCHANGE As Long = &H1A
Public Declare Function PostMessage Lib "coredll" _
Alias "PostMessageW" _
(ByVal hwnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
ByVal lParam As Long) As Long
Call PostMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0&, 0&)
To explain what I changed: Windows CE only contains 'wide' (unicode ) versions of the Win32 API functions, so you would have to use PostMessageW instead of PostMessageA. Also eVB does not support inline ByVal or declaring API function arguments 'As Any'. The way I modified the declaration is technically not really correct (lParam should actually be ByRef and isn't always a Long ) but it should do the job in this case since we're not using it anyway. Just don't use this declaration for code where lParam is actually needed or it will not work. I like to prefix API declarations with the name of the module or form they're in so that I can modify them for each particular situation. (On the desktop version of VB, the ability to declare 'As Any' avoids this situation ).
If you can't get it to work I would be more than happy to look at your code. Edited by WinCEDev 2023-03-18 6:15 PM
|
|
|
|
H/PC Philosopher Posts: | 471 |
Location: | Europe | Status: | |
| Thank you!  How would I get this code to work? If I just paste it in the editor, it tells me that it's missing a startup object |
|
|
|
Factorite (Junior) Posts: | 26 |
Location: | Europe | Status: | |
| That message means that eVB does not know where the entry point of your program is, this is where the runtime starts executing your code when someone runs your application.
If you get this message then I think you selected a formless project from the new project dialog, and you currently just have a module added to the project.
In that case, you can just add a Sub called Main to the module, and add the PostMessage line in it, the other code can remain outside of that function.
So something like this:
Private Const HWND_BROADCAST As Long = &HFFFF
Private Const WM_SETTINGCHANGE As Long = &H1A
Public Declare Function PostMessage _
Lib "coredll" _
Alias "PostMessageW" (ByVal hwnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
ByVal lParam As Long) As Long
Private Sub Main()
Call PostMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0, 0)
End Sub
I made a couple more adjustments to the code, the above example runs in the emulator for me.
You should be able to modify the registry value before you broadcast WM_SETTINGCHANGE and that should update the wallpaper. Edited by WinCEDev 2023-03-19 12:19 AM
|
|
|
|
Administrator H/PC Oracle Posts: | 17,449 |
Location: | United Kingdom | Status: | |
| Oh yeah, I've typed PostMessageA haven't I  |
|
|
|
H/PC Philosopher Posts: | 471 |
Location: | Europe | Status: | |
| Thank you!! The code compiles, though it doesn't work in updating the desktop  It just momentarily shows the hourglass cursor, but nothing else seems to happen
What could be causing this? Edited by I dunk for bananas 2023-03-19 11:32 AM
|
|
|
|
H/PC Philosopher Posts: | 471 |
Location: | Europe | Status: | |
| I also just found another annoying thing:
When I set the new wallpaper in the registry, it will show the little preview of it in the wallpaper properties window, but clicking OK doesn't update it, nothing happens. If I manually select that exact same image file with the wallpaper properties application and click OK it updates just fine
I also found this (you have to copy/paste the URL for it to work: https://learn.microsoft.com/en-us/previous-versions/ms942638(v=msdn.10 ) ) , which seems to include a specific function to change the wallpaper (SPI_SETDESKWALLPAPER ), perhaps this is what we want?
Edit: I tried it, but absolutely nothing happens when I run this code, no error messages or anything:
Private Const SPI_SETDESKWALLPAPER As Long = 20
Public Declare Function SystemParametersInfo _
Lib "coredll" (ByVal uiAction As Long, _
ByVal uiParam As Long, _
ByVal pvParam As Long, _
ByVal fWinIni As Long) As Long
Private Sub Main()
Call SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, "\test.bmp", 0)
End Sub
Edited by I dunk for bananas 2023-03-19 2:17 PM
|
|
|
|
H/PC Philosopher Posts: | 471 |
Location: | Europe | Status: | |
| I've changed pvParam to String, but there's still nothing happening |
|
|
|
Factorite (Junior) Posts: | 26 |
Location: | Europe | Status: | |
| I have made a little bit of progress, though nothing functional so far.
I noticed PostMessage was returning 0 indicating an error condition, though in the emulator calling GetLastError does not really seem to work, and on my Jornada it always seems to return 120 ( ERROR_CALL_NOT_IMPLEMENTED). However I think this is just one of eVB's many oddities as I have gotten back 120 many times where the function call actually succeeded in other scenarios.
So I set up a test project in desktop VB6 to see if I could at least get it to work there. PostMessage still returned 0, this time GetLastError returned 1159 ( ERROR_MESSAGE_SYNC_ONLY) or "The message can be used only with synchronous operations.". On desktop Windows, using SendMessage seems to work, and matches the documentation (Microsoft says to use SendMessageTimeout but that doesn't exist on CE 2.11 ).
Unfortunately, even when trying with SendMessage it still does not work on Windows CE.
On a side note, the reason why PostMessage is preferable with HWND_BROADCAST is because SendMessage will lock up your application if one of the other applications on the system is not responding.
I also tried to send the message directly to the desktop window, but then found that GetDesktopWindow is documented on MSDN but not actually exported from Coredll, at least not on CE 2.11.
Out of interest, what device and Windows CE version are you testing on? MSDN says that SPI_SETDESKWALLPAPER is only supported on Windows CE 2.12 and higher. I only have CE 2.11 and older to test on so I don't think I can verify if this works. I could try it on my Compaq iPAQ H3970 with Pocket PC 2002 (CE 3.0 ) though since there is no 'desktop' in the traditional sense on Pocket PC I don't know if that is a reliable test subject. Edited by WinCEDev 2023-03-19 3:41 PM
|
|
|
|
H/PC Philosopher Posts: | 471 |
Location: | Europe | Status: | |
| I'm on CE 5, it's an older TV receiver!
I've been trying to implement it in C# in the meantime and I've had no success either  |
|
|
|
Factorite (Junior) Posts: | 26 |
Location: | Europe | Status: | |
| Could you try to run the below code and tell me the result for each test? I'm not sure what we should actually be entering for fWinIni but this should hopefully shed some light on what might be going wrong.
Private Const SPI_SETDESKWALLPAPER As Long = 20
Private Const SPIF_UPDATEINIFILE As Integer = &H1
Private Const SPIF_SENDCHANGE As Integer = &H2
Public Declare Function SystemParametersInfo _
Lib "Coredll" (ByVal uiAction As Long, _
ByVal uiParam As Long, _
ByVal pvParam As String, _
ByVal fWinIni As Long) As Long
Public Declare Function GetLastError Lib "Coredll" () As Long
Private Sub Main()
Dim lngResult As Long
lngResult = SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, "\test.bmp", 0)
MsgBox "Test 1:" & vbNewLine & vbNewLine & "Return value: " & lngResult & vbNewLine & "GetLastError: " & GetLastError
lngResult = SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, "\test.bmp", SPIF_UPDATEINIFILE)
MsgBox "Test 2:" & vbNewLine & vbNewLine & "Return value: " & lngResult & vbNewLine & "GetLastError: " & GetLastError
lngResult = SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, "\test.bmp", SPIF_SENDCHANGE)
MsgBox "Test 3:" & vbNewLine & vbNewLine & "Return value: " & lngResult & vbNewLine & "GetLastError: " & GetLastError
lngResult = SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, "\test.bmp", SPIF_UPDATEINIFILE Or SPIF_SENDCHANGE)
MsgBox "Test 4:" & vbNewLine & vbNewLine & "Return value: " & lngResult & vbNewLine & "GetLastError: " & GetLastError
End Sub
|
|
|