Не выполняется код.

Тема в разделе "WASM.WIN32", создана пользователем Euler, 11 июн 2010.

  1. Euler

    Euler New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2009
    Сообщения:
    56
    Ситуация такая: приложение можно "легально" завершить двумя способами- отправить окну WM_DESTROY "стандартными средствами"(alt+F4 или красный крестик вверху) или выбрать в меню соответствующий пункт. Пункт меню обрабатывается так:
    Код (Text):
    1. switch(uMsg)
    2. {
    3. case WM_COMMAND:
    4.     {
    5.         switch(LOWORD(wParam))
    6.         {
    7.         case MENU_EXIT:
    8.             {
    9.                 PostQuitMessage(0);
    10.                 MessageBox(g_hWnd,L"MENU_EXIT",L"",MB_OK);
    11.                 return 0;
    12.             }
    13.         ...
    14.         }
    15.     ...
    16.     }
    17. ...
    18. }
    Тут всё выполняется корректно. А обработчик WM_DESTROY выглядит так:
    Код (Text):
    1. case WM_DESTROY:
    2. {
    3.    MessageBox(g_hWnd,L"WM_DESTROY до",L"",MB_OK);
    4.    PostQuitMessage(0);
    5.    MessageBox(g_hWnd,L"WM_DESTROY после",L"",MB_OK);
    6.    return 0;
    7. }
    А вот тут сообщение "WM_DESTROY до" появляется, а "WM_DESTROY после"- нет. И вообще весь код после этого PostQuitMessage игнорируется. Хотя встроенный отладчик VS2010 показывает, что этот код выполняется(прерывания срабатывают и трассировка внешне проходит нормально).
    Сам цикл выглядит так:
    Код (Text):
    1. Msg.message=0;
    2. SetTimer(NULL,0,1000,TimerFunction);
    3. while(Msg.message!=WM_QUIT)
    4. {
    5.     if(PeekMessage(&Msg,NULL,0,0,PM_REMOVE))
    6.     {
    7.         TranslateMessage(&Msg);
    8.         DispatchMessage(&Msg);
    9.     }
    10.     if(!DoFrame())
    11.         break;
    12. }
    13. MessageBox(g_hWnd,L"",L"",MB_OK);//Сообщение не выводится.
    14. FreeMouse();
    15. FreeDirect3D();
    16. FreeWindow();
    17. return Msg.wParam;
    Подскажите пожалуйста, в чём может быть дело?
     
  2. KeSqueer

    KeSqueer Сергей

    Публикаций:
    0
    Регистрация:
    19 июл 2007
    Сообщения:
    1.183
    Адрес:
    Москва
    Euler
    Долго медитировал над Вашим кодом, и тут внезапно вспомнил, что года полтора назад у меня была та же проблема. В некоторых местах программы в силу неведомых мне причин MessageBox отказывался выдавать сообщения. Но сейчас, помедитировав, подумал, что первый параметр, передаваемый в MessageBox некорректный.
     
  3. osox

    osox New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2009
    Сообщения:
    280
    красный крестик и alt+f4 это wm_close а не wm_destroy в ответ можно или вернуть 0 тогда приложение не закроется или отдать в defwindowproc что Вы и делаете defwindowproc на wm_close вызывает destroywindow и ставит в очередь wm_destroy когда после обработки wm_close вы обрабатываете wm_destroy окно уже разрушено и g_hWnd уже к этому времени не валидный
     
  4. osox

    osox New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2009
    Сообщения:
    280
    Код (Text):
    1. switch(LOWORD(wParam))
    2.         {
    3.         case MENU_EXIT:
    4.             {
    5.                 PostQuitMessage(0);
    6.                 MessageBox(g_hWnd,L"MENU_EXIT",L"",MB_OK);
    7.                 return 0;
    8.             }
    9.         ...
    10.         }
    Вы выходите не освождая память и не разрушая окно
    лучше так
    Код (Text):
    1. switch(LOWORD(wParam))
    2.         {
    3.         case MENU_EXIT:
    4.             {
    5.                 SendMessage(hWnd, WM_CLOSE, 0, 0);
    6.                 MessageBox(g_hWnd,L"MENU_EXIT",L"",MB_OK);
    7.                 return 0;
    8.             }
    9.         ...
    10.         }
    defwindowproc вызовет destroywindow поставит в очередь wm_destroy потом вернет вам управление у вас выведется messagebox следующим вы достанете wm_destroy и сделаете postquitmessage
     
  5. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    В wm_destroy окно еще не разрушено, а просто скрыто - и дело не в этом, а в том, что после PostQuitMessage вызывать диалог бесполезно, т.к. он даже не появившись получит это самое сообщение WM_QUIT и закроется, повторно послав WM_QUIT в очередь
     
  6. osox

    osox New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2009
    Сообщения:
    280
    до wm_destroy при обработке wm_close вызывается destroywindow Вы считаете что не разрушено ?
     
  7. osox

    osox New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2009
    Сообщения:
    280
    Euler
    а у вас при отладке в окне watch есть @err,hr ?
    а то он сразу выводит статус последней ошибки
    MessageBox(0x456, "", "", 0);
    @err,hr 0x00000578 Недопустимый дескриптор окна. unsigned long
     
  8. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Перечитай мсдн - wm_destroy посылается именно из DestroyWindow после сокрытия окна, но до его разрушения.
    И первый пост кстати тоже внимательно перечитай - первый MessageBox до PostQuitMessage отображается нормально, поэтому дело не в окне
     
  9. osox

    osox New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2009
    Сообщения:
    280
    leo
    Вы правы я неправ
     
  10. osox

    osox New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2009
    Сообщения:
    280
    хмм вот так и помогай людям только навредил а ведь и я сам верил в то что говорю
     
  11. osox

    osox New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2009
    Сообщения:
    280
    ну хоть + что то новое узнал :)
    теперь то я точно допишу свои проекты )))
     
  12. osox

    osox New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2009
    Сообщения:
    280
    аплодисменты leo
    ))) не дал сбиться с пути
     
  13. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    osox
    Ну тебя, брат, понесло под аплодисменты :)
    Тогда получи ложечку критики. МСДН это конечно хорошо, но нужно и свою "соображалку включать" - сам подумай, как окно может быть уже разрушено, если wm_destroy шлется ни кому-нибудь, а самому этому окну ? И соотв-но в его WindowProc передается хэндл, который должен быть еще валидным, хотя бы для того, чтобы вызвать родительскую процедуру CallWindowProc или DefWindowProc. Да и wm_destroy для дочерних окон, вызываются после. И т.д. и т.п.
     
  14. Euler

    Euler New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2009
    Сообщения:
    56
    Всё понял, огромное спасибо за ваши ответы. leo, вам отдельная благодарность за развёрнутые ответы- очень часто ваши посты на этом форуме помогали мне решать свои задачи.