Хакер писал(а):Смысл в своём ML — затормозить выполнение кода, заблокировать его внутри нужной процедуры пока не произойдёт что-то.
Хакер писал(а):Принципиально отказаться от дурацкой архитектуры.
Тогда каким другим способом "затормозить выполнение кода", не замораживая при этом UI?
Кстати, ты же и предложил идею самим скормить гету событие таймера:
Хакер писал(а):Ну ладно, раскрою: можно запустить таймер, который сработает через 100 мс и пришёл сообщение и вызвать GetMessage.
Хакер писал(а):Принципиальные грабли: при обработке какого-то сообщения обработчик породит свой ML, который случайно обработает твоё таймерное событие. Тогда тебе придётся нового таймерного события, но и его может кто-нибудь съесть
Это решить, как оказалось, совсем просто
- Код: Выделить всё
Sub mySleep(ByVal dwMillisecond As Long)
Dim idTm As Long, MSG As MSG
Dim endInterval As Long, tmNow As Long
On Error GoTo errH
endInterval = GetTickCount + dwMillisecond
On Error GoTo 0
' idTm = SetTimer(0&, 0&, dwMillisecond, AddressOf TimerProc)
idTm = SetTimer(0&, 0&, dwMillisecond, 0&)
Do
GetMessage MSG, 0&, 0&, 0&
TranslateMessage MSG
DispatchMessage MSG
tmNow = GetTickCount
' MSG.Time не годится, потому что за время обработки DispatchMessage интервал может уже и закончится
' If MSG.Time < 0 Then If endInterval >= 0 Then Exit Do
' If MSG.Time >= endInterval Then Exit Do
If tmNow < 0 Then If endInterval >= 0 Then Exit Do '
If tmNow >= endInterval Then Exit Do
Loop
KillTimer 0&, idTm
Exit Sub
errH:
If Err.Number = 6 Then 'переполнение
endInterval = &H80000000 + dwMillisecond - (&H7FFFFFFF - GetTickCount)
End If
Resume Next
End Sub
Съесть наш таймер могут только внутри нашего DispatchMessage, но это нам уже по барабану, потому что для выхода мы теперь ориентируемся не на MSG.Time, а на GetTickCount уже после обработки сообщения.
Остались грабли?