11-13-2013 06:35 AM
I have noticed a bad behavior of SetMouseCursor function when used in multithreaded programs.
I've written a simple program to demonstrate it (the full project is in the attached zip).
Pressing the Start button an asynchronous timer is started and the "hourglass" cursor is shown.
case PANEL_CMD_START: SetMouseCursor (VAL_HOUR_GLASS_CURSOR); SetCtrlAttribute(panel,PANEL_CMD_START, ATTR_DIMMED, 1); SetCtrlAttribute(panel,PANEL_LED, ATTR_CTRL_VAL, 1); hTimer = NewAsyncTimer (3.0, -1, 1, OnTimer, 0); break;
If you leave the mouse stationary, when the timer fires after three seconds, the cursor will be still shown as hourglass until the pointer is moved: this is because the function SetMouseCursor (VAL_DEFAULT_CURSOR) is executed by the asynchronous timer thread.
If the checkbox "main thread" is checked, the function SetMouseCursor will be executed in the context of the main thread of the application and in this case the mouse cursor will be updated immediately.
GetCtrlVal(panel, PANEL_CHK_WA, &UseWorkaround); if (! UseWorkaround) { SetMouseCursor (VAL_DEFAULT_CURSOR); // call in Asynchronous Timer thread } else { PostDeferredCall (DeferredCB, 0); // call in main thread } .... static void CVICALLBACK DeferredCB (void *callbackData) { SetMouseCursor (VAL_DEFAULT_CURSOR); }
11-20-2013 04:02 AM
Hi,
Based on the documentation for function SetMouseCursor, i think this is a bug.
But, anyway, over the years i found that direct access to the GUI from multiple threads is not a good idea.
Although CVI is working good in this way most of the times. I do not recommend this way. (especially for long-running applications)
It takes a bit more coding, but leads to more stable program in long term.
I hope this helps, but I'm sorry for my English.