Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 修改VCL组件代码_Delphi_Components_Vcl - Fatal编程技术网

Delphi 修改VCL组件代码

Delphi 修改VCL组件代码,delphi,components,vcl,Delphi,Components,Vcl,我需要更改组件中的功能。当您收到“您不能重写此”消息,或者您需要更改私有方法中的代码(“方法不存在于基类中”消息),从而使组件无法下降时,您该怎么办 在修改私有方法或行为时,有一些(主要是黑客)选项: 修改原始源,重新编译单元,并按照建议使用更改的dcu;从来没有这样做过,但我认为当您的代码使用新的dcu而其他VCL代码不使用时,这会让您非常头疼 组件行为通常由许多窗口消息控制——看看您是否可以通过修改对其中一些消息的反应来实现更改;您可以覆盖消息处理方法(带有message关键字的方法),即

我需要更改组件中的功能。当您收到“您不能重写此”消息,或者您需要更改私有方法中的代码(“方法不存在于基类中”消息),从而使组件无法下降时,您该怎么办

在修改私有方法或行为时,有一些(主要是黑客)选项:

  • 修改原始源,重新编译单元,并按照建议使用更改的dcu;从来没有这样做过,但我认为当您的代码使用新的dcu而其他VCL代码不使用时,这会让您非常头疼
  • 组件行为通常由许多窗口消息控制——看看您是否可以通过修改对其中一些消息的反应来实现更改;您可以覆盖消息处理方法(带有
    message
    关键字的方法),即使它们声明为私有,也可以替换WndProc
  • 你可以使用类似于修补铸造的黑客
  • 您可以使用答案中描述的一些迂回机制

或者你可以得到另一个组件。

如果我面临这个问题

  • 我首先尝试从组件或其CustomXXX祖先继承,看看这是否解决了问题。如果没有
  • 我会更深入,也就是说,试图截获传入的消息。这可以动态完成。如果结果太深,因为必须构建的代码太广泛,或者如果我仍然必须访问无法访问的项目
  • 我尝试黑客。一种方法是将组件和相关代码复制到具有不同名称的新单元,重命名组件并修改需要修改的内容
  • 有时候,我只需要重做一两个方法就可以让我的新行为成为可能
永远不要忘记给单元一个不同的名称,给组件一个不同的名称(可能继承自原始组件或其祖先之一,因此它们保持在相同的层次结构中)。切勿修改原始源,然后重新编译VCL。这是一场维护噩梦

我不喜欢interposer类,即与原始类同名但行为不同的类,它们继承自原始类。它们的功能取决于uses子句中包含的顺序,这在我看来似乎有些古怪。我不推荐那样做

但我做什么在很大程度上取决于问题。我认为一个人不能(或不应该)给出涵盖所有情况的全面建议


但我的主要建议是:不要修改原来的单元,始终将新代码放在新单元中,并使用新的类名。这样,原始版本和修改后的版本可以在IDE中和平共存。

首先,我宁愿复制单元,重命名它和我更改的类,并删除我不需要的所有内容(如有必要,“包括”定义常量、使用类型等的原始单元)。这就避免了大部分的头痛。永远不要修改原始来源,那是维护的噩梦。我同意。这更像是“修改、编译、使用dcu、撤消修改”。但你的方法听起来更好。只需复制单元并根据需要进行更改。缺点仍然是,由于第三方组件经常更新,它还需要一些维护。但是如果是VCL,那么下一个错误修复/更新将是Delphi的下一个版本,因此无需担心。只要禁用了运行时包,并且您不需要对
接口
部分进行任何更改,那么您就不需要重命名该单元或其类。只需将该单元复制到您的项目中,将该副本添加到您的项目中,然后根据需要修改其
实现
部分。在编译过程中,它将覆盖VCL的本机代码。对不起,雷米,但不这样做是错误的做法,也是维护的噩梦。重命名单元和类是唯一优雅的方法。从技术上讲这是不必要的,但不重命名在IMO中是不好的做法。更改单元和类名需要更改引用它们的代码。维护原始名称并不少见,因此不需要更改现有代码,特别是如果其目的是更改/修复内部行为(即,修复RTL/VCL bug)。有时,当我在测试东西时(尽管我在部署中从未这样做过),我只是跨VCL源单元复制到本地目录,编辑并重新编译。IMHO,当同一个类被修改时,重命名该类是维护的噩梦。如果“bug/”功能在更高版本的Delphi中得到修复,那么您所需要做的就是归档该单元,然后返回到原始VCL。如果重命名单元和类,这将是不可能的。而且更容易合并到未来版本的新单元版本中。
更改单元和类名需要更改引用它们的代码。
是的,这表明您正在使用修改过的组件。在我看来,修改VCL中的原件是一个坏主意,因为它使您的VCL与其他VCL不兼容,并且使您的代码成为维护的噩梦。任何错误都可能是由于您的修改或原始代码造成的。如果你把它们分开,很清楚会发生什么。