Сообщение окну

Тема в разделе "WASM.BEGINNERS", создана пользователем Perre, 17 сен 2007.

  1. Perre

    Perre New Member

    Публикаций:
    0
    Регистрация:
    6 апр 2007
    Сообщения:
    100
    Может ли прийти окну следующее сообщение, если он не обработал предыдущее ?
     
  2. wsd

    wsd New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2007
    Сообщения:
    2.824
    Нет
    Два потока одновременно в котексте одного сорвало бы стэк
     
  3. Veter

    Veter New Member

    Публикаций:
    0
    Регистрация:
    23 дек 2006
    Сообщения:
    161
    Пытался озвучить нажатия клавиш - в окне ричедит. Периодически появлялись - "error - программа будет закрыта"
    Не из-за этого случайно?
     
  4. wsd

    wsd New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2007
    Сообщения:
    2.824
    Veter
    Эта ситуация невозможна.
    Просто если бы была - были бы такие последствия
    У Вас скорей всего самая распространённая ошибка
    доступа к памяти.
    Но это не точно и надо её смотреть.
     
  5. Perre

    Perre New Member

    Публикаций:
    0
    Регистрация:
    6 апр 2007
    Сообщения:
    100
    Wsd стэки могут быть разными, доступ к памяти возможно – об этом я и думал
    Пробовал критическую секцию ставить не помогло, наверно дело не в этом
     
  6. Mental_Mirror

    Mental_Mirror New Member

    Публикаций:
    0
    Регистрация:
    7 май 2007
    Сообщения:
    431
    Ребя, давно известно что окно ассоциируется с потоком. Также существует такое понятие как "очередь сообщений окна".
     
  7. wsd

    wsd New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2007
    Сообщения:
    2.824
    Perre
    Причём тут критическая секция?
    Я ж написал что это тех невозможно.
    При обработке мессажей для каждого поток не создаётся а несколько сразу в одном быть неможет.
    Mental_Mirror проще объяснил:)
    но смысл тот же НЕМОЖЕТ
     
  8. FatMoon

    FatMoon New Member

    Публикаций:
    0
    Регистрация:
    28 ноя 2002
    Сообщения:
    954
    Адрес:
    Russia
    Mental_Mirror
    wsd
    Подробнее, плиз.

    необработанные сообщения в очереди объединяются - это факт. А DispatchMessage ждет возврата из callback-процедуры, возвращая именно то, что мы в этой процедуре вернули. Но в некоторых случаях ...

    - то есть у нас там что-то обрабатывается и еще (возможно) не завершилось, а оконная процедура вызвана еще раз, и ей передано WM_PAINT, без всяких GetMessage (или я как-то не так понял смысл процитированной фразы?)

    ...и еще в случае создания других окон при обработке событий в нашем - например диалога или мессажбокса - наша процедура продолжает принимать события! Хотя по логике должна полностью заморозится.
    (угу, это все потому, что очередь сообщений не окна, а потока, и что у мессаджбокса или другого диалога вызывается при инициализации своя callback-функция, и потом при возврате система немного путает, кто именно и что вернул /я так думаю.../- DispatchMessage возвращает то, что вернула та, другая, и цикл обработки сообщений продолжается... Но в стеке нормально продолжает лежать адрес возврата в нашу ветку, и по завершению вызванного диалога или мессаджбокса, попадаем куда надо - в продолжение обработки того самого события, например нажатия на кнопку...)

    Так что что-то тут совсем не ясно! То есть мне было ясно до этого топика, что окну МОЖЕТ придти следующее сообщение, несмотря на необработанность текущего. :))

    Вот если бы вы сказали "Оконная/диалоговая процедура не может обрабатывать 2 и более сообщений одновременно" ... (если никто не понял, что я имел в виду - под одновременностью в данном случае понимается отсутствие API вызовов в момент выполнения обработки обоих сообщений)

    короче, я понимаю, что ничего не понимаю!
     
  9. Freeman

    Freeman New Member

    Публикаций:
    0
    Регистрация:
    10 фев 2005
    Сообщения:
    1.385
    Адрес:
    Ukraine
    исходя из цитаты проца можед обрабатывать несколько сообщений сразу в разных тредах. для проверки можно в обработчик wmpaint'a кинуть проверку текущего хендла треда и запустить паралель но тред с вызовом updatewindow
     
  10. FatMoon

    FatMoon New Member

    Публикаций:
    0
    Регистрация:
    28 ноя 2002
    Сообщения:
    954
    Адрес:
    Russia
    Не, то что в разных тредах может быть, это даже не интересно. А вот если UpdateWindow вызывать из обработки WM_COMMAND, а после вызова еще выполнять какой-то не очень быстрый код... Итак, внимание! :)
    Код (Text):
    1. ...
    2. switch (uMsg)
    3.     {
    4.         case WM_PAINT:
    5.             printf("=== WM_PAINT: hwnd = %#0lx, message = %#0lx\n",hwnd, uMsg);
    6.             // Paint the window's client area.
    7.             return DefWindowProc(hwnd, uMsg, wParam, lParam);
    8.         case WM_KEYDOWN:
    9.     printf("=== WM_KEYDOWN start: wparam = %#0lx, lparam = %#0lx\n",wParam, lParam);
    10.     InvalidateRect(hwnd,NULL,TRUE);
    11.     UpdateWindow(hwnd);
    12.     Sleep (500);
    13.     printf("=== WM_KEYDOWN end ===");
    14.     return 0;
    15.         case WM_DESTROY:
    16.         case WM_CLOSE:
    17.             // Clean up window-specific data objects.
    18. printf("from WndProc (Close) hwnd = %#0lx, message = %#0lx\n",hwnd, uMsg);
    19.             PostQuitMessage(0);
    20.             break;
    21.         //
    22.         // Process other messages.
    23.         //
    24.  default:
    25.             return DefWindowProc(hwnd, uMsg, wParam, lParam);
    26.     }
    27.     return 0;
    28. }
    29. ...
    И что имеем на выходе при нажатиях на клавиши? (оконное приложение скомпилировано как консольное, выход перенаправлен в текстовый файл, ниже кусок из него)
    То есть мы продолжаем обрабатывать одно из событий (нажатие на клавишу), а в это время вклинивается WM_PAINT и успешно выполняется.

    Вопросы? Объяснения?
     
  11. shoo

    shoo New Member

    Публикаций:
    0
    Регистрация:
    17 июл 2003
    Сообщения:
    1.537
    Адрес:
    Ukraine
    sendmessage как раз и вызывает процедуру окна напрямую, а в очередь сообщений помещает postmessage. при этом если sendmessage выполняется внутри одного потока, то это равносильно вызову оконной процедуры как подпрограммы. а если из другого потока - там есть своя синхронизация (см. Remarks k SendMessage b MSDN):
     
  12. FatMoon

    FatMoon New Member

    Публикаций:
    0
    Регистрация:
    28 ноя 2002
    Сообщения:
    954
    Адрес:
    Russia
    shoo
    Угу, 100% так оно и есть. UpdateWindow так же не возвращает управления до завершения обработки WM_PAINT, вызов Sleep в данном случае совершенно не нужен. Но так значит, окну МОЖЕТ придти следующее сообщение, даже если оно не обработало предыдущее?
     
  13. shoo

    shoo New Member

    Публикаций:
    0
    Регистрация:
    17 июл 2003
    Сообщения:
    1.537
    Адрес:
    Ukraine
    ну, в принципе, если в оконной процедуре сделать UpdateWindow себя - то такой вариант возможен.
    (в каждом заборе найдется дырка :)
    ----------
    в том числе никто не запрещает посылать сообщения окну из собственно оконной процедуры.
     
  14. FatMoon

    FatMoon New Member

    Публикаций:
    0
    Регистрация:
    28 ноя 2002
    Сообщения:
    954
    Адрес:
    Russia
    Прорезюмирую - если оконная процедура вызывает что-то, приостанавливающее выполнение кода и инициирующее другие события окна (не обязательно данного), как-то: UpdateWindow, MessageBox, SendMessage, DialogBoxParam/Indirect - то окну могут приходить другие сообщения, хотя событие, в котором была вызвана подобная функция, останется еще недообработанным. Это не означает, что будет выполняться несколько потоков оконной процедуры - просто выполнение первого обработчика будет приостановлено.

    не наврал? :)
     
  15. shoo

    shoo New Member

    Публикаций:
    0
    Регистрация:
    17 июл 2003
    Сообщения:
    1.537
    Адрес:
    Ukraine
    смотря что иметь в виду под приостановкой выполнения кода: приостановку потока или перенос выполнения данного потока в код за пределами данной процедуры (т.е. выполнение какой-либо функции). если поток приостановлен - то окно не может получить сообщения ни из себя, ни из другого потока (см. синхронизацию). если поток продолжает выполняться - получение сообщений возможно. например, посылаем из процедуры главного окна сообщение дочернему окну, а дочернее окно, обрабатывая его, может послать какое-нибудь сообщение главному окну, и главное окно обработает его своей оконной процедурой до того, как первоначальный SendMessage "вернет" управление. Картина такого выполнения сродни рекурсии, при хранении промежуточных данных в локальных переменных или сохраняя регистры в стеке все должно быть прозрачно. но в некоторых случаях типа отрисовки нужно четко себе представлять что происходит, иначе можно или самовызов зациклить, или чего-то самому себе испортить следующим вызовом, и т.п.
     
  16. shoo

    shoo New Member

    Публикаций:
    0
    Регистрация:
    17 июл 2003
    Сообщения:
    1.537
    Адрес:
    Ukraine
    Вот набросал примерчик: на диалоге два однострочных эдита. подготовка: субклассируем верхний эдит процедурой sub_proc.

    теперь самое интересное:
    нажимаем ОК:
    1.оконная процедура диалога начала обрабатывать сообщение WM_COMMAND с кодом 1, о чем мы получаем уведомление "Начали" 2.далее: посылаем сообщение EM_GETHANDLE эдиту EDIT_1
    3.эдит EDIT_1 обрабатывая это сообщение субклассирующей процедурой посылает родительскому окну сообщение WM_COMMAND с кодом 33
    4.оконная процедура диалога обрабатывает сообщение WM_COMMAND с кодом 33, в результате чего в эдите EDIT_2 появляется надпись "Послание".
    5.неявные события: возвращение в субклассирующую процедуру, которая передает управление родной оконной процедуре эдита, затем возвращает управление назад в оконную процедуру диалога.
    6.оконная процедура заканчивает обработку WM_COMMAND с кодом 1, начатую в пункте №1, о чем мы получаем уведомление "Закончили".

    все предельно ясно. кому нет - можно натыкать дополнительных мессаджбоксов в разных местах до и после
     
  17. Perre

    Perre New Member

    Публикаций:
    0
    Регистрация:
    6 апр 2007
    Сообщения:
    100
    Всем кто откликнулся спасибо, насколько я понял обработка некоторых сообщений может быть прервана более важными сообщениями (например: перерисовка окна) , но потом первый обработчик продолжит работу
     
  18. AsmGuru62

    AsmGuru62 Member

    Публикаций:
    0
    Регистрация:
    12 сен 2002
    Сообщения:
    689
    Адрес:
    Toronto
    Просто оконная процедура может косвенно вызывать сама себя (ре-ентерабельность) и это не проблема.
     
  19. shoo

    shoo New Member

    Публикаций:
    0
    Регистрация:
    17 июл 2003
    Сообщения:
    1.537
    Адрес:
    Ukraine
    да, кстати, еще один момент (или готовое решение) по этому вопросу (правда не с отрисовкой):
    одно мое приложение выполняет операции, некоторые из которых занимают длительное время. чтобы окно не было в это время "парализованным" эти операции я выполняю в отдельном потоке - при этом окно можно сворачивать, двигать и т.п.
    а чтобы пользователь не выполнил в это время какой-либо другой операции - высавляется флаг: единица в статической ячейке. пока она стоит - WM_COMMAND игнорируется (проверкой в оконной процедуре). Когда операция завершается - она сбрасывает единицу в ноль - можно работать дальше. такая вот синхронизация подручными средствами ;)