{{notification.text}}

MirGames

19.06.06 00:20
0
Основной цикл программы:
Цитата

while(TRUE)
{
// test if there is a message in queue, if so get it
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
// translate any accelerator keys
TranslateMessage(&msg);
// send the message to the window proc
DispatchMessage(&msg);
} // end if
} // end while

Я думаю, что таким образом из очереди событий изымается только одно событие и оно же обрабатывается, верно? Тогда если за один цикл событий приходит больше чем одно, то очередь будет просто заваленна событиями, что вовсе не гуд. Я прав?
И ещё: события окну могут посылаться двумя способами: SendMessage и PostMessage. Если какая-то гадина пошлёт окошку событие SendMessage'эм, то программа прекратит делать то, что она делала, срочно обработает событие и продолжит делать то, что делала? А если послать два SendMessage'а подряд, при чём так, что второй придёт тогда, когда будет обрабатываться первый, то программа прекратит обрабатывать первый мэссэдж, начнёт обрабатывать второй, а когда закончит, продолжит обрабатывать первый?
#1
аксакал
19.06.06 00:27
0
Что за трава была? %)
Бред безпочвенный, делай основной цикл и в нём подцикл с обработкой всей очереди.
#2
19.06.06 00:45
0
всегда делал таким макаром:
Код
            while (m_bApplicationRun)
            {
                if (PeekMessage(&m_Msg, 0, 0, 0, PM_REMOVE))
                {
                    if (m_Msg.message == WM_QUIT) m_bApplicationRun = FALSE;
                    // обработка сообщений
                    TranslateMessage(&m_Msg);
                    DispatchMessage(&m_Msg);
                }
                else
                {
                    rError = m_Render.EndScene();
                    if (rError != Result_OK)
                    {
                        m_bApplicationRun = FALSE;
                        return Result_ABORT;
                    };
                    Sleep(0);
                };

и все без проблем работало...

А теперь обратимся к MSDN
Цитата(Bogdan1024 @ Сегодня, 22:20)
[snapback]27722[/snapback]
Я думаю, что таким образом из очереди событий изымается только одно событие и оно же обрабатывается, верно?

The PeekMessage function dispatches incoming sent messages, checks the thread message queue for a posted message, and retrieves the message (if any exist).

Цитата(Bogdan1024 @ Сегодня, 22:20)
[snapback]27722[/snapback]
Тогда если за один цикл событий приходит больше чем одно, то очередь будет просто заваленна событиями, что вовсе не гуд. Я прав?
И что ? Обработанное сообщение удаляется из очереди если стоит флаг PM_REMOVE, если PM_NOREMOVE то ни чего не удалится, а оно надо ?
Тебя волнует размер очереди сообщений ???
Цитата(Bogdan1024 @ Сегодня, 22:20)
[snapback]27722[/snapback]
события окну могут посылаться двумя способами: SendMessage и PostMessage.
Messages are processed in the following order:
* Sent messages
* Posted messages
* Input (hardware) messages and system internal events
* Sent messages (again)
* WM_PAINT messages
* WM_TIMER messages
To retrieve input messages before posted messages, use the wMsgFilterMin and wMsgFilterMax parameters.

В таком порядке события будут обработаны, но :!: это не значит, что если послать SendMessage - приложение все бросит и начнет обрабатывать его.
Как только программа выполнит PeekMessage(&m_Msg, 0, 0, 0, PM_REMOVE) программе пославшей SendMessage вернется подтверждение приема сообщения и оно продолжит работу...
Далее...если придет второе сообщение - оно просто запишется в очередь и все...
Обработано оно будет не раньше чем прога вновь вызовет PeekMessage(&m_Msg, 0, 0, 0, PM_REMOVE)

Но есть одно но и тут:
The PeekMessage function normally does not remove WM_PAINT messages from the queue. WM_PAINT messages remain in the queue until they are processed. However, if a WM_PAINT message has a NULL update region, PeekMessage does remove it from the queue.
#3
19.06.06 02:22
0
Цитата(XProger @ Сегодня, 16:27)
[snapback]27724[/snapback]
Что за трава была? %)

Трава называется "Анрэ Ламот" :) Пока скурил только 159 страниц из 850, так что мои посты ещё долго будут радовать эту конференцию.
Цитата(Drako @ Сегодня, 16:45)
[snapback]27732[/snapback]
Тебя волнует размер очереди
сообщений ???

Да!!! :) А вдруг очередь сообщений слишком много места съест если их обрабатывать по одному за цикл! (я понял что их нужно всех обрабатывать в цикле, спасибо)
Цитата(Drako @ Сегодня, 16:45)
[snapback]27732[/snapback]
В таком порядке события будут обработаны, но :!: это не значит, что если послать SendMessage - приложение все бросит и начнет обрабатывать его.
Как только программа выполнит PeekMessage(&m_Msg, 0, 0, 0, PM_REMOVE) программе пославшей SendMessage вернется подтверждение приема сообщения и оно продолжит работу...

The SendMessage function sends the specified message to a window or windows. It calls the window procedure for the specified window and does not return until the window procedure has processed the message.
Согласно написанному, SendMessage возвращается когда сообщение именно обработанно, а не полученно. Или я что-то не понял?

*Прочитавши пять раз топ*
Согласитесь или нет с этими утверждениями :) :
1. Моё приложение посылает само себе SendMessage(WM_QUIT):
Приложение запоминает то место, где оно остановилось (толкает всё в стек), виндовс вызывает в приложении обработчик событий. После такого сообщения управление после SendMessage не передаётся потому что приложение уже закрылось.
2. Моё приложение посылает само себе PostMessage(WM_CLOSE):
Виндовс ничего не вызывает, событие обрабатывается когда отлавливается PeekMessagem.
3. Чтобы обрабатывать Sent Messages PeekMessage не нужен, обработчик вызывается виндовсом. Выходит, Sent Messages PeekMessageм вообще не вылавливается?
#4
аксакал
19.06.06 04:20
0
Bogdan1024
Ты там эта, одним глазком... в последних примерах он такой же цикл использует? Это же... да как же... вот из-за таких... ну да ладно :)
#5
19.06.06 04:39
0
Цитата(XProger @ Сегодня, 20:20)
[snapback]27779[/snapback]
Ты там эта, одним глазком... в последних примерах он такой же цикл использует? Это же... да как же... вот из-за таких... ну да ладно :)

А ты когда художественную литературу читаешь, то ты сначала читаешь чем закончилось, а потом читаешь сначала :) ?
#6
аксакал
19.06.06 05:57
0
Bogdan1024
Стыдно, но вынужден признать, что чтение художественной литературы считаю пустой тратой своего времени :) Гораздо интереснее посмотреть что делает "воооот та" фитча, а затем читать её исходный код (документацию)...
#7
19.06.06 06:40
0
XProger, Андрэ во всей своей книге применяет такой алгоритм :)
Код

int WINAPI WinMain(    HINSTANCE hinstance,HINSTANCE hprevinstance, LPSTR lpcmdline,int ncmdshow)
{
//создаём окошко...
main_window_handle = hwnd; // save main window handle
Game_Init(); // initialize game here
while(TRUE) // enter main event loop
    {
    if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))    // test if there is a message in queue, if so get it
       {
       if (msg.message == WM_QUIT)       // test if this is a quit
           break;
       TranslateMessage(&msg);       // translate any accelerator keys
       DispatchMessage(&msg);       // send the message to the window proc
       } // end if
       Game_Main();       // main game processing goes here
    } // end while
Game_Shutdown(); // closedown game here
return(msg.wParam);// return to Windows like this
} // end WinMain

А я буду покорно копипэйстить этот код в свои приложения потому что моему мозгу не дано постигнуть мистерии сообщений виндовз :angry:
#8
19.06.06 06:44
0
Очередная доза паники:
Если я сам себе пошлю SendMessage(hwnd,WM_CLOSE,0,0), то программа таки всё бросит и обработает его, хотя теоретически она должна ждать пока оно обработается (когда программа сделает PeekMessage), но PeekMessage по идее должен никогда не наступить потому что программа ожидает пока обработается сообщение и дальше не работает, хотя этого не происходит...
Цитата
Стыдно, но вынужден признать, что чтение художественной литературы считаю пустой тратой своего времени :)

Солидарен :)
Отредактировано: 19.06.06 06:46
#9
19.06.06 17:00
0
Наконец-то разобрался.
Всем огромное спасибо кто тут писал!
#10
20.06.06 01:00
0
Понял или нет - уточним...

SendMessage возвращает управление после обработки сообщения приложением которому оно предназначено. Но как об этом узнать, не посылать же ответное сообщение (если послать - то вообще подвесим обе программы ибо обе будут ждать бесконечно)...
А очень просто - признаком обработки служит удаление сообщения из очереди, если не ошибаюсь, ошибаюсь - поправьте.
Поэтому, если используем GetMessage (который автоматически удаляет сообщения из очереди) то тут все просто, приложение забрало сообщение - значит обработало и поехали дальше...
А вот если использовать PeekMessage - история несколько инная...можно управлять удалением собщения из очереди изменяя флаг при вызове (PM_REMOVE или PM_NOREMOVE) например, можно просматривать последнее сообщение не удаляя его из очереди и лишь когда нужно - удалять вызывая PeekMessage c PM_NOREMOVE или GetMessage.

Таким образом, совершенно безразлично как было послано сообщение (SendMessage или PeekMessage) и как оно было принято (GetMessage или PeekMessage) они в любом случае будут обработаны, но только логику обработки пишет программист.

Цитата(Bogdan1024 @ Сегодня, 00:22)
[snapback]27759[/snapback]
Да!!! :) А вдруг очередь сообщений слишком много места съест если их обрабатывать по одному за цикл!
Очередь не принадлежит твоему приложению, её контрлирует Windows, так что размер этой очереди тебя волновать не должен...
А обработка - посмотри внимательно тот код, что я привел...
Не идеален, но имеет одну интересную фишку...сообщения все обрабатываются хором (потому как это довольно быстро...у меня :) ) и если сообщений нет - происходит рендер сцены =)
#{{post.Index}}
{{post.Author.Login}}
{{post.CreatedDate | date:'dd.MM.yy HH:mm'}}
{{post.VotesRating}}
Отредактировано: {{post.UpdatedDate | date:'dd.MM.yy HH:mm'}}