• 【第3版emWin教程】第44章 emWin6.x窗口管理器官方实例简单讲解


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

    第44章       emWin6.x窗口管理器官方实例简单讲解

    为了帮助大家更好的理解窗口管理器的回调和消息机制,官方也提供了好几个这方面的例子,本章节我们将官方这几个例子也跟大家进行简单讲解,进一步帮助大家更好的学习窗口管理器。

    44.1 初学者重要提示

    44.2 官方WM_Redraw.c实例讲解

    44.3  官方WM_Sample.c实例讲解(含大量窗口API操作)

    44.4 官方WM_LateClipping.c实例讲解

    44.5 官方WM_Video.c实例讲解

    44.6 总结

    44.1 初学者重要提示

    1、  通过实例来学习emWin是最佳的学习捷径。

    2、  本章节讲解的例子中用到的部分功能还没有讲解到,但是不影响大家学习窗口管理器相关的知识。没有讲解到的知识基本都会在后面章节中跟大家讲解。

    3、  窗口管理器这块的API函数应该是emWin手册所有章节中函数最多的,以后需要用到什么功能了,查询就行,或者看官方的实例,哪个函数不理解了也可以查手册。下图是中文版手册里面API函数位置:

     

     

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

     

     

    44.2 官方WM_Redraw.c实例讲解

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

     

     

    主要功能介绍:

    这个例子与第43章43.3小节中的例子相似,分别演示桌面窗口配置了重绘操作和不配置重绘操作下,移动窗口的效果。其实不光在桌面窗口上面移动窗口要重绘,其它创建的窗口上面移动是一样的,也需要设置重绘。如果用户新窗口的窗口回调函数里面没有写重绘消息WM_PAINT,窗口管理器就会按照系统默认的颜色的进行重绘,如果用户写了WM_PAINT消息就会按照用户设置的进行重绘。

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

    #include "GUI.h"
    #include "WM.h"
    
    /*********************************************************************
    *
    *       Defines
    *
    **********************************************************************
    */
    //
    // Recommended memory to run the sample with adequate performance
    //
    #define RECOMMENDED_MEMORY (1024L * 5)
    
    /*******************************************************************
    *
    *       static code
    *
    ********************************************************************
    */
    /*******************************************************************
    *
    *       _cbBkWindow
    */
    static void _cbBkWindow(WM_MESSAGE* pMsg) {      //--------------(1)
      switch (pMsg->MsgId) {
      case WM_PAINT:
        GUI_ClearRect(0, 50, 319, 239); //--------------(2)
      default:
        WM_DefaultProc(pMsg);
      }
    }
    
    /*******************************************************************
    *
    *       _cbWindow
    */
    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);
      }
    }
    
    /*******************************************************************
    *
    *       _MoveWindow
    */
    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; i < 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();
    }
    
    /*******************************************************************
    *
    *       _DemoRedraw
    */
    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 a 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 a window over background
        //
        _MoveWindow("Background has been redrawn");
        //
        // Delete callback for Background window
        //
        WM_SetCallback(WM_HBKWIN, _cbOldBk); //--------------(12)
      }
    }
    
    /*********************************************************************
    *
    *       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;
      }
      _DemoRedraw();
    }
    1. 桌面窗口回调函数。
    2. 在桌面窗口回调函数的WM_PAINT消息中刷一块矩形区域。
    3. 另外一个新创建窗口的回调函数。
    4. 函数WM_GetInsideRect返回客户区的坐标,即实际可供用户使用的显示区。
    5. 调用函数GUI_ClearRectEx清屏一块矩形区。
    6. 函数WM_CreateWindow用来创建一个窗口,其中每个参数的含义需要大家详细研究官方手册,这里就不做解释了。
    7. 通过函数WM_MoveWindow()实现窗口位置的移动,注意这里移动的是相对距离。
    8. 删除创建的窗口。
    9. 通过函数WM_Invalidate(WM_HBKWIN)使得桌面窗口无效,然后调用函数GUI_Exec()就会通过窗口管理给桌面窗口回调函数发送WM_PAINT消息,从而执行重绘。
    10. 执行第一种情况:移动窗口,但是不做桌面窗口的重绘。
    11. 给桌面窗口设置专门的回调函数。
    12. 执行第二种情况:移动窗口,并执行桌面窗口的重绘。

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

    第一种情况:没有执行桌面回调函数的显示效果

     

     

    第二种情况:执行桌面回调函数的显示效果

     

     

    44.3 官方WM_Sample.c实例讲解(含大量窗口API操作)

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

     

     

    主要功能介绍:

    这个例子最主要的特点是将大部分窗口管理器的API函数都进行了调用,方便用户查看演示效果。如果那个函数不太会使用了,看这个例子也是比较方便。

    下面我们将这个代码分析一下,这里捡几个重要的部分跟大家讲解一下:

    44.3.1   桌面窗口回调函数自定义消息的使用

    #define MSG_CHANGE_TEXT     (WM_USER + 0) //--------------(1)
    
    /*******************************************************************
    *
    *       _ChangeInfoText
    *
    * Function description
    *   Sends a message to the background window and invalidate it, so
    *   the callback of the background window display the new text.
    */
    static void _ChangeInfoText(char * pStr) { //--------------(2)
      WM_MESSAGE Message;
    
      Message.MsgId  = MSG_CHANGE_TEXT;
      Message.Data.p = pStr;
      WM_SendMessage(WM_HBKWIN, &Message);
      WM_InvalidateWindow(WM_HBKWIN);
    }
    
    /*******************************************************************
    *
    *       _DrawInfoText
    *
    * Function description
    *   Drawes the info text directly on the display. This function is for
    *   the moments when no callback is set.
    */
    static void _DrawInfoText(char * pStr) { //--------------(3)
      GUI_SetColor(GUI_WHITE);
      GUI_SetFont(&GUI_Font24_ASCII);
      GUI_DispStringHCenterAt("WindowManager - Sample", 160, 5);
      GUI_SetFont(&GUI_Font8x16);
      GUI_DispStringAtCEOL(pStr, 5, 40);
    }
    
    /*******************************************************************
    *
    *       _cbBkWindow
    */
    static void _cbBkWindow(WM_MESSAGE * pMsg) {
      switch (pMsg->MsgId) {
      case MSG_CHANGE_TEXT: //--------------(4)
        strcpy(_acInfoText, (char const *)pMsg->Data.p); //--------------(5)
      case WM_PAINT:        //--------------(6)
        GUI_SetBkColor(GUI_BLACK);
        GUI_Clear();
        GUI_SetColor(GUI_WHITE);
        GUI_SetFont(&GUI_Font24_ASCII);
        GUI_DispStringHCenterAt("WindowManager - Sample", 160, 5);
        GUI_SetFont(&GUI_Font8x16);
        GUI_DispStringAt(_acInfoText, 5, 40);
        break;
      default:
        WM_DefaultProc(pMsg);
      }
    }

    这部分代码主要学习消息发送函数WM_SendMessage的使用,43章的43.2小节学习了无参数的消息发送函数WM_SendMessageNoPara,而函数WM_SendMessage是带参数的。

    1. 用户自定义的消息ID,使用的时候一定要以WM_USER作为起始值,防止跟系统其他的数值冲突。如果还要实现其它自定义消息,在这个数值的基础上面定义即可。
    2. 通过用户自定义的消息实现给桌面窗口的回调函数发送数据。调用了函数WM_SendMessage(WM_HBKWIN, &Message)后会给桌面窗口的回调函数发送数据,再调用了函数WM_Invalidate(WM_HBKWIN)使得桌面窗口无效,然后调用函数GUI_Delay()就会通过窗口管理给桌面窗口回调函数发送WM_PAINT消息,从而执行重绘。
    3. 文本显示函数。
    4. 用户自定义消息ID。
    5. 字符串复制,将Data.p中的数据复制到_acInfoText中。
    6. 在WM_PAINT消息中显示文本acInfoText。

    44.3.2   Redrawing部分演示

    /*******************************************************************
    *
    *       _LiftUp
    */
    static void _LiftUp(int dy) {//--------------(1)
      int i;
      int tm;
    
      for (i = 0; i < (dy/4); i++) {
        tm = GUI_GetTime();
        WM_MoveWindow(_hWindow1, 0, -4);
        WM_MoveWindow(_hWindow2, 0, -4);
        while ((GUI_GetTime() - tm) < 20) {
          WM_Exec();
        }
      }
    }
    
    /*******************************************************************
    *
    *       _LiftDown
    */
    static void _LiftDown(int dy) { //--------------(2)
      int i;
      int tm;
    
      for (i = 0; i < (dy/4); i++) {
        tm = GUI_GetTime();
        WM_MoveWindow(_hWindow1, 0, 4);
        WM_MoveWindow(_hWindow2, 0, 4);
        while ((GUI_GetTime() - tm) < 20) {
          WM_Exec();
        }
      }
    }
    
    /*******************************************************************
    *
    *       _DemoRedrawing
    *
    * Function description
    *   Demonstrates how useful can be a callback
    */
    static void _DemoRedrawing(void) {
      int i;
      int tm;
      int tDiff;
    
      _ChangeInfoText("Demonstrating redrawing");
      GUI_Delay(SPEED);
      _LiftUp(40);
      GUI_Delay(SPEED/3);
      _ChangeInfoText("Using a callback for redrawing");
      GUI_Delay(SPEED/3);
      for (i = 0; i < 55; i++) {
        tm = GUI_GetTime();
        WM_MoveWindow(_hWindow1,  1,  1);
        WM_MoveWindow(_hWindow2, -1, -1);
        tDiff = 15 - (GUI_GetTime() - tm);
        GUI_Delay(tDiff);
      }
      for (i = 0; i < 55; i++) {
        tm = GUI_GetTime();
        WM_MoveWindow(_hWindow1, -1, -1);
        WM_MoveWindow(_hWindow2,  1,  1);
        tDiff = 15 - (GUI_GetTime() - tm);
        GUI_Delay(tDiff);
      }
      GUI_Delay(SPEED/4);
      _LiftDown(30);
      GUI_Delay(SPEED/2);
      _ChangeInfoText("Without redrawing");
      GUI_Delay(SPEED);
      _LiftUp(30);
      GUI_Delay(SPEED/4);
      WM_SetCallback(WM_HBKWIN, _cbBkWindowOld);
      for (i = 0; i < 55; i++) {
        tm = GUI_GetTime();
        WM_MoveWindow(_hWindow1,  1,  1);
        WM_MoveWindow(_hWindow2, -1, -1);
        tDiff = 15 - (GUI_GetTime() - tm);
        GUI_Delay(tDiff);
      }
      for (i = 0; i < 55; i++) {
        tm = GUI_GetTime();
        WM_MoveWindow(_hWindow1, -1, -1);
        WM_MoveWindow(_hWindow2,  1,  1);
        tDiff = 15 - (GUI_GetTime() - tm);
        GUI_Delay(tDiff);
      }
      GUI_Delay(SPEED/3);
      WM_SetCallback(WM_HBKWIN, _cbBkWindow);
      _LiftDown(40);
      GUI_Delay(SPEED);
    }

    这部分代码实现了两个窗口在具有重绘和不具有重绘功能时的演示,还有一个重点是学习窗口移动函数WM_MoveWindow的使用,这个函数是实现相对移动,相对于窗口当前所在的位置。另外还一个窗口移动函数WM_MoveTo是绝对位置移动,设置移动到那个坐标点就移动到那个坐标点。

    1. 实现两个窗口向上移动。
    2. 实现两个窗口向下移动。

    显示效果如下:

     

     

    44.3.3   Resize部分演示

    /*******************************************************************
    *
    *       _DemoResizeWindow
    *
    * Function description
    *   Demonstrates the use of WM_ResizeWindow
    */
    static void _DemoResizeWindow(void) {
      int i;
      int tm;
      int tDiff;
    
      _ChangeInfoText("WM_ResizeWindow()");
      GUI_Delay(SPEED);
      _LiftUp(30);
      for (i = 0; i < 20; i++) {
        tm = GUI_GetTime();
        WM_ResizeWindow(_hWindow1,  1,  1);
        WM_ResizeWindow(_hWindow2, -1, -1);
        tDiff = 15 - (GUI_GetTime() - tm);
        GUI_Delay(tDiff);
      }
      for (i = 0; i < 40; i++) {
        tm = GUI_GetTime();
        WM_ResizeWindow(_hWindow1, -1, -1);
        WM_ResizeWindow(_hWindow2,  1,  1);
        tDiff = 15 - (GUI_GetTime() - tm);
        GUI_Delay(tDiff);
      }
      for (i = 0; i < 20; i++) {
        tm = GUI_GetTime();
        WM_ResizeWindow(_hWindow1,  1,  1);
        WM_ResizeWindow(_hWindow2, -1, -1);
        tDiff = 15 - (GUI_GetTime() - tm);
        GUI_Delay(tDiff);
      }
      _LiftDown(30);
      GUI_Delay(SPEED);
    }

    这部分演示主要看窗口加大和减小函数WM_ResizeWindow()的使用,注意这个函数是对窗口的显示大小进行加大和减小,并不是进行放缩,显示效果如下:

     

     

    44.4 官方WM_LateClipping.c实例讲解

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

     

    主要功能介绍:

    这个例子依然主要演示回调函数的重绘机制,作为重绘机制方面的学习,比较有参考价值。

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

    #include "GUI.h"
    #include "WM.h"
    #include "FRAMEWIN.h"
    #include "BUTTON.h"
    
    /*********************************************************************
    *
    *       Defines
    *
    **********************************************************************
    */
    //
    // Recommended memory to run the sample with adequate performance
    //
    #define RECOMMENDED_MEMORY (1024L * 5)
    
    /*********************************************************************
    *
    *       Static data
    *
    **********************************************************************
    */
    static WM_HWIN _hWin1;
    static WM_HWIN _hWin2;
    static WM_HWIN _hBut1;
    static WM_HWIN _hBut2;
    static int     _PaintCount1;
    static int     _PaintCount2;
    
    static GUI_COLOR _aColors[] = {
      0x0000FF, 0x00FF00, 0xFF0000, 0x00FFFF, 0xA000A0, 0xFFFF00
    };
    
    /*********************************************************************
    *
    *       Static code
    *
    **********************************************************************
    */
    /*********************************************************************
    *
    *       _cbBkWin
    */
    static void _cbBkWin(WM_MESSAGE* pMsg) { //--------------(1)
      switch(pMsg->MsgId) {
      case WM_PAINT:     //--------------(2)
        GUI_SetBkColor(GUI_BLACK);
        GUI_Clear();
        GUI_SetColor(0x0060FF);
        GUI_DispStringAt("PaintCount (Early):", 0, 0);
        GUI_DispDecAt(_PaintCount1, 120, 0, 5);
        GUI_SetColor(0x00FFC0);
        GUI_DispStringAt("PaintCount (Late):", 0, 12);
        GUI_DispDecAt(_PaintCount2, 120, 12, 5);
        break;
      case WM_NOTIFY_PARENT:
        if (pMsg->Data.v == WM_NOTIFICATION_RELEASED) {
          if (pMsg->hWinSrc == _hBut1) { //--------------(3)
            WM_InvalidateWindow(_hWin1);
            WM_InvalidateWindow(_hWin2);
          } else if (pMsg->hWinSrc == _hBut2) { //--------------(4)
            _PaintCount1 = 0;
            _PaintCount2 = 0;
            WM_InvalidateWindow(pMsg->hWin);
          }
        }
        break;
      default:
        WM_DefaultProc(pMsg);
      }
    }
    
    /*********************************************************************
    *
    *       _cbTop
    */
    static void _cbTop(WM_MESSAGE* pMsg) { //--------------(5)
      switch(pMsg->MsgId) {
      case WM_PAINT:
        GUI_SetBkColor(GUI_MAGENTA);
        GUI_Clear();
        break;
      default:
        WM_DefaultProc(pMsg);
      }
    }
    
    /*********************************************************************
    *
    *       _cbFrameWin1
    */
    static void _cbFrameWin1(WM_MESSAGE* pMsg) { //--------------(6)
      switch(pMsg->MsgId) {
      case WM_PAINT:
        GUI_SetBkColor(_aColors[_PaintCount1 % 6]);
        GUI_Clear();
        GUI_SetColor(0x0060FF);
        GUI_FillCircle(25, 25, 15);
        GUI_SetColor(GUI_BLACK);
        GUI_DrawCircle(25, 25, 15);
        _PaintCount1++;
        WM_InvalidateWindow(WM_HBKWIN);
        break;
      default:
        WM_DefaultProc(pMsg);
      }
    }
    
    /*********************************************************************
    *
    *       _cbFrameWin2
    */
    static void _cbFrameWin2(WM_MESSAGE* pMsg) { //--------------(7)
      switch(pMsg->MsgId) {
      case WM_PAINT:
        GUI_SetBkColor(_aColors[_PaintCount2 % 6]);
        GUI_Clear();
        GUI_SetColor(0x00FFC0);
        GUI_FillCircle(25, 25, 15);
        GUI_SetColor(GUI_BLACK);
        GUI_DrawCircle(25, 25, 15);
        _PaintCount2++;
        WM_InvalidateWindow(WM_HBKWIN);
        break;
      default:
        WM_DefaultProc(pMsg);
      }
    }
    
    /*********************************************************************
    *
    *       _ShowDemo
    */
    static void _ShowDemo(void) {
      WM_HWIN hWin0;
      WM_HWIN hWin1;
      WM_HWIN hWin2;
      WM_HWIN hFrame1;
      WM_HWIN hFrame2;
      WM_HWIN hClient1;
      WM_HWIN hClient2;
    
      WM_SetCallback(WM_HBKWIN, _cbBkWin); //--------------(8)
      hFrame1  = FRAMEWIN_CreateEx( 10, 30, 140, 140, 0, WM_CF_SHOW, FRAMEWIN_CF_MOVEABLE, 0, "Early Clipping", _cbFrameWin1);
      hFrame2  = FRAMEWIN_CreateEx(170, 30, 140, 140, 0, WM_CF_SHOW, FRAMEWIN_CF_MOVEABLE, 0, "Late Clipping",
     _cbFrameWin2);
      hClient1 = WM_GetClientWindow(hFrame1);
      hClient2 = WM_GetClientWindow(hFrame2);
      _hWin1  = WM_CreateWindowAsChild(0, 0, WM_GetWindowSizeX(hClient1), WM_GetWindowSizeY(hClient1), hClient1,
     WM_CF_SHOW, _cbFrameWin1, 0);
      _hWin2  = WM_CreateWindowAsChild(0, 0, WM_GetWindowSizeX(hClient2), WM_GetWindowSizeY(hClient2), hClient2,
     WM_CF_SHOW | WM_CF_LATE_CLIP, _cbFrameWin2, 0);
      _hBut1  = BUTTON_CreateEx(10, 210, 140, 20, 0, WM_CF_SHOW, 0, 1);
      _hBut2  = BUTTON_CreateEx(170, 210, 140, 20, 0, WM_CF_SHOW, 0, 2);
      hWin0 = FRAMEWIN_CreateEx(60,  80, 40, 40, 0, WM_CF_SHOW | WM_CF_STAYONTOP, FRAMEWIN_CF_MOVEABLE, 0, "Top 0",
     _cbTop);
      hWin1 = FRAMEWIN_CreateEx(220, 80, 40, 40, 0, WM_CF_SHOW | WM_CF_STAYONTOP, FRAMEWIN_CF_MOVEABLE, 0, "Top 1",
     _cbTop);
      hWin2 = FRAMEWIN_CreateEx(140,170, 40, 40, 0, WM_CF_SHOW | WM_CF_STAYONTOP, FRAMEWIN_CF_MOVEABLE, 0, "Top 2",
     _cbTop);
      FRAMEWIN_SetResizeable(hWin0, 1);
      FRAMEWIN_SetResizeable(hWin1, 1);
      FRAMEWIN_SetResizeable(hWin2, 1);
      BUTTON_SetText(_hBut1, "Invalidate");
      BUTTON_SetText(_hBut2, "Reset counters");
      while(1) {
        GUI_Delay(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;
      }
      while(1) {
        _ShowDemo();
      }
    }

    1、桌面窗口回调函数。

    2、桌面窗口回调函数中重绘消息WM_PAINT。

    3、由于两个按钮是创建在桌面窗口上面的,所以按钮的WM_NOTIFICATION_RELEASED(通知代码消息类型)是在桌面窗口的回调函数中。这个按钮按下后将窗口_hWin1和窗口_hWin2无效,从而会执行这两个窗口的背景重绘功能。

    4、同上,只不过这里实现的功能是将两个计数值清零,并使桌面窗口无效,从而执行桌面窗口的重绘消息。

    5、此函数同时是hWin0,hWin1,hWin2三个框架窗口的回调函数。

    6、此函数是框架窗口hFrame1的回调函数,回调函数中主要实现了重绘消息,重绘消息中记录了重绘的次数,并根据重绘次数修改背景颜色。

    7、此函数是框架窗口hFrame2的回调函数,回调函数中主要实现了重绘消息,重绘消息中记录了重绘的次数,并根据重绘次数修改背景颜色。

    8、(1) 先创建两个框架窗口hFrame1和hFrame2。

    (2) 分别在这两个框架窗口中创建两个子窗口_hWin1和_hWin2。

    (3) 创建两个按钮_hBut1和_hBut2。

    (4) 创建三个框架窗口hWin0,hWin1和hWin2。

    这个例子对于研究回调函数函数还是非常好的,大家可以在这个例子的基础上做一些修改,实现一些功能,显示效果如下:

     

     

    44.5 官方WM_Video.c实例讲解

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

     

     

    主要功能介绍:

     这个例子主要演示框架窗口的创建,删除,隐藏和显示,关于框架窗口暂时还没有讲到,后面章节会专门讲解,跟普通窗口差不多,只是多了一个标题栏,所以将其放在本章节进行讲解也是可以的,用来学习窗口相关的API函数操作。

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

    #include <stddef.h>
    #include <stdio.h>
    
    #include "WM.h"
    #include "GUI.h"
    #include "FRAMEWIN.h"
    #include "BUTTON.h"
    #include "TEXT.h"
    
    static void _cbFrameWinTest(WM_MESSAGE * pMsg);
    
    /*********************************************************************
    *
    *       Defines
    *
    **********************************************************************
    */
    #define MAX_WINDOWS   50
    
    //
    // Recommended memory to run the sample with adequate performance
    //
    #define RECOMMENDED_MEMORY (1024L * 5)
    
    /*********************************************************************
    *
    *       Static data
    *
    **********************************************************************
    */
    
    static WM_HWIN _ahWin[MAX_WINDOWS];
    static char    _IsCompletelyVis;
    
    /*********************************************************************
    *
    *       Static code
    *
    **********************************************************************
    */
    /*********************************************************************
    *
    *       _CreateWindow
    */
    static void _CreateWindow(void) {  //--------------(1)
      unsigned i;
      WM_HWIN  hWin;
      char     ac[32];
      int      j;
    
      for (i = 0; i < MAX_WINDOWS; i++) {
        if (_ahWin[i] == 0) {
          j = i + 1;
          sprintf(ac, "Test window %d", j);
          hWin = FRAMEWIN_CreateEx(5 + 10 * i, 135 + 10 * i, 120, 60, 0, WM_CF_SHOW, FRAMEWIN_CF_MOVEABLE, 0, ac,
     _cbFrameWinTest);
          FRAMEWIN_SetClientColor(hWin, GUI_INVALID_COLOR);
          _ahWin[i] = hWin;
          break;
        }
      }
    }
    
    /*********************************************************************
    *
    *       _DeleteWindow
    */
    static void _DeleteWindow(void) {  //--------------(2)
      unsigned i;
    
      for (i = 0; i < MAX_WINDOWS; i++) {
        if (WM_IsVisible(_ahWin[i])) {
          WM_DeleteWindow(_ahWin[i]);
          _ahWin[i] = 0;
          break;
        }
      }
    }
    
    /*********************************************************************
    *
    *       _ShowWindow
    */
    static void _ShowWindow(void) {  //--------------(3)
      unsigned i;
    
      for (i = 0; i < MAX_WINDOWS; i++) {
        if (_ahWin[i] != 0) {
          if (WM_IsVisible(_ahWin[i]) == 0) {
            WM_ShowWindow(_ahWin[i]);
            break;
          }
        }
      }
    }
    
    /*********************************************************************
    *
    *       _HideWindow
    */
    static void _HideWindow(void) {  //--------------(4)
      unsigned i;
    
      for (i = 0; i < MAX_WINDOWS; i++) {
        if (WM_IsVisible(_ahWin[i])) {
          WM_HideWindow(_ahWin[i]);
          break;
        }
      }
    }
    
    /*********************************************************************
    *
    *       Static code, callbacks
    *
    **********************************************************************
    */
    /*********************************************************************
    *
    *       _cbBkWin
    */
    static void _cbBkWin(WM_MESSAGE* pMsg) {  //--------------(5)
      int Id;
    
      switch (pMsg->MsgId) {
      case WM_PAINT:
        GUI_SetBkColor(GUI_BLACK);
        GUI_Clear();
        break;
      case WM_NOTIFY_PARENT:
        if (pMsg->Data.v == WM_NOTIFICATION_RELEASED) {
          Id = WM_GetId(pMsg->hWinSrc);
          switch (Id) {
          case GUI_ID_BUTTON0:
            _CreateWindow();
            break;
          case GUI_ID_BUTTON1:
            _DeleteWindow();
            break;
          case GUI_ID_BUTTON2:
            _ShowWindow();
            break;
          case GUI_ID_BUTTON3:
            _HideWindow();
            break;
          }
        }
        break;
      default:
        WM_DefaultProc(pMsg);
      }
    }
    
    /*********************************************************************
    *
    *       _cbFrameWinVideo
    */
    static void _cbFrameWinVideo(WM_MESSAGE* pMsg) {  //--------------(6)
      WM_HWIN hWin;
      WM_HWIN hText;
      int     IsCompletelyVis;
      int     IsCompletelyCovered;
    
      switch (pMsg->MsgId) {
      case WM_PAINT:
        if (_IsCompletelyVis) {
          GUI_SetBkColor(GUI_DARKGREEN);
          GUI_Clear();
          GUI_SetColor(GUI_WHITE);
          GUI_DispStringAt("Completely visible", 5, 5);
        } else {
          GUI_SetBkColor(GUI_GRAY);
          GUI_Clear();
          GUI_SetColor(GUI_WHITE);
          GUI_DispStringAt("Not completely visible", 5, 5);
        }
        break;
      case WM_NOTIFY_VIS_CHANGED:
        hText = WM_GetDialogItem(WM_HBKWIN, GUI_ID_TEXT1);
        hWin  = WM_GetClientWindow(pMsg->hWin);
        IsCompletelyVis     = WM_IsCompletelyVisible(hWin);
        IsCompletelyCovered = WM_IsCompletelyCovered(hWin);
        if (IsCompletelyCovered) {
          TEXT_SetText(hText, "completely
    covered");
        } else {
          TEXT_SetText(hText, "not completely
    covered");
        }
        if (_IsCompletelyVis != IsCompletelyVis) {
          _IsCompletelyVis = IsCompletelyVis;
          WM_InvalidateWindow(hWin);    /* Only required if content changes if partially hidden */
        }
        break;
      default:
        WM_DefaultProc(pMsg);
      }
    }
    
    /*********************************************************************
    *
    *       _cbFrameWinTest
    */
    static void _cbFrameWinTest(WM_MESSAGE* pMsg) {  //--------------(7)
      switch (pMsg->MsgId) {
      case WM_PAINT:
        GUI_SetBkColor(GUI_DARKRED);
        GUI_Clear();
        break;
      default:
        WM_DefaultProc(pMsg);
      }
    }
    
    /*********************************************************************
    *
    *       Public code
    *
    **********************************************************************
    */
    /*********************************************************************
    *
    *       MainTask
    */
    void MainTask(void) {
      FRAMEWIN_Handle hWinVideo;
      BUTTON_Handle   hBut;
      WM_HWIN         hText;
    
      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_SetCallback(WM_HBKWIN, _cbBkWin); 
      //--------------(8)
      hText = TEXT_CreateEx(240,  85, 80, 26, WM_HBKWIN, WM_CF_SHOW, 0, GUI_ID_TEXT0, "The client
    window is");
      TEXT_SetTextColor(hText, GUI_WHITE);
      hText = TEXT_CreateEx(240, 111, 80, 26, WM_HBKWIN, WM_CF_SHOW, 0, GUI_ID_TEXT1, NULL);
      TEXT_SetTextColor(hText, GUI_WHITE);
      //
      // Create buttons
      //
      hBut = BUTTON_CreateEx(240,  5, 75, 18, WM_HBKWIN, WM_CF_SHOW, 0, GUI_ID_BUTTON0);
      BUTTON_SetText(hBut, "Create win");
      hBut = BUTTON_CreateEx(240, 25, 75, 18, WM_HBKWIN, WM_CF_SHOW, 0, GUI_ID_BUTTON1);
      BUTTON_SetText(hBut, "Delete win");
      hBut = BUTTON_CreateEx(240, 45, 75, 18, WM_HBKWIN, WM_CF_SHOW, 0, GUI_ID_BUTTON2);
      BUTTON_SetText(hBut, "Show win");
      hBut = BUTTON_CreateEx(240, 65, 75, 18, WM_HBKWIN, WM_CF_SHOW, 0, GUI_ID_BUTTON3);
      BUTTON_SetText(hBut, "Hide win");
      //
      // Create framewin video
      //  
      hWinVideo = FRAMEWIN_CreateEx(5, 5, 170, 120, 0, WM_CF_SHOW, FRAMEWIN_CF_MOVEABLE, 0, "Video window", 
    _cbFrameWinVideo);
      FRAMEWIN_SetClientColor(hWinVideo, GUI_INVALID_COLOR);
      //
      // Create test windows
      //
      _CreateWindow();
      _CreateWindow();
      _CreateWindow();
      while (1) {
        GUI_Delay(1000);
      }
    }

    1、创建FrameWin。

    2、删除FrameWin,主要是函数WM_DeleteWindow的使用。

    3、显示FrameWin,主要是函数WM_IsVisible和WM_ShowWindow的使用。

    4、隐藏FrameWin,主要是函数WM_HideWindow的使用。

    5、桌面窗口回调函数,主要看WM_NOTIFY_PARENT消息,进入后再分为4个button的消息,分别实现框架窗口的创建,删除,显示和隐藏。

    6、框架窗口FrameVideo的回调函数。

    7、函数_CreateWindow里面所创建框架窗口的回调函数。

    8、(1)创建两个文本控件。

    (2)创建四个按钮,分别实现创建,删除,显示和隐藏窗口。

    (3)创建框架窗口hWinVideo。

    这个例子相对要简单很多,下面是这个例子的实际显示效果:

     

     

    44.6 总结

    本期教程就跟大家讲这么多,官方提供的这几个例子还是比较有参考价值的,希望初学者把这几个例子研究下,并在模拟器或者开发板上面多做这方面的练习。

    微信公众号:armfly_com 安富莱论坛:www.armbbs.cn 安富莱淘宝:https://armfly.taobao.com
  • 相关阅读:
    跳跃游戏
    不同路径
    最大子序和
    最长回文子序列
    最长公共子序列
    零钱兑换
    合并区间
    寻找数组的中心索引
    制造小程序中的一些经验
    h5写的一个签到积分系统
  • 原文地址:https://www.cnblogs.com/armfly/p/15347728.html
Copyright © 2020-2023  润新知