什么是TApplication.Handle
?
德尔福帮助说:
TApplication.Handle
提供对应用程序主窗体(窗口)的窗口句柄的访问.
Run Code Online (Sandbox Code Playgroud)property Handle: HWND;
描述
在调用需要父窗口句柄的Windows API函数时使用句柄.例如,显示其自己的顶级弹出窗口的DLL需要父窗口才能在应用程序中显示其窗口.使用Handle属性使这些窗口成为应用程序的一部分,以便使应用程序最小化,恢复,启用和禁用它们.
如果我专注于" 应用程序主窗体的窗口句柄 "这个词,我认为它是指应用程序主窗体的窗口句柄,那么我可以比较:
MainForm
的Application
但他们不一样:
Application.MainForm.Handle: 11473728
Application.Handle: 11079574
Run Code Online (Sandbox Code Playgroud)
那是什么Application.Handle
?
Application
的MainForm
,那么他们为什么不匹配?Application
's 的窗口句柄MainForm
,那么它是什么?我真正要问的是:Application.Handle存在的设计原理是什么?如果我能理解为什么,应该如何变得明显.
通过20个问题的游戏更新理解:
在谈到通过让它的主人在任务栏上出现一个窗口的解决方案时null
,Peter Below在2000年说:
这可能会导致从次要形式显示的模态形式出现一些问题.
如果用户在模态表单启动时从应用程序切换,然后返回到显示它的表单,则模式表单可能隐藏在表单下方.可以通过确保模态形式是父级来处理这个问题[原文如此; 他的意思是拥有]到表明它的形式(使用
params.WndParent
如上)但是对于
Dialogs
单元和异常 …
将表单设置为WindowState = wsMaximized
有时会使表单最大化但不会:
长期错误:这是我在2003年首次在Borland新闻组中提出的一个问题:
然后在2006年:
然后在2008年再次:
有人在2012年的Embarcadero论坛上提出这个问题:
现在是时候将18岁的bug移植到Stackoverflow了.也许某人终于想出了一个解决方法.
重现的步骤:
我的帖子包含了六种失败模式,但最简单的是:
删除表单上的a Label
和Edit
a:
为以下内容添加OnEnter
活动TEdit
:
procedure TForm1.Edit1Enter(Sender: TObject);
begin
Label1.Font.Style := Label1.Font.Style + [fsBold];
end;
Run Code Online (Sandbox Code Playgroud)并设置表格:
WindowState
到wsMaximizedAutoScroll
为假而bazinga,失败了.
2008年帖子的另一组步骤之一:
- 创建一个新的应用程序和一个表单.
- 在设计时将表单设置为最大化(WindowState = wsMaximized).
- 删除窗体上的ListView控件
在OnShow期间,将20个空项添加到列表视图中:
Run Code Online (Sandbox Code Playgroud)procedure TForm1.FormShow(Sender: TObject); var i: Integer; begin for i := 1 to 20 do ListView1.Items.Add; end;
在设计时将表单的AutoScroll属性设置为false(AutoScroll = False)
当然,我没有追求的是"在n …
我希望了解
当应用于对象构造函数时.每次我随机添加关键字直到编译器关闭 - 并且(在使用Delphi开发12年之后)我宁愿知道我在做什么,而不是随意尝试.
给出一组假设的对象:
TComputer = class(TObject)
public
constructor Create(Cup: Integer); virtual;
end;
TCellPhone = class(TComputer)
public
constructor Create(Cup: Integer; Teapot: string); virtual;
end;
TiPhone = class(TCellPhone)
public
constructor Create(Cup: Integer); override;
constructor Create(Cup: Integer; Teapot: string); override;
end;
Run Code Online (Sandbox Code Playgroud)
我希望它们表现的方式可能从声明中可以明显看出,但是:
TComputer
有简单的构造函数,后代可以覆盖它TCellPhone
有一个替代构造函数,后代可以覆盖它TiPhone
覆盖两个构造函数,调用每个构造函数的继承版本现在该代码无法编译.我想明白为什么它不起作用.我也想了解覆盖构造函数的正确方法.或许你永远不能覆盖构造函数?或者覆盖构造函数是完全可以接受的?也许你永远不应该有多个构造函数,也许完全可以接受多个构造函数.
我想了解原因.修复它会很明显.
编辑:我也期待获得的订单上的推理virtual
,override
,overload
,reintroduce
.因为在尝试关键字的所有组合时,组合的数量会爆炸:
考虑:
const
clHotlight: TColor = $00FF9933;
clLink = clHotLight; //alias of clHotlight
[Error] file.pas: Constant expression expected
Run Code Online (Sandbox Code Playgroud)
和替代措辞有效:
const
clHotlight = TColor($00FF9933);
clLink = clHotLight; //alias of clHotlight
Run Code Online (Sandbox Code Playgroud)
说明.
然后考虑:
const
AdministratorGUID: TGUID = '{DE44EEA0-6712-11D4-ADD4-0006295717DA}';
SuperuserGUID = AdministratorGUID; //alias of AdministratorGUID
[Error] file.pas: Constant expression expected
Run Code Online (Sandbox Code Playgroud)
并修复.
编辑:const
在声明之前添加关键字; 有人不相信他们是常设.
delphi compiler-errors constants delphi-5 compiler-constants
在Delphi 5中是否有任何方法可以将字符串转换为TDateTime,您可以在其中指定要使用的实际格式?
I'm working on a jobprocessor, which accepts tasks from various workstations. The tasks have a range of parameters, some of which are dates, but (unfortunately, and out of my control) they're passed as strings. Since the jobs can come from different workstations, the actual datetime format used to format the dates as a string might (and, of course, actual do) differ.
Googling around, the only quick solutions I found was to sneakily change the ShortDateFormat
variable, and …
几个月前,一位同事提到我,我们的一个内部Delphi应用程序似乎占用了8 GB的RAM.我告诉他了:
那是不可能的
32位应用程序仅具有32位虚拟地址空间.即使存在内存泄漏,它可以消耗的内存最多也是2 GB.之后,分配将失败(因为虚拟地址空间中不会有空白空间).在内存泄漏的情况下,虚拟页面将被换出到页面文件,从而释放物理RAM.
但他指出Windows资源监视器表明系统上可用的RAM不到1 GB.虽然我们的应用程序仅使用220 MB的虚拟内存:关闭它可以释放8 GB的物理RAM.
我让应用程序运行了几个星期,今天我终于决定测试它.
首先,我在关闭应用程序之前查看内存使用情况:
我使用资源监视器来检查应用程序使用的内存,以及正在使用的总RAM:
然后关闭应用程序后的内存使用情况:
我还使用Process Explorer来查看前后物理RAM使用情况的细分.唯一的区别是8 GB的RAM 确实是未提交的,现在是免费的:
| Item | Before | After |
|-------------------------------|------------|-----------|
| Commit Charge (K) | 15,516,388 | 7,264,420 |
| Physical Memory Available (K) | 1,959,480 | 9,990,012 |
| Zeroed Paging List (K) | 539,212 | 8,556,340 |
Run Code Online (Sandbox Code Playgroud)
注意:Windows有时会浪费时间将所有内存清零,而不是简单地将其放在备用列表中,并根据需要将其清零(因为需要满足内存请求).
这些都没有解释RAM正在做什么(你坐在那里做什么!你包含什么!?)
我的问题类似于这里的想法:在delphi中替换组件类.
但我需要根据需要更改特定的组件类.
这是一些伪演示代码:
unit Unit1;
TForm1 = class(TForm)
ImageList1: TImageList;
ImageList2: TImageList;
private
ImageList3: TImageList;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
ImageList3 := TImageList.Create(Self);
// all instances of TImageList run as usual
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Unit2.MakeSuperImageList(ImageList2);
Unit2.MakeSuperImageList(ImageList3);
// from now on ONLY ImageList2 and ImageList3 are TSuperImageList
// ImageList1 is unchanged
end;
Run Code Online (Sandbox Code Playgroud)
unit Unit2;
type
TSuperImageList = class(Controls.TImageList)
protected
procedure DoDraw(Index: Integer; Canvas: TCanvas; X, Y: Integer;
Style: Cardinal; Enabled: Boolean = True); override;
end; …
Run Code Online (Sandbox Code Playgroud) 当我尝试Trunc()
一个Real
值时,我得到一个(可重复的)浮点异常.
例如:
Trunc(1470724508.0318);
Run Code Online (Sandbox Code Playgroud)
实际上,实际代码更复杂:
ns: Real;
v: Int64;
ns := ((HighPerformanceTickCount*1.0)/g_HighResolutionTimerFrequency) * 1000000000;
v := Trunc(ns);
Run Code Online (Sandbox Code Playgroud)
但最终它仍归结为:
Trunc(ARealValue);
Run Code Online (Sandbox Code Playgroud)
现在,我不能在其他任何地方重复它 - 就在这一点.每次失败的地方.
幸运的是计算机并不神奇.英特尔CPU执行非常具体的可观察操作.所以我应该能够找出浮点运算失败的原因.
进入CPU窗口
v:= Trunc(ns)
Run Code Online (Sandbox Code Playgroud)fld qword ptr [ebp-$10]
这会将ebp- $ 10处的8字节浮点值加载到浮点寄存器中ST0
.
内存地址[ebp- $ 10]的字节数为:
0018E9D0: 6702098C 41D5EA5E (as DWords)
0018E9D0: 41D5EA5E6702098C (as QWords)
0018E9D0: 1470724508.0318 (as Doubles)
Run Code Online (Sandbox Code Playgroud)
调用成功,浮点寄存器包含适当的值:
接下来是对RTL Trunc函数的实际调用:
call @TRUNC
Run Code Online (Sandbox Code Playgroud)
接下来是Delphi RTL的Trunc功能:
@TRUNC:
Run Code Online (Sandbox Code Playgroud)sub esp,$0c wait fstcw word ptr [esp] //Store Floating-Point Control Word on the …
在Delphi 1中,使用FloatToStrF
或CurrToStrF
将自动使用该DecimalSeparator
字符表示小数点.不幸的DecimalSeparator
是在SysUtils中声明为Char
1,2:
var
DecimalSeparator: Char;
Run Code Online (Sandbox Code Playgroud)
虽然LOCALE_SDECIMAL
被允许最多为三个字符:
用于小数分隔符的字符,例如"." 在"3.14"或","在"3,14"中.此字符串允许的最大字符数为4,包括终止空字符.
这导致Delphi无法正确读取小数分隔符; 回退假设一个默认的小数分隔符" .
":
DecimalSeparator := GetLocaleChar(DefaultLCID, LOCALE_SDECIMAL, '.');
Run Code Online (Sandbox Code Playgroud)
在我的计算机上,这是一个非常字符,这会导致浮点数和货币值错误地本地化为U + 002E(句号)小数点.
我很愿意直接调用Windows API函数,其目的是为了浮点或货币值转换为一个本地化的字符串:
除了这些函数之外,还需要一串图片代码,其中唯一允许的字符是:
U+0030
.. U+0039
).
),如果数字是浮点值(U+002E
)U+002D
)这将是一个很好的方式1至浮点或货币价值转换为遵守这些规则的字符串?例如
1234567.893332
-1234567
鉴于本地用户的语言环境(即我的电脑):
-
表示否定(例如--
).
来表示小数点(例如,,
)0123456789
来表示数字 …我们已经用Delphi 5编写了这个大型应用程序,直到今天仍在进行开发.有关于迁移到更新版本的研究正在进行中,但到目前为止还没有成功,因为一些第三方组件尚未更新,并且不适用于更高版本.
与此同时,人们需要继续努力.现在Delphi 5 IDE并不是真正的享受.它非常错误,并且缺乏当代IDE的许多功能,这使得它很难使用.特别是在调试方面.
所以我想知道 - 在这个过程中可以使用Visual Studio吗?据我所知,.PDB文件格式非常陈旧,并且有很好的文档记录.是否有可能使Delphi编译器以某种方式为其编译结果生成.PDB文件?然后可以使用Visual Studio调试程序,可能比原始IDE更大.
好吧,绝对的圣杯将把所有的开发都转移到VS,只是让编译器不受Delphi的影响,但我想这将是非常不可能的.