ucgui窗口分析.doc_第1页
ucgui窗口分析.doc_第2页
ucgui窗口分析.doc_第3页
ucgui窗口分析.doc_第4页
ucgui窗口分析.doc_第5页
已阅读5页,还剩5页未读, 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

一、相关结构体和变量窗口管理结构体/* 窗口管理结构体 共30个字节 */struct WM_Obj GUI_RECT Rect; /窗口尺寸(x0,y0,x1,y1) 8个字节 GUI_RECT InvalidRect; /无效区域(x0,y0,x1,y1) 8个字节 WM_CALLBACK* cb; /回调函数 4个字节 WM_HWIN hNextLin; /指向链表中的下一个窗口 2个字节 WM_HWIN hParent; /当前窗口的父窗口 2个字节 WM_HWIN hFirstChild; /当前窗口的第一个子窗口 2个字节 WM_HWIN hNext; /下一个兄弟窗口 2个字节 U16 Status; /标志位 2个字节;窗口创建的标志#define WM_CF_HASTRANS (10) /* Has transparency. Needs to be defined for windows which do not fill the entire section of their (client) rectangle. */#define WM_CF_HIDE (01) /* Hide window after creation (default !) */#define WM_CF_SHOW (11) /* Show window after creation */#define WM_CF_MEMDEV (12) /* Use memory device for redraws */#define WM_CF_STAYONTOP (13) /* Stay on top */#define WM_CF_DISABLED (14) /* Disabled: Does not receive PID (mouse & touch) input */* Create only flags . Not available as status flags */#define WM_CF_ACTIVATE (15) /* If automatic activation upon creation of window is desired */#define WM_CF_FGND (06) /* Put window in foreground after creation (default !) */#define WM_CF_BGND (16) /* Put window in background after creation */* Anchor flags */#define WM_CF_ANCHOR_RIGHT (17) /* Right anchor . If parent is resized, distance to right will remain const (left is default) */#define WM_CF_ANCHOR_BOTTOM (18) /* Bottom anchor . If parent is resized, distance to bottom will remain const (top is default) */#define WM_CF_ANCHOR_LEFT (19) /* Left anchor . If parent is resized, distance to left will remain const (left is default) */#define WM_CF_ANCHOR_TOP (110) /* Top anchor . If parent is resized, distance to top will remain const (top is default) */#define WM_CF_CONST_OUTLINE (111) /* Constant outline. This is relevant for transparent windows only. If a window is transparent and does not have a constant outline, its background is invalided instead of the window itself. This causes add. computation time when redrawing. */#define WM_CF_LATE_CLIP (112)#define WM_CF_MEMDEV_ON_REDRAW (113)#define WM_CF_RESERVED3 (114)#define WM_CF_RESERVED4 (1Rect.x0; y0 += pParent-Rect.y0; if (width=0) width = pParent-Rect.x1 - pParent-Rect.x0+1; if (height=0) height = pParent-Rect.y1 - pParent-Rect.y0+1; if (hWin = (WM_HWIN) GUI_ALLOC_AllocZero(NumExtraBytes + sizeof(WM_Obj) = 0) GUI_DEBUG_ERROROUT(WM_CreateWindow: No memory to create window); /如果没有空间来创建需要的动态内存块 else /申请动态内存成功 WM_NumWindows+; /保存系统总窗口数目的计数器加1 pWin = WM_H2P(hWin); /计算获取动态内存数据区的地址 /* 向动态内存区写入当前窗口的参数 */ pWin-Rect.x0 = x0; pWin-Rect.y0 = y0; pWin-Rect.x1 = x0 + width - 1; pWin-Rect.y1 = y0 + height - 1; pWin-cb = cb; /保存回调函数 /* Copy the flags which can simply be accepted */ pWin-Status |= (Style & (WM_CF_SHOW | WM_SF_MEMDEV | WM_CF_MEMDEV_ON_REDRAW | WM_SF_STAYONTOP | WM_CF_DISABLED | WM_SF_CONST_OUTLINE | WM_SF_HASTRANS | WM_CF_ANCHOR_RIGHT | WM_CF_ANCHOR_BOTTOM | WM_CF_ANCHOR_LEFT | WM_CF_ANCHOR_TOP | WM_CF_LATE_CLIP); /* Add to linked lists */ _AddToLinList(hWin); /将窗口插入到窗口管理链表当中 WM_InsertWindowIntoList(hWin, hParent); /插入到父窗口管理链表当中 /* 根据用户定义的窗口风格进行一些列的操作 */ /* Activate window if WM_CF_ACTIVATE is specified */ if (Style & WM_CF_ACTIVATE) /如果带激活标志的话,就激活窗口 WM_SelectWindow(hWin); /* This is not needed if callbacks are being used, but it does not cost a lot and makes life easier . */ /* Handle the Style flags, one at a time */ #if WM_SUPPORT_TRANSPARENCY if (Style & WM_SF_HASTRANS) /透明窗口 WM_TransWindowCnt+; /* Increment counter for transparency windows */ #endif if (Style & WM_CF_BGND) WM_BringToBottom(hWin); if (Style & WM_CF_SHOW) /显示窗口 pWin-Status |= WM_SF_ISVIS; /设置可视状态位 WM_InvalidateWindow(hWin); /如果有显示命令,还会设置窗口为无效,等待重绘 WM_SendMsgNoData(hWin, WM_CREATE); /发一个创建消息,这样创建的时候就可以在回调函数中进行处理 WM_UNLOCK(); return hWin;首先根据其父窗口的坐标计算出当前窗口的坐标、高度和宽度。从动态内存区中开辟出一块窗口管理区域,然后向其中填入当前窗口的参数值。比较重要的是接下来的两部,将当前窗口插入到窗口管理链表当中以及将窗口插入到其父窗口的同胞链表当中。最后,如果创建的时候以显示模式WM_CF_SHOW创建,那么要为此窗口加入了可视标志WM_SF_ISVIS,而且还要设置窗口为无效。这样在执行GUI_Exec()或者WM_Exec()的时候就会对该窗口进行重绘。2、_AddToLinList()static void _AddToLinList(WM_HWIN hNew) WM_Obj* pFirst; WM_Obj* pNew; if (WM_FirstWin) /如果不是桌面窗口(事实上桌面窗口肯定存在了) pFirst = WM_H2P(WM_FirstWin); /首先获取桌面窗口的动态内存地址 pNew = WM_H2P(hNew); /获取要插入窗口的动态内存地址 /* * 桌面窗口-最近创建的窗口1-更早创建的窗口2-0 = * 桌面窗口-当前要插入的窗口-最近创建的窗口1-更早创建的窗口2-0 */ pNew-hNextLin = pFirst-hNextLin; / pFirst-hNextLin = hNew; else WM_FirstWin = hNew; /创建桌面窗口时,将桌面窗口的句柄赋给此变量 将新建窗口添加到窗口管理链表中。这个窗口管理链表是建立在uCGUI的动态内存中,利用WM_obj类型中的成员hNextLin连接成一个单向链表。链表的构建过程如下:插入之前:桌面窗口-最近创建的窗口1-更早创建的窗口2-0=插入之后:桌面窗口-当前要插入的窗口-最近创建的窗口1-更早创建的窗口2-03、WM_InsertWindowIntoList()/* WM_InsertWindowIntoList* Routine describtion* This routine inserts the window in the list of child windows for* a particular parent window.* The window is placed on top of all siblings with the same level.*/void WM_InsertWindowIntoList(WM_HWIN hWin, WM_HWIN hParent) int OnTop; WM_HWIN hi; WM_Obj * pWin; WM_Obj * pParent; WM_Obj * pi; if (hParent) /桌面窗口是不存在父窗口的 pWin = WM_H2P(hWin); /获取当前窗口的动态内存地址 pWin-hNext = 0; /它的下一个兄弟窗口为0 pWin-hParent = hParent; /记录它的父窗口 pParent = WM_H2P(hParent); /获得它父窗口的动态内存地址 OnTop = pWin-Status & WM_CF_STAYONTOP; /可以用来判断此窗口是否有在最顶层的标志 hi = pParent-hFirstChild; /父窗口的第一个子窗口 /* Put it at beginning of the list if there is no child */ if (hi = 0) /* No child yet . Makes things easy ! */ /* * 父窗口-0 = * 父窗口-当前窗口-0 */ pParent-hFirstChild = hWin; /没有子窗口,就把它作为父窗口的第一个子窗口 return; /* Early out . We are done */ /* Put it at beginning of the list if first child is a TOP window and new one is not */ pi = WM_H2P(hi); /获取父窗口第一个子窗口的动态内存地址 if (!OnTop) /如果此窗口没有在最顶层的标志 if (pi-Status & WM_SF_STAYONTOP) /判断长兄是否有在最顶层的标志 /* * 父窗口-长兄-0 = * 父窗口-当前窗口-长兄-0 */ pWin-hNext = hi; /当前窗口的下一个窗口指向其长兄 pParent-hFirstChild = hWin; /父窗口的第一个子窗口为当前窗口 return; /* Early out . We are done */ /* 把它放在链表的最顶端或者在第一个“最顶层”窗口之前 */ do WM_Obj* pNext; WM_HWIN hNext; if (hNext = pi-hNext) = 0) /* End of sibling list ? */ pi-hNext = hWin; /* 放在链表的最顶端 */ break; pNext = WM_H2P(hNext); if (!OnTop) /如果当前窗口没有“在最顶层”的标志 if (pNext-Status & WM_SF_STAYONTOP) pi-hNext = hWin; pWin-hNext = hNext; break; pi = pNext; while (1); #if WM_SUPPORT_NOTIFY_VIS_CHANGED WM_NotifyVisChanged(hWin, &pWin-Rect); #endif 将新建窗口添加到父窗口的同胞窗口管理链表中。这个窗口管理链表是建立在uCGUI的动态内存中,利用WM_obj类型中的成员hFirstChild和hNext连接成一个单向链表。插入的原则是:1、如果父窗口没有孩子,直接将其作为父窗口的孩子即可。插入之前:父窗口-0=插入之后: 父窗口-当前窗口-02、如果父窗口有孩子,第一个孩子有“在顶层”的标志,而当前创建的窗口没有这个标志,则将其作为其父窗口的第一个孩子。插入之前:父窗口-长兄-0 =插入之后:父窗口-当前窗口-长兄-03、如果父窗口有孩子,第一个孩子没有“在顶层”的标志,而当前创建的窗口也没有这个标志,则将其放在同胞链表中有“在顶层”标志窗口的前边,也就是所有没有“在顶层”标志窗口的后边。插入之前:父窗口-长兄(没标志)-次兄(没标志)-三兄(有标志)-0 =插入之后:父窗口-长兄(没标志)-次兄(没标志)-当前窗口-三兄(有标志)-0 4、如果父窗口有孩子,第一个孩子没有“在顶层”的标志,而当前创建的窗口有这个标志,则将其放在同胞链表的最后边。插入之前:父窗口-长兄(没标志)-次兄(没标志)-三兄(有标志)-0 =插入之后:父窗口-长兄(没标志)-次兄(没标志)-三兄(有标志)-当前窗口-0三、窗口顺序排列分析1、按照窗口分层的概念来说,链表的头部窗口是显示在最底层,链表的尾部窗口是显示在最顶层。在进行窗口重绘的时候,正是从链表的头部开始依次往尾部进行重绘。2、子窗口相对于父窗口来说,子窗口在父窗口的顶部。四、桌面窗口的创建桌面窗口的创建发生在GUI_Init函数执行过程中。如果系统开启了窗口

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论