使用TestStand用户界面消息(UI消息)

更新 Jul 30, 2023

环境

软件

  • TestStand
  • LabVIEW
  • LabWindows/CVI

本教程概述了TestStand用户界面消息(UI消息),以及如何使用它们在TestStand执行与用户界面之间进行通信。本教程还提供了实现示例,用于发布消息和处理消息。

什么是UI消息?

TestStand使用UI消息对象将有关引擎状态和当前执行的信息传递给操作员界面或序列编辑器。例如,当步骤完成时,TestStand引擎会发布UI消息以通知操作员界面。然后,操作员界面可以响应此UI消息执行操作,例如刷新执行窗口控件以显示更新的步骤结果。

每个UI消息均包含以下与执行事件有关的数据:

  • 消息ID-指示要发送的消息的类型
  • 数值数据
  • 字符串数据
  • 对象参考数据


在本文的默认TestStand UI消息部分中,默认情况下提供了有关引擎发送的UI消息的更多详细信息。

在某些情况下,您可能需要将其他执行事件通知操作员界面,或将自定义数据传递给用户界面。为此,您可以使用TestStand API发送自定义UI消息。自定义UI消息的消息ID应大于UIMsg_UserMessageBase常量(默认为10000)。自定义UI消息的可能应用包括:

  1. 测试完成后,将有关测试的设备总数的信息传递到用户界面
  2. 从测试传递特定的数字结果,并将其附加到UI上的图形。


本教程讨论有关使用TestStand API发布UI消息的详细信息,以及如何在自定义操作员界面中处理UI消息。

为什么要使用UI消息?

UI消息是在TestStand用户界面和序列文件之间进行通信的最佳方式。使用序列文件属性或UI变量作为通信方式的替代方法(例如,从序列更新全局文件,然后在用户界面中检查其状态)会在序列文件和用户界面之间产生不必要的依赖关系。首选UI消息有两个原因:

  1. UI和序列文件的独立性-用户界面应始终与任何序列文件一起运行,反之亦然。通过使用UI消息,将序列文件与用户界面一起使用时,不需要某些属性存在于序列文件中。使用UI消息:

    • 用户界面可以执行未实现某些消息的序列(用户界面中的处理代码根本不会执行)

    • 可以在不是为处理定制消息而构建的UI中执行发布定制消息的序列(UI消息只会被用户界面忽略)

  2. 可维护性-UI消息避免了对序列文件属性或UI变量的依赖,这意味着序列文件和用户界面的开发人员无需维护

默认的TestStand UI消息

TestStand引擎在各个执行点自动将TestStand UI消息发布到操作员界面,以宣布发生了各种事件。用户界面使用这些消息来获取有关执行状态的信息。 TestStand引擎定义了几种消息类型(由消息ID指定),并在发生这些事件时自动发布UI消息。这些UI消息在TestStand帮助中定义。

本文档还提供了有关何时发布消息以及随消息一起传递哪些数据(如果有)的详细信息。也可以使用TestStand API手动发布这些消息,有关详细信息,请参见发布UI消息部分许多默认的UI消息会触发UI中的事件,但不会由TestStand引擎自动发送。

可以将用户界面配置为在发生特定的UI消息时执行代码。本文的接收和处理UI消息部分中详细讨论了此过程。

自定义UI消息

您可以使用大于或等于UIMsg_UserMessageBase常数(10,000)的消息ID来定义自己的自定义UI消息。这些消息的用法与默认消息的用法几乎相同,但是所有功能都必须由开发人员实现:

  • 在序列文件中发布消息-引擎不会自动发布自定义UI消息
  • 在用户界面中处理消息-默认情况下,TestStand UI管理器控件不执行任何代码来处理自定义消息。

下一部分将详细讨论这些过程。

发布UIMessages

要发布UI消息,请使用以下两种TestStand API方法之一:

  • Thread.PostUIMessageEx方法(典型)-从序列发布UI消息时使用此方法。使用当前线程和执行引用。
  • Engine.PostUIMessage方法-不发布序列中的消息时,请使用此方法。请注意,直接在引擎上调用此方法。与以前的方法不同,调用此方法时必须指定执行和线程引用

这些方法使您可以指定消息ID以及与该消息关联的数据。 PostUIMessageEx方法的参数如下所示:

PostUIMessageEx(eventCode,numericDataParam,stringDataParam,activeXDataParam,同步)

注意: final参数确定方法是否等待,直到用户界面(通常是应用程序管理器UI控件)确认UI消息为止。通常,此参数设置为true以避免可能的消息溢出,如果消息的发送速度超过了UI确认的速度,则可能发生消息溢出

与任何TestStand API调用一样,我们可以通过几种方式调用所需的方法:

  1. TestStand ActiveX步骤

  2. 外部代码模块-LabVIEW和LabWindows / CVI实现如下所示

    LabVIEW

    LabWindows / CVI

    //从序列上下文中获取对当前线程的引用
    tsErrChk(TS_SeqContextGetThread(
        seqContext,
        &errorInfo,
        &threadRef));
    
    //获取RunState.SequenceError.Msg属性值
    tsErrChk(TS_SeqContextGetRunTimeErrorMessageEx(
        seqContext,
        &errorInfo,
        &错误信息,
        空值,
        空值));
    
    //发布用户界面消息
    tsErrChk(TS_ThreadPostUIMessageEx(
        threadRef,
        &errorInfo,
        TS_UIMsg_UserMessageBase + 1
        0,
        错误信息,
        空值,
        真正));

     

  3. 语句步骤(TestStand 4.0及更高版本)

在此示例中,当前序列错误消息(如果存在)是通过UI消息的string参数发送的。请注意,将UIMsg_UserMessageBase参数用作事件代码的一部分-添加此值可确保此消息不会与TestStand默认UI消息冲突。

每当执行此步骤时,线程将发布自定义UIMessage(ID 10,001),该UIMessage传递Parameters.Result.Status的字符串值。在下一节中,我们将讨论如何配置用户界面以处理UI消息。

接收和处理UI消息

在序列编辑器或TestStand操作员界面中,应用程序管理器会自动确认UI消息,并处理默认的UI消息事件。但是,我们可以通过为两个Application Manager事件之一添加事件回调来配置操作员界面,以便在处理UI消息时运行用户定义的代码:

  • UImessage事件-每当应用程序管理器处理任何UI消息时,都会触发此事件。指定的事件回调将在任何默认的UI消息处理操作之前执行。可以在回调中将cancel输出事件参数设置为True,以覆盖默认事件操作
  • UserMessage事件-仅针对自定义UI消息(消息ID为10,000或更大的那些)触发此事件。

下一部分将详细探讨在LabVIEW和LabWindows / CVI中处理自定义UI消息的实现。

LabVIEW实施

在本节中,我们将修改简单的操作员界面以处理上例中的自定义UI消息。简单的操作员界面位于以下目录中:

<TestStand Public> \ UserInterfaces \ Simple \ LabVIEW \ TestExec.llb

在简单操作员界面中,TestStand事件在简单OI-配置事件回调子VI中注册。在该VI中,通过指定事件发生时要运行的回调VI来设置事件发生时应采取的措施。使用注册事件回调节点完成事件处理回调的配置。

为了实现在收到自定义UI消息时执行的代码,我们首先需要为UserMessage事件实现一个回调VI:

  1. 展开注册事件节点以包含其他事件。您应该看到三个附加输入
  2. 将应用程序管理器引用连接到第一个新输入。这指定我们正在处理应用程序管理器的事件
  3. 左键单击第一个输入以从应用程序管理器事件列表中选择用户消息事件
  4. 右键单击第二个输入(VI参考)的节点,然后从上下文菜单中选择创建回调VI。这将创建一个新的回调VI,该VI将在收到自定义UI消息时运行
  5. 将回调要使用的所有其他数据传递到用户参数节点中(在这种情况下,不需要其他数据)

进行了这些修改的简单OI-配置事件回调VI如下所示。

现在,我们需要在回调VI中实现在接收自定义UI消息时应执行的代码:

  1. 双击打开上述步骤4中创建的回调VI。注意,VI的参数是根据事件创建的
  2. 要访问UI消息数据,请取消捆绑Event Data参数以访问uiMsg对象,然后从该对象创建属性节点。该对象表示触发UserMessage事件的UI消息的数据
  3. 由于此事件回调将针对任何自定义UI消息运行,因此我们首先需要检查消息的ID。为此,将Event属性用作案例结构的选择器数据。为自定义事件的ID添加大小写(10001)
  4. 在案例结构中,创建要执行的代码。在这种情况下,我们将启动一个对话框以显示在UI消息中发送的错误信息。


完成的回调VI如下所示。



修改现已完成,并且UI现在将处理自定义UI消息。要处理其他自定义消息,只需在回调VI中为每个新的UI消息ID添加一个额外的大小写。

LabWindows / CVI

在本部分中,我们将修改简单操作员界面以处理上面示例中的自定义UI消息。简单的操作员界面位于以下目录中:

<TestStand Public> \ UserInterfaces \ Simple \ CVI \ TestExec.cws

在简单的操作员界面中,TestStand事件在SetupActiveXControls()函数中注册。在此函数中,我们通过调用事件注册函数来设置发生各种事件时应采取的措施。每种事件类型都有一个与之关联的单独功能;为了处理用户消息事件,我们使用以下函数:

errChk(TSUI__ApplicationMgrEventsRegOnUserMessage(gMainWindow.applicationMgr,ApplicationMgr_OnUserMessage,NULL,1,NULL));

此函数将回调函数配置为在收到用户消息时执行。它需要五个参数:

  1. 处理事件的对象-在这种情况下为应用程序管理器
  2. 事件发生时执行的回调函数-我们需要创建此处指定的函数(ApplicationMgr_OnUserMessage)
  3. 回调数据-回调函数中需要的任何其他数据-在这种情况下,不需要任何操作
  4. 启用回调-设置是否立即将回调链接到事件。在大多数情况下,应将其设置为1或true
  5. (返回参数)回调ID-使用此参数访问回调的唯一ID。本教程不需要此数据


此功能应与其他事件注册功能一起插入(第277-281行)。 CVI功能面板中提供了有关此功能以及其他TestStand API功能的文档。

现在,我们需要在回调函数中实现应在收到自定义UI消息时执行的代码。上面的注册功能的文档中提供了此功能的原型。


完成的回调函数如下所示。注释提供了有关每个呼叫的更多详细信息。

HRESULT CVICALLBACK ApplicationMgr_OnUserMessage(
CAObjHandle caServerObjHandle,
无效* caCallbackData,
TSUIObj_UIMessage uiMsg)
{
    char * stringData;
    枚举TSEnum_UIMessageCodes messageID;
    int错误= 0;

    //从UI消息对象获取消息ID
   tsErrChk(TS_UIMessageGetEvent(
                 uiMsg,
                 &errorInfo,
                 &messageID));

    开关(messageID)
    {
         案例10001:
         //仅为此消息类型运行(ID 10001)             

           //获取UI消息字符串数据
           tsErrChk(TS_UIMessageGetStringData(
                 uiMsg,
                 &errorInfo,
                 &stringData));  

            //向用户显示字符串数据
            MessagePopup(“ Sequence Error”,stringData);
        打破;
    }
    错误://处理错误(与其他回调相同)
       DisplayError(错误);
       返回错误<0? E_FAIL:S_OK;
}


修改现已完成,并且UI现在将处理自定义UI消息。要处理其他自定义消息,只需在回调函数中为每个新的UI消息ID添加一个额外的大小写。

修改后的TestExec.c文件可以在附件中找到。