我想在加载应用程序时显示启动画面.但是,某些第三方组件在启动期间会阻塞主线程几秒钟,这会导致所有表单都不更新.是否可以使用自己的线程启动屏幕,这样当主线程忙时它也会更新?
该应用程序是win32和Delphi 2007版.
编辑:我正在尝试避免"未绘制的启动画面"效果,如果某些其他窗口(来自其他应用程序)位于启动画面的顶部,例如alt-tabbing到另一个应用程序并返回,则会发生这种情况.
如果我有以下接口和一个实现它们的类 -
IBase = Interface ['{82F1F81A-A408-448B-A194-DCED9A7E4FF7}']
End;
IDerived = Interface(IBase) ['{A0313EBE-C50D-4857-B324-8C0670C8252A}']
End;
TImplementation = Class(TInterfacedObject, IDerived)
End;
Run Code Online (Sandbox Code Playgroud)
以下代码打印'Bad!' -
Procedure Test;
Var
A : IDerived;
Begin
A := TImplementation.Create As IDerived;
If Supports (A, IBase) Then
WriteLn ('Good!')
Else
WriteLn ('Bad!');
End;
Run Code Online (Sandbox Code Playgroud)
这有点烦人但可以理解.支持无法转换为IBase,因为IBase不在TImplementation支持的GUID列表中.可以通过将声明更改为 - 来修复
TImplementation = Class(TInterfacedObject, IDerived, IBase)
Run Code Online (Sandbox Code Playgroud)
然而,即使没有这样做,我已经知道 A实现了IBase,因为A是IDerived,而IDerived是IBase.所以,如果我遗漏支票,我可以投A,一切都会好的 -
Procedure Test;
Var
A : IDerived;
B : IBase;
Begin
A := TImplementation.Create As IDerived;
B := IBase(A);
//Can now successfully call any of B's methods …Run Code Online (Sandbox Code Playgroud) 我想在我的代码中禁用特定警告(W1035),因为我认为编译器对此警告是错误的:
function TfrmNagScreen.Run: TOption;
begin
if ShowModal = mrOk then
Result := TOption(rdgAction.EditValue)
else
Abort
end;
Run Code Online (Sandbox Code Playgroud)
因为Abort投掷,结果不可能是未定义的EAbort.
我试过了:
{$WARN 1035 Off}:显然这仅适用于某些特定错误(请参阅文档){$W-1035}:什么都不做我知道我可以在项目选项中全局关闭警告,或使用{$WARNINGS OFF},但这不是这里的意图.
编辑:我现在已经将QC作为#89744了.
以下代码应该编译并使用许多其他类型进行编译.
但是,编译器报告"Constant对象不能作为var参数传递"错误 - 尽管变量显然是一个变量.
program CurrencyConstant;
{$APPTYPE CONSOLE}
var
GVar: Currency;
begin
FillChar(GVar, SizeOf(GVar), 0);
end.
Run Code Online (Sandbox Code Playgroud)
同样,过程中的局部变量也会出现同样的问题.
procedure TestCurrency;
var
LVar: Currency;
begin
FillChar(LVar, SizeOf(LVar), 0);
end;
Run Code Online (Sandbox Code Playgroud)
我怀疑它与FillChar编译器魔术程序有关,这Dest是一个无类型的var参数. FillChar是我发现这个问题的唯一例程.
为了回应不可避免的"为什么要做那个评论":我们有一个代码生成器,它使用FillChar来一般地初始化记录结构和原始类型.它适用于其他一切,但出乎意料地失败了货币.我们确实有解决方法,但了解根本原因会很好,并且知道是否还有其他因素可能会给我们带来麻烦.
根据Jeroen的回答,可以合理地得出结论,这个问题存在于Delphi的所有部分中.此外,货币阵列显然也出现了类似的问题.
大卫的回答提供了一些很好的解决方法.
要考虑的最后一个解决方法是,修改生成器以处理Currency作为特例并简单地设置Value := 0.
我的公司有一个重大问题.我们在Delphi.NET中开发了一个由超过1.000.000行代码组成的应用程序.因此,我们坚持使用Delphi 2007和.NET 2.0.
随着技术和用例的不断发展,我们需要迁移到另一个开发平台.到目前为止,我们尝试了几种承诺将Delphi.NET转换为C#代码的工具 - 这些工具中的每一个都有一些问题,比如错误的字符串索引(Delphi 1 C#0)或类型用于声明数组边界.
在那种方法之后,我们尝试反编译Delphi.NET程序集 - 从中返回的代码几乎不可读,并且有数百个辅助函数调用Borland特定程序集.我已经看过自己编写一个转换器的可能性了,但Delphi的模糊语法很难用直接的语法实现.
那么现在是一个很好的问题,是否有任何可能性,不包括手工翻译所有代码?或者可能是允许部分和逐步迁移的迁移路径?
我已经阅读了针对FreeAndNil的案例,但仍然不明白为什么我不能在类析构函数中使用此方法?谁能解释一下.
更新:我认为Eric Grange的评论对我来说最有用.链接表明,如何处理它并不明显,这主要是品味问题.FreeAndInvalidate方法也很有用.
VCL表单设计器提供粉红色指导,用于在各自的文本基线上对齐控件:

但据我所知,这对标签和复选框不起作用. 更新:如果您准确地放置控件,它适用于标签,例如Ctrl- arrow.它适用于复选框 - 请参见截图.
现在,在某些形式上,我正在代码中创建控件,例如
ed := TEdit.Create(Self);
ed.SetBounds(...);
ed.Parent := SomePanel;
Run Code Online (Sandbox Code Playgroud)
我如何确保其文本基线对齐?我想将它用于编辑,组合框,标签和复选框.结果应该是这样的(没有红线,当然:-)):

编辑:我目前的做法是调用像AlignTop(8, [Edit1, ComboBox1], [CheckBox1, Label1]);用
procedure ControlArray_SetTop(const AControls: array of TControl; ATop: Integer);
var
i: Integer;
begin
for i := Low(AControls) to High(AControls) do
AControls[i].Top := ATop;
end;
procedure AlignTop(ATop: Integer; const AControls: array of TControl; const ALabelLikeControls: array of TControl);
begin
ControlArray_SetTop(AControls, ATop);
ControlArray_SetTop(ALabelLikeControls, ATop + 3);
end;
Run Code Online (Sandbox Code Playgroud)
我的目标是用更强大,更少hacky的东西取而代之.
我基本上想要的是启动AsyncCall并继续我的代码加载.我有接口部分,消耗大量的时间(600 + ms),我想在独立的线程中加载此代码.
我试图用AsyncCall这样的东西:
procedure Load;
begin
...
end;
initialization
AsyncCall(@Load, []); // or LocalAsyncCall(@Load)
Run Code Online (Sandbox Code Playgroud)
但是,此Load过程实际上是在主线程中启动,而不是在新创建的线程中启动.如何强制将Load程序加载到除以外的任何线程中MainThread?
我可以创建TThread和Execute这个,但我想强制AsyncCall或LocalAsyncCall或任何从AsyncCall库中进行工作.
谢谢你的帮助.
题:
有没有办法用Delphi 2007进行鸭子打字(即没有泛型和高级Rtti功能)?
Duck为Delphi 2010打字资源:
最后编辑:
我已经深入研究了上面列出的资源,并在这里研究了每个发布的答案.
我使用Delphi 2007.我有一个TListViewwith OwnerData并OwnerDraw设置为True.ViewStyle设置为vsReport.
我有一个record.
type TAList=record
Item:Integer;
SubItem1:String;
SubItem2:String;
end;
var
ModuleData: array of TAList;
procedure TForm1.ListView3Data(Sender: TObject; Item: TListItem);
begin
Item.Caption := IntToStr(ModuleData[Item.Index].Item);
Item.SubItems.Add(ModuleData[Item.Index].SubItem1);
Item.SubItems.Add(ModuleData[Item.Index].SubItem2);
end;
procedure TForm1.ListView3DrawItem(Sender: TCustomListView; Item: TListItem; Rect: TRect; State: TOwnerDrawState);
var
LIndex : integer;
LRect: TRect;
LText: string;
TTListView: TListView;
begin
TTListView := TListView(Sender);
if (Item.SubItems[0] = '...') then
begin
TTListView.Canvas.Brush.Color := clHighlight;
TTListView.Canvas.Font.Color := clHighlightText;
end else
begin
TTListView.Canvas.Brush.Color := TTListView.Color;
TTListView.Canvas.Font.Color …Run Code Online (Sandbox Code Playgroud) delphi ×10
delphi-2007 ×10
.net ×1
asynchronous ×1
c# ×1
delphi-5 ×1
delphi.net ×1
designer ×1
destructor ×1
duck-typing ×1
fillchar ×1
hint ×1
interface ×1
ownerdrawn ×1
tlistview ×1
types ×1
winapi ×1