www.pudn.com > windowsrunning > Enumerator.cls
VERSION 1.0 CLASS
BEGIN
MultiUse = -1 'True
Persistable = 0 'NotPersistable
DataBindingBehavior = 0 'vbNone
DataSourceBehavior = 0 'vbNone
MTSTransactionMode = 0 'NotAnMTSObject
END
Attribute VB_Name = "Enumerator"
Attribute VB_GlobalNameSpace = True
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Attribute VB_Description = "Use this Class to perform all of the enumeration functions. This class also has many functions to do with windows in general, plus a few explicit to the edit control."
Attribute VB_Ext_KEY = "SavedWithClassBuilder6" ,"Yes"
Attribute VB_Ext_KEY = "Top_Level" ,"Yes"
Option Explicit
'
' I have been to great troubles to learn all of the techniques in this program.
' I have spent many, many hours and late nights coding the many functions which I
' have included. As much as I resent it, Planet Source Code requires that I put
' the source code in the zip file. So I have placed it in here for you to view.
' Please use it wisely. And give me credit for all of the hard work that I have
' done. My biggest fear is that somebody will do an almost straight rip of this
' code, and take the credit for themselves. Please do not let this happening. I'm
' placing a lot of trust there. So please, use this program, use this code, and
' give me credit for it. If anybody rips all my routines, then my secret spy's
' (and I have a lot of them, as soon as I hire them) will tell me, and I'll get
' into my private jet (as soon as I buy it) and track you down over the whole
' world and eventually KILL YOU. You get the idea? Thanks. Read on for something
' a little more interesting!
'
' Code is Copyright Jolyon Bloomfield, February 2000
'
' A series of declares that drive this class around...
Private Const MAX_PATH& = 260
Private Const PROCESS_ALL_ACCESS = 0
Private Const TH32CS_SNAPPROCESS = 2&
Private Const TH32CS_SNAPTHREAD = 4&
' ShowWindow() Commands
Private Const SW_HIDE = 0
Private Const SW_SHOWNORMAL = 1
Private Const SW_NORMAL = 1
Private Const SW_SHOWMINIMIZED = 2
Private Const SW_SHOWMAXIMIZED = 3
Private Const SW_MAXIMIZE = 3
Private Const SW_SHOWNOACTIVATE = 4
Private Const SW_SHOW = 5
Private Const SW_MINIMIZE = 6
Private Const SW_SHOWMINNOACTIVE = 7
Private Const SW_SHOWNA = 8
Private Const SW_RESTORE = 9
Private Const SW_SHOWDEFAULT = 10
Private Const SW_MAX = 10
' For GetWindowLong
Private Const GWL_WNDPROC = (-4)
Private Const GWL_HINSTANCE = (-6)
Private Const GWL_HWNDPARENT = (-8)
Private Const GWL_STYLE = (-16)
Private Const GWL_EXSTYLE = (-20)
Private Const GWL_USERDATA = (-21)
Private Const GWL_ID = (-12)
' GetClassLong indexes
Private Const GCL_WNDPROC = (-24)
Private Const GCL_STYLE = (-26)
Private Const GCL_MENUNAME = (-8)
Private Const GCL_HMODULE = (-16)
Private Const GCL_HICON = (-14)
Private Const GCL_HCURSOR = (-12)
Private Const GCL_HBRBACKGROUND = (-10)
Private Const GCL_CBWNDEXTRA = (-18)
Private Const GCL_CBCLSEXTRA = (-20)
' SetWindowPos Flags
Private Const SWP_NOSIZE = &H1
Private Const SWP_NOMOVE = &H2
Private Const SWP_NOZORDER = &H4
Private Const SWP_NOREDRAW = &H8
Private Const SWP_NOACTIVATE = &H10
Private Const SWP_FRAMECHANGED = &H20 ' The frame changed: send WM_NCCALCSIZE
Private Const SWP_SHOWWINDOW = &H40
Private Const SWP_HIDEWINDOW = &H80
Private Const SWP_NOCOPYBITS = &H100
Private Const SWP_NOOWNERZORDER = &H200 ' Don't do owner Z ordering
' SetWindowPos() hwndInsertAfter values
Private Const HWND_TOP = 0
Private Const HWND_BOTTOM = 1
Private Const HWND_TOPMOST = -1
Private Const HWND_NOTOPMOST = -2
'
' Note: All of the Window's Styles, Window's Extended Styles,
' Window's messages, etc, etc, etc, messages, are stored in modConst.Bas
'
' All of the data types that this class requires (+ some in the global module)
Private Type THREADENTRY32
lSize As Long
lUsage As Long
lThreadID As Long
lOwnerProcessID As Long
lBasePri As Long
lDeltaPri As Long
lFlags As Long
End Type
Private Type WINDOWPLACEMENT
Length As Long
flags As Long
showCmd As Long
ptMinPosition As POINTAPI
ptMaxPosition As POINTAPI
rcNormalPosition As RECT
End Type
Private Type PROCESSENTRY32
dwSize As Long
cntUsage As Long
th32ProcessID As Long
th32DefaultHeapID As Long
th32ModuleID As Long
cntThreads As Long
th32ParentProcessID As Long
pcPriClassBase As Long
dwFlags As Long
szexeFile As String * MAX_PATH
End Type
Private Type ThreadIt
ID As Long
Process As Long
End Type
Private Type Winded
hWnd As Long
Parent As Long
StringParentUse As String
ClassName As String
Text As String
UseMe As Boolean
Thread As Long
Process As Long
DisplayText As String
End Type
Public Enum EnumPos
Normal = 0
Maximized = 1
Minimized = 2
End Enum
Public Enum Relations
GW_HWNDFIRST = 0
GW_HWNDLAST = 1
GW_HWNDNEXT = 2
GW_HWNDPREV = 3
GW_OWNER = 4
GW_CHILD = 5
End Enum
' What a heck of a lot of declares!!!
Private Declare Function GetLastError Lib "kernel32" () As Long
Private Declare Function TerminateProcess Lib "kernel32" (ByVal ApphProcess As Long, ByVal uExitCode As Long) As Long
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal blnheritHandle As Long, ByVal dwAppProcessId As Long) As Long
Private Declare Function ProcessFirst Lib "kernel32" Alias "Process32First" (ByVal hSnapshot As Long, uProcess As PROCESSENTRY32) As Long
Private Declare Function ProcessNext Lib "kernel32" Alias "Process32Next" (ByVal hSnapshot As Long, uProcess As PROCESSENTRY32) As Long
Private Declare Function CreateToolhelpSnapshot Lib "kernel32" Alias "CreateToolhelp32Snapshot" (ByVal lFlags As Long, lProcessId As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function GetExitCodeProcess Lib "kernel32" (ByVal hProcess As Long, lpExitCode As Long) As Long
Private Declare Function GetDesktopWindow Lib "user32" () As Long
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hWnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Private Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hWnd As Long) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hWnd As Long, lpdwProcessId As Long) As Long
Private Declare Function GetParent Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByRef lParam() As Long) As Long
Private Declare Function EnumChildWindows Lib "user32" (ByVal hWndParent As Long, ByVal lpEnumFunc As Long, ByRef lParam() As Long) As Long
Private Declare Function IsWindow Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function IsWindowEnabled Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function IsWindowVisible Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function SetFocus Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function SetForegroundWindow Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function GetCurrentProcessId Lib "kernel32" () As Long
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hWnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Private Declare Function GetMenu Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function GetSubMenu Lib "user32" (ByVal hMenu As Long, ByVal nPos As Long) As Long
Private Declare Function IsMenu Lib "user32" (ByVal hMenu As Long) As Long
Private Declare Function GetWindowPlacement Lib "user32" (ByVal hWnd As Long, lpwndpl As WINDOWPLACEMENT) As Long
Private Declare Function MoveWindow Lib "user32" (ByVal hWnd As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal bRepaint As Long) As Long
Private Declare Function SetWindowPlacement Lib "user32" (ByVal hWnd As Long, lpwndpl As WINDOWPLACEMENT) As Long
Private Declare Function SetWindowPos Lib "user32" (ByVal hWnd As Long, ByVal hWndInsertAfter As Long, ByVal X As Long, ByVal Y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
Private Declare Function EnableWindow Lib "user32" (ByVal hWnd As Long, ByVal fEnable As Long) As Long
Private Declare Function ShowWindow Lib "user32" (ByVal hWnd As Long, ByVal nCmdShow As Long) As Long
Private Declare Function SetActiveWindow Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function Thread32First Lib "kernel32" (ByVal hSnapshot As Long, uProcess As THREADENTRY32) As Long
Private Declare Function Thread32Next Lib "kernel32" (ByVal hSnapshot As Long, uThread As THREADENTRY32) As Long
Private Declare Function IsHungThread Lib "user32" (ByVal lThreadID As Long) As Long
Private Declare Function SetParentA Lib "user32" Alias "SetParent" (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long
Private Declare Function IsZoomed Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function IsIconic Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function FlashWindow Lib "user32" (ByVal hWnd As Long, ByVal bInvert As Long) As Long
Private Declare Function GetWindow Lib "user32" (ByVal hWnd As Long, ByVal wCmd As Long) As Long
Private Declare Function GetNextWindow Lib "user32" Alias "GetWindow" (ByVal hWnd As Long, ByVal wFlag As Long) As Long
Private Declare Function GetWindowDC Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function ReleaseDC Lib "user32" (ByVal hWnd As Long, ByVal hdc As Long) As Long
Private Declare Function BringWindowToTop Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function SetWindowText Lib "user32" Alias "SetWindowTextA" (ByVal hWnd As Long, ByVal lpString As String) As Long
Private Declare Function InvalidateRect Lib "user32" (ByVal hWnd As Long, lpRect As Any, ByVal bErase As Long) As Long
Private Declare Function UpdateWindow Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function GetClassLong Lib "user32" Alias "GetClassLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
' These are the three enumerations.
Private WindsEnum() As Long
Private ThreadsEnum() As ThreadIt
Private ProcessEnum() As Long
' Other variables of sorts
Private mvarEnumsReady As Boolean
Private mvarNewEnum As ReEnumType
Private DoingSomething As Boolean
'
' Sets how EnumIt looks after enumerations that are already there.
'
Public Property Let NewEnum(ByVal EnumNew As ReEnumType)
Attribute NewEnum.VB_Description = "Sets what to do when a function is called that requires an enumeration to be present, but the enumeration doesn't exits."
mvarNewEnum = EnumNew
End Property
Public Property Get NewEnum() As ReEnumType
NewEnum = mvarNewEnum
End Property
'
' Returns a window's process from it's hWnd
'
Public Function WindProcess(ByVal hWnd As Long) As Long
Dim Temp As Long
Temp = GetWindowThreadProcessId(hWnd, WindProcess)
End Function
'
' Returns a window's thread from it's hWnd
'
Public Function WindThread(ByVal hWnd As Long) As Long
Dim Temp As Long
WindThread = GetWindowThreadProcessId(hWnd, Temp)
End Function
'
' Returns the module path for a process through it's processId
'
Public Function ProcessName(ByVal ProcessID As Long) As String
Dim uProcess As PROCESSENTRY32
Dim rProcessFound As Long
Dim hSnapshot As Long
Dim i As Integer
uProcess.dwSize = Len(uProcess)
hSnapshot = CreateToolhelpSnapshot(TH32CS_SNAPPROCESS, 0&)
rProcessFound = ProcessFirst(hSnapshot, uProcess)
Do While rProcessFound
If uProcess.th32ProcessID = ProcessID Then ProcessName = FixApi(uProcess.szexeFile): Call CloseHandle(hSnapshot): Exit Function
rProcessFound = ProcessNext(hSnapshot, uProcess)
Loop
ProcessName = ""
Call CloseHandle(hSnapshot)
End Function
'
' Returns the parent of a window
'
Public Function ParentWind(ByVal hWnd As Long) As Long
ParentWind = GetParent(hWnd)
End Function
'
' Returns the desktop window
'
Public Function DesktopWind() As Long
DesktopWind = GetDesktopWindow()
End Function
'
' Formats a long value into hexedecimal, using 8 characters
'
Public Function Format8(ByVal Value As Long) As String
Format8 = String(8 - Len(Trim(Hex(Value))), "0") & Trim(Hex(Value))
End Function
'
' Returns an enumeration of processes
'
Public Sub ReturnProcessEnum(ByRef Process() As Long)
If (EnumsReady = False Or NewEnum = 1) And DoingSomething = False Then EnumAll
Dim i As Long
ReDim Process(LBound(ProcessEnum) To UBound(ProcessEnum)) As Long
For i = LBound(ProcessEnum) To UBound(ProcessEnum)
Process(i) = ProcessEnum(i)
Next i
End Sub
'
' Returns an enumeration of threads
'
Public Sub ReturnThreadEnum(ByRef Threads() As Long)
If (EnumsReady = False Or NewEnum = 1) And DoingSomething = False Then EnumAll
Dim i As Long
ReDim Threads(LBound(ThreadsEnum) To UBound(ThreadsEnum)) As Long
For i = LBound(ThreadsEnum) To UBound(ThreadsEnum)
Threads(i) = ThreadsEnum(i).ID
Next i
End Sub
'
' Returns an enumeration of windows
'
Public Sub ReturnWindEnum(ByRef Winds() As Long)
'
' also remember to put the desktop window inside the enumeration
'
If (EnumsReady = False Or NewEnum = 1) And DoingSomething = False Then EnumAll
Dim i As Long
ReDim Winds(LBound(WindsEnum) To UBound(WindsEnum)) As Long
For i = LBound(WindsEnum) To UBound(WindsEnum)
Winds(i) = WindsEnum(i)
Next i
End Sub
'
' Enumerates everything in a treeview control, according to the style)
'
Public Sub EnumInTreeView(ByRef TreeView As TreeView, Optional PicList As ImageList, Optional DesktopPic As String = "", Optional ProcessPic As String = "", Optional ThreadPic As String = "", Optional WindPic As String = "", Optional ByVal Style As DispEnum = 0)
Dim Mouser As Hourglass
Set Mouser = New Hourglass
If (EnumsReady = False Or NewEnum = 1) And DoingSomething = False Then EnumAll
TreeView.Visible = False
Select Case Style
Case Is = DispEnum.Full
TreeFull TreeView, PicList, DesktopPic, ProcessPic, ThreadPic, WindPic
End Select
TreeView.Visible = True
End Sub
'
' Returns if a window is valid or not
'
Public Function IsValidWindow(ByVal hWnd As Long) As Boolean
IsValidWindow = IsWindow(hWnd)
End Function
'
' Destroys all enumerations
'
Public Sub DestroyEnums()
mvarEnumsReady = False
ReDim ProcessEnum(0 To 0) As Long
ReDim ThreadsEnum(0 To 0) As ThreadIt
ReDim WindsEnum(0 To 0) As Long
End Sub
'
' Returns whether or not the enumerations are ready
'
Public Property Get EnumsReady() As Boolean
EnumsReady = mvarEnumsReady
End Property
'
' Enumerates everything
'
Public Sub EnumAll()
Dim Mouser As Hourglass
Set Mouser = New Hourglass
' Dimensioning
Dim i As Long
Dim k As Long
Dim Temp As Long
' First, we destroy the enumerations.
DestroyEnums
'
' Now to enumerate the windows.
'
' Send it off to the module, as I can't use the addressof operator insed a class module.
ReDim WindsEnum(0 To 0) As Long
modConst.EnumAllWinds WindsEnum
'
' The windows are now enumerated. Now to enumerate the processes.
'
Dim uProcess As PROCESSENTRY32
Dim rProcessFound As Long
Dim hSnapshot As Long
ReDim ProcessEnum(0 To 0) As Long
uProcess.dwSize = Len(uProcess)
hSnapshot = CreateToolhelpSnapshot(TH32CS_SNAPPROCESS, 0&)
rProcessFound = ProcessFirst(hSnapshot, uProcess)
Do While rProcessFound
ReDim Preserve ProcessEnum(0 To UBound(ProcessEnum) + 1) As Long
ProcessEnum(UBound(ProcessEnum)) = uProcess.th32ProcessID
rProcessFound = ProcessNext(hSnapshot, uProcess)
Loop
Call CloseHandle(hSnapshot)
'
' The processes are now also enumerated.
'
'
' Thankyou to Konstantin Tretyakov (kt_ee@yahoo.com) for a lot of the code that went
' into all of these enumerations!!!
'
' /--- Code used before I found enumeration APIs
' \/
'
'Dim Found As Boolean
'Dim CurrentThread As Long
'
'ReDim ThreadsEnum(0 To 0) As ThreadIt
'
'For i = 1 To UBound(WindsEnum)
' Found = False
' CurrentThread = WindThread(WindsEnum(i))
' For k = 1 To UBound(ThreadsEnum)
' If CurrentThread = ThreadsEnum(k).ID Then Found = True: Exit For
' Next k
' If Found = False Then
' ReDim Preserve ThreadsEnum(0 To UBound(ThreadsEnum) + 1) As ThreadIt
' ThreadsEnum(UBound(ThreadsEnum)).ID = CurrentThread
' ThreadsEnum(UBound(ThreadsEnum)).Process = WindProcess(WindsEnum(i))
' End If
'Next i
Dim lSnapShot As Long
Dim CanEnum As Long
Dim uThread As THREADENTRY32
Dim ItemToAdd As String
ReDim ThreadsEnum(0 To 0) As ThreadIt
lSnapShot = CreateToolhelpSnapshot(TH32CS_SNAPTHREAD, 0&)
If lSnapShot <> 0 Then
uThread.lSize = Len(uThread)
CanEnum = Thread32First(lSnapShot, uThread)
Do While CanEnum
ReDim Preserve ThreadsEnum(0 To UBound(ThreadsEnum) + 1) As ThreadIt
ThreadsEnum(UBound(ThreadsEnum)).ID = uThread.lThreadID
ThreadsEnum(UBound(ThreadsEnum)).Process = uThread.lOwnerProcessID
CanEnum = Thread32Next(lSnapShot, uThread)
Loop
CloseHandle (lSnapShot)
End If
'
' Good Lord! I thought I'd never get through all of that! well, I did =>
'
mvarEnumsReady = True
End Sub
'
' Kills a task by it's process Id
'
Public Function KillProcess(ByVal ProcessID As Long) As Boolean
Const PROCESS_ALL_ACCESS = &H0
Dim exitCode As Long
Dim myProcess As Long
' Get the process
myProcess = OpenProcess(PROCESS_ALL_ACCESS, False, ProcessID)
If IsNull(myProcess) = True Or myProcess = 0 Then KillProcess = False: GoTo closit
' Get the Exit Code
If GetExitCodeProcess(ProcessID, exitCode) = False Then
If GetLastError = True Then
KillProcess = False
GoTo closit
End If
End If
' Kill the process
KillProcess = TerminateProcess(myProcess, exitCode)
closit:
' ... and close the handle
Call CloseHandle(myProcess)
End Function
Public Function NumOfWinds() As Long
NumOfWinds = UBound(WindsEnum)
End Function
Public Function NumOfProcesses() As Long
NumOfProcesses = UBound(ProcessEnum)
End Function
Public Function NumOfThreads() As Long
NumOfThreads = UBound(ThreadsEnum)
End Function
Public Function FixApi(ByVal APIString As String) As String
If InStr(APIString, Chr(0)) <> 0 Then FixApi = Left$(APIString, InStr(APIString, Chr(0)) - 1) Else FixApi = APIString
End Function
Private Sub TreeFull(ByRef Tree As TreeView, Optional PicList As ImageList, Optional DesktopPic As String, Optional ProcessPic As String, Optional ThreadPic As String, Optional WindPic As String)
'
' Whack all of the data into the treeview control, with nice formatting and junk.
'
Dim NodesWork As Node
Dim i As Long
On Error GoTo errhandler
' First of all, lets get rid of all of the nodes that are there already.
Tree.Nodes.Clear
' And do all of the property setting business...
Tree.ImageList = PicList
' Next, we place the desktop on the topmost node.
Set NodesWork = Tree.Nodes.Add(, , "_" & Format8(DesktopWind), Format8(DesktopWind) & " " & ClassName(DesktopWind) & " (Desktop Window) " & GetWindText(DesktopWind), DesktopPic)
NodesWork.Tag = DesktopWind
' Now go through and place in all of the processes
For i = 1 To UBound(ProcessEnum)
Set NodesWork = Tree.Nodes.Add("_" & Format8(DesktopWind), tvwChild, "_" & Format8(ProcessEnum(i)), Format8(ProcessEnum(i)) & " """ & ProcessName(ProcessEnum(i)) & """", ProcessPic)
NodesWork.Tag = ProcessEnum(i)
Next i
' Next goes in the threads...
For i = 1 To UBound(ThreadsEnum)
Set NodesWork = Tree.Nodes.Add("_" & Format8(ThreadsEnum(i).Process), tvwChild, "_" & Format8(ThreadsEnum(i).ID), Format8(ThreadsEnum(i).ID) & IIf(ThreadHung(ThreadsEnum(i).ID), " This thread is not responding.", ""), ThreadPic)
NodesWork.Tag = ThreadsEnum(i).ID
Next i
' And guess what? The next item to do is the windows =P
' First of all, though, create a new array with a data type that stores
' all sorts of info; i.e., text, id, classname, and the would-be key of the parent node.
' Also check for a window being a child of the desktop. In such a case,
' put it in under it's thread, and add some text to the string to display.
Dim Winds2() As Winded
Dim k As Long
ReDim Winds2(0 To 0) As Winded
k = 0
For i = 1 To UBound(WindsEnum)
If WindsEnum(i) <> DesktopWind Then
ReDim Preserve Winds2(0 To UBound(Winds2) + 1) As Winded
k = k + 1
Winds2(k).hWnd = WindsEnum(k)
Winds2(k).ClassName = ClassName(Winds2(k).hWnd)
Winds2(k).Parent = ParentWind(Winds2(k).hWnd)
Winds2(k).Text = GetWindText(Winds2(k).hWnd)
Winds2(k).Thread = WindThread(Winds2(k).hWnd)
Winds2(k).Process = WindProcess(Winds2(k).hWnd)
Winds2(k).UseMe = True
If Winds2(k).Parent = 0 Then
Winds2(k).StringParentUse = "_" & Format8(Winds2(k).Thread)
ElseIf Winds2(k).Parent = DesktopWind Then
Winds2(k).StringParentUse = "_" & Format8(Winds2(k).Thread)
Else
Winds2(k).StringParentUse = "_" & Format8(Winds2(k).Parent)
End If
If Winds2(k).Parent = DesktopWind Then
With Winds2(k)
.DisplayText = Format8(Winds2(k).hWnd) & " " & .ClassName & " (This is a child of the desktop window) """ & .Text & """"
End With
Else
With Winds2(k)
.DisplayText = Format8(Winds2(k).hWnd) & " " & .ClassName & " """ & .Text & """"
End With
End If
End If
Next i
Dim Changed As Boolean
Doadds:
Do
Changed = False
For i = 1 To UBound(Winds2)
If Winds2(i).UseMe = True And ParentIsIn(Tree.Nodes, Winds2(i).StringParentUse) = True Then
Set NodesWork = Tree.Nodes.Add(Winds2(i).StringParentUse, tvwChild, "_" & Format8(Winds2(i).hWnd), Winds2(i).DisplayText, WindPic)
NodesWork.Tag = Winds2(i).hWnd
Winds2(i).UseMe = False
Changed = True
End If
Next i
Loop While Changed = True
' Now go through and look for broken windows.
For i = 1 To UBound(Winds2)
If Winds2(i).UseMe = True Then
' For some reason, there is a broken window in the system somewhere.
' Add it in underneath it's thread, and add a little bit to the display string.
Set NodesWork = Tree.Nodes.Add("_" & Format8(Winds2(i).Thread), tvwChild, "_" & Format8(Winds2(i).hWnd), Winds2(i).DisplayText & " The parental link to this window is broken.", WindPic)
NodesWork.Tag = Winds2(i).hWnd
Winds2(i).UseMe = False
' This might clear up some errors, so go back and retry it.
GoTo Doadds
End If
Next i
' Finally, make the whole list sorted
For Each NodesWork In Tree.Nodes
NodesWork.Sorted = True
Next NodesWork
' Put out the desktop selection
Tree.Nodes("_" & Format8(DesktopWind)).Expanded = True
Tree.Nodes("_" & Format8(DesktopWind)).Selected = True
Exit Sub
errhandler:
MsgBox "There has been an error parsing data inside the enumerator class. This may have been due to a window, thread, or complete program terminating, and changing records that were currently being processed. As a result, the list will not be loaded. Please try again.", vbCritical, "Critical Error"
Tree.Nodes.Clear
End Sub
Public Function ClassName(ByVal hWnd As Long) As String
ClassName = Space(500)
GetClassName hWnd, ClassName, Len(ClassName)
ClassName = FixApi(ClassName)
End Function
Public Function GetWindText(ByVal hWnd As Long) As String
GetWindText = Space(GetWindTextLength(hWnd) + 1)
GetWindowText hWnd, GetWindText, Len(GetWindText)
GetWindText = FixApi(GetWindText)
End Function
Public Function GetWindTextLength(ByVal hWnd As Long) As Long
GetWindTextLength = GetWindowTextLength(hWnd)
End Function
Private Sub Class_Initialize()
DestroyEnums
End Sub
Private Sub Class_Terminate()
DestroyEnums
End Sub
Private Function ParentIsIn(ByRef NodeCol As Nodes, ByVal ParentKey As String)
Dim Dummy As String
On Error Resume Next
Dummy = NodeCol(ParentKey).Key
If Err Then ParentIsIn = False Else ParentIsIn = True
End Function
Public Function Progenitor(ByVal hWnd As Long) As Long
Dim NewParent As Long
NewParent = hWnd
Do While NewParent
Progenitor = NewParent
NewParent = GetParent(Progenitor)
Loop
' The Progenitor variables now holds the progenitor... well, what did you expect?
End Function
Public Function IsEnabled(ByVal hWnd As Long) As Boolean
IsEnabled = IsWindowEnabled(hWnd)
End Function
Public Function IsVisible(ByVal hWnd As Long) As Boolean
IsVisible = IsWindowVisible(hWnd)
End Function
Public Function ThreadProcess(ByVal ThreadID As Long) As Long
' Call around to get hold of all of the threads.
Dim lSnapShot As Long
Dim CanEnum As Long
Dim uThread As THREADENTRY32
Dim ItemToAdd As String
ReDim ThreadsEnum(0 To 0) As ThreadIt
lSnapShot = CreateToolhelpSnapshot(TH32CS_SNAPTHREAD, 0&)
If lSnapShot <> 0 Then
uThread.lSize = Len(uThread)
CanEnum = Thread32First(lSnapShot, uThread)
Do While CanEnum
If uThread.lThreadID = ThreadID Then ThreadProcess = uThread.lOwnerProcessID: Exit Do
CanEnum = Thread32Next(lSnapShot, uThread)
Loop
CloseHandle (lSnapShot)
End If
End Function
Public Function ThreadHung(ByVal ThreadID As Long) As Boolean
ThreadHung = IsHungThread(ThreadID)
End Function
Public Function MenuHandle(ByVal hWnd As Long) As Long
MenuHandle = GetMenu(hWnd)
If IsMenu(MenuHandle) = False Then MenuHandle = 0
End Function
Public Function SubMenu(ByVal hMenu As Long, ByVal Pos As Long) As Long
If IsMenu(hMenu) = False Then Exit Function
SubMenu = GetSubMenu(hMenu, Pos)
End Function
Public Function IsOnTop(ByVal hWnd As Long) As Boolean
Dim Styles As Long
Styles = GetWindowLong(hWnd, GWL_EXSTYLE)
If IsStyle(Styles, WS_EX_TOPMOST) = True Then IsOnTop = True
End Function
Public Function IsStyle(ByVal StyleLong As Long, ByVal StyleCheck As Long) As Boolean
If (StyleLong And StyleCheck) = StyleCheck Then IsStyle = True
End Function
Public Function StyleVal(ByVal hWnd As Long) As Long
If IsValidWindow(hWnd) = True Then
StyleVal = GetWindowLong(hWnd, GWL_STYLE)
End If
End Function
Public Function ExtStyleVal(ByVal hWnd As Long) As Long
If IsValidWindow(hWnd) = True Then
ExtStyleVal = GetWindowLong(hWnd, GWL_EXSTYLE)
End If
End Function
Public Function GetHandleInstance(ByVal hWnd As Long) As Long
If IsValidWindow(hWnd) = True Then
GetHandleInstance = GetWindowLong(hWnd, GWL_HINSTANCE)
End If
End Function
Public Function GetUserData(ByVal hWnd As Long) As Long
If IsValidWindow(hWnd) = True Then
GetUserData = GetWindowLong(hWnd, GWL_USERDATA)
End If
End Function
Public Function GetWndProc(ByVal hWnd As Long) As Long
If IsValidWindow(hWnd) = True Then
GetWndProc = GetWindowLong(hWnd, GWL_WNDPROC)
End If
End Function
Public Function GetControlID(ByVal hWnd As Long) As Long
If IsValidWindow(hWnd) = True Then
GetControlID = GetWindowLong(hWnd, GWL_ID)
End If
End Function
Public Function SetParent(ByVal hWnd As Long, ByVal NewParent As Long) As Boolean
SetParent = CBool(SetParentA(hWnd, NewParent))
End Function
Public Function SetVisible(ByVal hWnd As Long, ByVal Visible As Boolean) As Boolean
If Visible = True Then
SetVisible = ShowWindow(hWnd, SW_SHOWNA)
Else
SetVisible = ShowWindow(hWnd, SW_HIDE)
End If
End Function
Public Function SetOntop(ByVal hWnd As Long, ByVal TopMost As Boolean) As Boolean
SetOntop = SetWindowPos(hWnd, IIf(TopMost, HWND_TOPMOST, HWND_NOTOPMOST), 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE)
End Function
Public Function SetEnabled(ByVal hWnd As Long, ByVal Enabled As Boolean) As Boolean
SetEnabled = EnableWindow(hWnd, Enabled)
End Function
Public Sub ForeGround(ByVal hWnd As Long)
SetForegroundWindow hWnd
End Sub
Public Sub ActiveWind(ByVal hWnd As Long)
SetActiveWindow hWnd
End Sub
Public Sub FocusWind(ByVal hWnd As Long)
SetFocus hWnd
End Sub
Public Sub SetWindPos(ByVal hWnd As Long, ByVal Pos As Integer)
' Sets the Min, Max, or Normal attribute
Select Case Pos
Case Is = 0
' Normal
ShowWindow hWnd, SW_SHOWNORMAL
Case Is = 2
' Minimised
ShowWindow hWnd, SW_SHOWMINIMIZED
Case Is = 1
' Maximised
ShowWindow hWnd, SW_SHOWMAXIMIZED
End Select
End Sub
Public Sub TerminateWind(ByVal hWnd As Long)
PostMessage hWnd, modConst.WM_CLOSE, &O0, &O0
End Sub
Public Function WindPos(ByVal hWnd As Long) As EnumPos
If IsZoomed(hWnd) Then
WindPos = Maximized
ElseIf IsIconic(hWnd) Then
WindPos = Minimized
Else
WindPos = Normal
End If
End Function
Public Function Flash(ByVal hWnd As Long, ByVal Flasher As Boolean) As Long
Flash = FlashWindow(hWnd, Flasher)
End Function
Public Sub SetWinSizePos(ByVal hWnd As Long, ByVal X As Long, ByVal Y As Long, ByVal Width As Long, ByVal Height As Long)
MoveWindow hWnd, X, Y, Width, Height, True
End Sub
Public Function GetRelWindow(ByVal hWnd As Long, ByVal RelType As Relations) As Long
GetRelWindow = GetWindow(hWnd, RelType)
End Function
Public Sub BringToTop(ByVal hWnd As Long)
BringWindowToTop hWnd
End Sub
Public Sub SendToBottom(ByVal hWnd As Long)
SetWindowPos hWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE
End Sub
Public Function GetDC(ByVal hWnd As Long) As Long
GetDC = GetWindowDC(hWnd)
End Function
Public Sub RelDC(ByVal hWnd As Long, ByVal hdc As Long)
ReleaseDC hWnd, hdc
End Sub
Public Sub SetWindText(ByVal hWnd As Long, ByVal Text As String)
SetWindowText hWnd, Text
End Sub
Public Sub ForceRedraw(ByVal hWnd As Long)
Call InvalidateRect(hWnd, CLng(0), 1)
Call UpdateWindow(hWnd)
End Sub
Public Function GetBigIconH(ByVal hWnd As Long) As Long
GetBigIconH = SendMessage(hWnd, WM_GETICON, 1, 0) ' 1 = ICON_BIG
End Function
Public Function GetSmallIconH(ByVal hWnd As Long) As Long
GetSmallIconH = SendMessage(hWnd, WM_GETICON, 0, 0) ' 0 = ICON_SMALL
End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' From here down, the functions are to do with class information '
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Public Function GetClassExtraBytes(ByVal hWnd As Long) As Long
GetClassExtraBytes = GetClassLong(hWnd, GCL_CBCLSEXTRA)
End Function
Public Function GetClassExtraWndBytes(ByVal hWnd As Long) As Long
GetClassExtraWndBytes = GetClassLong(hWnd, GCL_CBWNDEXTRA)
End Function
Public Function GetClasshBackgroundBrush(ByVal hWnd As Long) As Long
GetClasshBackgroundBrush = GetClassLong(hWnd, GCL_HBRBACKGROUND)
End Function
Public Function GetClassHCursor(ByVal hWnd As Long) As Long
GetClassHCursor = GetClassLong(hWnd, GCL_HCURSOR)
End Function
Public Function GetClassHIcon(ByVal hWnd As Long) As Long
GetClassHIcon = GetClassLong(hWnd, GCL_HICON)
End Function
Public Function GetClasshSmallIcon(ByVal hWnd As Long) As Long
GetClasshSmallIcon = GetClassLong(hWnd, GCL_WNDPROC)
End Function
Public Function GetClassHModule(ByVal hWnd As Long) As Long
GetClassHModule = GetClassLong(hWnd, GCL_HMODULE)
End Function
Public Function GetClassMenuName(ByVal hWnd As Long) As Long
GetClassMenuName = GetClassLong(hWnd, GCL_MENUNAME)
End Function
Public Function GetClassStyle(ByVal hWnd As Long) As Long
GetClassStyle = GetClassLong(hWnd, GCL_STYLE)
End Function
Public Function GetClassWndProc(ByVal hWnd As Long) As Long
GetClassWndProc = GetClassLong(hWnd, GCL_WNDPROC)
End Function