How to exit from a GUIBuilder created window and 1) free memory, 2) get you display to function correctly

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

    • How to exit from a GUIBuilder created window and 1) free memory, 2) get you display to function correctly


      I have created a MainTask that does not use GUIBuilder - That worksperfectly
      I created an App configuration Dialog Window formy app using GUIBuilder - It's called: CreateIntroPageV1_6() - That works perfectly
      Now from my MainTask, this is how I call the Dialog createdwith GUIBuilder:

      void MainTask(void)
      WM_HWIN hDlg;
      hDlg = CreateIntroPageV1_6();
      MyDialog window that in CreateIntroPageV1_6() works perfectly. All buttons and callbacks work perfectly

      The questions I have are:
      1) When I finish executingfrom CreateIntroPageV1_6() and want to return to myMainTask what should I do to free all memory used in CreateIntroPageV1_6()?
      Will WindowManager free up the memory for me automatically upon executing "return hWin;" or should I callGUI_EndDialog(hDlg,0)?
      Ifyes, where should this be called from? MainTask or CreateIntroPageV1_6()?

      2)When CreateIntroPageV1_6() returns and I’m back in my MainTask, what wasdisplayed when CreateIntroPageV1_6() was executing is not erased. The only wayI can get it to erase is to call: WM_SetDesktopColor(GUI_BLACK);
      Isthere a better way to do clear the screen? I tried GUI_Clear(); butthat does not work.

      3)When CreateIntroPageV1_6() returns and I’m back in my MainTask my graphics inMainTask is not displaying correctly some parts of my drawings are not displaying correctly.

      Sobasically, I need to understand how to exit from a GUIBuilder created routineand get back to my MainTask (that does not use Window Manager) and have thingsback to normal.

      Thanks for your help
      Kind regards
    • Hi,

      You can simply react on a button (can be within or outside the dialog) and delete the dialog by using its handle.

      The memory gets freed automatically by the Window Manager.

      For the background you have to set either a custom callback which clears it with a color or set a color for the background window.

      Here is a quick example on how to do:

      C Source Code

      1. #include "DIALOG.h"
      2. /*********************************************************************
      3. *
      4. * Defines
      5. *
      6. **********************************************************************
      7. */
      8. #define ID_WINDOW_0 (GUI_ID_USER + 0x00)
      9. #define ID_BUTTON_0 (GUI_ID_USER + 0x01)
      10. // USER START (Optionally insert additional defines)
      11. // USER END
      12. /*********************************************************************
      13. *
      14. * Static data
      15. *
      16. **********************************************************************
      17. */
      18. // USER START (Optionally insert additional static data)
      19. // USER END
      20. /*********************************************************************
      21. *
      22. * _aDialogCreate
      23. */
      24. static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
      25. { WINDOW_CreateIndirect, "Window", ID_WINDOW_0, 0, 0, 320, 240, 0, 0x0, 0 },
      26. { BUTTON_CreateIndirect, "Delete", ID_BUTTON_0, 25, 25, 80, 20, 0, 0x0, 0 },
      27. // USER START (Optionally insert additional widgets)
      28. // USER END
      29. };
      30. /*********************************************************************
      31. *
      32. * Static code
      33. *
      34. **********************************************************************
      35. */
      36. // USER START (Optionally insert additional static code)
      37. // USER END
      38. /*********************************************************************
      39. *
      40. * _cbDialog
      41. */
      42. static void _cbDialog(WM_MESSAGE * pMsg) {
      43. int NCode;
      44. int Id;
      45. // USER START (Optionally insert additional variables)
      46. // USER END
      47. switch (pMsg->MsgId) {
      48. case WM_NOTIFY_PARENT:
      49. Id = WM_GetId(pMsg->hWinSrc);
      50. NCode = pMsg->Data.v;
      51. switch(Id) {
      52. case ID_BUTTON_0: // Notifications sent by 'Delete'
      53. switch(NCode) {
      55. // USER START (Optionally insert code for reacting on notification message)
      56. // USER END
      57. break;
      59. // USER START (Optionally insert code for reacting on notification message)
      60. //
      61. // Delete this dialog (pMsg->hWin) on button release
      62. //
      63. WM_DeleteWindow(pMsg->hWin);
      64. // USER END
      65. break;
      66. // USER START (Optionally insert additional code for further notification handling)
      67. // USER END
      68. }
      69. break;
      70. // USER START (Optionally insert additional code for further Ids)
      71. // USER END
      72. }
      73. break;
      74. // USER START (Optionally insert additional message handling)
      75. // USER END
      76. default:
      77. WM_DefaultProc(pMsg);
      78. break;
      79. }
      80. }
      81. /*********************************************************************
      82. *
      83. * _cbBk
      84. */
      85. static void _cbBk(WM_MESSAGE * pMsg) {
      86. switch (pMsg->MsgId) {
      87. case WM_PAINT:
      88. GUI_SetBkColor(GUI_BLACK);
      89. GUI_Clear();
      90. break;
      91. default:
      92. WM_DefaultProc(pMsg);
      93. break;
      94. }
      95. }
      96. /*********************************************************************
      97. *
      98. * Public code
      99. *
      100. **********************************************************************
      101. */
      102. /*********************************************************************
      103. *
      104. * CreateWindow
      105. */
      106. WM_HWIN CreateWindow(void);
      107. WM_HWIN CreateWindow(void) {
      108. WM_HWIN hWin;
      109. hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);
      110. return hWin;
      111. }
      112. /*********************************************************************
      113. *
      114. * MainTask
      115. */
      116. void MainTask(void) {
      117. WM_HWIN hDialog;
      118. GUI_Init();
      119. //
      120. // Either set a color for the desktop window, or set a suctom
      121. // callback for it. This will make sure the background gets
      122. // redrawn/cleared properly.
      123. //
      124. //WM_SetDesktopColor(GUI_BLACK);
      125. WM_SetCallback(WM_HBKWIN, _cbBk);
      126. hDialog = CreateWindow();
      127. while (1) {
      128. GUI_Delay(100);
      129. if (!WM_IsWindow(hDialog)) {
      130. GUI_Delay(1000);
      131. hDialog = CreateWindow();
      132. }
      133. }
      134. }
      135. /*************************** End of file ****************************/
      Display All
    • Hello Sven,

      This got me further, thanks for the code you posted.

      However, if I use your example, when I press the "Delete" Button, the code execution returns to MainTask. Now imagine that in MainTask (after calling CreateWindow() and returning from it) I display BMP images and use drawing primitives (GUI_DrawRect(), GUI_DrawLine(), etc...), well the drawings are all broken and some rectangles are drawn incomplete (i.e. only two sides are drawn).

      If I comment out the line "hDialog = CreateWindow();" so the dialog is not used, my lines and rectangles are perfectly drawn. Its like emWIN is not drawing in that portion of the screen when hDialog = CreateWindow(); is executed.

      I spent hours trying to solve this issue.

      Kind regards
    • Hi,

      Things are broken because the Window Manager doesn't "know" about your drawing operations. The Window Manager expects any drawing operations within a WM_PAINT event.

      The best would be to not draw in MainTask. Move the drawings to a window. This window could also be the desktop window, just draw in the callback set for WM_HBKWIN.


      C Source Code

      1. /*********************************************************************
      2. *
      3. * _cbBk
      4. */
      5. static void _cbBk(WM_MESSAGE * pMsg) {
      6. switch (pMsg->MsgId) {
      7. case WM_PAINT:
      8. GUI_SetBkColor(GUI_BLACK);
      9. GUI_Clear();
      10. //
      11. // Draw the primitves here
      12. //
      13. GUI_DrawBitmap(&BMP, sizeof(BMP), 0, 0);
      14. GUI_DrawLine(0, 0, 30, 30);
      15. //
      16. // ...
      17. //
      18. break;
      19. default:
      20. WM_DefaultProc(pMsg);
      21. break;
      22. }
      23. }
      Display All
      Or you create a dedicated window which gets created/displayed after the dialog has been deleted.

    • Hi Sven,

      I think going with your second suggestion ("... create a dedicated window which gets created/displayed after the dialog has been deleted.) would work best for me since I have a lot of function calls and code already running flawlessly in my MainTask.

      Could you show me please how to create a dedicated window in MainTask right after the dialog has been deleted? You can use your first example (from Monday) as it resembles my own code architecture/organization. I'm still having difficulties wrapping my head around how to make WM "know" about my drawing operations.

      Thanks a bunch for your great help!
    • Hi,

      You can simply use the callback function of the back ground window (_cbBk) and perform the drawing operations within the WM_PAINT.

      Another way would be to create a window with WM_CreateWindowAsChild(), don't forget to set a callback function, and perform the drawings in this callback functions WM_PAINT event.

      I'm still having difficulties wrapping my head around how to make WM "know" about my drawing operations.

      It's not rellay knowing, just perform drawing operations only within WM_PAINT events. Keep the MainTask as small as possible.

      Here you will find a bunch of examples you might wnat to refer to:

    • Hello Sven,

      I'm sorry to have so many questions on such a simple thing that I'm trying to do with emWin but it's turning out to be overly complicated...

      So, as you recommended, I reorganized all my drawing functions (primitives, BMP drawing, etc..) in the call back function within the "WM_PAINT" event. I checked in the emWin reference manual what could be included in the WM_PAINT event. This is what the manual says:

      "When processing the WM_PAINT event, the following functions may not be called: WM_SelectWindow(), WM_Paint(),
      WM_DeleteWindow() and WM_CreateWindow(). Also any other functions which changes the properties of a window may not be called: WM_Move(), WM_Resize(), ...

      So I included my own drawing functions (they don't change the properties of any window) in the WM_PAINT event. Everything compiled well but
      I got the following run-time error: " Function may not be called from within a Pain event". These so called "Functions" are just my own line drawing functions organised in different functions based on what they draw. This is just modular programming so I don't do everything in a big blob. But now
      the WM_PAINT event does not like the fact that I have my own functions in it...

      Please let me know what do you suggest, as I getting very discouraged with simply be able to draw my own lines and display BMPs.

      Kind regards and thanks for your understanding.
    • Hi,

      I'm afraid but without knowing which emWin functions you are calling within WM_PAINT I can't really say why you get the error.

      Basically this error message gets only thrown for three emWin functions, WM_DeleteWindow(), WM_SelectWindow() and WM_Update().

      You can also step through your WM_PAINT event and try to find out which emWin function causes the error.


    • Hello Sven,

      Just wanted to thank you for your help and let you know that I figured out the issue. One of my function calls was passing a string (Draw("house");) and that generated the error. I simply commented out that function and all worked well after.

      Thanks again
      Kind regards