NI TestStand

cancel
Showing results for 
Search instead for 
Did you mean: 

Problems using UIMessageCallback in Step DLL

Hi,
 
i have a problem calling a UIMessageCallback in my step DLL. There are several time intensive steps in my DLL, so i want to make these steps breakable. I need to get the UIMessages (BreakOnUserRequest,...) from the teststand engine during execution of steps. With the following lines i can register my function and the callback get called correct several times. After about 20 calls the teststand engine hangs and i can only kill the process by using the windows task manager.
 
I register my callback with following function:
 
int __declspec(dllexport) RegisterUIMsgCallback   (CAObjHandle ThisContext)
{
  TS_SeqContextGetEngine (ThisContext, NULL, &ObjHandle_Engine);
  TS_EngineGetUIMessagePollingEnabled (ObjHandle_Engine, NULL, FALSE);
  TS_EngineRegisterUIMessageCallback (ObjHandle_Engine, NULL, (long)UIMessageCallback);
  CA_DiscardObjHandle (ObjHandle_Engine);
}
 
The callback function itself:
void __declspec(dllexport) UIMessageCallback (struct IDispatch *UIMessageDisp)

  rc = CA_CreateObjHandleFromInterface (UIMessageDisp, &Interface_ID, 1, LOCALE_NEUTRAL, 0, 1, &ObjHandle_UIMsg);
  rc = TS_UIMessageGetEvent (ObjHandle_UIMsg, NULL, &Event);
  switch (Event)
  {
    case TS_UIMsg_BreakOnUserRequest:
    ...
    TS_UIMessageAcknowledge (ObjHandle_UIMsg, NULL);
    break;
  ...
  }
}
 
Thanks for help.
0 Kudos
Message 1 of 5
(3,345 Views)
The RegisterUIMessageCallback method was not designed to be called from a code module.  The help for the function states:

Note
  This method should only be used inside of the sequence editor or user interface.


Instead, if you want the ability to break while running a large code module, you can set the Thread.ExternallySuspended property to true.  This will allow TestStand to break, but your code will continue running.  If you would like to handle this break in your code in another way, you will need to call the Execution.GetStates method.

Allen P.
NI
0 Kudos
Message 2 of 5
(3,323 Views)
Also, if you want your code module to exit when the execution it is called from is terminated, you might want to inspect the source code for TS_RemoveCancelDialogIfExecutionStops and TS_CancelDialogIfExternalExecutionStops in tsutil.c. If your code module calls RunUserInterface, you might be able to use one of these functions directly.
0 Kudos
Message 3 of 5
(3,317 Views)
Thanks for your help! Smiley Happy
 
I will use the "Execution.GetState" method to get the information i need.
0 Kudos
Message 4 of 5
(3,304 Views)
Alfi,

Just want to let you know that you might need to Set Thread.ExternallySuspended to true while your step is running (and back to false right before it completes) or the state of the execution might not be able to change to paused.

-Doug
0 Kudos
Message 5 of 5
(3,283 Views)