Hey.
I am looking into how to manage windows on multiple virtual desktops.
I found this API: https://docs.microsoft.com/en-us/window ... wdesktopid
But I am not that experienced with `DllCall()`.
How would I use this API in an AHK script?
Thank you
How to call a Win32 API with UUID [IVirtualDesktopManager]
-
- Posts: 9
- Joined: 16 Jun 2015, 06:40
- Contact:
Re: How to call a Win32 API with UUID [IVirtualDesktopManager] [IVirtualDesktopManagerInternal]
Code: Select all
; IVirtualDesktopManager interface
; https://docs.microsoft.com/en-us/windows/desktop/api/shobjidl_core/nn-shobjidl_core-ivirtualdesktopmanager
IVirtualDesktopManager := ComObjCreate("{AA509086-5CA9-4C25-8F95-589D3C07B48A}", "{A5CD92FF-29BE-454C-8D04-D82879FB3F1B}")
IsWindowOnCurrentVirtualDesktop := NumGet(NumGet(IVirtualDesktopManager+0)+3*A_PtrSize)
GetWindowDesktopId := NumGet(NumGet(IVirtualDesktopManager+0)+4*A_PtrSize)
MoveWindowToDesktop := NumGet(NumGet(IVirtualDesktopManager+0)+5*A_PtrSize)
/*
IServiceProvider := ComObjCreate("{C2F03A33-21F5-47FA-B4BB-156362A2F239}", "{6D5140C1-7436-11CE-8034-00AA006009FA}")
IVirtualDesktopManagerInternal := ComObjQuery(IServiceProvider, "{C5E0CDCA-7B6E-41B2-9FC4-D93975CC467B}", "{F31574D6-B682-4CDC-BD56-1827860ABEC6}")
GetCount := NumGet(NumGet(IVirtualDesktopManagerInternal+0)+3*A_PtrSize)
MoveViewDesktop := NumGet(NumGet(IVirtualDesktopManagerInternal+0)+4*A_PtrSize)
CanViewMoveDesktops := NumGet(NumGet(IVirtualDesktopManagerInternal+0)+5*A_PtrSize)
GetCurrentDesktop := NumGet(NumGet(IVirtualDesktopManagerInternal+0)+6*A_PtrSize)
GetDesktops := NumGet(NumGet(IVirtualDesktopManagerInternal+0)+7*A_PtrSize)
GetAdjacentDesktop := NumGet(NumGet(IVirtualDesktopManagerInternal+0)+8*A_PtrSize)
SwitchDesktop := NumGet(NumGet(IVirtualDesktopManagerInternal+0)+9*A_PtrSize)
CreateDesktopW := NumGet(NumGet(IVirtualDesktopManagerInternal+0)+10*A_PtrSize)
RemoveDesktop := NumGet(NumGet(IVirtualDesktopManagerInternal+0)+11*A_PtrSize)
FindDesktop := NumGet(NumGet(IVirtualDesktopManagerInternal+0)+12*A_PtrSize)
*/
; IVirtualDesktopManager::GetWindowDesktopId method
; https://docs.microsoft.com/en-us/windows/desktop/api/shobjidl_core/nf-shobjidl_core-ivirtualdesktopmanager-getwindowdesktopid
TopLevelWindow := WinExist("A")
VarSetCapacity(GUID, 16)
R := DllCall(GetWindowDesktopId, "UPtr", IVirtualDesktopManager, "Ptr", TopLevelWindow, "UPtr", &GUID, "UInt")
if ( !R ) ; OK
{
VarSetCapacity(strGUID, (38 + 1) * 2)
DllCall("Ole32.dll\StringFromGUID2", "UPtr", &GUID, "UPtr", &strGUID, "Int", 38 + 1)
MsgBox % "Identifier for the virtual desktop hosting the topLevelWindow`n" . StrGet(&strGUID, "UTF-16")
}
ExitApp
-
- Posts: 9
- Joined: 16 Jun 2015, 06:40
- Contact:
Re: How to call a Win32 API with UUID [IVirtualDesktopManager]
Awesome.
Thank you, Flipeador
Thank you, Flipeador
-
- Posts: 9
- Joined: 16 Jun 2015, 06:40
- Contact:
Re: How to call a Win32 API with UUID [IVirtualDesktopManager]
@Flipeador
could you show me how to use the parts you have commented out, such as "GetDesktops"?
could you show me how to use the parts you have commented out, such as "GetDesktops"?
Re: How to call a Win32 API with UUID [IVirtualDesktopManager]
The IVirtualDesktopManagerInternal interface is not officially documented by Microsoft, it could stop working in any Windows update!.
As there is nothing documented, it is not easy to guess how it works, what are you trying to do?. I guess that number at the end of IVirtualDesktopManagerInternal has something to do with the Windows version (IVirtualDesktopManagerInternal14328).
Code: Select all
; IVirtualDesktopManager interface
; https://docs.microsoft.com/en-us/windows/desktop/api/shobjidl_core/nn-shobjidl_core-ivirtualdesktopmanager
IVirtualDesktopManager := ComObjCreate("{AA509086-5CA9-4C25-8F95-589D3C07B48A}", "{A5CD92FF-29BE-454C-8D04-D82879FB3F1B}")
IsWindowOnCurrentVirtualDesktop := NumGet(NumGet(IVirtualDesktopManager+0)+3*A_PtrSize)
GetWindowDesktopId := NumGet(NumGet(IVirtualDesktopManager+0)+4*A_PtrSize)
MoveWindowToDesktop := NumGet(NumGet(IVirtualDesktopManager+0)+5*A_PtrSize)
; internal interface IVirtualDesktopManagerInternal14328
; https://sourceforge.net/p/virtual-desktop-grid-switcher/src/ci/d85ff70ced929d161bd45d10a47ebb0c0f2a1f68/tree/VirtualDesktop-master/source/VirtualDesktop/Interop/IVirtualDesktopManagerInternal.cs#l71
IServiceProvider := ComObjCreate("{C2F03A33-21F5-47FA-B4BB-156362A2F239}", "{6D5140C1-7436-11CE-8034-00AA006009FA}")
IVirtualDesktopManagerInternal := ComObjQuery(IServiceProvider, "{C5E0CDCA-7B6E-41B2-9FC4-D93975CC467B}", "{F31574D6-B682-4CDC-BD56-1827860ABEC6}")
GetCount := NumGet(NumGet(IVirtualDesktopManagerInternal+0)+3*A_PtrSize)
MoveViewDesktop := NumGet(NumGet(IVirtualDesktopManagerInternal+0)+4*A_PtrSize)
CanViewMoveDesktops := NumGet(NumGet(IVirtualDesktopManagerInternal+0)+5*A_PtrSize)
GetCurrentDesktop := NumGet(NumGet(IVirtualDesktopManagerInternal+0)+6*A_PtrSize)
GetDesktops := NumGet(NumGet(IVirtualDesktopManagerInternal+0)+7*A_PtrSize)
GetAdjacentDesktop := NumGet(NumGet(IVirtualDesktopManagerInternal+0)+8*A_PtrSize)
SwitchDesktop := NumGet(NumGet(IVirtualDesktopManagerInternal+0)+9*A_PtrSize)
CreateDesktopW := NumGet(NumGet(IVirtualDesktopManagerInternal+0)+10*A_PtrSize)
RemoveDesktop := NumGet(NumGet(IVirtualDesktopManagerInternal+0)+11*A_PtrSize)
FindDesktop := NumGet(NumGet(IVirtualDesktopManagerInternal+0)+12*A_PtrSize)
; IVirtualDesktopManagerInternal::GetDesktops method
IObjectArray := 0
DllCall(GetDesktops, "UPtr", IVirtualDesktopManagerInternal, "UPtrP", IObjectArray, "UInt")
; IObjectArray::GetCount method
; https://docs.microsoft.com/en-us/windows/desktop/api/objectarray/nf-objectarray-iobjectarray-getcount
Count := 0
DllCall(NumGet(NumGet(IObjectArray+0)+3*A_PtrSize), "UPtr", IObjectArray, "UIntP", Count, "UInt")
VarSetCapacity(strGUID, (38 + 1) * 2)
VarSetCapacity(GUID, 16)
IVirtualDesktop := 0
Loop % (Count)
{
; https://github.com/nullpo-head/Windows-10-Virtual-Desktop-Switching-Shortcut/blob/master/VirtualDesktopSwitcher/VirtualDesktopSwitcher/VirtualDesktops.h
DllCall("Ole32.dll\CLSIDFromString", "Str", "{FF72FFDD-BE7E-43FC-9C03-AD81681E88E4}", "UPtr", &GUID)
; IObjectArray::GetAt method
; https://docs.microsoft.com/en-us/windows/desktop/api/objectarray/nf-objectarray-iobjectarray-getat
DllCall(NumGet(NumGet(IObjectArray+0)+4*A_PtrSize), "UPtr", IObjectArray, "UInt", A_Index-1, "UPtr", &GUID, "UPtrP", IVirtualDesktop, "UInt")
; IVirtualDesktop::GetID method
DllCall(NumGet(NumGet(IVirtualDesktop+0)+4*A_PtrSize), "UPtr", IVirtualDesktop, "UPtr", &GUID, "UInt")
DllCall("Ole32.dll\StringFromGUID2", "UPtr", &GUID, "UPtr", &strGUID, "Int", 38 + 1)
MsgBox % StrGet(&strGUID, "UTF-16")
}
-
- Posts: 9
- Joined: 16 Jun 2015, 06:40
- Contact:
Re: How to call a Win32 API with UUID [IVirtualDesktopManager]
I am trying to write a script where I can record a state of what window/program goes on what VD.
And when I (re)boot, it will reconstruct that setup - instead of me having to move windows to other VDs.
I found this script which reads the UUIDs of the VDs from the registry.
https://github.com/pmb6tz/windows-deskt ... hk#L24-L49
And when I (re)boot, it will reconstruct that setup - instead of me having to move windows to other VDs.
I found this script which reads the UUIDs of the VDs from the registry.
https://github.com/pmb6tz/windows-deskt ... hk#L24-L49
Re: How to call a Win32 API with UUID [IVirtualDesktopManager]
Yes, reading from the registry and using the Send command is the most "simple" way to do it. The correct (and serious) way to do it would be with DllCall, the only problem, as I mentioned, is that it could stop working with future Windows updates (nothing that we can not solve).
I'll see what I can do.
I'll see what I can do.
Re: How to call a Win32 API with UUID [IVirtualDesktopManager]
I have tried to use MoveWindowToDesktop but it does not work with the windows of other processes, it only works with the windows of your script. Maybe it can work by hooking or inject a DLL, but things get too complicated (this would take work). When you try to call the method, it returns 0x80070005 (E_ACCESSDENIED).
Links of interest:
https://stackoverflow.com/questions/318 ... l-desktops
https://github.com/Grabacr07/SylphyHorn
https://github.com/Eun/MoveToDesktop
https://github.com/tmyt/VDMHelper
https://autohotkey.com/boards/viewtopic.php?t=5571
Honestly I can not think of any simple way to move a window to another virtual desktop. Maybe someone who has experience injecting code into another process can help you. If I find any way I will let you know.
Links of interest:
https://stackoverflow.com/questions/318 ... l-desktops
https://github.com/Grabacr07/SylphyHorn
https://github.com/Eun/MoveToDesktop
https://github.com/tmyt/VDMHelper
https://autohotkey.com/boards/viewtopic.php?t=5571
Honestly I can not think of any simple way to move a window to another virtual desktop. Maybe someone who has experience injecting code into another process can help you. If I find any way I will let you know.
-
- Posts: 9
- Joined: 16 Jun 2015, 06:40
- Contact:
Re: How to call a Win32 API with UUID [IVirtualDesktopManager]
I appreciate the help
Re: How to call a Win32 API with UUID [IVirtualDesktopManager]
I had written a script to move windows between virtual desktops using the function MoveWindowToDesktopNumberProc from https://github.com/Ciantic/VirtualDesktopAccessor/