Friday, June 18, 2004

A friend who asked me...

How can I get a list of all the Winforms in my .net application... hmmm I thought this should be easy... I should have known Brian (Long) would not have asked the question if it was easy... as he is pure evil that way. Making me think, as my wife will concur this is a big task in itself!.... I undertook to use the CLR rather than using Interop... Well Brian here is one Solution:

procedure TWinForm.Button2_Click(sender: System.Object; e: System.EventArgs);

AllBindingFlags : BindingFlags = BindingFlags.Instance or BindingFlags.Static or
BindingFlags.Public or BindingFlags.NonPublic or

CtorParams : array [0..1] of System.Type = (TypeOf(Control),TypeOf(boolean));

TIntptrArrayType = array of IntPtr;

MSCorlibModule : Module;
FusionType : System.Type;
FldInfo : FieldInfo;
ThreadWindowsCtor : ConstructorInfo;
ThreadWindowsObject : TObject;
ThreadWindowsParams : array [0..1] of TObject;
ThreadWindowCount, i : integer;
WindowsArr : TIntptrArrayType;
TempControl : Control;
//We could "MSCorlibAssembly := Assembly.Load('mscorlib');" again BUT this is
//easier... there are numerous ways to skin this cat.
MSCorlibModule := Self.GetType.BaseType.Module;
if not Assigned(MSCorlibModule) then Exit;
FusionType := MSCorlibModule.GetType('System.Windows.Forms.Application+ThreadWindows');
if not Assigned(FusionType) then Exit;
ThreadWindowsCtor := FusionType.GetConstructor(AllBindingFlags, nil,
CallingConventions.HasThis,CtorParams, nil);
if not Assigned(ThreadWindowsCtor) then Exit;

ThreadWindowsParams[0] := nil; //Look for all controls on the thread
ThreadWindowsParams[1] := TObject(false); //False ONLY get winforms

// Create the ThreadWindows Object
ThreadWindowsObject := ThreadWindowsCtor.Invoke(ThreadWindowsParams);
if not Assigned(ThreadWindowsObject) then Exit;

//Get the number of windows on the thread
FldInfo := FusionType.GetField('windowCount',AllBindingFlags);
ThreadWindowCount := integer(FldInfo.GetValue(ThreadWindowsObject));
if ThreadWindowCount <= 0 then Exit;

//Get an window handles
FldInfo := FusionType.GetField('windows',AllBindingFlags);
if not Assigned(FldInfo) then Exit;
WindowsArr := TIntptrArrayType(FldInfo.GetValue(ThreadWindowsObject));
if not Assigned(WindowsArr) then Exit;
for i := 0 to ThreadWindowCount -1 do
TempControl := Control.FromHandle(WindowsArr[i]);
if Assigned(TempControl) then
//Get the caption of each control


Yes, people that is Pascal or Delphi if you prefer... written in a C-ish fashion.


Post a Comment

<< Home