我一直在使用Windows API和Parts and States获得一些乐趣,并了解如何将控件绘制到画布上.
经过大量的试验和错误,我设法提出了这个程序,它会在画布上绘制一个按钮:
type
TButtonState = (bsDefault, bsDisabled, bsHot, bsNormal, bsPressed);
procedure DrawButton(ACanvas: TCanvas; X, Y, AWidth, AHeight: Integer;
AFont: TFont; Caption: string; ButtonState: TButtonState);
var
Size: TSize;
R: TRect;
H: HTHEME;
begin
Size.cx := AWidth;
Size.cy := AHeight;
R := Rect(X, Y, X + AWidth, Y + AHeight);
if Winapi.uxTheme.UseThemes then
begin
H := OpenThemeData(0, 'BUTTON');
if H <> 0 then
try
ACanvas.Brush.Style := bsClear;
if AFont <> nil then
begin
ACanvas.Font.Assign(AFont);
end;
case …
Run Code Online (Sandbox Code Playgroud) 我有一个EurekaLog错误报告显示EEncodingError
.日志指向TFile.AppendAllText
.我打电话TFile.AppendAllText
是我的这个程序:
procedure WriteToFile(CONST FileName: string; CONST uString: string; CONST WriteOp: WriteOpperation; ForceFolder: Boolean= FALSE); // Works with UNC paths
begin
if NOT ForceFolder
OR (ForceFolder AND ForceDirectoriesMsg(ExtractFilePath(FileName))) then
if WriteOp= (woOverwrite)
then IOUtils.TFile.WriteAllText (FileName, uString)
else IOUtils.TFile.AppendAllText(FileName, uString);
end;
Run Code Online (Sandbox Code Playgroud)
这是来自EurekaLog的信息.
是什么导致这种情况发生?
刚刚安装了Delphi xe7.打开了一个用XE7开发的项目.旁注,但我首先担心的是,所有内容都会导致IDE挂起,无论是将"视图"从Master更改为iPhone4,还是只是在"设计视图"中拖动控件.我之前有一个工具单元,它具有接受TComboEdit参数的功能.似乎他们再次移动了一些东西,因为这个功能现在已被打破.为了快速找出哪个单元主持组合编辑,我打开了一个表单并放下了一个Combo编辑并保存.很酷,现在我知道有一个FMX.ComboEdit单元.我尝试删除组合编辑,这是我得到的:Selection contains a component, ComboEdit1, introduced in an ancestor and can not be deleted.
对于我在表单上删除的任何新控件也是如此,例如甚至是TEdits.无法删除任何内容.快速谷歌搜索引用TGrids和列...在我的表单上,只有Layouts和一个TabControl,其中新的位置控件在TabItem中.好吧,也许TabItems存在类似的错误,所以我尝试移动控件,使表单成为父级.但是,IDE会挂起大约30秒并且不会执行任何操作.
如何在Delphi xe7中删除这些控件?
我试图修改我的Delphi 2010代码以在XE7中编译(并希望保留在2010年编译它的能力).因此,在我的mainform的单元中,我添加了条件指令.以下工作在2010年正常
uses
{$IF CompilerVersion >= 24}System.Actions, {$ELSE}Actnlist,{$IFEND}
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
Run Code Online (Sandbox Code Playgroud)
但是XE7会自动System.Actions
在最后添加一个用于创建一个uses子句,该子句现在已经声明了两次System.Actions(见下文),并给出了一条错误消息[dcc32 Error] MyForm.pas(10): E2004 Identifier redeclared: 'System.Actions'
.为什么XE7不接受条件指令中的单位?
uses
{$IF CompilerVersion >= 24}System.Actions, {$ELSE}Actnlist,{$IFEND}
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
System.Actions; // <- automatically added
Run Code Online (Sandbox Code Playgroud) TParallel.For()
有一个称为的论点AStride
.在我的情况下,AStride是2:
TParallel.&For(2, 1, 10,
procedure(index: Integer)
begin
TThread.Queue(nil,
procedure
begin
memo1.Lines.Add(index.ToString());
end
);
end
);
Run Code Online (Sandbox Code Playgroud)
我在这里无法理解"AStride"的技术含义.是否AStride = 2
意味着第一个线程将处理该范围内的两个连续数字[1..10]
,第二个线程将处理下一个连续数字等?
**英语不是我的母语,我将"Stride"翻译为"long step"或"pace".
我正在使用Delphi XE7 IDE并且它经常挂起,开始消耗许多系统资源并且在例外情况下失败:
第三个例外的原因是什么?
我该怎么做才能让它稳定下来?
当我调用函数来获取值时,我通常初始化varible,以防函数失败或不返回任何内容,我想避免处理未初始化的变量.我对字符串,整数或任何其他类型都这样做.
整数变量的示例:
vPropValue := 0;
vPropValue := GetPropValue(vObject,'Height');
IF vPropValue > 0 Then
...
Run Code Online (Sandbox Code Playgroud)
这是我最常用的方式.
我知道我可以使用:
If GetPropValue(vObject,'Height') > 0 Then
...
Run Code Online (Sandbox Code Playgroud)
但是在第一个例子中,我避免多次调用函数,如果我稍后需要在代码中再次得到结果.
对于字符串也是一样的(即使我知道本地字符串被初始化为空字符串,而整数不是可以保存任何值)
vName := '';
vName := GetObjectName(vObject,'ObjectName');
IF Trim(vPropStrValue) <> '' Then
...
Run Code Online (Sandbox Code Playgroud)
我知道我可以采取措施避免重复的值赋值,比如确保函数在所有内容都失败时返回0.但是我有100多个函数而且我不能依赖我从来没有弄错过函数如何处理所有事情而且我确定有些人不会返回0,如果一切都失败了.
我试图理解为什么这不是理想的做法以及如何最好地避免它.
编辑
以下是函数未返回正确值或0的示例:
function GetValue(vType:integer):integer;
begin
if vType=1 then
Result:=100
else if (vType>2) and (vType<=9) then
Result:=200;
end;
procedure TForm1.Button1Click(Sender: TObject);
var vValue:integer;
begin
vValue:=GetValue(11);
Button1.Caption:=IntToStr(vValue);
end;
Run Code Online (Sandbox Code Playgroud)
在这种情况下,函数返回的值是一些随机数.
在这种情况下,初始化似乎是有效的方法.或不?
编辑2:
正如大卫在他的回答中指出的那样,正确的是,有一个警告
[dcc32 Warning] Unit1.pas(33): W1035 Return value of function 'GetValue' might be …
Run Code Online (Sandbox Code Playgroud) 我正在比较这两种初始化动态数组的方式之间的性能:
Arr := TArray<integer>.Create(1, 2, 3, 4, 5);
Run Code Online (Sandbox Code Playgroud)
和
SetLength(Arr, 5);
Arr[0] := 1;
Arr[1] := 2;
Arr[2] := 3;
Arr[3] := 4;
Arr[4] := 5;
Run Code Online (Sandbox Code Playgroud)
我准备了一个测试,我注意到使用数组"构造函数"需要两倍于另一个方法所需的时间.
测试:
uses
DateUtils;
function CreateUsingSetLength() : TArray<integer>;
begin
SetLength(Result, 5);
Result[0] := 1;
Result[1] := 2;
Result[2] := 3;
Result[3] := 4;
Result[4] := 5;
end;
Run Code Online (Sandbox Code Playgroud)
...
const
C_COUNT = 10000000;
var
Start : TDateTime;
i : integer;
Arr : TArray<integer>;
MS1 : integer;
MS2 : integer;
begin
Start := Now;
i := …
Run Code Online (Sandbox Code Playgroud) 为什么这段代码不会崩溃?T
没有.它是如何可以访问Caption
是否T
是nil
?
procedure Crash;
VAR T: TButton;
begin
T:= NIL;
T.Caption:= ''; <---------- this works
end;
Run Code Online (Sandbox Code Playgroud) 在Delphi XE7中,我使用此技巧根据是否选择了ListView中的项目来自动启用或禁用工具栏按钮("编辑ListView项目"),以防止用户在没有ListView时单击按钮选择的项目:
actTest
. actTest
给按钮. 在OnUpdate
该事件actTest
的行动写:
procedure TForm1.actTestUpdate(Sender: TObject);
begin
actTest.Enabled := ListView1.SelCount > 0;
CodeSite.Send('actTestUpdate'); // gets fired very often!
end;
Run Code Online (Sandbox Code Playgroud)现在,您可以看到根据是否选择了ListView中的项目来启用或禁用该按钮,与您是使用鼠标还是使用键盘或以编程方式选择/取消选择项目无关.
但是,在CodeSite Live Viewer中,我可以看到actTestUpdate
事件是连续且非常频繁地触发的,因此该语句很快actTest.Enabled := ListView1.SelCount > 0;
就被执行了.
所以我的问题是:这会降低性能吗?如果是,是否有另一种技巧可以实现上述目的?
delphi ×10
delphi-xe7 ×10
arrays ×1
delphi-2010 ×1
delphi-ide ×1
firemonkey ×1
parallel-for ×1
taction ×1
tlistview ×1
unicode ×1
winapi ×1