MrShoor
А где гарантируется, что WM_PAINT приходит после WM_* инпутов? :)
MrShoor
Короче умничать можно долго. Но невижу смысла. РедравВиндоу посылает только WM_PAINT все остальное делает лишний ни кому не нужный в играх гемморой. Так то конечно плевать что вызывать, но кичиться тем что знаешь винапи тоже не стоит, там нехрен знать
XProger
> А где гарантируется, что WM_PAINT приходит после WM_* инпутов? :)
Виндой это гарантируется. В msdn где-то можно найти. WM_PAINT - не настоящая мессага, а генерируемая (т.е. GetMessage и PeekMessage генерируют её, когда в очереди нет никаких сообщений кроме WM_TIMER-а, и только если окно имеет не валидные участки), с одним из самых низких приоритетов. Ниже WM_PAINT по приоритетам только WM_TIMER.
cNoNim
> РедравВиндоу посылает только WM_PAINT все остальное делает лишний ни кому не
> нужный в играх гемморой.
Покажи, как ты вызываешь RedrawWindow. :)
MrShoor
вот так
while (!done) { if ( auto message = instance.peekMessage( win::PeekMessageFlagBits::Remove)) { if ( win::WindowMessage::QuitMessage == message->message) done = true; else { message->translate( ); message->dispatch( ); } } window.redraw( win::RedrawWindowFlagBits::InternalPaint); }
еще вопросы?
cNoNim
> window.redraw(win::RedrawWindowFlagBits::InternalPaint);
А под капотом что? Поди RedrawWindow(handle, 0, 0, RDW_INTERNALPAINT | RDW_INVALIDATE) ?
MrShoor
> Поди
када кажется крестятся
RedrawWindow(handle, NULL, NULL, RDW_INTERNALPAINT);
и бинарный OR пишется по другому, умник
cNoNim
> када кажется крестятся
> RedrawWindow(handle, NULL, NULL, RDW_INTERNALPAINT);
И работает? Потому что у меня не работает и уже ох как давно.
А что кстати GetUpdateRect внутри WM_PAINT возвращает?
MrShoor
чему там не работать?
нафига тебе GetUpdateRect если ты перерисовываешь все окно...
ты окно как создаешь?
я даже не знаю как создание окна влияет правда
cNoNim
Проверил. Вроде сейчас работает, но было дело, когда оно у меня не работало (хотя может ошибка в чем-то другом у меня была, сейчас уже не упомнить).
cNoNim
> нафига тебе GetUpdateRect если ты перерисовываешь все окно...
GetUpdateRect звать надо в любом случае, чтобы определять надо звать BeginPaint/EndPaint или нет. Либо если это рендер - нужно будет звать ValidateRect. Иначе WM_PAINT будет все время в очереди сидеть.
p.s. Вот короче мой код: http://pastebin.com/9dmsbbYc
p.p.s. В любом случае Invalidate vs Redraw - это мизерная стоимость.
MrShoor
> Иначе WM_PAINT будет все время в очереди сидеть.
слушай... без обид... откуда вообще вся эта инфа?
то что ты пишешь?
давай попробуем доки почитать?
я понимаю это щас не модно и проще пороть бред на форуме изображая веское мнение
https://msdn.microsoft.com/ru-ru/library/windows/desktop/dd145213(v=vs.85).aspx
The system sends this message when there are no other messages in the application's message queue.
DispatchMessage determines where to send the message; GetMessage determines which message to dispatch.
GetMessage returns the WM_PAINT message when there are no other messages in the application's message queue, and DispatchMessage sends the message to the appropriate window procedure.
хз, надо перевести каждую строчку? или надо объяснить смысл того что там написано?
давай по порядку... хотя по мне там вот если просто почитать весь раздел Remarks все очень прозрачно написано
1) WM_PAING посылается только если других сообщений нет
2) GetMessage (ну или PeekMessage) вовзращает WM_PAINT только если других сообщений в очереди нет
перевожу... WM_PAINT не будет тебе выдан в GetMessage или PeekMessage
до тех пор пока у тебя есть хоть какое то другое сообщение, даже если там что то застряла по причине не валидности региона окна,
именно по этому в оконном цикле не нужны ни какие дополнительные циклы которые сначала выгребают всю очередь,
достаточно самого тупого цикла
while (!done) { PeekMessage( &msg, NULL, 0, 0, PM_REMOVE); if ( msg.message == WM_QUIT) done = true; else { TranslateMessage( &msg); DispatchMessage( &msg); } RedrawWindow( demo.window, NULL, NULL, RDW_INTERNALPAINT); }
он и так будет работать так как надо, выгребутся всек сообщения кроме WM_PAINT
последним выгребется WM_PAINT
RedrawWindow здесь что бы WM_PAINT был в очереди всегда,
а ты хочешь его еще и принудительно из очереди выкидывать, что бы он там не застревал лол
а твой код я вообще не хочу комментить, фиг с тем фактом что там юзается куча функций смысла и необходимость которых ты очевидно не осознаешь, так ты еще и Invalidate делаешь по таймеру
тот код который я привел выше, можно чуть чуть улучшить, перед redraw сделать проверку что текущее сообщение WM_PAINT что бы не делать лишний вызов который добавляет WM_PAINT в очередь после каждого сообщения...
но вот так если чуть чуть пораскинуть мозгами, то окажется что единственный способ для тех кто писал WinAPI реализовать вот это
GetMessage returns the WM_PAINT message when there are no other messages in the application's message queue
очень простой, сделать WM_PAINT флагом, а не сообщением потому что сортировать сообщения фиговая затея
меня особенно порадовало про то что WM_PAINT останется в очереди...
при наличии PM_REMOVE :) допустим
при чем вот я же даже понимаю, почему наличие WM_PAINT в очереди его так волнует... таймер не работает просто... но понять причину как то не получается лол )
подсказка на счет таймера кстати тут
https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms644902(v=vs.85).aspx
и еще некоторая доп инфа по WM_PAINT
https://msdn.microsoft.com/ru-ru/library/windows/desktop/dd145167(v=vs.85).aspx
но я боюсь без разжевывания не понятно о чем эти все статьи
в самом двигле у меня не было никаких WM_PAINT я просто делал Present из рендерящего потока. ну и окно создавал с какимто арибутами чтоб оно не пыталось перекраситься мессагами.
чето там НЕ_ПЕРЕКРАШИВАТЬ_БЕКГРАУНД и еще забыл флаг.
Mira
смысл в WM_PAINT... что бы как бы как тут все пекутся быть ближе к инпуту
на самом как бы не хочу делать открытие для всех
но мессаги обрабатываются так
сначала те что посланы через SendMessage
потом те что через PostMessage
потом инпут
потом WM_PAINT
потом WM_TIMER
при этом с твоим подходом надо действительно сначала отдельным циклом выгребать всю очередь, что бы продвигалась обработка инпута
но просто такое поведение по дизайну сделано для WM_PAINT и все эти отдельные циклы это изобретение велосипеда
Тема в архиве.