Dropwdown Event WM_NOTIFICATION_CLICKED not received

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

  • Dropwdown Event WM_NOTIFICATION_CLICKED not received

    Hey, i'd like to create a dropdown. SO i used the GUI Builder to create the skeleton code.

    My idea is: when the user presses the dropdown the list is supposed to expand, when the user presses somewhere outside the dropdown, the list should collapse.

    Now i'm only receiving WM_NOTIFICATION_LOST_FOCUS events in my callback routine. The Event WM_NOTIFICATION_CLICKED never occurs. Does anybody know why?


    C Source Code

    1. /*********************************************************************
    2. * *
    3. * SEGGER Microcontroller GmbH & Co. KG *
    4. * Solutions for real time microcontroller applications *
    5. * *
    6. **********************************************************************
    7. * *
    8. * C-file generated by: *
    9. * *
    10. * GUI_Builder for emWin version 5.32 *
    11. * Compiled Oct 8 2015, 11:59:02 *
    12. * (c) 2015 Segger Microcontroller GmbH & Co. KG *
    13. * *
    14. **********************************************************************
    15. * *
    16. * Internet: www.segger.com Support: support@segger.com *
    17. * *
    18. **********************************************************************
    19. */
    20. // USER START (Optionally insert additional includes)
    21. #include "FramewinDLG_new.h"
    22. #include "cmsis_os.h"
    23. // USER END
    24. /*********************************************************************
    25. *
    26. * Defines
    27. *
    28. **********************************************************************
    29. */
    30. #define ID_FRAMEWIN_0 (GUI_ID_USER + 0x00)
    31. #define ID_DROPDOWN_0 (GUI_ID_USER + 0x04)
    32. // USER START (Optionally insert additional defines)
    33. ///Maximale Breite des Displays
    34. #define X_MAX 240
    35. ///Maximale Höhe des Displays
    36. #define Y_MAX 320
    37. //
    38. // Recommended memory to run the sample with adequate performance
    39. //
    40. #define RECOMMENDED_MEMORY (1024L * 2)
    41. // USER END
    42. /*********************************************************************
    43. *
    44. * Static data
    45. *
    46. **********************************************************************
    47. */
    48. // USER START (Optionally insert additional static data)
    49. // USER END
    50. /*********************************************************************
    51. *
    52. * _aDialogCreate
    53. */
    54. static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] =
    55. {
    56. { FRAMEWIN_CreateIndirect, "Framewin", ID_FRAMEWIN_0, 0, 0, X_MAX, Y_MAX, 0, 0x0, 0 },
    57. { DROPDOWN_CreateIndirect, "Dropdown_menu", ID_DROPDOWN_0, 0, 0, 144, 25, 0, 0x0, 0 },
    58. // USER START (Optionally insert additional widgets)
    59. // USER END
    60. };
    61. /*********************************************************************
    62. *
    63. * Static code
    64. *
    65. **********************************************************************
    66. */
    67. // USER START (Optionally insert additional static code)
    68. // USER END
    69. /*********************************************************************
    70. *
    71. * _cbDialog
    72. */
    73. static void _cbDialog(WM_MESSAGE * pMsg)
    74. {
    75. //TODO weg
    76. volatile uint8_t test = 0;
    77. WM_HWIN hItem;
    78. int NCode;
    79. int Id;
    80. // USER START (Optionally insert additional variables)
    81. // USER END
    82. switch (pMsg->MsgId)
    83. {
    84. case WM_INIT_DIALOG:
    85. //
    86. // Initialization of 'Dropdown_menu'
    87. //
    88. hItem = WM_GetDialogItem(pMsg->hWin, ID_DROPDOWN_0);
    89. DROPDOWN_SetFont(hItem, GUI_FONT_20_1);
    90. DROPDOWN_AddString(hItem, "Show Menue");
    91. DROPDOWN_AddString(hItem, "Show Ike");
    92. DROPDOWN_AddString(hItem, "Show Sensor Values");
    93. // USER START (Optionally insert additional code for further widget initialization)
    94. // USER END
    95. break;
    96. case WM_NOTIFY_PARENT:
    97. test++;
    98. test += 11;
    99. test -= 9;
    100. Id = WM_GetId(pMsg->hWinSrc);
    101. NCode = pMsg->Data.v;
    102. switch (Id)
    103. {
    104. case ID_DROPDOWN_0: // Notifications sent by 'Dropdown_menu'
    105. switch (NCode)
    106. {
    107. case WM_NOTIFICATION_CLICKED:
    108. // USER START (Optionally insert code for reacting on notification message)
    109. hItem = WM_GetDialogItem(pMsg->hWin, ID_DROPDOWN_0);
    110. test++;
    111. test += 4;
    112. test--;
    113. DROPDOWN_Expand(hItem);
    114. // USER END
    115. break;
    116. case WM_NOTIFICATION_RELEASED:
    117. // USER START (Optionally insert code for reacting on notification message)
    118. // USER END
    119. break;
    120. case WM_NOTIFICATION_SEL_CHANGED:
    121. // USER START (Optionally insert code for reacting on notification message)
    122. // USER END
    123. break;
    124. // USER START (Optionally insert additional code for further notification handling)
    125. case WM_NOTIFICATION_LOST_FOCUS:
    126. // USER START (Optionally insert code for reacting on notification message)
    127. hItem = WM_GetDialogItem(pMsg->hWin, ID_DROPDOWN_0);
    128. test++;
    129. test += 4;
    130. test--;
    131. DROPDOWN_Collapse(hItem);
    132. // USER END
    133. }
    134. break;
    135. // USER START (Optionally insert additional code for further Ids)
    136. // USER END
    137. }
    138. break;
    139. // USER START (Optionally insert additional message handling)
    140. // USER END
    141. default:
    142. WM_DefaultProc(pMsg);
    143. break;
    144. }
    145. }
    146. /*********************************************************************
    147. *
    148. * Public code
    149. *
    150. **********************************************************************
    151. */
    152. /*********************************************************************
    153. *
    154. * CreateFramewin
    155. */
    156. WM_HWIN CreateFramewin_new(void)
    157. {
    158. WM_HWIN hWin;
    159. //
    160. // Check if recommended memory for the sample is available
    161. //
    162. if (GUI_ALLOC_GetNumFreeBytes() < RECOMMENDED_MEMORY)
    163. {
    164. GUI_ErrorOut("Not enough memory available.");
    165. return 0;
    166. }
    167. hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);
    168. return hWin;
    169. }
    170. // USER START (Optionally insert additional public code)
    171. // USER END
    172. /*************************** End of file ****************************/
    Display All


    my display thread looks like this

    Source Code

    1. void DisplayThread(void const * argument)
    2. {
    3. //Display Init.
    4. GUI_Init();
    5. CreateFramewin_new();
    6. const size_t nMax = 32;
    7. uint8_t * touchcoords[nMax];
    8. for (;;)
    9. {
    10. snprintf((char *) touchcoords, nMax, "X: %04d, Y: %04d", touchX, touchY);
    11. GUI_DispStringAt((char *) touchcoords, 0, 0);
    12. WM_Exec();
    13. osDelay(500);
    14. }
    15. }
    Display All


    The GUI_TOUCH_StoreStateEx() is called in a separate thread every 25ms to get the newest touched coordinates (that part works, since i'm receiving events)

    Now my question is, how can i expand the dropdown list when pressing on it?

    Thx for your help :)
  • Hi,

    I tested you application but it caused a crash because of an endless loop generated with the functions DROPDOWN_Expand/Collapse(). Below is the application slightly changed. Now the DROPDOWN widget closes if anywhere outside the widget a pressed event occures.

    C Source Code

    1. #include "DIALOG.h"
    2. /*********************************************************************
    3. *
    4. * Defines
    5. *
    6. **********************************************************************
    7. */
    8. #define ID_FRAMEWIN_0 (GUI_ID_USER + 0x00)
    9. #define ID_DROPDOWN_0 (GUI_ID_USER + 0x04)
    10. // USER START (Optionally insert additional defines)
    11. ///Maximale Breite des Displays
    12. #define X_MAX 240
    13. ///Maximale Höhe des Displays
    14. #define Y_MAX 320
    15. /*********************************************************************
    16. *
    17. * Static data
    18. *
    19. **********************************************************************
    20. */
    21. /*********************************************************************
    22. *
    23. * _aDialogCreate
    24. */
    25. static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
    26. { FRAMEWIN_CreateIndirect, "Framewin", ID_FRAMEWIN_0, 0, 0, X_MAX, Y_MAX, 0, 0x0, 0 },
    27. { DROPDOWN_CreateIndirect, "Dropdown_menu", ID_DROPDOWN_0, 0, 0, 144, 80, 0, 0x0, 0 },
    28. };
    29. static WM_HWIN _hDropDown;
    30. /*********************************************************************
    31. *
    32. * Static code
    33. *
    34. **********************************************************************
    35. */
    36. /*********************************************************************
    37. *
    38. * _cbDialog
    39. */
    40. static void _cbDialog(WM_MESSAGE * pMsg) {
    41. WM_HWIN hItem;
    42. int NCode;
    43. int Id;
    44. switch (pMsg->MsgId) {
    45. case WM_INIT_DIALOG:
    46. //
    47. // Initialization of 'Dropdown_menu'
    48. //
    49. _hDropDown = hItem = WM_GetDialogItem(pMsg->hWin, ID_DROPDOWN_0);
    50. DROPDOWN_SetFont(hItem, GUI_FONT_20_1);
    51. DROPDOWN_AddString(hItem, "Show Menue");
    52. DROPDOWN_AddString(hItem, "Show Ike");
    53. DROPDOWN_AddString(hItem, "Show Sensor Values");
    54. break;
    55. case WM_NOTIFY_PARENT:
    56. Id = WM_GetId(pMsg->hWinSrc);
    57. NCode = pMsg->Data.v;
    58. switch (Id)
    59. {
    60. case ID_DROPDOWN_0: // Notifications sent by 'Dropdown_menu'
    61. switch (NCode) {
    62. case WM_NOTIFICATION_CLICKED:
    63. break;
    64. case WM_NOTIFICATION_RELEASED:
    65. break;
    66. case WM_NOTIFICATION_SEL_CHANGED:
    67. break;
    68. case WM_NOTIFICATION_LOST_FOCUS:
    69. break;
    70. }
    71. break;
    72. }
    73. break;
    74. default:
    75. WM_DefaultProc(pMsg);
    76. break;
    77. }
    78. }
    79. /*********************************************************************
    80. *
    81. * CreateFramewin
    82. */
    83. static void _PidHook(GUI_PID_STATE * pState) {
    84. WM_HWIN hListBox;
    85. //
    86. // Check if pState is not a null pointer
    87. //
    88. if (pState) {
    89. //
    90. // Get the LISTBOX attached to the dropdown, if it not 0 the DROPDOWN is expansed
    91. //
    92. hListBox = DROPDOWN_GetListbox(_hDropDown);
    93. if (hListBox) {
    94. //
    95. // If PID is pressed..
    96. //
    97. if (pState->Pressed) {
    98. //
    99. // .. and the window under the input is not the DROPDOWN
    100. // or the LISTBOX widget, close the DROPDOWN.
    101. //
    102. if ((hListBox != WM_Screen2hWin(pState->x, pState->y)) &&
    103. (_hDropDown != WM_Screen2hWin(pState->x, pState->y))) {
    104. DROPDOWN_Collapse(_hDropDown);
    105. }
    106. }
    107. }
    108. }
    109. }
    110. /*********************************************************************
    111. *
    112. * Public code
    113. *
    114. **********************************************************************
    115. */
    116. /*********************************************************************
    117. *
    118. * CreateFramewin
    119. */
    120. WM_HWIN CreateFramewin_new(void) {
    121. WM_HWIN hWin;
    122. hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);
    123. return hWin;
    124. }
    125. /*********************************************************************
    126. *
    127. * Public code
    128. *
    129. **********************************************************************
    130. */
    131. void MainTask(void) {
    132. GUI_Init();
    133. CreateFramewin_new();
    134. GUI_PID_SetHook(_PidHook);
    135. while(1) {
    136. GUI_Delay(1000);
    137. }
    138. }
    Display All


    In WM_INIT_DIALOG we remember the handle of the DROPDOWN widget and check in _PidHook if the input is outside the DROPDOWN widget and outside the attached LISTBOX widget.
    After setting the _PidHook function it gets called each time a new PID input gets passed to emWin.

    Depending on the emWin version you are using the function GUI_PID_SetHook() might not be available (it was introduced with version 5.38). If this the case try to call GUI_PID__SetHook() instead (it works almost the same but gets called after the PID input is passed to emWin).

    Regards,
    Sven
    Please read the forum rules before posting.

    Keep in mind, this is *not* a support forum.
    Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
    Should you be entitled to support you can contact us via our support system: segger.com/ticket/

    Or you can contact us via e-mail.
  • hey
    big thx for your great help. :)
    I have been working with your solution this weekend and it works very well. :D
    Based on your solution i was able to implement my own menu.
    I couldn't figure out, what emWin Version ST is using, but it didn't support GUI_PID_SetHook(), but GUI_PID__SetHook() works fine as well :)
  • Hi,

    to get the emWin version search for GUI_Version.h. In that file is a define like:

    #define GUI_VERSION 54011

    The version above would V5.40k.

    Regards,
    Sven
    Please read the forum rules before posting.

    Keep in mind, this is *not* a support forum.
    Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
    Should you be entitled to support you can contact us via our support system: segger.com/ticket/

    Or you can contact us via e-mail.
  • Hi Sven,

    I am also facing the same issue, I just tested the code modified by you. But still i am facing the same issue.
    Please find the screen shot of call stack window in the attachment.

    Also One more interesting thing is if I Add string of character size i.e. "Fe","Zn","Al".. and check the dropdown , it does not crashes.
    But when i increase the size more than 2 chars i.e. Fe_Steel, Zn_Si.... it crashes.

    Please help ....

    Thanks and Best Regards,
    Rohit.
    Images
    • call_stack_dropdown_crash.jpg

      296.36 kB, 1,366×768, viewed 525 times
  • why are you getting a task exit error?
    Are you using an RTOS? If so could you check if a task accidentally breaks out of his loop.
    For me i took the code posted above and it works really nicely. I did not make any big adjustments :thumbup:
    The only adjustment i made was: since i'm using an RTOS i canot use GUI_DELAY(). I had to use the RTOS own delay function in combination with GUI_EXEC();
    Both (GUI_EXEC() and the delay function are called in a separate task :)
  • i am using freeRtos.

    "why are you getting a task exit error?"
    The Scheduler is checking for any task exit error before context switch.



    When DROPDOWN_Expand is called the program crashes. This is due to some memory locking issue ?


    When i tested this condition with stm32f429 stemwin library it is working fine. But there is some issue with stm32f7 stemwin library......?

    Is there any work around to get rid of the lockout condition....?

    Thanks and Best Regards,
    Rohit
  • Just to clarify. You simply replaced the Stemwin library file (aka the libStemWin****.a file) from the Stm32F7 Cube Package with the library file from the STM32F4 Cube package?
    The code is the same?

    You MUST NOT use GUI_DELAY() with an RTOS. i'm not sure what exactly GUI_DELAY internally does, but it is always better to use the RTOS own task delay functions, i.e. osDelay (delay in ms) or vTaskDelay(delay in ticks).


    I once made the bad fault to use HAL_DELAY() in a freertos project, the scheduler did not like that :P

    Use GUI_Exec and osDelay()/vTaskDelay() instead.

    Note: Use vTaskDelay if your task has been created using FreeROS Functions, use osDelay if your task has been created using the CMSIS FreeRtos API. :thumbup:

    The post was edited 4 times, last by JuliusCaesar ().

  • Hi,

    @mrohit2011
    How much memory did you spend emWin (GUI_ALLOC_AssignMemory() in the function GUI_X_Config()), try to increase the amount of memory.

    @JuliusCaesar
    Of course it is allowed to call GUI_Delay() with a RTOS. A GUI_Delay() performs all required operations to keep the GUI 'alive' (like checking for touch, check for timer, updating any windows, etc) beside of that it also calles a delay of the RTOS. Of course, this works only if it configured correctly. Check the functions below if they are implemented correctly:

    GUI_X_GetTime()
    GUI_X_Delay()
    GUI_X_ExecIdle()

    Attached are some sample implementation for different RTOS.

    Regards,
    Sven
    Files
    • GUI_X.zip

      (8.27 kB, downloaded 331 times, last: )
    Please read the forum rules before posting.

    Keep in mind, this is *not* a support forum.
    Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
    Should you be entitled to support you can contact us via our support system: segger.com/ticket/

    Or you can contact us via e-mail.