【问题标题】:TTreeView gets corrupted after Windows Theme changeWindows 主题更改后 TTreeView 损坏
【发布时间】:2022-08-14 01:24:25
【问题描述】:

我在 C++Builder 中的应用程序使用具有几个派生 TTreeNode 类的节点的 VCL TTreeview。更改 Windows 主题后,树视图会以某种方式重新创建,而不仅仅是重新绘制。在重新创建期间,派生的树节点析构函数被调用,但它们的构造函数未被调用。看起来新节点都是基本的 TTreeNode 类型,而不是派生类型。因此,派生类的所有方法和属性都会在此过程中丢失。

另外,在游戏过程中,节点在TreeView->Items(TTreeNodes)中获取新地址,如果在某个节点的长时间动作中发生主题变化,以创建子节点结束,即必须将孩子添加到不再存在的父地址。

有没有办法防止主题更改对 TTreeView 及其节点产生影响?或者任何其他解决方案?

    标签: treeview nodes c++builder vcl ttreenodes


    【解决方案1】:

    在重新创建期间,派生的树节点析构函数被调用,但它们的构造函数未被调用。看起来新节点都是基本的 TTreeNode 类型,而不是派生类型。

    正确的。在HWND 重新创建期间,在其HWND 被销毁之前,TTreeView 将其节点数据保存到临时内存流并销毁其节点对象,然后在新的HWND 可用后,它会创建新的节点对象并恢复保存的节点数据到其中。但是,在保存和恢复该数据时,它没有派生类的概念,因此无法正确持久化它们。

    如果您的所有节点都是相同的派生类型,那么您只需使用TTreeView.OnCreateNodeClass 事件或覆盖虚拟TTreeView.CreateNode() 方法就可以了。但是,如果您的节点使用多个派生类型,那么您只是 SOL,抱歉。本机功能根本无法知道要为哪个节点重新创建哪个派生类型。

    此外,在游戏中,节点在 TreeView->Items (TTreeNodes) 中获得新地址

    是的,因为它们是新对象。

    如果主题更改发生在某个节点的长时间操作期间以创建子节点结束,即必须将子节点添加到不再存在的父地址,这将成为一个问题。

    你在做什么需要这么长时间才能跨越一个窗口娱乐?不要一开始就保存TTreeNode 引用,你就不会有这个问题。如果您需要跟踪自定义数据,请改用 TTreeNode.Data 属性,该属性在窗口重新创建期间正确保留。

    有没有办法防止主题更改对 TTreeView 及其节点产生影响?

    不是我知道的,不。

    还是有其他解决方案?

    自己处理窗口娱乐。将TTreeView.CreateWndRestores 属性设置为false,然后在ControlState 属性具有csRecreating 标志时覆盖虚拟DestroyWnd() 方法以保存节点数据,并覆盖虚拟CreateWnd() 方法以根据需要恢复该数据。例如,您可以保存每个节点的类名,然后使用它再次创建派生节点对象。

    【讨论】:

    • 谢谢,雷米。我的应用程序正在进行统计分析,有时可能会占用数小时的计算时间。树视图用于浏览分析的各个阶段。例如,根节点可能表示具有数百个个体的数千个遗传观察的数据集,在一种类型的分析之后,可以创建一个子节点,表示观察如何对应于染色体,孙节点将表示染色体,等等。
    • 在日文 Windows PC 上使用我的英语软件的客户在使用 Windows 锁屏后以及更改 Windows 主题后抱怨运行时错误。虽然我无法在锁定屏幕后重现错误,但主题更改的错误是可重现的。我认为日本锁屏将由相同的 TTreeView 娱乐引起。顺便说一句,在默认 Windows 主题和另一个主题之间切换时,似乎会发生 TTreeView 重新创建;在两个非默认主题之间切换不会强制重新创建 TTreeView。我不明白其中的区别。
    • 考虑到长时间的计算,我认为锁屏是不可避免的。在其方法进行长时间计算时销毁节点是一个坏主意。所以我正在寻找完全阻止重新创建 TTreeView,或者实际上是它的 TreeNode 对象(单个树中的多个派生类;OOP 多态性!)。目前我正在尝试捕获 WM_THEMECHANGED 通知以防止重新创建,但它没有显示在我分配给派生 TTreeView 类的 WindowProc 的处理程序中。非常感谢这里的帮助!
    猜你喜欢
    • 2016-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-14
    • 1970-01-01
    • 2016-11-30
    相关资源
    最近更新 更多