有人说LabWindows/CVI没有什么编译上的问题,我却一直都持反对态度!有一次,我在做一个数据采集时,突然发现它的定时器好像存在一些BUG。我百思不得其解,最后就不了了之了!每当我在用定时器调试程序的时候,我一直都是认为NI的编译器有问题,先把程序代码调换一个位置,如果还是有问题,才从自己的角度找错误!听说他们的编译器不是自己做的,而是买来的,当我问他们是从哪买的时候,却保持了缄默!目前,我也是在稀里糊涂地用!当然了,只要能每种编程的平台都有它们自己的一些错误,有错误并不可怕,可怕的是不知道怎么解决!所以在写代码的时候,我最讨厌用定时器,却还是不得不用!最讨厌响应一些高级的鼠标事件,却经常用到! 再有,就是它的事件响应机制!不知各位看官发现没有,LabWindows/CVI在响应鼠标事件的时候,其实是将消息传递给面板,然后再由面板传递给控件!我的老天,这简直就是天方夜谭!如果把握不好事件的响应,不了解的看官将某些事件写入了面板的回调函数,就会产生不可思议的效果!但,事情总是两面的!换一个角度来思考,我们可以利用它的消息传递机制,也可以写出一些有意思的代码来!NI的思路属于逆其道而行之,就像欧阳峰练九阴真经打通了仁笃二脉一样,结果是天下无敌,后果则是疯疯颠颠! 看过《东邪西毒》的观客可能会想起欧阳老前辈的一句话:“很多年之后,我有个绰号叫做西毒,任何人都可以变得狠毒,只要你尝试过甚么叫忌炉,我不会介意他人怎样看我,我只不过不想别人比我更开心。”其实,可以把这句话改一下:“很多年之后,我开始用CVI,任何人都可以用它,只要你尝试过甚么叫编程,我不会介意他人怎样实现其功能,我只不过是想让别人知道我的思路。” 好了,有一段代码让诸位看一下,它就是在用定时器时如果改变代码顺序而引起的一些问题! 界面为: 代码为: #include #include #include "aaa.h" static int panelHandle; int main (int argc, char *argv[]) { if (InitCVIRTE (0, argv, 0) == 0) return -1; /* out of memory */ if ((panelHandle = LoadPanel (0, "aaa.uir", PANEL)) < 0) return -1; DisplayPanel (panelHandle); RunUserInterface (); DiscardPanel (panelHandle); return 0; } int CVICALLBACK QuitCallback (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { switch (event) { case EVENT_COMMIT: QuitUserInterface (0); break; } return 0; } int CVICALLBACK timer (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { int textleft; int textwidth; int panelwidth; switch (event) { case EVENT_TIMER_TICK: GetPanelAttribute (panelHandle, ATTR_WIDTH, &panelwidth); GetCtrlAttribute (panelHandle, PANEL_TEXTMSG, ATTR_WIDTH, &textwidth); GetCtrlAttribute (panelHandle, PANEL_TEXTMSG, ATTR_LEFT, &textleft); SetCtrlAttribute (panelHandle, PANEL_TEXTMSG, ATTR_LEFT, textleft -= 10); //本句放在上面与下面效果不同 if (textleft <= -textwidth) { SetCtrlAttribute (panelHandle, PANEL_TEXTMSG, ATTR_LEFT, panelwidth); } // SetCtrlAttribute (panelHandle, PANEL_TEXTMSG, ATTR_LEFT, textleft -= 10); //本句放在上面与下面效果不同 break; } return 0; }
各位看官可以调整一下有注释两句的位置,看看会有什么结果,问题出在哪?我也不是很明白,请大家讨论! |