• 【第3版emWin教程】第52章 emWin6.x的FrameWin框架窗口控件


    教程不断更新中:http://www.armbbs.cn/forum.php?mod=viewthread&tid=98429

    第52章       emWin6.x的FrameWin框架窗口控件

    本章节为大家讲解emWin支持的框架窗口控件,外加上一章节为大家讲解的窗口控件,对话框所必须的两个主体控件就为大家都进行了讲解,这样可以方便我们后续讲解其它控件。

    52.1 初学者重要提示

    52.2 框架窗口控件基础知识

    52.3 使用GUIBuilder创建框架窗口控件并用模拟器显示出来

    52.4 官方WIDGET_FrameWin.c实例讲解

    52.5 实验例程说明(RTOS)

    52.6 实验例程说明(裸机)

    52.7 总结

    52.1 初学者重要提示

    1.   学习框架窗口要将框架窗口和框架窗口的客户端窗口区分开,而且他们对应的回调函数也是不一样的。
    2.   框架窗口控件的所有API函数在emWin手册中都有讲解,下图是中文版手册里面API函数位置:

     

    下图是英文版手册里面API函数的位置:

     

     

    52.2 框架窗口控件基础知识

    框架窗口控件为用户的应用程序提供了一个类似PC应用程序的窗口外观。这些窗口由周围框架、标题栏和用户区组成。标题栏的颜色改变由显示窗口是否被激活决定,如下图所示:

     

    另外,还可以将预定义的按钮附加到标题栏,也可将自定义的按钮附加到标题栏:

     

    如果设置皮肤色后,框架窗口的显示效果如下:

     

    52.2.1   框架窗口控件的结构

    下图显示了框架窗口控件的详细结构和外观:

     

    框架窗口控件实际上由2种窗口组成;主窗口和子窗口,子窗口称为客户端窗口。处理回调函数时意识到此点非常重要:主窗口和客户端窗口都有自己的回调函数,在框架窗口上面创建子窗口或者控件时,这些子窗口或者控件通常作为客户端窗口的子窗口或者子控件而创建,也就是说它们的父窗口是客户端窗口。

     

    更多对话框上面创建框架窗口的注意事项在第48章48.5小节详细进行了讲解,这里不再赘述。

    52.2.2   键盘反应(输入聚焦)

    框架窗口控件不支持输入聚焦,这点要特别注意。不支持输入聚焦的话,外置键盘或者类似外置键盘的输入设备给框架窗口控件发消息是没有任何反应的。

    (输入聚焦是一个重要的知识点,使用外置键盘或者类似外置键盘的输入设备要用到)

    52.2.3   框架窗口控件API函数

    框架窗口控件的API函数比较多,但调用都不难,大家只需看官方手册中的API函数说明就够用了,后面用到的函数中有需要特别注意的再跟大家进行讲解。

    本章节教程配套例子是将框架窗口控件配合对话框一起使用的,实际项目中也推荐大家这么做,可以很方便的进行界面管理。在对话框上面使用框架窗口控件是通过函数FRAMEWIN_CreateIndirect()来实现的。根据第47章47.7.1小节讲解的<WIDGET>_CreateIndirect()函数,GUI_WIDGET_CREATE_INFO结构体类型定义如下:

    typedef struct {
    GUI_WIDGET_CREATE_FUNC * pfCreateIndirect;    // 间接创建函数
    const char * pName;                           // 控件名(不是所有控件都需要)
    I16 Id;                                       // 控件ID
    I16 x0, y0, xSize, ySize;                     // 控件的坐标位置和大小
    I16 Flags;                                    // 控件用到的标志,没有就写0
    I32 Para;                                     // 控件用到的参数,没有就写0
    U32 NumExtraBytes;                            // 函数 <WIDGET>_SetUserData & <WIDGET>_GetUserData用到的
    // 额外字节。
    } GUI_WIDGET_CREATE_INFO;

    上面结构体成员里面的标记Flags和参数Para是可选的,函数FRAMEWIN_CreateIndirect()没有用到参数Para,但用到了标记Flags,与函数FRAMEWIN_CreateEx的形参ExFlags是等效的,具体形参ExFlags支持哪些标记参看emWin官方手册中的说明即可。

    这里举一个对话框资源列表里面创建框架窗口控件的例子,帮助大家更好的理解:

    /*
    *********************************************************************************************************
    *                           GUI_WIDGET_CREATE_INFO类型数组
    *********************************************************************************************************
    */
    static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = 
    {
        { FRAMEWIN_CreateIndirect,  "Framewin",   ID_FRAMEWIN_0,   0, 0, 800, 480, 0, 0, 0 },
        { BUTTON_CreateIndirect,    "Button",     ID_BUTTON_0,   130, 28, 147, 35, 0, 0x0, 0 },
        { SCROLLBAR_CreateIndirect, "Scrollbar",  ID_SCROLLBAR_0,129, 74, 147, 28, 0, 0x0, 0 },
        { SLIDER_CreateIndirect,    "Slider",     ID_SLIDER_0,   133, 118, 137, 25, 0, 0x0, 0 },
    };

    上面的对话框资源列表里面依次创建了框架窗口控件,按钮控件,滚动条控件和滑动条控件。框架窗口控件的参数和GUI_WIDGET_CREATE_INFO结构成员的对应关系如下:

    pfCreateIndirect = FRAMEWIN_CreateIndirect;
    pName = "Framewin";
    Id = ID_FRAMEWIN_0;
    x0 = 0;
    y0 = 0
    xSize = 800;
    ySzie = 480;
    Flags = 0;
    Para = 0x0;
    NumExtraBytes = 0;

    52.3 使用GUIBuilder创建框架窗口控件并用模拟器显示出来

    GUIBuilder在MDK5.X的安装目录中,路径\Keil\MDK-Middleware\7.12.0\emWin\Tool (版本不同,红色数值不同)里面:

     

    52.3.1        第一步:建立一个对话框,主体是框架窗口

    •   找到GUIBuilder后,打开这个软件,并按照如下方式建立一个对话框。

     

    •   修改框架窗口大小为800*480。

     

    •   下面设置对话框标题的字体,对齐方式,和显示的文本。首先,在建立的对话框上面右击鼠标,选择Set font。

     

    弹出如下界面,并选择字体GUI_FONT_32B_ASCII,点击OK。

    设置好字体以后再设置对齐方式,还是右击鼠标,选择Set text alignment,并选择居中

    配置完成后,上面的字体Framewin会居中显示,然后还是鼠标右击,选择Set title text,并更改Framewin为armfly,修改的地方在左下角:

    设置好以后,对话框就算建立完毕。

    52.3.2        第二步:在对话框上面建立按钮控件

    仅显示一个框架窗口控件的话,内容太少了,我们在上面添加一个按钮控件。按钮的建立方法和上面的对话框是一样的。按钮上面的字体大小和显示内容,大家可以任意设置。按钮上的文本不支持对齐方式设置,默认是居中显示,这里是显示字符armfly,字体GUI_FONT_24B_ASCII,建立后的效果如下所示:

    对于建立的按钮控件,用户可以任意拖动,并通过鼠标调整其大小,调整方法如下:先左击选中相应控件,会出现绿色的边框,在边框的地方拖动鼠标即可修改大小

     

    52.3.3        第三步:在对话框上面建立滚动条控件

    仅显示一个框架窗口控件的话,内容太少了,我们在上面再添加一个滚动条控件。同样的方法,添加滚动条后的效果如下所示:

     

    52.3.4        第四步:在对话框上面建立滑动条控件

    仅显示一个框架窗口控件的话,内容太少了。最后,我们在上面再添加一个滑动条控件。同样的方法,添加滑动条后显示效果如下:

     

    52.3.5        第五步:建立好后点击File-save

    保存方法如下:

    保存后生成的文件在GUIBuilder5.32软件所在的文件夹里面:

     

    52.3.6        第五步:在模拟器上运行GUIBuilder生成的代码

    在模拟器上面如何演示GUIBuilder的生成的代码已经在第6章的6.3小节详细讲述了,这里不再赘述。可以在模拟器上面运行的完整代码如下:

    /*********************************************************************
    *                                                                    *
    *                SEGGER Microcontroller GmbH & Co. KG                *
    *        Solutions for real time microcontroller applications        *
    *                                                                    *
    **********************************************************************
    *                                                                    *
    * C-file generated by:                                               *
    *                                                                    *
    *        GUI_Builder for emWin version 5.32                          *
    *        Compiled Oct  8 2015, 11:59:02                              *
    *        (c) 2015 Segger Microcontroller GmbH & Co. KG               *
    *                                                                    *
    **********************************************************************
    *                                                                    *
    *        Internet: www.segger.com  Support: support@segger.com       *
    *                                                                    *
    **********************************************************************
    */
    
    // USER START (Optionally insert additional includes)
    // USER END
    
    #include "DIALOG.h"
    
    /*********************************************************************
    *
    *       Defines
    *
    **********************************************************************
    */
    #define ID_FRAMEWIN_0  (GUI_ID_USER + 0x00)
    #define ID_BUTTON_0    (GUI_ID_USER + 0x01)
    #define ID_SCROLLBAR_0 (GUI_ID_USER + 0x02)
    #define ID_SLIDER_0    (GUI_ID_USER + 0x03)
    
    
    // USER START (Optionally insert additional defines)
    // USER END
    
    /*********************************************************************
    *
    *       Static data
    *
    **********************************************************************
    */
    
    // USER START (Optionally insert additional static data)
    // USER END
    
    /*********************************************************************
    *
    *       _aDialogCreate
    */
    static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
      { FRAMEWIN_CreateIndirect, "Framewin", ID_FRAMEWIN_0, 0, 0, 800, 480, 0, 0x64, 0 },//--------------(1)
      { BUTTON_CreateIndirect, "Button", ID_BUTTON_0, 130, 28, 147, 35, 0, 0x0, 0 },
      { SCROLLBAR_CreateIndirect, "Scrollbar", ID_SCROLLBAR_0, 129, 74, 147, 28, 0, 0x0, 0 },
      { SLIDER_CreateIndirect, "Slider", ID_SLIDER_0, 133, 118, 137, 25, 0, 0x0, 0 },
      // USER START (Optionally insert additional widgets)
      // USER END
    };
    
    /*********************************************************************
    *
    *       Static code
    *
    **********************************************************************
    */
    
    // USER START (Optionally insert additional static code)
    // USER END
    
    /*********************************************************************
    *
    *       _cbDialog
    */
    static void _cbDialog(WM_MESSAGE * pMsg) {
      WM_HWIN hItem;
      int     NCode;
      int     Id;
      // USER START (Optionally insert additional variables)
      // USER END
    
      switch (pMsg->MsgId) {
      case WM_INIT_DIALOG:
        //
        // Initialization of 'Framewin'
        //
        hItem = pMsg->hWin;
        FRAMEWIN_SetFont(hItem, GUI_FONT_32B_ASCII); //--------------(2)
        FRAMEWIN_SetTextAlign(hItem, GUI_TA_HCENTER | GUI_TA_VCENTER); //--------------(3)
        FRAMEWIN_SetText(hItem, "armfly");           //--------------(4)
        //
        // Initialization of 'Button'
        //
        hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_0);
        BUTTON_SetFont(hItem, GUI_FONT_24B_ASCII);
        BUTTON_SetText(hItem, "armfly");
        // USER START (Optionally insert additional code for further widget initialization)
        // USER END
        break;
      case WM_NOTIFY_PARENT:
        Id    = WM_GetId(pMsg->hWinSrc);
        NCode = pMsg->Data.v;
        switch(Id) {
        case ID_BUTTON_0: // Notifications sent by 'Button'
          switch(NCode) {
          case WM_NOTIFICATION_CLICKED:
            // USER START (Optionally insert code for reacting on notification message)
            // USER END
            break;
          case WM_NOTIFICATION_RELEASED:
            // USER START (Optionally insert code for reacting on notification message)
            // USER END
            break;
          // USER START (Optionally insert additional code for further notification handling)
          // USER END
          }
          break;
        case ID_SCROLLBAR_0: // Notifications sent by 'Scrollbar'
          switch(NCode) {
          case WM_NOTIFICATION_CLICKED:
            // USER START (Optionally insert code for reacting on notification message)
            // USER END
            break;
          case WM_NOTIFICATION_RELEASED:
            // USER START (Optionally insert code for reacting on notification message)
            // USER END
            break;
          case WM_NOTIFICATION_VALUE_CHANGED:
            // USER START (Optionally insert code for reacting on notification message)
            // USER END
            break;
          // USER START (Optionally insert additional code for further notification handling)
          // USER END
          }
          break;
        case ID_SLIDER_0: // Notifications sent by 'Slider'
          switch(NCode) {
          case WM_NOTIFICATION_CLICKED:
            // USER START (Optionally insert code for reacting on notification message)
            // USER END
            break;
          case WM_NOTIFICATION_RELEASED:
            // USER START (Optionally insert code for reacting on notification message)
            // USER END
            break;
          case WM_NOTIFICATION_VALUE_CHANGED:
            // USER START (Optionally insert code for reacting on notification message)
            // USER END
            break;
          // USER START (Optionally insert additional code for further notification handling)
          // USER END
          }
          break;
        // USER START (Optionally insert additional code for further Ids)
        // USER END
        }
        break;
      // USER START (Optionally insert additional message handling)
      // USER END
      default:
        WM_DefaultProc(pMsg);
        break;
      }
    }
    
    /*********************************************************************
    *
    *       Public code
    *
    **********************************************************************
    */
    /*********************************************************************
    *
    *       CreateFramewin
    */
    WM_HWIN CreateFramewin(void);
    WM_HWIN CreateFramewin(void) {
      WM_HWIN hWin;
    
      hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);
      return hWin;
    }
    
    /*********************************************************************
    *
    *       MainTask
    */
    void MainTask(void) 
    {
         /* 初始化 */
        GUI_Init();
    
        /* 窗口自动使用存储设备 */
        WM_SetCreateFlags(WM_CF_MEMDEV);
    
        /* 创建对话框,使用GUIBulder5.32生成的对话框创建函数 */
        CreateWindow();
    
        while(1)
        {
            GUI_Delay(10);
        }
    }
    
    /*************************** End of file ****************************/

    创建的这个例子相对比较容易,主要实现了在对话框上面创建了几个控件,对话框的主体是用的框架窗口控件。

    1. 在对话框的资源列表中创建框架窗口控件。
    2. 通过函数WM_GetDialogItem获得对话框上框架窗口的句柄。
    3. 通过函数FRAMEWIN_SetFont设置框架窗口标题栏显示的字体。
    4. 通过函数FRAMEWIN_SetTextAlign设置框架窗口标题栏文本的对齐方式。
    5. 通过函数FRAMEWIN_SetText设置框架窗口标题显示的文本。

    实际显示效果如下,分辨率800*480:

     

    对于这个创建和演示过程,强烈建议初学者实际动手操作。

    52.4 官方WIDGET_FrameWin.c实例讲解

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

     

    主要功能介绍:

    这个例子简单的演示了框架窗口大部分API函数的效果,对于初学者来说,这个例子还是非常具有参考价值的。另外这个例子还为框架窗口和框架窗口的客户端窗口分别都创建了回调函数,很好的将框架窗口和框架窗口的客户端窗口区分开。

    程序代码如下:

    #include <stddef.h>
    #include <string.h>
    #include "GUI.h"
    #include "FRAMEWIN.h"
    
    /*********************************************************************
    *
    *       Defines
    *
    **********************************************************************
    */
    #define SPEED   1200
    
     
    #define MSG_CHANGE_MAIN_TEXT (WM_USER + 0) //--------------(1)
    
    //
    // Recommended memory to run the sample with adequate performance
    //
    #define RECOMMENDED_MEMORY (1024L * 30)
    
    /*********************************************************************
    *
    *       Static data
    *
    **********************************************************************
    */
    static FRAMEWIN_Handle  _hFrame;
    static WM_CALLBACK*     _pcbOldFrame;
    static char             _acMainText[100];
    static int              _LockClose = 1;
    
    /*******************************************************************
    *
    *       Static code
    *
    ********************************************************************
    */
    /*******************************************************************
    *
    *       _ChangeMainText
    *
    *  Sends a message to the background window and invalidate it, so
    *  the callback of the background window display the new text.
    */
    static void _ChangeMainText(char* pStr, int Delay) {  //--------------(2)
      WM_MESSAGE Message;
      Message.MsgId  = MSG_CHANGE_MAIN_TEXT;
      Message.Data.p = pStr;
      GUI_Delay(Delay);
      WM_SendMessage(WM_HBKWIN, &Message);
      WM_InvalidateWindow(WM_HBKWIN);
      GUI_Delay(Delay/3);
    }
    
    /*******************************************************************
    *
    *       _cbChild
    */
    static void _cbChild(WM_MESSAGE * pMsg) {  //--------------(3)
      WM_HWIN hWin = (FRAMEWIN_Handle)(pMsg->hWin);
      switch (pMsg->MsgId) {
      case WM_PAINT:
        //
        // Handle the paint message
        //
        GUI_SetBkColor(GUI_WHITE);
        GUI_SetColor(GUI_BLACK);
        GUI_SetFont(&GUI_FontComic24B_ASCII);
        GUI_SetTextAlign(GUI_TA_HCENTER | GUI_TA_VCENTER);
        GUI_Clear();
        GUI_DispStringHCenterAt("Client window", 
                                WM_GetWindowSizeX(hWin) / 2, 
                                WM_GetWindowSizeY(hWin) / 2);
        break;
      default:
        WM_DefaultProc(pMsg);
      }
    }
    
    /*******************************************************************
    *
    *       _cbFrame
    */
    static void _cbFrame(WM_MESSAGE * pMsg) {  //--------------(4)
      switch (pMsg->MsgId) {
      case WM_NOTIFY_PARENT:
        if (pMsg->Data.v == WM_NOTIFICATION_RELEASED) {
          int Id = WM_GetId(pMsg->hWinSrc);      // Id of widget
          if (Id == GUI_ID_CLOSE) {
            if (_LockClose) {
              return;
            }
            _hFrame = 0;
          }
        }
        break;
      }
      if (_pcbOldFrame) {
        (*_pcbOldFrame)(pMsg);
      }
    }
    
    /*******************************************************************
    *
    *       _cbBkWindow
    *
    * Function description
    *   This callback is necessary to redraw the background when
    *   frame window is moved
    */
    static void _cbBkWindow(WM_MESSAGE * pMsg) {  //--------------(5)
      switch (pMsg->MsgId) {
        case MSG_CHANGE_MAIN_TEXT:
          strcpy(_acMainText, (char const *)pMsg->Data.p);
          WM_InvalidateWindow(pMsg->hWin);
          break;
        case WM_PAINT:
          GUI_SetBkColor(GUI_BLACK);
          GUI_Clear();
          GUI_SetColor(GUI_WHITE);
          GUI_SetFont(&GUI_Font24_ASCII);
          GUI_DispStringHCenterAt("WIDGET_FrameWin - Sample", 160, 5);
          GUI_SetFont(&GUI_Font8x16);
          GUI_DispStringHCenterAt(_acMainText, 160, 40);
          GUI_SetFont(&GUI_Font6x8);
          GUI_DispStringHCenterAt("The function FRAMEWIN_Create creates both the\n"
                                  "frame window and the client window.", 160, 190);
          break;
        default:
          WM_DefaultProc(pMsg);
      }
    }
    
    /*******************************************************************
    *
    *       _DemoFramewin
    *
    * Function description
    *   Creates the frame window and sets the callback for frame, child
    *   and background window
    */
    static void _DemoFramewin(void) {  //--------------(6)
      int i; 
      char acInfoText[] = "-- sec to play with window";
      WM_HWIN hChild;
    
     
      WM_SetCallback(WM_HBKWIN, _cbBkWindow);
      //
      // Create and configure frame window
      //
      _ChangeMainText("FRAMEWIN_Create", SPEED);
      _hFrame = FRAMEWIN_Create("Frame window", 0, WM_CF_SHOW, 50, 75, 220, 100); //--------------(7)
      _pcbOldFrame = WM_SetCallback(_hFrame, _cbFrame); //--------------(8)
      hChild = WM_GetClientWindow(_hFrame);             //--------------(9)
      WM_SetCallback(hChild, _cbChild);                 //--------------(10)
      FRAMEWIN_SetMoveable(_hFrame, 1);                 //--------------(11)
      //
      // Create buttons
      //
      FRAMEWIN_AddCloseButton(_hFrame, FRAMEWIN_BUTTON_LEFT, 0); //--------------(12)
      FRAMEWIN_AddMaxButton(_hFrame, FRAMEWIN_BUTTON_RIGHT, 0);
      FRAMEWIN_AddMinButton(_hFrame, FRAMEWIN_BUTTON_RIGHT, 2);
      //
      // Modify frame window attributes
      //
      _ChangeMainText("FRAMEWIN_SetActive", SPEED);
      FRAMEWIN_SetActive(_hFrame, 1);                //--------------(13)
      _ChangeMainText("FRAMEWIN_SetFont", SPEED);
      FRAMEWIN_SetFont(_hFrame, &GUI_Font16B_ASCII); //--------------(14)
      FRAMEWIN_SetTitleHeight(_hFrame, 20);          //--------------(15)
      _ChangeMainText("FRAMEWIN_SetTextColor", SPEED);
      FRAMEWIN_SetTextColor(_hFrame, GUI_YELLOW);    //--------------(16)
      _ChangeMainText("FRAMEWIN_SetTextAlign", SPEED);
      FRAMEWIN_SetTextAlign(_hFrame, GUI_TA_HCENTER); //--------------(17)
      _ChangeMainText("FRAMEWIN_Minimize", SPEED);
      FRAMEWIN_Minimize(_hFrame);                     //--------------(18)
      _ChangeMainText("FRAMEWIN_Maximize", SPEED);
      FRAMEWIN_Maximize(_hFrame);                     //--------------(19)
      _ChangeMainText("FRAMEWIN_Restore", SPEED);
      FRAMEWIN_Restore(_hFrame);                      //--------------(20)
      _ChangeMainText("FRAMEWIN_SetTitleVis", SPEED);
      for (i = 0; i < 5; i++) {
        FRAMEWIN_SetTitleVis(_hFrame, 0);            //--------------(21)
        GUI_Delay(200);
        FRAMEWIN_SetTitleVis(_hFrame, 1);
        GUI_Delay(200);
      }
      //
      // Time to play with frame window
      //
      _LockClose = 0;
      for (i = 250; (i > 0) && _hFrame; i--) {
        acInfoText[0] = '0' + ((i + 9) / 100);
        acInfoText[1] = '0' + (((i + 9) / 10) % 10);
        _ChangeMainText(acInfoText, 0);
        GUI_Delay(100);
      }
      if (_hFrame) {
        _ChangeMainText("WM_Delete", SPEED);
        WM_DeleteWindow(_hFrame); //--------------(22)
      } else {
        _ChangeMainText("", 50);
      }
    }
    
    /*********************************************************************
    *
    *       Public code
    *
    **********************************************************************
    */
    /*********************************************************************
    *
    *       MainTask
    */
    void MainTask(void) {
      GUI_Init();
      //
      // Check if recommended memory for the sample is available
      //
      if (GUI_ALLOC_GetNumFreeBytes() < RECOMMENDED_MEMORY) {
        GUI_ErrorOut("Not enough memory available."); 
        return;
      }
      WM_EnableMemdev(WM_HBKWIN); //--------------(23)
      while(1) {
          _DemoFramewin();
      }
    }
    1. 自定义的一个回调消息类型,消息类型建议从WM_USER开始统计,方便系统统一管理。
    2. 用于给桌面窗口发送自定义的回调消息类型,发送后将桌面窗口变得无效,从而会触发窗口管理器去执行桌面窗口回调函数中的WM_PAINT消息。
    3. 框架窗口中客户端窗口的回调函数。
    4. 框架窗口的回调函数,注意和框架窗口客户端窗口的回调函数区分开。
    5. 桌面窗口的回调函数。
    6. 框架窗口中部分API函数的演示函数。
    7. 通过函数FRAMEWIN_Create创建框架窗口。
    8. 通过函数WM_SetCallback设置框架窗口的回调函数。
    9. 通过函数WM_GetClientWindow获得框架窗口中客户端窗口句柄。
    10. 通过函数WM_SetCallback设置客户端窗口的回调函数。
    11. 通过函数FRAMEWIN_SetMoveable设置框架窗口可移动。
    12. 通过函数FRAMEWIN_AddCloseButton为框架窗口添加关闭按钮。

      通过函数FRAMEWIN_AddMaxButton为框架窗口添加最大化按钮。

      通过函数FRAMEWIN_AddMinButton为框架窗口添加最小化按钮。

    13. 通过函数FRAMEWIN_SetActive激活框架窗口。
    14. 通过函数FRAMEWIN_SetFont设置框架窗口中标题栏的字体。
    15. 通过函数FRAMEWIN_SetTitleHeight设置标题栏的高度。
    16. 通过函数FRAMEWIN_SetTextColor设置标题栏中字体的颜色。
    17. 通过函数FRAMEWIN_SetTextAlign设置标题栏中文本的对齐方式。
    18. 通过函数FRAMEWIN_Minimize设置框架窗口最小化。
    19. 通过函数FRAMEWIN_Maximize设置框架窗口最大化。
    20. 通过函数FRAMEWIN_Restore将框架窗口从最小化或最大化恢复。
    21. 通过函数FRAMEWIN_SetTitleVis设置框架窗口标题的可见性。
    22. 通过函数WM_DeleteWindow删除框架窗口。
    23. 通过函数WM_EnableMemdev(WM_HBKWIN)使能桌面窗口使用存储设备。

    另外,这个例子中变量_LockClose的作用也很重要,它的主要作用就是在演示框架窗口时锁住关闭按钮,防止在演示的时候,用户点击了关闭按钮。同时,大家也特别注意框架窗口回调函数_cbFrame的处理,这个回调函数才是框架窗口的回调函数,而不是客户端窗口的回调函数,而且框架窗口标题栏上面的最大化,最小化和关闭按钮是框架窗口的子控件,而不是客户端窗口的子控件。

    实际显示效果如下:

     

    52.5 实验例程说明(RTOS)

    配套例子:

    V7-568_emWin6.x实验_FrameWin框架窗口控件(RTOS)

    实验目的:

    1. 本实验主要学习框架窗口控件的使用。
    2. emWin功能的实现在MainTask.c文件里面。

    实验内容:

    1、K1按键按下,串口或者RTT打印任务执行情况(串口波特率115200,数据位8,奇偶校验位无,停止位1)。

    2、(1) 凡是用到printf函数的全部通过函数App_Printf实现。

    (2) App_Printf函数做了信号量的互斥操作,解决资源共享问题。

    3、默认上电是通过串口打印信息,如果使用RTT打印信息:

    MDK AC5,MDK AC6或IAR通过使能bsp.h文件中的宏定义为1即可

    #define Enable_RTTViewer  1

    4、各个任务实现的功能如下:

    App Task Start   任务 :启动任务,这里用作BSP驱动包处理。

    App Task MspPro任务 :消息处理,这里用作LED闪烁。

    App Task UserIF  任务 :按键消息处理。

    App Task COM   任务 :暂未使用。

    App Task GUI    任务 :GUI任务。

    μCOS-III任务调试信息(按K1按键,串口打印):

    RTT 打印信息方式:

     

    程序设计:

    任务栈大小分配:

    μCOS-III任务栈大小在app_cfg.h文件中配置:

    #define  APP_CFG_TASK_START_STK_SIZE                      512u

    #define  APP_CFG_TASK_MsgPro_STK_SIZE                     2048u

    #define  APP_CFG_TASK_COM_STK_SIZE                        512u

    #define  APP_CFG_TASK_USER_IF_STK_SIZE                    512u

    #define  APP_CFG_TASK_GUI_STK_SIZE                        2048u

    任务栈大小的单位是4字节,那么每个任务的栈大小如下:

    App Task Start   任务 :2048字节。

    App Task MspPro任务 :8192字节。

    App Task UserIF  任务 :2048字节。

    App Task COM   任务 :2048字节。

    App Task GUI    任务 :8192字节。

    系统栈大小分配:

    μCOS-III的系统栈大小在os_cfg_app.h文件中配置:

    #define  OS_CFG_ISR_STK_SIZE                      512u     

    系统栈大小的单位是4字节,那么这里就是配置系统栈大小为2KB

    emWin动态内存配置:

    GUIConf.c文件中的配置如下:

    #define EX_SRAM   1/*1 used extern sram, 0 used internal sram */
    
    #if EX_SRAM
    #define GUI_NUMBYTES  (1024*1024*24)
    #else
    #define GUI_NUMBYTES  (100*1024)
    #endif

    通过宏定义来配置使用内部SRAM还是外部的SDRAM做为emWin的动态内存,当配置:

    #define  EX_SRAM     1 表示使用外部SDRAM作为emWin动态内存,大小24MB。

    #define  EX_SRAM     0 表示使用内部SRAM作为emWin动态内存,大小100KB。

    默认情况下,本教程配套的所有emWin例子都是用外部SDRAM作为emWin动态内存。

    emWin界面显示效果:

    800*480分辨率界面效果。

     

     

    52.6 实验例程说明(裸机)

    配套例子:

    V7-567_emWin6.x实验_FrameWin框架窗口控件(裸机)

    实验目的:

    1. 本实验主要学习框架窗口控件的使用。
    2. emWin功能的实现在MainTask.c文件里面。

    emWin界面显示效果:

    800*480分辨率界面效果。

    emWin动态内存配置:

    GUIConf.c文件中的配置如下:

    #define EX_SRAM   1/*1 used extern sram, 0 used internal sram */
    
    #if EX_SRAM
    #define GUI_NUMBYTES  (1024*1024*24)
    #else
    #define GUI_NUMBYTES  (100*1024)
    #endif

    通过宏定义来配置使用内部SRAM还是外部的SDRAM做为emWin的动态内存,当配置:

    #define  EX_SRAM     1 表示使用外部SDRAM作为emWin动态内存,大小24MB。

    #define  EX_SRAM     0 表示使用内部SRAM作为emWin动态内存,大小100KB。

    默认情况下,本教程配套的所有emWin例子都是用外部SDRAM作为emWin动态内存。

    52.7 总结

    本期教程主要是跟大家讲解了框架窗口控件的使用,希望初学者可以使用GUIBulider实际创建一个例子在模拟器和开发板上面都运行下。另外,教程中只是使用了部分的框架窗口API,其它的API大家都可以试试。

    微信公众号:armfly_com 安富莱论坛:www.armbbs.cn 安富莱淘宝:https://armfly.taobao.com
  • 相关阅读:
    asp.net将图片转成二进制存入数据库
    ionic2打包生成APK报错 Error: Could not find gradle wrapper within Android SDK. Might need to update your Android SDK. Looked here: D:AndroidSDK ools emplatesgradlewrapper
    'ionic' 不是内部或外部命令,也不是可运行的程序或批处理文件。
    ABP-vs2017执行Add-Migration出现的问题
    关闭页面时,弹出JS提示框提示是否关闭
    C#生成Bar Code Image
    MemoryStream转imageSource
    RadControls RadGridView 显示加载数据时间
    RadGridView 分页控件
    CRM2011弹出asp.net模态窗口关闭的问题
  • 原文地址:https://www.cnblogs.com/armfly/p/15749099.html
Copyright © 2020-2023  润新知