停用表单时出现TTreeView绘图错误

Dav*_*nan 7 delphi delphi-2010

我发现了似乎与之相关的错误TTreeView.

  • 采取包含一个形式TTreeViewHideSelection集到True.
  • 使树视图多选并在树视图中选择多个项目.
  • 显示另一个表单,以便您的应用程序有两个表单.
  • 为树视图提供焦点,然后单击另一个窗体.

结果如下:

在此输入图像描述

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

相反,如果您单击编辑框(或实际上任何其他需要关注的控件),则会正确隐藏所有项目.因此,将焦点转移到表单上的另一个控件是很好的 - 问题似乎仅限于停用表单.

我通过反复试验发现,Invalidate只要表单被停用并激活(需要防止错误的镜像),我就可以通过调用树视图来解决这个问题.但是,我正在寻找一个更好的理解错误是什么以及如何以一种侵入性较小的方式修复它,即在树视图级别而不是包含的表单级别.

总而言之,我的问题是:

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

提交问题为QC#94908.

Ond*_*lle 9

解决方案似乎是通过使所选节点无效来响应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;
Run Code Online (Sandbox Code Playgroud)

编辑:大卫的质量控制报告.

  • @David谢谢!我很高兴我可以帮忙.顺便说一句,我发现在切换到另一个应用程序时(不仅仅是同一个应用程序中的另一个表单)也会发生同样的问题.上面的代码似乎也解决了这种情况. (2认同)