Многопоточный фильтр сообщений для TwinCAT - PullRequest
0 голосов
/ 20 сентября 2019

У меня нет опыта работы с C #, поэтому извините за отсутствие знаний ..

Мне нужно реализовать фильтр сообщений COM для многопоточного приложения (фоновый работник).Я получил сообщение на этом (https://docs.microsoft.com/en-us/previous-versions/ms809971(v=msdn.10)?redirectedfrom=MSDN) сайте), но он не дает пример работающего фильтра. Кажется, я не могу найти многопоточный фильтр сообщений онлайн. У кого-нибудь есть пример кода дляэтот фильтр?

Ошибка, которую я получаю, описана на сайте Beckhoff (https://infosys.beckhoff.com/english.php?content=../content/1033/tc3_automationinterface/54043195771173899.html&id=, прокрутите вниз, пока не увидите черное окно администратора, это ошибка), но это не помогает мне исправитьпроблема.

Спасибо!

1 Ответ

0 голосов
/ 20 сентября 2019

Вот пример фильтра сообщений com:

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);
    }
}

вызовите фильтр в вашем основном методе следующим образом:

class Program
{
    [STAThread]
    static void Main(string[] args)
    {
        MessageFilter.Register();

        //Your code here
        //...

        MessageFilter.Revoke();
    }
}
...