STM32F746G-Discovery

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • HI,

      Of course, _cbCallback and _cbDialog are just names and you can choose them freely.

      But, the callback set for a dialog receives a WM_INIT_DIALOG message after all its dialog elements are created. This gives you the chance to configure the different elements.

      A callback function set for a single window gets a WM_CREATE message giving you the chance of reacting to it and creating further child windows or set up some data.

      You can react to WM_CREATE only if the pointer to the callback function is a prameter of the create function like "cb" of the following function:

      C Source Code

      1. WM_HWIN WM_CreateWindowAsChild(int x0,
      2. int y0,
      3. int width,
      4. int height,
      5. WM_HWIN hParent,
      6. U32 Style,
      7. WM_CALLBACK * cb,
      8. int NumExtraBytes);

      With a widget it is not possible to pass a callback to its create function. Therefore we have added a message to react on setting a callback. Since emWin version 5.46 a callback gets send a WM_SET_CALLBACK message when calling WM_SetCallback().

      Regards,
      Sven
    • Hi,

      you could overwrite the button callback function or set a custom skinning function. When it comes to drawing the button text you can display the string rotated with the function GUI_DispStringInRectEx().

      C Source Code

      1. #include "DIALOG.h"
      2. /*********************************************************************
      3. *
      4. * Static code
      5. *
      6. **********************************************************************
      7. */
      8. /*********************************************************************
      9. *
      10. * _ButtonSkin
      11. */
      12. static int _ButtonSkin(const WIDGET_ITEM_DRAW_INFO * pInfo) {
      13. char acBuffer[32];
      14. GUI_RECT Rect;
      15. switch (pInfo->Cmd) {
      16. case WIDGET_ITEM_DRAW_BACKGROUND:
      17. if (BUTTON_IsPressed(pInfo->hWin)) {
      18. GUI_SetBkColor(GUI_GREEN);
      19. } else {
      20. GUI_SetBkColor(GUI_BLUE);
      21. }
      22. GUI_Clear();
      23. return 0;
      24. case WIDGET_ITEM_DRAW_TEXT:
      25. BUTTON_GetText(pInfo->hWin, acBuffer, sizeof(acBuffer));
      26. if (BUTTON_IsPressed(pInfo->hWin)) {
      27. GUI_SetColor(GUI_BLUE);
      28. } else {
      29. GUI_SetColor(GUI_GREEN);
      30. }
      31. WM_GetClientRect(&Rect);
      32. GUI_DispStringInRectEx(acBuffer, &Rect, GUI_TA_HCENTER | GUI_TA_VCENTER, sizeof(acBuffer), GUI_ROTATE_CCW);
      33. return 0;
      34. default:
      35. return BUTTON_DrawSkinFlex(pInfo);
      36. }
      37. }
      38. /*********************************************************************
      39. *
      40. * _cbButtonTrans
      41. */
      42. static void _cbButtonTrans(WM_MESSAGE * pMsg) {
      43. char acBuffer[32];
      44. GUI_RECT Rect;
      45. switch (pMsg->MsgId) {
      46. case WM_PAINT:
      47. if (BUTTON_IsPressed(pMsg->hWin)) {
      48. GUI_SetBkColor(GUI_GREEN);
      49. } else {
      50. GUI_SetBkColor(GUI_BLUE);
      51. }
      52. GUI_Clear();
      53. BUTTON_GetText(pMsg->hWin, acBuffer, sizeof(acBuffer));
      54. if (BUTTON_IsPressed(pMsg->hWin)) {
      55. GUI_SetColor(GUI_BLUE);
      56. } else {
      57. GUI_SetColor(GUI_GREEN);
      58. }
      59. WM_GetClientRect(&Rect);
      60. GUI_DispStringInRectEx(acBuffer, &Rect, GUI_TA_HCENTER | GUI_TA_VCENTER, sizeof(acBuffer), GUI_ROTATE_CCW);
      61. break;
      62. default:
      63. BUTTON_Callback(pMsg);
      64. break;
      65. }
      66. }
      67. /*********************************************************************
      68. *
      69. * _cbBk
      70. */
      71. static void _cbBk(WM_MESSAGE * pMsg) {
      72. WM_HWIN hItem;
      73. int Id;
      74. int NCode;
      75. switch (pMsg->MsgId) {
      76. case WM_PAINT:
      77. GUI_DrawGradientH(0, 0, LCD_GetXSize() - 1, LCD_GetYSize() - 1, GUI_BLACK, GUI_LIGHTGRAY);
      78. break;
      79. default:
      80. WM_DefaultProc(pMsg);
      81. break;
      82. }
      83. }
      84. /*********************************************************************
      85. *
      86. * Public code
      87. *
      88. **********************************************************************
      89. */
      90. /*********************************************************************
      91. *
      92. * MainTask
      93. */
      94. void MainTask(void) {
      95. WM_HWIN hButton;
      96. WM_HWIN hText;
      97. GUI_Init();
      98. WM_MULTIBUF_Enable(1);
      99. WM_SetCallback(WM_HBKWIN, _cbBk);
      100. hButton = BUTTON_CreateEx(20, 20, 20, 80, WM_HBKWIN, WM_CF_SHOW, 0, GUI_ID_BUTTON0);
      101. BUTTON_SetText(hButton, "Button");
      102. WM_SetCallback(hButton, _cbButtonTrans);
      103. hButton = BUTTON_CreateEx(50, 20, 20, 80, WM_HBKWIN, WM_CF_SHOW, 0, GUI_ID_BUTTON1);
      104. BUTTON_SetText(hButton, "Button");
      105. BUTTON_SetSkin(hButton, _ButtonSkin);
      106. while (1) {
      107. GUI_Delay(100);
      108. }
      109. }
      110. /*************************** End of file ****************************/
      Display All

      It is not possible to simply rotate the default button. The background wouldn't get rotated.

      Regards,
      Sven
    • I want to rotate the inscription on the button. What's wrong here?

      #define ID_WINDOW_0 (GUI_ID_USER + 0x00)
      #define ID_BUTTON_0 (GUI_ID_USER + 0x01) // START
      #define ID_BUTTON_1 (GUI_ID_USER + 0x02) // STOP
      #define ID_BUTTON_2 (GUI_ID_USER + 0x03) // UP
      #define ID_BUTTON_3 (GUI_ID_USER + 0x04) // DOWN

      static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = { {
      WINDOW_CreateIndirect, "Window", ID_WINDOW_0, 0, 0, 480, 272,
      WM_CF_SHOW, 0 }, { BUTTON_CreateIndirect, "START",
      ID_BUTTON_0, 30, 20, 40, 232 }, { BUTTON_CreateIndirect, "STOP",
      ID_BUTTON_1, 90, 20, 40, 232 }, { BUTTON_CreateIndirect, "UP",
      ID_BUTTON_2, 150, 20, 40, 232 }, { BUTTON_CreateIndirect, "DOWN",
      ID_BUTTON_3, 210, 20, 40, 232 } };


      static void _cbCallback(WM_MESSAGE * pMsg) {


      WM_HWIN hWin;
      WM_HWIN hItem;


      int NCode;
      int Id;



      hItem = pMsg->hWin;
      switch (pMsg->MsgId) {
      case WM_INIT_DIALOG:
      WINDOW_SetBkColor(hItem, GUI_BLUE);


      hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_0);
      BUTTON_SetFont(hItem, GUI_FONT_24B_ASCII);
      BUTTON_SetText(hItem, "START");
      BUTTON_SetTextColor(hItem, BUTTON_CI_PRESSED, GUI_RED);
      GUI_DispStringInRectEx("START", hItem, GUI_TA_HCENTER | GUI_TA_VCENTER,
      6, GUI_ROTATE_CCW);



      hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_1);
      BUTTON_SetFont(hItem, GUI_FONT_24B_ASCII);
      BUTTON_SetText(hItem, "STOP");


      hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_2);
      BUTTON_SetFont(hItem, GUI_FONT_24B_ASCII);
      BUTTON_SetText(hItem, "UP");


      hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_3);
      BUTTON_SetFont(hItem, GUI_FONT_24B_ASCII);
      BUTTON_SetText(hItem, "DOWN");


      break;


      default:
      WM_DefaultProc(pMsg);
      break;
      }
      }


      WM_HWIN CreateWindow(void) {
      WM_HWIN hWin;


      hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate),
      _cbCallback, WM_HBKWIN, 0, 0);
      return hWin;
      }


      void MainTask(void) {


      CreateWindow();


      }
    • Hi,

      Andrzej wrote:

      What is the difference between _cbButton and cbButton?
      _cbButtonTrans() is a callback function gets called by emWin if something happens related to the button this callback is set to. This allows you to react different events like touch, or WM_PAINT.

      _ButtonSkin() is callback dedicated for drawing. This gets called by the default callback function of a button and allows you to draw the single parts of a button like background and text.


      Andrzej wrote:

      I want to rotate the inscription on the button. What's wrong here?

      You have to set either a custom skin or a custom callback for the buttons. Otherwise you can not change the drawing.

      You can not simply call a drawing function within WM_INIT_DIALOG. Draw functions should be called only within a WM_PAINT event.

      C Source Code

      1. #include "DIALOG.h"
      2. #define ID_WINDOW_0 (GUI_ID_USER + 0x00)
      3. #define ID_BUTTON_0 (GUI_ID_USER + 0x01) // START
      4. #define ID_BUTTON_1 (GUI_ID_USER + 0x02) // STOP
      5. #define ID_BUTTON_2 (GUI_ID_USER + 0x03) // UP
      6. #define ID_BUTTON_3 (GUI_ID_USER + 0x04) // DOWN
      7. static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
      8. { WINDOW_CreateIndirect, "Window", ID_WINDOW_0, 0, 0, 480, 272, WM_CF_SHOW, 0 },
      9. { BUTTON_CreateIndirect, "START", ID_BUTTON_0, 30, 20, 40, 232 },
      10. { BUTTON_CreateIndirect, "STOP", ID_BUTTON_1, 90, 20, 40, 232 },
      11. { BUTTON_CreateIndirect, "UP", ID_BUTTON_2, 150, 20, 40, 232 },
      12. { BUTTON_CreateIndirect, "DOWN", ID_BUTTON_3, 210, 20, 40, 232 }
      13. };
      14. /*********************************************************************
      15. *
      16. * _ButtonSkin
      17. */
      18. static int _ButtonSkin(const WIDGET_ITEM_DRAW_INFO * pInfo) {
      19. char acBuffer[32];
      20. GUI_RECT Rect;
      21. const GUI_FONT * pFont;
      22. GUI_COLOR Color;
      23. switch (pInfo->Cmd) {
      24. case WIDGET_ITEM_DRAW_TEXT:
      25. BUTTON_GetText(pInfo->hWin, acBuffer, sizeof(acBuffer));
      26. WM_GetClientRect(&Rect);
      27. pFont = BUTTON_GetFont(pInfo->hWin);
      28. GUI_SetFont(pFont);
      29. GUI_SetTextMode(GUI_TM_TRANS);
      30. if (BUTTON_IsPressed(pInfo->hWin)) {
      31. Color = BUTTON_GetTextColor(pInfo->hWin, BUTTON_CI_PRESSED);
      32. } else {
      33. Color = BUTTON_GetTextColor(pInfo->hWin, BUTTON_CI_UNPRESSED);
      34. }
      35. GUI_SetColor(Color);
      36. GUI_DispStringInRectEx(acBuffer, &Rect, GUI_TA_HCENTER | GUI_TA_VCENTER, sizeof(acBuffer), GUI_ROTATE_CCW);
      37. return 0;
      38. default:
      39. return BUTTON_DrawSkinFlex(pInfo);
      40. }
      41. }
      42. /*********************************************************************
      43. *
      44. * _cbCallback
      45. */
      46. static void _cbCallback(WM_MESSAGE * pMsg) {
      47. WM_HWIN hWin;
      48. WM_HWIN hItem;
      49. int NCode;
      50. int Id;
      51. hItem = pMsg->hWin;
      52. switch (pMsg->MsgId) {
      53. case WM_INIT_DIALOG:
      54. WINDOW_SetBkColor(hItem, GUI_BLUE);
      55. hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_0);
      56. BUTTON_SetFont(hItem, GUI_FONT_24B_ASCII);
      57. BUTTON_SetText(hItem, "START");
      58. BUTTON_SetTextColor(hItem, BUTTON_CI_PRESSED, GUI_RED);
      59. BUTTON_SetSkin(hItem, _ButtonSkin);
      60. hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_1);
      61. BUTTON_SetFont(hItem, GUI_FONT_24B_ASCII);
      62. BUTTON_SetText(hItem, "STOP");
      63. BUTTON_SetSkin(hItem, _ButtonSkin);
      64. hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_2);
      65. BUTTON_SetFont(hItem, GUI_FONT_24B_ASCII);
      66. BUTTON_SetText(hItem, "UP");
      67. BUTTON_SetSkin(hItem, _ButtonSkin);
      68. hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_3);
      69. BUTTON_SetFont(hItem, GUI_FONT_24B_ASCII);
      70. BUTTON_SetText(hItem, "DOWN");
      71. BUTTON_SetSkin(hItem, _ButtonSkin);
      72. break;
      73. default:
      74. WM_DefaultProc(pMsg);
      75. break;
      76. }
      77. }
      78. /*********************************************************************
      79. *
      80. * CreateWindow
      81. */
      82. WM_HWIN CreateWindow(void) {
      83. WM_HWIN hWin;
      84. hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbCallback, WM_HBKWIN, 0, 0);
      85. return hWin;
      86. }
      87. /*********************************************************************
      88. *
      89. * _cbBk
      90. */
      91. static void _cbBk(WM_MESSAGE * pMsg) {
      92. switch (pMsg->MsgId) {
      93. case WM_PAINT:
      94. GUI_SetBkColor(GUI_BLACK);
      95. GUI_Clear();
      96. break;
      97. default:
      98. WM_DefaultProc(pMsg);
      99. break;
      100. }
      101. }
      102. void MainTask(void) {
      103. GUI_Init();
      104. WM_MULTIBUF_Enable(1);
      105. WM_SetCallback(WM_HBKWIN, _cbBk);
      106. CreateWindow();
      107. while (1) {
      108. GUI_Delay(100);
      109. }
      110. }
      Display All



      Regards,
      Sven
    • Hi Andrzej,

      I'm not sure what you mean by converting, but if you mean custom drawing a widget then yes, you're able to custom draw all widgets.

      This is done by executing the drawing operations in a WM_PAINT case in a callback function. This function will be set to a widget using WM_SetCallback().

      Here's a small sample demonstrating how to do this:

      C Source Code

      1. #include "DIALOG.h"
      2. /*********************************************************************
      3. *
      4. * Static code
      5. *
      6. **********************************************************************
      7. */
      8. /*********************************************************************
      9. *
      10. * _cbButton
      11. */
      12. static void _cbButton(WM_MESSAGE * pMsg) {
      13. GUI_RECT Rect;
      14. switch (pMsg->MsgId) {
      15. case WM_PAINT:
      16. //
      17. // Execute drawing operations in WM_PAINT. This is how the button looks.
      18. //
      19. GUI_SetColor(GUI_GRAY_9A);
      20. //
      21. // Save dimensions of this window (button) for drawing.
      22. //
      23. WM_GetClientRect(&Rect);
      24. //
      25. // Draw something.
      26. //
      27. GUI_FillRoundedRect(Rect.x0, Rect.y0, Rect.x1, Rect.y1, 3);
      28. GUI_SetColor(GUI_BLACK);
      29. GUI_SetTextMode(GUI_TM_TRANS);
      30. GUI_AA_DrawRoundedRectEx(&Rect, 3);
      31. GUI_DispStringInRect("Button", &Rect, GUI_TA_HCENTER | GUI_TA_VCENTER);
      32. break;
      33. default:
      34. WM_DefaultProc(pMsg);
      35. break;
      36. }
      37. }
      38. /*********************************************************************
      39. *
      40. * Public code
      41. *
      42. **********************************************************************
      43. */
      44. /*********************************************************************
      45. *
      46. * MainTask
      47. */
      48. void MainTask(void) {
      49. WM_HWIN hButton;
      50. GUI_Init();
      51. WM_SetDesktopColor(GUI_WHITE);
      52. //
      53. // Create button widget
      54. //
      55. hButton = BUTTON_CreateEx(20, 20, 120, 40, WM_HBKWIN, WM_CF_SHOW, 0, GUI_ID_BUTTON0);
      56. //
      57. // Set callback routine to the button
      58. //
      59. WM_SetCallback(hButton, _cbButton);
      60. while (1) {
      61. GUI_Delay(100);
      62. }
      63. }
      64. /*************************** End of file ****************************/
      Display All


      Best regards,

      Florian
    • Hi

      I want to put NUMBER on position x = 250, y = 40. I have the following code. Why can't I do that? How to declare GUI_RECT?

      static void _cbCallback(WM_MESSAGE * pMsg) {
      WM_HWIN hWin;
      WM_HWIN hItem;
      int NCode;
      int Id;
      GUI_RECT Rect = {10, 10, 40, 80};


      hItem = pMsg->hWin;
      switch (pMsg->MsgId) {
      case WM_INIT_DIALOG:


      WINDOW_SetBkColor(hItem, GUI_BLUE);


      hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_0);
      BUTTON_SetFont(hItem, GUI_FONT_24B_ASCII);
      BUTTON_SetText(hItem, "START");
      BUTTON_SetSkin(hItem, _ButtonSkin);


      hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_1);
      BUTTON_SetFont(hItem, GUI_FONT_24B_ASCII);
      BUTTON_SetText(hItem, "STOP");
      BUTTON_SetSkin(hItem, _ButtonSkin);


      hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_2);
      BUTTON_SetFont(hItem, GUI_FONT_24B_ASCII);
      BUTTON_SetText(hItem, "UP");
      BUTTON_SetTextColor(hItem, BUTTON_CI_PRESSED, GUI_RED);
      BUTTON_SetSkin(hItem, _ButtonSkin);


      hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_3);
      BUTTON_SetFont(hItem, GUI_FONT_24B_ASCII);
      BUTTON_SetText(hItem, "DOWN");
      BUTTON_SetTextColor(hItem, BUTTON_CI_PRESSED, GUI_RED);
      BUTTON_SetSkin(hItem, _ButtonSkin);


      break;


      case WM_PAINT:


      GUI_DispStringInRectEx("NUMBER", &Rect,
      GUI_TA_HCENTER | GUI_TA_VCENTER, 10, GUI_ROTATE_CCW);


      break;


      default:
      WM_DefaultProc(pMsg);
      break;
      }
      }


      /*********************************************************************
      *
      * CreateWindow
      */
      WM_HWIN CreateWindow(void) {
      WM_HWIN hWin;


      hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate),
      _cbCallback, WM_HBKWIN, 0, 0);
      return hWin;
      }


      void MainTask(void) {


      GUI_Init();
      WM_MULTIBUF_Enable(1);
      CreateWindow();
      while (1) {
      GUI_Delay(100);
      }
      }
    • Hi Andrzej,

      no, rotating widgets is not possible. What you might want to do instead is changing the display orientation instead of rotating each item individually.

      You can do this by changing the display driver in the file LCDConf.c. Your hardware uses the Lin driver and you can find a list of available orientation settings in the manual under "33.7.6 GUIDRV_Lin".

      Setting the display driver to GUIDRV_LIN_OSX_32 should achieve what you need, if your color depth is 32bpp.

      Best regards,

      Florian