官方例程如下:
#include "GUI.h" #include "WM.H" #include "FRAMEWIN.H" static void _cbBkWindow(WM_MESSAGE *pMsg) { switch(pMsg->MsgId) { case WM_PAINT: GUI_ClearRect(0, 50, 319, 239); default: WM_DefaultProc(pMsg); } } static void _cbWindow(WM_MESSAGE *pMsg) { GUI_RECT Rect; switch(pMsg->MsgId) { case WM_PAINT: WM_GetInsideRect(&Rect); GUI_SetBkColor(GUI_RED); GUI_SetColor(GUI_YELLOW); GUI_ClearRectEx(&Rect); GUI_DrawRectEx(&Rect); GUI_SetColor(GUI_BLACK); GUI_SetFont(&GUI_Font8x16); GUI_DispStringAt("Foreground window", 75, 40); break; default: WM_DefaultProc(pMsg); } } static void _MoveWindow(const char *pText) { WM_HWIN hWin; int i; hWin = WM_CreateWindow(10, 50, 150, 100, WM_CF_SHOW, _cbWindow, 0); GUI_Delay(100); for (i = 0; i < 40; i++) { WM_MoveWindow(hWin, 2, 2); GUI_Delay(100); WM_Invalidate(WM_HBKWIN); } if (pText) { GUI_DispStringAt(pText, 5, 50); GUI_Delay(100); } WM_DeleteWindow(hWin); WM_Invalidate(WM_HBKWIN); GUI_Exec(); } static void _DemoRedraw(void) { WM_CALLBACK *_cbOldBk; GUI_SetBkColor(GUI_BLACK); GUI_Clear(); GUI_SetColor(GUI_WHITE); GUI_SetFont(&GUI_Font24_ASCII); GUI_DispStringHCenterAt("WM_Redraw - Sample", 160, 5); GUI_SetFont(&GUI_Font8x16); while(1) { _MoveWindow("Background has not been redrawn"); GUI_ClearRect(0, 50, 319, 239); GUI_Delay(1000); _cbOldBk = WM_SetCallback(WM_HBKWIN, _cbBkWindow); _MoveWindow("Background has been redraw"); WM_SetCallback(WM_HBKWIN, _cbOldBk); } } /* * * MainTask * */ void MainTask(void) { GUI_Init(); //WM_SetDesktopColor(GUI_BLACK); //My Add //FRAMEWIN_Create("FrameWin", (WM_CALLBACK *)0, WM_CF_SHOW, 0, 50, 319, 189); //My Add _DemoRedraw(); }
图2
在UCGUI手册中有如下一段话:
因为背景窗口没有默认背景颜色,也没有设置回调函数,不会自动重绘,所以第71行调用_MoveWindow()函数移动矩形窗口时的移动痕迹没有清除,如图2。
第76行代码设置了自定义的回调函数后,第二个样例的移动没有痕迹,如图2。从这里可以看出矩形窗口每移动一次,背景窗口的回调函数就收到一次WM_PAINT消息,背景窗口就重绘一次;
实验时发现第73、74行和第57、58行代码作用有重复了,注释掉第73、74行后,第一个样例移动完后也会删除,虽然是在_MoveWindow()返回后设置的背景窗口的回调函数。官方例程的意思是对于删除矩形窗口后背景窗口的重绘,第一次移动是通过73、74行直接清除一定矩形区域实现的,第二次移动是通过回调函数实现的。
_MoveWindow()函数尾部的WM_Invalidate(WM_HBKWIN)和GUI_Exec()函数的在第一个样例中的主要作用是为了矩形窗口删除后进行背景窗口的重绘,通过76行设置的回调函数(将73、74行注释后)实现的;在第二个样例中又有个额外的作用就是人为触发一次回调函数,因为移动完后又将背景窗口的回调函数设置回了默认值(80行),这里如果不人为触发一次自定义的回调函数就会调用默认回调函数,这样就无法调用自定义回调函数重绘背景窗口,可以看出窗口管理器发出WM_PAINT消息后如果接着设置新的回调函数,则会调用新的回调函数,就如上述注释掉第73、74行后的行为一样。
结果对比:
1)注释掉73、74行
第一次移动有痕迹,移动完后背景窗口“WM_Redraw – Sample”字符串以下区域重绘;第二次移动没有痕迹,移动完后背景窗口“WM_Redraw – Sample”字符串以下区域重绘。
2)注释掉57、58行
第一次移动有痕迹,移动完后背景窗口“WM_Redraw – Sample”字符串以下区域重绘;第二次移动没有痕迹,移动完后背景窗口“WM_Redraw – Sample”字符串以下区域不重绘。
3)注释掉57、58、79行
第一次移动有痕迹,移动完后背景窗口“WM_Redraw – Sample”字符串以下区域重绘;第二次移动没有痕迹,移动完后背景窗口“WM_Redraw – Sample”字符串以下区域重绘。
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/229732.html原文链接:https://javaforall.net
