【问题标题】:TTreeView drawing error when deactivating a form停用表单时出现 TTreeView 绘图错误
【发布时间】:2011-06-08 12:08:10
【问题描述】:

我发现了一个似乎与 TTreeView 相关的错误。

  • 获取一个包含TTreeView 的表单,其中HideSelection 设置为True
  • 使树形视图多选并在树形视图中选择多个项目。
  • 显示另一个表单,以便您的应用有两个表单。
  • 将焦点放在树视图上,然后单击其他窗体。

结果如下:

但实际上应该没有突出显示的项目。有趣的是,最后一个项目被选中,它不再突出显示,所有其他项目确实如此。似乎最近点击的项目是获得特殊处理的项目。

如果您单击编辑框(或任何其他获得焦点的控件),则所有项目都将正确隐藏。因此,将焦点转移到表单上的另一个控件就可以了——问题似乎仅限于停用表单。

我通过反复试验发现,只要表单被停用和激活(需要防止错误的镜像),我可以通过在树视图上调用 Invalidate 来解决此问题。但是,我希望更好地了解错误是什么以及如何以侵入性较小的方式修复它,即在树视图级别而不是包含表单级别。

所以,总而言之,我的问题是:

  1. 究竟是什么导致了问题?
  2. 如何在不编写挂钩 TForm 事件的代码的情况下修复它?

将问题提交为QC#94908

【问题讨论】:

  • 我已经尝试过了,在 D2009 中也是如此。正如您所说,具有焦点的项目将其隐藏;其余部分仍然突出显示。

标签: delphi delphi-2010


【解决方案1】:

解决方案似乎是通过使选定节点无效来响应NM_SETFOCUSNM_KILLFOCUS 通知。可以直接修改TCustomTreeView.CNNotify,也可以写一个新的TCustomTreeView后代。这是一个快速破解,仅用于显示丢失的代码:

type
  TTreeView = class(ComCtrls.TTreeView)
  private
    procedure CNNotify(var Message: TWMNotifyTV); message CN_NOTIFY;
  end;

procedure TTreeView.CNNotify(var Message: TWMNotifyTV);
begin
  case Message.NMHdr^.code of
    NM_KILLFOCUS, NM_SETFOCUS:
      InvalidateSelectionsRects;
  end;
  inherited;
end;

编辑:大卫的QC report

【讨论】:

  • 不需要后代。您的拦截器方法正是我们在这些情况下经常使用的方法。我们通常在一个单独的单元中编写这样的修复程序,我们只是在使用中包含所有标准内容之后。为了识别这些单元,它们都被称为 Fix.pas...
  • 这解决了我的问题,正是我想要的。非常感谢您将卓越的知识用于解决我的小问题!现在我将提交一份质量控制报告。
  • @Marjan 碰巧我已经在使用后代方法了。事实上,我碰巧也在编译我自己的 ComCtrls.pas 版本,以修复其他无法从该单元外部访问的错误。
  • @David 谢谢!我很高兴能帮上忙。顺便说一句,我发现切换到另一个应用程序(而不仅仅是同一个应用程序中的另一个表单)时也会发生同样的问题。上面的代码似乎也解决了这种情况。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-04
  • 1970-01-01
相关资源
最近更新 更多