11-05-2018, 09:44 PM
This .NET/COM dll can be used to run macros in QM from other programs and scripts.
Where can be used
In any programming/scripting language through COM.
In C# and other .NET languages directly.
In 32-bit and 64-bit processes.
Setup
The dll uses .NET framework 4. Can be installed any 4.x.x version. If not installed, download from Microsoft and install.
Download the attached zip file. Extract anywhere, for example in QM folder.
Register the dll, unless you'll not use it as a COM component. To register, you can use regasm.exe or this QM code. Note: if you have an old RegisterNetComComponent function, need to update it.
Macro Macro35
Function RegisterNetComComponent
How to use in scripts etc
Create COM object "QmSendMessage.QMSM".
To run a macro or function, call the Run function with QM command line, like in the example.
Examples
VBScript example
You can test it in QM
Macro Macro82
Some limitations
Returning a value is not supported in this version.
The dll is not signed.
Source code
Dll source code in C#, if you want to build it in Visual Studio etc
Where can be used
In any programming/scripting language through COM.
In C# and other .NET languages directly.
In 32-bit and 64-bit processes.
Setup
The dll uses .NET framework 4. Can be installed any 4.x.x version. If not installed, download from Microsoft and install.
Download the attached zip file. Extract anywhere, for example in QM folder.
Register the dll, unless you'll not use it as a COM component. To register, you can use regasm.exe or this QM code. Note: if you have an old RegisterNetComComponent function, need to update it.
Macro Macro35
Function RegisterNetComComponent
;/
function $dllFile [flags] ;;flags: 1 unregister, 2 create type library (.tlb file), 4 use /codebase
;Registers or unregisters .NET dll as COM component.
;Error if fails.
;QM must be running as administrator.
;REMARKS
;It is possible to use .NET COM components without registration. Use __ComActivator class.
;EXAMPLE
;RegisterNetComComponent "$desktop$\ClassLibrary2.dll" 2|4
str cl so
if(!GetNetRuntimeFolder(cl)) end ES_FAILED
cl.formata("\regasm.exe ''%s'' /nologo" _s.expandpath(dllFile))
if(flags&1) cl+" /u"
else
,if(flags&2) cl+" /tlb"
,if(flags&4) cl+" /codebase"
int i
for i 0 2
,int ec=RunConsole2(cl so)
,err end _error
,so.trim
,if(ec) end so
,if(so.len) out so
,if(i or !_win64) break
,cl.findreplace("\Framework\" "\Framework64\" 5)
How to use in scripts etc
Create COM object "QmSendMessage.QMSM".
To run a macro or function, call the Run function with QM command line, like in the example.
Examples
VBScript example
You can test it in QM
Macro Macro82
str vbs=
;set q = CreateObject("QmSendMessage.QMSM")
;q.Run "Q ^ M ^Fun5^", true
VbsExec vbs
Some limitations
Returning a value is not supported in this version.
The dll is not signed.
Source code
Dll source code in C#, if you want to build it in Visual Studio etc
using System;
using System.Runtime.InteropServices;
[module: DefaultCharSet(CharSet.Unicode)]
//these can be in AssemblyInfo.cs, or here if you don't use it:
//[assembly: ComVisible(true)]
//[assembly: Guid("2cd050a0-8337-4d80-b548-56af5b16de04")]
//Also, in project properties, assembly name and default namespace is QmSendMessage, platform can be AnyCPU.
namespace QmSendMessage
{
[Guid("A4F7F0F0-44BE-4383-8065-6C2636696882")]
public interface IQMSM
{
void Run(string macro, bool wait = false);
}
[Guid("BAB07F95-1558-47C6-A6AA-0127BB8F6799"), ClassInterface(ClassInterfaceType.None)]
public class QMSM :IQMSM
{
public void Run(string commandLine, bool wait)
{
var w = FindWindow("QM_Editor", null);
if(w == default(IntPtr)) throw new InvalidOperationException("QM is not running");
SendMessage(w, WM_SETTEXT, (IntPtr)(wait ? 2 : 1), commandLine);
}
[DllImport("user32.dll", EntryPoint = "FindWindowW")]
internal static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", EntryPoint = "SendMessageW")]
internal static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, string lParam);
internal const int WM_SETTEXT = 0xC;
}
}