|
H/PC Elite Posts: | 708 |
Location: | Europe | Status: | |
| Nothing happens when I try to run the code Perhaps it has to have a form? |
|
|
|
H/PC Elite Posts: | 708 |
Location: | Europe | Status: | |
| I made a new project and added the code to be loaded upon the loading of the form, and now when I execute it I'm getting "An error was encountered while running this program: Unable to load function SystemParametersInfo." |
|
|
|
Factorite (Senior) Posts: | 79 |
Location: | Europe | Status: | |
| Ah I'm sorry, the function is actually defined as SystemParametersInfoW, can you try it again with the function declaration changed like this?
Public Declare Function SystemParametersInfo _
Lib "Coredll" _
Alias "SystemParametersInfoW" (ByVal uiAction As Long, _
ByVal uiParam As Long, _
ByVal pvParam As String, _
ByVal fWinIni As Long) As Long
|
|
|
|
H/PC Elite Posts: | 708 |
Location: | Europe | Status: | |
| These are the results:
- Test 1: 0, 1439
- Test 2: 0, 1439
- Test 3: 0, 1439
- Test 4: 0, 1439
|
|
|
|
Factorite (Senior) Posts: | 79 |
Location: | Europe | Status: | |
| That return value is ERROR_INVALID_SPI_VALUE, which unfortunately means that it does not recognize SPI_SETDESKWALLPAPER.
Curiously, if we compare the documentation on SystemParametersInfo for CE 3.0 and CE 5.0, only the page for 3.0 mentions SPI_SETDESKWALLPAPER. It might be a coincidence but maybe Microsoft decided to remove this functionality in a later version of CE? It seems like an odd decision but it does match what we're seeing right now.
To be honest I'm not really sure how to proceed from here, I guess a very crude method would be to forcefully terminate explorer.exe and then start it again, but I wouldn't recommend this except if the application is just going to be for your own use. |
|
|
|
H/PC Elite Posts: | 708 |
Location: | Europe | Status: | |
| I do suspect they might have removed it, yeah..
We could look into the PostMessage way of doing it, I think that might be the way! |
|
|
|
Factorite (Senior) Posts: | 79 |
Location: | Europe | Status: | |
| That's right, because you're running CE 5.0, there's a few more things to try.
Could you try the following example and let me know the test results?
Private Const HWND_BROADCAST As Long = &HFFFF
Private Const WM_SETTINGCHANGE As Long = &H1A
Public Declare Function GetDesktopWindow Lib "Coredll" () As Long
Public Declare Function SendMessage _
Lib "Coredll" _
Alias "SendMessageW" (ByVal hwnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
ByVal lParam As Long) As Long
Public Declare Function GetLastError Lib "Coredll" () As Long
Private Sub Main()
Dim lngDesktopWindow As Long
lngDesktopWindow = GetDesktopWindow
Dim lngResult As Long
lngResult = SendMessage(lngDesktopWindow, WM_SETTINGCHANGE, 0, 0)
MsgBox "Test 1:" & vbNewLine & vbNewLine & "SendMessage Result: " & lngResult & vbNewLine & "Desktop Handle: " & lngDesktopWindow & "GetLastError: " & GetLastError
lngResult = SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0, 0)
MsgBox "Test 2:" & vbNewLine & vbNewLine & "SendMessage Result: " & lngResult & vbNewLine & "GetLastError: " & GetLastError
End Sub
Hopefully GetDesktopWindow is actually implemented in CE 5.0. |
|
|
|
H/PC Elite Posts: | 708 |
Location: | Europe | Status: | |
| Test 1:
SendMessage Result: 1
Desktop Handle: 2080445216
GetLastError: 0
Test 2:
SendMessage Result: 0
GetLastError: 1400 |
|
|
|
H/PC Elite Posts: | 708 |
Location: | Europe | Status: | |
| I checked again in CE 5's winuser.h, and SPI_SETDESKWALLPAPER is absolutely defined there, so it should be still available. Weird |
|
|
|
Factorite (Senior) Posts: | 79 |
Location: | Europe | Status: | |
| That's not what I expected, but I guess we're getting somewhere.
The first result looks like it should have actually worked, have you tried to see if it updates the wallpaper?
Error 1400 is ERROR_INVALID_WINDOW_HANDLE which is very strange in this context since we're broadcasting to all windows, it's as if it isn't recognizing HWND_BROADCAST as a valid value.
Could you try passing -1 directly to SendMessage instead of the HWND_BROADCAST constant to see if that changes something perhaps?
Like so:
lngResult = SendMessage(-1, WM_SETTINGCHANGE, 0, 0)
I dunk for bananas - 2023-03-19 7:33 PM
I checked again in CE 5's winuser.h, and SPI_SETDESKWALLPAPER is absolutely defined there, so it should be still available. Weird
It could be that the value is still defined but SystemParametersInfo is not recognizing it anymore.
Edited by WinCEDev 2023-03-19 6:49 PM
|
|
|
|
Administrator H/PC Oracle Posts: | 18,043 |
Location: | United Kingdom | Status: | |
| This is why the CE API is a convoluted nightmare and so few people coded for it.
If you are in a desperate hurry and if you want to try and crack a nut with a sledgehammer, killing the explorer shell process and reloading it should force GDI to do a full re-draw. It'll close any open windows of course. |
|
|
|
H/PC Elite Posts: | 708 |
Location: | Europe | Status: | |
| Hi all! I've circled back to this thread after ages of experimenting, and I've finally found something that actually works!
Private Const HWND_BROADCAST As Long = &HFFFF
Private Const WM_SETTINGCHANGE As Long = &H1A
Private Const WM_WININICHANGE = &H1A
Private Const SPI_SETDESKWALLPAPER = 20
Private Const WM_PAINT = &HF
Public Declare Function GetDesktopWindow Lib "Coredll" () As Long
Public Declare Function SendMessage _
Lib "Coredll" _
Alias "SendMessageW" (ByVal hwnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
ByVal lParam As Long) As Long
Public Declare Function GetLastError Lib "Coredll" () As Long
Private Sub Form_Load()
Dim lngDesktopWindow As Long
lngDesktopWindow = GetDesktopWindow
Dim lngResult As Long
lngResult = SendMessage(lngDesktopWindow, WM_WININICHANGE, SPI_SETDESKWALLPAPER, 0)
MsgBox "Test 1:" & vbNewLine & vbNewLine & "SendMessage Result: " & lngResult & vbNewLine & "Desktop Handle: " & lngDesktopWindow & "GetLastError: " & GetLastError
lngResult = SendMessage(lngDesktopWindow, WM_PAINT, 0, 0)
MsgBox "Test 2:" & vbNewLine & vbNewLine & "SendMessage Result: " & lngResult & vbNewLine & "GetLastError: " & GetLastError
End Sub
I'll be writing my tool based off of this! Thank you again for your help and patience |
|
|