ComObjQuery / vtable
ComObjQuery / vtable
Regarding the first example on the ComObjQuery docs page, how do you tell which function is at an nth position in a virtual function table?
Re: ComObjQuery / vtable
I would usually do a web search with something like "IDispatch methods in vtable order" etc. Not really sure, maybe if you install Windows SDK, you can check the header file...
Re: ComObjQuery / vtable
View the interface definition in its header file. If you don't have the SDK on hand, you might find the appropriate header file via Google or searchcode.com. Searching for the plain C definition (typedef struct InterfaceNameVtbl) might get more relevant results. It also saves you having to take into account which methods are inherited from other interfaces, because they're defined explicitly.
Re: ComObjQuery / vtable
Thanks for this.lexikos wrote:Searching for the plain C definition (typedef struct InterfaceNameVtbl) might get more relevant results.
Re: ComObjQuery / vtable
I tried to recreate the example here (See "Bringing it All Together - Sample Code"). The script should use IActiveDesktop::GetWallpaper to get the name of the current wallpaper.
I think I found the correct vtable offset by looking in Shlobj.h, but I am still failing to understand something because the script crashes.
I think I found the correct vtable offset by looking in Shlobj.h, but I am still failing to understand something because the script crashes.
Code: Select all
AD_GETWP_BMP := 0
CLSID_ActiveDesktop := "{75048700-EF1F-11D0-9888-006097DEACF9}"
IID_IActiveDesktop := "{f490eb00-1240-11d1-9888-006097deacf9}"
cchWallpaper := 260
AD := ComObjCreate(CLSID_ActiveDesktop, IID_IActiveDesktop)
hr := DllCall(vtable(AD, 4), "Ptr", AD, "Ptr*", wszWallpaper, "UInt", cchWallpaper, "UInt", AD_GETWP_BMP) ; GetWallpaper
Wallpaper := StrGet(wszWallpaper, "UTF-16")
MsgBox, % "hr: " hr "`nWallpaper: " Wallpaper
ObjRelease(AD)
ExitApp
vtable(ptr, n) {
; NumGet(ptr+0) returns the address of the object's virtual function
; table (vtable for short). The remainder of the expression retrieves
; the address of the nth function's address from the vtable.
return NumGet(NumGet(ptr+0), n*A_PtrSize)
}
Re: ComObjQuery / vtable
hr := DllCall(vtable(AD, 4), "Ptr", AD, "Ptr", wszWallpaper := 0, "UInt", cchWallpaper, "UInt", AD_GETWP_BMP), the one in red prevents the crash but HRESULT != 0
This one kinda works (changed Ptr to Str), but I only get C:\:
This one kinda works (changed Ptr to Str), but I only get C:\:
Code: Select all
AD_GETWP_BMP := 0
CLSID_ActiveDesktop := "{75048700-EF1F-11D0-9888-006097DEACF9}"
IID_IActiveDesktop := "{f490eb00-1240-11d1-9888-006097deacf9}"
cchWallpaper := 260
AD := ComObjCreate(CLSID_ActiveDesktop, IID_IActiveDesktop)
hr := DllCall(vtable(AD, 4), "Ptr", AD, "Str", wszWallpaper := 0, "UInt", cchWallpaper, "UInt", AD_GETWP_BMP) ; GetWallpaper
; Wallpaper := StrGet(wszWallpaper, "UTF-16")
MsgBox, % "hr: " hr "`nWallpaper: " . wszWallpaper ; Wallpaper
ObjRelease(AD)
ExitApp
vtable(ptr, n) {
; NumGet(ptr+0) returns the address of the object's virtual function
; table (vtable for short). The remainder of the expression retrieves
; the address of the nth function's address from the vtable.
return NumGet(NumGet(ptr+0), n*A_PtrSize)
}
Re: ComObjQuery / vtable
Yes, when I try that I get 0x80070057, which is E_INVALIDARG - One or more arguments are not valid.
Re: ComObjQuery / vtable
I posted before I saw your edit. I just get C:\ too, not sure why.Coco wrote:This one kinda works (changed Ptr to Str), but I only get C:\
Re: ComObjQuery / vtable
Thanks Coco, I think I got it. I added VarSetCapacity() for wszWallpaper.
Based on the ComObjQuerry example in the docs I expected "Ptr*" to work.
Code: Select all
AD_GETWP_BMP := 0
CLSID_ActiveDesktop := "{75048700-EF1F-11D0-9888-006097DEACF9}"
IID_IActiveDesktop := "{f490eb00-1240-11d1-9888-006097deacf9}"
cchWallpaper := 260
AD := ComObjCreate(CLSID_ActiveDesktop, IID_IActiveDesktop)
VarSetCapacity(wszWallpaper, A_IsUnicode ? 520 : 260, 0)
hr := DllCall(vtable(AD, 4), "Ptr", AD, "str", wszWallpaper := 0, "UInt", cchWallpaper, "UInt", AD_GETWP_BMP) ; GetWallpaper
MsgBox, % "hr: " hr "`nWallpaper: " . wszWallpaper
ObjRelease(AD)
ExitApp
vtable(ptr, n) {
; NumGet(ptr+0) returns the address of the object's virtual function
; table (vtable for short). The remainder of the expression retrieves
; the address of the nth function's address from the vtable.
return NumGet(NumGet(ptr+0), n*A_PtrSize)
}
Re: ComObjQuery / vtable
When this method returns, contains a pointer to a null-terminated, Unicode buffer that contains the file name of the wallpaper.
Code: Select all
#NoEnv
AD_GETWP_BMP := 0
AD_GETWP_LAST_APPLIED := 0x00000002
CLSID_ActiveDesktop := "{75048700-EF1F-11D0-9888-006097DEACF9}"
IID_IActiveDesktop := "{f490eb00-1240-11d1-9888-006097deacf9}"
cchWallpaper := 260
VarSetCapacity(wszWallpaper, cchWallpaper * 2, 0)
AD := ComObjCreate(CLSID_ActiveDesktop, IID_IActiveDesktop)
hr := DllCall(vtable(AD, 4), "Ptr", AD, "Ptr", &wszWallpaper, "UInt", cchWallpaper, "UInt", AD_GETWP_LAST_APPLIED) ; GetWallpaper
Wallpaper := StrGet(&wszWallpaper, "UTF-16")
MsgBox, % "hr: " hr "`nWallpaper: " Wallpaper
ObjRelease(AD)
ExitApp
vtable(ptr, n) {
; NumGet(ptr+0) returns the address of the object's virtual function
; table (vtable for short). The remainder of the expression retrieves
; the address of the nth function's address from the vtable.
return NumGet(NumGet(ptr+0), n*A_PtrSize)
}
Re: ComObjQuery / vtable
Thanks just me! Silly mistake on my part, since all strings returned from COM methods should be Unicode regardless of the AHK version. "Ptr", &wszWallpaper makes more sense to me now too.
Re: ComObjQuery / vtable
We totally forgot that we need to initialize wszWallpaper...lol
- theimmersion
- Posts: 181
- Joined: 09 Jul 2016, 08:34
- Location: Serbia
Re: ComObjQuery / vtable
Late to this conversation but hope someone might still be looking at this and have an answer.
I found some info about IActiveDesktop to be able to change a wallpaper with fade like when dekstop wallpaper slide is enabled.
Can you somehow make a code like the above to also set a wallpaper via IActiveDesktop?
I could not find anything else in regards to changing wallpapers via AHK but with fade effect. Im not gonna even try go the hack/workaround (draw fake background etc) route, dont think its viable at all unless with some form of native MS stuff.
So far, im using "DllCall("SystemParametersInfo", UINT, 0x14, UINT, 0, STR, image_file, UINT, 2)" to change wallpapers but by God, its ugly when it does that.
Thanks for the above, will come in handy as well one day.
I dont even understand why MS didnt do the fade effect on that call as well. I see no point to have such a behavior as a default.
Even the right click context "Set as desktop background" does not fade and i really dont see the reason why.
At least not on Win 10. I thought we improved with soft/hardware enough to have something this simple yet pleasing feature (that could also be optional of course but easier accessible). Oh well. xD
This was my attempt and of course it doesnt work.
I found some info about IActiveDesktop to be able to change a wallpaper with fade like when dekstop wallpaper slide is enabled.
Can you somehow make a code like the above to also set a wallpaper via IActiveDesktop?
I could not find anything else in regards to changing wallpapers via AHK but with fade effect. Im not gonna even try go the hack/workaround (draw fake background etc) route, dont think its viable at all unless with some form of native MS stuff.
So far, im using "DllCall("SystemParametersInfo", UINT, 0x14, UINT, 0, STR, image_file, UINT, 2)" to change wallpapers but by God, its ugly when it does that.
Thanks for the above, will come in handy as well one day.
I dont even understand why MS didnt do the fade effect on that call as well. I see no point to have such a behavior as a default.
Even the right click context "Set as desktop background" does not fade and i really dont see the reason why.
At least not on Win 10. I thought we improved with soft/hardware enough to have something this simple yet pleasing feature (that could also be optional of course but easier accessible). Oh well. xD
This was my attempt and of course it doesnt work.
Code: Select all
CLSID_ActiveDesktop := "{75048700-EF1F-11D0-9888-006097DEACF9}"
IID_IActiveDesktop := "{f490eb00-1240-11d1-9888-006097deacf9}"
cchWallpaper := 260
VarSetCapacity(file, cchWallpaper * 2, 0)
file := A_Desktop . "\the_purge__election_year___vector_wallpaper_2_by_elclon-da9w8qe.png"
AD := ComObjCreate(CLSID_ActiveDesktop, IID_IActiveDesktop)
hr := DllCall(vtable(AD, 4), "Ptr", file, "UInt", 0)
ObjRelease(AD)
Re: ComObjQuery / vtable
Code: Select all
file := A_Desktop . "\the_purge__election_year___vector_wallpaper_2_by_elclon-da9w8qe.png"
hr := DllCall(vtable(AD, 5), "Ptr", AD, "WStr", file, "UInt", 0, "UInt") ; IActiveDesktop::SetWallpaper
- theimmersion
- Posts: 181
- Joined: 09 Jul 2016, 08:34
- Location: Serbia
Re: ComObjQuery / vtable
Doesnt seem to do anything.
Am i missing a mistake i made?
Edit, also hr returns 0. It should return something like an ms error code on fail or S_OK.
Thanks for trying to help!
Am i missing a mistake i made?
Code: Select all
CLSID_ActiveDesktop := "{75048700-EF1F-11D0-9888-006097DEACF9}"
IID_IActiveDesktop := "{f490eb00-1240-11d1-9888-006097deacf9}"
cchWallpaper := 260
VarSetCapacity(file, cchWallpaper * 2, 0)
file := A_Desktop . "\the_purge__election_year___vector_wallpaper_2_by_elclon-da9w8qe.png"
AD := ComObjCreate(CLSID_ActiveDesktop, IID_IActiveDesktop)
hr := DllCall(vtable(AD, 5), "Ptr", AD, "WStr", file, "UInt", 0, "UInt") ; IActiveDesktop::SetWallpaper
ObjRelease(AD)
Thanks for trying to help!
Re: ComObjQuery / vtable
S_OK = 0. I cannot see a mistake in your attempt. Sorry!
Re: ComObjQuery / vtable
Maybe you need to call IActiveDesktop::ApplyChanges additionally:
Code: Select all
hr := DllCall(vtable(AD, 5), "Ptr", AD, "WStr", file, "UInt", 0, "UInt") ; IActiveDesktop::SetWallpaper
hr := DllCall(vtable(AD, 3), "Ptr", AD, "UInt", 0x07, "UInt") ; IActiveDesktop::ApplyChanges - AD_APPLY_ALL
Code: Select all
////////////////////////////////////////////
// Flags for IActiveDesktop::ApplyChanges()
#define AD_APPLY_SAVE 0x00000001
#define AD_APPLY_HTMLGEN 0x00000002
#define AD_APPLY_REFRESH 0x00000004
#define AD_APPLY_ALL (AD_APPLY_SAVE | AD_APPLY_HTMLGEN | AD_APPLY_REFRESH)
#define AD_APPLY_FORCE 0x00000008
#define AD_APPLY_BUFFERED_REFRESH 0x00000010
#define AD_APPLY_DYNAMICREFRESH 0x00000020
- theimmersion
- Posts: 181
- Joined: 09 Jul 2016, 08:34
- Location: Serbia
Re: ComObjQuery / vtable
This works, but still no fade effect.
Ok, so i experimented a bit and its the AD_APPLY_SAVE that triggers the change (but instant). Trying different combinations but so far no luck.
Ok, so i experimented a bit and its the AD_APPLY_SAVE that triggers the change (but instant). Trying different combinations but so far no luck.
Re: ComObjQuery / vtable
Active Desktop hasn't been a thing on Windows for a long time now. And good riddance. It might have been the IE part that provided the fade effect.
On Windows 10, you should be using IDesktopWallpaper - https://msdn.microsoft.com/en-us/librar ... s.85).aspx
SetWallpaper might do the fade effect, but it's unlikely. Instead, you might try this sequence as a last resort:
* SetSlideshowOptions to disable shuffling (maybe optional) and set a long transition time (and maybe GetSlideshowOptions to get the current results so that you can save them for later)
* GetWallpaper to get the path of a current wallpaper
* SetSlideshow to add that current wallpaper and the new wallpaper to a slideshow
* AdvanceSlideshow to go to the new wallpaper with the fade effect
* SetWallpaper to set the wallpaper to the same thing, removing the slideshow, but without any aesthetically displeasing "jolts" to the new wallpaper
On Windows 10, you should be using IDesktopWallpaper - https://msdn.microsoft.com/en-us/librar ... s.85).aspx
SetWallpaper might do the fade effect, but it's unlikely. Instead, you might try this sequence as a last resort:
* SetSlideshowOptions to disable shuffling (maybe optional) and set a long transition time (and maybe GetSlideshowOptions to get the current results so that you can save them for later)
* GetWallpaper to get the path of a current wallpaper
* SetSlideshow to add that current wallpaper and the new wallpaper to a slideshow
* AdvanceSlideshow to go to the new wallpaper with the fade effect
* SetWallpaper to set the wallpaper to the same thing, removing the slideshow, but without any aesthetically displeasing "jolts" to the new wallpaper
- theimmersion
- Posts: 181
- Joined: 09 Jul 2016, 08:34
- Location: Serbia
Re: ComObjQuery / vtable
Yeah, ive seen that everyone said how IActiveDesktop was not used anymore past Windows XP but still worked in Vista and 7 and i think i read 8 as well.
But all those codes i saw are for C/C++ and i dont know how and if possible to translate into AHK code.
Heres one site i saw for Win 7 apparently working.
https://www.neowin.net/forum/topic/1035 ... wallpaper/
Heres another interesting one.
https://stackoverflow.com/questions/147 ... er-restart
All have one thing in common i guess and its the handle. I made sure WorkerW is the handle but still no fade.
Also, i saw somewhere it was possible in C/C++ to trigger WorkerW to become desktops handle without going in task view or personalize->wallpaper.
But again, no idea how to turn the code into AHK if even possible.
Man, MS did some BS for a simple wallpaper change with fade.
How would IDesktopWallpaper look like? No idea how to swap that for IActiveDesktop to give it a try.
In mean time, ill keep digging and experimenting.
How you know which of these options you mentioned are the number for (i assume) vtable(AD, *option number*) ?
But all those codes i saw are for C/C++ and i dont know how and if possible to translate into AHK code.
Heres one site i saw for Win 7 apparently working.
https://www.neowin.net/forum/topic/1035 ... wallpaper/
Heres another interesting one.
https://stackoverflow.com/questions/147 ... er-restart
All have one thing in common i guess and its the handle. I made sure WorkerW is the handle but still no fade.
Also, i saw somewhere it was possible in C/C++ to trigger WorkerW to become desktops handle without going in task view or personalize->wallpaper.
But again, no idea how to turn the code into AHK if even possible.
Man, MS did some BS for a simple wallpaper change with fade.
How would IDesktopWallpaper look like? No idea how to swap that for IActiveDesktop to give it a try.
In mean time, ill keep digging and experimenting.
How you know which of these options you mentioned are the number for (i assume) vtable(AD, *option number*) ?
Who is online
Users browsing this forum: No registered users and 233 guests