Is there an "open folder" event Topic is solved
-
- Posts: 115
- Joined: 18 Dec 2020, 05:17
Re: Is there an "open folder" event
Oh, there's no folder path since I just wanted to check if a particular file was opened. I'd use your solution to check if a folder was opened.
-
- Posts: 4602
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: Is there an "open folder" event
If the folder has been opened this doesn't mean that the file has been launched from that folder.
-
- Posts: 115
- Joined: 18 Dec 2020, 05:17
Re: Is there an "open folder" event
You're right!
I think the answer is somewhere here: https://www.autohotkey.com/boards/viewtopic.php?p=120546#p120546
But it's way above my pay grade lol.
I think the answer is somewhere here: https://www.autohotkey.com/boards/viewtopic.php?p=120546#p120546
But it's way above my pay grade lol.
-
- Posts: 4602
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: Is there an "open folder" event
If you mean reading the command line of the process, this is an option, but the command line does not have to contain the path to the currently open file.
-
- Posts: 4
- Joined: 27 Jul 2021, 14:30
Re: Is there an "open folder" event
Thank you so much for this. What if one wants to change the monitored folder (while the script is already running)? Or in another case, turning off the folder monitoring completely without exiting the script. Is there a way to do these?teadrinker wrote: ↑27 Sep 2020, 08:22If the Program Files folder or its subfolder is open, a message will appear.Code: Select all
#Persistent global EVENT_OBJECT_SHOW := 0x8002 , EVENT_OBJECT_NAMECHANGE := 0x800C folderPath := "C:\Program Files" WatchFolders := Func("IsMyFolderOpened").Bind(folderPath) Hook := new WinEventHook(EVENT_OBJECT_SHOW, EVENT_OBJECT_NAMECHANGE, "HookProc", Object(WatchFolders)) IsMyFolderOpened(folderPath, hWnd) { openedFolderPath := GetFolderPath(hWnd) if InStr(openedFolderPath, folderPath . "\") || openedFolderPath = folderPath MsgBox, Folder %openedFolderPath% was opened } HookProc(hWinEventHook, event, hwnd, idObject, idChild, dwEventThread, dwmsEventTime) { static OBJID_WINDOW := 0, CallBack, prevTime := 0 (!CallBack && CallBack := Object(A_EventInfo)) if (idObject != OBJID_WINDOW) Return if !(event = EVENT_OBJECT_SHOW || event = EVENT_OBJECT_NAMECHANGE) Return WinGetClass, winClass, ahk_id %hwnd% if (winClass != "CabinetWClass") Return if (A_TickCount - prevTime < 300) Return prevTime := A_TickCount CallBack.(hwnd) } GetFolderPath(hWnd := "") { (!hWnd && hWnd := WinExist("A")) WinGetClass, winClass, ahk_id %hWnd% if !(winClass ~="Progman|WorkerW|(Cabinet|Explore)WClass") Return if (winClass ~= "Progman|WorkerW") Return A_Desktop for window in ComObjCreate("Shell.Application").Windows { if (hWnd = window.HWND && dirPath := window.Document.Folder.Self.Path) break } Return dirPath } class WinEventHook { __New(eventMin, eventMax, hookProc, eventInfo := 0, idProcess := 0, idThread := 0, dwFlags := 0) { this.pCallback := RegisterCallback(hookProc, "F",, eventInfo) this.hHook := DllCall("SetWinEventHook", "UInt", eventMin, "UInt", eventMax, "Ptr", 0, "Ptr", this.pCallback , "UInt", idProcess, "UInt", idThread, "UInt", dwFlags, "Ptr") } __Delete() { DllCall("UnhookWinEvent", "Ptr", this.hHook) DllCall("GlobalFree", "Ptr", this.pCallback, "Ptr") } }
-
- Posts: 4602
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: Is there an "open folder" event
Of course.AutoGiraffe wrote: ↑Is there a way to do these?
Code: Select all
#Persistent
global EVENT_OBJECT_SHOW := 0x8002
, EVENT_OBJECT_NAMECHANGE := 0x800C
WatchFolders := Func("IsMyFolderOpened").Bind(folderPathObj := [])
pObj := Object(WatchFolders)
Return
$F1:: folderPathObj[1] := SelectFolderEx(, "Select the folder to monitor")
$F2::
if !InStr( FileExist(folderPathObj[1]), "D" )
MsgBox, No folder chosen
else
Hook := new WinEventHook(EVENT_OBJECT_SHOW, EVENT_OBJECT_NAMECHANGE, "HookProc", pObj)
Return
$F3:: Hook := ""
IsMyFolderOpened(obj, hWnd) {
openedFolderPath := GetFolderPath(hWnd)
if InStr(openedFolderPath, obj[1] . "\") || openedFolderPath = obj[1]
MsgBox, Folder %openedFolderPath% was opened
}
HookProc(hWinEventHook, event, hwnd, idObject, idChild, dwEventThread, dwmsEventTime) {
static OBJID_WINDOW := 0, CallBack, prevTime := 0
(!CallBack && CallBack := Object(A_EventInfo))
if (idObject != OBJID_WINDOW)
Return
if !(event = EVENT_OBJECT_SHOW || event = EVENT_OBJECT_NAMECHANGE)
Return
WinGetClass, winClass, ahk_id %hwnd%
if (winClass != "CabinetWClass")
Return
if (A_TickCount - prevTime < 300)
Return
prevTime := A_TickCount
CallBack.(hwnd)
}
GetFolderPath(hWnd := "") {
(!hWnd && hWnd := WinExist("A"))
WinGetClass, winClass, ahk_id %hWnd%
if !(winClass ~="Progman|WorkerW|(Cabinet|Explore)WClass")
Return
if (winClass ~= "Progman|WorkerW")
Return A_Desktop
for window in ComObjCreate("Shell.Application").Windows {
if (hWnd = window.HWND && dirPath := window.Document.Folder.Self.Path)
break
}
Return dirPath
}
class WinEventHook
{
__New(eventMin, eventMax, hookProc, eventInfo := 0, idProcess := 0, idThread := 0, dwFlags := 0) {
this.pCallback := RegisterCallback(hookProc, "F",, eventInfo)
this.hHook := DllCall("SetWinEventHook", "UInt", eventMin, "UInt", eventMax, "Ptr", 0, "Ptr", this.pCallback
, "UInt", idProcess, "UInt", idThread, "UInt", dwFlags, "Ptr")
}
__Delete() {
DllCall("UnhookWinEvent", "Ptr", this.hHook)
DllCall("GlobalFree", "Ptr", this.pCallback, "Ptr")
}
}
SelectFolderEx(StartingFolder := "", Prompt := "", OwnerHwnd := 0, OkBtnLabel := "") {
static OsVersion := DllCall("GetVersion", "UChar")
, IID_IShellItem := 0
, InitIID := VarSetCapacity(IID_IShellItem, 16, 0)
& DllCall("Ole32.dll\IIDFromString", "WStr", "{43826d1e-e718-42ee-bc55-a1e261c37bfe}", "Ptr", &IID_IShellItem)
, Show := A_PtrSize * 3
, SetOptions := A_PtrSize * 9
, SetFolder := A_PtrSize * 12
, SetTitle := A_PtrSize * 17
, SetOkButtonLabel := A_PtrSize * 18
, GetResult := A_PtrSize * 20
SelectedFolder := ""
if (OsVersion < 6) { ; IFileDialog requires Win Vista+, so revert to FileSelectFolder
FileSelectFolder, SelectedFolder, *%StartingFolder%, 3, %Prompt%
Return SelectedFolder
}
OwnerHwnd := DllCall("IsWindow", "Ptr", OwnerHwnd, "UInt") ? OwnerHwnd : 0
if !(FileDialog := ComObjCreate("{DC1C5A9C-E88A-4dde-A5A1-60F82A20AEF7}", "{42f85136-db7e-439c-85f1-e4075d135fc8}"))
Return ""
VTBL := NumGet(FileDialog + 0, "UPtr")
; FOS_CREATEPROMPT | FOS_NOCHANGEDIR | FOS_PICKFOLDERS
DllCall(NumGet(VTBL + SetOptions, "UPtr"), "Ptr", FileDialog, "UInt", 0x00002028, "UInt")
if (StartingFolder <> "")
if !DllCall("Shell32.dll\SHCreateItemFromParsingName", "WStr", StartingFolder, "Ptr", 0, "Ptr", &IID_IShellItem, "PtrP", FolderItem)
DllCall(NumGet(VTBL + SetFolder, "UPtr"), "Ptr", FileDialog, "Ptr", FolderItem, "UInt")
if (Prompt <> "")
DllCall(NumGet(VTBL + SetTitle, "UPtr"), "Ptr", FileDialog, "WStr", Prompt, "UInt")
if (OkBtnLabel <> "")
DllCall(NumGet(VTBL + SetOkButtonLabel, "UPtr"), "Ptr", FileDialog, "WStr", OkBtnLabel, "UInt")
if !DllCall(NumGet(VTBL + Show, "UPtr"), "Ptr", FileDialog, "Ptr", OwnerHwnd, "UInt") {
if !DllCall(NumGet(VTBL + GetResult, "UPtr"), "Ptr", FileDialog, "PtrP", ShellItem, "UInt") {
GetDisplayName := NumGet(NumGet(ShellItem + 0, "UPtr"), A_PtrSize * 5, "UPtr")
if !DllCall(GetDisplayName, "Ptr", ShellItem, "UInt", 0x80028000, "PtrP", StrPtr) ; SIGDN_DESKTOPABSOLUTEPARSING
SelectedFolder := StrGet(StrPtr, "UTF-16"), DllCall("Ole32.dll\CoTaskMemFree", "Ptr", StrPtr)
ObjRelease(ShellItem)
} }
if (FolderItem)
ObjRelease(FolderItem)
ObjRelease(FileDialog)
Return SelectedFolder
}
-
- Posts: 1
- Joined: 28 Jul 2021, 00:55
Re: Is there an "open folder" event
Very much obliged!
Re: Is there an "open folder" event
This is an impressive piece of code! I know this is the v1.1 forum, but is there any chance we can port this to v2? I tried doing it myself, but, alas, it proved to be difficult (as expected) for a mortal like myself.teadrinker wrote: ↑27 Jul 2021, 19:31Code: Select all
#Persistent global EVENT_OBJECT_SHOW := 0x8002 , EVENT_OBJECT_NAMECHANGE := 0x800C WatchFolders := Func("IsMyFolderOpened").Bind(folderPathObj := []) pObj := Object(WatchFolders) Return $F1:: folderPathObj[1] := SelectFolderEx(, "Select the folder to monitor") $F2:: if !InStr( FileExist(folderPathObj[1]), "D" ) MsgBox, No folder chosen else Hook := new WinEventHook(EVENT_OBJECT_SHOW, EVENT_OBJECT_NAMECHANGE, "HookProc", pObj) Return $F3:: Hook := "" IsMyFolderOpened(obj, hWnd) { openedFolderPath := GetFolderPath(hWnd) if InStr(openedFolderPath, obj[1] . "\") || openedFolderPath = obj[1] MsgBox, Folder %openedFolderPath% was opened } HookProc(hWinEventHook, event, hwnd, idObject, idChild, dwEventThread, dwmsEventTime) { static OBJID_WINDOW := 0, CallBack, prevTime := 0 (!CallBack && CallBack := Object(A_EventInfo)) if (idObject != OBJID_WINDOW) Return if !(event = EVENT_OBJECT_SHOW || event = EVENT_OBJECT_NAMECHANGE) Return WinGetClass, winClass, ahk_id %hwnd% if (winClass != "CabinetWClass") Return if (A_TickCount - prevTime < 300) Return prevTime := A_TickCount CallBack.(hwnd) } GetFolderPath(hWnd := "") { (!hWnd && hWnd := WinExist("A")) WinGetClass, winClass, ahk_id %hWnd% if !(winClass ~="Progman|WorkerW|(Cabinet|Explore)WClass") Return if (winClass ~= "Progman|WorkerW") Return A_Desktop for window in ComObjCreate("Shell.Application").Windows { if (hWnd = window.HWND && dirPath := window.Document.Folder.Self.Path) break } Return dirPath } class WinEventHook { __New(eventMin, eventMax, hookProc, eventInfo := 0, idProcess := 0, idThread := 0, dwFlags := 0) { this.pCallback := RegisterCallback(hookProc, "F",, eventInfo) this.hHook := DllCall("SetWinEventHook", "UInt", eventMin, "UInt", eventMax, "Ptr", 0, "Ptr", this.pCallback , "UInt", idProcess, "UInt", idThread, "UInt", dwFlags, "Ptr") } __Delete() { DllCall("UnhookWinEvent", "Ptr", this.hHook) DllCall("GlobalFree", "Ptr", this.pCallback, "Ptr") } } SelectFolderEx(StartingFolder := "", Prompt := "", OwnerHwnd := 0, OkBtnLabel := "") { static OsVersion := DllCall("GetVersion", "UChar") , IID_IShellItem := 0 , InitIID := VarSetCapacity(IID_IShellItem, 16, 0) & DllCall("Ole32.dll\IIDFromString", "WStr", "{43826d1e-e718-42ee-bc55-a1e261c37bfe}", "Ptr", &IID_IShellItem) , Show := A_PtrSize * 3 , SetOptions := A_PtrSize * 9 , SetFolder := A_PtrSize * 12 , SetTitle := A_PtrSize * 17 , SetOkButtonLabel := A_PtrSize * 18 , GetResult := A_PtrSize * 20 SelectedFolder := "" if (OsVersion < 6) { ; IFileDialog requires Win Vista+, so revert to FileSelectFolder FileSelectFolder, SelectedFolder, *%StartingFolder%, 3, %Prompt% Return SelectedFolder } OwnerHwnd := DllCall("IsWindow", "Ptr", OwnerHwnd, "UInt") ? OwnerHwnd : 0 if !(FileDialog := ComObjCreate("{DC1C5A9C-E88A-4dde-A5A1-60F82A20AEF7}", "{42f85136-db7e-439c-85f1-e4075d135fc8}")) Return "" VTBL := NumGet(FileDialog + 0, "UPtr") ; FOS_CREATEPROMPT | FOS_NOCHANGEDIR | FOS_PICKFOLDERS DllCall(NumGet(VTBL + SetOptions, "UPtr"), "Ptr", FileDialog, "UInt", 0x00002028, "UInt") if (StartingFolder <> "") if !DllCall("Shell32.dll\SHCreateItemFromParsingName", "WStr", StartingFolder, "Ptr", 0, "Ptr", &IID_IShellItem, "PtrP", FolderItem) DllCall(NumGet(VTBL + SetFolder, "UPtr"), "Ptr", FileDialog, "Ptr", FolderItem, "UInt") if (Prompt <> "") DllCall(NumGet(VTBL + SetTitle, "UPtr"), "Ptr", FileDialog, "WStr", Prompt, "UInt") if (OkBtnLabel <> "") DllCall(NumGet(VTBL + SetOkButtonLabel, "UPtr"), "Ptr", FileDialog, "WStr", OkBtnLabel, "UInt") if !DllCall(NumGet(VTBL + Show, "UPtr"), "Ptr", FileDialog, "Ptr", OwnerHwnd, "UInt") { if !DllCall(NumGet(VTBL + GetResult, "UPtr"), "Ptr", FileDialog, "PtrP", ShellItem, "UInt") { GetDisplayName := NumGet(NumGet(ShellItem + 0, "UPtr"), A_PtrSize * 5, "UPtr") if !DllCall(GetDisplayName, "Ptr", ShellItem, "UInt", 0x80028000, "PtrP", StrPtr) ; SIGDN_DESKTOPABSOLUTEPARSING SelectedFolder := StrGet(StrPtr, "UTF-16"), DllCall("Ole32.dll\CoTaskMemFree", "Ptr", StrPtr) ObjRelease(ShellItem) } } if (FolderItem) ObjRelease(FolderItem) ObjRelease(FileDialog) Return SelectedFolder }
For SelectFolderEx(), v2 offers FileSelect("D"), which is nice. However, I just can't wrap my head around the DllCalls and the objects. RegisterCallback is also deprecated, but I can't make the newer CallbackCreate work. It's also my first time seeing CallBack.(hwnd), and from the docs, it should be akin to CallBack[""].hwnd. I could keep on going... Anyway, I would appreciate any help
-
- Posts: 4602
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: Is there an "open folder" event
Thank you! Will do