加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

【STemWin教程入门篇】第34章 窗口管理器实例(一)

(2015-02-13 16:17:50)
标签:

ucos-iii

ucgui

emwin

dsp

窗口管理器

分类: emWin
特别说明:完整STemWin的1-60期教程和配套实例下载地址:链接

第34章  窗口管理器实例(一)

为了帮助大家更好的理解窗口管理器的回调和消息机制,本期教程专门做了三个相关的例子,帮助大家更好的理解。

34.  用户自定义消息类型实例

34. 桌面窗口回调函数实例

34. 官方WM_Redraw.c实例

34. 总结

34.1  用户自定义消息类型实例

这里用上期教程所介绍的自定义消息类型做一个实例。代码跟上期教程的三个实例类似。实现源码如下(可以直接将代码复制到模拟器或者开发板上面运行)。

#include 

#include "GUI.h"

#include "DIALOG.h"

 

#include "WM.h"

#include "BUTTON.h"

#include "CHECKBOX.h"

#include "DROPDOWN.h"

#include "EDIT.h"

#include "FRAMEWIN.h"

#include "LISTBOX.h"

#include "MULTIEDIT.h"

#include "RADIO.h"

#include "SLIDER.h"

#include "TEXT.h"

#include "PROGBAR.h"

#include "SCROLLBAR.h"

#include "LISTVIEW.h"

 

 

#define WM_UPDATE  WM_USER 1(1)

 

GUI_COLOR _acColor[3] {GUI_BLUE,GUI_RED,GUI_YELLOW};

static  char ucBackColor; 

 

 

 

 

 

static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] {

    FRAMEWIN_CreateIndirect,  "armfly",            0,                       0,  0,  800,480,FRAMEWIN_CF_MOVEABLE,0},

    BUTTON_CreateIndirect,    "BUTTON0",           GUI_ID_BUTTON0,          82, 122,162,37, 0,0},

    BUTTON_CreateIndirect,    "BUTTON1",           GUI_ID_BUTTON1,          357,123,152,35, 0,0}

};

 

 

 

void PaintDialog(WM_MESSAGE pMsg)

{

    WM_HWIN hWin pMsg->hWin;

GUI_SetBkColor(_acColor[ucBackColor]);

GUI_Clear();

}

 

 

 

void InitDialog(WM_MESSAGE pMsg)

{

    WM_HWIN hWin pMsg->hWin;

    //

    //FRAMEWIN

    //

    FRAMEWIN_SetFont(hWin,&GUI_Font24B_ASCII);

    FRAMEWIN_SetTextAlign(hWin,GUI_TA_VCENTER|GUI_TA_CENTER);

    FRAMEWIN_AddCloseButton(hWin, FRAMEWIN_BUTTON_RIGHT, 0);

    FRAMEWIN_AddMaxButton(hWin, FRAMEWIN_BUTTON_RIGHT, 1);

    FRAMEWIN_AddMinButton(hWin, FRAMEWIN_BUTTON_RIGHT, 2);

    FRAMEWIN_SetTitleHeight(hWin,30);

 

 

ucBackColor 0;

}

 

 

static void _cbCallback(WM_MESSAGE pMsg) 

{

    int NCode, Id;

    WM_HWIN hWin pMsg->hWin;

    switch (pMsg->MsgId) 

    {

 

case WM_UPDATE: (2)

ucBackColor++;

if (ucBackColor == 3)

{

ucBackColor 0;

}

WM_InvalidateWindow(hWin);

break;

case WM_MOUSEOVER:

 

            break;

case WM_PAINT:

            PaintDialog(pMsg);

            break;

        case WM_INIT_DIALOG:

            InitDialog(pMsg);

            break;

        case WM_KEY:

            switch (((WM_KEY_INFO*)(pMsg->Data.p))->Key) 

            {

                case GUI_KEY_ESCAPE:

                    GUI_EndDialog(hWin, 1);

                    break;

                case GUI_KEY_ENTER:

                    GUI_EndDialog(hWin, 0);

                    break;

            }

            break;

        case WM_NOTIFY_PARENT:

            Id WM_GetId(pMsg->hWinSrc); 

            NCode pMsg->Data.v;        

            switch (Id) 

            {

                case GUI_ID_OK:

                    if(NCode==WM_NOTIFICATION_RELEASED)

                        GUI_EndDialog(hWin, 0);

                    break;

                case GUI_ID_CANCEL:

                    if(NCode==WM_NOTIFICATION_RELEASED)

                        GUI_EndDialog(hWin, 0);

                    break;

                case GUI_ID_BUTTON0:

                    switch(NCode)

                    {

                        case WM_NOTIFICATION_CLICKED:

ucBackColor++;

if (ucBackColor == 3)

{

ucBackColor 0;

}

WM_InvalidateWindow(hWin);

                            break;

                        case WM_NOTIFICATION_RELEASED:

 

                            break;

                        case WM_NOTIFICATION_MOVED_OUT:

 

                            break;

                    }

                    break;

                case GUI_ID_BUTTON1:

                    switch(NCode)

                    {

                        case WM_NOTIFICATION_CLICKED:

ucBackColor--;

if (ucBackColor 0)

{

ucBackColor 2;

}

WM_InvalidateWindow(hWin);

                            break;

                        case WM_NOTIFICATION_RELEASED:

 

                            break;

                        case WM_NOTIFICATION_MOVED_OUT:

 

                            break;

                    }

                    break;

 

            }

            break;

        default:

            WM_DefaultProc(pMsg);

    }

}

 

 

 

void MainTask(void) 

    WM_HWIN hDlg;

 

GUI_Init();

    WM_SetDesktopColor(GUI_BLUE);      

    WM_SetCreateFlags(WM_CF_MEMDEV);  

PROGBAR_SetDefaultSkin(PROGBAR_SKIN_FLEX);

FRAMEWIN_SetDefaultSkin(FRAMEWIN_SKIN_FLEX);

PROGBAR_SetDefaultSkin(PROGBAR_SKIN_FLEX);

BUTTON_SetDefaultSkin(BUTTON_SKIN_FLEX);

CHECKBOX_SetDefaultSkin(CHECKBOX_SKIN_FLEX);

DROPDOWN_SetDefaultSkin(DROPDOWN_SKIN_FLEX);

SCROLLBAR_SetDefaultSkin(SCROLLBAR_SKIN_FLEX);

SLIDER_SetDefaultSkin(SLIDER_SKIN_FLEX);

HEADER_SetDefaultSkin(HEADER_SKIN_FLEX);

RADIO_SetDefaultSkin(RADIO_SKIN_FLEX);

 

 

    hDlg GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), &_cbCallback, 0, 0, 0);

while (1)

{

WM_SendMessageNoPara(WM_GetClientWindow(hDlg), WM_UPDATE); (3)

GUI_Delay(500);

}

 

}

1. 定义一个用户消息WM_UPDATE。一定要以WM_USER作为起始值,防止跟系统其他的数值冲突。

2. 在回调函数中加入咱们定义的消息WM_UPDATE,实现对话框中背景的更新功能。

3. 通过函数WM_SendMessageNoPara()每隔500ms给对话框发送消息。这里要特别的注意一点,这个函数是给窗口发送消息的,而咱们前面创建的是对话框,所以这里必须得通过函数WM_GetClientWindow得到窗口的句柄。

这个程序的显示效果如下:

【STemWin教程入门篇】第34章 <wbr>窗口管理器实例(一)

34.2  桌面窗口回调函数实例

这里用上期教程所介绍的自定义消息类型做一个实例。代码跟上期教程的三个实例类似。实现源码如下(可以直接将代码复制到模拟器或者开发板上面运行)。

#include 

#include "GUI.h"

#include "DIALOG.h"

 

#include "WM.h"

#include "BUTTON.h"

#include "CHECKBOX.h"

#include "DROPDOWN.h"

#include "EDIT.h"

#include "FRAMEWIN.h"

#include "LISTBOX.h"

#include "MULTIEDIT.h"

#include "RADIO.h"

#include "SLIDER.h"

#include "TEXT.h"

#include "PROGBAR.h"

#include "SCROLLBAR.h"

#include "LISTVIEW.h"

 

 

#define WM_UPDATE  WM_USER 1

 

GUI_COLOR _acColor[3] {GUI_BLUE,GUI_RED,GUI_YELLOW};

static  char ucBackColor; 

 

 

 

 

 

static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] {

    FRAMEWIN_CreateIndirect,  "armfly",            0,                       0,  0,  800,480,FRAMEWIN_CF_MOVEABLE,0},

    BUTTON_CreateIndirect,    "BUTTON0",           GUI_ID_BUTTON0,          82, 122,162,37, 0,0},

    BUTTON_CreateIndirect,    "BUTTON1",           GUI_ID_BUTTON1,          357,123,152,35, 0,0}

};

 

 

 

void PaintDialog(WM_MESSAGE pMsg)

{

    WM_HWIN hWin pMsg->hWin;

// GUI_SetBkColor(_acColor[ucBackColor]);

// GUI_Clear();

}

 

 

 

void InitDialog(WM_MESSAGE pMsg)

{

    WM_HWIN hWin pMsg->hWin;

    //

    //FRAMEWIN

    //

    FRAMEWIN_SetFont(hWin,&GUI_Font24B_ASCII);

    FRAMEWIN_SetTextAlign(hWin,GUI_TA_VCENTER|GUI_TA_CENTER);

    FRAMEWIN_AddCloseButton(hWin, FRAMEWIN_BUTTON_RIGHT, 0);

    FRAMEWIN_AddMaxButton(hWin, FRAMEWIN_BUTTON_RIGHT, 1);

    FRAMEWIN_AddMinButton(hWin, FRAMEWIN_BUTTON_RIGHT, 2);

    FRAMEWIN_SetTitleHeight(hWin,30);

 

 

ucBackColor 0;

}

 

 

static void _cbCallback(WM_MESSAGE pMsg) 

{

    int NCode, Id;

    WM_HWIN hWin pMsg->hWin;

    switch (pMsg->MsgId) 

    {

case WM_PAINT:

            PaintDialog(pMsg);

            break;

        case WM_INIT_DIALOG:

            InitDialog(pMsg);

            break;

        case WM_KEY:

            switch (((WM_KEY_INFO*)(pMsg->Data.p))->Key) 

            {

                case GUI_KEY_ESCAPE:

                    GUI_EndDialog(hWin, 1);

                    break;

                case GUI_KEY_ENTER:

                    GUI_EndDialog(hWin, 0);

                    break;

            }

            break;

        case WM_NOTIFY_PARENT:

            Id WM_GetId(pMsg->hWinSrc); 

            NCode pMsg->Data.v;        

            switch (Id) 

            {

                case GUI_ID_OK:

                    if(NCode==WM_NOTIFICATION_RELEASED)

                        GUI_EndDialog(hWin, 0);

                    break;

                case GUI_ID_CANCEL:

                    if(NCode==WM_NOTIFICATION_RELEASED)

                        GUI_EndDialog(hWin, 0);

                    break;

                case GUI_ID_BUTTON0:

                    switch(NCode)

                    {

                        case WM_NOTIFICATION_CLICKED:

                            break;

                        case WM_NOTIFICATION_RELEASED:

 

                            break;

                        case WM_NOTIFICATION_MOVED_OUT:

 

                            break;

                    }

                    break;

                case GUI_ID_BUTTON1:

                    switch(NCode)

                    {

                        case WM_NOTIFICATION_CLICKED:

 

                            break;

                        case WM_NOTIFICATION_RELEASED:

 

                            break;

                        case WM_NOTIFICATION_MOVED_OUT:

 

                            break;

                    }

                    break;

 

            }

            break;

        default:

            WM_DefaultProc(pMsg);

    }

}

 

 

static void _cbBkWindow(WM_MESSAGE pMsg) (1)

{

    WM_HWIN hWin pMsg->hWin;

 

    switch (pMsg->MsgId) 

    {

case WM_PAINT:  (2)

GUI_SetBkColor(_acColor[ucBackColor]);

GUI_Clear();

            break;

case WM_UPDATE:(3)

ucBackColor++;

if (ucBackColor == 3)

{

ucBackColor 0;

}

WM_InvalidateWindow(hWin);

            break;

        default:

            WM_DefaultProc(pMsg);

    }

}

 

 

void MainTask(void) 

    WM_HWIN hDlg;

 

 

WM_SetCreateFlags(WM_CF_MEMDEV);   (4)

GUI_Init();

    

WM_SetCallback(WM_HBKWIN, _cbBkWindow);(5)

    //WM_SetDesktopColor(GUI_BLUE);       (6)

PROGBAR_SetDefaultSkin(PROGBAR_SKIN_FLEX);

FRAMEWIN_SetDefaultSkin(FRAMEWIN_SKIN_FLEX);

PROGBAR_SetDefaultSkin(PROGBAR_SKIN_FLEX);

BUTTON_SetDefaultSkin(BUTTON_SKIN_FLEX);

CHECKBOX_SetDefaultSkin(CHECKBOX_SKIN_FLEX);

DROPDOWN_SetDefaultSkin(DROPDOWN_SKIN_FLEX);

SCROLLBAR_SetDefaultSkin(SCROLLBAR_SKIN_FLEX);

SLIDER_SetDefaultSkin(SLIDER_SKIN_FLEX);

HEADER_SetDefaultSkin(HEADER_SKIN_FLEX);

RADIO_SetDefaultSkin(RADIO_SKIN_FLEX);

 

 

    hDlg GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), &_cbCallback, 0, 0, 0);

while (1)

{

WM_SendMessageNoPara(WM_HBKWIN, WM_UPDATE);                                                   (7)

GUI_Delay(500);

}

 

}

1. 桌面窗口的回调函数(桌面窗口是emWin最底层的窗口,是初始化后自动创建的)。

2. 重绘消息,用于实现桌面颜色的重绘。

3. 这个是自定义消息,功能和上面34.1小节讲的一样。

4. 使能窗口使用内存设备,这样可以有效的避免闪烁。

5. 通过函数WM_SetCallback来设置桌面窗口的回调函数。

6. 函数WM_SetDesktopColor可以实现桌面窗口颜色的自动重绘。

7. 这里要尤其的注意,系统消息由GUI库发送。请勿从用户应用程序向窗口或小工具发送系统定义的消息。要不会出现异常的。也就是说我们不能发WM_PAINT消息,但是可以发自定义消息,进而来触发重绘。

这个DEMO的功能就是每隔500ms改变一次桌面窗口的颜色,实际显示效果如下:

【STemWin教程入门篇】第34章 <wbr>窗口管理器实例(一)

34.3  官方WM_Redraw.c实例

这个DEMO在模拟器中的位置:

【STemWin教程入门篇】第34章 <wbr>窗口管理器实例(一)

下面我们将这个代码分析一下:

#include "GUI.h"

#include "WM.h"

 

 

 

static void _cbBkWindow(WM_MESSAGE* pMsg) {(1)

  switch (pMsg->MsgId) {

  case WM_PAINT:

    GUI_ClearRect(0, 50, 319, 239);(2)

  default:

    WM_DefaultProc(pMsg);

  }

}

 

 

static void _cbWindow(WM_MESSAGE* pMsg) {(3)

  GUI_RECT Rect;

 

  switch (pMsg->MsgId) {

  case WM_PAINT:

    WM_GetInsideRect(&Rect);(4)

    GUI_SetBkColor(GUI_RED);

    GUI_SetColor(GUI_YELLOW);

    GUI_ClearRectEx(&Rect);(5)

    GUI_DrawRectEx(&Rect);

    GUI_SetColor(GUI_BLACK);

    GUI_SetFont(&GUI_Font8x16);

    GUI_DispStringHCenterAt("Foreground window", 75, 40);

    break;

  default:

    WM_DefaultProc(pMsg);

  }

}

 

 

static void _MoveWindow(const char* pText) {

  WM_HWIN hWnd;

  int     i;

 

  //

  // Create foreground window

  //

  hWnd WM_CreateWindow(10, 50, 150, 100, WM_CF_SHOW, _cbWindow, 0);(6)

  GUI_Delay(500);

  //

  // Move foreground window

  //

  for (i 0; 40; i++) {

    WM_MoveWindow(hWnd, 2, 2);(7)

    GUI_Delay(10);

  }

  //

  // Show text before deleting window if we have one

  //

  if (pText) {

    GUI_DispStringAt(pText, 5, 50);

    GUI_Delay(2500);

  }

  //

  // Delete foreground window

  //

  WM_DeleteWindow(hWnd);(8)

  WM_Invalidate(WM_HBKWIN);(9)

  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) {

    //

    // Move window over background

    //

    _MoveWindow("Background has not been redrawn");(10)

    //

    // Clear background

    //

    GUI_ClearRect(0, 50, 319, 239);

    GUI_Delay(1000);

    //

    // Set callback for background window

    //

    _cbOldBk WM_SetCallback(WM_HBKWIN, _cbBkWindow);(11)

    //

    // Move window over background

    //

    _MoveWindow("Background has been redrawn");

    //

    // Delete callback for Background window

    //

    WM_SetCallback(WM_HBKWIN, _cbOldBk);(12)

  }

}

 

 

 

void MainTask(void) {

  GUI_Init();

  _DemoRedraw();

}

1. 桌面窗口回调函数。

2. 在回调函数的WM_PAINT消息中清除一块区域。

3. 另一个创建窗口的回调函数。

4. 函数WM_GetInsideRect返回客户区的坐标,该区域由活动小工具尺寸减去边界尺寸确定。此函数向活动窗口发送一条消息,检索内部矩形。如果小工具不处理此消息(也即意味着小工具没有边界),则需使用WM_GetClientRect函数计算出矩形。结果通过窗口坐标给出。也即,GUI_RECT结构中的x0和y0相当于x和y的边界尺寸,x1和y1相当于窗口尺寸减去边界尺寸-1。

5. 调用函数GUI_ClearRectEx清除部分区域。

6. 函数WM_CreateWindow中每个参数的含义需要大家详细研究下官方手册,这里就不做解释了。

7. 通过函数WM_MoveWindow()实现窗口位置的移动,注意这里移动的是相对距离

8. 删除这个创建的窗口。

9. 通过函数WM_Invalidate(WM_HBKWIN)使得桌面窗口无效,然后调用函数GUI_Exec()就会执行重绘。

10. 执行第一种情况:移动窗口,但是不做桌面窗口的重绘。

11. 给桌面窗口设置专门的回调函数。

12. 执行第二种情况:移动窗口,并执行桌面窗口的重绘。

这个演示实例的主要功能就是两种情况,一种是演示:移动窗口的情况下,但是不做桌面窗口的重绘。另一种是:移动窗口,并执行桌面窗口的重绘。通过这两种情况的演示可以帮助大家对回调函数有一个更好的认识。

第一幅:没有执行桌面回调函数的情况:

【STemWin教程入门篇】第34章 <wbr>窗口管理器实例(一)

第二幅:执行桌面回调函数的情况:

【STemWin教程入门篇】第34章 <wbr>窗口管理器实例(一)

34.4  总结

本期教程就跟大家讲这么多,希望通过本期教程让大家对窗口管理器有更好的认识,不过还需要大家在模拟器或者开发板上面多做这方面的练习。

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有