-
Notifications
You must be signed in to change notification settings - Fork 48
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Is it possible to have a function registered to run whenever the virtual desktop changes? #14
Comments
me too. that code maybe from https://github.com/Ciantic/VirtualDesktopAccessor |
this is cool (that it's possible and that I am taught how to do something this complicated(well something that I didn't know how to do before(no pointers))) thanks @MaxSherry (and Ciantic) |
instead of #NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
#SingleInstance force
ListLines Off
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
SetBatchLines -1
#KeyHistory 0
Address1 := RegisterCallback("VD._CurrentVirtualDesktopChanged")
CurrentVirtualDesktopChanged(desktopNum) {
MsgBox % "desktopNum: " desktopNum
}
DllCall(Address1)
VD.CurrentVirtualDesktopChanged:=Func("CurrentVirtualDesktopChanged")
DllCall(Address1)
VD.CurrentVirtualDesktopChanged:=anotherClass.CurrentVirtualDesktopChanged.Bind(VD) ;automatically is a Func("anotherClass.CurrentVirtualDesktopChanged")
DllCall(Address1)
class anotherClass {
CurrentVirtualDesktopChanged(desktopNum) {
MsgBox % "desktopNum from anotherClass: " desktopNum
}
}
class VD {
_CurrentVirtualDesktopChanged() {
VD.CurrentVirtualDesktopChanged.Call(1) ;Call removes `this` as 1st argument
}
CurrentVirtualDesktopChanged(desktopNum) {
}
}
return
f3::Exitapp I've just realized that there are many complications with |
28 days ago, hmmm |
you can have these 2 files for now: #SingleInstance force
ListLines 0
KeyHistory 0
SendMode "Input" ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir A_ScriptDir ; Ensures a consistent starting directory.
VD.RegisterDesktopNotifications()
class VD {
static _QueryInterface(riid, ppvObject) { ;https://www.autohotkey.com/boards/viewtopic.php?t=36025&start=20#p176225
if (!ppvObject) {
return 0x80070057 ;E_INVALIDARG
}
str_IID_IUnknown:="{00000000-0000-0000-C000-000000000046}"
str_IID_IVirtualDesktopNotification:="{C179334C-4295-40D3-BEA1-C654D965605A}"
someStr:=Buffer(80)
DllCall("Ole32\StringFromGUID2", "Ptr", riid, "Ptr",someStr, "Ptr",40)
str_riid:=StrGet(someStr)
if (str_riid==str_IID_IUnknown || str_riid==str_IID_IVirtualDesktopNotification) {
NumPut("Ptr", this, ppvObject, 0)
VD._AddRef.Call(this)
return 0 ;S_OK
}
; *ppvObject = NULL;
NumPut("Ptr", 0, ppvObject, 0)
return 0x80004002 ;E_NOINTERFACE
; // Always set out parameter to NULL, validating it first.
; if (!ppvObject)
; return E_INVALIDARG;
; *ppvObject = NULL;
;
; if (riid == IID_IUnknown || riid == IID_IVirtualDesktopNotification)
; {
; // Increment the reference count and return the pointer.
; *ppvObject = (LPVOID)this;
; AddRef();
; return S_OK;
; }
; return E_NOINTERFACE;
}
static _AddRef() {
refCount:=NumGet(this, A_PtrSize, "UInt")
refCount++
NumPut("UInt", refCount, this, A_PtrSize)
; return InterlockedIncrement(&_referenceCount);
return refCount
}
static _Release() {
refCount:=NumGet(this, A_PtrSize, "UInt")
refCount--
NumPut("UInt", refCount, this, A_PtrSize)
; ULONG result = InterlockedDecrement(&_referenceCount);
; if (result == 0)
; {
; delete this;
; }
return refCount
}
static _VirtualDesktopCreated() {
Tooltip 11111
return 0 ;S_OK
}
static _VirtualDesktopDestroyBegin() {
Tooltip 22222
return 0 ;S_OK
}
static _VirtualDesktopDestroyFailed() {
Tooltip 33333
return 0 ;S_OK
}
static _VirtualDesktopDestroyed() {
Tooltip 44444
return 0 ;S_OK
}
static _ViewVirtualDesktopChanged() {
Tooltip 55555
return 0 ;S_OK
}
static _CurrentVirtualDesktopChanged() {
Tooltip 66666
return 0 ;S_OK
}
static RegisterDesktopNotifications() {
methods:=Buffer(9*A_PtrSize)
NumPut("Ptr", CallbackCreate(VD._QueryInterface, "F"), methods, 0*A_PtrSize)
NumPut("Ptr", CallbackCreate(VD._AddRef, "F"), methods, 1*A_PtrSize)
NumPut("Ptr", CallbackCreate(VD._Release, "F"), methods, 2*A_PtrSize)
NumPut("Ptr", CallbackCreate(VD._VirtualDesktopCreated, "F"), methods, 3*A_PtrSize)
NumPut("Ptr", CallbackCreate(VD._VirtualDesktopDestroyBegin, "F"), methods, 4*A_PtrSize)
NumPut("Ptr", CallbackCreate(VD._VirtualDesktopDestroyFailed, "F"), methods, 5*A_PtrSize)
NumPut("Ptr", CallbackCreate(VD._VirtualDesktopDestroyed, "F"), methods, 6*A_PtrSize)
NumPut("Ptr", CallbackCreate(VD._ViewVirtualDesktopChanged, "F"), methods, 7*A_PtrSize)
NumPut("Ptr", CallbackCreate(VD._CurrentVirtualDesktopChanged, "F"), methods, 8*A_PtrSize)
obj:=Buffer(A_PtrSize + 4)
NumPut("Ptr", methods.Ptr, obj, 0)
NumPut("UInt", 0, obj, A_PtrSize) ;refCount
this.methods:=methods ;PLEASE DON'T GARBAGE COLLECT IT, this took me hours to debug, I was lucky ahkv2 garbage collected slowly
this.obj:=obj ;PLEASE DON'T GARBAGE COLLECT IT, this took me hours to debug, I was lucky ahkv2 garbage collected slowly
; "CoCreateInstance", "Ptr" rclsid, IntPtr pUnkOuter, UInt32 dwClsContext, IntPtr riid, IntPtr ppv);
; pDesktopNotificationService:=ComObject("{A501FDEC-4A09-464C-AE4E-1B9C21B84918}", "{0CD45E71-D927-4F15-8B0A-8FEF525337BF}")
this.IServiceProvider := ComObject("{C2F03A33-21F5-47FA-B4BB-156362A2F239}", "{6D5140C1-7436-11CE-8034-00AA006009FA}")
pDesktopNotificationService := ComObjQuery(this.IServiceProvider, "{A501FDEC-4A09-464C-AE4E-1B9C21B84918}", "{0CD45E71-D927-4F15-8B0A-8FEF525337BF}")
HRESULT:=ComCall(3, pDesktopNotificationService, "Ptr",obj, "Uint*",&pdwCookie:=0)
ok2:=A_LastError
ok:=0
; HRESULT hrNotificationService = pServiceProvider->QueryService(
; CLSID_IVirtualNotificationService,
; __uuidof(IVirtualDesktopNotificationService),
; (PVOID*)&pDesktopNotificationService);
}
static _vtable(ppv, index) {
Return NumGet(NumGet(ppv.Ptr, 0, "Ptr")+A_PtrSize*index, 0, "Ptr")
}
}
return
f3::Exitapp
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
#SingleInstance force
ListLines Off
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
SetBatchLines -1
#KeyHistory 0
VD.RegisterDesktopNotifications()
class VD {
_QueryInterface(riid, ppvObject) { ;https://www.autohotkey.com/boards/viewtopic.php?t=36025&start=20#p176225
if (!ppvObject) {
return 0x80070057 ;E_INVALIDARG
}
str_IID_IUnknown:="{00000000-0000-0000-C000-000000000046}"
str_IID_IVirtualDesktopNotification:="{C179334C-4295-40D3-BEA1-C654D965605A}"
VarSetCapacity(someStr, 40)
DllCall("Ole32\StringFromGUID2", "Ptr", riid, "Ptr",&someStr, "Ptr",40)
str_riid:=StrGet(&someStr)
if (str_riid==str_IID_IUnknown || str_riid==str_IID_IVirtualDesktopNotification) {
NumPut(this, ppvObject+0, 0, "Ptr")
VD._AddRef.Call(this)
return 0 ;S_OK
}
; *ppvObject = NULL;
NumPut(0, ppvObject+0, 0, "Ptr")
return 0x80004002 ;E_NOINTERFACE
; // Always set out parameter to NULL, validating it first.
; if (!ppvObject)
; return E_INVALIDARG;
; *ppvObject = NULL;
;
; if (riid == IID_IUnknown || riid == IID_IVirtualDesktopNotification)
; {
; // Increment the reference count and return the pointer.
; *ppvObject = (LPVOID)this;
; AddRef();
; return S_OK;
; }
; return E_NOINTERFACE;
}
_AddRef() {
refCount:=NumGet(this+0, A_PtrSize, "UInt")
refCount++
NumPut(refCount, this+0, A_PtrSize, "UInt")
; return InterlockedIncrement(&_referenceCount);
return refCount
}
_Release() {
refCount:=NumGet(this+0, A_PtrSize, "UInt")
refCount--
NumPut(refCount, this+0, A_PtrSize, "UInt")
; ULONG result = InterlockedDecrement(&_referenceCount);
; if (result == 0)
; {
; delete this;
; }
return refCount
}
_VirtualDesktopCreated() {
Tooltip % 11111
return 0 ;S_OK
}
_VirtualDesktopDestroyBegin() {
Tooltip % 22222
return 0 ;S_OK
}
_VirtualDesktopDestroyFailed() {
Tooltip % 33333
return 0 ;S_OK
}
_VirtualDesktopDestroyed() {
Tooltip % 44444
return 0 ;S_OK
}
_ViewVirtualDesktopChanged() {
Tooltip % 55555
return 0 ;S_OK
}
_CurrentVirtualDesktopChanged() {
Tooltip % 66666
return 0 ;S_OK
}
RegisterDesktopNotifications() {
methods:=DllCall("GlobalAlloc", "Uint",0x40, "Uint",8*A_PtrSize) ;PLEASE DON'T GARBAGE COLLECT IT, this took me hours to debug, I was lucky ahkv2 garbage collected slowly
NumPut(RegisterCallback("VD._QueryInterface", "F"), methods+0, 0*A_PtrSize, "Ptr")
NumPut(RegisterCallback("VD._AddRef", "F"), methods+0, 1*A_PtrSize, "Ptr")
NumPut(RegisterCallback("VD._Release", "F"), methods+0, 2*A_PtrSize, "Ptr")
NumPut(RegisterCallback("VD._VirtualDesktopCreated", "F"), methods+0, 3*A_PtrSize, "Ptr")
NumPut(RegisterCallback("VD._VirtualDesktopDestroyBegin", "F"), methods+0, 4*A_PtrSize, "Ptr")
NumPut(RegisterCallback("VD._VirtualDesktopDestroyFailed", "F"), methods+0, 5*A_PtrSize, "Ptr")
NumPut(RegisterCallback("VD._VirtualDesktopDestroyed", "F"), methods+0, 6*A_PtrSize, "Ptr")
NumPut(RegisterCallback("VD._ViewVirtualDesktopChanged", "F"), methods+0, 7*A_PtrSize, "Ptr")
NumPut(RegisterCallback("VD._CurrentVirtualDesktopChanged", "F"), methods+0, 8*A_PtrSize, "Ptr")
obj:=DllCall("GlobalAlloc", "Uint",0x40, "Uint",A_PtrSize + 4) ;PLEASE DON'T GARBAGE COLLECT IT, this took me hours to debug, I was lucky ahkv2 garbage collected slowly
NumPut(methods, obj+0, 0, "Ptr")
NumPut(0, obj+0, A_PtrSize, "UInt") ;refCount
; "CoCreateInstance", "Ptr" rclsid, IntPtr pUnkOuter, UInt32 dwClsContext, IntPtr riid, IntPtr ppv);
; pDesktopNotificationService:=ComObjCreate("{A501FDEC-4A09-464C-AE4E-1B9C21B84918}", "{0CD45E71-D927-4F15-8B0A-8FEF525337BF}")
this.IServiceProvider := ComObjCreate("{C2F03A33-21F5-47FA-B4BB-156362A2F239}", "{6D5140C1-7436-11CE-8034-00AA006009FA}")
pDesktopNotificationService := ComObjQuery(this.IServiceProvider, "{A501FDEC-4A09-464C-AE4E-1B9C21B84918}", "{0CD45E71-D927-4F15-8B0A-8FEF525337BF}")
Register:=this._vtable(pDesktopNotificationService, 3)
HRESULT:=DllCall(Register,"UPtr",pDesktopNotificationService, "Ptr",obj, "Uint*",pdwCookie:=0)
ok1:=ErrorLevel
ok2:=A_LastError
ok:=0
; HRESULT hrNotificationService = pServiceProvider->QueryService(
; CLSID_IVirtualNotificationService,
; __uuidof(IVirtualDesktopNotificationService),
; (PVOID*)&pDesktopNotificationService);
}
_vtable(ppv, index) {
Return NumGet(NumGet(ppv+0, 0, "Ptr")+index*A_PtrSize, 0, "Ptr")
; Return NumGet(NumGet(0+ppv)+A_PtrSize*index)
}
}
return
f3::Exitapp |
it is done, VD.ahk/other examples/CurrentVirtualDesktopChanged RegisterDesktopNotifications.ahk Lines 9 to 14 in 73e52f9
|
Thank you so much for working on this request, and so quickly once you started!! I've tested this out on my two computers and it works perfectly in Windows 10, but still doesn't work in Windows 11 for me. I'm assuming the {GUID} is different in Windows 11, but I don't know enough about that to figure it out and test. Thank you again for looking into it, and for adding the functionality. |
MScholtes/VirtualDesktop#29 (comment) |
Thanks to @NyaMisty |
@TWF1212 notification, Win11 done |
Amazing, it is working perfectly! thank you so much. |
I've been using some form of my own custom Virtual Desktop manager using AHK for awhile, and it all broke with Windows 11.
I found your class, and was able to implement it and everything is working perfectly. Thank you!
One thing that would be nice, that seemed to work in windows 10, using an OnMessage Listener:
I don't remember where I got that bit of code from, but it worked in Windows 10.
My use case is that I have an icon that I made myself that shows which desktop I am currently on located in the taskbar. I can manually make sure it is accurate when I use the program to change desktops, but on occasion Windows will pull me to another desktop when I click on a notification, or I'll sometimes use the built-in
Ctrl+Win+Left/Right
to change desktop instead. This then de-syncs my icon until I use the program to switch again.I have a work around of using a SetTimer that will always get current number and update the icon accordingly, but I'd prefer to again be able to just have a function that runs whenever the desktop is changed.
I was thinking of maybe being able to register a function in your VD class that will then be used as this callback function.
i.e.
Figured I'd ask, if this isn't possible not a problem as I am happy enough with my workaround.
Thank you.
The text was updated successfully, but these errors were encountered: