Opened DROPDOWN issue with WM_GetFocussedWindow()

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

    • Opened DROPDOWN issue with WM_GetFocussedWindow()

      Hello.

      Very usual conditions:

      There is a FrameWindow with some widgets, one of them is DROPDOWN (in attached sample there is only a single DROPDOWN - for simplify).

      And there is a dedicated key (in attached sample it is SHIFT-key) for calling another window (for example MessageBox).

      If this window being closed then the control and focus should return to the widget, from which this window was called.

      So, if press a key while a DROPDOWN-widget is in opened state (opened by SPACE-key), then after return from called window there is a run-tume error, because DROPDOWN-widget was closed, and already there is no object (derived listbox-item), from which this window was opened.

      C Source Code

      1. #include "DIALOG.h"
      2. #define ID_FRAMEWIN_0 (GUI_ID_USER + 0x00)
      3. #define ID_DROPDOWN_0 (GUI_ID_USER + 0x01)
      4. #define RECOMMENDED_MEMORY (1024L * 5)
      5. static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
      6. { FRAMEWIN_CreateIndirect, "Framewin", ID_FRAMEWIN_0, 0, 0, 320, 240, 0, 0x0, 0 },
      7. { DROPDOWN_CreateIndirect, "Dropdown", ID_DROPDOWN_0, 100, 40, 80, 80, 0, 0x0, 0 },
      8. };
      9. void messageBox(const char * pText, const char * pCaption) {
      10. WM_HWIN focusedWindow = WM_GetFocussedWindow();
      11. GUI_MessageBox(pText, pCaption, GUI_MESSAGEBOX_CF_MODAL | GUI_MESSAGEBOX_CF_MOVEABLE);
      12. WM_SetFocus(focusedWindow);
      13. }
      14. static void _cbDialog(WM_MESSAGE * pMsg) {
      15. WM_HWIN hItem;
      16. int NCode;
      17. int Id;
      18. WM_KEY_INFO * pInfo = (WM_KEY_INFO *)pMsg->Data.p;
      19. switch (pMsg->MsgId) {
      20. case WM_INIT_DIALOG:
      21. hItem = WM_GetDialogItem(pMsg->hWin, ID_DROPDOWN_0);
      22. DROPDOWN_AddString(hItem, "Item 1");
      23. DROPDOWN_AddString(hItem, "Item 2");
      24. DROPDOWN_AddString(hItem, "Item 3");
      25. break;
      26. case WM_KEY:
      27. if (pInfo->PressedCnt == 0) {
      28. switch (pInfo->Key) {
      29. case GUI_KEY_SHIFT:
      30. messageBox("Message", "Title");
      31. break;
      32. }
      33. }
      34. break;
      35. default:
      36. WM_DefaultProc(pMsg);
      37. break;
      38. }
      39. }
      40. static WM_HWIN CreateFramewin(void) {
      41. WM_HWIN hWin;
      42. hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);
      43. return hWin;
      44. }
      45. void MainTask(void) {
      46. GUI_Init();
      47. if (GUI_ALLOC_GetNumFreeBytes() < RECOMMENDED_MEMORY) {
      48. GUI_ErrorOut("Not enough memory available.");
      49. return;
      50. }
      51. CreateFramewin();
      52. while (1) {
      53. GUI_Delay(100);
      54. };
      55. }
      Display All

      How to resolve this issue?
      Best regards,
      Volodymyr.

      The post was edited 1 time, last by volodymyr ().

    • Hello,

      maybe something like this

      C Source Code

      1. #include "DIALOG.h"
      2. #define ID_FRAMEWIN_0 (GUI_ID_USER + 0x00)
      3. #define ID_DROPDOWN_0 (GUI_ID_USER + 0x01)
      4. #define RECOMMENDED_MEMORY (1024L * 5)
      5. /***** for a dropdown handle *****/
      6. WM_HWIN hDropdown;
      7. /********************************/
      8. static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
      9. { FRAMEWIN_CreateIndirect, "Framewin", ID_FRAMEWIN_0, 0, 0, 320, 240, 0, 0x0, 0 },
      10. { DROPDOWN_CreateIndirect, "Dropdown", ID_DROPDOWN_0, 100, 40, 80, 80, 0, 0x0, 0 },
      11. };
      12. void messageBox(const char * pText, const char * pCaption) {
      13. /***** if focused window is opened listbox ******/
      14. U8 fw_is_listbox = 0;
      15. /***********************************************/
      16. WM_HWIN focusedWindow = WM_GetFocussedWindow();
      17. /******* set if it is listbox ******/
      18. if (focusedWindow == DROPDOWN_GetListbox(hDropdown))
      19. fw_is_listbox = 1;
      20. /**********************************/
      21. GUI_MessageBox(pText, pCaption, GUI_MESSAGEBOX_CF_MODAL | GUI_MESSAGEBOX_CF_MOVEABLE);
      22. /******* if it is not a listbox do as usual ******/
      23. if (fw_is_listbox == 0)
      24. WM_SetFocus(focusedWindow);
      25. /**** else show listbox again ****/
      26. else
      27. DROPDOWN_Expand(hDropdown);
      28. /*** or you can just set focus on dropdown in closed state ***/
      29. // WM_SetFocus(hDropdown); // instead of DROPDOWN_Expand()
      30. /*********************************/
      31. }
      32. static void _cbDialog(WM_MESSAGE * pMsg) {
      33. WM_HWIN hItem;
      34. int NCode;
      35. int Id;
      36. WM_KEY_INFO * pInfo = (WM_KEY_INFO *)pMsg->Data.p;
      37. switch (pMsg->MsgId) {
      38. case WM_INIT_DIALOG:
      39. hItem = WM_GetDialogItem(pMsg->hWin, ID_DROPDOWN_0);
      40. DROPDOWN_AddString(hItem, "Item 1");
      41. DROPDOWN_AddString(hItem, "Item 2");
      42. DROPDOWN_AddString(hItem, "Item 3");
      43. /**** keep dropdown handle ****/
      44. hDropdown = hItem;
      45. /******************************/
      46. break;
      47. case WM_KEY:
      48. if (pInfo->PressedCnt == 0) {
      49. switch (pInfo->Key) {
      50. case GUI_KEY_SHIFT:
      51. messageBox("Message", "Title");
      52. break;
      53. }
      54. }
      55. break;
      56. default:
      57. WM_DefaultProc(pMsg);
      58. break;
      59. }
      60. }
      61. static WM_HWIN CreateFramewin(void) {
      62. WM_HWIN hWin;
      63. hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);
      64. return hWin;
      65. }
      66. void MainTask(void) {
      67. GUI_Init();
      68. if (GUI_ALLOC_GetNumFreeBytes() < RECOMMENDED_MEMORY) {
      69. GUI_ErrorOut("Not enough memory available.");
      70. return;
      71. }
      72. CreateFramewin();
      73. while (1) {
      74. GUI_Delay(100);
      75. };
      76. }
      Display All
      In case you want just to focus on dropdown in closed state there you can do easier:

      if (focusedWindow == DROPDOWN_GetListbox(hDropdown))
      focusedWindow = hDropdown;

      without using fw_is_listbox variable.

      Alex.

      The post was edited 3 times, last by LexaGB ().

    • LexaGb wrote:

      Hello,

      maybe something like this

      C Source Code

      1. #include "DIALOG.h"
      2. #define ID_FRAMEWIN_0 (GUI_ID_USER + 0x00)
      3. #define ID_DROPDOWN_0 (GUI_ID_USER + 0x01)
      4. #define RECOMMENDED_MEMORY (1024L * 5)
      5. /***** for a dropdown handle *****/
      6. WM_HWIN hDropdown;
      7. /********************************/
      8. static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
      9. { FRAMEWIN_CreateIndirect, "Framewin", ID_FRAMEWIN_0, 0, 0, 320, 240, 0, 0x0, 0 },
      10. { DROPDOWN_CreateIndirect, "Dropdown", ID_DROPDOWN_0, 100, 40, 80, 80, 0, 0x0, 0 },
      11. };
      12. void messageBox(const char * pText, const char * pCaption) {
      13. /***** if focused window is opened listbox ******/
      14. U8 fw_is_listbox = 0;
      15. /***********************************************/
      16. WM_HWIN focusedWindow = WM_GetFocussedWindow();
      17. /******* set if it is listbox ******/
      18. if (focusedWindow == DROPDOWN_GetListbox(hDropdown))
      19. fw_is_listbox = 1;
      20. /**********************************/
      21. GUI_MessageBox(pText, pCaption, GUI_MESSAGEBOX_CF_MODAL | GUI_MESSAGEBOX_CF_MOVEABLE);
      22. /******* if it is not a listbox do as usual ******/
      23. if (fw_is_listbox == 0)
      24. WM_SetFocus(focusedWindow);
      25. /**** else show listbox again ****/
      26. else
      27. DROPDOWN_Expand(hDropdown);
      28. /*** or you can just set focus on dropdown in closed state ***/
      29. // WM_SetFocus(hDropdown); // instead of DROPDOWN_Expand()
      30. /*********************************/
      31. }
      32. static void _cbDialog(WM_MESSAGE * pMsg) {
      33. WM_HWIN hItem;
      34. int NCode;
      35. int Id;
      36. WM_KEY_INFO * pInfo = (WM_KEY_INFO *)pMsg->Data.p;
      37. switch (pMsg->MsgId) {
      38. case WM_INIT_DIALOG:
      39. hItem = WM_GetDialogItem(pMsg->hWin, ID_DROPDOWN_0);
      40. DROPDOWN_AddString(hItem, "Item 1");
      41. DROPDOWN_AddString(hItem, "Item 2");
      42. DROPDOWN_AddString(hItem, "Item 3");
      43. /**** keep dropdown handle ****/
      44. hDropdown = hItem;
      45. /******************************/
      46. break;
      47. case WM_KEY:
      48. if (pInfo->PressedCnt == 0) {
      49. switch (pInfo->Key) {
      50. case GUI_KEY_SHIFT:
      51. messageBox("Message", "Title");
      52. break;
      53. }
      54. }
      55. break;
      56. default:
      57. WM_DefaultProc(pMsg);
      58. break;
      59. }
      60. }
      61. static WM_HWIN CreateFramewin(void) {
      62. WM_HWIN hWin;
      63. hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);
      64. return hWin;
      65. }
      66. void MainTask(void) {
      67. GUI_Init();
      68. if (GUI_ALLOC_GetNumFreeBytes() < RECOMMENDED_MEMORY) {
      69. GUI_ErrorOut("Not enough memory available.");
      70. return;
      71. }
      72. CreateFramewin();
      73. while (1) {
      74. GUI_Delay(100);
      75. };
      76. }
      Display All
      In case you want just to focus on dropdown in closed state there you can do easier:

      if (focusedWindow == DROPDOWN_GetListbox(hDropdown))
      focusedWindow = hDropdown;

      without using fw_is_listbox variable.

      Alex.
      Hello, Alex.

      I have many dialog windows in my project each of them may contain DROPDOWN-widget or not.

      Also I have a popup window (also dialog-window), that can appear at any time if some non-GUI issue occurs, with return focus to window or widget that had focus before appearing popup window when it is closed.

      And I don't know which window and which widget will be focused before appearing popup-window.

      Your way is to know handles of all DROPDOWN's in all windows and give them to popup-window, but I doubt it is good way.

      I would like to find a way to get the handle of parent DROPDOWN of opened LISTBOX (or even parent FRAMEWIN-window) and set focus on it if the handle of its LISTBOX (or other widget) is invalid.

      P.S. I already found an universal and very elegant way.
      I check if focused object is LISTBOX (by checking its callback), then get its OWNER (LISTBOX_GetOwner()) and then if this owner is DROPDOWN (also checking its callback), set focus to it.

      Solved.
      Best regards,
      Volodymyr.

      The post was edited 3 times, last by volodymyr ().

    • Hello,

      yes, I think it is the good way, but in case your LISTBOXes' default callbacks are changed by custom callbacks, also be sure to check these callbacks.

      Alex.
    • LexaGb wrote:

      Hello,

      yes, I think it is the good way, but in case your LISTBOXes' default callbacks are changed by custom callbacks, also be sure to check these callbacks.

      Alex.
      Yes, I already did so, I check both callbacks for DROPDOWN - original and my own. There is no redefined callbacks for LISTBOXes in my project.
      Best regards,
      Volodymyr.