Possible to use COM IMessageFilter interface from VB?

W

Whitney Kew

Hi there,

I want to implement the COM interface IMessageFilter from my VB.NET
application. I realize that it's inside ole32.dll, and that ole32.dll
doesn't have a type library inside of it, so I'm unsure if this is
even possible. I'm pretty green to VB.NET, and .NET in general, so
would anyone be able to give me a little push? Specifically, I think
what I want to do is to somehow "import" ole32.dll into my VB app, but
I'm unsure of how to do this.

My basic problem is that I'm automating Visual Studio .NET 2003 with
the EnvDTE interface, and I'm occasionally getting an exception ("Call
was rejected by callee") when I run builds with devenv.exe from the
command line. I saw the following Google article...

http://www.google.com/[email protected]&rnum=6

that pointed out that I need to implement an IMessageFilter, but the
code it points to is in C#. Does anyone know how to do this in VB?

Thanks so much in advance!
Whitney Kew
Software Engineer
Rain Bird Corporation
 
Joined
Jun 20, 2007
Messages
1
Reaction score
0
I am working with MSAccess and MS Project and have adapted my code from this example. And it works :dance:. Note all .NET languages are translatable* you can use http://www.developerfusion.com/tools/convert/csharp-to-vb/ or a number of others to adjust syntax.

* (I believe some C++ functionality is not translatable to VB.NET)

Code:
Imports Autodesk.AutoCAD.Interop
Imports System.Windows.Forms
Imports System.Runtime.InteropServices
Imports System.Reflection
Imports LoadableComponent

' For more information on IMessageFilter:
' http://msdn.microsoft.com/en-us/library/ms693740(VS.85).aspx

Namespace DrivingAutoCAD
    <ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("00000016-0000-0000-C000-000000000046")> _
    Public Interface IMessageFilter
        <PreserveSig> _
        Function HandleInComingCall(dwCallType As Integer, hTaskCaller As IntPtr, dwTickCount As Integer, lpInterfaceInfo As IntPtr) As Integer
        <PreserveSig> _
        Function RetryRejectedCall(hTaskCallee As IntPtr, dwTickCount As Integer, dwRejectType As Integer) As Integer
        <PreserveSig> _
        Function MessagePending(hTaskCallee As IntPtr, dwTickCount As Integer, dwPendingType As Integer) As Integer
    End Interface

    Public Partial Class Form1
        Inherits Form
        Implements IMessageFilter
        <DllImport("ole32.dll")> _
        Private Shared Function CoRegisterMessageFilter(lpMessageFilter As IMessageFilter, ByRef lplpMessageFilter As IMessageFilter) As Integer
        End Function

        Public Sub New()
            InitializeComponent()
            Dim oldFilter As IMessageFilter
            CoRegisterMessageFilter(Me, oldFilter)
        End Sub

        Private Sub button1_Click(sender As Object, e As EventArgs)
            Const  progID As String = "AutoCAD.Application.18"

            Dim acApp As AcadApplication = Nothing
            Try
                acApp = DirectCast(Marshal.GetActiveObject(progID), AcadApplication)
            Catch
                Try
                    Dim acType As Type = Type.GetTypeFromProgID(progID)
                    acApp = DirectCast(Activator.CreateInstance(acType, True), AcadApplication)
                Catch
                    MessageBox.Show("Cannot create object of type """ & progID & """")
                End Try
            End Try
            If acApp IsNot Nothing Then
                Try
                    ' By the time this is reached AutoCAD is fully
                    ' functional and can be interacted with through code

                    acApp.Visible = True

                    Dim app As INumberAddition = DirectCast(acApp.GetInterfaceObject("LoadableComponent.Commands"), INumberAddition)

                    ' Now let's call our method

                    Dim res As String = app.AddNumbers(5, 6.3)

                    acApp.ZoomAll()

                    MessageBox.Show(Me, "AddNumbers returned: " & res)
                Catch ex As Exception
                    MessageBox.Show(Me, "Problem executing component: " & ex.Message)
                End Try
            End If
        End Sub
        #Region "IMessageFilter Members"

        Private Function IMessageFilter_HandleInComingCall(dwCallType As Integer, hTaskCaller As IntPtr, dwTickCount As Integer, lpInterfaceInfo As IntPtr) As Integer Implements IMessageFilter.HandleInComingCall
            Return 0
            ' SERVERCALL_ISHANDLED
        End Function

        Private Function IMessageFilter_RetryRejectedCall(hTaskCallee As IntPtr, dwTickCount As Integer, dwRejectType As Integer) As Integer Implements IMessageFilter.RetryRejectedCall
            Return 1000
            ' Retry in a second
        End Function

        Private Function IMessageFilter_MessagePending(hTaskCallee As IntPtr, dwTickCount As Integer, dwPendingType As Integer) As Integer Implements IMessageFilter.MessagePending
            Return 1
            ' PENDINGMSG_WAITNOPROCESS
        End Function

        #End Region
    End Class
End Namespace
 
Last edited:

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top