As Louis Amstrong's funeral song went "ONE MORE TIME!!!"
This is a dreaded 3rd way to get all the Winforms (OR any other bloody OS handle it seems...) in your application! So this solution has the potential to be used as a resource tracker if you suspected that the CLR was leaking handles. It also has the potential to SLLLOOOWWW your app down.
Add this unit to your delphi.net project
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
unit HookHandleAllocator;
interface
uses System.Collections;
procedure HandleAdded(handleType: string; handleValue: IntPtr; currentHandleCount: integer);
procedure HandleRemoved(handleType: string; handleValue: IntPtr; currentHandleCount: integer);
var
WinformList : System.Collections.ArrayList;
implementation
uses System.Reflection,System.Windows.Forms;
type
THandleChangeEventHandler = procedure (handleType: string; handleValue: IntPtr; currentHandleCount: integer) of object;
var
aDelegate : THandleChangeEventHandler;
procedure HandleAdded(handleType: string; handleValue: IntPtr; currentHandleCount: integer);
begin
if (handleType = 'Window') then WinformList.Add(handleValue);
end;
procedure HandleRemoved(handleType: string; handleValue: IntPtr; currentHandleCount: integer);
begin
if (handleType = 'Window') then WinformList.Remove(handleValue);
end;
procedure HookIntoHandleAllocator;
const
AllBindingFlags : BindingFlags = BindingFlags.Instance or BindingFlags.Static or
BindingFlags.Public or BindingFlags.NonPublic or
BindingFlags.FlattenHierarchy;
type
TObjectArray = array of TObject;
var
SystemModule : Module;
FusionType : System.Type;
HandleType : System.Type;
DelegateType : System.Type;
UnitType : System.Type;
HandleEventInfo : EventInfo;
HandlerMethodInfo : MethodInfo;
WindowHandleCollection : TObjectArray;
ParamArray : array [0..0] of TObject;
begin
SystemModule := TypeOf(System.Windows.Forms.Form).Module;
if not Assigned(SystemModule) then Exit;
FusionType := SystemModule.GetType('System.HandleCollector');
if not Assigned(FusionType) then Exit;
DelegateType := SystemModule.GetType('System.HandleChangeEventHandler');
if not Assigned(DelegateType) then Exit;
HandleEventInfo := FusionType.GetEvent('HandleAdded',AllBindingFlags);
if not Assigned(HandleEventInfo) then Exit;
HandlerMethodInfo := HandleEventInfo.GetAddMethod(true);
if not Assigned(HandlerMethodInfo) then Exit;
UnitType := Assembly.GetExecutingAssembly.
GetModules[0].GetType('HookHandleAllocator.Unit',true);
if not Assigned(UnitType) then Exit;
aDelegate := HandleAdded;
ParamArray[0] := Delegate.CreateDelegate(DelegateType,UnitType,'HandleAdded');
HandlerMethodInfo.Invoke(nil,ParamArray);
HandleEventInfo := FusionType.GetEvent('HandleRemoved',AllBindingFlags);
if not Assigned(HandleEventInfo) then Exit;
HandlerMethodInfo := HandleEventInfo.GetAddMethod(true);
if not Assigned(HandlerMethodInfo) then Exit;
aDelegate := HandleRemoved;
ParamArray[0] := Delegate.CreateDelegate(DelegateType,UnitType,'HandleAdded');
HandlerMethodInfo.Invoke(nil,ParamArray);
end;
initialization
WinformList := System.Collections.ArrayList.Create;
HookIntoHandleAllocator;
finalization
end.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
procedure TWinForm.Button7_Click(sender: System.Object; e: System.EventArgs);
var
i : integer;
FoundControl : Control;
begin
for i := 0 to WinformList.Count - 1 do
begin
FoundControl := Control.FromHandle(IntPtr(WinformList.Item[i]));
if FoundControl is System.Windows.Forms.Form then
MessageBox.Show(FoundControl.Text);
end;
end;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
I hope this is last solution to the WinForm list issue... Now I need to check if all this works in CLR 2.0.