我们已经用Delphi 5编写了这个大型应用程序,直到今天仍在进行开发.有关于迁移到更新版本的研究正在进行中,但到目前为止还没有成功,因为一些第三方组件尚未更新,并且不适用于更高版本.
与此同时,人们需要继续努力.现在Delphi 5 IDE并不是真正的享受.它非常错误,并且缺乏当代IDE的许多功能,这使得它很难使用.特别是在调试方面.
所以我想知道 - 在这个过程中可以使用Visual Studio吗?据我所知,.PDB文件格式非常陈旧,并且有很好的文档记录.是否有可能使Delphi编译器以某种方式为其编译结果生成.PDB文件?然后可以使用Visual Studio调试程序,可能比原始IDE更大.
好吧,绝对的圣杯将把所有的开发都转移到VS,只是让编译器不受Delphi的影响,但我想这将是非常不可能的.
我有一个对象,它将一个特别复杂的接口的实现委托给子对象.这正是我认为的工作TAggregatedObject." child "对象维护对其" 控制器 " 的弱引用,并且所有QueryInterface请求都传递回父级.这样可以保持IUnknown
始终为同一对象的规则.
所以,我的父(即"Controller")对象声明它实现了IStream接口:
type
TRobot = class(TInterfacedObject, IStream)
private
function GetStream: IStream;
public
property Stream: IStream read GetStrem implements IStream;
end;
Run Code Online (Sandbox Code Playgroud)
注意:这是一个假设的例子.我选择这个词
Robot是因为它听起来很复杂,并且单词只有5个字母 - 它很短.我也选择IStream因为它的短.我打算使用IPersistFile或IPersistFileInit,但它们更长,并使示例代码更难实现.换句话说:这是一个假设的例子.
现在我有我的子对象将实现IStream:
type
TRobotStream = class(TAggregatedObject, IStream)
public
...
end;
Run Code Online (Sandbox Code Playgroud)
所有剩下的,这就是我的问题开始的地方:创建RobotStream它被要求的时间:
function TRobot.GetStream: IStream;
begin
Result := TRobotStream.Create(Self) as IStream;
end;
Run Code Online (Sandbox Code Playgroud)
此代码无法编译,错误Operator not applicable to this operand …
更新:用一个更简单的例子来解决问题,原来接受的答案没有回答
鉴于以下类及其祖先:
TComputer = class(TObject)
public
constructor Create(Teapot: string='');
end;
TCellPhone = class(TComputer)
public
constructor Create(Cup: Integer); overload; virtual;
constructor Create(Cup: Integer; Teapot: string); overload; virtual;
end;
Run Code Online (Sandbox Code Playgroud)
现在TCellPhone有3个构造函数可见:
我该怎么做才能TCellPhone使祖先构造函数(Teapot: string = '')不可见,只留下声明的构造函数:
注:通常简单的行为有一个后代的构造函数隐藏了祖先:
Run Code Online (Sandbox Code Playgroud)TCellPhone = class(TComputer) public constructor Create(Cup: Integer); virtual; end;
- 杯子:整数
如果你想保留祖先构造函数和后代,你可以将后代标记为
overload:Run Code Online (Sandbox Code Playgroud)TCellPhone = class(TComputer) public constructor Create(Cup: Integer); overload; virtual; end;
- 杯子:整数
- 茶壶:string =''
在这个问题的示例代码中,Delphi误解了我的 …
我在Windows应用程序中托管Internet Explorer.我可以向下滚动到文档的底部.当我然后尝试向上滚动时,我得到除零异常:
当我滚动使用Page Up崩溃似乎发生在呼叫 -IOleInPlaceActiveObject:TranslateAccelerator
当我使用鼠标滚动时,在调用期间发生崩溃
无论哪种方式,崩溃都发生在Internet Explorer中.
Delphi在异常时显示的堆栈跟踪:

与Jedi异常跟踪显示的堆栈跟踪不同:
Exception EZeroDivide in module mshtml.dll at 00378B89.
Floating point division by zero.
Exception raised by object: TEmbeddedWB
Full Exception Details:
EZeroDivide
ExceptionCode: 0xC000008E (EXCEPTION_FLT_DIVIDE_BY_ZERO)
The thread tried to divide a floating-point value by a floating-point divisor of zero.
ExceptionFlags: 0x00000002
ExceptionAddress: 0x574C8B89
Parameters: (0x00000000)
EXCEPTION_RECORD: nil
Message: Floating point division by zero
Stack Trace:
[574C8B89] Unknown function at DllGetClassObject + $FF033
[004CA61E] …Run Code Online (Sandbox Code Playgroud) 微软已经在GetTickCount的文档中说过,你永远无法比较滴答计数来检查是否已经过了一段时间.例如:
不正确(伪代码):
DWORD endTime = GetTickCount + 10000; //10 s from now
...
if (GetTickCount > endTime)
break;
Run Code Online (Sandbox Code Playgroud)
上面的代码很糟糕,因为它可以对tick计数器进行翻转.例如,假设时钟接近其范围的结尾:
endTime = 0xfffffe00 + 10000
= 0x00002510; //9,488 decimal
Run Code Online (Sandbox Code Playgroud)
然后你执行检查:
if (GetTickCount > endTime)
Run Code Online (Sandbox Code Playgroud)
这是立刻感到满意,因为GetTickCount 是大于endTime:
if (0xfffffe01 > 0x00002510)
Run Code Online (Sandbox Code Playgroud)
相反,你应该总是减去两个时间间隔:
DWORD startTime = GetTickCount;
...
if (GetTickCount - startTime) > 10000 //if it's been 10 seconds
break;
Run Code Online (Sandbox Code Playgroud)
看着同样的数学:
if (GetTickCount - startTime) > 10000
if (0xfffffe01 - 0xfffffe00) > 10000
if (1 > 10000)
Run Code Online (Sandbox Code Playgroud)
在C/C++中,这一点都很好,编译器在某种程度上表现得很好. …
我如何从IDE 运行TestCase?
我用一个简单的形式创建了一个新项目:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TForm1 = class(TForm)
private
public
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
end.
Run Code Online (Sandbox Code Playgroud)
现在我将添加一个测试用例来检查推送Button1是否应该完成:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
public
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
uses
TestFramework;
type
TForm1Tests = class(TTestCase)
private
f: TForm1;
protected
procedure SetUp; override;
procedure …Run Code Online (Sandbox Code Playgroud) 一个来自雷蒙德陈今天博客文章让我体会到优雅的解决方案我有一个问题.
各种shell函数,而不是所有的ITEMIDLIST结构,只能接受:
ITEMID_CHILDIDLIST_RELATIVEIDLIST_ABSOLUTEITEMID_CHILD_ARRAY结构.结构都是相同的,但现在您可以在编译器级别强制执行概念类型.
我有一套功能:
C:\Users\Ian\Desktop\AllisonAngel.jpg)AllisonAngel.jpg)C:\Users\Ian\Desktop)现在他们都被宣布为string,例如:
function GetFilenames(Folder: string; ...): ...
function IsValidBatchFilename(Path: string): ...
function GetReportType(Filename: string): ...
Run Code Online (Sandbox Code Playgroud)
我必须相信我传递了正确的东西; 而且我相信开发人员(例如我),知道以下两者之间的区别:
我想更改函数以使用"类型"字符串:
function GetFilenames(Folder: TFolderOnly; ...): ...
function IsValidBatchFilename(Path: TFullPath): ...
function GetReportType(Filename: TFilenameOnly): ...
Run Code Online (Sandbox Code Playgroud)
哪里:
type
TFullPath = …Run Code Online (Sandbox Code Playgroud) Application创建实例的位置和时间?(同样适用于Screen实例).
我在部分Forms或 System initialization部分没有看到任何内容.
在之前的CPU窗口中Application.Initialize,我看到了对@_InitExe(SysInit)的调用- 它导致了_StartExe(系统)和大量的asm代码 - Application据我所知,这并没有创建实例.
我在这里错过了什么?
我想打电话给EnumSystemLocales德尔福.例如:
{ Called for each supported locale. }
function LocalesCallback(Name: PChar): BOOL; stdcall;
begin
OutputDebugString(Name);
Result := Bool(1); //True
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
EnumSystemLocales(@LocalesCallback, LCID_SUPPORTED);
end;
Run Code Online (Sandbox Code Playgroud)
问题是回调只被调用一次.
注: EnumSystemLocales 在返回true,表示成功.
这句EnumSystemLocales话说我的回调必须返回true才能继续枚举(或者更准确地说,不能返回false继续枚举):
该函数通过将区域设置标识符(一次一个)传递给指定的应用程序定义的回调函数来枚举区域设置.这将一直持续到所有已安装或支持的语言环境标识符都已传递给回调函数或回调函数返回FALSE.
BOOL CALLBACK EnumLocalesProc(
__in LPTSTR lpLocaleString
);
Run Code Online (Sandbox Code Playgroud)
评论者遇到了"非虚假"定义的问题:
此函数必须返回1,而不是(DWORD)-1才能继续处理
这让我觉得delphi的定义
True: BOOL;
Run Code Online (Sandbox Code Playgroud)
与Window不同.(这就是我尝试返回值BOOL(1)- 仍然失败的原因).
接下来我想知道它是不是应该是stdcall.
无论哪种方式,有人可以建议如何在Delpi打电话EnumSystemLocales吗?
编辑:还试过:
Result := BOOL(-1);Result := BOOL($FFFFFFFF);Result := …我如何得到EXCEPTION_POINTERS,即:
PEXCEPTION_RECORD 和 PCONTEXTEExternal异常期间的数据?
当Windows抛出异常时,它会传递一个PEXCEPTION_POINTERS; 指向异常信息的指针:
typedef struct _EXCEPTION_POINTERS {
PEXCEPTION_RECORD ExceptionRecord;
PCONTEXT ContextRecord;
} EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;
Run Code Online (Sandbox Code Playgroud)
当Delphi抛出EExternal异常时,它只包含一半的信息,PEXCEPTION_RECORD唯一的:
EExternal = class(Exception)
public
ExceptionRecord: PExceptionRecord;
end;
Run Code Online (Sandbox Code Playgroud)
在EExternal例外情况下,如何同时获得两者?
我正在尝试使用MiniDumpWriteDumpDelphi中的函数编写Minidump .
该函数有一些可选参数:
function MiniDumpWriteDump(
hProcess: THandle; //A handle to the process for which the information is to be generated.
ProcessID: DWORD; //The identifier of the process for which the information is to be generated.
hFile: …Run Code Online (Sandbox Code Playgroud) delphi ×10
delphi-5 ×10
constructor ×1
dbghelp ×1
debugging ×1
delegation ×1
dunit ×1
interface ×1
minidump ×1
pdb-files ×1
tdd ×1
twebbrowser ×1
types ×1
unit-testing ×1
winapi ×1