Machsupport Forum

Mach Discussion => VB and the development of wizards => Topic started by: TonyG on January 14, 2010, 12:48:01 PM

Title: Using the COM API in VB .NET
Post by: TonyG on January 14, 2010, 12:48:01 PM
I'm trying to use VB .NET to control Mach, and I'm having problems getting things set up.  I searched the forums for help, and the only useful topic I found (http://www.machsupport.com/forum/index.php/topic,8429.msg54415/topicseen.html#msg54415 (http://www.machsupport.com/forum/index.php/topic,8429.msg54415/topicseen.html#msg54415))  mentions adding Mach3 as a component to your project, then gives the following code snipit:

Public Class Form1
     Dim mach As Mach4.IMach4
         mach = GetObject(, "Mach4.Document")
     Dim scriptObject As Mach4.IMyScriptObject
         scriptObject = mach.GetScriptDispatch()

     scriptObject.LoadFile("d:\Mach3\GCode\roadrunner.tap")
End Class

I added the Mach3 component by selecting Project->Add Existing Item (BTW, I'm using VB 2008 Express).  Then I selected the "Mach3.exe".  After that I saw a Mach4 namespace in my component browser window with a class named "CMach4Doc".  I then copied the code into the form procedure and tried to run the program.

The compiler complains that "Mach4.IMach4" is not defined.  Since the class name is CMach4Doc, I also tried "Dim mach As Mach4.CMach4Doc" with the same results.

I'm sure I'm missing something obvious, I just don't know what.

Tony
Title: Re: Using the COM API in VB .NET
Post by: ART on January 19, 2010, 04:08:20 PM
Tony:

  Wont be many that can help I think. I wrote that dispatch for use in C++, where you specify more data and get the actual scripter dispatch from mach3 before
using it.. as in

LPUNKNOWN lpUnk;
LPDISPATCH lpDispatch;
CLSID   clsid;

CLSIDFromProgID(OLESTR("Mach4.Document"), &clsid);
GetActiveObject( clsid, NULL, &lpUnk);
lpUnk->QueryInterface(IID_IDispatch,
      (LPVOID*)&lpDispatch);
lpUnk->Release();
mach4.AttachDispatch(lpDispatch, TRUE);
lpDispatch = mach4.GetScriptDispatch();
scripter.AttachDispatch(lpDispatch, TRUE);

   Now how that translates to VB, Im not sure.. I only program in C++..

Art

Title: Re: Using the COM API in VB .NET
Post by: TonyG on January 19, 2010, 04:18:41 PM
Art,

The poster in the thread I referenced claimed that he got it working "perfectly".  That was over a year ago and I don't know what versions of Mach and VB he was using, but if it worked then I would hope it works now.

As another option, I received some sample code showing how to access the COM interface using MFC.  But I can't find any documentation on what functions are available, what parameters they expect, what they return, etc.  Do you know if there's any documentation for the COM API?

Tony
Title: Re: Using the COM API in VB .NET
Post by: ART on January 19, 2010, 07:29:16 PM
Tony:

  There isnt. I wrote an application called Mach3 remote that exemplifies how to use the interface though , and I believe its downloadable somewhere
on the web site. IF you cant find it I can send you a copy of the C++ application if you contact me offlist at fenerty@artofcnc.ca


Art
Title: Re: Using the COM API in VB .NET
Post by: TonyG on February 02, 2010, 11:23:32 AM
Art,

I'm really close to getting this working.  I worked with Microsoft support to get the Visual Basic side of it working.  I now have a VB program that can connect to a running instance of Mach3 and send it GCode commands using the Code() function.  My only problem is that most of the time the ActiveX connection only works once.  The next time I try to connect, I get an exception.

Here's the code from my VB program:

Code: [Select]
Module Module1
    Function Main() As Integer
        Dim GCodeCommand As String
        Dim Mach As Mach4.IMach4
        Dim ScriptObject As Mach4.IMyScriptObject
        Dim ReturnCode As Integer

        ReturnCode = 0

        GCodeCommand = ""

        For Each Argument As String In My.Application.CommandLineArgs
            GCodeCommand = GCodeCommand + Argument + " "
        Next

        If (GCodeCommand <> "") Then
            Try
                Mach = GetObject(, "Mach4.Document")
                ScriptObject = Mach.GetScriptDispatch()
                ScriptObject.Code(GCodeCommand)
            Catch
                ReturnCode = -2
            End Try
        Else
            ReturnCode = -1
        End If

        Return ReturnCode
    End Function
End Module

This is a simple program that takes a G Code command from the command line and sends it to Mach3.  Then the program terminates.  My problem is that usually the next time I run the program, the call to GetObject throws an exception saying that it cannot connect to the ActiveX server.  Once this happens, it continues to happen until I close and reopen Mach3.  It always works the first time after starting Mach3, and sometimes it works multiple times in a row.  But once it fails, it's done.

I suspect that I'm missing some cleanup code, but I'm not sure what it would be.  I tried waiting for the movement to complete via IsMoving before terminating my program, but that didn't make a difference.  I saw that the C++ code sample calls DetachDispatch, but as far as I can tell those functions are part of the OLE class in C++ and are not available in VB. 

Do you have any ideas what could be causing this problem? 
Title: Re: Using the COM API in VB .NET
Post by: ART on February 02, 2010, 01:21:52 PM
Hi:

 The design is to have it connect once and MAch3 cleans up after closing.. It wasnt meant for multiple disconnect and reconnects. Thats probably why the error..

Art
Title: Re: Using the COM API in VB .NET
Post by: TonyG on February 02, 2010, 04:00:04 PM
I was afraid you were going to say that.  I'll just have to adjust my strategy to match.  Thanks for your help.  BTW, once I have the details worked out, I'm going to start a new post explaining how to use the ActiveX server in VB. 
Title: Re: Using the COM API in VB .NET
Post by: TonyG on February 09, 2010, 10:25:27 AM
Art,

I have a couple of follow up questions.  After my program opens Mach3, I have to tell the user to click on the Reset button and then the REF ALL HOME button.  I would prefer to execute those two functions automatically through the ActiveX interface.  I found a function called ResetTHC.  Does executing that function do the same thing as hitting the Reset button?  What does THC stand for?  Is there a function I can call that is equivalent to clicking on the  REF ALL HOME button?
Title: Re: Using the COM API in VB .NET
Post by: ART on February 09, 2010, 12:19:51 PM
Hi:

  THC is torch height control for plasma cutters, you likely dont wat that. As far as buttons are concerned.. just use
the scripters DoButton function to automatically press any buttons you like. The DoButton allows for any button, including any you may
have added to be pressed..

Art
Title: Re: Using the COM API in VB .NET
Post by: TonyG on February 09, 2010, 12:23:21 PM
Where can I find a list of button identifiers to send to the DoButton function?
Title: Re: Using the COM API in VB .NET
Post by: Chaoticone on February 09, 2010, 12:33:15 PM
http://www.machsupport.com/forum/index.php/topic,6657.msg90480.html#msg90480

Brett
Title: Re: Using the COM API in VB .NET
Post by: ART on February 09, 2010, 12:58:55 PM
Check the MAch3 developers documentation , theres a few documents around that describe the various button codes.. the Wiki as well documents them

Art
Title: Re: Using the COM API in VB .NET
Post by: TonyG on February 09, 2010, 05:36:20 PM
I looked at the XLS file that Brett pointed to.  If I understand it correctly, the old number for the Reset button is 1021 and the new number is 44600.  I'm not sure if I should be using old or new.  I tried 1021 and it didn't work, and 44600 is too large for the function call (DoButton function takes a short which in VB is -32k to +32k). 

Where can I find the developer's document that Art mentioned?
Title: Re: Using the COM API in VB .NET
Post by: TonyG on March 04, 2010, 02:13:54 PM
I still need some help figuring out how to activate the buttons through the ActiveX Server.