有点象IDispatch.Invoke()方法 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;
呵呵,脚本引擎在公司,家里没有!我这里只有一个测试 Demo
通过RTTI可以得到每个事件具体的声明 参考如下代码: {$R-}uses TypInfo;function MethodCategory(AEventType: Pointer): string; var vTypeInfo: PTypeInfo absolute AEventType; vTypeData: PTypeData; I: Integer; vParams: string; vParamData: PChar; vParamFlags: TParamFlags; vParamName: ShortString; vTypeName: ShortString; vResultType: ShortString; begin Result := ''; if vTypeInfo^.Kind <> tkMethod then Exit; // 非方法类型 Result := vTypeInfo^.Name; PChar(vTypeData) := PChar(vTypeInfo) + SizeOf(TTypeKind) + Length(vTypeInfo^.Name) + SizeOf(Byte); case vTypeData^.MethodKind of mkProcedure: Result := Result + ' = procedure %s of object;'; mkFunction: Result := Result + ' = function %s: %s of object'; mkConstructor: Result := Result + ' = constructor %s of object'; mkDestructor: Result := Result + ' = destructor %s of object'; mkClassProcedure: Result := Result + ' = procedure %s of class'; mkClassFunction: Result := Result + ' = function %s: %s of class'; mkSafeProcedure: Result := Result + ' = procedure %s of class'; mkSafeFunction: Result := Result + ' = function %s: %s of class'; end; vParams := ''; vParamData := @vTypeData^.ParamList[0]; for I := 0 to vTypeData^.ParamCount - 1 do begin Move(vParamData^, vParamFlags, SizeOf(TParamFlags)); Inc(vParamData, SizeOf(TParamFlags)); Move(vParamData^, vParamName[0], SizeOf(Byte)); Inc(vParamData, SizeOf(Byte)); Move(vParamData^, vParamName[1], Ord(vParamName[0])); Inc(vParamData, Ord(vParamName[0])); Move(vParamData^, vTypeName[0], SizeOf(Byte)); Inc(vParamData, SizeOf(Byte)); Move(vParamData^, vTypeName[1], Ord(vTypeName[0])); Inc(vParamData, Ord(vTypeName[0])); vParams := vParams + '; '; if pfVar in vParamFlags then vParams := vParams + 'var '; if pfConst in vParamFlags then vParams := vParams + 'const '; if pfOut in vParamFlags then vParams := vParams + 'out '; vParams := vParams + vParamName; if vTypeName <> '' then begin vParams := vParams + ': '; if pfArray in vParamFlags then vParams := vParams + 'array of '; vParams := vParams + vTypeName; end; end; Move(vParamData^, vResultType[0], SizeOf(Byte)); Inc(vParamData, SizeOf(Byte)); Move(vParamData^, vResultType[1], Ord(vResultType[0])); Delete(vParams, 1, 2); if vParams <> '' then vParams := '(' + vParams + ')'; case vTypeData^.MethodKind of mkProcedure, mkConstructor, mkDestructor, mkClassProcedure, mkSafeProcedure: Result := Format(Result, [vParams]); else Result := Format(Result, [vParams, vResultType]); end; end;procedure TForm1.Button1Click(Sender: TObject); begin Edit1.Text := MethodCategory(TypeInfo(TMouseEvent)); end;
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;
Demo
参考如下代码:
{$R-}uses TypInfo;function MethodCategory(AEventType: Pointer): string;
var
vTypeInfo: PTypeInfo absolute AEventType;
vTypeData: PTypeData;
I: Integer;
vParams: string;
vParamData: PChar;
vParamFlags: TParamFlags;
vParamName: ShortString;
vTypeName: ShortString;
vResultType: ShortString;
begin
Result := '';
if vTypeInfo^.Kind <> tkMethod then Exit; // 非方法类型
Result := vTypeInfo^.Name;
PChar(vTypeData) := PChar(vTypeInfo) +
SizeOf(TTypeKind) + Length(vTypeInfo^.Name) + SizeOf(Byte);
case vTypeData^.MethodKind of
mkProcedure: Result := Result + ' = procedure %s of object;';
mkFunction: Result := Result + ' = function %s: %s of object';
mkConstructor: Result := Result + ' = constructor %s of object';
mkDestructor: Result := Result + ' = destructor %s of object';
mkClassProcedure: Result := Result + ' = procedure %s of class';
mkClassFunction: Result := Result + ' = function %s: %s of class';
mkSafeProcedure: Result := Result + ' = procedure %s of class';
mkSafeFunction: Result := Result + ' = function %s: %s of class';
end;
vParams := '';
vParamData := @vTypeData^.ParamList[0];
for I := 0 to vTypeData^.ParamCount - 1 do
begin
Move(vParamData^, vParamFlags, SizeOf(TParamFlags));
Inc(vParamData, SizeOf(TParamFlags)); Move(vParamData^, vParamName[0], SizeOf(Byte));
Inc(vParamData, SizeOf(Byte));
Move(vParamData^, vParamName[1], Ord(vParamName[0]));
Inc(vParamData, Ord(vParamName[0])); Move(vParamData^, vTypeName[0], SizeOf(Byte));
Inc(vParamData, SizeOf(Byte));
Move(vParamData^, vTypeName[1], Ord(vTypeName[0]));
Inc(vParamData, Ord(vTypeName[0]));
vParams := vParams + '; ';
if pfVar in vParamFlags then vParams := vParams + 'var ';
if pfConst in vParamFlags then vParams := vParams + 'const ';
if pfOut in vParamFlags then vParams := vParams + 'out ';
vParams := vParams + vParamName;
if vTypeName <> '' then
begin
vParams := vParams + ': ';
if pfArray in vParamFlags then vParams := vParams + 'array of ';
vParams := vParams + vTypeName;
end;
end;
Move(vParamData^, vResultType[0], SizeOf(Byte));
Inc(vParamData, SizeOf(Byte));
Move(vParamData^, vResultType[1], Ord(vResultType[0])); Delete(vParams, 1, 2);
if vParams <> '' then vParams := '(' + vParams + ')';
case vTypeData^.MethodKind of
mkProcedure, mkConstructor, mkDestructor, mkClassProcedure,
mkSafeProcedure: Result := Format(Result, [vParams]);
else Result := Format(Result, [vParams, vResultType]);
end;
end;procedure TForm1.Button1Click(Sender: TObject);
begin
Edit1.Text := MethodCategory(TypeInfo(TMouseEvent));
end;
在解析的时候就通过RTTI得到了这些信息
我是希望通过这些消息能够得到该事件触发时候传递到我说的那中通用过程中的参数的值