The COM table is basically a list of applications that register with Windows saying that they want to let other applications communicate with them and here is their number to call them. In short it is a dating site for applications that Windows runs to help programs hookup and create lots of little subroutines.
Here is a script what will let you see all Active COM objects and also a function to get a connection to all Workbooks regardless of if they are open in separate processes of Excel.
Code: Select all
; Lexikos example to get all active objects
list := "All Active COM Objects`n"
for name, obj in GetActiveObjects()
list .= name " -- " ComObjType(obj, "Name") "`n"
MsgBox %list%
; FanaticGuru example of Excel_Objects class method Xls
list := "All Excel Workbooks and Visible State`n"
Xls := Excel_Objects.Xls() ; Get all Excel objects
for index, Xl in Xls
for Workbook in Xl.Workbooks
list .= Workbook.name "`t" Workbook.Windows(1).Visible "`n"
MsgBox %list%
; FanaticGuru example of Excel_Objects class method Wbs
list := "All Visible Excel Workbooks and Visible State`n"
Wbs := Excel_Objects.Wbs(,1) ; only visible workbooks
for index, Wb in Wbs
list .= Wb.Name "`t" Wb.Windows(1).Visible "`n"
MsgBox %list%
Esc::ExitApp
class Excel_Objects
{
Xls(Needle := "")
{
Xls := {}
for index, obj in GetActiveObjects()
{
try
Name := obj.Application.ActiveWorkbook.Name
catch
continue
if (RegExMatch(index, "(^|\\)" Name "$") and RegExMatch(Name, Needle))
Xls.Push(obj.Application)
}
return Xls
}
Wbs(Needle := "", Visible := "")
{
Wbs := {}
Xls := Excel_Objects.Xls()
for index, Xl in Xls
for Workbook in Xl.Workbooks
if RegExMatch(Workbook.Name, Needle)
if (Visible = 1 and Workbook.Windows(1).Visible)
Wbs.Push(Workbook)
else if (Visible = 0 and not Workbook.Windows(1).Visible)
Wbs.Push(Workbook)
else if (Visible = "")
Wbs.Push(Workbook)
return Wbs
}
}
; GetActiveObjects v1.0 by Lexikos
; http://ahkscript.org/boards/viewtopic.php?f=6&t=6494
GetActiveObjects(Prefix:="", CaseSensitive:=false) {
objects := {}
DllCall("ole32\CoGetMalloc", "uint", 1, "ptr*", malloc) ; malloc: IMalloc
DllCall("ole32\CreateBindCtx", "uint", 0, "ptr*", bindCtx) ; bindCtx: IBindCtx
DllCall(NumGet(NumGet(bindCtx+0)+8*A_PtrSize), "ptr", bindCtx, "ptr*", rot) ; rot: IRunningObjectTable
DllCall(NumGet(NumGet(rot+0)+9*A_PtrSize), "ptr", rot, "ptr*", enum) ; enum: IEnumMoniker
while DllCall(NumGet(NumGet(enum+0)+3*A_PtrSize), "ptr", enum, "uint", 1, "ptr*", mon, "ptr", 0) = 0 ; mon: IMoniker
{
DllCall(NumGet(NumGet(mon+0)+20*A_PtrSize), "ptr", mon, "ptr", bindCtx, "ptr", 0, "ptr*", pname) ; GetDisplayName
name := StrGet(pname, "UTF-16")
DllCall(NumGet(NumGet(malloc+0)+5*A_PtrSize), "ptr", malloc, "ptr", pname) ; Free
if InStr(name, Prefix, CaseSensitive) = 1 {
DllCall(NumGet(NumGet(rot+0)+6*A_PtrSize), "ptr", rot, "ptr", mon, "ptr*", punk) ; GetObject
; Wrap the pointer as IDispatch if available, otherwise as IUnknown.
if (pdsp := ComObjQuery(punk, "{00020400-0000-0000-C000-000000000046}"))
obj := ComObject(9, pdsp, 1), ObjRelease(punk)
else
obj := ComObject(13, punk, 1)
; Store it in the return array by suffix.
objects[SubStr(name, StrLen(Prefix) + 1)] := obj
}
ObjRelease(mon)
}
ObjRelease(enum)
ObjRelease(rot)
ObjRelease(bindCtx)
ObjRelease(malloc)
return objects
}