ptrex Posted March 29, 2017 Share Posted March 29, 2017 Is the HP "dotnetfactory" a dotnetAssembly ? is so can you provide me a copy so I can look into the Assembly DLL to see if an learn from that code base... Regarding the reflection I posted some nice material a fews days back, can be of interest to see post 46 .Net Reflection What is reflection in .Net : https://www.codeproject.com/articles/55710/reflection-in-net Downside of the reflection is the speed ... compared to te CLR approach is seems. But better slow speed than no speed Contributions :Firewall Log Analyzer for XP - Creating COM objects without a need of DLL's - UPnP support in AU3Crystal Reports Viewer - PDFCreator in AutoIT - Duplicate File FinderSQLite3 Database functionality - USB Monitoring - Reading Excel using SQLRun Au3 as a Windows Service - File Monitor - Embedded Flash PlayerDynamic Functions - Control Panel Applets - Digital Signing Code - Excel Grid In AutoIT - Constants for Special Folders in WindowsRead data from Any Windows Edit Control - SOAP and Web Services in AutoIT - Barcode Printing Using PS - AU3 on LightTD WebserverMS LogParser SQL Engine in AutoIT - ImageMagick Image Processing - Converter @ Dec - Hex - Bin -Email Address Encoder - MSI Editor - SNMP - MIB ProtocolFinancial Functions UDF - Set ACL Permissions - Syntax HighLighter for AU3ADOR.RecordSet approach - Real OCR - HTTP Disk - PDF Reader Personal Worldclock - MS Indexing Engine - Printing ControlsGuiListView - Navigation (break the 4000 Limit barrier) - Registration Free COM DLL Distribution - Update - WinRM SMART Analysis - COM Object Browser - Excel PivotTable Object - VLC Media Player - Windows LogOnOff Gui -Extract Data from Outlook to Word & Excel - Analyze Event ID 4226 - DotNet Compiler Wrapper - Powershell_COM - New Link to comment Share on other sites More sharing options...
LarsJ Posted March 29, 2017 Share Posted March 29, 2017 Event_handling.au3: expandcollapse popup;#AutoIt3Wrapper_UseX64=y #include "CLR.au3" Example() Func Example() ; Compile the helper class. This could be pre-compiled. Local $oHelper, $oHelperAsm = _CLR_CompileCSharp( FileRead( "EventHelper.cs" ) ) $oHelperAsm.CreateInstance( "EventHelper", $oHelper ) ConsoleWrite( "IsObj( $oHelper ) = " & IsObj( $oHelper ) & @CRLF ) ; Create our test object, which simply exposes a single event. Local $oTest, $oTestAsm = _CLR_CompileCSharp( FileRead( "TestObject.cs" ) ) $oTestAsm.CreateInstance( "ObjectWithEvent", $oTest ) ConsoleWrite( "IsObj( $oTest ) = " & IsObj( $oTest ) & @CRLF ) Local $hEventHandler = DllCallbackRegister( "EventHandler", "int", "ptr" ) Local $pEventHandler = DllCallbackGetPtr( $hEventHandler ) ; Add an event handler for the "OnEvent" event. Use "" to pass the ; address as a string, since IDispatch doesn't support 64-bit integers. $oHelper.AddHandler( $oTest, "OnEvent", $pEventHandler ) ; Make an event handler (event must be of the EventHandler type). Local $oHandler = $oHelper.MakeHandler( $pEventHandler ) $oTest.add_OnEvent( $oHandler ) ; Test the event handlers. $oTest.RaiseEvent() EndFunc ; Our event handler is called with a SAFEARRAY of parameters. This ; makes it much easier to get the type and value of each parameter. Func EventHandler( $pprm ) ConsoleWrite( "$pprm = " & $pprm & @CRLF ) Local $iDim = SafeArrayGetDim( $pprm ) ConsoleWrite( "$iDim = " & $iDim & @CRLF ) Local $iLBound, $iUBound SafeArrayGetLBound( $pprm, 1, $iLBound ) SafeArrayGetUBound( $pprm, 1, $iUBound ) ConsoleWrite( "$iLBound = " & $iLBound & @CRLF ) ConsoleWrite( "$iUBound = " & $iUBound & @CRLF ) Local $tprm = DllStructCreate( $tagSAFEARRAY, $pprm ) Local $fFeatures = DllStructGetData( $tprm, "fFeatures" ) ConsoleWrite( "$fFeatures = 0x" & Hex( $fFeatures ) & @CRLF ) Local $cbElements = DllStructGetData( $tprm, "cbElements" ) ConsoleWrite( "$cbElements = " & $cbElements & @CRLF ) Local $vt SafeArrayGetVartype( $pprm, $vt ) ConsoleWrite( "$vt = " & $vt & @CRLF ) Local $prmData, $tvt, $data, $obj SafeArrayAccessData( $pprm, $prmData ) $tvt = DllStructCreate( "word", $prmData ) $vt = DllStructGetData( $tvt, 1 ) ConsoleWrite( "$vt = " & $vt & @CRLF ) ; EventArgs Class $data = DllStructGetData( DllStructCreate( "ptr", $prmData + 8 ), 1 ) $obj = ConvertPtrToIDispatch($data) ConsoleWrite( $obj.ToString() & @CRLF ) $tvt = DllStructCreate( "word", $prmData + ( @AutoItX64 ? 24 : 16 ) ) $vt = DllStructGetData( $tvt, 1 ) ConsoleWrite( "$vt = " & $vt & @CRLF ) ; EventArgs Class $data = DllStructGetData( DllStructCreate( "ptr", $prmData + ( @AutoItX64 ? 24 : 16 ) + 8 ), 1 ) $obj = ConvertPtrToIDispatch($data) ConsoleWrite( $obj.ToString() & @CRLF ) SafeArrayUnaccessData( $pprm ) EndFunc ; In the end we still want the autoit object. This function converts a raw pointer to an autoit object Func ConvertPtrToIDispatch($IDispatch_Ptr) ; This would have been 10000x easier if autoit had supported the idispatch* type in dllstructs... ; Fortunetely memcpy can copy the pointer into a idispatch*, lucky us. $ptr_struct=DllStructCreate("ptr") DllStructSetData($ptr_struct,1,$IDispatch_Ptr) $aCall = DllCall("ntdll.dll","ptr:cdecl","memcpy","idispatch*","","ptr",DllStructGetPtr($ptr_struct),"long",4) return $aCall[1] EndFunc EventHelper.cs expandcollapse popupusing System; using System.Reflection; using System.Reflection.Emit; using System.Runtime.InteropServices; public class EventHelper { // Delegate type for the AutoHotkey callback. public delegate void CallbackType([MarshalAs(UnmanagedType.SafeArray)] object[] argv); // AddHandler: Adds a callback as a handler for the given event of the given object. public void AddHandler(object target, string eventName, string pcb) { var cb = ParseCB(pcb); // Reference: http://msdn.microsoft.com/en-us/library/ms228976 EventInfo evt = target.GetType().GetEvent(eventName); Type handlerType = evt.EventHandlerType; MethodInfo handlerSig = handlerType.GetMethod("Invoke"); ParameterInfo[] parameters = handlerSig.GetParameters(); Type[] parameterTypes = new Type[parameters.Length+1]; parameterTypes[0] = typeof(CallbackType); for (int i = 0; i < parameters.Length; i++) parameterTypes[i+1] = parameters[i].ParameterType; var handler = new DynamicMethod("", handlerSig.ReturnType, parameterTypes, true); var il = handler.GetILGenerator(); var loc = il.DeclareLocal(typeof(object[])); il.Emit(OpCodes.Ldc_I4_2); il.Emit(OpCodes.Newarr, typeof(object)); il.Emit(OpCodes.Stloc_0); il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Ldc_I4_0); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Stelem_Ref); il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Ldc_I4_1); il.Emit(OpCodes.Ldarg_2); il.Emit(OpCodes.Stelem_Ref); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Call, typeof(CallbackType).GetMethod("Invoke")); il.Emit(OpCodes.Ret); var delg = handler.CreateDelegate(handlerType, cb); var adder = evt.GetAddMethod(); adder.Invoke(target, new object[] { delg }); } // Much simpler method, restricted to a specific delegate type. public EventHandler MakeHandler(string pcb) { var cb = ParseCB(pcb); return (sender, e) => cb(new object[]{ sender, e }); } public CallbackType ParseCB(string cb) { // For 32-bit, simply marking the parameter of AddHandler/MakeHandler with: // [MarshalAs(UnmanagedType.FunctionPtr)] CallbackType cb // is adequate, but since IDispatch doesn't support 64-bit integers, // we have to pass the callback address as a string for x64 builds. return (CallbackType) Marshal.GetDelegateForFunctionPointer( (IntPtr)Int64.Parse(cb), typeof(CallbackType)); } } TestObject.cs public class ObjectWithEvent { public void RaiseEvent() { if (OnEvent != null) OnEvent(this, System.EventArgs.Empty); } public event System.EventHandler OnEvent; } tst00.au3 expandcollapse popup;#AutoIt3Wrapper_UseX64=y #include "CLR.au3" Example() ; Form Using System.Windows.Forms.Form Func Example() ; Compile the helper class. This could be pre-compiled. Local $oHelper, $oHelperAsm = _CLR_CompileCSharp( FileRead( "EventHelper.cs" ) ) $oHelperAsm.CreateInstance( "EventHelper", $oHelper ) ConsoleWrite( "IsObj( $oHelper ) = " & IsObj( $oHelper ) & @CRLF ) ConsoleWrite( "_CLR_LoadLibrary System.Windows.Forms" & @CRLF ) Local $oAssembly = _CLR_LoadLibrary( "System.Windows.Forms" ) ConsoleWrite( "IsObj( $oAssembly ) = " & IsObj( $oAssembly ) & @CRLF ) ConsoleWrite( @CRLF & "_CRL_CreateObject: System.Windows.Forms.Form" & @CRLF ) Local $oForm = _CRL_CreateObject( $oAssembly, "System.Windows.Forms.Form" ) ConsoleWrite( "IsObj( $oForm ) = " & IsObj( $oForm ) & @CRLF ) $oForm.Text = "Form From Net - AutoIt Rocks" $oForm.Width = 800 $oForm.Height = 400 ConsoleWrite( @CRLF & "_CRL_CreateObject System.Windows.Forms.Button" & @CRLF ) Local $oButton1 = _CRL_CreateObject($oAssembly, "System.Windows.Forms.Button") $oButton1.Text = "button" $oButton1.Width = 60 $oButton1.Height = 30 Local $hEventHandler = DllCallbackRegister( "EventHandler", "int", "ptr" ) Local $pEventHandler = DllCallbackGetPtr( $hEventHandler ) ; Add an event handler for the "OnEvent" event. Use "" to pass the ; address as a string, since IDispatch doesn't support 64-bit integers. $oHelper.AddHandler( $oButton1, "Click", $pEventHandler ) ;$oForm.Controls.Add( $oButton1 ) ; ERR $oButton1.Parent = $oForm ; OK $oForm.ShowDialog() $oForm.Dispose() EndFunc ; Our event handler is called with a SAFEARRAY of parameters. This ; makes it much easier to get the type and value of each parameter. Func EventHandler( $pprm ) ConsoleWrite( "$pprm = " & $pprm & @CRLF ) Local $iDim = SafeArrayGetDim( $pprm ) ConsoleWrite( "$iDim = " & $iDim & @CRLF ) Local $iLBound, $iUBound SafeArrayGetLBound( $pprm, 1, $iLBound ) SafeArrayGetUBound( $pprm, 1, $iUBound ) ConsoleWrite( "$iLBound = " & $iLBound & @CRLF ) ConsoleWrite( "$iUBound = " & $iUBound & @CRLF ) Local $tprm = DllStructCreate( $tagSAFEARRAY, $pprm ) Local $fFeatures = DllStructGetData( $tprm, "fFeatures" ) ConsoleWrite( "$fFeatures = 0x" & Hex( $fFeatures ) & @CRLF ) Local $cbElements = DllStructGetData( $tprm, "cbElements" ) ConsoleWrite( "$cbElements = " & $cbElements & @CRLF ) Local $vt SafeArrayGetVartype( $pprm, $vt ) ConsoleWrite( "$vt = " & $vt & @CRLF ) Local $prmData, $tvt, $data, $obj SafeArrayAccessData( $pprm, $prmData ) $tvt = DllStructCreate( "word", $prmData ) $vt = DllStructGetData( $tvt, 1 ) ConsoleWrite( "$vt = " & $vt & @CRLF ) ; EventArgs Class $data = DllStructGetData( DllStructCreate( "ptr", $prmData + 8 ), 1 ) $obj = ConvertPtrToIDispatch($data) ConsoleWrite( $obj.ToString() & @CRLF ) $tvt = DllStructCreate( "word", $prmData + ( @AutoItX64 ? 24 : 16 ) ) $vt = DllStructGetData( $tvt, 1 ) ConsoleWrite( "$vt = " & $vt & @CRLF ) ; EventArgs Class $data = DllStructGetData( DllStructCreate( "ptr", $prmData + ( @AutoItX64 ? 24 : 16 ) + 8 ), 1 ) $obj = ConvertPtrToIDispatch($data) ConsoleWrite( $obj.ToString() & @CRLF ) SafeArrayUnaccessData( $pprm ) EndFunc ; In the end we still want the autoit object. This function converts a raw pointer to an autoit object Func ConvertPtrToIDispatch($IDispatch_Ptr) ; This would have been 10000x easier if autoit had supported the idispatch* type in dllstructs... ; Fortunetely memcpy can copy the pointer into a idispatch*, lucky us. $ptr_struct=DllStructCreate("ptr") DllStructSetData($ptr_struct,1,$IDispatch_Ptr) $aCall = DllCall("ntdll.dll","ptr:cdecl","memcpy","idispatch*","","ptr",DllStructGetPtr($ptr_struct),"long",4) return $aCall[1] EndFunc ptrex, Gianni, Danyfirex and 1 other 4 Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions Link to comment Share on other sites More sharing options...
Gianni Posted March 29, 2017 Share Posted March 29, 2017 Chimp small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt.... Link to comment Share on other sites More sharing options...
ptrex Posted March 29, 2017 Share Posted March 29, 2017 (edited) Hi Larsj, again a victory with your 'event handler' !!! Also good to see that the SafeArray do really fit in, into this project... A lot of hightech code to get it working though, but it works that's most important ... I was reading through the code, and tried to figure out where you add the trigger in the eventhandler to activate a function ? Like this : $oButton1.add_click(test()) Edited March 30, 2017 by ptrex Contributions :Firewall Log Analyzer for XP - Creating COM objects without a need of DLL's - UPnP support in AU3Crystal Reports Viewer - PDFCreator in AutoIT - Duplicate File FinderSQLite3 Database functionality - USB Monitoring - Reading Excel using SQLRun Au3 as a Windows Service - File Monitor - Embedded Flash PlayerDynamic Functions - Control Panel Applets - Digital Signing Code - Excel Grid In AutoIT - Constants for Special Folders in WindowsRead data from Any Windows Edit Control - SOAP and Web Services in AutoIT - Barcode Printing Using PS - AU3 on LightTD WebserverMS LogParser SQL Engine in AutoIT - ImageMagick Image Processing - Converter @ Dec - Hex - Bin -Email Address Encoder - MSI Editor - SNMP - MIB ProtocolFinancial Functions UDF - Set ACL Permissions - Syntax HighLighter for AU3ADOR.RecordSet approach - Real OCR - HTTP Disk - PDF Reader Personal Worldclock - MS Indexing Engine - Printing ControlsGuiListView - Navigation (break the 4000 Limit barrier) - Registration Free COM DLL Distribution - Update - WinRM SMART Analysis - COM Object Browser - Excel PivotTable Object - VLC Media Player - Windows LogOnOff Gui -Extract Data from Outlook to Word & Excel - Analyze Event ID 4226 - DotNet Compiler Wrapper - Powershell_COM - New Link to comment Share on other sites More sharing options...
LarsJ Posted March 30, 2017 Share Posted March 30, 2017 Chimp, This was a good laugh. ptrex, Add some Switch statements to the bottom of the event handler. Here demonstrated with MsgBoxes. Note that the MsgBoxes are not blocking. You can use Tab to navigate between buttons and Enter/Space to click. tst01.au3 expandcollapse popup;#AutoIt3Wrapper_UseX64=y #include "CLR.au3" Example() ; Form Using System.Windows.Forms.Form Func Example() ; Compile the helper class. This could be pre-compiled. Local $oHelper, $oHelperAsm = _CLR_CompileCSharp( FileRead( "EventHelper.cs" ) ) $oHelperAsm.CreateInstance( "EventHelper", $oHelper ) ConsoleWrite( "IsObj( $oHelper ) = " & IsObj( $oHelper ) & @CRLF ) ConsoleWrite( "_CLR_LoadLibrary System.Windows.Forms" & @CRLF ) Local $oAssembly = _CLR_LoadLibrary( "System.Windows.Forms" ) ConsoleWrite( "IsObj( $oAssembly ) = " & IsObj( $oAssembly ) & @CRLF ) ConsoleWrite( @CRLF & "_CRL_CreateObject: System.Windows.Forms.Form" & @CRLF ) Local $oForm = _CRL_CreateObject( $oAssembly, "System.Windows.Forms.Form" ) ConsoleWrite( "IsObj( $oForm ) = " & IsObj( $oForm ) & @CRLF ) $oForm.Text = "Form From Net - AutoIt Rocks" $oForm.Width = 800 $oForm.Height = 400 ConsoleWrite( @CRLF & "_CRL_CreateObject System.Windows.Forms.Button" & @CRLF ) Local $oButton1 = _CRL_CreateObject($oAssembly, "System.Windows.Forms.Button") $oButton1.Text = "button1" $oButton1.Width = 60 $oButton1.Height = 30 $oButton1.Left = 100 $oButton1.Top = 100 ConsoleWrite( @CRLF & "_CRL_CreateObject System.Windows.Forms.Button" & @CRLF ) Local $oButton2 = _CRL_CreateObject($oAssembly, "System.Windows.Forms.Button") $oButton2.Text = "button2" $oButton2.Width = 60 $oButton2.Height = 30 $oButton2.Left = $oButton1.Right + 50 $oButton2.Top = $oButton1.Top Local $hEventHandler = DllCallbackRegister( "EventHandler", "int", "ptr" ) Local $pEventHandler = DllCallbackGetPtr( $hEventHandler ) ; Add an event handler for the "OnEvent" event. Use "" to pass the ; address as a string, since IDispatch doesn't support 64-bit integers. $oHelper.AddHandler( $oButton1, "Click", $pEventHandler ) $oHelper.AddHandler( $oButton2, "Click", $pEventHandler ) ;$oForm.Controls.Add( $oButton1 ) ; ERR $oButton1.Parent = $oForm ; OK $oButton2.Parent = $oForm ; OK $oForm.ShowDialog() $oForm.Dispose() EndFunc ; Our event handler is called with a SAFEARRAY of parameters. This ; makes it much easier to get the type and value of each parameter. Func EventHandler( $pprm ) ConsoleWrite( "$pprm = " & $pprm & @CRLF ) Local $iDim = SafeArrayGetDim( $pprm ) ConsoleWrite( "$iDim = " & $iDim & @CRLF ) Local $iLBound, $iUBound SafeArrayGetLBound( $pprm, 1, $iLBound ) SafeArrayGetUBound( $pprm, 1, $iUBound ) ConsoleWrite( "$iLBound = " & $iLBound & @CRLF ) ConsoleWrite( "$iUBound = " & $iUBound & @CRLF ) Local $tprm = DllStructCreate( $tagSAFEARRAY, $pprm ) Local $fFeatures = DllStructGetData( $tprm, "fFeatures" ) ConsoleWrite( "$fFeatures = 0x" & Hex( $fFeatures ) & @CRLF ) Local $cbElements = DllStructGetData( $tprm, "cbElements" ) ConsoleWrite( "$cbElements = " & $cbElements & @CRLF ) Local $vt SafeArrayGetVartype( $pprm, $vt ) ConsoleWrite( "$vt = " & $vt & @CRLF ) Local $prmData, $tvt, $data, $obj SafeArrayAccessData( $pprm, $prmData ) $tvt = DllStructCreate( "word", $prmData ) $vt = DllStructGetData( $tvt, 1 ) ConsoleWrite( "$vt = " & $vt & @CRLF ) ; EventArgs Class $data = DllStructGetData( DllStructCreate( "ptr", $prmData + 8 ), 1 ) $obj = ConvertPtrToIDispatch($data) Local $sCtrlInfo = $obj.ToString() ConsoleWrite( $sCtrlInfo & @CRLF ) $tvt = DllStructCreate( "word", $prmData + ( @AutoItX64 ? 24 : 16 ) ) $vt = DllStructGetData( $tvt, 1 ) ConsoleWrite( "$vt = " & $vt & @CRLF ) ; EventArgs Class $data = DllStructGetData( DllStructCreate( "ptr", $prmData + ( @AutoItX64 ? 24 : 16 ) + 8 ), 1 ) $obj = ConvertPtrToIDispatch($data) ConsoleWrite( $obj.ToString() & @CRLF ) SafeArrayUnaccessData( $pprm ) Local $aCtrlInfo = StringSplit( $sCtrlInfo, ", ", 2 ) ; 2 = $STR_NOCOUNT For $i = 0 To UBound( $aCtrlInfo ) - 1 ConsoleWrite( "$i = " & $i & ", $aCtrlInfo[$i] = " & $aCtrlInfo[$i] & @CRLF ) Next Switch $aCtrlInfo[0] Case "System.Windows.Forms.Button" Switch $aCtrlInfo[3] Case "button1" MsgBox( 0, "", "button1" ) Case "button2" MsgBox( 0, "", "button2" ) EndSwitch EndSwitch EndFunc ; In the end we still want the autoit object. This function converts a raw pointer to an autoit object Func ConvertPtrToIDispatch($IDispatch_Ptr) ; This would have been 10000x easier if autoit had supported the idispatch* type in dllstructs... ; Fortunetely memcpy can copy the pointer into a idispatch*, lucky us. $ptr_struct=DllStructCreate("ptr") DllStructSetData($ptr_struct,1,$IDispatch_Ptr) $aCall = DllCall("ntdll.dll","ptr:cdecl","memcpy","idispatch*","","ptr",DllStructGetPtr($ptr_struct),"long",4) return $aCall[1] EndFunc Danyfirex 1 Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions Link to comment Share on other sites More sharing options...
trancexx Posted March 30, 2017 Share Posted March 30, 2017 (edited) ^^ Small remark if I may... that ConvertPtrToIDispatch() function isn't really how it should be done today. Much better would be: $obj = ObjCreateInterface($data, $sIID_IDispatch) Grrr... "nowadays". Edited March 31, 2017 by trancexx LarsJ 1 ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
ptrex Posted March 31, 2017 Share Posted March 31, 2017 (edited) Hi Larsj, Working like a charm again one step closer to getting the GUI to run including controls... Thanks again for all the efforts There are still some challenges to tackle though Trancexx, Indeed works as well like this ? Thanks for looking over our shoulders expandcollapse popup;#AutoIt3Wrapper_UseX64=y #include "CLR.au3" Example() ; Form Using System.Windows.Forms.Form Func Example() ; Compile the helper class. This could be pre-compiled. Local $oHelper, $oHelperAsm = _CLR_CompileCSharp( FileRead( "EventHelper.cs" ) ) $oHelperAsm.CreateInstance( "EventHelper", $oHelper ) ConsoleWrite( "IsObj( $oHelper ) = " & IsObj( $oHelper ) & @CRLF ) ConsoleWrite( "_CLR_LoadLibrary System.Windows.Forms" & @CRLF ) Local $oAssembly = _CLR_LoadLibrary( "System.Windows.Forms" ) ConsoleWrite( "IsObj( $oAssembly ) = " & IsObj( $oAssembly ) & @CRLF ) ConsoleWrite( @CRLF & "_CRL_CreateObject: System.Windows.Forms.Form" & @CRLF ) Local $oForm = _CRL_CreateObject( $oAssembly, "System.Windows.Forms.Form" ) ConsoleWrite( "IsObj( $oForm ) = " & IsObj( $oForm ) & @CRLF ) $oForm.Text = "Form From Net - AutoIt Rocks" $oForm.Width = 800 $oForm.Height = 400 ConsoleWrite( @CRLF & "_CRL_CreateObject System.Windows.Forms.Button" & @CRLF ) Local $oButton1 = _CRL_CreateObject($oAssembly, "System.Windows.Forms.Button") $oButton1.Text = "button1" $oButton1.Width = 60 $oButton1.Height = 30 $oButton1.Left = 100 $oButton1.Top = 100 ConsoleWrite( @CRLF & "_CRL_CreateObject System.Windows.Forms.Button" & @CRLF ) Local $oButton2 = _CRL_CreateObject($oAssembly, "System.Windows.Forms.Button") $oButton2.Text = "button2" $oButton2.Width = 60 $oButton2.Height = 30 $oButton2.Left = $oButton1.Right + 50 $oButton2.Top = $oButton1.Top Local $hEventHandler = DllCallbackRegister( "EventHandler", "int", "ptr" ) Local $pEventHandler = DllCallbackGetPtr( $hEventHandler ) ; Add an event handler for the "OnEvent" event. Use "" to pass the ; address as a string, since IDispatch doesn't support 64-bit integers. $oHelper.AddHandler( $oButton1, "Click", $pEventHandler ) $oHelper.AddHandler( $oButton2, "Click", $pEventHandler ) ;$oForm.Controls.Add( $oButton1 ) ; ERR $oButton1.Parent = $oForm ; OK $oButton2.Parent = $oForm ; OK $oForm.ShowDialog() $oForm.Dispose() EndFunc ; Our event handler is called with a SAFEARRAY of parameters. This ; makes it much easier to get the type and value of each parameter. Func EventHandler( $pprm ) ConsoleWrite( "$pprm = " & $pprm & @CRLF ) Local $iDim = SafeArrayGetDim( $pprm ) ConsoleWrite( "$iDim = " & $iDim & @CRLF ) Local $iLBound, $iUBound SafeArrayGetLBound( $pprm, 1, $iLBound ) SafeArrayGetUBound( $pprm, 1, $iUBound ) ConsoleWrite( "$iLBound = " & $iLBound & @CRLF ) ConsoleWrite( "$iUBound = " & $iUBound & @CRLF ) Local $tprm = DllStructCreate( $tagSAFEARRAY, $pprm ) Local $fFeatures = DllStructGetData( $tprm, "fFeatures" ) ConsoleWrite( "$fFeatures = 0x" & Hex( $fFeatures ) & @CRLF ) Local $cbElements = DllStructGetData( $tprm, "cbElements" ) ConsoleWrite( "$cbElements = " & $cbElements & @CRLF ) Local $vt SafeArrayGetVartype( $pprm, $vt ) ConsoleWrite( "$vt = " & $vt & @CRLF ) Local $prmData, $tvt, $data, $obj SafeArrayAccessData( $pprm, $prmData ) $tvt = DllStructCreate( "word", $prmData ) $vt = DllStructGetData( $tvt, 1 ) ConsoleWrite( "$vt = " & $vt & @CRLF ) ; EventArgs Class $data = DllStructGetData( DllStructCreate( "ptr", $prmData + 8 ), 1 ) ;~ $obj = ConvertPtrToIDispatch($data) $obj = ObjCreateInterface($data, $sIID_IDispatch) Local $sCtrlInfo = $obj.ToString() ConsoleWrite( $sCtrlInfo & @CRLF ) $tvt = DllStructCreate( "word", $prmData + ( @AutoItX64 ? 24 : 16 ) ) $vt = DllStructGetData( $tvt, 1 ) ConsoleWrite( "$vt = " & $vt & @CRLF ) ; EventArgs Class $data = DllStructGetData( DllStructCreate( "ptr", $prmData + ( @AutoItX64 ? 24 : 16 ) + 8 ), 1 ) ;~ $obj = ConvertPtrToIDispatch($data) $obj = ObjCreateInterface($data, $sIID_IDispatch) ConsoleWrite( $obj.ToString() & @CRLF ) SafeArrayUnaccessData( $pprm ) Local $aCtrlInfo = StringSplit( $sCtrlInfo, ", ", 2 ) ; 2 = $STR_NOCOUNT For $i = 0 To UBound( $aCtrlInfo ) - 1 ConsoleWrite( "$i = " & $i & ", $aCtrlInfo[$i] = " & $aCtrlInfo[$i] & @CRLF ) Next Switch $aCtrlInfo[0] Case "System.Windows.Forms.Button" Switch $aCtrlInfo[3] Case "button1" MsgBox( 0, "", "button1" ) Case "button2" MsgBox( 0, "", "button2" ) EndSwitch EndSwitch EndFunc #cs ; In the end we still want the autoit object. This function converts a raw pointer to an autoit object Func ConvertPtrToIDispatch($IDispatch_Ptr) ; This would have been 10000x easier if autoit had supported the idispatch* type in dllstructs... ; Fortunetely memcpy can copy the pointer into a idispatch*, lucky us. $ptr_struct=DllStructCreate("ptr") DllStructSetData($ptr_struct,1,$IDispatch_Ptr) $aCall = DllCall("ntdll.dll","ptr:cdecl","memcpy","idispatch*","","ptr",DllStructGetPtr($ptr_struct),"long",4) return $aCall[1] EndFunc #ce Edited March 31, 2017 by ptrex Contributions :Firewall Log Analyzer for XP - Creating COM objects without a need of DLL's - UPnP support in AU3Crystal Reports Viewer - PDFCreator in AutoIT - Duplicate File FinderSQLite3 Database functionality - USB Monitoring - Reading Excel using SQLRun Au3 as a Windows Service - File Monitor - Embedded Flash PlayerDynamic Functions - Control Panel Applets - Digital Signing Code - Excel Grid In AutoIT - Constants for Special Folders in WindowsRead data from Any Windows Edit Control - SOAP and Web Services in AutoIT - Barcode Printing Using PS - AU3 on LightTD WebserverMS LogParser SQL Engine in AutoIT - ImageMagick Image Processing - Converter @ Dec - Hex - Bin -Email Address Encoder - MSI Editor - SNMP - MIB ProtocolFinancial Functions UDF - Set ACL Permissions - Syntax HighLighter for AU3ADOR.RecordSet approach - Real OCR - HTTP Disk - PDF Reader Personal Worldclock - MS Indexing Engine - Printing ControlsGuiListView - Navigation (break the 4000 Limit barrier) - Registration Free COM DLL Distribution - Update - WinRM SMART Analysis - COM Object Browser - Excel PivotTable Object - VLC Media Player - Windows LogOnOff Gui -Extract Data from Outlook to Word & Excel - Analyze Event ID 4226 - DotNet Compiler Wrapper - Powershell_COM - New Link to comment Share on other sites More sharing options...
LarsJ Posted April 1, 2017 Share Posted April 1, 2017 (edited) In the code in the post above you can replace ; Add an event handler for the "OnEvent" event. Use "" to pass the ; address as a string, since IDispatch doesn't support 64-bit integers. $oHelper.AddHandler( $oButton1, "Click", $pEventHandler ) $oHelper.AddHandler( $oButton2, "Click", $pEventHandler ) with ; Make an event handler (event must be of the EventHandler type). Local $oHandler = $oHelper.MakeHandler( $pEventHandler ) $oButton1.add_Click( $oHandler ) $oButton2.add_Click( $oHandler ) if you prefer. And in fact it's probably the best way. And in bottom of the event handler it's much better to compare the objects directly instead of just checking the text of the object: For $i = 0 To UBound( $aObjects ) - 1 If $obj.Equals( $aObjects[$i] ) Then ExitLoop Next If $i < UBound( $aObjects ) Then MsgBox( 0, "", $obj.ToString() ) EndIf tst02.au3: expandcollapse popup;#AutoIt3Wrapper_UseX64=y #include "CLR.au3" Global $aObjects[2] Example() ; Form Using System.Windows.Forms.Form Func Example() ; Compile the helper class. This could be pre-compiled. Local $oHelper, $oHelperAsm = _CLR_CompileCSharp( FileRead( "EventHelper.cs" ) ) $oHelperAsm.CreateInstance( "EventHelper", $oHelper ) ConsoleWrite( "IsObj( $oHelper ) = " & IsObj( $oHelper ) & @CRLF ) ConsoleWrite( "_CLR_LoadLibrary System.Windows.Forms" & @CRLF ) Local $oAssembly = _CLR_LoadLibrary( "System.Windows.Forms" ) ConsoleWrite( "IsObj( $oAssembly ) = " & IsObj( $oAssembly ) & @CRLF ) ConsoleWrite( @CRLF & "_CRL_CreateObject: System.Windows.Forms.Form" & @CRLF ) Local $oForm = _CRL_CreateObject( $oAssembly, "System.Windows.Forms.Form" ) ConsoleWrite( "IsObj( $oForm ) = " & IsObj( $oForm ) & @CRLF ) $oForm.Text = "Form From Net - AutoIt Rocks" $oForm.Width = 800 $oForm.Height = 400 ConsoleWrite( @CRLF & "_CRL_CreateObject System.Windows.Forms.Button" & @CRLF ) Local $oButton1 = _CRL_CreateObject($oAssembly, "System.Windows.Forms.Button") $oButton1.Text = "button1" $oButton1.Width = 60 $oButton1.Height = 30 $oButton1.Left = 100 $oButton1.Top = 100 $aObjects[0] = $oButton1 ConsoleWrite( @CRLF & "_CRL_CreateObject System.Windows.Forms.Button" & @CRLF ) Local $oButton2 = _CRL_CreateObject($oAssembly, "System.Windows.Forms.Button") $oButton2.Text = "button2" $oButton2.Width = 60 $oButton2.Height = 30 $oButton2.Left = $oButton1.Right + 50 $oButton2.Top = $oButton1.Top $aObjects[1] = $oButton2 Local $hEventHandler = DllCallbackRegister( "EventHandler", "int", "ptr" ) Local $pEventHandler = DllCallbackGetPtr( $hEventHandler ) ; Add an event handler for the "OnEvent" event. Use "" to pass the ; address as a string, since IDispatch doesn't support 64-bit integers. ;$oHelper.AddHandler( $oButton1, "Click", $pEventHandler ) ;$oHelper.AddHandler( $oButton2, "Click", $pEventHandler ) ; Make an event handler (event must be of the EventHandler type). Local $oHandler = $oHelper.MakeHandler( $pEventHandler ) $oButton1.add_Click( $oHandler ) $oButton2.add_Click( $oHandler ) ;$oForm.Controls.Add( $oButton1 ) ; ERR $oButton1.Parent = $oForm ; OK $oButton2.Parent = $oForm ; OK $oForm.ShowDialog() $oForm.Dispose() EndFunc ; Our event handler is called with a SAFEARRAY of parameters. This ; makes it much easier to get the type and value of each parameter. Func EventHandler( $pprm ) ConsoleWrite( "$pprm = " & $pprm & @CRLF ) Local $iDim = SafeArrayGetDim( $pprm ) ConsoleWrite( "$iDim = " & $iDim & @CRLF ) Local $iLBound, $iUBound SafeArrayGetLBound( $pprm, 1, $iLBound ) SafeArrayGetUBound( $pprm, 1, $iUBound ) ConsoleWrite( "$iLBound = " & $iLBound & @CRLF ) ConsoleWrite( "$iUBound = " & $iUBound & @CRLF ) Local $tprm = DllStructCreate( $tagSAFEARRAY, $pprm ) Local $fFeatures = DllStructGetData( $tprm, "fFeatures" ) ConsoleWrite( "$fFeatures = 0x" & Hex( $fFeatures ) & @CRLF ) Local $cbElements = DllStructGetData( $tprm, "cbElements" ) ConsoleWrite( "$cbElements = " & $cbElements & @CRLF ) Local $vt SafeArrayGetVartype( $pprm, $vt ) ConsoleWrite( "$vt = " & $vt & @CRLF ) Local $prmData, $pData, $obj SafeArrayAccessData( $pprm, $prmData ) $vt = DllStructGetData( DllStructCreate( "word", $prmData ), 1 ) ConsoleWrite( "$vt = " & $vt & @CRLF & @CRLF ) ; EventArgs Class $pData = DllStructGetData( DllStructCreate( "ptr", $prmData + 8 ), 1 ) $obj = ObjCreateInterface( $pData, $sIID_IDispatch ) SafeArrayUnaccessData( $pprm ) For $i = 0 To UBound( $aObjects ) - 1 If $obj.Equals( $aObjects[$i] ) Then ExitLoop Next If $i < UBound( $aObjects ) Then MsgBox( 0, "", $obj.ToString() ) EndIf EndFunc Edited April 1, 2017 by LarsJ Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions Link to comment Share on other sites More sharing options...
ptrex Posted April 1, 2017 Share Posted April 1, 2017 Hi Larsj, Nice you reworked the EventHandler in clean code ... ! I added some more controls to the Example : Label CheckBox TextBox ComboBox Listview : issues here adding columns ?! expandcollapse popup;#AutoIt3Wrapper_UseX64=y #include "CLR.au3" Global $aObjects[2] Example() ; Form Using System.Windows.Forms.Form Func Example() #Region Register EventHelper ; Compile the helper class. This could be pre-compiled. Local $oHelper, $oHelperAsm = _CLR_CompileCSharp( FileRead( "EventHelper.cs" ) ) $oHelperAsm.CreateInstance( "EventHelper", $oHelper ) ConsoleWrite( "IsObj( $oHelper ) = " & IsObj( $oHelper ) & @CRLF ) #EndRegion #Region Add Controls ConsoleWrite( "_CLR_LoadLibrary System.Windows.Forms" & @CRLF ) Local $oAssembly = _CLR_LoadLibrary( "System.Windows.Forms" ) ConsoleWrite( "IsObj( $oAssembly ) = " & IsObj( $oAssembly ) & @CRLF ) ConsoleWrite( @CRLF & "_CRL_CreateObject: System.Windows.Forms.Form" & @CRLF ) Local $oForm = _CRL_CreateObject( $oAssembly, "System.Windows.Forms.Form" ) ConsoleWrite( "IsObj( $oForm ) = " & IsObj( $oForm ) & @CRLF ) $oForm.Text = "Form From Net - AutoIt Rocks" $oForm.Width = 800 $oForm.Height = 400 ConsoleWrite( @CRLF & "_CRL_CreateObject System.Windows.Forms.Button 1" & @CRLF ) Local $oButton1 = _CRL_CreateObject($oAssembly, "System.Windows.Forms.Button") $oButton1.Text = "button1" $oButton1.Width = 60 $oButton1.Height = 30 $oButton1.Left = 40 $oButton1.Top = 10 $aObjects[0] = $oButton1 ConsoleWrite( @CRLF & "_CRL_CreateObject System.Windows.Forms.Button 2" & @CRLF ) Local $oButton2 = _CRL_CreateObject($oAssembly, "System.Windows.Forms.Button") $oButton2.Text = "button2" $oButton2.Width = 60 $oButton2.Height = 30 $oButton2.Left = $oButton1.Right + 50 $oButton2.Top = $oButton1.Top $aObjects[1] = $oButton2 ConsoleWrite( @CRLF & "_CRL_CreateObject System.Windows.Forms.checkbox" & @CRLF ) Local $checkbox1 = _CRL_CreateObject($oAssembly, "System.Windows.Forms.checkbox") $checkbox1.Top = 55 $checkbox1.Left = 155 ConsoleWrite( @CRLF & "_CRL_CreateObject System.Windows.Forms.ComboBox" & @CRLF ) Local $Combo = _CRL_CreateObject($oAssembly, "System.Windows.Forms.ComboBox") $Combo.Width = 50 $Combo.Top = 15 $Combo.Left = 290 For $i = 1 to 4 $Combo.Items.Add("test" & $i) Next ConsoleWrite( @CRLF & "_CRL_CreateObject System.Windows.Forms.Label" & @CRLF ) Local $Label = _CRL_CreateObject($oAssembly, "System.Windows.Forms.Label") $Label.Width = 140 $Label.Top = 55 $Label.Left = 15 ;~ $Label.Font = "Microsoft Sans Serif, 18pt, style=Bold, Italic" ; Does not Work $Label.Text = "Press The Buttons ..." ConsoleWrite( @CRLF & "_CRL_CreateObject System.Windows.Forms.TextBox" & @CRLF ) Local $Textbox = _CRL_CreateObject($oAssembly, "System.Windows.Forms.TextBox") $Textbox.Width = 120 $Textbox.Top = 55 $Textbox.Left = 295 $Textbox.Text = "Enter Text Here ..." ConsoleWrite( @CRLF & "_CRL_CreateObject System.Windows.Forms.ListView" & @CRLF ) Local $ListView = _CRL_CreateObject($oAssembly, "System.Windows.Forms.ListView") $ListView.Width = 220 $ListView.Top = 95 $ListView.Left = 295 ConsoleWrite( @CRLF & "_CRL_CreateObject System.Windows.Forms.ColumnHeader" & @CRLF ) Local $columnHeader1 = _CRL_CreateObject($oAssembly, "System.Windows.Forms.ColumnHeader") ConsoleWrite("$columnHeader1 : " & IsObj($columnHeader1) & @CRLF & @CRLF) $ListView.Columns.add($columnHeader1) ; Does not work !!! #EndRegion #Region Events Local $hEventHandler = DllCallbackRegister( "EventHandler", "int", "ptr" ) Local $pEventHandler = DllCallbackGetPtr( $hEventHandler ) ; Add an event handler for the "OnEvent" event. Use "" to pass the ; address as a string, since IDispatch doesn't support 64-bit integers. ; $oHelper.AddHandler( $oButton1, "Click", $pEventHandler ) ; $oHelper.AddHandler( $oButton2, "Click", $pEventHandler ) ; Make an event handler (event must be of the EventHandler type). Local $oHandler = $oHelper.MakeHandler( $pEventHandler ) $oButton1.add_Click( $oHandler ) $oButton2.add_Click( $oHandler ) #EndRegion #Region Add Controls ;$oForm.Controls.Add( $oButton1 ) ; ERR $oButton1.Parent = $oForm ; OK $oButton2.Parent = $oForm $checkbox1.Parent = $oForm $Combo.Parent = $oForm $Label.Parent = $oForm $Textbox.Parent = $oForm $ListView.Parent = $oForm #EndRegion $oForm.ShowDialog() $oForm.Dispose() EndFunc #Region EventHandler ; Our event handler is called with a SAFEARRAY of parameters. This ; makes it much easier to get the type and value of each parameter. Func EventHandler( $pprm ) ConsoleWrite( "$pprm = " & $pprm & @CRLF ) Local $iDim = SafeArrayGetDim( $pprm ) ConsoleWrite( "$iDim = " & $iDim & @CRLF ) Local $iLBound, $iUBound SafeArrayGetLBound( $pprm, 1, $iLBound ) SafeArrayGetUBound( $pprm, 1, $iUBound ) ConsoleWrite( "$iLBound = " & $iLBound & @CRLF ) ConsoleWrite( "$iUBound = " & $iUBound & @CRLF ) Local $tprm = DllStructCreate( $tagSAFEARRAY, $pprm ) Local $fFeatures = DllStructGetData( $tprm, "fFeatures" ) ConsoleWrite( "$fFeatures = 0x" & Hex( $fFeatures ) & @CRLF ) Local $cbElements = DllStructGetData( $tprm, "cbElements" ) ConsoleWrite( "$cbElements = " & $cbElements & @CRLF ) Local $vt SafeArrayGetVartype( $pprm, $vt ) ConsoleWrite( "$vt = " & $vt & @CRLF ) Local $prmData, $pData, $obj SafeArrayAccessData( $pprm, $prmData ) $vt = DllStructGetData( DllStructCreate( "word", $prmData ), 1 ) ConsoleWrite( "$vt = " & $vt & @CRLF & @CRLF ) ; EventArgs Class $pData = DllStructGetData( DllStructCreate( "ptr", $prmData + 8 ), 1 ) $obj = ObjCreateInterface( $pData, $sIID_IDispatch ) ; Convert Pointer to iDispatch SafeArrayUnaccessData( $pprm ) For $i = 0 To UBound( $aObjects ) - 1 If $obj.Equals( $aObjects[$i] ) Then ExitLoop Next If $i < UBound( $aObjects ) Then MsgBox( 0, "", $obj.ToString() ) EndIf EndFunc #EndRegion Again issues with adding controls using the .NET syntax Anyhow there are a few more hurdles to take ... like the _CRL_CreateObject( xxx, Arg1, Arg2, ...) is missing list of arguments to pass to the object's constructor. Examples : - System.Drawing.Size(130,60) - System.Drawing.Font("Times New Roman",12) Also found this was implemented on the AHK CLR : CLR_CreateObject( Assembly, sType [, Type1, Arg1, Type2, Arg2 ... ] ) (CLR) Instantiates an object of the specified type from the specified assembly. Optionally accepts a list of arguments to pass to the object's constructor. For AutoHotkey Basic, TypeN is a value from the VARENUM enumeration Again we are a few steps closer to the finish line ... Gianni 1 Contributions :Firewall Log Analyzer for XP - Creating COM objects without a need of DLL's - UPnP support in AU3Crystal Reports Viewer - PDFCreator in AutoIT - Duplicate File FinderSQLite3 Database functionality - USB Monitoring - Reading Excel using SQLRun Au3 as a Windows Service - File Monitor - Embedded Flash PlayerDynamic Functions - Control Panel Applets - Digital Signing Code - Excel Grid In AutoIT - Constants for Special Folders in WindowsRead data from Any Windows Edit Control - SOAP and Web Services in AutoIT - Barcode Printing Using PS - AU3 on LightTD WebserverMS LogParser SQL Engine in AutoIT - ImageMagick Image Processing - Converter @ Dec - Hex - Bin -Email Address Encoder - MSI Editor - SNMP - MIB ProtocolFinancial Functions UDF - Set ACL Permissions - Syntax HighLighter for AU3ADOR.RecordSet approach - Real OCR - HTTP Disk - PDF Reader Personal Worldclock - MS Indexing Engine - Printing ControlsGuiListView - Navigation (break the 4000 Limit barrier) - Registration Free COM DLL Distribution - Update - WinRM SMART Analysis - COM Object Browser - Excel PivotTable Object - VLC Media Player - Windows LogOnOff Gui -Extract Data from Outlook to Word & Excel - Analyze Event ID 4226 - DotNet Compiler Wrapper - Powershell_COM - New Link to comment Share on other sites More sharing options...
trancexx Posted April 1, 2017 Share Posted April 1, 2017 You don't need to use .Equals to compare objects. AutoIt can do that by itself. Besides this all can be reduced on both sides, maybe like this: EventHelper.cs using System; using System.Reflection; using System.Reflection.Emit; using System.Runtime.InteropServices; public class EventHelper { // Delegate type for the AutoIt callback. public delegate void CallbackType([MarshalAs(UnmanagedType.LPArray)] object[] argv); public EventHandler MakeHandler([MarshalAs(UnmanagedType.FunctionPtr)] CallbackType cb) { return (sender, e) => cb( new[] {sender} ); } } And then the last example LarsJ posted expandcollapse popup#include "CLR.au3" Global $aObjects[2] Example() ; Form Using System.Windows.Forms.Form Func Example() ; Compile the helper class. This could be pre-compiled. Local $oHelper, $oHelperAsm = _CLR_CompileCSharp(FileRead("EventHelper.cs")) $oHelperAsm.CreateInstance("EventHelper", $oHelper) ConsoleWrite("IsObj( $oHelper ) = " & IsObj($oHelper) & @CRLF) ConsoleWrite("_CLR_LoadLibrary System.Windows.Forms" & @CRLF) Local $oAssembly = _CLR_LoadLibrary("System.Windows.Forms") ConsoleWrite("IsObj( $oAssembly ) = " & IsObj($oAssembly) & @CRLF) ConsoleWrite(@CRLF & "_CRL_CreateObject: System.Windows.Forms.Form" & @CRLF) Local $oForm = _CRL_CreateObject($oAssembly, "System.Windows.Forms.Form") ConsoleWrite("IsObj( $oForm ) = " & IsObj($oForm) & @CRLF) $oForm.Text = "Form From Net - AutoIt Rocks" $oForm.Width = 800 $oForm.Height = 400 ConsoleWrite(@CRLF & "_CRL_CreateObject System.Windows.Forms.Button" & @CRLF) Local $oButton1 = _CRL_CreateObject($oAssembly, "System.Windows.Forms.Button") $oButton1.Text = "button1" $oButton1.Width = 60 $oButton1.Height = 30 $oButton1.Left = 100 $oButton1.Top = 100 $aObjects[0] = $oButton1 ConsoleWrite(@CRLF & "_CRL_CreateObject System.Windows.Forms.Button" & @CRLF) Local $oButton2 = _CRL_CreateObject($oAssembly, "System.Windows.Forms.Button") $oButton2.Text = "button2" $oButton2.Width = 60 $oButton2.Height = 30 $oButton2.Left = $oButton1.Right + 50 $oButton2.Top = $oButton1.Top $aObjects[1] = $oButton2 Local $hEventHandler = DllCallbackRegister("EventHandler", "int", "ptr") Local $pEventHandler = DllCallbackGetPtr($hEventHandler) ; Make an event handler (event must be of the EventHandler type). Local $oHandler = $oHelper.MakeHandler($pEventHandler) $oButton1.add_Click($oHandler) $oButton2.add_Click($oHandler) $oButton1.Parent = $oForm ; OK $oButton2.Parent = $oForm ; OK $oForm.ShowDialog() $oForm.Dispose() EndFunc ; Event handler is called with a LPArray of 1 parameter (variant pointer). Func EventHandler($pprm) ConsoleWrite("$pprm = " & $pprm & @CRLF) Local $vVar = DllStructCreate($tagVARIANT, $pprm) $obj = ObjCreateInterface(DllStructGetData($vVar, "data"), $sIID_IDispatch) For $i = 0 To UBound($aObjects) - 1 If $obj = $aObjects[$i] Then MsgBox(0, "", $obj.ToString(), 0, $obj.Handle) ; give it parent handle not to have ten boxes one over other ExitLoop EndIf Next EndFunc junkew 1 ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
ptrex Posted April 1, 2017 Share Posted April 1, 2017 trancexx, Nice clean up ! works like a charm ... but expandcollapse popup;#AutoIt3Wrapper_UseX64=y #include "CLR.au3" Global $aObjects[3] Example() ; Form Using System.Windows.Forms.Form Func Example() #Region Register EventHelper ; Compile the helper class. This could be pre-compiled. Local $oHelper, $oHelperAsm = _CLR_CompileCSharp( FileRead( "EventHelperNEW.cs" ) ) ; NEWER Version $oHelperAsm.CreateInstance( "EventHelper", $oHelper ) ConsoleWrite( "IsObj( $oHelper ) = " & IsObj( $oHelper ) & @CRLF ) #EndRegion #Region Add Controls ConsoleWrite( "_CLR_LoadLibrary System.Drawing" & @CRLF ) Local $oAssemblyDraw = _CLR_LoadLibrary( "System.Drawing" ) ConsoleWrite( "IsObj( $oAssemblyDraw ) = " & IsObj( $oAssemblyDraw ) & @CRLF ) ConsoleWrite( "_CLR_LoadLibrary System.Windows.Forms" & @CRLF ) Local $oAssembly = _CLR_LoadLibrary( "System.Windows.Forms" ) ConsoleWrite( "IsObj( $oAssembly ) = " & IsObj( $oAssembly ) & @CRLF ) ConsoleWrite( @CRLF & "_CRL_CreateObject: System.Windows.Forms.Form" & @CRLF ) Local $oForm = _CRL_CreateObject( $oAssembly, "System.Windows.Forms.Form" ) ConsoleWrite( "IsObj( $oForm ) = " & IsObj( $oForm ) & @CRLF ) $oForm.Text = "Form From Net - AutoIt Rocks" $oForm.Width = 800 $oForm.Height = 400 ConsoleWrite( @CRLF & "_CRL_CreateObject System.Windows.Forms.Button 1" & @CRLF ) Local $oButton1 = _CRL_CreateObject($oAssembly, "System.Windows.Forms.Button") $oButton1.Text = "button1" $oButton1.Width = 60 $oButton1.Height = 30 $oButton1.Left = 40 $oButton1.Top = 10 $aObjects[0] = $oButton1 ConsoleWrite( @CRLF & "_CRL_CreateObject System.Windows.Forms.Button 2" & @CRLF ) Local $oButton2 = _CRL_CreateObject($oAssembly, "System.Windows.Forms.Button") $oButton2.Text = "button2" $oButton2.Width = 60 $oButton2.Height = 30 $oButton2.Left = $oButton1.Right + 50 $oButton2.Top = $oButton1.Top $aObjects[1] = $oButton2 ConsoleWrite( @CRLF & "_CRL_CreateObject System.Windows.Forms.checkbox" & @CRLF ) Local $checkbox1 = _CRL_CreateObject($oAssembly, "System.Windows.Forms.checkbox") $checkbox1.Top = 55 $checkbox1.Left = 155 $checkbox1.Checked = True ConsoleWrite( @CRLF & "_CRL_CreateObject System.Windows.Forms.ComboBox" & @CRLF ) Local $Combo = _CRL_CreateObject($oAssembly, "System.Windows.Forms.ComboBox") $Combo.Width = 50 $Combo.Top = 15 $Combo.Left = 290 For $i = 1 to 4 $Combo.Items.Add("test" & $i) Next ConsoleWrite( @CRLF & "_CRL_CreateObject System.Windows.Forms.Label" & @CRLF ) Local $Label = _CRL_CreateObject($oAssembly, "System.Windows.Forms.Label") $Label.Width = 140 $Label.Top = 55 $Label.Left = 15 ;~ $Label.Font = "Microsoft Sans Serif, 18pt, style=Bold, Italic" ; Does not Work $Label.Text = "Press The Buttons ..." ConsoleWrite( @CRLF & "_CRL_CreateObject System.Windows.Forms.TextBox" & @CRLF ) Local $Textbox = _CRL_CreateObject($oAssembly, "System.Windows.Forms.TextBox") $Textbox.Width = 120 $Textbox.Top = 55 $Textbox.Left = 295 $Textbox.Text = "Enter Text Here ..." ConsoleWrite( @CRLF & "_CRL_CreateObject System.Windows.Forms.ListView" & @CRLF ) Local $ListView = _CRL_CreateObject($oAssembly, "System.Windows.Forms.ListView") $ListView.Width = 220 $ListView.Top = 95 $ListView.Left = 295 $ListView.Name = "listView1" ConsoleWrite( @CRLF & "_CRL_CreateObject System.Windows.Forms.ColumnHeader" & @CRLF ) Local $columnHeader1 = _CRL_CreateObject($oAssembly, "System.Windows.Forms.ColumnHeader") ConsoleWrite("$columnHeader1 : " & IsObj($columnHeader1) & @CRLF & @CRLF) $ListView.Columns.add($columnHeader1) ; Does not work !!! #EndRegion #Region Events Local $hEventHandler = DllCallbackRegister( "EventHandler", "int", "ptr" ) Local $pEventHandler = DllCallbackGetPtr( $hEventHandler ) ; Add an event handler for the "OnEvent" event. Use "" to pass the ; address as a string, since IDispatch doesn't support 64-bit integers. ; $oHelper.AddHandler( $oButton1, "Click", $pEventHandler ) ; $oHelper.AddHandler( $oButton2, "Click", $pEventHandler ) ; Make an event handler (event must be of the EventHandler type). Local $oHandler = $oHelper.MakeHandler( $pEventHandler ) $oButton1.add_Click( $oHandler ) $oButton2.add_Click( $oHandler ) $checkbox1.add_Click( $oHandler ) #EndRegion #Region Add Controls ;$oForm.Controls.Add( $oButton1 ) ; ERR $oButton1.Parent = $oForm ; OK $oButton2.Parent = $oForm $checkbox1.Parent = $oForm $Combo.Parent = $oForm $Label.Parent = $oForm $Textbox.Parent = $oForm $ListView.Parent = $oForm ; $Panel.Parent = $oForm #EndRegion $oForm.ShowDialog() $oForm.Dispose() EndFunc #Region EventHandler ; Event handler is called with a LPArray of 1 parameter (variant pointer). Func EventHandler($pprm) ConsoleWrite("$pprm = " & $pprm & @CRLF) Local $vVar = DllStructCreate($tagVARIANT, $pprm) $obj = ObjCreateInterface(DllStructGetData($vVar, "data"), $sIID_IDispatch) For $i = 0 To UBound($aObjects) - 1 ConsoleWrite("test " & $obj & " " & $aObjects[$i] & @CRLF) If $obj = $aObjects[$i] Then MsgBox(0, "Event Output", $obj.ToString(), 0, $obj.Handle) ; give it parent handle not to have ten boxes one over other ExitLoop EndIf Next EndFunc #EndRegion Added an event to checkbox but no output ? the $obj does not return anything ? Contributions :Firewall Log Analyzer for XP - Creating COM objects without a need of DLL's - UPnP support in AU3Crystal Reports Viewer - PDFCreator in AutoIT - Duplicate File FinderSQLite3 Database functionality - USB Monitoring - Reading Excel using SQLRun Au3 as a Windows Service - File Monitor - Embedded Flash PlayerDynamic Functions - Control Panel Applets - Digital Signing Code - Excel Grid In AutoIT - Constants for Special Folders in WindowsRead data from Any Windows Edit Control - SOAP and Web Services in AutoIT - Barcode Printing Using PS - AU3 on LightTD WebserverMS LogParser SQL Engine in AutoIT - ImageMagick Image Processing - Converter @ Dec - Hex - Bin -Email Address Encoder - MSI Editor - SNMP - MIB ProtocolFinancial Functions UDF - Set ACL Permissions - Syntax HighLighter for AU3ADOR.RecordSet approach - Real OCR - HTTP Disk - PDF Reader Personal Worldclock - MS Indexing Engine - Printing ControlsGuiListView - Navigation (break the 4000 Limit barrier) - Registration Free COM DLL Distribution - Update - WinRM SMART Analysis - COM Object Browser - Excel PivotTable Object - VLC Media Player - Windows LogOnOff Gui -Extract Data from Outlook to Word & Excel - Analyze Event ID 4226 - DotNet Compiler Wrapper - Powershell_COM - New Link to comment Share on other sites More sharing options...
trancexx Posted April 1, 2017 Share Posted April 1, 2017 18 minutes ago, ptrex said: trancexx, Nice clean up ! works like a charm ... but expandcollapse popup;#AutoIt3Wrapper_UseX64=y #include "CLR.au3" Global $aObjects[3] Example() ; Form Using System.Windows.Forms.Form Func Example() #Region Register EventHelper ; Compile the helper class. This could be pre-compiled. Local $oHelper, $oHelperAsm = _CLR_CompileCSharp( FileRead( "EventHelperNEW.cs" ) ) ; NEWER Version $oHelperAsm.CreateInstance( "EventHelper", $oHelper ) ConsoleWrite( "IsObj( $oHelper ) = " & IsObj( $oHelper ) & @CRLF ) #EndRegion #Region Add Controls ConsoleWrite( "_CLR_LoadLibrary System.Drawing" & @CRLF ) Local $oAssemblyDraw = _CLR_LoadLibrary( "System.Drawing" ) ConsoleWrite( "IsObj( $oAssemblyDraw ) = " & IsObj( $oAssemblyDraw ) & @CRLF ) ConsoleWrite( "_CLR_LoadLibrary System.Windows.Forms" & @CRLF ) Local $oAssembly = _CLR_LoadLibrary( "System.Windows.Forms" ) ConsoleWrite( "IsObj( $oAssembly ) = " & IsObj( $oAssembly ) & @CRLF ) ConsoleWrite( @CRLF & "_CRL_CreateObject: System.Windows.Forms.Form" & @CRLF ) Local $oForm = _CRL_CreateObject( $oAssembly, "System.Windows.Forms.Form" ) ConsoleWrite( "IsObj( $oForm ) = " & IsObj( $oForm ) & @CRLF ) $oForm.Text = "Form From Net - AutoIt Rocks" $oForm.Width = 800 $oForm.Height = 400 ConsoleWrite( @CRLF & "_CRL_CreateObject System.Windows.Forms.Button 1" & @CRLF ) Local $oButton1 = _CRL_CreateObject($oAssembly, "System.Windows.Forms.Button") $oButton1.Text = "button1" $oButton1.Width = 60 $oButton1.Height = 30 $oButton1.Left = 40 $oButton1.Top = 10 $aObjects[0] = $oButton1 ConsoleWrite( @CRLF & "_CRL_CreateObject System.Windows.Forms.Button 2" & @CRLF ) Local $oButton2 = _CRL_CreateObject($oAssembly, "System.Windows.Forms.Button") $oButton2.Text = "button2" $oButton2.Width = 60 $oButton2.Height = 30 $oButton2.Left = $oButton1.Right + 50 $oButton2.Top = $oButton1.Top $aObjects[1] = $oButton2 ConsoleWrite( @CRLF & "_CRL_CreateObject System.Windows.Forms.checkbox" & @CRLF ) Local $checkbox1 = _CRL_CreateObject($oAssembly, "System.Windows.Forms.checkbox") $checkbox1.Top = 55 $checkbox1.Left = 155 $checkbox1.Checked = True ConsoleWrite( @CRLF & "_CRL_CreateObject System.Windows.Forms.ComboBox" & @CRLF ) Local $Combo = _CRL_CreateObject($oAssembly, "System.Windows.Forms.ComboBox") $Combo.Width = 50 $Combo.Top = 15 $Combo.Left = 290 For $i = 1 to 4 $Combo.Items.Add("test" & $i) Next ConsoleWrite( @CRLF & "_CRL_CreateObject System.Windows.Forms.Label" & @CRLF ) Local $Label = _CRL_CreateObject($oAssembly, "System.Windows.Forms.Label") $Label.Width = 140 $Label.Top = 55 $Label.Left = 15 ;~ $Label.Font = "Microsoft Sans Serif, 18pt, style=Bold, Italic" ; Does not Work $Label.Text = "Press The Buttons ..." ConsoleWrite( @CRLF & "_CRL_CreateObject System.Windows.Forms.TextBox" & @CRLF ) Local $Textbox = _CRL_CreateObject($oAssembly, "System.Windows.Forms.TextBox") $Textbox.Width = 120 $Textbox.Top = 55 $Textbox.Left = 295 $Textbox.Text = "Enter Text Here ..." ConsoleWrite( @CRLF & "_CRL_CreateObject System.Windows.Forms.ListView" & @CRLF ) Local $ListView = _CRL_CreateObject($oAssembly, "System.Windows.Forms.ListView") $ListView.Width = 220 $ListView.Top = 95 $ListView.Left = 295 $ListView.Name = "listView1" ConsoleWrite( @CRLF & "_CRL_CreateObject System.Windows.Forms.ColumnHeader" & @CRLF ) Local $columnHeader1 = _CRL_CreateObject($oAssembly, "System.Windows.Forms.ColumnHeader") ConsoleWrite("$columnHeader1 : " & IsObj($columnHeader1) & @CRLF & @CRLF) $ListView.Columns.add($columnHeader1) ; Does not work !!! #EndRegion #Region Events Local $hEventHandler = DllCallbackRegister( "EventHandler", "int", "ptr" ) Local $pEventHandler = DllCallbackGetPtr( $hEventHandler ) ; Add an event handler for the "OnEvent" event. Use "" to pass the ; address as a string, since IDispatch doesn't support 64-bit integers. ; $oHelper.AddHandler( $oButton1, "Click", $pEventHandler ) ; $oHelper.AddHandler( $oButton2, "Click", $pEventHandler ) ; Make an event handler (event must be of the EventHandler type). Local $oHandler = $oHelper.MakeHandler( $pEventHandler ) $oButton1.add_Click( $oHandler ) $oButton2.add_Click( $oHandler ) $checkbox1.add_Click( $oHandler ) #EndRegion #Region Add Controls ;$oForm.Controls.Add( $oButton1 ) ; ERR $oButton1.Parent = $oForm ; OK $oButton2.Parent = $oForm $checkbox1.Parent = $oForm $Combo.Parent = $oForm $Label.Parent = $oForm $Textbox.Parent = $oForm $ListView.Parent = $oForm ; $Panel.Parent = $oForm #EndRegion $oForm.ShowDialog() $oForm.Dispose() EndFunc #Region EventHandler ; Event handler is called with a LPArray of 1 parameter (variant pointer). Func EventHandler($pprm) ConsoleWrite("$pprm = " & $pprm & @CRLF) Local $vVar = DllStructCreate($tagVARIANT, $pprm) $obj = ObjCreateInterface(DllStructGetData($vVar, "data"), $sIID_IDispatch) For $i = 0 To UBound($aObjects) - 1 ConsoleWrite("test " & $obj & " " & $aObjects[$i] & @CRLF) If $obj = $aObjects[$i] Then MsgBox(0, "Event Output", $obj.ToString(), 0, $obj.Handle) ; give it parent handle not to have ten boxes one over other ExitLoop EndIf Next EndFunc #EndRegion Added an event to checkbox but no output ? the $obj does not return anything ? Shouldn't you have $aObjects[2] = $checkbox1 somewhere there? ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
LarsJ Posted April 2, 2017 Share Posted April 2, 2017 Listview. Can't you use the parent parameter of $columnHeader1? So far CLR.au3 only contains code that is used in the specific examples. The code in my examples is not finished code. So it may well be possible to optimize some bits of the code. EventHelper.cs. The AddHandler function is not used in these examples. But I still think there is a need for it. Eg. to detect events generated through C#/VB code. trancexx, Do you have an idea of what this problem with Controls.Add and Columns.Add (Form.Controls.Add(Button), ListView.Columns.Add(ColumnHeader)) is? And if so how we solve the problem? Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions Link to comment Share on other sites More sharing options...
ptrex Posted April 2, 2017 Share Posted April 2, 2017 (edited) The question is first to find out where the problem is in CLR or in AU3 ? Junkew can you do a test if it works in VBA ? Larsj is it working in AHK ? If it is not working there it is not an AU3 issue but a limitation of CLR. Edited April 3, 2017 by ptrex Contributions :Firewall Log Analyzer for XP - Creating COM objects without a need of DLL's - UPnP support in AU3Crystal Reports Viewer - PDFCreator in AutoIT - Duplicate File FinderSQLite3 Database functionality - USB Monitoring - Reading Excel using SQLRun Au3 as a Windows Service - File Monitor - Embedded Flash PlayerDynamic Functions - Control Panel Applets - Digital Signing Code - Excel Grid In AutoIT - Constants for Special Folders in WindowsRead data from Any Windows Edit Control - SOAP and Web Services in AutoIT - Barcode Printing Using PS - AU3 on LightTD WebserverMS LogParser SQL Engine in AutoIT - ImageMagick Image Processing - Converter @ Dec - Hex - Bin -Email Address Encoder - MSI Editor - SNMP - MIB ProtocolFinancial Functions UDF - Set ACL Permissions - Syntax HighLighter for AU3ADOR.RecordSet approach - Real OCR - HTTP Disk - PDF Reader Personal Worldclock - MS Indexing Engine - Printing ControlsGuiListView - Navigation (break the 4000 Limit barrier) - Registration Free COM DLL Distribution - Update - WinRM SMART Analysis - COM Object Browser - Excel PivotTable Object - VLC Media Player - Windows LogOnOff Gui -Extract Data from Outlook to Word & Excel - Analyze Event ID 4226 - DotNet Compiler Wrapper - Powershell_COM - New Link to comment Share on other sites More sharing options...
junkew Posted April 4, 2017 Share Posted April 4, 2017 Little to busy with other stuff maybe in the weekend Ï will try further Nice reading on .NET 4.0 https://msdn.microsoft.com/en-us/library/system.dynamic.expandoobject.aspx could be an alternative I think to AutoIt objects https://msdn.microsoft.com/en-us/library/system.dynamic.dynamicobject(v=vs.110).aspx use for wrapping around not exposed comvisible interfaces??? FAQ 31 How to click some elements, FAQ 40 Test automation with AutoIt, Multithreading CLR .NET Powershell CMDLets Link to comment Share on other sites More sharing options...
LarsJ Posted April 5, 2017 Share Posted April 5, 2017 So far we have successfully been able to implement the following: Load the Common Language Runtime (CLR) into the AutoIt process (post 25 by Danyfirex) Examples in the following posts by Danyfirex, junkew and ptrex From the code in post 25 it was possible to create the _AppDomain object (post 56) From there we've managed to translate two AutoHotkey examples. The first example in post 62 loads a XPTable.dll assembly, creates a listview with checkboxes and buttons, and displays the listview in an AutoIt GUI. The second example in post 65 compiles and executes C#-code on the fly. Danyfirex has collected all code and examples in the zip file in post 68 At this point we can load .Net assemblies (DLL-files), compile and execute C#/VB-code on the fly and create simple Windows.Forms GUIs. Example code by ptrex and junkew in posts 80 - 98 shows some issues with .Net Windows.Forms code related to collections of controls. Examples in posts 102 - 110 demonstrates how to handle events. Two event handlers are translated from AutoHotkey code in post 102. trancexx has shown an event handler with reduced code in post 110. (If $aObjects[] is replaced with a dictionary object, the array loop in bottom of the event handler function can be avoided and replaced by a dictionary lookup.) With these event handlers we can handle events from Windows.Forms controls, .Net assemblies and C#/VB-code We've been able to implement all this without too overwhelming effort. Personally I'm happy with what we've achieved and that means I'll scale down my own efforts significantly. It should be possible to create up to several interesting UDFs based on the code in previous posts. Of course the code has to be completed and cleaned up but that should not be too hard. I'll not go into this. Maybe I'll create a few UDFs for my own purposes. But it'll not be soon. It has been fun. Regards Lars. Danyfirex 1 Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions Link to comment Share on other sites More sharing options...
junkew Posted April 5, 2017 Share Posted April 5, 2017 @LarsJ thx so far Added summary in post 4. FAQ 31 How to click some elements, FAQ 40 Test automation with AutoIt, Multithreading CLR .NET Powershell CMDLets Link to comment Share on other sites More sharing options...
ptrex Posted April 5, 2017 Share Posted April 5, 2017 LarsJ, My thanks as well, you made it at least possible to access the .Net framework !!! Junkew, if I look at the AHK examples there is an other issue not solved yet and that is the parameters, that are missing in the _CRL_CreateObject. Like this : drawing := CLR_LoadLibrary("System.Drawing") headerFont := CLR_CreateObject(drawing, "System.Drawing.Font", "Tahoma", 20) rowFont := CLR_CreateObject(drawing, "System.Drawing.Font", "Tahoma", 12) This is crucial in many in many of this objects; that need to be created, not only the GUI Controls... Anyhow let's see how this evolves... the links you posted is definitely interesting reading material too. Contributions :Firewall Log Analyzer for XP - Creating COM objects without a need of DLL's - UPnP support in AU3Crystal Reports Viewer - PDFCreator in AutoIT - Duplicate File FinderSQLite3 Database functionality - USB Monitoring - Reading Excel using SQLRun Au3 as a Windows Service - File Monitor - Embedded Flash PlayerDynamic Functions - Control Panel Applets - Digital Signing Code - Excel Grid In AutoIT - Constants for Special Folders in WindowsRead data from Any Windows Edit Control - SOAP and Web Services in AutoIT - Barcode Printing Using PS - AU3 on LightTD WebserverMS LogParser SQL Engine in AutoIT - ImageMagick Image Processing - Converter @ Dec - Hex - Bin -Email Address Encoder - MSI Editor - SNMP - MIB ProtocolFinancial Functions UDF - Set ACL Permissions - Syntax HighLighter for AU3ADOR.RecordSet approach - Real OCR - HTTP Disk - PDF Reader Personal Worldclock - MS Indexing Engine - Printing ControlsGuiListView - Navigation (break the 4000 Limit barrier) - Registration Free COM DLL Distribution - Update - WinRM SMART Analysis - COM Object Browser - Excel PivotTable Object - VLC Media Player - Windows LogOnOff Gui -Extract Data from Outlook to Word & Excel - Analyze Event ID 4226 - DotNet Compiler Wrapper - Powershell_COM - New Link to comment Share on other sites More sharing options...
junkew Posted April 6, 2017 Share Posted April 6, 2017 @ptrex Did we already have an example on that parameter thing? should be "straight forward" with a safe array as args parameter public: [SecurityCriticalAttribute] [ObsoleteAttribute("Methods which use evidence to sandbox are obsolete and will be removed in a future release of the .NET Framework. Please use an overload of CreateInstance which does not take an Evidence parameter. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")] static ObjectHandle^ CreateInstance( AppDomain^ domain, String^ assemblyName, String^ typeName, bool ignoreCase, BindingFlags bindingAttr, Binder^ binder, array<Object^>^ args, CultureInfo^ culture, array<Object^>^ activationAttributes, Evidence^ securityAttributes ) some HP UFT dotnetfactory examples (so no reason to believe it will not work in AutoIt) Set dialogForm = DotNetFactory.CreateInstance("System.Windows.Forms.Form", "System.Windows.Forms") Set dialogStartPosition = DotNetFactory.CreateInstance("System.Windows.Forms.FormStartPosition", "System.Windows.Forms") Set dialogBorderStyle = DotNetFactory.CreateInstance("System.Windows.Forms.FormBorderStyle", "System.Windows.Forms") Set dialogLabel = DotNetFactory.CreateInstance("System.Windows.Forms.Label", "System.Windows.Forms") Set dialogFont = DotNetFactory.CreateInstance("System.Drawing.Font", "System.Drawing", "Microsoft Sans Serif", 11) Set dialogContentAlign = DotNetFactory.CreateInstance("System.Drawing.ContentAlignment", "System.Drawing") FAQ 31 How to click some elements, FAQ 40 Test automation with AutoIt, Multithreading CLR .NET Powershell CMDLets Link to comment Share on other sites More sharing options...
ptrex Posted April 6, 2017 Share Posted April 6, 2017 Hi Junkew / Larsj, This is the CreateObject function, it only accepts 1 parameter ? Func _CRL_CreateObject(ByRef $oAssembly, $sTypeName = "", $sParameter3 = "") #forceref $oAssembly, $sTypeName, $sParameter3 If @NumParams = 2 Then Local $oObject = 0 $oAssembly.CreateInstance_2($sTypeName, True, $oObject) Return $oObject EndIf If @NumParams = 3 Then ; static Array_Empty := ComObjArray(0xC,0), null := ComObject(13,0) Local $pSAEmpty, $tSAB = DllStructCreate($tagSAFEARRAYBOUND) DllStructSetData($tSAB, "cElements", 0) DllStructSetData($tSAB, "lLbound", 0) $pSAEmpty = SafeArrayCreate($VT_VARIANT, 0, $tSAB) Local $oObject = 0 $oAssembly.CreateInstance_3($sTypeName, True, 0, 0, CreateSafeArray($sParameter3), 0, $pSAEmpty, $oObject) Return $oObject EndIf EndFunc ;==>_CRL_CreateObject If it exceeds 3 parameters or more, the SafeArray should probably be loaded with the additional parameters data. By looping through the parameters, this can be passed on to the $Assembly.CreateInstance_3 This is the AHK function ... https://pastebin.com/G1BrL6p6 CLR_CreateObject(Assembly, TypeName, Args*) { if !(argCount := Args.MaxIndex()) return Assembly.CreateInstance_2(TypeName, true) vargs := ComObjArray(0xC, argCount) Loop % argCount vargs[A_Index-1] := Args[A_Index] static Array_Empty := ComObjArray(0xC,0), nulln := ComObject(13,0) return Assembly.CreateInstance_3(TypeName, true, 0, nulln, vargs, nulln, Array_Empty) } Example is like this : expandcollapse popup;~ #AutoIt3Wrapper_UseX64=y #include "CLR.Au3" _Example() Func _Example() ;~ Local $ofrmAssembly = _CLR_LoadLibrary("System.Windows.Forms") Local $oAssembly = _CLR_LoadLibrary("System.Windows.Forms") ConsoleWrite("!$oAssembly: " & IsObj($oAssembly) & @CRLF) Local $oForm = _CRL_CreateObject($oAssembly, "System.Windows.Forms.Form") ConsoleWrite("!$oForm: " & IsObj($oForm) & @CRLF) $oform.name="Form1" #Region dynamic controls $oCol=$oForm.controls ConsoleWrite("!$oCol: " & IsObj($oCol) & @CRLF) Local $oBtn= _CRL_CreateObject($oAssembly, "System.Windows.Forms.Button") ConsoleWrite("!$oBtn " & IsObj($oBtn) & @CRLF) $oBtn.Name="Button1" $oBtn.Text="Button1" $oBtn.Top = 20 $oBtn.Width=80 $oBtn.Left = 150 Local $oText= _CRL_CreateObject($oAssembly, "System.Windows.Forms.TextBox") ConsoleWrite("!$oText: " & IsObj($oText) & @CRLF) $oText.Top = 20 $oText.Left = 20 $oText.Text = "Font Test" #cs AHK Syntax using Paramters is missing in AU3 - https://pastebin.com/G1BrL6p6 drawing := CLR_LoadLibrary("System.Drawing") headerFont := CLR_CreateObject(drawing, "System.Drawing.Font", "Tahoma", 20) rowFont := CLR_CreateObject(drawing, "System.Drawing.Font", "Tahoma", 12) #ce Local $drawing = _CLR_LoadLibrary("System.Drawing") ConsoleWrite("!$drawing: " & IsObj($drawing) & @CRLF) $oFontText = _CRL_CreateObject($drawing, "System.Drawing.Font","Courier New", 10, 20) ConsoleWrite("!$oFontText: " & IsObj($oFontText) & @CRLF) ;~ Local $oSize = _CRL_CreateObject($drawing, "System.Drawing.Size", 10, 20) ;~ ConsoleWrite("!$oSize: " & IsObj($oSize) & @CRLF) ;~ $oBtn.Size = $oSize ;~ $oForm.opacity=0.75 $oForm.Text = "Form From Net - AutoIt Rocks" $oForm.Width = 800 $oForm.Height = 400 ;~ consolewrite("ocol.count " & $ocol.count & @crlf) ;~ $oForm.controls.Add($oText) ; this does does not work ?! $oBtn.parent = $oForm $oText.parent = $oForm #EndRegion ;~ $oForm.Show() $oForm.ShowDialog() ;~ Sleep(1000) ConsoleWrite("$oForm Handle: " & $oForm.Handle & @CRLF) $oForm.Dispose() EndFunc ;==>_Example Most of the Type constructors have 2 or more parameters... so without handling this properly the use is very limited. Contributions :Firewall Log Analyzer for XP - Creating COM objects without a need of DLL's - UPnP support in AU3Crystal Reports Viewer - PDFCreator in AutoIT - Duplicate File FinderSQLite3 Database functionality - USB Monitoring - Reading Excel using SQLRun Au3 as a Windows Service - File Monitor - Embedded Flash PlayerDynamic Functions - Control Panel Applets - Digital Signing Code - Excel Grid In AutoIT - Constants for Special Folders in WindowsRead data from Any Windows Edit Control - SOAP and Web Services in AutoIT - Barcode Printing Using PS - AU3 on LightTD WebserverMS LogParser SQL Engine in AutoIT - ImageMagick Image Processing - Converter @ Dec - Hex - Bin -Email Address Encoder - MSI Editor - SNMP - MIB ProtocolFinancial Functions UDF - Set ACL Permissions - Syntax HighLighter for AU3ADOR.RecordSet approach - Real OCR - HTTP Disk - PDF Reader Personal Worldclock - MS Indexing Engine - Printing ControlsGuiListView - Navigation (break the 4000 Limit barrier) - Registration Free COM DLL Distribution - Update - WinRM SMART Analysis - COM Object Browser - Excel PivotTable Object - VLC Media Player - Windows LogOnOff Gui -Extract Data from Outlook to Word & Excel - Analyze Event ID 4226 - DotNet Compiler Wrapper - Powershell_COM - New Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now