.NET System .__ ComObject AutoCAD事件接口

时间:2012-04-09 05:29:32

标签: .net events com interface autocad

我使用.NET Reflector从AutoCAD interop .dll重新创建了_DAcadApplicationEvents接口,并且我的代码适用于AutoCAD 2010.问题是我需要这个与AutoCAD 2006兼容,直到2012年和前进。我正在运行.NET 4.0,因此使用Embed Interop Type设置为true以确保我的Application对象正确解析到运行时而不需要反射调用方法,但我似乎无法找到一种方法来使事件接口无需工作GUID中的硬编码(特定于程序集)。


这是我从原始AutoDesk.AutoCAD.Interop.dll创建的自定义界面:

    <ComImport(), Guid("1F893620-C96D-4361-BBAF-A61D4144B7F8"), TypeLibType(CShort(&H1010))>
    Public Interface _DAcadApplicationEventsClone
        <MethodImpl(MethodImplOptions.InternalCall, MethodCodeType:=MethodCodeType.Runtime), DispId(1)>
        Sub SysVarChanged(<[In](), MarshalAs(UnmanagedType.BStr)> ByVal SysvarName As String, <[In](),
                          MarshalAs(UnmanagedType.Struct)> ByVal newVal As Object)

        <MethodImpl(MethodImplOptions.InternalCall, MethodCodeType:=MethodCodeType.Runtime), DispId(8)>
        Sub BeginQuit(<[In](), Out()> ByRef Cancel As Boolean)
    End Interface

以这种方式创建Application对象:

Public Application As Object

Application = Marshal.GetActiveObject("AutoCAD.Application")

接下来,我使用IConnectionPoint连接到克隆的界面:

Dim acGUID As New Guid(GetInterfaceGUID())

Dim acConnectionPoint As ComTypes.IConnectionPoint = Nothing
TryCast(Application, ComTypes.IConnectionPointContainer).FindConnectionPoint(acGUID, acConnectionPoint)

Dim acSinkCookie As Integer
acConnectionPoint.Advise(Me, acSinkCookie)

正如您所看到的,我正在运行一个名为“GetInterfaceGUID”的函数来动态搜索正确的GUID,具体取决于系统上安装的AutoCAD版本。但是,如果返回的GUID与接口上的硬编码GUID不匹配,则无论如何都无法正常工作。我已经尝试了不同的反射方法来使用System._ComObject,这是我唯一能够接近的方法。我觉得我已经接近成功了,并且在这一点上会感激任何意见。提前谢谢。

-Locke

1 个答案:

答案 0 :(得分:0)

正如您所发现的,AutoCAD COM Interop是版本甚至位数(32位/ 64位)相关。为什么不使用AutoCAD .NET应用程序事件来解决这些问题,如下所示?

using System;
using System.Text;
using System.Linq;
using System.Xml;
using System.Reflection;
using System.ComponentModel;
using System.Collections;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Media.Imaging;
using System.Windows.Forms;

using System.IO;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.EditorInput;

using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Windows;

using AcadApplication = Autodesk.AutoCAD.ApplicationServices.Application;
using AcadDocument = Autodesk.AutoCAD.ApplicationServices.Document;
using AcadWindows = Autodesk.AutoCAD.Windows;

namespace AcadNetAddinByVS2010
{
    public class AppEvents1
    {
        bool mSuppressMsgOutput = false;

        void OptionalMessageOutput(EventArgs obj, string eventName)
        {
            if (!mSuppressMsgOutput)
            {
                string msg = string.Format("Info about the {0} event:{1}", eventName, Environment.NewLine);

                PropertyInfo[] piArr = obj.GetType().GetProperties();
                foreach (PropertyInfo pi in piArr)
                {
                    string attValue = pi.GetValue(obj, null).ToString();
                    msg += string.Format("\t{0}: {1}{2}", pi.Name, attValue, Environment.NewLine);
                }

                MessageBox.Show(msg, "Event: " + eventName, MessageBoxButtons.OK, MessageBoxIcon.Information);
                System.Diagnostics.Debug.Write(msg);
            }
        }

        public void Register()
        {
            AcadApplication.SystemVariableChanging += AppEvent_SystemVariableChanging_Handler;
            AcadApplication.SystemVariableChanged += AppEvent_SystemVariableChanged_Handler;
            AcadApplication.QuitWillStart += AppEvent_QuitWillStart_Handler;
            AcadApplication.QuitAborted += AppEvent_QuitAborted_Handler;
            AcadApplication.PreTranslateMessage += AppEvent_PreTranslateMessage_Handler;
            AcadApplication.LeaveModal += AppEvent_LeaveModal_Handler;
            AcadApplication.Idle += AppEvent_Idle_Handler;
            AcadApplication.EnterModal += AppEvent_EnterModal_Handler;
            AcadApplication.DisplayingOptionDialog += AppEvent_DisplayingOptionDialog_Handler;
            AcadApplication.DisplayingDraftingSettingsDialog += AppEvent_DisplayingDraftingSettingsDialog_Handler;
            AcadApplication.DisplayingCustomizeDialog += AppEvent_DisplayingCustomizeDialog_Handler;
            AcadApplication.BeginQuit += AppEvent_BeginQuit_Handler;

        }

        public void UnRegister()
        {
            AcadApplication.SystemVariableChanging -= AppEvent_SystemVariableChanging_Handler;
            AcadApplication.SystemVariableChanged -= AppEvent_SystemVariableChanged_Handler;
            AcadApplication.QuitWillStart -= AppEvent_QuitWillStart_Handler;
            AcadApplication.QuitAborted -= AppEvent_QuitAborted_Handler;
            AcadApplication.PreTranslateMessage -= AppEvent_PreTranslateMessage_Handler;
            AcadApplication.LeaveModal -= AppEvent_LeaveModal_Handler;
            AcadApplication.Idle -= AppEvent_Idle_Handler;
            AcadApplication.EnterModal -= AppEvent_EnterModal_Handler;
            AcadApplication.DisplayingOptionDialog -= AppEvent_DisplayingOptionDialog_Handler;
            AcadApplication.DisplayingDraftingSettingsDialog -= AppEvent_DisplayingDraftingSettingsDialog_Handler;
            AcadApplication.DisplayingCustomizeDialog -= AppEvent_DisplayingCustomizeDialog_Handler;
            AcadApplication.BeginQuit -= AppEvent_BeginQuit_Handler;

        }

        public void AppEvent_BeginQuit_Handler(object sender, EventArgs e)
        {
            OptionalMessageOutput(e, "BeginQuit");

        }

        public void AppEvent_DisplayingCustomizeDialog_Handler(object sender, TabbedDialogEventArgs e)
        {
            OptionalMessageOutput(e, "DisplayingCustomizeDialog");

        }

        public void AppEvent_DisplayingDraftingSettingsDialog_Handler(object sender, TabbedDialogEventArgs e)
        {
            OptionalMessageOutput(e, "DisplayingDraftingSettingsDialog");

        }

        public void AppEvent_DisplayingOptionDialog_Handler(object sender, TabbedDialogEventArgs e)
        {
            OptionalMessageOutput(e, "DisplayingOptionDialog");

        }

        public void AppEvent_EnterModal_Handler(object sender, EventArgs e)
        {
            OptionalMessageOutput(e, "EnterModal");

        }

        public void AppEvent_Idle_Handler(object sender, EventArgs e)
        {
            OptionalMessageOutput(e, "Idle");

        }

        public void AppEvent_LeaveModal_Handler(object sender, EventArgs e)
        {
            OptionalMessageOutput(e, "LeaveModal");

        }

        public void AppEvent_PreTranslateMessage_Handler(object sender, PreTranslateMessageEventArgs e)
        {
            OptionalMessageOutput(e, "PreTranslateMessage");

        }

        public void AppEvent_QuitAborted_Handler(object sender, EventArgs e)
        {
            OptionalMessageOutput(e, "QuitAborted");

        }

        public void AppEvent_QuitWillStart_Handler(object sender, EventArgs e)
        {
            OptionalMessageOutput(e, "QuitWillStart");

        }

        public void AppEvent_SystemVariableChanged_Handler(object sender, Autodesk.AutoCAD.ApplicationServices.SystemVariableChangedEventArgs e)
        {
            OptionalMessageOutput(e, "SystemVariableChanged");

        }

        public void AppEvent_SystemVariableChanging_Handler(object sender, Autodesk.AutoCAD.ApplicationServices.SystemVariableChangingEventArgs e)
        {
            OptionalMessageOutput(e, "SystemVariableChanging");

        }

    }
}

以下是所选IExtensionApplication实现中的事件注册代码:

#region Namespaces

using System;
using System.Text;
using System.Linq;
using System.Xml;
using System.Reflection;
using System.ComponentModel;
using System.Collections;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Media.Imaging;
using System.Windows.Forms;
using System.Drawing;
using System.IO;

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Windows;

using AcadApplication = Autodesk.AutoCAD.ApplicationServices.Application;
using AcadDocument = Autodesk.AutoCAD.ApplicationServices.Document;
using AcadWindows = Autodesk.AutoCAD.Windows;

#endregion

namespace AcadNetAddinByVS2010
{
    public class ExtApp : IExtensionApplication
    {
        #region IExtensionApplication Members

        public void Initialize()
        {
            //TODO: add code to run when the ExtApp initializes. Here are a few examples:
            //          Checking some host information like build #, a patch or a particular Arx/Dbx/Dll;
            //          Creating/Opening some files to use in the whole life of the assembly, e.g. logs;
            //          Adding some ribbon tabs, panels, and/or buttons, when necessary;
            //          Loading some dependents explicitly which are not taken care of automatically;
            //          Subscribing to some events which are important for the whole session;
            //          Etc.

            mAppEvents1.Register();
        }

        public void Terminate()
        {
            //TODO: add code to clean up things when the ExtApp terminates. For example:
            //          Closing the log files;
            //          Deleting the custom ribbon tabs/panels/buttons;
            //          Unloading those dependents;
            //          Un-subscribing to those events;
            //          Etc.

            mAppEvents1.UnRegister();
        }

        #endregion

        AppEvents1 mAppEvents1 = new AppEvents1();
    }
}