Добрый день,
Проблема в том, что когда вы вызываете ProcessMessage в OnMouseLeave, то вы по сути прерываете логику обработки Hovered контрола (Тот, что находится под мышкой). То есть вызывая ProcessMessage вы запускаете новый прогон обработки сообщений заново, не закончив предыдущий. В итоге, новый запуск сбрасывает ссылки на объект Hovered. А после возвращения в обратно в первый ProcessMessage Hovered еще используется, но он уже nil. Тут и возникает AV.
procedure TCommonCustomForm.SetHovered(const Value: IControl);
begin
if (Value <> FHovered) then
begin
if FHovered <> nil then
begin
FHovered.DoMouseLeave; // <Тут вы вызываете ProcessMessage и после выхода, тут будет nil
FHovered.RemoveFreeNotify(Self);
end;
FHovered := Value;
if FHovered <> nil then
begin
FHovered.AddFreeNotify(Self);
FHovered.DoMouseEnter;
end;
end;
end;
Если очень хочется использовать ProcessMessage в таком месте, можете добавить проверку на нил, после:
FHovered.DoMouseLeave;
if FHovered <> nil then
FHovered.RemoveFreeNotify(Self);