WM_SetCallback, unexpected behavior

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

    • WM_SetCallback, unexpected behavior

      emWin 6.16. Function WM_SetCallback leads to a crush with this simple code:

      C Source Code

      1. static void (*cb_prev)(WM_MESSAGE *pMsg);
      2. //===============================================
      3. static void cb_new(WM_MESSAGE *pMsg)
      4. {
      5. switch (pMsg->MsgId)
      6. {
      7. default:
      8. cb_prev(pMsg);
      9. break;
      10. }
      11. }
      12. //===============================================
      13. static void _cbDialog(WM_MESSAGE *pMsg)
      14. {
      15. switch (pMsg->MsgId)
      16. {
      17. case WM_INIT_DIALOG:
      18. {
      19. WM_HWIN hItem = WM_GetDialogItem(pMsg->hWin, ID_WINCHILD_001);
      20. cb_prev = WM_SetCallback(hItem, cb_new);
      21. }
      22. break;
      23. default:
      24. WM_DefaultProc(pMsg);
      25. break;
      26. }
      27. }
      Display All
      With 5.44 version that worked great, but somewhere between 5.44 and 6.16 this call had been added:
      WM__SendMessageNoPara(hWin, WM_SET_CALLBACK);
      There are lots of workarounds, that is not the point. It becomes an unpleasant surprise, for what possible purpose sending WM_SET_CALLBACK to a new cb may be useful??
    • Hi,

      WM_SET_CALLBACK gets sent immediately to a window after its callback has been changed by WM_SetCallback().

      WM_SetCallback() sends a WM_SET_CALLBACK message before returning the previous function pointer. So your application crashes because the function pointer is still NULL and gets called in cb_new.

      You can fix this by adding a WM_SET_CALLBACK case to cb_new that does not call cb_prev.

      Reacting on this message can be useful e.g. when setting a custom callback to the background window. In a custom callback for the background window the WM_CREATE case is unreachable (because the background window has already been created after GUI_Init() was called). WM_SET_CALLBACK can be used as a substitute, to initialize window-related variables etc.

      I hope this has brought some clarity to your concern.

      Best regards,