天道酬勤,学无止境

在 Delphi 2009 的 dfm 中添加的 DoubleBuffered 属性在 Delphi 2007 中不存在(DoubleBuffered property being added in the dfm in Delphi 2009 does not exist in Delphi 2007)

问题

这是否意味着我不能在 delphi 2007 和 2009 之间共享表单?

回答1

是的。 除非您从 DFM 中删除未在 Delphi 2007 中发布的属性,否则这是不可能的。

回答2

DoubleBuffered 在 TWinControl 中已经有一段时间了。 Delphi 2009 的不同之处在于它现在已发布。 如果您只能忽略错误(而不是使属性起作用),那么这是一个可能的解决方案:

unit Delphi2009Form;

interface

uses
  Windows, Classes, SysUtils, Controls, Forms;

type
{$IFDEF VER200}
  TDelphi2009Form = class(TForm);
{$ELSE}
  TDelphi2009Form = class(TForm)
  private
    procedure ReaderError(Reader: TReader; const Message: string; var Handled: Boolean);
  protected
    procedure ReadState(Reader: TReader); override;
  end;

  TReaderErrorProc = procedure(const Message: string);

var
  ReaderErrorProc: TReaderErrorProc = nil;
{$ENDIF}

implementation

{$IFNDEF VER200}
type
  THackReader = class(TReader);

procedure TDelphi2009Form.ReaderError(Reader: TReader; const Message: string; var Handled: Boolean);
begin
  with THackReader(Reader) do
    Handled := AnsiSameText(PropName, 'DoubleBuffered') or AnsiSameText(PropName, 'ParentDoubleBuffered');
  if Handled and Assigned(ReaderErrorProc) then
    ReaderErrorProc(Message);
end;

procedure TDelphi2009Form.ReadState(Reader: TReader);
begin
  Reader.OnError := ReaderError;
  inherited ReadState(Reader);
end;
{$ENDIF}

end.

然后将项目中表单的声明更改为继承自 TDelphi2009Form,例如:

type
  TFormMain = class(TDelphi2009Form)
  ...

这将在运行时起作用 - 属性错误将被忽略。 为了让它在设计时也能工作,创建一个只设计的包,将 designide.dcp 添加到它的 requires 子句,并添加以下单元:

unit Delphi2009FormReg;

interface

uses
  Delphi2009Form;

procedure Register;

implementation

uses
  DesignIntf, DesignEditors, ToolsAPI;

procedure ShowReaderError(const Message: string);
begin
  with BorlandIDEServices as IOTAMessageServices do
    AddTitleMessage(Message);
end;

procedure Register;
begin
  RegisterCustomModule(TDelphi2009Form, TCustomModule);
  ReaderErrorProc := ShowReaderError;
end;

initialization

finalization
  ReaderErrorProc := nil;

end.

在 Delphi 2007 IDE 中安装包,在 IDE 中打开表单时,将自动忽略 DoubleBuffered 和 ParentDoubleBuffered 属性的属性错误。 当您在 Delphi 2007 中保存表单时,属性的值将丢失,因此您应该改为在代码中初始化它们。

编辑:我添加了代码以将阅读器错误消息输出到 IDE 消息窗口:

IDE 错误信息

回答3

Delphi 项目一直非常容易移植到新版本。 您必须更加小心,但是将当前代码与较旧的编译器一起使用也非常简单。 我在 Delphi 2005/2006/2007 中维护了其他人仍然需要在 Delphi 6 和 7 中使用的代码。

如果您从 DFM 中删除不兼容的属性,它们应该可以在旧版本中正常工作,而不会在 Delphi 2009 中弄乱它们。最大的例子是 Delphi 2006 中引入的显式* 属性。我有一个自制的“DFM 洗涤器”,可以去除这些出去。 请记住,这些属性的存在是有原因的,因此您应该只清除您打算向后兼容的属性。

您还可以考虑投资静态代码分析工具,如 CodeHealer 或 Pascal Analyzer。 除了指出问题(尤其是 CodeHealer)并帮助您清理代码之外,您还可以选择要分析的 Delphi 版本,从而更容易找到除 DFM 属性之外的不兼容性。 它们可以作为构建过程的一部分自动化。

只是一个注释。 共享源代码,但为每个版本保留单独的项目。 这在 Delphi 2007 和 Delphi 2009 之间尤其重要。最近的 .dproj 文件使用相同的扩展名,但与 Delphi 2007 不兼容。您也可能遇到一些资源不兼容的问题。

回答4

每个表单都有一个 dfm 文件,其中包含表单及其组件的属性设置。 某些属性值具有默认值,因此如果保留默认值,则不会存储它们。 只是做了一个小测试:

  • 2009年创建表单
  • 添加几个标准控件
  • 保存
  • 在 2006 年打开它(抱歉,这台电脑上没有 2007)

它在没有消息的情况下工作。 但也许你没有那么幸运。

使用Delphi,在版本之间共享数据往往有点麻烦。 升级的可能性很大,但降级很麻烦。 所以我建议不要在不同版本之间共享表单文件。

据我所知,无法在 dfm 文件中添加条件定义。 但是话又说回来,我们真的想要那个......我更喜欢一种忽略未知属性的机制。

回答5

您可以在表单的 OnCreate 方法的代码中安全地添加属性,并在它们周围包裹一个 {$IFDEF VER200} // NEW PROPERTIES {$ENDIF}。 您可以将 DoubleBuffered 留在 ifdefs 之外,因为它存在于 Delphi 2007 中,只是对属性检查器不可用。

您只需要担心您设置的与默认值不同的属性。 对于双缓冲,如果它设置为 true,您只需要担心这一点。

在 Delphi 2007 中加载 Delphi 2009 表单时,您将收到一个属性将被破坏的警告,只需记下这些属性,因为这些是您需要处理的。

我正在使用这样一种方法将我的代码从 Delphi 2006 迁移到 Delphi 2009。我的大多数项目都包含几个共享单元,并且必须在 Delphi 2006 中编译发布版本,在 Delphi 2009 中编译“下一个”版本。 我还大量使用 {$IFDEF UNICODE} 定义我需要确保字符串是宽字符串或 ansistring 的位置,具体取决于例程。

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • DoubleBuffered property being added in the dfm in Delphi 2009 does not exist in Delphi 2007
    Does that mean that I can't share a Form between delphi 2007 and 2009?
  • 如何减小可执行文件的大小(Delphi)?(What Can I Do To Reduce My Executable's Size (Delphi)?)
    问题 我使用Delphi 2009为桌面程序发布了一个可执行文件(.EXE)。我没有外部DLL或运行该程序所需的资源。 我使用两个组件:LMD Innovative的ELPack和Sergey Tkachenko的TRichView,它们已编译到我的可执行文件中。 当我使用“发布”构建配置来构建生产版本时,所生成的可执行文件为13,533 KB。 在使用Delphi 2009之前,我使用的是Delphi4。它生成的可执行文件只有2,671 KB,同时包含相同的两个组件,并且基本上具有与当前版本相同的代码。 我确实知道Delphi 2009完全是Unicode(这是我升级的主要原因),而成为Unicode可能导致大小加倍。 但这大约是它的5倍。 为什么我的可执行文件必须保持5倍大? 还是有一些简单的方法可以减少可执行文件的大小? 请注意。 有人在回答压缩Delphi EXE的方法。 那不是我想做的。 我试图简单地了解为什么要使用这么多的空间来删除​​可能不必要的内容。 如果这样做,则压缩仍可以在以后进行。 安装可执行文件后,它的大小实际上并不重要。 它用于下载目的,并最大程度地减少要压缩它的服务器负载和下载时间。 我更喜欢使用Inno Setup并在安装例程本身内部压缩程序。 然后在安装后将其扩展为完整尺寸。 这既防止了可能的病毒检测,又消除了解压缩内存中程序所需的额外启动时间。
  • 为什么默认情况下禁用DoubleBuffered?(Why is DoubleBuffered disabled by default?)
    问题 创建新表格后,我通常会执行以下仪式: 将名称更改为有意义的名称; 输入Caption ; 更改position属性(DefaultPosOnly几乎不是用户所期望的); 将ShowHint设置为true ; 将DoubleBuffered设置为true ; 我一直想知道为什么默认值是'False'。 对我来说,它看起来技术含量低且cr脚,在我的新机器上,我没有注意到性能上的任何差异。 在旧计算机,VNC,远程桌面或虚拟机中双缓冲是否有问题? 您将其打开还是关闭? 有什么建议吗? 回答1 您可能知道,双缓冲区通常涉及创建与可视组件大小相同的屏幕外内存缓冲区。 在此缓冲区上执行写入/绘制,完成后,将“交换”整个缓冲区,以便现在将其绘制在可视组件上。 (注意:“交换”可能包括简单地更改指针指向的地址,或者实际上可能涉及复制内存块,例如使用BitBlt,memcpy等)。 因此,为其启用的每个组件分配了合理数量的内存以支持此过程。 如果您的应用程序有许多窗口或组件,则分配的内存将不小。 如果不需要平滑的视觉更新/滚动,为什么要浪费此内存? 当然也有一个论点,即当今大多数计算机都具有足够的可用内存,所以为什么要担心。 但是,我仍然不认为这是不需要时默认启用双重缓冲的原因。 如果手动将DoubleBuffered设置为true对您来说很麻烦,那么您始终可以创建自己的自定义控件/组件
  • 如何制作PNG资源?(How do I make a PNG resource?)
    问题 我有一个带有大TImage的表单作为背景。 问题是,它直接以位图的形式存储在DFM中,这大约需要3 MB。 原始的PNG文件约为250K。 我想尝试通过将PNG嵌入资源中,然后在OnCreate期间将其加载窗体来减少膨胀。 Delphi 2009包含PNG支持,现在我可以做到这一点,除了我不太了解如何构建包含PNG的资源文件。 有人知道这是怎么做的吗? 回答1 示例文本文件(名为myres.rc): MYPNG RCDATA mypng.png 添加到项目: {$R 'myres.res' 'myres.rc'} 在运行时加载的示例: uses PngImage; var Png: TPngImage; begin Png := TPngImage.Create; try Png.LoadFromResourceName(HInstance, 'MYPNG'); Image1.Picture.Graphic := Png; // Image1: TImage on the form finally Png.Free; end; end; 回答2 对于那些使用C ++ Builder的人,此代码对我有用: 在ResourceTest.rc文件中 IMG_BMP BITMAP "Ressources\\myimage.bmp"; IMG_PNG RCDATA
  • 如何减少 Delphi 中的 PageControl 闪烁?(How can I reduce PageControl flicker in Delphi?)
    问题 在 Delphi 2009 中,我发现 PageControl 的闪烁(在调整表单大小期间发生)可以通过将其DoubleBuffered属性设置为 true 来减少。 但是,如果我将控件添加到 PageControl 标签页,无论它们的 DoubleBuffered 属性设置如何,它们都会闪烁。 我也试过启用和不启用运行时主题。 回答1 将 PageControl 上的组件的ParentBackground设置为False有很大帮助。 然而,这会导致这些面板组件的颜色不同,它们现在都有更暗的背景。 也许这可以轻松解决(不会失去主题支持)。 我还安装了 VCL Fix Pack,它有一个针对 QC 56252 的修复程序(TPageControl 在激活主题时闪烁很多)。 回答2 这远非完美,但您可能想使用它: protected procedure WMExitSize(var Message: TMessage); message WM_EXITSIZEMOVE; procedure WMEnterSize(var Message: TMessage); message WM_ENTERSIZEMOVE; procedure TFormMain.WMEnterSize(var Message: TMessage); begin if Assigned
  • 在对象检查器上显示TFrame后代的其他属性(Showing TFrame descendant's additional properties on the object inspector)
    问题 Delphi对象检查器没有按设计显示TFrame后代的其他属性。 人们倾向于建议使用一种已知的技巧,该技巧通常用于在对象检查器上显示TForm后代的属性。 诀窍是:通过如下设计时程序包将TForm后代的自定义模块注册到Delphi IDE: RegisterCustomModule(TMyFrame, TCustomModule); 对象检查器可以通过这种方式显示TFrame Descendant实例的其他属性,但是当它嵌入到窗体中时,它将丢失其帧行为。 不可重新设计,不可能为其子组件实现事件,并且它接受子控件(没有)。 但是它在自己的设计区域中通常表现良好。 看起来,Delphi IDE专门为TFrame提供的那些行为。 他们可能不是通用工具。 还有其他方法可以完成此操作而又不会丢失帧行为吗? 我正在使用Delphi 2007 @Tondrej, 请先阅读有关该问题的评论,谢谢。 frameunit.dfm: object MyFrame: TMyFrame Left = 0 Top = 0 Width = 303 Height = 172 TabOrder = 0 object Edit1: TEdit Left = 66 Top = 60 Width = 151 Height = 21 TabOrder = 0 Text = 'Edit1' end end unit
  • 在Delphi 7中有效的ZeroConf / Bonjour代码在2009年无法正常工作(ZeroConf/Bonjour Code that works in Delphi 7 not working in 2009)
    问题 我对DNSServiceRegister具有以下声明: function DNSServiceRegister ( var sdRef: TDNSServiceRef; const flags: TDNSServiceFlags; const interfaceIndex: uint32_t; const name: PUTF8String; //* may be NULL */ const regType: PUTF8String; const domain: PUTF8String; //* may be NULL */ const host: PUTF8String; //* may be NULL */ const port: uint16_t; const txtLen: uint16_t; const txtRecord: Pointer; //* may be NULL */ const callBack: TDNSServiceRegisterReply; //* may be NULL */ const context: Pointer //* may be NULL */ ): TDNSServiceErrorType; stdcall; external DNSSD_DLL; 在我的Bonjour框架中,对于已启用的已宣布服务
  • 如何改善Delphi框架的使用(How to improve the use of Delphi Frames)
    问题 我在Delphi中使用框架已经很多年了,它们是VCL的最强大功能之一,但是标准使用它们似乎存在一些风险,例如: 在不知道您正在“调整”框架的情况下,很容易在框架的宿主窗体上意外移动或编辑框架子组件-我知道这不会影响原始框架代码,但通常不是您想要的。 当使用框架时,即使该框架已经使用多年并且不应被触摸,您仍然可以对其子组件进行可视化编辑。 所以我不得不思考... 有没有一种方法可以将组件“分组”以使其位置“锁定”? 这对于完成的表格以及框架都是有用的。 通常,其他开发人员会将代码返回给我,其中仅更改了表单边界,甚至他们无意进行任何更改。 有什么办法可以将框架及其组件变成单个Delphi组件? 如果是这样,则框架内部将被完全隐藏,并且其可用性将进一步提高。 我对任何想法都感兴趣... 布赖恩 回答1 将框架注册为组件可同时解决1.和2 .: 当您将该框架控件放在窗体或其他框架上时,框架上的组件将被锁定您将获得可以直观设计的组件(实际上是控件) 但是:有一些问题(可以解决,请参阅文章链接),其中最重要的是这一点: 当您在框架上放置组件,然后将该框架作为组件放置在Delphi表单或框架上时,这些组件将在“结构”窗格中可见。 问题在于,由于它们在结构窗格中可见,因此您可以将其删除,从而导致访问冲突。 解决这个问题的技巧是不要忘记“小树枝”。 我在DelphiLive
  • Delphi-为什么ExplicitWidth和ExplicitHeight继续出现在.DFM文件中,这是什么?(Delphi - Why does ExplicitWidth and ExplicitHeight keep appearing in .DFM files and what is it?)
    问题 我们注意到,在检查更新时,我们的.DFM文件已添加ExplicitWidth和ExplicitHeight属性-但我们不知道为什么。 我的问题是: 这些属性是做什么用的? 为什么它们会被Delphi自动添加? 下面是显示添加的ExplicitWidth属性的示例: object Splitter2: TcxSplitter Left = 0 Top = 292 Width = 566 Height = 8 Cursor = crVSplit HotZoneClassName = 'TcxXPTaskBarStyle' AlignSplitter = salBottom Control = BottomPanel Color = clBtnFace ExplicitWidth = 8 end 回答1 来自谷歌搜索... 原始文章可以在这里找到。 在将Align或Anchor属性从其默认值更改之前,Explicit属性会记住控件的先前边界。 仅当Align属性设置回其默认值alNone时,才写入Explicit属性。 这是控件实际使用Explicit属性将其边界重置为以前的范围的时候。 回答2 使用DDevExtensions,您可以禁用将这些属性存储在dfm中: http://andy.jgknet.de/blog/?page_id=10 添加了Explicit *属性删除器
  • 引入/不推荐使用的Delphi语言功能和版本列表(List of Delphi language features and version in which they were introduced/deprecated)
    问题 在开始之前,我想指出的是,我已经通过Google进行了一次诚实而真诚的搜索,涉及范围很广,无法找到它。 我需要(对于我正在开发的项目)所有Delphi(2007到最新发布的版本,不再支持任何早于2007的版本)“语言功能”的列表,以及引入这些功能的版本,以及( (如果适用)不推荐使用,改进或删除。 我之前在Stack Overflow上已经注意到了与此类似的问题,尽管大多数问题都是以“哪个功能最好”的形式表述的,并被认为不合适。 如果有人知道这样一个列表(或有足够的空闲时间来编写一个列表),我将不胜感激。 接受的答案将包含指向此类列表的链接,或者包含列表本身。 回答1 请注意,此答案仅列出了新的语言功能不是新的VCL / FMX功能。 以下是RAD Studio docwiki的链接: Rad Studio 10.3 Rio的新增功能 Delphi和C ++ Builder 10.2 Tokyo中的新增功能 Delphi和C ++ Builder 10.1 Berlin的新增功能 Delphi和C ++ Builder 10 Seattle中的新增功能 Delphi和C ++ Builder XE8的新增功能 Delphi和C ++ Builder XE7的新增功能 Delphi和C ++ Builder XE6的新增功能 Delphi和C ++ Builder
  • 在<= 2007的Delphi版本中处理Unicode字符串(Handling a Unicode String in Delphi Versions <= 2007)
    问题 背景:该问题与2009年以下的Delphi版本有关(即,没有内置Unicode支持)。 我有一个规范,要求我通过TCP连接传输Unicode编码的字符串,但我没有Delphi 2009。 问题是否存在单个函数或很小的库(我不需要太大的体积),可以在通过网络发送之前立即使用它来将单个字符串编码为UTF-8? 我的问题的第二部分:如果有UTF-8编码的字符串作为响应发送回去,我想我将需要另一个函数将其恢复为Delphi字符串格式。 我了解以这种方式支持此类Unicode的局限性。 回答1 Delphi 2009之前的Delphi版本确实内置了Unicode支持WideString类型自Delphi 4起就可以使用了,我认为可能更早。 WideString不像新的UnicodeString类型那样好,但是它仍然包含16位Unicode字符,您可以将其类型PWideChar为PWideChar以将字符串发送给Unicode API函数。 Windows单元声明了API函数的大多数“宽”版本,并且如果发现缺少某些函数,也没有什么可以阻止您自己声明其他函数。 以前的版本没有的是VCL中的Unicode支持。 为此,您可以使用Tnt Unicode控件。 他们曾经是免费的。 似乎在某些地方仍然可以找到最新的免费版本:(1),(2)。 JCL有几个用于处理Unicode的单元。
  • IntraWeb 的 SSL 问题 - Delphi 2007(SSL Issues with IntraWeb - Delphi 2007)
    问题 最近一段时间我一直在尝试使用 SSL 处理我的 IW 程序,但我一直遇到“无法加载 SSL 库”的问题。 我遵循了我能找到的关于这个主题的每一条建议,但仍然没有快乐。 我已经在本地目录和 system32 中尝试了建议的 DLL。 有没有人对我应该使用哪些 OpenSSL DLL 有明确的答案? 它们的构造是什么? 或者任何其他想法? Indy:昨天更新到最新快照 IntraWeb:已安装库存 D2007 这是在 Vista 机器上运行的,如果这有什么不同的话。 TIA, 特雷弗 回答1 解决了: 看起来问题是在我的机器上漂浮着一个 bpl。 以下是我采取的步骤,以防其他人在让独立服务器与 D2007 和预安装的库一起运行时遇到困难: 从你的机器上删除所有 Indy 的痕迹 - 在 Indy 站点的某个地方有一个 howto; 从 subversion 存储库下载 Indy 10 主干按照说明安装Indy; 从 atozed 下载最新的 IW9 - 你需要一把钥匙; 安装它 - 让它破坏你当前的安装; 现在,对于 OpenSSL DLL: 从这里获取它们:http://www.slproweb.com/download/Win32OpenSSL_Light-0_9_8i.exe 这些对我来说效果很好; 确保您的防火墙允许端口 443 通过(或您选择的任何端口); 在这一点上
  • 在 Delphi 7 中,我可以设置“调试”和“发布”模式吗?(In Delphi 7, can I set up 'Debug' and 'Release' modes?)
    问题 在大多数现代 IDE 中,您可以拥有 Debug 和 Release 构建配置,并且可以在它们之间快速切换。 在 Delphi 7 中,这似乎是不可能的。 我必须转到项目设置并手动切换优化和所有调试信息。 如果有一个插件或一些插件可以为我处理这个问题,那就太好了。 有人知道吗? 还有其他建议吗? 编辑:我无法升级到 Delphi 2007 或 2009,因为我们有一个必须转换的大型 Delphi 7 代码库。 我同意这将是理论上的最佳解决方案:P 回答1 使用 Andreas Hausladen 出色的 DDevExtensions IDE 专家,您可以非常轻松地添加项目配置,类似于其他 IDE 提供的配置。 只需确保从我提到的链接下载 1.6 版本,因为更高版本仅适用于 Delphi 2009。1.6 版本适用于 5 到 2007 之间的任何 Delphi 版本,包括 5 和 2007。 专家在项目菜单下添加了一个子菜单,以防您一开始找不到它。 回答2 我不知道 Delphi 7 的任何构建配置插件,但是您可以模拟它; 只需在项目的每个单元中应用一个包含文件(无论如何这是一件明智的事情),然后让它自行调整为一个单一的定义,如下所示: --- ExampleIncludeFile.inc --- {$IFDEF DEBBUG} {$OPTIMIZATION OFF} {
  • Delphi 2010 或 2007 用于升级 Delphi 3 项目?(Delphi 2010 or 2007 for upgrading Delphi 3 project?)
    问题 我刚刚收到一项任务,将我在 1999 年编写的旧 Delphi 3 项目升级到更新版本并添加功能(我之前在相关问题中讨论过这里和这里)。 我假设适当的路线是首先将我的开发环境升级到 Delphi 2010,然后移植应用程序。 我现在正在考虑是否将应用程序升级到我现有的 Delphi 2007 副本,以避免出现 Unicode 问题。 该应用程序在美国的一家公司运行,并且与单一州的要求紧密相关,因此它不会从 Unicode 支持中受益。 我的问题是:处理 Unicode 问题的额外麻烦会超过使用最新版本的 Delphi 的好处吗? 您可能认为我对 Unicode 没有任何经验。 回答1 他们在 Delphi 2009 中实现 Unicode 做得非常好,以至于大多数不使用字符和字节技巧的程序都可以毫无问题地转换过来。 需要注意的是,只要您不使用任何 3rd 方软件包。 如果你是,你应该升级那些。 如果他们没有升级并且你没有他们的源代码,那么你最好不要去 Delphi 2010。 但如果可能的话,我会跳下去。 我做到了,我很高兴我做到了。 回答2 为什么“升级”到不是最新的版本,它只是保证更早的“下一次升级”。 我对 Delphi 2010 非常满意,我建议移植到该版本,除非您使用 D2010 不可用的 3rd 方库 回答3 您应该在 D2010 试用版中尝试(升级)
  • 将复杂的应用程序从C ++ Builder 2007升级到2010时,我需要知道些什么?(What do I need to know to upgrade a complex application from C++Builder 2007 to 2010?)
    问题 我公司的主要应用程序主要是用C ++编写的(带有一些Delphi代码和组件)。 我们将在大约一周的时间内从RAD Studio 2007升级到下一个版本的2010。 我需要了解什么才能确保此升级顺利进行? 到目前为止,我想到的几点是: Unicode。 这看起来复杂。 我们的应用程序包含std :: string-s和AnsiString-s与它们之间的强制转换的可怕混合。 我对此有很多疑问,例如“ wstring是否可以容纳UnicodeString所能提供的一切,我们是否应该进行搜索/替换”,或“我们应该完全避免使用所有C ++字符串类型并使用UnicodeString”,“我们可以更改所有事件处理程序以使用String,尽管现有的.HPPs事件处理程序方法原型已编译为编译器转换为AnsiString”,然后改为基础知识,例如“我们应为所有字符串加上L前缀,还是启用Unicode的编译器足够聪明使用Unicode字符串”等。对此深有体会。 我们还需要向后兼容。 我们的应用程序使用自己的二进制元组格式,该格式当前将字符串存储为字节数组。 我需要对其进行升级以读取旧文件,并且大概还要编写新的Unicode字符串。 如何处理以二进制格式嵌入的Unicode字符串? 有什么通用的方法可以将UnicodeString指向一个字节数组,该数组最初可以写为ANSI字节或Unicode
  • 在 TWinControl 类上添加属性(Add a property on TWinControl Class)
    问题 我想在 TWinControl 中添加一个已发布的属性。 有没有办法在不需要重新编译基本源代码的情况下做到这一点? 如果没有,有什么方法可以重新编译基本源代码而不会有太多麻烦? 忠告... 编辑新想法的原因 好吧,我想做什么我正在尝试覆盖 System.pas 中的 _GetMem 以获取从 TWinControl 继承的类。 为什么 ? 因为我会为对象分配一些额外的空间,足够一个整数。 为什么是整数? 因为这样我可以添加任何指向对象的指针。 因此,在 TWinControl 的帮助器类上,我可以创建一个 Get 一个 Set 函数来访问这个内存空间。 很好不是吗? 这该怎么做 ? 覆盖 GetMem 过程我可以使用在 FastCode 上使用的相同策略,为新过程创建一个跳线。 我现在需要的是了解这个内存分配如何工作 InstanceSize 来覆盖它。 我正在研究 Delphi 是如何做到这一点的……为了在 DFM 上添加这个,我会以同样的方式做,我会为文件管理器创建一个跳线。 有人有一些想法在对象中添加新空间吗? 我需要覆盖什么方法? 跳投我知道怎么做。 再一次。 编辑 = 进化 我想我做了内存注入。 我需要做更多的测试。 我刚刚做了,我现在不关心优化,如果有人想测试它,代码在这里。 只需将该单元添加为项目的第一个单元即可。 unit uMemInjection
  • Delphi 对象持久化,最好的方法是什么(Delphi object persistence, what is the best way)
    问题 我开发了用于绘制一些形状(主要是线条)的应用程序,现在我需要能够将草图存储到文件中,我知道 delphi 已经内置了用于对象持久性的例程,但我从未使用过它。 有人可以告诉我,如果我必须保留也引用其他对象(将被存储到)的对象,我可以使用对象持久性,我有可以连接到其他 TLine 对象的 TLine 对象等。 使用此功能或编写自定义过程来将对象存储到文件中/从文件中读取对象是否更好。 回答1 我过去使用的一种方法是将我的对象属性存储在一个 XML 文件中,编写一个自定义的“保存”例程,该例程添加到传递的 IXMLNode,以及一个从传递的 IXMLNode 读取的新构造函数。 我将组件存储为一个节点,将属性存储为属性(除非该属性是另一个对象,否则它将是一个子节点)。 我相信 Delphi Jedi 项目中有一些例程可以为你处理组件流,但我没有直接使用它们,因为我的大部分 XML 流都是手工完成的,因为我的对象非常简单,只能用一个少数属性。 回答2 内置对象持久性主要设计用于将组件流式传输到 dfm,你需要做的工作来持久化你的草图不会从该机制中受益很多。 我认为你最好提出一个自定义方案。 回答3 我使用 TI 对象持久性框架 (tiopf.com)。 我在 http://tiopf.sourceforge.net/Doc/overview/index.shtml 写了概述。
  • 升级到D2009(不包括Unicode)的主要诱因是什么?(What are major incentives to upgrade to D2009 (Unicode excluded)?)
    问题 在开发工具方面,我犹豫不决。 对于大约一半的产品,我仍然使用D7,而对于其他产品,则使用D2006。 事实是,尽管对Unicode的支持不但受到欢迎而且非常有用,但它可能给我带来的麻烦多于我目前的项目所带来的麻烦(它们已经或多或少已经准备好Unicode了)。 对于其中一个特别是这种情况,如果每个字符串占用的内存是以前的两倍,那么性能将受到很大影响。 因此,除了Unicode之外,还有哪些其他主要的升级激励措施? 回答1 为了使问题更直观,请看一下在Delphi 7和Delphi 2007之间添加的内容。这是一个明显的高水位线。 http://blogs.codegear.com/nickhodges/2007/03/28/33579 http://www.stevetrefethen.com/blog/VCLAndRTLEnhancementsSinceDelphi7D7.aspx Delphi 2009的门槛更高。 http://blogs.codegear.com/pawelglowacki/2008/11/03/38527 http://blogs.codegear.com/chrispattinson/2008/09/19/38897 这是我的一些最爱: RTL中的泛型(自然)和泛型集合。 改进的构建配置,使它们可以从通用基本配置继承。 DataSnap的改进
  • Delphi中的线程安全(Thread-safe in delphi)
    问题 我必须修改和更改线程中的某些可视组件,并且您知道这样做不安全。 我的问题是如何编写完全线程安全的代码? 有可能的? 如果可以,请给我一个简单的例子吗? 我的代码不是线程安全的: type tMyWorkerThread = class(TThread) public procedure Execute; override; end; var Form1: TForm1; implementation {$R *.dfm} procedure tMyWorkerThread.Execute; begin //codes //working with visual components end; procedure TForm1.Button1Click(Sender: TObject); begin TMyWorkerThread.Create(false); end; 谢谢你。 回答1 用Delphi编写线程安全代码涉及您使用任何其他语言所需要的基本护理,即处理竞争条件。 当不同的线程访问相同的数据时,就会发生争用情况。 处理该问题的一种好方法是声明TCriticalSection的实例并将危险代码包装在其中。 下面的代码显示了一个属性的getter和setter(通过假设),该属性具有竞争条件。 constructor TMyThread.Create; begin
  • 如何在Delphi 2007应用程序中显示Crystal XI报表?(How can I display Crystal XI reports inside a Delphi 2007 application?)
    问题 Delphi 7发行了用于Delphi的最新Crystal XI组件。该VCL组件在D2007中编译,但在运行时给我错误。 在Delphi 2007应用程序中显示与数据库连接的Crystal Report的最佳方法是什么? 回答1 这是我使用ActiveX找到的解决方案: 首先,像这样注册Active X控件: 在Delphi中,选择Component-> Import Component 单击“类型库”,然后单击“下一步”。 选择“ Crystal ActiveX报表查看器库11.5” 选择您想要的任何调色板页面(我使用“数据访问”) 选择一个导入位置 退出向导 将您选择的位置添加到项目“搜索路径”中 现在这段代码应该可以工作了: ... uses CrystalActiveXReportViewerLib11_5_TLB, OleAuto; ... procedure TForm1.Button1Click(Sender: TObject); var cry : TCrystalActiveXReportViewer; oRpt, oApp : variant; i : integer; frm : TForm; begin cry := TCrystalActiveXReportViewer.Create(Self); oApp := CreateOleObject(