我一直听说Delphi可以做任何C++可以做的事情......除了编写Windows驱动程序.这是正确的,如果是这样,那为什么呢?
我最近在线阅读了一篇博客文章,可能表明使用Delphi编写驱动程序的可能解决方案,但它已经3年了,我不知道这些信息有多准确.
因此,使用最新版本的Delphi(2010),编写Windows驱动程序在技术上是否可行?
这是一个构造的例子.我不想在这里发布原始代码.我尝试提取相关部分.
我有一个管理监听器列表的界面.
TListenerProc = reference to procedure (SomeInt : ISomeInterface);
ISomeInterface = interface
procedure AddListener (Proc : TListenerProc);
end;
Run Code Online (Sandbox Code Playgroud)
现在我注册一个监听器:
SomeObj.AddListener (MyListener);
procedure MyListener (SomeInt : ISomeInterface);
begin
ExecuteSynchronized (procedure
begin
DoSomething (SomeInt);
end);
end;
Run Code Online (Sandbox Code Playgroud)
我确实得到了内存泄漏.永远不会释放匿名方法和接口.我怀疑这是由于某种循环引用.匿名方法保持界面生效,界面保持匿名方法生效.
两个问题:
提前致谢!
编辑:在一个小到足以在此发布的应用程序中重现这一点并不容易.我现在能做的最好的事情如下.匿名方法不会在这里发布:
program TestMemLeak;
{$APPTYPE CONSOLE}
uses
Generics.Collections, SysUtils;
type
ISomeInterface = interface;
TListenerProc = reference to procedure (SomeInt : ISomeInterface);
ISomeInterface = interface
['{DB5A336B-3F79-4059-8933-27699203D1B6}']
procedure AddListener (Proc : TListenerProc);
procedure NotifyListeners;
procedure Test;
end;
TSomeInterface = class (TInterfacedObject, ISomeInterface) …Run Code Online (Sandbox Code Playgroud) delphi memory-management interface anonymous-methods delphi-2010
我刚刚开始使用Delphi 2010中的新单元IOUtils.pas,我发现它们将所有方法都放在Records(TFile, TPath, TDirectory)类函数和过程中.
在记录而不是类中执行此操作有什么好处吗?在这两种情况下都不需要任何变量或实例,但我不确定在内存消耗或性能改进方面是否有任何实际好处.
在D2010中不推荐使用TThread的简历方法.所以,我认为现在应该这样工作:
TMyThread = class (TThread)
protected
Execute; override;
public
constructor Create;
end;
...
TMyThread.Create;
begin
inherited Create (True);
...
Start;
end;
Run Code Online (Sandbox Code Playgroud)
不幸的是,我得到一个例外"无法在正在运行或已经上线的线程上调用start"...考虑到文档告诉我应该在以挂起模式创建的线程上调用Start这一事实,这对我来说似乎很奇怪.
我在这里错过了什么?
我已经将Delphi 2007的应用程序更新到了Delphi 2010,一切都很顺利,除了一个编译正常但不能正常工作的语句:
If Edit1.Text[1] in ['S','?'] then
ShowMessage('Found')
else
ShowMessage('Not Found')
Run Code Online (Sandbox Code Playgroud)
但是,我知道不会,所以我改为 CharInSet
If CharinSet(Edit1.Text[1],['S','?']) then
ShowMessage('Found')
else
ShowMessage('Not Found')
Run Code Online (Sandbox Code Playgroud)
但它永远不会工作当字符串?,但总是使用S,即使我使用AnsiChar 转换edt1.Text 1它总是不工作阿拉伯字母.
我做错了什么,或者这不是CharInSet可行的方式?,或者那是一个错误CharinSet?
更新:
我的好朋友伊萨姆·阿里提出了另一个解决方案,它的工作正常:
If CharinSet(AnsiString(edt1.Text)[1],['S','?']) then
Run Code Online (Sandbox Code Playgroud) 我使用以下代码将文本复制到剪贴板:
Clipboard.Open;
try
Clipboard.AsText := GenerateClipboardText;
finally
Clipboard.Close;
end;
Run Code Online (Sandbox Code Playgroud)
看似随意我得到"无法打开剪贴板:拒绝访问"错误.我猜这些错误是由其他应用程序锁定剪贴板引起的,但我似乎从来没有对应该导致锁定的其他应用程序做任何事情.
奇怪的是,我的用户似乎报告了Vista和Windows 7的错误,而不是XP.
有没有办法在尝试访问它之前检查剪贴板是否已锁定?
我正在尝试阅读HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run with OpenKeyReadOnly,GetValueNames但它会从HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run返回值.
如何读取64位值而不是重定向到32位密钥?
该程序作为管理帐户运行.我也试过RegOpenKeyEx和RegEnumValue.
我正在使用Delphi 2010.
看看这段代码:
dic:=TObjectDictionary<Integer, TObject>.Create([doOwnsValues]);
testObject:=TObject.Create;
dic.AddOrSetValue(1,testObject);
dic.AddOrSetValue(1,testObject);
Run Code Online (Sandbox Code Playgroud)
代码
令人惊讶的是,当您第二次添加对象时,该对象将被释放.
这是预期的行为吗?或者是Delphi库中的错误?
文档简单地说"如果对象是拥有的,当从字典中删除条目时,键和/或值被释放".因此,释放一个我刚刚要求添加的对象似乎有点奇怪!
有没有办法告诉TObjectDictionary不这样做?目前,每次添加一个值时,我必须首先检查Key-Value组合是否已经在Dictionary中.
Delphi 2010
[编辑:阅读完所有评论后:
我的结论(他们的价值)]
[/编辑]
Delphi 2010的TSpeedButtons似乎并没有真正支持PNG透明度,因为Glyph属性在内部使用TBitmap,TBitmap用于位图,并且不能正确支持PNG透明度,并且TSpeedButton.Glyph不能支持透明度然后.. 更新:但实际的问题是我有一些外部的东西(Developer Express组件)让delphi的PNG支持无功能,另一方面TImage,虽然它仍然是TPicture,并且可以支持PNG,也受此开发者快递的影响错误.
这里已经提出了一个问题,答案显示了如何使用预混合,以便透明度不会变成黑色像素.我想知道是否有另一个按钮控件将使用在设计时加载的alpha混合PNG,并且不会将PNG资源转换为丢弃Alpha通道的BMP格式,并导致此处显示的黑色边框.
简而言之,此控件不会使用TBitmap,也不会使用TBitmap所具有的颜色键透明度功能.
重复一遍,我不是问如何在仍然使用过时的基于TBitmap/TSpeedButton的VCL功能的情况下解决黑外问题,因为它缺乏现代的PNG透明功能,我要求用它替换它"正常工作"的其他东西.
作为次要的缺点,将一个小的.png文件转换为.DFM位图资源本质上是浪费空间并使我的表单.DFM内容太大..dfm中的原生.png文件格式存储应该使得结果形式更小.

更新: PngComponents看起来应该可以工作,但是Invalid Graphic format当我尝试将png加载到Png speedbutton时出现错误.请注意,Png图像列表组件没有这样的问题.似乎cxLibrary(开发人员快递包)正在破坏事物.一旦我删除了所有开发者表达的东西,这个问题就消失了.因此,尽管我选择了Pngcomponents作为答案,但如果你安装了devex的东西,请改用他们的按钮,而不是pngcomponents.

作为测试,我决定使用Delphi 4,5,6,7,2005,2010和XE3在Delphi中创建一个简单的"Hello world"应用程序.该应用程序只不过是一个TForm,一个带有OnClick事件的TButton调用ShowMessage('Hello world').
以下是关闭调试的每个最终EXE的结果:

有人可以解释为什么XE3版本比之前版本的Delphi平均大26倍?
以下是我对XE3的项目设置:


delphi ×10
delphi-2010 ×10
arabic ×1
c++ ×1
clipboard ×1
copy-paste ×1
delphi-7 ×1
delphi-xe ×1
delphi-xe3 ×1
driver ×1
interface ×1
kernel ×1
png ×1
registry ×1
unicode ×1