/* Copyright (c) 2024 PTC Inc. and/or Its Subsidiary Companies. All Rights Reserved. */ /*------------------------------------------------------------------*\ Pro/TOOLKIT includes \*------------------------------------------------------------------*/ #include "ProToolkit.h" #include "ProCore.h" #include "ProMenu.h" #include "ProMessage.h" #include "ProMenuBar.h" #include "ProMdl.h" #include "ProNotify.h" #include "ProUtil.h" #include "ProToolkitDll.h" #include "ProTKRunTime.h" /*------------------------------------------------------------------*\ Application includes \*------------------------------------------------------------------*/ #include "TestError.h" #include "UtilString.h" #include "UtilFiles.h" #include <stdlib.h> #include <time.h> /* STATICS */ static int event = 0; static int Action_done = 1; static ProFileName msgfil; static ProProcessHandle proe_handle; static int connect_mode = 0; void UserTerminateAction PRO_PROTO ((ProeTerminationStatus term_type)); int UserActionFunc PRO_PROTO (( ProAppData ptr, int opt)); int UserRestartProeTest (char*, char*, int, char*); int UserTerm (); int ProTestShowMenu (); ProError UserNotificationFunc(); #define USER_RETRIEVE_ACTION 1 #define USER_MESSAGE_ACTION 2 #define USER_EXIT_ACTION 3 #define MSGFIL msgfil /*====================================================================*\ FUNCTION : TestAccessDefault() PURPOSE : enable access to the -Main button \*====================================================================*/ static uiCmdAccessState TestAccessDefault(uiCmdAccessMode access_mode) { return (ACCESS_AVAILABLE); } static int PTAsyncMain (int argc, char*argv[]); #ifdef PT_ASYNC_MD /*============================================================================*\ Function : InvokePTAsyncByDll Purpose : Demonstrate the asynchronous mode of operations invoked from an external DLL \*============================================================================*/ __declspec (dllexport) int InvokePTAsyncMDByDll(int argc, char *argv[]) { return PTAsyncMain (argc, argv); } #else /*============================================================================*\ Function : main Purpose : Demonstrate the asynchronous mode of operations \*============================================================================*/ int main(int argc, char *argv[]) { return PTAsyncMain (argc, argv); } #endif /*============================================================================*\ Function : PTAsyncMain Purpose : Asynchronous demonstration procedure \*============================================================================*/ int PTAsyncMain (int argc, char* argv[]) { int i, action, bad_status = 0; char *part_to_retrieve=NULL; char proe_command[PRO_PATH_SIZE], text_path[PRO_PATH_SIZE]; char ua_msg[20]; int counter = 0, timeout = 10; char *hostname ; /* hostname not supported in Release 20. */ char *display=NULL, *user=NULL; ProBoolean random, asy_flag = PRO_B_FALSE, random_choice; ProError err, last_err = PRO_TK_NO_ERROR; time_t action_time = 0, report_time = 0, cur_time; wchar_t workspace[PRO_NAME_SIZE]; ProProcessHandle p_handle; ProStringToWstring(MSGFIL, "usermsg.txt"); ProTestErrlogOpen("pt_toolkit", "", ""); if (argc >= 2) if (strncmp (argv[1], "-rpc", 4) == 0) asy_flag = PRO_B_TRUE; if (asy_flag == PRO_B_TRUE) /* Start application from Pro/E session */ { err = ProAsynchronousMain (argc, argv); TEST_CALL_REPORT ("ProAsynchronousMain()", "main()", err, err != PRO_TK_NO_ERROR); if (err != PRO_TK_NO_ERROR) { ProTKFprintf (stderr, "Could not connect to Pro/E\n"); exit (0); } else ProTKPrintf ("Connection may have succeeded!\n"); } else /* Start application from command line */ { /* Check command line args and make the proe command */ for(i=0; i<argc; i++) { ProTKFprintf(stderr, " argv[%d]: %s\n", i, argv[i]); } if (argc < 3 || ((ProUtilStrcmp(argv[1], "-connect")==0) && (argc<3))) { ProTKFprintf(stderr, "\t%s <Pro/E command> <text_path> or\n", argv[0]); ProTKFprintf(stderr, "\t%s <Pro/E command> <text_path> <model/trailfile> or\n", argv[0]); ProTKFprintf(stderr, "\t%s <Pro/E command> <text_path> <runmode> <graphics mode>" " <trail mode> <trailfile>\n", argv[0]); ProTKFprintf(stderr, "\t%s -connect <text_path> [user [display ]]\n", argv[0]); exit(0); } /*------------------------------------------------------------------*\ Connect to a Pro/ENGINNER session. \*------------------------------------------------------------------*/ if (ProUtilStrcmp(argv[1], "-connect")==0) { connect_mode = 1; strcpy(text_path, argv[2]); hostname = "" ; if (argc>4) display = argv[4]; if (argc>3) user = argv[3]; ProTKPrintf("Attempt to connect ... user %s, display %s\n", user == NULL ? "any" : user, display == NULL ? "any" : display); ProTKPrintf("Text path %s\n", text_path); if (argc>5) { if (argc<7) { ProTKFprintf(stderr, "\t%s -connect <text_path> [user [display [workspace timeout]] ]\n", argv[0]); } ProStringToWstring (workspace, argv[5]); timeout = atoi (argv[6]); err = ProEngineerConnectWS ("", display, user, workspace, text_path, PRO_B_TRUE, timeout, &random_choice, &p_handle); TEST_CALL_REPORT("ProEngineerConnectWS()", "main()", err, err != PRO_TK_NO_ERROR); } else{ err = ProEngineerConnect(hostname, display, user, text_path, PRO_B_TRUE, 20, &random, &proe_handle); TEST_CALL_REPORT("ProEngineerConnect()", "main()", err, err != PRO_TK_NO_ERROR); } if (err != PRO_TK_NO_ERROR) { /* print error directly, so users don't have to look for it. */ ProTKPrintf("Attempt unsuccessfull (error %d), exiting\n", err); return (0); } } /*------------------------------------------------------------------*\ Spawn a Pro/ENGINNER session. \*------------------------------------------------------------------*/ else { strcpy(proe_command, argv[1]); /* Pro/E command */ if(argc == 4) { strcat(proe_command, " "); strcat(proe_command, argv[argc-1]); /* model or trail file */ } else if (argc > 4) { strcat(proe_command, " "); strcat(proe_command, argv[3]); /* run mode */ strcat(proe_command, " "); strcat(proe_command, argv[4]); /* graphics mode */ strcat(proe_command, " "); strcat(proe_command, argv[5]); /* trail mode */ strcat(proe_command, " "); strcat(proe_command, argv[6]); /* trail file */ } strcpy(text_path, argv[2]); /* Start up Pro/ENGINEER */ ProTKFprintf(stderr, "\n*****\tStarting Pro/Engineer\t*****\n"); ProTKFprintf(stderr, "\tProe command: \"%s\"\t\n\tPlease wait...\n", proe_command); err = ProEngineerStart(proe_command, text_path); TEST_CALL_REPORT("ProEngineerStart()", "main()", err, err != PRO_TK_NO_ERROR); } } /* Interrupt handling */ ProAsynchronousEventLoop(); ProEventProcess(); if (asy_flag == PRO_B_FALSE) { /*------------------------------------------------------------------*\ If the Pro/ENGINEER session was spawned by this application, restart Pro/ENGINEER after initial Pro/ENGINEER termination. (Restart is simple asynchronous model.) \*------------------------------------------------------------------*/ if (!connect_mode) { /* Now re-start Pro/E */ UserRestartProeTest(proe_command, text_path, argc, part_to_retrieve); } } ProTestErrlogClose(); return (0); } /*===========================================================================*\ Function : user_initialize() Purpost : demo another way to add user's menu item \*===========================================================================*/ int user_initialize(int argc, char *argv[]) { char *pre = "Pre", *post = "Post"; ProError err; uiCmdCmdId cmd_id; /*------------------------------------------------------------------*\ Parse the command line \*------------------------------------------------------------------*/ ProUtilCommandLineParse( argc, argv ); /*------------------------------------------------------------------*\ Initialize termination notification function. \*------------------------------------------------------------------*/ err = ProTermFuncSet((ProTerminationAction)UserTerminateAction); TEST_CALL_REPORT("ProTermFuncSet()", "user_initialize()", err, err != PRO_TK_NO_ERROR); if( err != PRO_TK_NO_ERROR) ProTKFprintf(stderr, "\nTermination function is NOT SET !!!\n"); /*---------------------------------------------------------------------*\ Add new button to the menu bar \*---------------------------------------------------------------------*/ err = ProCmdActionAdd("-Pt Async", (uiCmdCmdActFn)ProTestShowMenu, uiProe2ndImmediate, TestAccessDefault, PRO_B_TRUE, PRO_B_TRUE, &cmd_id); TEST_CALL_REPORT("ProCmdActionAdd", "user_initialize", err, err != PRO_TK_NO_ERROR); err = ProMenubarmenuPushbuttonAdd( "Utilities", "-Pt Async", "-Pt Async", "Async mode test commands", "Utilities.psh_util_aux", PRO_B_TRUE, cmd_id, MSGFIL); TEST_CALL_REPORT("ProMenubarmenuPushbuttonAdd", "user_initialize", err, err != PRO_TK_NO_ERROR); err = ProCmdCmdIdFind("exit", &cmd_id); TEST_CALL_REPORT("ProCmdCmdIdFind()", "user_initialize()", err, err != PRO_TK_NO_ERROR && err != PRO_TK_GENERAL_ERROR); err = ProCmdBracketFuncAdd(cmd_id, (uiCmdCmdBktFn)UserTerm, "UserTerm", NULL); err = ProMenuFileRegister("Async Test", "tkasync.mnu", NULL); TEST_CALL_REPORT("ProMenuFileRegister()", "user_initialize()", err, err !=PRO_TK_NO_ERROR); err = ProMenubuttonActionSet("Async Test", "Async Test", (ProMenubuttonAction)ProMenuDelete, NULL, 0); TEST_CALL_REPORT("ProMenubuttonActionSet()", "user_initialize()", err, err !=PRO_TK_NO_ERROR); err = ProMenubuttonActionSet("Async Test", "Done/Return", (ProMenubuttonAction)ProMenuDelete, NULL, 0); TEST_CALL_REPORT("ProMenubuttonActionSet()", "user_initialize()", err, err !=PRO_TK_NO_ERROR); err = ProMenubuttonActionSet("Async Test", "-Retrieve Obj", (ProMenubuttonAction)UserActionFunc, NULL, USER_RETRIEVE_ACTION); TEST_CALL_REPORT("ProMenubuttonActionSet()", "user_initialize()", err, err !=PRO_TK_NO_ERROR); err = ProMenubuttonLocationSet("Async Test", "-Exit", -1); TEST_CALL_REPORT("ProMenubuttonLocationSet()", "user_initialize()", err, err !=PRO_TK_NO_ERROR); err = ProMenubuttonActionSet("Async Test", "-Exit", (ProMenubuttonAction)UserActionFunc, NULL, USER_EXIT_ACTION); TEST_CALL_REPORT("ProMenubuttonActionSet()", "user_initialize()", err, err !=PRO_TK_NO_ERROR); err = ProNotificationSet(PRO_MDL_DISPLAY_PRE, (ProFunction)UserNotificationFunc); TEST_CALL_REPORT("ProNotificationSet()", "user_initialize()", err, err !=PRO_TK_NO_ERROR); return(0); } /*===========================================================================*\ Function : user_terminate() Purpost : end Pro/T application \*===========================================================================*/ void user_terminate() { ProError err; err = ProNotificationUnset(PRO_MDL_DISPLAY_PRE); TEST_CALL_REPORT("ProNotificationUnset()", "user_terminate()", err, err !=PRO_TK_NO_ERROR); TEST_CALL_REPORT("user_terminate()", "user_terminate()", PRO_TK_NO_ERROR, 0); ProTKPrintf("user terminate\n"); ProAsynchronousEventLoopInterrupt(); } /*===========================================================================*\ Function : UserTerm() Purpose : Calling Async Event Loop Interrupt telling Pro/DEVELOP application that Pro/E terminated \*===========================================================================*/ int UserTerm() { ProLine wcmd; ProError err; ProAsynchronousEventLoopInterrupt(); ProStringToWstring(wcmd, "yes"); err = ProMacroLoad(wcmd); TEST_CALL_REPORT("ProMacroLoad()", "UserTerm()", err, err !=PRO_TK_NO_ERROR); return(0); } /*===========================================================================*\ Function : UserRestartProeTest() Purpose : test restarting Pro/E and simple async call \*===========================================================================*/ int UserRestartProeTest( char *pro_command, char *text_path, int arg_num, char *part_to_retrieve) { char name[PRO_FAMILY_MDLNAME_SIZE]; ProMdlfileType type; char name_type[PRO_FAMILY_MDLNAME_SIZE + PRO_TYPE_SIZE + 2]; wchar_t w_name_type[PRO_FAMILY_MDLNAME_SIZE + PRO_TYPE_SIZE + 2]; ProMdl model; char *proe; int w_id, ret = 0; ProError err; if(arg_num>3) if (arg_num==4) { proe=strrchr(pro_command, ' '); *proe='\0'; } else { return (0); } /* Start up Pro/ENGINEER */ ProTKFprintf(stderr, "\n*****\tRe-Starting Pro/Engineer\t*****\n"); ProTKFprintf(stderr, "\tProe command: \"%s\"\t\n", pro_command); ProTKFprintf(stderr, "\t\tPlease wait...\n"); err = ProEngineerStart(pro_command, text_path); TEST_CALL_REPORT("ProEngineerStart()", "UserRestartProeTest()", err, err !=PRO_TK_NO_ERROR); if (part_to_retrieve!=NULL) { ProTKFprintf(stderr, "\nRetrieving part %s\n", part_to_retrieve); /* Query for an object */ ret = ProUtilConfirmNameType(part_to_retrieve, name, (ProType*)&type); } else { /* Query for an object */ err = ProMessageDisplay(MSGFIL, "USER %0s", "Enter object name.type: "); TEST_CALL_REPORT("ProMessageDisplay()", "UserRestartProeTest()", err, err !=PRO_TK_NO_ERROR); err = ProMessageStringRead(79, w_name_type); if (err == PRO_TK_NO_ERROR) { ProWstringToString(name_type, w_name_type); part_to_retrieve = name_type ; ret = ProUtilConfirmNameType(name_type, name, (ProType*)&type); } } /* Retrieve an object */ if (err == PRO_TK_NO_ERROR && ret > 0) { ProStringToWstring(w_name_type, name); err = ProMdlnameRetrieve (w_name_type, type, &model); TEST_CALL_REPORT("ProMdlnameRetrieve ()", "UserRestartProeTest()", err, err !=PRO_TK_NO_ERROR); /* Display the object */ err = ProObjectwindowMdlnameCreate(w_name_type, (ProType)type, &w_id); TEST_CALL_REPORT("ProObjectwindowMdlnameCreate()", "UserRestartProeTest()", err, err !=PRO_TK_NO_ERROR); err = ProMdlDisplay(model); TEST_CALL_REPORT("ProMdlDisplay()", "UserRestartProeTest()", err, err !=PRO_TK_NO_ERROR); ProTKFprintf(stderr, "After retrieving '%s' part\n", part_to_retrieve); ProTKFprintf(stderr, "Exit Pro/E\n"); } err = ProEngineerEnd(); TEST_CALL_REPORT("ProEngineerEnd()", "UserRestartProeTest()", err, err != PRO_TK_NO_ERROR); return (0); } /*---------------------------------------------------------------------*\ Function: UserTerminateAction() Purpose: called on Pro/E exit \*---------------------------------------------------------------------*/ void UserTerminateAction( ProeTerminationStatus term_type) { TEST_CALL_REPORT("ProTerminationAction()", "UserTerminateAction()", PRO_TK_NO_ERROR, 0); ProAsynchronousEventLoopInterrupt(); switch (term_type) { case PROTERM_EXIT: ProTKFprintf(stderr, "\nMenu item 'EXIT' was picked\n"); break; } } /*============================================================================*\ Function : ProTestShowMenu() Purpose : Perform a Pro/E operation \*============================================================================*/ int ProTestShowMenu() { int action, menu_id; ProError err; err = ProMenuCreate(PROMENUTYPE_MAIN, "Async Test", &menu_id); TEST_CALL_REPORT("ProMenuCreate()", "ProTestShowMenu()", err, err != PRO_TK_NO_ERROR); err = ProMenuProcess("Async Test", &action); TEST_CALL_REPORT("ProMenuProcess()", "ProTestShowMenu()", err, err != PRO_TK_NO_ERROR); return(0); } /*============================================================================*\ Function : UserActionFunc() Purpose : Perform a Pro/E operation \*============================================================================*/ int UserActionFunc( ProAppData ptr, int opt) { char name[PRO_FAMILY_MDLNAME_SIZE]; ProMdlfileType type; ProMdl model; ProCharLine msgbuf; char name_type[PRO_FAMILY_MDLNAME_SIZE + PRO_TYPE_SIZE + 2]; wchar_t w_name_type[PRO_FAMILY_MDLNAME_SIZE + PRO_TYPE_SIZE + 2]; ProError err; int strLength; int w_id, ret=0; switch (opt) { case USER_RETRIEVE_ACTION : Action_done = 1; /* Query for an object */ err = ProMessageDisplay(MSGFIL, "USER %0s", "Enter object name.type: "); TEST_CALL_REPORT("ProMessageDisplay()", "UserActionFunc()", err, err !=PRO_TK_NO_ERROR); err = ProMessageStringRead(79, w_name_type); if (err == PRO_TK_NO_ERROR) { ProWstringToString(name_type, w_name_type); ret = ProUtilConfirmNameType(name_type, name, (ProType*)&type); } /* Retrieve the object */ if (err == PRO_TK_NO_ERROR && ret > 0) { ProStringToWstring(w_name_type, name); err = ProMdlnameRetrieve(w_name_type, type, &model); TEST_CALL_REPORT("ProMdlnameRetrieve()", "UserActionFunc()", err, err !=PRO_TK_NO_ERROR); /* Display the object */ err = ProObjectwindowMdlnameCreate(w_name_type, (ProType)type, &w_id); TEST_CALL_REPORT("ProObjectwindowMdlnameCreate()", "UserActionFunc()", err, err !=PRO_TK_NO_ERROR); err = ProWindowActivate(w_id); TEST_CALL_REPORT("ProWindowActivate()", "UserActionFunc()", err, err !=PRO_TK_NO_ERROR); err = ProMdlDisplay(model); TEST_CALL_REPORT("ProMdlDisplay()", "UserActionFunc()", err, err !=PRO_TK_NO_ERROR); if (err == PRO_TK_NO_ERROR) { /* Confirm back to user */ err = ProWstringLengthGet (w_name_type, &strLength); TEST_CALL_REPORT("ProWstringLengthGet()", "UserActionFunc()", err, err !=PRO_TK_NO_ERROR); if (strLength < 80) { ProTKSprintf(msgbuf, "Retrieved: %s", name_type); err = ProMessageDisplay(MSGFIL, "USER %0s", msgbuf); TEST_CALL_REPORT("ProMessageDisplay()", "UserActionFunc()", err, err !=PRO_TK_NO_ERROR); ProTKFprintf(stderr, "\t%s\n", msgbuf); } else { return PRO_TK_LINE_TOO_LONG; } } } break; case USER_MESSAGE_ACTION : err = ProMessageDisplay(MSGFIL, "USER %0s", msgbuf); TEST_CALL_REPORT("ProMessageDisplay()", "UserActionFunc()", err, err !=PRO_TK_NO_ERROR); ProTKFprintf(stderr, "\t%s\n", msgbuf); break; case USER_EXIT_ACTION : if (!connect_mode) { err = ProEngineerEnd(); TEST_CALL_REPORT("ProEngineerEnd()", "UserActionFunc()", err, err != PRO_TK_NO_ERROR); ProTKFprintf(stderr, "\n\tHello World! After ProEngineerEnd()\n"); } else { err = ProEngineerDisconnect(&proe_handle, 20); TEST_CALL_REPORT("ProEngineerDisconnect()", "UserActionFunc()", err, err != PRO_TK_NO_ERROR); ProTKFprintf(stderr, "\n\tHello World! After ProDisconnectProe()\n"); } ProAsynchronousEventLoopInterrupt(); break; default : break; } return(0); } /*============================================================================*\ Function : UserNotificationFunc() Purpose : Test Notification function in async mode \*============================================================================*/ ProError UserNotificationFunc() { ProTKFprintf(stderr, "Notification function\n"); TEST_CALL_REPORT("ProMdlDisplayPre()", "UserNotificationFunc()", PRO_TK_NO_ERROR, 0); return (PRO_TK_NO_ERROR); }