07-08-2010 04:19 AM
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
Solved! Go to Solution.
07-09-2010 02:09 AM
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
07-09-2010 05:06 AM
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
07-09-2010 07:22 AM
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
07-09-2010 08:16 AM
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?
07-12-2010 05:08 AM
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!
07-12-2010 05:54 AM - edited 07-12-2010 05:56 AM
The sleep (1000) and not calling ProcessSystemEvents () are the reasons!
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;
}
07-19-2010 02:09 AM
Roberto,
your comments helps very much and my code is working
thanks......