- NSIS Discussion
- External DLLs and passing Windows Constants?
Archive: External DLLs and passing Windows Constants?
Nebulus
20th July 2004 16:23 UTC
External DLLs and passing Windows Constants?
Does anybody have an example of how you might pass windows constants to an external DLL? MSDN shows for user32.dll, you can call SystemParametersInfo to make changes to icons, fonts, desktop, etc. Here's the link of all the possibilities:
http://msdn.microsoft.com/library/de...metersinfo.asp
Is there a way to pass the value of that contant?
deguix
20th July 2004 16:47 UTC
You need first to get the constant value in hexadecimal or decimal, name it using a define and use it using System plugin to call the dll. There are some examples of windows constants inside Include\WinMessages.nsh of your NSIS dir.
If you don't know the values in hexa or dec, I'll give 'em if you want.
Nebulus
20th July 2004 17:09 UTC
That's where I was going, but have no way to get the hex values. By the way, how DO you get the hex values?
Here're the constants I'm looking for:
SPI_SETDESKWALLPAPER
SPIF_UPDATEINIFILE
SPIF_SENDWININICHANGE
SPIF_SENDCHANGE
Basically, I'm trying to call user32.dll's SystemParametersInfo method to refresh the desktop wallpaper without a reboot. To date, I haven't seend any NSIS scripting that'll actually pull it of. IF I can manage it, I'll post it to the archive. Thanks for the help!
Nebulus
20th July 2004 17:29 UTC
Ok, I've got this code, and while I''m getting an obvious error code back, does anybody know why or where I'm going wrong?
**************
BEGIN CODE
**************
!define SPI_SETDESKWALLPAPER 20
!define WALLPAPER "%SystemRoot%\Web\Wallpaper\test.html"
!define SPIF_UPDATEINIFILE 0x1
!define SPIF_SENDWININICHANGE 0x2
!define SPIF_SENDCHANGE 0x1
System::Call "user32::SystemParametersInfo(i ${SPI_SETDESKWALLPAPER}, i 0, t ${WALLPAPER}, i ${SPIF_SENDCHANGE}|${SPIF_SENDWININICHANGE}) l .r0"
MessageBox MB_OK "Return Value: $0"
**************
ENDDE
**************
The return value I'm getting is: 4294967297. I get a Desktop flicker, but nothing changes, and the value of WALLPAPER isn't set in the registry.
deguix
20th July 2004 18:08 UTC
I got it, tested and everything:
!define SPI_SETDESKWALLPAPER 0x0014
!define WALLPAPER ""%SystemRoot%\Web\Wallpaper\test.html"
!define SPIF_UPDATEINIFILE 0x0001
!define SPIF_SENDWININICHANGE 0x0002
System::Alloc ${NSIS_MAX_STRLEN}
Pop $0
StrCpy $0 "${WALLPAPER}"
System::Call "user32::SystemParametersInfo(i ${SPI_SETDESKWALLPAPER}, i 0, t r0, i ${SPIF_SENDWININICHANGE}) i .r1"
System::Free $0
One thing to learn here: Everytime it says "set parameter to point to a null-terminated string" you have to allocate memory for a variable, use the variable and free its allocated memory.
Nebulus
20th July 2004 18:38 UTC
Deguix - thanks for the help there. I'm not getting the error code anymore, but I am getting a "0" returned from the call - basically a false, and the desktop still doesn't refresh for me. I tested it with some of the default images in windows as well, and they also didn't work.
Is there a way to just broadcast to the system that there was a change in order to trigger a refresh?
By the way, I'm trying this on a Win XP Pro system, but the MDSN docs showed that this should work on Win 9x and up.
Thanks for the help so far!
deguix
20th July 2004 23:31 UTC
What? I have Windows XP Home and that code was tested and everything, it even gave 1 as a result.
(Oh... try changing this:
""%SystemRoot%\Web\Wallpaper\test.html"
to this:
"%SystemRoot%\Web\Wallpaper\test.html")
Nebulus
21st July 2004 00:41 UTC
Yeah I did that and checked all the code a few times. I'm not exactly what's going on, but I can't get consistent results. Now I did manage to get it to set a bitmap to the background and refresh, but no go on the html based wallpaper...
deguix
21st July 2004 12:31 UTC
Oh yeah, a html as wallpaper... MSDN says that this only works for bitmaps, and I tested w/ bitmaps. So that's why... The only thing I found in my Plataform SDK documentation is about the Active Desktop:
To access the Active Desktop, a client application would need to create an instance of the ActiveDesktop object (CLSID_ActiveDesktop) with the CoCreateInstance function and retrieve a pointer to the object's IActiveDesktop interface.
And there says that we can use AddDesktopItemWithUI or AddDesktopItem methods to add an item to it. And the ApplyChanges method that writes to the registry the changes. This seems complicated...
Now there is a question to everyone, how can I use this type of code using System plugin?
zimsms
21st July 2004 13:16 UTC
Looks like the system plugin would be able to handle all of that. just a few calls:
One to obtain an instance of the ActiveDesktop.
Then multiple calls to AddItem/AddItemUI
Then the call to apply the changes
Nebulus
21st July 2004 13:43 UTC
Ok, so I'm not going insane.... just using the wrong code :) If anybody does have a method for doing this, please enlighten us!
Nebulus
20th August 2004 15:36 UTC
Ok, in checking the MSDN site and some of the NSIS System usage, I think this is possible to set a wallpaper - I'm just stuck on syntax and usage.
Here's what we'd need to send to the IActiveDesktop instance:
SetWallpaper("path\wallpaper_page",0)
ApplyChanges(dWord)
with dWord being one of these (I suspect AD_APPLY_REFRESH
):
AD_APPLY_ALL
AD_APPLY_BUFFERED_REFRESH
AD_APPLY_DYNAMICREFRESH
AD_APPLY_FORCE
AD_APPLY_HTMLGEN
AD_APPLY_REFRESH
AD_APPLY_SAVE
Now, from the NSIS docs and System DLL usage, here's a chunk of code for getting the wallpaper with this code:
# defines
!define CLSCTX_INPROC_SERVER 1
!define CLSID_ActiveDesktop {75048700-EF1F-11D0-9888-006097DEACF9}
!define IID_IActiveDesktop {F490EB00-1240-11D1-9888-006097DEACF9}
# create IActiveDesktop interface
System::Call "ole32::CoCreateInstance( \
g '${CLSID_ActiveDesktop}', i 0, \
i ${CLSCTX_INPROC_SERVER}, \
g '${IID_IActiveDesktop}', *i .r0) i.r1"
StrCmp $1 0 0 end
# call IActiveDesktop->GetWallpaper
System::Call "$0->4(w .r2, i ${NSIS_MAX_STRLEN}, i 0)"
# call IActiveDesktop->Release
System::Call "$0->2()"
# print result
DetailPrint $2
end:
Now... since I SUCK at using the System DLL, is there any chance somebody could help tweak this?
Also, is there a resource for getting the hex value of the MS dWords? I googled the hell out of it and can't find anything.
Thanks!
matt21
20th August 2004 18:12 UTC
The following might help! See http://dotnetforums.net/showthread.p...685#post420685 for more. Unfortunately I know nothing about System DLL
Public Const AD_APPLY_ALL As Integer = AD_APPLY_SAVE Or AD_APPLY_HTMLGEN Or AD_APPLY_REFRESH
Public Const AD_APPLY_BUFFERED_REFRESH As Integer = &H10
Public Const AD_APPLY_DYNAMICREFRESH As Integer = &H20
Public Const AD_APPLY_FORCE As Integer = &H8
Public Const AD_APPLY_HTMLGEN As Integer = &H2
Public Const AD_APPLY_REFRESH As Integer = &H4
Public Const AD_APPLY_SAVE As Integer = &H1
Nebulus
20th August 2004 18:28 UTC
Cool, thanks!
So far, I can run this script:
# defines
!define CLSCTX_INPROC_SERVER 1
!define CLSID_ActiveDesktop {75048700-EF1F-11D0-9888-006097DEACF9}
!define IID_IActiveDesktop {F490EB00-1240-11D1-9888-006097DEACF9}
# create IActiveDesktop interface
System::Call "ole32::CoCreateInstance( \
g '${CLSID_ActiveDesktop}', i 0, \
i ${CLSCTX_INPROC_SERVER}, \
g '${IID_IActiveDesktop}', *i .r0) i.r1"
StrCmp $1 0 0 end
# call IActiveDesktop->SetWallpaper
System::Call "$0->4(t ${WP_Path}${WP_Page}, i 0, )"
# call IActiveDesktop->ApplyChanges
System::Call "$0->4(i ${AD_APPLY_REFRESH})"
# call IActiveDesktop->Release
System::Call "$0->2()"
end:
where I've defined
AD_APPLY_REFRESH as 0x4.
This setup blows up and throws an error window. Imust be close - at the very least I'm causing errors :igor:
Anyone, anyone, bueler?