1. 程式人生 > 其它 >【第3版emWin教程】第55章 emWin6.x按鈕Button控制元件自定義回撥函式,實現各種按鈕效果

【第3版emWin教程】第55章 emWin6.x按鈕Button控制元件自定義回撥函式,實現各種按鈕效果

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

第55章 emWin6.x按鈕Button控制元件自定義回撥函式,實現各種按鈕效果

本章節為大家講解按鈕控制元件自定義回撥函式,通過其回撥函式就可以實現各種按鈕效果。這方面的問題也是經常有初學者問,所以專門做一期教程。

55.1初學者重要提示

55.2 按鈕控制元件自定義回撥函式的實現方法

55.3 官方WIDGET_ButtonRound.c例項講解

55.4 實驗例程說明(RTOS)

55.5 實驗例程說明(裸機)

55.6 總結

55.1 初學者重要提示

  1. 很多時候,我們希望設計出不同效果的按鈕出來,比如做一個音樂播放器介面將快進,快退,暫停,開始等都通過按鈕來實現,這個時候時候按鈕的自定義回撥函式就派上用場了。希望初學者掌握這個重要的知識點。不僅僅是按鈕控制元件,後面要講解到的其它控制元件都是可以設定自定義回撥函式。
  2. 按鈕控制元件的所有API函式在emWin手冊中都有講解,下圖是中文版手冊裡面API函式位置:

下圖是英文版手冊裡面API函式的位置:

55.2 按鈕控制元件自定義回撥函式的實現方法

按鈕控制元件的本質也是視窗,所以也是有回撥函式的,只是被封裝了,使用者看不到,不像我們使用視窗或者框架視窗的時候還需要專門的設定回撥函式。

實現自定義回撥函式的關鍵就是函式WM_SetCallback,通過這個函式就可以重定向按鈕的回撥函式,從而也就可以實現各種效果的按鈕。下面我們通過一個例項給大家介紹如何實現按鈕控制元件的自定義回撥函式。完整程式碼在例子在本章教程配置的例子裡面:

#include "
DIALOG.h" /* ********************************************************************************************************* * 圖片點陣圖資料 ********************************************************************************************************* */ static GUI_CONST_STORAGE unsigned long
_acpic1[] = { 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, 0xFF000000, /* 後面的資料未列出 */ }; GUI_CONST_STORAGE GUI_BITMAP bmpic1 = { 64, // xSize 64, // ySize 256, // BytesPerLine 32, // BitsPerPixel (unsigned char *)_acpic1, // Pointer to picture data NULL, // Pointer to palette GUI_DRAW_BMP8888 } /* ********************************************************************************************************* * 巨集定義 ********************************************************************************************************* */ #define ID_FRAMEWIN_0 (GUI_ID_USER + 0x00) #define ID_BUTTON_0 (GUI_ID_USER + 0x01) #define ID_BUTTON_1 (GUI_ID_USER + 0x02) /* ********************************************************************************************************* * GUI_WIDGET_CREATE_INFO型別陣列 ********************************************************************************************************* */ static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = { { FRAMEWIN_CreateIndirect, "Framewin", ID_FRAMEWIN_0, 0, 0, 800, 480, 0, 0x64, 0 }, { BUTTON_CreateIndirect, "", ID_BUTTON_0, 30, 30, 64, 64, 0, 0x0, 0 }, { BUTTON_CreateIndirect, "", ID_BUTTON_1, 30, 120, 120, 40, 0, 0x0, 0 }, }; /* ********************************************************************************************************* * 函 數 名: _cbButton * 功能說明: 按鈕回撥函式 * 形 參: pMsg 訊息指標 * 返 回 值: 無 ********************************************************************************************************* */ static void _cbButton(WM_MESSAGE * pMsg) //--------------(3) { WM_HWIN hWin; hWin = pMsg->hWin; switch (pMsg->MsgId) { case WM_PAINT: if (BUTTON_IsPressed(hWin)) { GUI_SetBkColor(GUI_WHITE); GUI_Clear(); GUI_SetAlpha(0xb0); GUI_DrawBitmap(&bmpic1, 0,0); GUI_SetAlpha(0); } else { GUI_DrawBitmap(&bmpic1, 0, 0); } break; default: BUTTON_Callback(pMsg); } } /* ********************************************************************************************************* * 函 數 名: _cbButton1 * 功能說明: 按鈕回撥函式 * 形 參: pMsg 訊息指標 * 返 回 值: 無 ********************************************************************************************************* */ static void _cbButton1(WM_MESSAGE * pMsg) //--------------(6) { WM_HWIN hWin; GUI_RECT Rect; hWin = pMsg->hWin; switch (pMsg->MsgId) { case WM_PAINT: WM_GetClientRect(&Rect); if (BUTTON_IsPressed(hWin)) { GUI_SetColor(GUI_DARKGRAY); GUI_FillRoundedRect(Rect.x0, Rect.y0, Rect.x1, Rect.y1, 5); GUI_SetBkColor(GUI_DARKGRAY); GUI_SetColor(GUI_WHITE); } else { GUI_SetColor(GUI_LIGHTBLUE); GUI_FillRoundedRect(Rect.x0, Rect.y0, Rect.x1, Rect.y1, 5); GUI_SetBkColor(GUI_LIGHTBLUE); GUI_SetColor(GUI_WHITE); } GUI_SetFont(&GUI_Font16_ASCII); GUI_DispStringInRect("LED1", &Rect, GUI_TA_HCENTER | GUI_TA_VCENTER); break; default: BUTTON_Callback(pMsg); } } /* ********************************************************************************************************* * 函 數 名: _cbDialog * 功能說明: 對話方塊回撥函式 * 形 參: pMsg 回撥引數 * 返 回 值: 無 ********************************************************************************************************* */ static void _cbDialog(WM_MESSAGE * pMsg) { WM_HWIN hItem; int NCode; int Id; switch (pMsg->MsgId) { case WM_INIT_DIALOG: // // 初始化框架視窗 // hItem = pMsg->hWin; FRAMEWIN_SetFont(hItem, GUI_FONT_32B_ASCII); FRAMEWIN_SetTextAlign(hItem, GUI_TA_HCENTER | GUI_TA_VCENTER); FRAMEWIN_SetText(hItem, "armfly"); // // 初始化按鈕控制元件 // hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_0); WM_SetHasTrans(hItem); //--------------(1) WM_SetCallback(hItem, _cbButton); //--------------(2) // // 初始化按鈕控制元件 // hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_1); WM_SetHasTrans(hItem); //--------------(4) WM_SetCallback(hItem, _cbButton1); //--------------(5) break; case WM_NOTIFY_PARENT: Id = WM_GetId(pMsg->hWinSrc); NCode = pMsg->Data.v; switch(Id) { case ID_BUTTON_0: switch(NCode) { case WM_NOTIFICATION_CLICKED: break; case WM_NOTIFICATION_RELEASED: break; } break; } break; default: WM_DefaultProc(pMsg); break; } } /* ********************************************************************************************************* * 函 數 名: CreateFramewin * 功能說明: 建立對話方塊 * 形 參: 無 * 返 回 值: 返回對話方塊控制代碼 ********************************************************************************************************* */ WM_HWIN CreateFramewin(void) { WM_HWIN hWin; hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0); return hWin; } /* ********************************************************************************************************* * 函 數 名: MainTask * 功能說明: GUI主函式 * 形 參: 無 * 返 回 值: 無 ********************************************************************************************************* */ void MainTask(void) { /* 初始化 */ GUI_Init(); /* 視窗自動使用儲存裝置 */ WM_SetCreateFlags(WM_CF_MEMDEV); /* 建立對話方塊,使用GUIBulder生成的對話方塊建立函式 */ CreateFramewin(); while(1) { GUI_Delay(10); } }

這個例子在對話方塊上建立了2個按鈕控制元件,每個按鈕都重新設定了回撥函式,實現了兩種不同的按鈕效果,一個是圖示按鈕,另一個是扁平化效果的按鈕。

1、通過函式WM_SetHasTrans設定ID為ID_BUTTON_0的按鈕控制元件的透明效果,呼叫了這個函式有什麼用呢?通過這個函式就可以將按鈕回撥函式中WM_PAINT訊息沒有重繪到的區域顯示為完全透明,比如我們在按鈕控制元件回撥函式的WM_PAINT訊息裡面繪製了一個填充的圓圈,那麼按鈕控制元件所在區域的圓圈以外部分就是完全透明的。

2、通過函式WM_SetCallback重新設定ID為ID_BUTTON_0的按鈕控制元件的回撥函式。

3、通過此回撥函式就可以設定各種效果的按鈕了,這裡是將按鈕設定成一個圖示。這個回撥函式只有兩個訊息,一個是WM_PAINT,一個是預設的default,也就是說除了WM_PAINT訊息以外,其它所有訊息還是使用按鈕控制元件預設的回撥處理機制BUTTON_Callback來實現。這個問題解釋清楚了,剩下就是WM_PAINT訊息裡面實現的功能了,這個訊息裡面實現了按鈕按下和未按下兩種狀態的顯示效果,通過函式BUTTON_IsPressed來區分這兩種狀態,返回1就是按下了,返回0就是未按下。

/* 
按下狀態,按下後,我們通過函式GUI_SetAlpha設定圖片顯示出來的透明效果,
這樣就將按下和未按下兩種狀態區分開了。
*/
if (BUTTON_IsPressed(hWin)) 
{
/* 
先將按鈕顯示區清為白色,清為白色是因為按鈕所在的對話方塊客戶端視窗背景色是白色的 
       另一個作用是背景圖片是要跟這個白色區域做alpha融合,所以要清成白色。
*/
    GUI_SetBkColor(GUI_WHITE);
    GUI_Clear();
     /* 設定圖片的透明程度是0xb0,設定為0xFF表示完全透明,0x00表示完全不透明 */
    GUI_SetAlpha(0xb0);
    GUI_DrawBitmap(&bmpic1, 0,0);
     /* 顯示完畢圖片後設置為預設的完全不透明 */
    GUI_SetAlpha(0);        
} 
/* 未按下狀態,顯示一個圖示 */
else 
{
    GUI_DrawBitmap(&bmpic1, 0, 0);        
}

通過上面的程式碼就實現了按鈕未按下時顯示的是一個圖示,按下時是一個有透明效果的圖示。

4、通過函式WM_SetHasTrans設定ID為ID_BUTTON_1的按鈕控制元件的透明效果。

5、通過函式WM_SetCallback重新設定ID為ID_BUTTON_1的按鈕控制元件的回撥函式。

6、通過此回撥函式就可以設定各種效果的按鈕了,這裡是將按鈕設定成圓角矩形。這裡我們重點看WM_PAINT訊息,其它跟第3條講解的是一樣的。

/* 獲取按鈕的顯示區座標,即左上角座標和右下角座標 */
WM_GetClientRect(&Rect);

/* 按下狀態,*/
if (BUTTON_IsPressed(hWin)) 
{
     /* 設定前景色用於繪製圓角矩形 */
    GUI_SetColor(GUI_DARKGRAY);
     /* 圓角矩形繪製函式 */
    GUI_FillRoundedRect(Rect.x0, Rect.y0, Rect.x1, Rect.y1, 5);
    /* 設定背景色和前景色用於函式GUI_DispStringInRect 顯示文字LED1使用 */
    GUI_SetBkColor(GUI_DARKGRAY);
    GUI_SetColor(GUI_WHITE); 
} 
/* 未按下狀態  */
else 
{
/* 設定前景色用於繪製圓角矩形 */
    GUI_SetColor(GUI_LIGHTBLUE);
     /* 圓角矩形繪製函式 */
    GUI_FillRoundedRect(Rect.x0, Rect.y0, Rect.x1, Rect.y1, 5);
     /* 設定背景色和前景色用於函式GUI_DispStringInRect 顯示文字LED1使用 */
    GUI_SetBkColor(GUI_LIGHTBLUE);
    GUI_SetColor(GUI_WHITE);   
}
/* 設定文字顯示字型 */
GUI_SetFont(&GUI_Font16_ASCII);
/* 將文字顯示到按鈕區域的垂直居中和水平居中 */
GUI_DispStringInRect("LED1", &Rect, GUI_TA_HCENTER | GUI_TA_VCENTER);

通過上面的程式碼就實現了按鈕未按下和按下時兩種不同的按鈕顏色。實際顯示效果如下,解析度800*480:

通過學習這個例項,建議大家嘗試設定各種其它的按鈕顯示效果。

55.3 官方WIDGET_ButtonRound.c例項講解

這個DEMO在模擬器中的位置:

主要功能介紹:

這個例子演示了按鈕自定義回撥函式的實現,通過其回撥函式實現了一個圓形的按鈕,由於是官方做的例子,所以細節的處理上更專業些。學習這個例子前務必先學習前面47.2小節的講解。

程式程式碼如下:

#include <stddef.h>
#include <string.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 int _Color;
static int _Font;
static int _Pressed;

static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
  { FRAMEWIN_CreateIndirect, "Round button sample", 0,      50,  60, 200, 120, FRAMEWIN_CF_MOVEABLE },
  { BUTTON_CreateIndirect,   "Button",   GUI_ID_BUTTON0,   100,  10,  80,  80 },
  { BUTTON_CreateIndirect,   "Callback", GUI_ID_BUTTON1,    10,  10,  60,  20 },
  { BUTTON_CreateIndirect,   "Font",     GUI_ID_BUTTON2,    10,  30,  60,  20 },
  { BUTTON_CreateIndirect,   "Color",    GUI_ID_BUTTON3,    10,  50,  60,  20 },
  { BUTTON_CreateIndirect,   "Cancel",   GUI_ID_CANCEL,     10,  70,  60,  20 }
};

/*********************************************************************
*
*       Static functions
*
**********************************************************************
*/
/*********************************************************************
*
*       _OnPaint
*
* Function description
*   Paints the owner drawn button
*/
static void _OnPaint(BUTTON_Handle hObj) { //--------------(1)
  int Index;
  char ac[50];
  GUI_RECT Rect;

  Index = (WIDGET_GetState(hObj) & BUTTON_STATE_PRESSED) ? 1 : 0; //--------------(2)
  WM_GetClientRect(&Rect); 
  //
  // Draw filled ellipse with button background color
  //
  GUI_SetColor(BUTTON_GetBkColor(hObj, Index));
  GUI_FillEllipse(Rect.x1 / 2, Rect.y1 / 2, Rect.x1 / 2, Rect.y1 / 2);
  //
  // Draw black shape
  //
  GUI_SetColor(GUI_BLACK);
  GUI_DrawEllipse(Rect.x1 / 2, Rect.y1 / 2, Rect.x1 / 2, Rect.y1 / 2);
  //
  // Draw button text with widget attributes
  //
  GUI_SetColor(BUTTON_GetTextColor(hObj, Index));
  GUI_SetBkColor(BUTTON_GetBkColor(hObj, Index));
  GUI_SetFont(BUTTON_GetFont(hObj));
  BUTTON_GetText(hObj, ac, sizeof(ac));
  if (_Pressed) {                              //--------------(3)
    strcpy(ac + strlen(ac), "\npressed");
  }
  GUI_DispStringInRect(ac, &Rect, GUI_TA_HCENTER | GUI_TA_VCENTER);
}

/*********************************************************************
*
*       _cbButton
*
* Function description 
*  1. Calls the owner draw function if the WM_PAINT message has been send
*  2. Calls the original callback for further messages
*  3. After processing the messages the function evaluates the pressed-state
*     if the WM_TOUCH message has been send
*/
static void _cbButton(WM_MESSAGE * pMsg) {  //--------------(4)
  switch (pMsg->MsgId) {
    case WM_PAINT:                          //--------------(5)
      _OnPaint(pMsg->hWin);
      break;
    default:                                //--------------(6)
      BUTTON_Callback(pMsg); // The original callback
      break;
  }

  if (pMsg->MsgId == WM_TOUCH) {           //--------------(7)
    if (BUTTON_IsPressed(pMsg->hWin)) {
      if (!_Pressed) {
        _Pressed = 1;
      }
    } else {
      _Pressed = 0;
    }
  }
}

/*********************************************************************
*
*       _cbDialog
*
* Function description
*   Dialog callback routine
*/
static void _cbDialog(WM_MESSAGE * pMsg) {
  int           NCode;
  int           Id;
  WM_HWIN       hDlg;
  BUTTON_Handle hButton;

  hDlg = pMsg->hWin;
  switch (pMsg->MsgId) {
    case WM_PAINT:
      WM_DefaultProc(pMsg); // Handle dialog items    //--------------(8)
      //
      // After drawing the dialog items add some user drawn items to the window
      //
      GUI_SetPenSize(10);
      GUI_SetColor(GUI_GREEN);
      GUI_DrawLine( 95,  5, 185, 95);
      GUI_SetColor(GUI_RED);
      GUI_DrawLine( 95, 95, 185,  5);
      break;
    case WM_INIT_DIALOG:
      hButton = WM_GetDialogItem(hDlg, GUI_ID_BUTTON0); 
      WM_SetHasTrans(hButton);              // Set transparency flag for button   //--------------(9)
      break;
    case WM_KEY:
      switch (((WM_KEY_INFO *)(pMsg->Data.p))->Key) {
        case GUI_KEY_ESCAPE:
          GUI_EndDialog(hDlg, 1);
          break;
        case GUI_KEY_ENTER:
          GUI_EndDialog(hDlg, 0);
          break;
      }
      break;
    case WM_NOTIFY_PARENT:
      Id    = WM_GetId(pMsg->hWinSrc);      // Id of widget
      NCode = pMsg->Data.v;                 // Notification code
      switch (NCode) {
        case WM_NOTIFICATION_RELEASED:      // React only if released  //--------------(10)
          hButton = WM_GetDialogItem(hDlg, GUI_ID_BUTTON0);
          if (Id == GUI_ID_BUTTON1) {       // Toggle callback //--------------(11)
            if (WM_GetCallback(hButton) == _cbButton) { 
              WM_SetCallback(hButton, BUTTON_Callback);
            } else {
              WM_SetCallback(hButton, _cbButton);
            }
            WM_InvalidateWindow(hButton);
          }
          if (Id == GUI_ID_BUTTON2) {       // Toggle font //--------------(12)
            if (_Font) {
              BUTTON_SetFont(hButton, &GUI_Font13_1);
            } else {
              BUTTON_SetFont(hButton, &GUI_Font8x16);
            }
            _Font ^= 1;
          }
          if (Id == GUI_ID_BUTTON3) {       // Toggle color //--------------(13)
            if (_Color) {
              BUTTON_SetBkColor(hButton, 0, 0xaaaaaa);
              BUTTON_SetBkColor(hButton, 1, GUI_WHITE);
              BUTTON_SetTextColor(hButton, 0, GUI_BLACK);
              BUTTON_SetTextColor(hButton, 1, GUI_BLACK);
            } else {
              BUTTON_SetBkColor(hButton, 0, GUI_BLUE);
              BUTTON_SetBkColor(hButton, 1, GUI_RED);
              BUTTON_SetTextColor(hButton, 0, GUI_WHITE);
              BUTTON_SetTextColor(hButton, 1, GUI_YELLOW);
            }
            _Color ^= 1;
          }
          if (Id == GUI_ID_OK) {            // OK Button //--------------(14)
            GUI_EndDialog(hDlg, 0);
          }
          if (Id == GUI_ID_CANCEL) {        // Cancel Button //--------------(15)
            GUI_EndDialog(hDlg, 1);
          }
          break;
      }
      break;
    default:
      WM_DefaultProc(pMsg);
  }
}

/*********************************************************************
*
*       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;
  }
  //
  // Use memory devices for all windows
  //
  #if GUI_SUPPORT_MEMDEV
    WM_SetCreateFlags(WM_CF_MEMDEV);
    WM_EnableMemdev(WM_HBKWIN);
  #endif
  WM_SetDesktopColor(GUI_GREEN);
  while(1) {
    _Font = _Color = 0;
    GUI_ExecDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), &_cbDialog, 0, 0, 0);
    GUI_Delay(1000);
  }
}

/*************************** End of file ****************************/
  1. 按鈕自定義回撥函式中WM_PAINT訊息的處理。
  2. 通過函式(WIDGET_GetState(hObj) & BUTTON_STATE_PRESSED) ? 1 : 0返回當前按鈕是按下還是未按下,按下的話,返回數值1,未按下返回數值0。根據這個返回值,在WM_PIANT訊息裡面繪製按鈕按下和未按下兩種狀態的顯示效果。
  3. 根據變數_Pressed的數值設定是否顯示字元,如果變數數值非0表示按鈕被按下,顯示字元Button pressed,如果未按下,僅顯示字元Button。變數_Pressed數值的改變是在按鈕回撥函式_cbButton裡面修改的。其實這裡直接使用第2條中函式(WIDGET_GetState(hObj) & BUTTON_STATE_PRESSED) ? 1 : 0的返回值就可以的,官方這裡設計的稍有些囉嗦了。
  4. 按鈕自定義的回撥函式。
  5. 按鈕自定義回撥函式中WM_PAINT訊息的處理。
  6. 按鈕回撥函式中,除了WM_PIANT訊息,其它訊息的處理繼續使用系統預設的函式BUTTON_Callback(pMsg)來實現。
  7. 如果按鈕被按下,回撥函式首先收到的就是這個WM_TOUCH訊息,然後才是WM_PAINT訊息的處理,這樣的話,就可以通過這個訊息配合函式BUTTON_IsPressed(pMsg->hWin)來設定變數_Pressed,賦值為1表示按下,賦值為0表示未按下。
  8. 函式WM_DefaultProc(pMsg)放在這裡比較巧妙,先呼叫這個函式的話,系統就會按照預設配置先重繪對話方塊,然後使用者在這個基礎上再繪製自己需要的內容。
  9. 通過函式WM_SetHasTrans設定ID為GUI_ID_BUTTON0的按鈕控制元件的透明效果。
  10. 按鈕釋放後的訊息處理。
  11. 按鈕ID為GUI_ID_BUTTON1的按鈕釋放訊息處理,這裡實現對ID為GUI_ID_BUTTON0按鈕的回撥函式切換。
  12. 按鈕ID為GUI_ID_BUTTON2的按鈕釋放訊息處理,這裡實現對ID為GUI_ID_BUTTON0按鈕顯示字型的切換。
  13. 按鈕ID為GUI_ID_BUTTON3的按鈕釋放訊息處理,這裡實現對ID為GUI_ID_BUTTON0按鈕顯示文字的背景色和前景色的切換。
  14. 按鈕ID為GUI_ID_OK的按鈕釋放訊息處理,此按鈕在本程式未用到,因為沒有建立ID為GUI_ID_OK的按鈕。
  15. 按鈕ID為GUI_ID_CANCEL的按鈕釋放訊息處理,這裡實現關閉阻塞式對話方塊。如果關閉了,1秒後會重新建立這個對話方塊,如此迴圈。

顯示效果如下:

55.4 實驗例程說明(RTOS)

配套例子:

V7-574_emWin6.x實驗_Button按鈕控制元件通過自定義回撥函式實現各種按鈕訊息(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解析度介面效果。

55.5 實驗例程說明(裸機)

配套例子:

V7-573_emWin6.x實驗_Button按鈕控制元件通過自定義回撥函式實現各種按鈕訊息(裸機)

實驗目的:

  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動態記憶體。

55.6 總結

本章節主要為大家講解了按鈕控制元件自定義回撥函式的實現方法,對於這種方法,望初學者一定要掌握,後面章節學習其它控制元件做自定義回撥函式,方法是相同的。

微信公眾號:armfly_com 安富萊論壇:www.armbbs.cn 安富萊淘寶:https://armfly.taobao.com