Попробую объяснить свою ситуацию:
Я использую VirtualTree в качестве сетки, и каждый раз, когда запускается событие OnFocusChanged и изменяется активный узел фокуса, у меня есть синхронная операция, которая может занять 0 -1 сек, что блокирует основной поток (иногда больше).
Я могу с этим смириться.
Пока я не могу перенести эту логику в рабочий поток.
Моя проблема возникает, когда я использую клавиши со стрелками для перемещения вверх и вниз по сетке, а узел фокуса быстро меняется. Это не гладко из-за блокировки.
Поэтому я попытался использовать сообщение Post, например:
procedure TForm1.VTFocusChanged(Sender: TBaseVirtualTree;
Node: PVirtualNode; Column: TColumnIndex);
begin
// if (T = 0) or (GetTickCount - T > 1000) then
begin
Sender.InvalidateNode(Node);
PostMessage(Handle, UM_VT_CHANGED, Integer(Sender), Integer(Node));
end;
end;
procedure TForm1.UMVTChanged(var Message: TMessage);
var
Tree: TBaseVirtualTree;
Node: PVirtualNode;
begin
// T := GetTickCount;
Tree := TBaseVirtualTree(Message.WParam);
Node := PVirtualNode(Message.LParam);
...
// DO the job!
end;
Это немного помогает, но все же я понимаю, что мне нужен какой-то «холостой» механизм. Поэтому, если я перемещаю стрелки вверх и вниз, мой рабочий процесс будет запускаться только тогда, когда VirtualTree простаивает в течение 100 мс или около того. Я понимаю, что мне нужно использовать какой-то таймер или, может быть, «съесть» почтовые сообщения и обработать только последнее, но я не могу понять, как это сделать. Я пробовал много вариантов с TTimer/GetTickCount, и кажется, что я действительно испортил что-то настолько тривиальное.