Window

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

    • Hi,

      I would like to display a separate window after the button press. Is there a reference code for such functionality? I have gone through some sample codes provided by emWin but couldn't find anything that matched what I need.
      Thank you so much in advance.

      Best regards,
      BMD
    • Hi,

      Below is a very basic example which shows how to create and delete a window on button press (or in this case on button release).

      C Source Code

      1. #include "DIALOG.h"
      2. /*********************************************************************
      3. *
      4. * Static code
      5. *
      6. **********************************************************************
      7. */
      8. /*********************************************************************
      9. *
      10. * _cbBk
      11. */
      12. static void _cbWin(WM_MESSAGE * pMsg) {
      13. GUI_RECT Rect;
      14. switch (pMsg->MsgId) {
      15. case WM_PAINT:
      16. //
      17. // Draw the window
      18. //
      19. GUI_SetBkColor(GUI_RED);
      20. GUI_Clear();
      21. WM_GetClientRect(&Rect);
      22. GUI_DispStringInRect("A Window", &Rect, GUI_TA_HCENTER | GUI_TA_VCENTER);
      23. break;
      24. default:
      25. WM_DefaultProc(pMsg); // Call default callback
      26. break;
      27. }
      28. }
      29. /*********************************************************************
      30. *
      31. * _cbBk
      32. */
      33. static void _cbBk(WM_MESSAGE * pMsg) {
      34. static WM_HWIN hWin;
      35. int Id;
      36. int NCode;
      37. switch (pMsg->MsgId) {
      38. case WM_PAINT:
      39. //
      40. // Draw the background. This is quite important because otherwise we would still see the child window although it gets deleted.
      41. // With this drawing the background wouldn't "know" how to draw itself.
      42. //
      43. GUI_SetBkColor(GUI_BLACK);
      44. GUI_Clear();
      45. break;
      46. case WM_NOTIFY_PARENT:
      47. //
      48. // A child window/widget has something for us
      49. //
      50. Id = WM_GetId(pMsg->hWinSrc); // Get its Id. pMsg->hWinSrc is the handle of the sender, here it is the button
      51. NCode = pMsg->Data.v; // pMsg->Data.v contains information about the event type
      52. switch (Id) {
      53. case GUI_ID_BUTTON0: // Button with this Id has something
      54. switch (NCode) {
      55. case WM_NOTIFICATION_RELEASED: // It was released, possible other event is WM_NOTIFICATION_CLICKED. This depends on the type of widget
      56. if (WM_IsWindow(hWin)) {
      57. //
      58. // If hWin is a window we delete it and set a different text for the button
      59. //
      60. WM_DeleteWindow(hWin);
      61. hWin = 0;
      62. BUTTON_SetText(pMsg->hWinSrc, "Create Window");
      63. } else {
      64. //
      65. // hWin is not a window, so we create one. Set button text.
      66. //
      67. hWin = WM_CreateWindowAsChild(10, 40, 100, 100, pMsg->hWin, WM_CF_SHOW, _cbWin, 0);
      68. BUTTON_SetText(pMsg->hWinSrc, "Delete Window");
      69. }
      70. break;
      71. }
      72. break;
      73. }
      74. break;
      75. default:
      76. WM_DefaultProc(pMsg); // Call default callback
      77. break;
      78. }
      79. }
      80. /*********************************************************************
      81. *
      82. * Public code
      83. *
      84. **********************************************************************
      85. */
      86. /*********************************************************************
      87. *
      88. * MainTask
      89. */
      90. void MainTask(void) {
      91. WM_HWIN hButton;
      92. GUI_Init();
      93. //
      94. // Enable multibuffering to avoid flickering, works only with GUIDRV_Lin and properly initialized multibuffering in LCDConf.c
      95. //
      96. WM_MULTIBUF_Enable(1);
      97. //
      98. // Set a callback for the background window. This processes messages send by child windows/widgets and manages drawing of the background.
      99. //
      100. WM_SetCallback(WM_HBKWIN, _cbBk);
      101. //
      102. // Create a button and set some text.
      103. //
      104. hButton = BUTTON_CreateEx(10, 10, 100, 20, WM_HBKWIN, WM_CF_SHOW, 0, GUI_ID_BUTTON0);
      105. BUTTON_SetText(hButton, "Create Window");
      106. while (1) {
      107. GUI_Delay(100);
      108. }
      109. }
      110. /*************************** End of file ****************************/
      Display All
      Regards,
      Sven
    • Thank you, Sven.
      That worked. But I am trying to do touch calibration after button click. I don't see anything after button click. Display goes blank. Please see below code. Is there something that's blocking the code to display calibration code? I have tested the calibration code separately and it works perfectly fine. I don't seem to understand where I am going wrong. Any help is appreciated.

      Best regards,
      BMD

      C Source Code

      1. /* ========================================
      2. *
      3. * Copyright YOUR COMPANY, THE YEAR
      4. * All Rights Reserved
      5. * UNPUBLISHED, LICENSED SOFTWARE.
      6. *
      7. * CONFIDENTIAL AND PROPRIETARY INFORMATION
      8. * WHICH IS THE PROPERTY OF your company.
      9. *
      10. * ========================================
      11. */
      12. #include "project.h"
      13. #include <stdio.h>
      14. #include <math.h>
      15. #include <string.h>
      16. #include "DIALOG.h"
      17. #include "Global Defines.h"
      18. #define GLOBALS_INTERNAL
      19. #include "Global Variables.h"
      20. GUI_PID_STATE TouchState;
      21. #define NUM_CALIB_POINTS 5 // Number of points for calibration
      22. int _aRefX[NUM_CALIB_POINTS];
      23. int _aRefY[NUM_CALIB_POINTS];
      24. int _aSamX[NUM_CALIB_POINTS];
      25. int _aSamY[NUM_CALIB_POINTS];
      26. int i;
      27. unsigned char Calibrate(void)
      28. {
      29. static unsigned char CalibrationPoint = 0;
      30. static unsigned char PreviousTouchState = 0;
      31. int xSize, ySize;
      32. unsigned char CalibrationComplete = FALSE;
      33. xSize = LCD_GetXSize();
      34. ySize = LCD_GetYSize();
      35. //
      36. // Calculate reference points depending on LCD size
      37. //
      38. _aRefX[0] = (xSize * 5) / 100;
      39. _aRefY[0] = (ySize * 5) / 100;
      40. _aRefX[1] = xSize - (xSize * 5) / 100;
      41. _aRefY[1] = _aRefY[0];
      42. _aRefX[2] = _aRefX[1];
      43. _aRefY[2] = ySize - (ySize * 5) / 100;
      44. _aRefX[3] = _aRefX[0];
      45. _aRefY[3] = _aRefY[2];
      46. _aRefX[4] = xSize / 2;
      47. _aRefY[4] = ySize / 2;
      48. GUI_SetPenSize(3);
      49. // GUI_Clear();
      50. GUI_DispStringHCenterAt("Please touch the point", LCD_GetXSize() / 2, LCD_GetYSize() / 2 - 60);
      51. GUI_DrawCircle(_aRefX[CalibrationPoint], _aRefY[CalibrationPoint], 5);
      52. GUI_DispStringAt("State = ", 50,80);
      53. GUI_TOUCH_Exec();
      54. GUI_DispDecAt(GUI_TOUCH_GetState(&TouchState),200,150,1);
      55. if (GUI_TOUCH_GetState(&TouchState) != PreviousTouchState)
      56. {
      57. if (GUI_TOUCH_GetState(&TouchState) == 1)
      58. {
      59. // Store sample points
      60. _aSamX[CalibrationPoint] = GUI_TOUCH_GetxPhys();
      61. _aSamY[CalibrationPoint] = GUI_TOUCH_GetyPhys();
      62. // GUI_DispDecAt(_aSamX[CalibrationPoint],150,80,3);
      63. // GUI_DispDecAt(_aSamY[CalibrationPoint],200,80,3);
      64. }
      65. else if (CalibrationPoint < NUM_CALIB_POINTS - 1)
      66. {
      67. GUI_Clear();
      68. CalibrationPoint++;
      69. }
      70. else if (CalibrationPoint == NUM_CALIB_POINTS - 1)
      71. {
      72. // Pass measured points to emWin.
      73. GUI_TOUCH_CalcCoefficients(NUM_CALIB_POINTS, _aRefX, _aRefY, _aSamX, _aSamY, xSize, ySize);
      74. GUI_Clear();
      75. CalibrationComplete = TRUE;
      76. }
      77. PreviousTouchState = GUI_TOUCH_GetState(&TouchState);
      78. }
      79. return CalibrationComplete;
      80. }
      81. void TouchCalibration(void)
      82. {
      83. unsigned char CalibrationComplete = FALSE;
      84. while(CalibrationComplete == FALSE)
      85. {
      86. if (FiveMsFlag == TRUE)
      87. {
      88. FiveMsFlag = FALSE;
      89. CalibrationComplete = Calibrate();
      90. }
      91. }
      92. }
      93. /* [] END OF FILE */
      Display All

      C Source Code

      1. #include <stddef.h>
      2. #include <string.h>
      3. #include "WM.h"
      4. #include "DIALOG.h"
      5. #include "BUTTON.h"
      6. #include "Global Defines.h"
      7. #define GLOBALS_INTERNAL
      8. #include "Global Variables.h"
      9. #define GUI_ID_WINDOW_0 (GUI_ID_USER + 0x00)
      10. #define RECOMMENDED_MEMORY (1024L * 5)
      11. extern char Calibrate(void);
      12. extern void TouchCalibration(void);
      13. static int TouchCalibrate;
      14. static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] =
      15. {
      16. { WINDOW_CreateIndirect, "Tools", GUI_ID_WINDOW_0, 0, 0, 320, 240},
      17. { BUTTON_CreateIndirect, "O2 Cell", GUI_ID_BUTTON0, 25, 50, 220, 45},
      18. { BUTTON_CreateIndirect, "Touchscreen", GUI_ID_BUTTON1, 25, 110, 220, 45},
      19. { BUTTON_CreateIndirect, "Cancel", GUI_ID_CANCEL, 25, 170, 100, 30 },
      20. };
      21. static void _cbButton(WM_MESSAGE * pMsg)
      22. {
      23. switch (pMsg->MsgId)
      24. {
      25. case WM_PAINT:
      26. GUI_SetBkColor(GUI_BLACK);
      27. GUI_Clear();
      28. break;
      29. default:
      30. WM_DefaultProc(pMsg);
      31. // BUTTON_Callback(pMsg);
      32. break;
      33. }
      34. /*********************************************************************
      35. *
      36. * _cbDialog
      37. */
      38. static void _cbDialog(WM_MESSAGE * pMsg)
      39. {
      40. U32 FileSize;
      41. const void * pData;
      42. WM_HWIN hDlg;
      43. int NCode;
      44. int Id;
      45. static WM_HWIN hWin;
      46. // USER START (Optionally insert additional variables)
      47. // USER END
      48. // hDlg = pMsg->hWin;
      49. switch (pMsg->MsgId)
      50. {
      51. case WM_PAINT:
      52. GUI_SetBkColor(GUI_BLACK);
      53. GUI_Clear();
      54. break;
      55. case WM_NOTIFY_PARENT:
      56. Id = WM_GetId(pMsg->hWinSrc);
      57. NCode = pMsg->Data.v;
      58. // unsigned char CalibrationComplete = FALSE;
      59. switch(NCode)
      60. {
      61. case WM_NOTIFICATION_RELEASED:
      62. if(Id == GUI_ID_BUTTON1)
      63. {
      64. if(TouchCalibrate)
      65. {
      66. hWin = WM_CreateWindowAsChild(0,0,320,240,pMsg->hWin,WM_CF_SHOW, _cbButton,0);
      67. TouchCalibration();
      68. }
      69. else
      70. {
      71. WM_DeleteWindow(hWin);
      72. }
      73. TouchCalibrate = 1;
      74. }
      75. if (Id == GUI_ID_CANCEL)
      76. { // Cancel Button
      77. GUI_EndDialog(hDlg, 1);
      78. }
      79. break;
      80. }
      81. default:
      82. WM_DefaultProc(pMsg);
      83. break;
      84. }
      85. }
      86. /*********************************************************************
      87. *
      88. * Public code
      89. *
      90. **********************************************************************
      91. */
      92. /*********************************************************************
      93. *
      94. * CreateWindow
      95. */
      96. void CreateToolsScreen(void)
      97. {
      98. // WM_HWIN hButton;
      99. //
      100. // Check if recommended memory for the sample is available
      101. //
      102. if (GUI_ALLOC_GetNumFreeBytes() < RECOMMENDED_MEMORY)
      103. {
      104. GUI_ErrorOut("Not enough memory available.");
      105. return;
      106. }
      107. //
      108. // Use memory devices for all windows
      109. //
      110. #if GUI_SUPPORT_MEMDEV
      111. WM_SetCreateFlags(WM_CF_MEMDEV);
      112. WM_EnableMemdev(WM_HBKWIN);
      113. #endif
      114. //
      115. // Set a callback for the background window. This processes messages send by child windows/widgets and manages drawing of the background.
      116. //
      117. WM_SetCallback(WM_HBKWIN, _cbDialog);
      118. WM_SetDesktopColor(GUI_BLUE);
      119. while(1)
      120. {
      121. TouchCalibrate = 0;
      122. GUI_ExecDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), &_cbDialog, 0, 0, 0);
      123. GUI_Delay(1);
      124. }
      125. }
      Display All
    • Hi,

      The problem is that you can not simply draw outside of a WM_PAINT message. You call the calibrate function from WM_NOTIFY_PARENT.

      Try this:

      C Source Code

      1. #include <stddef.h>
      2. #include <string.h>
      3. #include "DIALOG.h"
      4. #define GUI_ID_WINDOW_0 (GUI_ID_USER + 0x00)
      5. #define NUM_CALIB_POINTS 5 // Number of points for calibration
      6. static int _aRefX[NUM_CALIB_POINTS];
      7. static int _aRefY[NUM_CALIB_POINTS];
      8. static int _aSamX[NUM_CALIB_POINTS];
      9. static int _aSamY[NUM_CALIB_POINTS];
      10. static int i;
      11. static int FiveMsFlag = 1;
      12. static int TouchCalibrate = 1;
      13. static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] =
      14. {
      15. { WINDOW_CreateIndirect, "Tools", GUI_ID_WINDOW_0, 0, 0, 320, 240},
      16. { BUTTON_CreateIndirect, "O2 Cell", GUI_ID_BUTTON0, 25, 50, 220, 45},
      17. { BUTTON_CreateIndirect, "Touchscreen", GUI_ID_BUTTON1, 25, 110, 220, 45},
      18. { BUTTON_CreateIndirect, "Cancel", GUI_ID_CANCEL, 25, 170, 100, 30 },
      19. };
      20. /*********************************************************************
      21. *
      22. * _cbCalibrate
      23. */
      24. static void _cbCalibrate(WM_MESSAGE * pMsg) {
      25. int xSize, ySize;
      26. static int CalibrationPoint;
      27. WM_PID_STATE_CHANGED_INFO * pInfo;
      28. switch (pMsg->MsgId) {
      29. case WM_CREATE:
      30. xSize = LCD_GetXSize();
      31. ySize = LCD_GetYSize();
      32. //
      33. // Calculate reference points depending on LCD size
      34. //
      35. _aRefX[0] = (xSize * 5) / 100;
      36. _aRefY[0] = (ySize * 5) / 100;
      37. _aRefX[1] = xSize - (xSize * 5) / 100;
      38. _aRefY[1] = _aRefY[0];
      39. _aRefX[2] = _aRefX[1];
      40. _aRefY[2] = ySize - (ySize * 5) / 100;
      41. _aRefX[3] = _aRefX[0];
      42. _aRefY[3] = _aRefY[2];
      43. _aRefX[4] = xSize / 2;
      44. _aRefY[4] = ySize / 2;
      45. break;
      46. case WM_PAINT:
      47. GUI_SetBkColor(GUI_BLACK);
      48. GUI_Clear();
      49. GUI_SetPenSize(3);
      50. GUI_DispStringHCenterAt("Please touch the point", LCD_GetXSize() / 2, LCD_GetYSize() / 2 - 60);
      51. GUI_DrawCircle(_aRefX[CalibrationPoint], _aRefY[CalibrationPoint], 5);
      52. break;
      53. case WM_PID_STATE_CHANGED:
      54. pInfo = (WM_PID_STATE_CHANGED_INFO *)pMsg->Data.p;
      55. if (pInfo) {
      56. if (pInfo->State == 1 && pInfo->StatePrev == 0) {
      57. _aSamX[CalibrationPoint] = pInfo->x;
      58. _aSamY[CalibrationPoint] = pInfo->y;
      59. CalibrationPoint++;
      60. WM_InvalidateWindow(pMsg->hWin);
      61. if (CalibrationPoint == NUM_CALIB_POINTS - 1) {
      62. xSize = LCD_GetXSize();
      63. ySize = LCD_GetYSize();
      64. GUI_TOUCH_CalcCoefficients(NUM_CALIB_POINTS, _aRefX, _aRefY, _aSamX, _aSamY, xSize, ySize);
      65. WM_DeleteWindow(pMsg->hWin);
      66. }
      67. }
      68. }
      69. break;
      70. default:
      71. WM_DefaultProc(pMsg);
      72. break;
      73. }
      74. }
      75. /*********************************************************************
      76. *
      77. * _cbDialog
      78. */
      79. static void _cbDialog(WM_MESSAGE * pMsg) {
      80. U32 FileSize;
      81. const void * pData;
      82. WM_HWIN hDlg;
      83. int NCode;
      84. int Id;
      85. static WM_HWIN hWin;
      86. switch (pMsg->MsgId) {
      87. case WM_PAINT:
      88. GUI_SetBkColor(GUI_BLACK);
      89. GUI_Clear();
      90. break;
      91. case WM_NOTIFY_PARENT:
      92. Id = WM_GetId(pMsg->hWinSrc);
      93. NCode = pMsg->Data.v;
      94. switch(NCode) {
      95. case WM_NOTIFICATION_RELEASED:
      96. if (Id == GUI_ID_BUTTON1) {
      97. if (TouchCalibrate) {
      98. hWin = WM_CreateWindowAsChild(0, 0, 320, 240, pMsg->hWin, WM_CF_SHOW, _cbCalibrate, 0);
      99. } else {
      100. WM_DeleteWindow(hWin);
      101. }
      102. TouchCalibrate = 1;
      103. }
      104. if (Id == GUI_ID_CANCEL) { // Cancel Button
      105. GUI_EndDialog(pMsg->hWin, 1);
      106. }
      107. break;
      108. }
      109. break;
      110. default:
      111. WM_DefaultProc(pMsg);
      112. break;
      113. }
      114. }
      115. /*********************************************************************
      116. *
      117. * Public code
      118. *
      119. **********************************************************************
      120. */
      121. /*********************************************************************
      122. *
      123. * MainTask
      124. */
      125. void MainTask(void) {
      126. GUI_Init();
      127. WM_SetDesktopColor(GUI_BLUE);
      128. GUI_ExecDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), &_cbDialog, 0, 0, 0);
      129. while(1) {
      130. GUI_Delay(100);
      131. }
      132. }
      Display All
      Regards,
      Sven
    • Thank you.
      But what if I have more than one button on the display, do I need to write separate functions for each button created? .
      For example, I have touch calibration and O2 cell. The code above is for touch. Do I need to write a different code for O2 cell in another c file? I am jus t trying to understand how emWin works and it's so different from the rest of the tools.
      Also, what if you want to call a function inside another function?

      Much appreciate all the help.

      Best regards,
      BMD
    • Hi,

      it depends on what you like to do, you can either use one BUTTON callback for several buttons and check via the widget ID what should be drawn/done, or create a callback for each button individually to have the code separated.

      If these buttons are all in the same window, I would advise you to keep it all in one C file just for the sake of clarity. But, same as with the callbacks, here you're also free to decide whatever suits best for you.

      bio_med wrote:

      Also, what if you want to call a function inside another function?
      If this refers to callback routines, then no, you can't call one of your callbacks in any of your other callbacks. The only other callback to be called within your callback is WM_DefaultProc() in the default case for windows and <WIDGET>_Callback() in the default case for any widgets, like e.g. BUTTON_Callback().

      Best regards,

      Florian