📄 system.pas
字号:
{ *********************************************************************** }
{ }
{ Delphi / Kylix Cross-Platform Runtime Library }
{ System Unit }
{ }
{ Copyright (c) 1988, 2001 Borland Software Corporation }
{ }
{ This file may be distributed and/or modified under the terms of the }
{ GNU General Public License version 2 as published by the Free Software }
{ Foundation and appearing at http://www.borland.com/kylix/gpl.html. }
{ }
{ Licensees holding a valid Borland No-Nonsense License for this }
{ Software may use this file in accordance with such license, which }
{ appears in the file license.txt that came with this software. }
{ }
{ *********************************************************************** }
unit System; { Predefined constants, types, procedures, }
{ and functions (such as True, Integer, or }
{ Writeln) do not have actual declarations.}
{ Instead they are built into the compiler }
{ and are treated as if they were declared }
{ at the beginning of the System unit. }
{$H+,I-,R-,O+,W-}
{$WARN SYMBOL_PLATFORM OFF}
{ L- should never be specified.
The IDE needs to find DebugHook (through the C++
compiler sometimes) for integrated debugging to
function properly.
ILINK will generate debug info for DebugHook if
the object module has not been compiled with debug info.
ILINK will not generate debug info for DebugHook if
the object module has been compiled with debug info.
Thus, the Pascal compiler must be responsible for
generating the debug information for that symbol
when a debug-enabled object file is produced.
}
interface
(* You can use RTLVersion in $IF expressions to test the runtime library
version level independently of the compiler version level.
Example: {$IF RTLVersion >= 16.2} ... {$IFEND} *)
const
RTLVersion = 15.00;
{$EXTERNALSYM CompilerVersion}
(*
const
CompilerVersion = 0.0;
CompilerVersion is assigned a value by the compiler when
the system unit is compiled. It indicates the revision level of the
compiler features / language syntax, which may advance independently of
the RTLVersion. CompilerVersion can be tested in $IF expressions and
should be used instead of testing for the VERxxx conditional define.
Always test for greater than or less than a known revision level.
It's a bad idea to test for a specific revision level.
*)
{$IFDEF DECLARE_GPL}
(* The existence of the GPL symbol indicates that the System unit
and the rest of the Delphi runtime library were compiled for use
and distribution under the terms of the GNU General Public License (GPL).
Under the terms of the GPL, all applications compiled with the
GPL version of the Delphi runtime library must also be distributed
under the terms of the GPL.
For more information about the GNU GPL, see
http://www.gnu.org/copyleft/gpl.html
The GPL symbol does not exist in the Delphi runtime library
purchased for commercial/proprietary software development.
If your source code needs to know which licensing model it is being
compiled into, you can use {$IF DECLARED(GPL)}...{$IFEND} to
test for the existence of the GPL symbol. The value of the
symbol itself is not significant. *)
const
GPL = True;
{$ENDIF}
{ Variant type codes (wtypes.h) }
varEmpty = $0000; { vt_empty 0 }
varNull = $0001; { vt_null 1 }
varSmallint = $0002; { vt_i2 2 }
varInteger = $0003; { vt_i4 3 }
varSingle = $0004; { vt_r4 4 }
varDouble = $0005; { vt_r8 5 }
varCurrency = $0006; { vt_cy 6 }
varDate = $0007; { vt_date 7 }
varOleStr = $0008; { vt_bstr 8 }
varDispatch = $0009; { vt_dispatch 9 }
varError = $000A; { vt_error 10 }
varBoolean = $000B; { vt_bool 11 }
varVariant = $000C; { vt_variant 12 }
varUnknown = $000D; { vt_unknown 13 }
//varDecimal = $000E; { vt_decimal 14 } {UNSUPPORTED as of v6.x code base}
//varUndef0F = $000F; { undefined 15 } {UNSUPPORTED per Microsoft}
varShortInt = $0010; { vt_i1 16 }
varByte = $0011; { vt_ui1 17 }
varWord = $0012; { vt_ui2 18 }
varLongWord = $0013; { vt_ui4 19 }
varInt64 = $0014; { vt_i8 20 }
//varWord64 = $0015; { vt_ui8 21 } {UNSUPPORTED as of v6.x code base}
{ if adding new items, update Variants' varLast, BaseTypeMap and OpTypeMap }
varStrArg = $0048; { vt_clsid 72 }
varString = $0100; { Pascal string 256 } {not OLE compatible }
varAny = $0101; { Corba any 257 } {not OLE compatible }
// custom types range from $110 (272) to $7FF (2047)
varTypeMask = $0FFF;
varArray = $2000;
varByRef = $4000;
{ TVarRec.VType values }
vtInteger = 0;
vtBoolean = 1;
vtChar = 2;
vtExtended = 3;
vtString = 4;
vtPointer = 5;
vtPChar = 6;
vtObject = 7;
vtClass = 8;
vtWideChar = 9;
vtPWideChar = 10;
vtAnsiString = 11;
vtCurrency = 12;
vtVariant = 13;
vtInterface = 14;
vtWideString = 15;
vtInt64 = 16;
{ Virtual method table entries }
vmtSelfPtr = -76;
vmtIntfTable = -72;
vmtAutoTable = -68;
vmtInitTable = -64;
vmtTypeInfo = -60;
vmtFieldTable = -56;
vmtMethodTable = -52;
vmtDynamicTable = -48;
vmtClassName = -44;
vmtInstanceSize = -40;
vmtParent = -36;
vmtSafeCallException = -32 deprecated; // don't use these constants.
vmtAfterConstruction = -28 deprecated; // use VMTOFFSET in asm code instead
vmtBeforeDestruction = -24 deprecated;
vmtDispatch = -20 deprecated;
vmtDefaultHandler = -16 deprecated;
vmtNewInstance = -12 deprecated;
vmtFreeInstance = -8 deprecated;
vmtDestroy = -4 deprecated;
vmtQueryInterface = 0 deprecated;
vmtAddRef = 4 deprecated;
vmtRelease = 8 deprecated;
vmtCreateObject = 12 deprecated;
type
TObject = class;
TClass = class of TObject;
HRESULT = type Longint; { from WTYPES.H }
{$EXTERNALSYM HRESULT}
PGUID = ^TGUID;
TGUID = packed record
D1: LongWord;
D2: Word;
D3: Word;
D4: array[0..7] of Byte;
end;
PInterfaceEntry = ^TInterfaceEntry;
TInterfaceEntry = packed record
IID: TGUID;
VTable: Pointer;
IOffset: Integer;
ImplGetter: Integer;
end;
PInterfaceTable = ^TInterfaceTable;
TInterfaceTable = packed record
EntryCount: Integer;
Entries: array[0..9999] of TInterfaceEntry;
end;
TMethod = record
Code, Data: Pointer;
end;
{ TObject.Dispatch accepts any data type as its Message parameter. The
first 2 bytes of the data are taken as the message id to search for
in the object's message methods. TDispatchMessage is an example of
such a structure with a word field for the message id.
}
TDispatchMessage = record
MsgID: Word;
end;
TObject = class
constructor Create;
procedure Free;
class function InitInstance(Instance: Pointer): TObject;
procedure CleanupInstance;
function ClassType: TClass;
class function ClassName: ShortString;
class function ClassNameIs(const Name: string): Boolean;
class function ClassParent: TClass;
class function ClassInfo: Pointer;
class function InstanceSize: Longint;
class function InheritsFrom(AClass: TClass): Boolean;
class function MethodAddress(const Name: ShortString): Pointer;
class function MethodName(Address: Pointer): ShortString;
function FieldAddress(const Name: ShortString): Pointer;
function GetInterface(const IID: TGUID; out Obj): Boolean;
class function GetInterfaceEntry(const IID: TGUID): PInterfaceEntry;
class function GetInterfaceTable: PInterfaceTable;
function SafeCallException(ExceptObject: TObject;
ExceptAddr: Pointer): HResult; virtual;
procedure AfterConstruction; virtual;
procedure BeforeDestruction; virtual;
procedure Dispatch(var Message); virtual;
procedure DefaultHandler(var Message); virtual;
class function NewInstance: TObject; virtual;
procedure FreeInstance; virtual;
destructor Destroy; virtual;
end;
const
S_OK = 0; {$EXTERNALSYM S_OK}
S_FALSE = $00000001; {$EXTERNALSYM S_FALSE}
E_NOINTERFACE = HRESULT($80004002); {$EXTERNALSYM E_NOINTERFACE}
E_UNEXPECTED = HRESULT($8000FFFF); {$EXTERNALSYM E_UNEXPECTED}
E_NOTIMPL = HRESULT($80004001); {$EXTERNALSYM E_NOTIMPL}
type
IInterface = interface
['{00000000-0000-0000-C000-000000000046}']
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
end;
IUnknown = IInterface;
{$M+}
IInvokable = interface(IInterface)
end;
{$M-}
IDispatch = interface(IUnknown)
['{00020400-0000-0000-C000-000000000046}']
function GetTypeInfoCount(out Count: Integer): HResult; stdcall;
function GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): HResult; stdcall;
function GetIDsOfNames(const IID: TGUID; Names: Pointer;
NameCount, LocaleID: Integer; DispIDs: Pointer): HResult; stdcall;
function Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer;
Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult; stdcall;
end;
{$EXTERNALSYM IUnknown}
{$EXTERNALSYM IDispatch}
{ TInterfacedObject provides a threadsafe default implementation
of IInterface. You should use TInterfaceObject as the base class
of objects implementing interfaces. }
TInterfacedObject = class(TObject, IInterface)
protected
FRefCount: Integer;
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
public
procedure AfterConstruction; override;
procedure BeforeDestruction; override;
class function NewInstance: TObject; override;
property RefCount: Integer read FRefCount;
end;
TInterfacedClass = class of TInterfacedObject;
{ TAggregatedObject and TContainedObject are suitable base
classes for interfaced objects intended to be aggregated
or contained in an outer controlling object. When using
the "implements" syntax on an interface property in
an outer object class declaration, use these types
to implement the inner object.
Interfaces implemented by aggregated objects on behalf of
the controller should not be distinguishable from other
interfaces provided by the controller. Aggregated objects
must not maintain their own reference count - they must
have the same lifetime as their controller. To achieve this,
aggregated objects reflect the reference count methods
to the controller.
TAggregatedObject simply reflects QueryInterface calls to
its controller. From such an aggregated object, one can
obtain any interface that the controller supports, and
only interfaces that the controller supports. This is
useful for implementing a controller class that uses one
or more internal objects to implement the interfaces declared
on the controller class. Aggregation promotes implementation
sharing across the object hierarchy.
TAggregatedObject is what most aggregate objects should
inherit from, especially when used in conjunction with
the "implements" syntax. }
TAggregatedObject = class(TObject)
private
FController: Pointer; // weak reference to controller
function GetController: IInterface;
protected
{ IInterface }
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
public
constructor Create(const Controller: IInterface);
property Controller: IInterface read GetController;
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -