LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

CALLBACK functions in cvi

Solved!
Go to solution

hi,

Need a simple clarification on working with callback function.

 

i have 3 different callback buttons function as start test, stop test, quit.

 

Whenever Start test button is pressed by EVENT_COMMIT, it calls some functions and executes the same. in the middle of this function execution i need to stop the test by pressing stop test button or i need to quit the interface. How can i do this?

 

i am facing problem like once i press the start button i am not getting controls to other button until the all functions available inside start button gets completed.

 

Thanks in advance

 

 

 

 

 

 

0 Kudos
Message 1 of 8
(7,987 Views)

The callback mechanism is rather simple in principle: when the OS detects a user operation on a control, it fires the corresponding callback, if any.

The main problem is that "when the OS detects...": the way you develop your code may prevent the system to onhour user actions, like when you structure one control callback code in a strict loop without letting the system look at what's happening outside. This may be your case: the user presses Stop or Quit button and the system does not catches that until the test loop has finished.

 

There are a couple of ways to prevent this.

 

1. Add ProcessSystemEvents while inside the loop; in Stop button callback simply set a global variable to "1"; test the global value in the loop so that you may be informed of the user will.

 

// Test presetting and so on...

globalStop = 0;

while (1) {

  // Running test instructions go here

  ProcessSystemEvents ();

  if (globalStop) break;   // User pressed 'Stop'

}

// Cleanup...

 

2. Use a toggle button as a stop button; do not set any callback for it; inside the loop use GetCtrlVal on that button and if value = 1 (i.e. button pressed) stop your test. This will avoid using a global variable.

 

3. Structure your test as a state machine to execute inside a timer (either a UI timer or an async timer). Inside the timer callback test the stop variable and operate consequently or test stop button state as per option 2 above

 

4. Move on a multithreaded environment and pass the stop informations from the UI thread to the test thread in some of the communications mechanisms available in CVI. This is an advanced programming structure that implies an advanced programmin skill to be designed in a proper way. There is a basic application note in bin folder in Cvi installation that may serve as a skeleton approach to multithreading



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
Message 2 of 8
(7,960 Views)

Hi,

 

the above conditions works if we have control to press stop button/stop toggle button any code is under execution. my scenario is different. i started a test by pressing start test button which runs for 15 mins,but in the middle of test execution say 8th min i want to stop the test.  i was not able to press any button or select anything. i can get control to press stop button only after 15 min.

 

i need to stop the execution at the middle by pressing stop button, but the problem is i cant press stop button in the middle of exection.

 

Please help me to solve this...

thanks

0 Kudos
Message 3 of 8
(7,948 Views)

Hi,

 

the problem is that all your code is within the callback routine. Accordingly, make the callback short, i.e. use it only to (re)set one variable. In the start callback, you set running=true; while in the stop callback you set running=false.

 

Wolfgang

 

0 Kudos
Message 4 of 8
(7,942 Views)

raj129* ha scritto:

Hi,

 

the above conditions works if we have control to press stop button/stop toggle button any code is under execution. my scenario is different. i started a test by pressing start test button which runs for 15 mins,but in the middle of test execution say 8th min i want to stop the test.  i was not able to press any button or select anything. i can get control to press stop button only after 15 min.

 

i need to stop the execution at the middle by pressing stop button, but the problem is i cant press stop button in the middle of exection.

 

Please help me to solve this...

thanks


 

raj,

are you calling repeatedly ProcessSystemEvents inside your test function? If you aren't doing it every user action is ignored!

 

Can you post a skeleton of your callback code?



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 5 of 8
(7,934 Views)

Hi Robert,

 

here are my code,

 

int CVICALLBACK Btn_Start_Test (int panel, int control, int event,
  void *callbackData, int eventData1, int eventData2)

switch (event)
 {
 case EVENT_COMMIT:
 {
   Tree_getselectedChilditems();
   MessagePopup("Info","TEST COMPLETED SUCCESSFULLY");
 }
 break;
 }
 return 0;
}


int CVICALLBACK btn_stop_test (int panel, int control, int event,
  void *callbackData, int eventData1, int eventData2)
{
 switch (event)
 {
  case EVENT_COMMIT:
   
  XL_KillWindowsProcess("EXCEL.EXE");//not exactly excel file,it may be any file which is running 
  
   break;
 }
 return 0;
}
double Tree_getselectedChilditems(void)//double testcaseno)
{
 int noOfItems;int val,i;  //int index;
 int noOfChild,index=1;
 char treelabel[500]={0};
 char charval;char TCno[100];
 int select;  char testno[100]={0};
   
  for(error = GetTreeItem (panelHandle, PANEL_TREE, VAL_CHILD, 0, VAL_FIRST, VAL_NEXT_PLUS_SELF, VAL_MARKED, &index);
          index >= 0&&error<=0;error = GetTreeItem(panelHandle, PANEL_TREE, VAL_ALL, 0,
                index, VAL_NEXT, VAL_MARKED, &index))
     {
         GetTreeCellAttribute(panelHandle, PANEL_TREE,
            index, 0, ATTR_LABEL_TEXT, treelabel);
  
   Scan(treelabel,"%s",TCno);
   strcpy(testcaseno,TCno);
  
       
   Sleep(1000);
  
   readTestcasesheet(ExcelWorkbookHandle, ExcelWorksheetHandle,testcaseno);
   Fmt(treelabel,"%s",""); 
  }
 
 
  return 1;
}


int XL_KillWindowsProcess(char *processName)
{
    HANDLE hndl = 0;
    DWORD dwsma = 0;
    DWORD dwExitCode = 0;
    PROCESSENTRY32  procEntry={0};
    HANDLE hHandle = 0;

    /* Get the list of running process */
    hndl = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
    dwsma = GetLastError();
    dwExitCode = 0;

    /* Get the size of the process entry table */
    procEntry.dwSize = sizeof( PROCESSENTRY32 );
    Process32First(hndl,&procEntry);
    do
    {
        /* Search whether the process is present */
        if(!stricmp(procEntry.szExeFile, processName))
        {
        /* Open that process to get the handle */
         hHandle = OpenProcess(PROCESS_ALL_ACCESS, 0, procEntry.th32ProcessID);
        /* Get the exit code to terminate the process */
         GetExitCodeProcess(hHandle, &dwExitCode);
         TerminateProcess(hHandle, dwExitCode);
        }
    }while(Process32Next(hndl, &procEntry));
    return dwExitCode;  

 

in the Btn_Start_Test() function i am calling Tree_getselectedChilditems() which runs for 15 mins, in the middle of test i need to stop by pressing sop button. i havent used ProcessSystemEvents() anywhere in the code.

 

thanks in advance!
 

0 Kudos
Message 6 of 8
(7,895 Views)
Solution
Accepted by topic author raj129*

The sleep (1000) and not calling ProcessSystemEvents () are the reasons!

  1. Sleep () completely blocks the program until the time has expired. It is advisable that you dont call it for long intervals!
  2. If you don't call ProcessSystemEvents () you cannot get stop button press

 

Try modifying the code this way:

 

 

int    requestToStop;    // Define this at module level



int CVICALLBACK Btn_Start_Test (int panel, int control, int event,
  void *callbackData, int eventData1, int eventData2)

switch (event)  {
 case EVENT_COMMIT:

   requestToStop = 0;    // Clear stop flag and start the test
   if (Tree_getselectedChilditems())

       MessagePopup ("Info", "Operator stopped the test!");

   else
       MessagePopup("Info","TEST COMPLETED SUCCESSFULLY");
   break;
 }
 return 0;
}



int CVICALLBACK btn_stop_test (int panel, int control, int event,
  void *callbackData, int eventData1, int eventData2)
{
 switch (event)  {
  case EVENT_COMMIT:
    requestToStop = 1;
//  XL_KillWindowsProcess("EXCEL.EXE");//not exactly excel file,it may be any file which is running 
    break;
 }
 return 0;
}



int Tree_getselectedChilditems (void)     //double testcaseno)
{
 int noOfItems;int val,i;  //int index;
 int noOfChild,index=1;
 char treelabel[500]={0};
 char charval;char TCno[100];
 int select;  char testno[100]={0};

 double tini;

  
  for(error = GetTreeItem (panelHandle, PANEL_TREE, VAL_CHILD, 0, VAL_FIRST, VAL_NEXT_PLUS_SELF, VAL_MARKED, &index);
          index >= 0&&error<=0;error = GetTreeItem(panelHandle, PANEL_TREE, VAL_ALL, 0,
                index, VAL_NEXT, VAL_MARKED, &index))
     {
         GetTreeCellAttribute(panelHandle, PANEL_TREE,
            index, 0, ATTR_LABEL_TEXT, treelabel);
  
   Scan(treelabel,"%s",TCno);
   strcpy(testcaseno,TCno);
  
       
//   Sleep(1000);     // Substitute this line with the following code
     tini = Timer ();
     while (Timer () - tini < 1.0) {

        ProcessSystemEvents ();

        if (RequestToStop) break;     // Operator stoo

     }
  
   readTestcasesheet(ExcelWorkbookHandle, ExcelWorksheetHandle,testcaseno);
   Fmt(treelabel,"%s",""); 


   if (RequestToStop) break;     // Operator stop
  }
 
 
  return requestToStop;
}

 



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
Message 7 of 8
(7,886 Views)

Roberto,

your comments helps very much and my code is working

thanks......

0 Kudos
Message 8 of 8
(7,807 Views)