使用TestStand User Interface Messages(UI Messages)

更新 Apr 14, 2025

環境

軟體

  • TestStand
  • LabVIEW
  • LabWindows/CVI

此教學概述了TestStand User Interface Messages(UI Messages),以及如何使用它們在TestStand executions與User Interface之間進行通信。本教學還提供了實踐範例,用於發布messages和處理messages。

什麼是UI Messages?

TestStand使用UI Messages物件將有關engine狀態和當前執行的信息傳遞給Operator Interface 或是 Sequence Editor。例如,當step完成時,TestStand engine會發布UI message以通知Operator Interface。然後,Operator Interface就可以執行操作以回應此UI message,例如刷新execution window control以顯示更新的step結果。

每個UI message均包含以下與執行事件有關的數據:

  • message ID-指示要發送的message的類型
  • 數值數據
  • 字串數據
  • Object Reference數據


在本文的“Default TestStand UI Messages”部分中,提供了更多有關預設情況下Engine發送UI message的詳細信息。

在某些情況下,您可能需要將其他execution events通知Operator Interface,或將custom數據傳遞給User interface。為此,您可以使用TestStand API發送custom UI message。custom UI message的message ID應大於UIMsg_UserMessageBase常數值(預設為10000)。custom UI message的可能應用包括:

  1. 測試完成後,將有關待測物總數的信息傳遞到User interface
  2. 從測試端傳遞特定的數值結果,並將其添加到UI上的圖件。


本教學討論有關使用TestStand API發布UI messages的詳細信息,以及如何在customOperator Interface中處理UI messages。

 

為什麼要使用UI Messages?

UI messages是在TestStand User interface和sequence files之間進行通信的最佳方式。若你改成使用sequence files屬性或UI變量作為通信方式的替代方法(例如,從sequence更新 file global,然後在user interface中檢查其狀態)時會在sequence files和User interface之間產生不必要的依賴關係。而我們會首選UI messages有兩個原因:

  1. UI和sequence files的獨立性-User interface應始終與任何sequence files一起運行,反之亦然。通過使用UI messages,sequence files與User interface一起使用時,將不需要某些屬性存在於sequence files中。使用UI messages:

    • User interface可以對未實行某些messages的sequence做執行(User interface中的handling code根本不會執行)

    • 可以在不是用來處理custom messages而構建的UI中執行post custom messages的sequences(UI messages只會被User interface忽略)

  2. 可維護性-UI messages避免了對sequence files屬性或UI變量的依賴,這意味著sequence files和User interface的開發人員無需維護

 

預設的TestStand UI message

TestStand engine在各個執行點自動將TestStand UI messages發佈到Operator Interface,以宣布發生了各種事件。User interface使用這些messages來獲取有關執行狀態的信息。 TestStand engine定義了幾種message類型(由message ID指定),並在發生這些事件時自動發布UI messages。這些UI messages在TestStand help中定義。

本文件還提供了有關何時發布message以及哪些數據(如果有)隨message一起傳遞的詳細信息。也可以使用TestStand API手動發布這些message,有關詳細信息,請參見發布UI Messages部分許多預設的UI messages會觸發UI中的事件,但不會由TestStand engine自動發送。

可以將User interface配置為在發生特定的UI message時執行代碼。本文的“Receiving and Handling UI Messages部分中詳細討論了此過程。

custom UI Messages

您可以使用大於或等於UIMsg_UserMessageBase常數(10,000)的message ID來定義自己的custom UI message。這些message的用法與預設message的用法幾乎相同,但是所有功能都必須由開發人員實現:

  • 在sequence files中發布message-engine不會自動發布custom UI message
  • 在User interface中處理message-預設情況下,TestStand UI manager controls不執行任何代碼來處理custom message。

下一部分將詳細討論這些過程。

發布UI Messages

要發布UI message,請使用以下兩種TestStand API方法之一:

  • Thread.PostUIMessageEx方法(典型)-從sequence發布UI message時使用此方法。使用當前thread和執行reference。
  • Engine.PostUIMessage方法-不發布sequence中的message時,請使用此方法。請注意,請直接在engine上調用此方法。與上面的方法不同,調用此方法時必須指定執行和thread reference

這些方法使您可以指定message ID以及與該message關聯的數據。 PostUIMessageEx方法的參數如下所示:

PostUIMessageEx (eventCode, numericDataParam, stringDataParam, activeXDataParam, synchronous)

注意: final參數決定方法是否等待,直到user interface(通常是 application manager UI control)確認到UI message為止。通常,此參數設置為true以避免可能的message overflows,如果message的發送速度超過了UI確認的速度,則可能發生message overflows

與任何TestStand API調用一樣,我們可以通過幾種方式調用所需的方法:

  1. TestStand ActiveX step

  2. 外部code module-LabVIEW和LabWindows / CVI實現方式如下所示

    LabVIEW

    LabWindows / CVI

    //get a reference to the current thread from sequence context
    tsErrChk(TS_SeqContextGetThread(
        seqContext,
        &errorInfo,
        &threadRef));
    
    //get the RunState.SequenceError.Msg property value
    tsErrChk(TS_SeqContextGetRunTimeErrorMessageEx(
        seqContext,
        &errorInfo,
        &errorMessage,
        NULL,
        NULL));
    
    //post the UI message
    tsErrChk(TS_ThreadPostUIMessageEx(
        threadRef,
        &errorInfo,
        TS_UIMsg_UserMessageBase + 1,
        0,
        errorMessage,
        NULL,
        TRUE));

     

  3. Statement step(TestStand 4.0及更高版本) 

在此範例中,當前sequence error message(如果存在)是通過UI message的string參數發送的。請注意,將UIMsg_UserMessageBase參數用作事件代碼的一部分-添加此值可確保此message不會與TestStand預設UI message衝突。

每當執行此步驟時,thread將發布customUI Message(ID 10,001),該UI Message傳遞Parameters.Result.Status的字串值。在下一節中,我們將討論如何配置 user interface以處理UI message。

接收和處理UI message

在sequence editor或TestStand Operator Interface 中,Application Manager會自動確認UI message,並處理預設的UI message事件。但是,我們可以通過為兩個Application Manager事件之一添加 event callback 來配置operator interface,以便在處理UI message時運行用戶定義的代碼:

  • UImessage事件-每當Application manager處理任何UI message時,都會觸發此事件。指定的event callback將在任何預設的UI message處理操作之前執行。可以在callback中將cancel輸出事件參數設置為True,以覆蓋預設事件操作
  • UserMessage事件-僅針對customUImessage(messageID為10,000或更大的那些)觸發此事件。

下一部分將詳細探討在LabVIEW和LabWindows / CVI中處理custom UI message的實踐。

LabVIEW實踐

在本節中,我們將修改simple Operator Interface以處理上例中的customUI message。simple Operator Interface位於以下目錄中:

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

在simple Operator Interface中,TestStand事件在Simple OI - Configure Event Callbacks 子VI中註冊。在該VI中,通過指定事件發生時要運行的callback VI來設置事件發生時應採取的措施。使用Register Event Callback Node完成事件處理callbacks的配置。

為了實現在收到customUI message時執行的代碼,我們首先需要為UserMessage事件實現一個callback VI:

  1. 展開Register event node以包含其他事件。您應該看到三個附加輸入
  2. 將 Application manager reference連接到第一個新輸入。這指明我們正在處理Application Manager的事件
  3. 左鍵點擊第一個輸入以從Application Manager事件列表中選擇User Message事件
  4. 右鍵點擊第二個輸入(VI參考)的節點,然後從context選單中選擇Create Callback VI。這將創建一個新的callback VI,該VI將在收到customUI message時運行
  5. 將callback要使用的所有其他數據傳遞到User Parameter節點中(在這種情況下,不需要其他數據)

進行了這些修改的Simple OI - Configure Event Callbacks VI如下所示。

現在,我們需要在callback VI中實現在接收customUI message時應執行的代碼:

  1. 雙擊打開上述步驟4中創建的callback VI。注意,VI的參數是根據事件創建的
  2. 要訪問UI message數據,請unbundle the Event Data參數以存取uiMsg對象,然後從該對象創建屬性節點。該對象表示觸發UserMessage事件的UI message的數據
  3. 由於此事件callback將針對任何customUI message運行,因此我們首先需要檢查message的ID。為此,將Event屬性用作案例結構的選擇器數據。為custom事件的ID添加大小寫(10001)
  4. 在案例結構中,創建要執行的代碼。在這種情況下,我們將啟動一個對話框以顯示在UI message中發送的錯誤信息。


完成的callbackVI如下所示。



現在修改已完成,並且UI現在將處理custom UI message。要處理其他custom message,只需在callback VI中為每個新的UI messageID添加一個額外的case。

LabWindows / CVI

在本部分中,我們將修改Simple Operator Interface以處理上面範例中的customUI message。Simple Operator Interface位於以下目錄中:

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

在Simple Operator Interface中,TestStand事件在SetupActiveXControls()函數中註冊。在此函數中,我們通過調用event registration functions 來設置發生各種事件時應採取的措施。每種事件類型都有一個與之關聯的單獨功能;為了處理用戶message事件,我們使用以下函數:

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

此函數將callback函數配置為在收到用戶message時執行。它需要五個參數:

  1. 處理事件的對象-在這種情況下為application manager
  2. 事件發生時執行的callback函數-我們需要創建此處指定的函數(ApplicationMgr_OnUserMessage)
  3. callback數據-callback函數中需要的任何其他數據-在這種情況下,不需要任何操作
  4. 啟用callback-設置是否立即將callback鏈接到事件。在大多數情況下,應將其設置為1或true
  5. (返回參數)callbackID-使用此參數訪問callback的唯一ID。本教學不需要此數據


此功能應與其他事件註冊功能一起插入(第277-281行)。 CVI功能面板中提供了有關此功能以及其他TestStand API功能的文件。

現在,我們需要在callback函數中實現應在收到customUI message時執行的代碼。上面的註冊功能的文件中提供了此功能的原型。


完成的callback函數如下所示。注釋提供了有關每個呼叫的更多詳細信息。

HRESULT CVICALLBACK ApplicationMgr_OnUserMessage (
CAObjHandle caServerObjHandle,
void *caCallbackData,
TSUIObj_UIMessage  uiMsg)
{
    char *stringData;
    enum TSEnum_UIMessageCodes messageID;
    int error = 0;

    //obtain message ID from UI message object
   tsErrChk(TS_UIMessageGetEvent(
                 uiMsg,
                 &errorInfo,
                 &messageID));

    switch (messageID)
    {
         case 10001:
         //run only for this message type (ID 10001)             

           //get the UI message string data
           tsErrChk(TS_UIMessageGetStringData(
                 uiMsg,
                 &errorInfo,
                 &stringData));  

            //display the string data to the user
            MessagePopup("Sequence Error",stringData);
        break;
    }
    Error: //handle errors (same as other callbacks)
       DisplayError(error);
       return error < 0 ? E_FAIL : S_OK;
}


現在修改已完成,並且UI現在將處理custom UI message。要處理其他custom message,只需在callback函數中為每個新的UI message ID添加一個額外的case。

修改後的TestExec.c檔案可以在附件中找到。