Text Widget does not update on multiple invalidate call in WM_PAINT Block

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

    • Text Widget does not update on multiple invalidate call in WM_PAINT Block

      Text Widget does update on multiple invalidate call in WM_PAINT Block
      I am trying to update text widget in a WM_Paint block but it does not.My code


      This is initialization


      Source Code

      1. hItem = WM_GetDialogItem(pMsg->hWin, ID_TEXT_0);
      2. TEXT_SetTextColor(hItem, GUI_MAKE_COLOR(0x00FFFFFF));
      3. TEXT_SetTextAlign(hItem, GUI_TA_HCENTER | GUI_TA_VCENTER);
      4. TEXT_SetText(hItem, "hello");
      5. WM_SetCallback(hItem, _cbFaultAlertText);


      Now I am invalidating it using WM_Invalidate


      Source Code

      1. hItem = WM_GetDialogItem(pMsg->hWin, ID_TEXT_0);
      2. WM_Invalidate(hItem);
      And it callback funtion


      Source Code

      1. /* fault_alert_text callback */
      2. static void _cbFaultAlertText(WM_MESSAGE * pMsg)
      3. {
      4. /* Decode message type */
      5. switch (pMsg->MsgId)
      6. {
      7. /* Component repaint message */
      8. case WM_PAINT:
      9. {
      10. static char str1[20] = {'\0'};
      11. printLogs("User Data :: a : %d, s : %s\r\n", data.a, data.s);
      12. sprintf(str1, "%s : %d", data.s, data.a);
      13. TEXT_SetTextColor(pMsg->hWin, GUI_MAKE_COLOR(0x00FFFFFF));
      14. TEXT_SetTextAlign(pMsg->hWin, GUI_TA_HCENTER | GUI_TA_VCENTER);
      15. TEXT_SetText(pMsg->hWin, str1);
      16. }
      17. /* Default callback message */
      18. default:
      19. TEXT_Callback(pMsg);
      20. }
      21. }
      Display All
      Here user data keeps updating. I am getting it into logs but can not show any changes on screen
    • Hi,

      There isn't any text shown in your TEXT widget because you have overwritten the WM_PAINT case in your callback. This means that when the TEXT widget is invalidated, your WM_PAINT case is executed which does not draw any text on the screen, but only sets widget properties.

      In this case, I would simply get rid of the TEXT callback and set the properties of the text like you did above when initializing the widget. You can redraw the TEXT widget by calling WM_InvalidateWindow() when your data has updated.

      Best regards,
      Florian
      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.
    • Thanks @

      SEGGER - Florian wrote:

      Hi,

      There isn't any text shown in your TEXT widget because you have overwritten the WM_PAINT case in your callback. This means that when the TEXT widget is invalidated, your WM_PAINT case is executed which does not draw any text on the screen, but only sets widget properties.

      In this case, I would simply get rid of the TEXT callback and set the properties of the text like you did above when initializing the widget. You can redraw the TEXT widget by calling WM_InvalidateWindow() when your data has updated.

      Best regards,
      Florian
      Thanks Florian for the answer. I did as you say but couldn't get the result as expected.


      Source Code

      1. // USER START (Optionally insert additional message handling)
      2. case WM_USER_DATA:
      3. {
      4. WM_GetUserData(pMsg->hWin, &data, sizeof(data));
      5. hItem = WM_GetDialogItem(pMsg->hWin, ID_TEXT_0);
      6. char str1[20] = {'\0'};
      7. char str2[20] = {'\0'};
      8. TEXT_GetText(hItem, str2, sizeof(str2));
      9. printLogs("get text :: %s\r\n", str2);
      10. printLogs("User Data :: a : %d, s : %s\r\n", data.a, data.s);
      11. sprintf(str1, "%s : %d", data.s, data.a);
      12. TEXT_SetText(hItem, str1);
      13. WM_InvalidateWindow(hItem);
      14. }
      15. break;
      Display All
      This is from main window callback function switch case.
    • Hi,

      A window only receives the WM_USER_DATA message shortly after WM_SetUserData() has been called. Do you call WM_SetUserData() every time you update the data?

      Also, when you update the text, do the old string and new string have the same length? There recently was an issue with TEXT widgets that they would not update when the string length had not changed after calling TEXT_SetText(). The issue has now been fixed.

      Best regards,
      Florian
      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.
    • Thanks for the reply.

      Source Code

      1. A window only receives the WM_USER_DATA message shortly after WM_SetUserData() has been called. Do you call WM_SetUserData() every time you update the data?
      Yes. Actually by means of WM_SetUserData() only I am updating data.

      Also I am changing length every time but issue is still the same.

      Source Code

      1. This means that when the TEXT widget is invalidated, your WM_PAINT case is executed which does not draw any text on the screen, but only sets widget properties.
      By Above I understand that using TEXT_SetText() I am only setting the widget properties. So how would I draw something ? What does you mean by which does not draw any text ?

      Btw I have tried removing the call back and did same thing in WM_USER_DATA case of parent window callback but no success.
    • Hi,

      a WM_PAINT case in your TEXT callback means you have to draw the text to be displayed yourself. Which is of course possible, but letting the widget draw the text is more convenient and it makes more sense for a simple widget such as the TEXT widget.

      But in your WM_PAINT case, you did not call any function to display text such as GUI_DispString(). Rather, you only set the widget's properties like the text color, alignment and the text itself instead of drawing the text. This is why no text was displayed by the widget and why you can remove the WM_PAINT case.

      However, it is still odd that the widget's text is not updated by calling the routines you mentioned. From here on I can only guess what's wrong. Can you provide me with a full example so I can reproduce the behavior you are describing? This would be very helpful to find out what exactly is causing this issue.

      Thank you and best regards,
      Florian
      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.
    • Thank you Florian.

      I have attached my code. Please let me know what you find. This is GUIBuilder generated file which I have edited. In a text widget it has added 0x64 as additional para which I don't understand. Also in WM_INIT_DIALOG case I have tried to draw rectangle which is also not displaying.

      But Still I have doubts in your explanation.


      Source Code

      1. Which is of course possible, but letting the widget draw the text is more convenient and it makes more sense for a simple widget such as the TEXT widget.
      How is it possible ? How does the widget itself draws the text ?




      I am willing to set text in a text widget and show it on display. So why would I use functions like GUI_DispString() for drawing. Purpose I am using Text Widget is in future I want it to hide and show multiple time using WM_HideWindow() and WM_ShowWindow(). So can you please let me know what is the right method for it ?
      Files
    • Hi,

      I had to change a few things to get your application working:
      • GUI_Init() was missing as the first call in your application. It is necessary that you call this before calling any other emWin routines.
      • Replace the WM_Invalidate() in the WM_USER_DATA case in _cbDialog() with the code of WM_PAINT of _cbFaultAlertText().
      • Remove the callback _cbFaultAlertText().
      • Change the TEXT color to GUI_BLACK.
      After these changes, the data was correctly displayed in the widget.

      Best regards,
      Florian
      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.
    • Thanks @SEGGER - Florian for the answer.

      • GUI_Init() is called in my earlier code. I have sent you the GUI file only with modification of main();
      • I have tried removing WM_Invalidate() and _cbFaultAlertText(). But with NO success.
      • Tried changing color to GUI_BLACK

      • Source Code

        1. GUI_SetColor(GUI_WHITE);
        2. GUI_FillRoundedRect(100, 100, 50, 50, 10);
        these lines are not working so I can see only black background with keyur : 0 written in white color in my code.





      I have again tried above 4 points which you suggested but not working.

      Can you please elaborate more ?


      Thanks
      Keyur Thumar
    • Hi,

      Attached you will find my edited version of your code that you can take as a reference.

      Best regards,
      Florian
      Files
      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.