Здравствуйте, Штирлиц! : ))

Очень приятно видеть, что кто-то заинтересовался главным циклом BlackBox. Проблема остановки фоновых задач при удержании кнопки мыши или вхождении в главное меню - это первое, что мне сильно не понравилось, когда я стал изучать BlackBox чуть больше года назад. Кстати, обратите внимание на 100% загрузку процессора при удержании кнопки мыши.

Я пожаловался на это дело в официальную рассылкуblackbox@oberon.ch, в результате чего некто Marco Ciot 25.03.2006 поделился своим вариантом исправления. (Его вариант был куда лучше того, что к тому времени придумал я.) Данный патч, впоследствии немного доработанный мною, выложенздесьпод названием "Фоновая многозадачность". Этот патч положил начало целой серии исправлений стандартных модулей BlackBox, предпринятых мною за почти год освоения среды и попыток написать на ней полезный код. Все эти правки (кроме самой последней, некритичной) выложены на блоге, ссылку на который я дал выше.

Недавно некто O.Nick спросил у меня на том же блоге, как эти исправления сочетаются с SP от Метасистем. Вот мой ответ, опубликованный там:
> -- Цитата:
> К сожалению, метасистемщики не включили мои заплатки в свой последний сервис-пак. Я так понимаю, что сам выход SP 4 связан скорее с работой над Active BlackBox, а не с желанием устранить существующие неисправности. Моя же цель - устранить неисправности, поэтому наши пакеты обновлений несколько рассинхронизировались.Что касается того, как они уживаются, могу ответить так: все мои исправления полностью совместимы с их SP. Однако, некоторые модули были исправлены как мной, так и ими (например, HostWindows, входящий в патч "проблема прорисовки"). Такие модули нужно править вручную, причем мои исправления добавлять в SP, а не наоборот. Это не сложно, так как мои правки немногочисленны, выделены цветом и перечислены в стандартном заголовке (внутри складки после слова "сhanges").В свое время метасистемщики ко мне обратились с вопросом об интеграции моих исправлений в разрабатываемую ими версию BlackBox. Я провел означенную интеграцию в их базу данных исходников. Честно говоря, я думал, что SP формируется именно на основе этой базы данных. Отдельно исправлять еще и ServicePack никто меня не просил. Поскольку сам я им не пользуюсь, то подобные проблемы мне даже и в голову не приходили.

Если будете качать патчи, то лучше сразу берите полный архив из последнего поста блога. Дело в том, что некоторые модули правились несколько раз, последняя по времени версия содержит все предыдущие исправления.

Что касается цикла обработки сообщений, то он сделан не во всех местах очень хорошо : )) (покосился на info21, но продолжил рассказ). Например, 100% загрузка процессора берется из того факта, что всякий View, если он хочет отслеживать положение мыши (например, когда вы выделяете блок текста, нажав кнопку) вынужден организовывать цикл опроса мыши и клавиатуры, постоянно вызывая Rider.Input. Этот способ официально рекомендуется в документации разработчика. Видимо, это единственный способ реализовать перехват всех сообщений от мыши, так уж устроен фреймворк. Выглядит это иногда вот так (циатата из HostMechanisms):
## Код:
```
REPEAT f.Input(x, y, m, isDown) UNTIL ~isDown;
```

Подобных циклов немало разбросано по исходникам BlackBox (более десятка). В Delphi VCL при организации подобного цикла всегда есть возможноть "дать дышать" всем другим объектам и процессам, вызывая главный цикл обработки сообщений: Application.ProcessMessages. В BlackBox такой возможности не предусмотрено. Более того, если внимательно посмотреть на HostMenus.Loop, то станет очевидно, что процедура не рассчитана на повторное вхождение. Потому и не опубликована. Кстати, в официальной почтовой рассылке уже не один раз за прошедший год пролетали "рецепты по разморозке" в виде небольших циклов обработки сообщений Windows. Естественно, ни о какой платформенной независимости тут речи вести не приходится.

Что касается приемлемого решения, то оно есть. Если в Rider.Input внедрить небольшой Sleep, а заодно вызывать обработку фоновых задач и прорисовку окон, то многих неприятностей можно избежать малой кровью. Только фоновые задачи нужно прокручивать не выуживая WM_TIMER (я тоже сначала пошел по этому пути), а вызывая напрямую Services.actionHook.Step. Идеи Sleep и Step принадлежат Marco Ciot, за что я ему до сих пор благодарен.

Однако, это не решает всех проблем. Например, кубик все равно не будет перерисовываться при нажатии кнопки мыши, вхождении в меню или перетаскивании окна. Он будет крутиться "в памяти", но прорисовка будет отложена до момента выхода из меню. Форсировать прорисовку возможно с помощью некоторых недокументированных процедур, таких как Views.ValidateRoot, Windows.Directory.Update и пр.

Чтобы кубик вертелся при работе с меню, нужно поправить процедуру HostWindows.Idle следующим образом:
## Код:
```
...
      WHILE w # NIL DO
         IF ~w.trapped THEN
            w.trapped := TRUE;
            Views.ValidateRoot(w.frame); (* <- добавить эту строчку *)
            w.UpdateScrollbars(focus & (w = fWindow));
            w.trapped := FALSE
         END;
         w := dir.Next(w)
      END;
...
```


Я думаю, что по умолчанию этого не сделано чтобы не загружать процессор лишней работой. Типа: "Зачем вам обновление окон, если вы в меню находитесь?" Лично я не согласен с этим, но допускаю, что на слабых машинах это могло когда-то иметь смысл. А может быть, это банальная недоработка. К сожалению, разработчики вряд ли станут это комментировать или обсуждать.

PS: Илья, ваш способ с Windows.dir.Update не защищен от трэпов при прорисовке.
PPS: Во время выделения текста кубик все равно замирает, так что, по-видимому, из Rider.Input нужно вызывать HostWindows.Idle, а не Services.actionHook.Step. Я протестирую этот момент и выложу заплатку на свой блог.