12-22-2009 11:05 AM
But I can call the IMyScriptObject with no errors. Does this company have examples of how to call their code, can you provide one?
01-05-2010 01:47 PM
Richard,
They provided a sample project using MFC. I uploaded the file to the FTP site using the same file name (143367.rar).
The Code function we talked about previously, which should be a method but is shows up as an event, is called in the Code method defined in CMyScriptObjcet.h like this:
void Code(LPCTSTR Command)
{
static BYTE parms[] = VTS_BSTR ;
InvokeHelper(0x1c, DISPATCH_METHOD, VT_EMPTY, NULL, parms, Command);
}
Tony
01-07-2010 05:51 PM
Tony,
I looked into the library that was provided as part of this active x server, and the functions are declared in in the typedef as events. So CVI is recognizing the functions in accordance with how the Active X server was built and defined. That being said we can call callbacks directly as if they were functions (because they are) though they would not leveredge the eventdata that is traditionally passed into callbacks.
Since installing the origional mach4 software, i have had to reformat my machine. Can you please post the generated .fp from CVI as well as the supporting files (should be the same name, but have different extensions such as .h, .c, etc.) ?
01-11-2010 11:27 AM
I uploaded a ZIP file with all the Mach4 created files in it. Since the original 143367.zip file was still there, I named this one 143367b.zip.
Tony
01-12-2010 04:10 PM
Richard,
I decided to try your suggestion of just calling the callback directly. However, I ran into problems trying to register the callback. Here's my test code:
void Test(void);
static CAObjHandle Mach4Server;
HRESULT CVICALLBACK CodeCallback (CAObjHandle caServerObjHandle,
void *caCallbackData,
char *command);
void Test(void)
{
char ResultDescr[1000];
HRESULT Result = Mach4_ActiveIMach4 (NULL, 1, LOCALE_NEUTRAL, 0, &Mach4Server);
CA_GetAutomationErrorString (Result, ResultDescr, sizeof(ResultDescr));
InsertTextBoxLine (panelHandle, PANEL_txt, -1, ResultDescr);
Result = Mach4_IMyScriptObjectRegOnCode (Mach4Server, CodeCallback, NULL, 1, NULL);
CA_GetAutomationErrorString (Result, ResultDescr, sizeof(ResultDescr));
InsertTextBoxLine (panelHandle, PANEL_txt, -1, ResultDescr);
} /* Test */
HRESULT CVICALLBACK CodeCallback (CAObjHandle caServerObjHandle,
void *caCallbackData,
char *command)
{
return S_OK;
} /* CodeCallback */
The call to Mach4_IMyScriptObjectRegOnCode returns error 0x80004002 = "No sych interface supported".
Tony
P.S. I wasn't sure whether I should start with Mach4_ActiveIMach4 or Mach4_NewIMach4. Through trial and error I found that I first needed to open the Mach program and then call Mach4_ActiveIMach4. Any other combination locked up CVI or put me in an infinite loop of popup error messages from Mach.
01-15-2010 11:29 AM
Tony,
I'm still looking into this but don't have any additional information at this time.
01-19-2010 01:55 PM
Tony,
When looking at the type library for the ActiveX interface in question, we see that the methods that are being imported as callback registration routines are marked with the [default, source] attribute.
According to msdn, http://msdn.microsoft.com/en-us/library/aa232463%28VS.60%29.aspx this means that these methods are called, rather than implemented. Basically - these are events that can occur, and the user must register for. We will need to get Mach involved to verify that the IDL matches what their developers expect the IDL to look like. From all indications, it seems we are importing the members correctly.
The members highlighted in the picture follow a design pattern http://en.wikipedia.org/wiki/Component_Object_Model#COM_as_an_object_framework that would denote the members are events.
01-19-2010 02:05 PM
Thanks for the explanation. I'm going to email this thread to Mach's tech support and see what they say.
Tony
02-05-2010 05:40 PM
I've spent the last couple of weeks trying to go a different direction. I've run into another brick wall going down that path, but I learned some things that may help with the original question of how to use this ActiveX server in CVI.
To keep things short I won't bother explaining what I did or why, just what I found out. I can use this ActiveX server in .NET VB with the following code:
Dim Mach As Mach4.IMach4
Dim ScriptObject As Mach4.IMyScriptObject
Mach = GetObject(, "Mach4.Document")
ScriptObject = Mach.GetScriptDispatch()
ScriptObject.Code(GCodeCommand)
The last line with the call to the Code function is what I'm trying to get to in CVI. So here's what I noticed: The Code function isn't accessed directly from the IMach4 object in VB. I first have to call GetScriptDisptach. Then I use the handle rerturned by that function to call Code.
The created FP in CVI has a GetScriptDispatch command, too. I can call it like this:
CAObjHandle MachHandle;
CAObjHandle ScriptObjectHandle;
Mach4_OpenIMach4 ("c:\\Mach3\\Mach3.exe", NULL, 1, LOCALE_NEUTRAL, 0, &MachHandle);
Mach4_IMach4GetScriptDispatch (MachHandle, NULL, &ScriptObjectHandle);
My next step would be to use the ScriptObjectHandle to call the Code function. But of course the '.' syntax doesn't work here (as in "ScriptObjectHandle.Code..."). I tried to find some general information in the help file on what I can do with a CAObjectHandle once I've got it, but I couldn't find any general overview that pointed me in the right direction. I'm assuming there's some function call or mapping process that will let me access the members of the ScriptObjectHandle interface, I just can't figure out what they are.
Anyone have any ideas?
02-10-2010 12:02 PM
Hey Tony -
I've been working with Richard on this, and may have something you can work with.
We still hold that if these methods are meant to be callable, the type library has been created incorrectly, and should ultimately be corrected.
However, I have been able to step into our code that automatically generates the fp, and modify the generation routine to create methods that should be callable for this particular activex interface. I have attached the necessary files below for you. One thing to note is that the IMyScriptObject now has three methods New/Open/ActiveIMyScriptObject that most likely never need to be used. To get the object handle to pass to these methods (such as Mach4_IMyScriptObjectCode), you should continue to use the method you mentioned earlier - Mach4_IMach4GetScriptDispatch.
I am not able to test this, so I'm not entirely sure it will work for you. Take a look at it and let me know if it will work for you.
NickB
National Instruments