Search code examples
c#twincatimessagefilter

Multi-Thread message filter for TwinCAT


I'm not experienced with C# so excuse me for my lack of knowledge..

I need to implement a COM Message filter for a multi-thread application(Background worker). I got send through to this(https://learn.microsoft.com/en-us/previous-versions/ms809971(v=msdn.10)?redirectedfrom=MSDN) site but it doesn't give an example of a working filter. I can't seem to find a multi-thread message filter online.. does anyone have an example code for this filter?

The error I'm getting is described on the Beckhoff site(https://infosys.beckhoff.com/english.php?content=../content/1033/tc3_automationinterface/54043195771173899.html&id=, scroll down until you see the black administrator window, that's the error), but doesn't help me fix the problem.

Thanks!


Solution

  • Here is an example of a com message filter:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using EnvDTE;
    using EnvDTE80;
    using System.Diagnostics;
    using System.Runtime.InteropServices;
    using System.Runtime.InteropServices.ComTypes;
    using System.Collections;
    
    namespace TwincatCodeGenerator
    {
        [ComImport(),Guid("00000016-0000-0000-C000-000000000046"),InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
        interface IOleMessageFilter{
            [PreserveSig]
            int HandleInComingCall(int dwCallType, IntPtr hTaskCaller, int dwTickCount, IntPtr lpInterfaceInfo);
            [PreserveSig]
            int RetryRejectedCall(IntPtr hTaskCallee, int dwTickCount, int dwRejectType);
            [PreserveSig]
            int MessagePending(IntPtr hTaskCallee, int dwTickCount, int dwPendingType);
        }
        class MessageFilter : IOleMessageFilter
        {
            public static void Register()
            {
                IOleMessageFilter newFilter = new MessageFilter();
                IOleMessageFilter oldFilter = null;
                int test = CoRegisterMessageFilter(newFilter, out oldFilter);
                if (test != 0)
                {
                    Console.WriteLine(string.Format("CoRegisterMessageFilterfailed with error : {0}", test));
                }
            }
    
            public static void Revoke()
            {
                IOleMessageFilter oldFilter = null;
                int test = CoRegisterMessageFilter(null, out oldFilter);
            }
    
            int IOleMessageFilter.HandleInComingCall(int dwCallType, System.IntPtr hTaskCaller, int dwTickCount, System.IntPtr lpInterfaceInfo)
            {
                //returns the flag SERVERCALL_ISHANDLED.
                Console.WriteLine("HandleIncomingCall");
                return 0;
            }
    
            int IOleMessageFilter.RetryRejectedCall(System.IntPtr hTaskCallee, int dwTickCount, int dwRejectType)
            {
                //Console.WriteLine("RetryRejectedCall");
                // Thread call was refused, try again.
                if (dwRejectType == 2)
                // flag = SERVERCALL_RETRYLATER.
                {
                    // retry thread call at once, if return value >=0 &
                    // <100.
                    return 99;
                }
                return -1;
            }
    
            int IOleMessageFilter.MessagePending(System.IntPtr hTaskCallee, int dwTickCount, int dwPendingType)
            {//return flag PENDINGMSG_WAITDEFPROCESS.
                Console.WriteLine("Message Pending");
                return 2;
            }
    
            [DllImport("Ole32.dll")]private static extern int CoRegisterMessageFilter(IOleMessageFilter newFilter, out IOleMessageFilter oldFilter);
        }
    }
    

    call the filter in your main method like this:

    class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            MessageFilter.Register();
    
            //Your code here
            //...
    
            MessageFilter.Revoke();
        }
    }