parent
7406cfb299
commit
2f98f9a684
|
|
@ -0,0 +1,751 @@
|
|||
unit utslvcl_com;
|
||||
interface
|
||||
(*
|
||||
//20231111
|
||||
//范例
|
||||
步骤:
|
||||
//继承 t_com_class
|
||||
//重写 get_clsid
|
||||
//重写 get_com_name
|
||||
//重写 invoke_param_is_excel
|
||||
//重写 execute_retun_is_excel
|
||||
//重写 invoke_call
|
||||
//重写 install_for_all_users
|
||||
//编译成exe
|
||||
//安装 名称.exe -install
|
||||
//卸载 名称.exe -uninstall
|
||||
//************脚本范例,编译该脚本为exe***************************
|
||||
com := new my_com();
|
||||
return com.do_command();
|
||||
type my_com=class(t_com_class)
|
||||
function create();
|
||||
begin
|
||||
inherited;
|
||||
end
|
||||
function get_clsid();virtual; //配置clsid
|
||||
begin
|
||||
return "{F59A8177-02A0-4019-A393-AF079F9AB365}";
|
||||
end
|
||||
function get_com_name();virtual; //配置名称
|
||||
begin
|
||||
return "mycom.test";
|
||||
end
|
||||
end
|
||||
*)
|
||||
uses tslvcl;
|
||||
type t_com_class = class()
|
||||
private
|
||||
theFactory;
|
||||
dwRegister;
|
||||
sguid;
|
||||
fapp;
|
||||
public
|
||||
function create();
|
||||
begin
|
||||
end
|
||||
function get_clsid();virtual; //配置clsid
|
||||
begin
|
||||
return "{F59A8177-02A0-4019-A393-AF079F9AB362}";
|
||||
//raise "clsid err";
|
||||
end
|
||||
function get_com_name();virtual; //配置名称
|
||||
begin
|
||||
return "tscomctl.test";
|
||||
//raise "com name err";
|
||||
end
|
||||
function invoke_param_is_excel(fname);virtual; //执行时候参数是否为excel格式
|
||||
begin
|
||||
return false;
|
||||
end
|
||||
function execute_retun_is_excel(fname);virtual;//返回时候参数是否为excel格式
|
||||
begin
|
||||
return false;
|
||||
end
|
||||
function invoke_call(fname,pms);virtual; //执行函数
|
||||
begin
|
||||
return callinarray(findfunction(fname),pms);
|
||||
end
|
||||
function COINIT_Param();virtual; //启动参数
|
||||
begin
|
||||
return 0;
|
||||
end
|
||||
function install_for_all_users(); //是否安装到本地为所有人使用
|
||||
begin
|
||||
return false;
|
||||
end
|
||||
function stop_run(); //停止
|
||||
begin
|
||||
fapp._wapi.PostQuitMessage(0);
|
||||
end
|
||||
function do_command();//执行
|
||||
begin
|
||||
for i:= 0 to sysparamcount() do
|
||||
begin
|
||||
//"-Embedding") == 0) || (_stricmp(lpCmdLine, "/Embedding"
|
||||
si := sysparamstr(i);
|
||||
if si="-Embedding" or si= "/Embedding" then
|
||||
begin
|
||||
return run_com();
|
||||
end
|
||||
if si="-install" then
|
||||
begin
|
||||
return do_install();
|
||||
end
|
||||
if si="-uninstall" then
|
||||
begin
|
||||
return do_uninstall();
|
||||
end
|
||||
end
|
||||
end
|
||||
function install_success();virtual;
|
||||
begin
|
||||
echo "步骤:安装完成!\r\n\r\n";
|
||||
end
|
||||
function uninstall_success();virtual;
|
||||
begin
|
||||
echo "步骤:卸载完成!\r\n\r\n";
|
||||
end
|
||||
private
|
||||
function do_install();
|
||||
begin
|
||||
do_install_sub();
|
||||
echo "\r\n输入回车键退出";
|
||||
s := readln();
|
||||
end
|
||||
function do_uninstall();
|
||||
begin
|
||||
do_uninstall_sub();
|
||||
echo "\r\n输入回车键退出";
|
||||
s := readln();
|
||||
end
|
||||
function do_install_sub();
|
||||
begin
|
||||
dllclsid := get_clsid();
|
||||
subid := "LocalServer32";
|
||||
comname := get_com_name();
|
||||
dllPath := sysexecname();
|
||||
rk := get_classes_key();
|
||||
if not ifobj(rk) then
|
||||
begin
|
||||
echo "警告:请使用管理员权限执行CMD。\r\n";
|
||||
return;
|
||||
end
|
||||
tkpath := rk.openKeyA("CLSID\\"+dllclsid+"\\"+subid);
|
||||
tkname := rk.openKeyA(comname+"\\CLSID");
|
||||
if 0=tkpath.SetValueStringA(nil,dllPath) then
|
||||
begin
|
||||
echo "步骤:注册执行程序成功。\r\n";
|
||||
end
|
||||
else
|
||||
begin
|
||||
echo "步骤:注册执行程序失败。\r\n";
|
||||
return ;
|
||||
end
|
||||
if 0= tkname.SetValueStringA(nil,dllclsid) then
|
||||
begin
|
||||
echo "步骤:写入clsid成功。\r\n";
|
||||
end else
|
||||
begin
|
||||
echo "警告:写入clsid失败。\r\n";
|
||||
return ;
|
||||
end
|
||||
install_success();
|
||||
end
|
||||
function get_classes_key();
|
||||
begin
|
||||
if install_for_all_users() then
|
||||
begin
|
||||
rk := new TRegKey(class(TRegKey).HKEY_LOCAL_MACHINE);
|
||||
end else
|
||||
begin
|
||||
rk := new TRegKey(class(TRegKey).HKEY_CURRENT_USER);
|
||||
end
|
||||
return rk.openKeyA("Software\\Classes");
|
||||
end
|
||||
function do_uninstall_sub();
|
||||
begin
|
||||
dllclsid := get_clsid();
|
||||
comname := get_com_name();
|
||||
rk := get_classes_key();
|
||||
if not ifobj(rk) then
|
||||
begin
|
||||
echo "警告:请使用管理员权限执行。\r\n";
|
||||
return;
|
||||
end
|
||||
else
|
||||
begin
|
||||
id := rk.openKeyA(comname+"\\CLSID").GetValueA();
|
||||
if not ifstring(id) then
|
||||
begin
|
||||
echo "警告:没有安装,不需要卸载!\r\n";
|
||||
return ;
|
||||
end
|
||||
if rk.DeleteTreeA(comname)=0 then
|
||||
begin
|
||||
echo "步骤:注册表删除com名成功!\r\n";
|
||||
|
||||
end else
|
||||
begin
|
||||
echo "警告:删除注册表com名失败!\r\n";
|
||||
return 0;
|
||||
end
|
||||
if rk.DeleteTreeA("CLSID\\"+dllclsid)=0 then
|
||||
begin
|
||||
echo "步骤:注册表删除clsid成功!\r\n";
|
||||
|
||||
end else
|
||||
begin
|
||||
echo "警告:删除注册clsid表失败!\r\n";
|
||||
return 0;
|
||||
end
|
||||
uninstall_success();
|
||||
return ;
|
||||
end
|
||||
end
|
||||
function run_com(); //运行
|
||||
begin
|
||||
if not fapp then
|
||||
begin
|
||||
fapp := initializeapplication();
|
||||
end
|
||||
WSAStartup(0,0);
|
||||
CoInitializeEx(0,COINIT_Param());
|
||||
RegisterFactory();
|
||||
fapp.run();
|
||||
UnregisterFactory();
|
||||
end
|
||||
function RegisterFactory(); //执行注册
|
||||
begin
|
||||
theFactory := new IClassFactory();
|
||||
theFactory.fcom_mgr := self(true);
|
||||
pUnkForFactory := theFactory._getptr_();
|
||||
v := 0;
|
||||
dwRegister := 0;
|
||||
CoRegisterClassObject(getguid()._getptr_,pUnkForFactory,4,1,v);
|
||||
dwRegister:= v;
|
||||
end
|
||||
procedure UnregisterFactory(); //执行退出
|
||||
begin
|
||||
if dwRegister<>0 then
|
||||
begin
|
||||
CoRevokeClassObject(dwRegister);
|
||||
end
|
||||
{if theFactory then
|
||||
begin
|
||||
theFactory.release();
|
||||
end }
|
||||
theFactory := nil;
|
||||
end
|
||||
function getguid();
|
||||
begin
|
||||
if not sguid then
|
||||
begin
|
||||
sguid := new tguid();
|
||||
sguid.readstr(get_clsid());
|
||||
end
|
||||
return sguid;
|
||||
end
|
||||
end
|
||||
implementation
|
||||
type tcom_const = class
|
||||
static const E_NOTIMPL=0x80004001L;
|
||||
static const E_NOINTERFACE=0x80004002L;
|
||||
static const E_INVALIDARG=0x80070057L;
|
||||
{
|
||||
static const VT_EMPTY = 0;
|
||||
static const VT_NULL = 1;
|
||||
static const VT_I2 = 2;
|
||||
static const VT_I4 = 3;
|
||||
static const VT_R4 = 4;
|
||||
static const VT_R8 = 5;
|
||||
static const VT_CY = 6;
|
||||
static const VT_DATE = 7;
|
||||
static const VT_BSTR = 8;
|
||||
static const VT_DISPATCH = 9;
|
||||
static const VT_ERROR = 10;
|
||||
static const VT_BOOL = 11;
|
||||
static const VT_VARIANT = 12;
|
||||
static const VT_UNKNOWN = 13;
|
||||
static const VT_DECIMAL = 14;
|
||||
static const VT_I1 = 16;
|
||||
static const VT_UI1 = 17;
|
||||
static const VT_UI2 = 18;
|
||||
static const VT_UI4 = 19;
|
||||
static const VT_I8 = 20;
|
||||
static const VT_UI8 = 21;
|
||||
static const VT_INT = 22;
|
||||
static const VT_UINT = 23;
|
||||
static const VT_VOID = 24;
|
||||
static const VT_HRESULT = 25;
|
||||
static const VT_PTR = 26;
|
||||
static const VT_SAFEARRAY = 27;
|
||||
static const VT_CARRAY = 28;
|
||||
static const VT_USERDEFINED = 29;
|
||||
static const VT_LPSTR = 30;
|
||||
static const VT_LPWSTR = 31;
|
||||
static const VT_RECORD = 36;
|
||||
static const VT_INT_PTR = 37;
|
||||
static const VT_UINT_PTR = 38;
|
||||
static const VT_FILETIME = 64;
|
||||
static const VT_BLOB = 65;
|
||||
static const VT_STREAM = 66;
|
||||
static const VT_STORAGE = 67;
|
||||
static const VT_STREAMED_OBJECT = 68;
|
||||
static const VT_STORED_OBJECT = 69;
|
||||
static const VT_BLOB_OBJECT = 70;
|
||||
static const VT_CF = 71;
|
||||
static const VT_CLSID = 72;
|
||||
static const VT_VERSIONED_STREAM = 73;
|
||||
static const VT_BSTR_BLOB = 0xfff;
|
||||
static const VT_VECTOR = 0x1000;
|
||||
static const VT_ARRAY = 0x2000;
|
||||
static const VT_BYREF = 0x4000;
|
||||
static const VT_RESERVED = 0x8000;
|
||||
static const VT_ILLEGAL = 0xffff;
|
||||
static const VT_ILLEGALMASKED = 0xfff;
|
||||
static const VT_TYPEMASK = 0xfff;
|
||||
}
|
||||
|
||||
end
|
||||
|
||||
type tguid=class(tslcstructureobj)
|
||||
uses cstructurelib;
|
||||
private
|
||||
class function getstruct()
|
||||
begin
|
||||
if not SSTRUCT then SSTRUCT := MemoryAlignmentCalculate(array(
|
||||
("data1","int",0xf59a8177),
|
||||
("data2","short",0x2a0),
|
||||
("data3","short",0x4019),
|
||||
("data4","byte[8]",array(0xa3, 0x93, 0xaf, 0x7, 0x9f, 0x9a, 0xb3, 0x62)),
|
||||
)
|
||||
);
|
||||
return SSTRUCT;
|
||||
end
|
||||
public
|
||||
function create(ptr)
|
||||
begin
|
||||
inherited create(getstruct(),ptr);
|
||||
end
|
||||
function readstr(s);
|
||||
begin
|
||||
r := __getid(s);
|
||||
_setvalue_("data1",r[0]);
|
||||
_setvalue_("data2",r[1]);
|
||||
_setvalue_("data3",r[2]);
|
||||
_setvalue_("data4",r[3:]);
|
||||
end
|
||||
function __getid(clsid);
|
||||
begin
|
||||
//clsid := getmycomregclsid(); //"{F59A8177-02A0-4019-A393-AF079F9AB361}";
|
||||
r := zeros(11);
|
||||
guidinfo := array(8,4,4,2,2,2,2,2,2,2,2);
|
||||
num := inttostr(0->9);
|
||||
sym := array("A","B","C","D","E","F");
|
||||
hs := array();
|
||||
for i,v in num do hs[v] := true;
|
||||
for i,v in sym do hs[v] := true;
|
||||
for i,v in lowercase(sym) do hs[v] := true;
|
||||
idx := 0;
|
||||
vvi := "";
|
||||
for i:= 1 to length(clsid) do
|
||||
begin
|
||||
vi := clsid[i];
|
||||
if length(vvi)=guidinfo[idx] then
|
||||
begin
|
||||
r[idx] := eval(&("0x"+vvi));
|
||||
idx++;
|
||||
vvi := "";
|
||||
end
|
||||
if not(hs[vi]) then continue;
|
||||
vvi+=vi;
|
||||
end
|
||||
return r;
|
||||
end
|
||||
function equ(riid);
|
||||
begin
|
||||
if ifarray(riid) then
|
||||
begin
|
||||
return _getdata_()=riid ;
|
||||
end
|
||||
if riid>0 then
|
||||
begin
|
||||
d := _getdata_();
|
||||
o := new tguid(riid);
|
||||
return d=o._getdata_();
|
||||
end
|
||||
return false;
|
||||
end
|
||||
end
|
||||
|
||||
type tagVARIANT =class(tslcstructureobj)
|
||||
uses cstructurelib;
|
||||
private
|
||||
class function getstruct()
|
||||
begin
|
||||
if not SSTRUCT then SSTRUCT := MemoryAlignmentCalculate(array(
|
||||
("vt","short",0),
|
||||
("wReserved1","short",0),
|
||||
("wReserved2","short",0),
|
||||
("wReserved3","short",0),
|
||||
("data","intptr",0),
|
||||
("data2","intptr",0)
|
||||
)
|
||||
);
|
||||
return SSTRUCT;
|
||||
end
|
||||
public
|
||||
function create(ptr)
|
||||
begin
|
||||
inherited create(getstruct(),ptr);
|
||||
end
|
||||
end
|
||||
type tagDISPPARAMS = class(tslcstructureobj)
|
||||
uses cstructurelib;
|
||||
private
|
||||
class function getstruct()
|
||||
begin
|
||||
if not SSTRUCT then SSTRUCT := MemoryAlignmentCalculate(array(
|
||||
("rgvarg","intptr",0),
|
||||
("rgdispidNamedArgs","intptr",0),
|
||||
("cArgs","int",0),
|
||||
("cNamedArgs","int",0)
|
||||
)
|
||||
);
|
||||
return SSTRUCT;
|
||||
end
|
||||
public
|
||||
function create(ptr)
|
||||
begin
|
||||
inherited create(getstruct(),ptr);
|
||||
end
|
||||
function getarg(idx);
|
||||
begin
|
||||
if (idx >=0) and (idx<_getvalue_("cArgs")) then
|
||||
begin
|
||||
addri := _getvalue_("rgvarg");
|
||||
obj := new tagVARIANT(addri);
|
||||
if idx>0 then
|
||||
begin
|
||||
addri := int64(addri+idx*obj._size_()); //_tool.readptr(addri+idx*8);
|
||||
obj._setcptr_(addri);
|
||||
end
|
||||
return obj;
|
||||
end
|
||||
end
|
||||
function getArgs(od);
|
||||
begin
|
||||
r := array();
|
||||
ct := _getvalue_("cArgs");
|
||||
if ct<1 then return r;
|
||||
addri := _getvalue_("rgvarg");
|
||||
obj := new tagVARIANT(addri);
|
||||
r[0] := obj;
|
||||
sz := obj._size_();
|
||||
for i:= 1 to ct-1 do
|
||||
begin
|
||||
addri+=sz;
|
||||
r[i] := new tagVARIANT(addri);
|
||||
end
|
||||
if not od then
|
||||
begin
|
||||
rt := array();
|
||||
idx := 0;
|
||||
for i:= ct-1 downto 0 do
|
||||
begin
|
||||
rt[idx++] := r[i];
|
||||
end
|
||||
return rt;
|
||||
end
|
||||
return r;
|
||||
end
|
||||
property cArgs index "cArgs" read _getvalue_;
|
||||
end
|
||||
type tptrarray =class(tslcstructureobj)
|
||||
uses cstructurelib;
|
||||
private
|
||||
class function getstruct()
|
||||
begin
|
||||
if not SSTRUCT then SSTRUCT := MemoryAlignmentCalculate(array(
|
||||
("ptr","intptr",0)
|
||||
)
|
||||
);
|
||||
return SSTRUCT;
|
||||
end
|
||||
public
|
||||
function create(ptr)
|
||||
begin
|
||||
inherited create(getstruct(),ptr);
|
||||
end
|
||||
function ansistr();
|
||||
begin
|
||||
p := _getvalue_("ptr");
|
||||
wlen := uaw_wcslen(p);
|
||||
sansi := "";
|
||||
setlength(sansi,wlen*2+1);
|
||||
WideCharToMultiByte(0,0,p,wlen,sansi,length(sansi),0,0);
|
||||
return sansi;
|
||||
end
|
||||
end
|
||||
|
||||
type iunkown =class(tslcstructureobj,tcom_const)
|
||||
uses cstructurelib;
|
||||
private
|
||||
static SSTRUCT;
|
||||
protected
|
||||
static IID_IUnknown ;//:= new tguid();
|
||||
static IID_IClassFactory;// := new tguid();
|
||||
static IID_IDispatch;// := new tguid();
|
||||
m_dwRef;
|
||||
fvtable;
|
||||
class function getstruct()
|
||||
begin
|
||||
if not SSTRUCT then
|
||||
begin
|
||||
IID_IUnknown := new tguid();
|
||||
IID_IClassFactory := new tguid();
|
||||
IID_IDispatch := new tguid();
|
||||
IID_IUnknown.readstr("{00000000-0000-0000-C000-000000000046}");
|
||||
IID_IClassFactory.readstr("{00000001-0000-0000-C000-000000000046}");
|
||||
IID_IDispatch.readstr("{00020400-0000-0000-C000-000000000046}");
|
||||
|
||||
SSTRUCT := MemoryAlignmentCalculate(array(
|
||||
("vtable","intptr",0)
|
||||
)
|
||||
);
|
||||
end
|
||||
return SSTRUCT;
|
||||
end
|
||||
public
|
||||
function create(ptr)
|
||||
begin
|
||||
inherited create(getstruct(),ptr);
|
||||
end
|
||||
function addref(s:pointer):integer;stdcall;
|
||||
begin
|
||||
m_dwRef++;
|
||||
//echo "\r\nidispath addref:",s,"====",m_dwRef;
|
||||
return m_dwRef;
|
||||
end
|
||||
function release(s:pointer):integer;stdcall;virtual;
|
||||
begin
|
||||
if m_dwRef>0 then m_dwRef--;
|
||||
return m_dwRef;
|
||||
end
|
||||
end
|
||||
type dispatchvtable =class(tslcstructureobj)
|
||||
uses cstructurelib;
|
||||
private
|
||||
class function getstruct()
|
||||
begin
|
||||
if not SSTRUCT then SSTRUCT := MemoryAlignmentCalculate(array(
|
||||
("QueryInterface","intptr",0),
|
||||
("AddRef","intptr",0),
|
||||
("Release","intptr",0),
|
||||
("GetTypeInfoCount","intptr",0),
|
||||
("GetTypeInfo","intptr",0),
|
||||
("GetIDsOfNames","intptr",0),
|
||||
("Invoke","intptr",0)
|
||||
)
|
||||
);
|
||||
return SSTRUCT;
|
||||
end
|
||||
public
|
||||
function create(ptr)
|
||||
begin
|
||||
inherited create(getstruct(),ptr);
|
||||
end
|
||||
end
|
||||
type idispatch=class(iunkown)
|
||||
private
|
||||
frgDispIds;
|
||||
frgDispIds2;
|
||||
function getdispid(s);
|
||||
begin
|
||||
id := frgDispIds[s];
|
||||
if id>0 then
|
||||
begin
|
||||
return id;
|
||||
end
|
||||
id := length(frgDispIds);
|
||||
frgDispIds2[id] := s;
|
||||
frgDispIds[s] := id;
|
||||
end
|
||||
function getdispidstr(id);
|
||||
begin
|
||||
return frgDispIds2[id];
|
||||
end
|
||||
public
|
||||
[weakref] fcom_mgr;
|
||||
function create(ptr)
|
||||
begin
|
||||
inherited ;//create(getstruct(),ptr);
|
||||
if not ptr then
|
||||
begin
|
||||
fvtable := new dispatchvtable();
|
||||
_setvalue_("vtable",fvtable._getptr_());
|
||||
fvtable._setvalue_("QueryInterface",makeinstance(thisfunction(QueryInterface)));
|
||||
fvtable._setvalue_("Release",makeinstance(thisfunction(Release)));
|
||||
fvtable._setvalue_("AddRef",makeinstance(thisfunction(addref)));
|
||||
fvtable._setvalue_("GetTypeInfoCount",makeinstance(thisfunction(GetTypeInfoCount)));
|
||||
fvtable._setvalue_("GetTypeInfo",makeinstance(thisfunction(GetTypeInfo)));
|
||||
fvtable._setvalue_("GetIDsOfNames",makeinstance(thisfunction(GetIDsOfNames)));
|
||||
fvtable._setvalue_("Invoke",makeinstance(thisfunction(Invoke_)));
|
||||
end else
|
||||
begin
|
||||
fvtable := new fvtable(_getvalue_("vtable"));
|
||||
m_dwRef := 0;
|
||||
end
|
||||
frgDispIds := array();
|
||||
frgDispIds2 := array();
|
||||
end
|
||||
function GetTypeInfoCount(s:pointer;var pctinfo:integer):integer;stdcall;
|
||||
begin
|
||||
pctinfo := 0;
|
||||
return 0;
|
||||
end
|
||||
function GetTypeInfo(s:pointer;iTInfo:integer;lcid:integer;var ppTInfo:pointer):integer;stdcall;
|
||||
begin
|
||||
if ppTInfo then ppTInfo := 0;
|
||||
return E_NOTIMPL;
|
||||
end
|
||||
function GetIDsOfNames(s:pointer;riid:pointer;rgszNames:pointer;cNames:integer;lcid:integer;var rgDispId:integer):integer;stdcall;
|
||||
begin
|
||||
if cnames>1 then return E_INVALIDARG;
|
||||
ostr := new tptrarray(rgszNames);
|
||||
rgDispId := getdispid(ostr.ansistr);
|
||||
return 0;
|
||||
end
|
||||
function Invoke_(s:pointer;dispIdMember:integer;riid:pointer;lcid:integer;wFlags:short;pDispParams:pointer; pVarResult:pointer;pExcepInfo:pointer;var puArgErr:integer):integer;stdcall;
|
||||
begin
|
||||
o := new tagDISPPARAMS(pDispParams);
|
||||
pp := o.getArgs();
|
||||
pms := array();
|
||||
fname := getdispidstr(dispIdMember);
|
||||
for idx,p1 in pp do
|
||||
begin
|
||||
VariantToObj2(TS_GetGlobalL(),p1._getptr_,r,fcom_mgr.invoke_param_is_excel(fname));
|
||||
pms[idx] := r;
|
||||
end
|
||||
x := fcom_mgr.invoke_call(fname,pms);
|
||||
ObjToVariantRef(TS_GetGlobalL(),x,pVarResult,fcom_mgr.execute_retun_is_excel(fname));
|
||||
return 0;
|
||||
end
|
||||
function QueryInterface(s:pointer;riid:pointer;var ppv:pointer):integer;stdcall;
|
||||
begin
|
||||
if IID_IUnknown.equ(riid) or IID_IDispatch.equ(riid) then
|
||||
begin
|
||||
ppv := _getptr_();
|
||||
addref(ppv);
|
||||
return 0;
|
||||
end
|
||||
return E_NOINTERFACE;
|
||||
end
|
||||
|
||||
function release(s:pointer):integer;stdcall;override;
|
||||
begin
|
||||
r := inherited;
|
||||
//echo "\r\nidispath release:",s,"====",r;
|
||||
if r=0 and fcom_mgr then fcom_mgr.stop_run();
|
||||
return r;
|
||||
end
|
||||
end
|
||||
type ClassFactoryvtable = class(tslcstructureobj)
|
||||
uses cstructurelib;
|
||||
private
|
||||
class function getstruct()
|
||||
begin
|
||||
if not SSTRUCT then SSTRUCT := MemoryAlignmentCalculate(array(
|
||||
("QueryInterface","intptr",0),
|
||||
("AddRef","intptr",0),
|
||||
("Release","intptr",0),
|
||||
("CreateInstance","intptr",0),
|
||||
("LockServer","intptr",0)
|
||||
)
|
||||
);
|
||||
return SSTRUCT;
|
||||
end
|
||||
public
|
||||
function create(ptr)
|
||||
begin
|
||||
inherited create(getstruct(),ptr);
|
||||
end
|
||||
end
|
||||
type IClassFactory=class(iunkown)
|
||||
static sguid;
|
||||
private
|
||||
static dwRegister;
|
||||
static theFactory;
|
||||
fdispatchs;
|
||||
public
|
||||
[weakref] fcom_mgr;
|
||||
function create(ptr);override;
|
||||
begin
|
||||
inherited ;
|
||||
fdispatchs := array();
|
||||
if not ptr then
|
||||
begin
|
||||
fvtable := new ClassFactoryvtable();
|
||||
_setvalue_("vtable",fvtable._getptr_());
|
||||
fvtable._setvalue_("QueryInterface",makeinstance(thisfunction(QueryInterface)));
|
||||
fvtable._setvalue_("Release",makeinstance(thisfunction(Release)));
|
||||
fvtable._setvalue_("AddRef",makeinstance(thisfunction(addref)));
|
||||
fvtable._setvalue_("CreateInstance",makeinstance(thisfunction(CreateInstance)));
|
||||
fvtable._setvalue_("LockServer",makeinstance(thisfunction(LockServer)));
|
||||
|
||||
end else
|
||||
begin
|
||||
fvtable := new fvtable(_getvalue_("vtable"));
|
||||
m_dwRef := 0;
|
||||
end
|
||||
end
|
||||
function QueryInterface(s:pointer;riid:pointer;var ppv:pointer):integer;stdcall;
|
||||
begin
|
||||
if IID_IUnknown.equ(riid) or IID_IClassFactory.equ(riid) then
|
||||
begin
|
||||
ppv := _getptr_();
|
||||
addref(ppv);
|
||||
return 0;
|
||||
end
|
||||
return E_NOINTERFACE;
|
||||
end
|
||||
function release(s:pointer):integer;stdcall;override;
|
||||
begin
|
||||
r := inherited;
|
||||
//echo "\r\nIClassFactory release:",s,"====",r;
|
||||
return r;
|
||||
end
|
||||
function CreateInstance(s:pointer;known:pointer;riid:pointer;var ppvObject:pointer):integer;stdcall;//
|
||||
begin
|
||||
if not fdispatchs then
|
||||
begin
|
||||
fdispatchs := new idispatch();
|
||||
fdispatchs.fcom_mgr := fcom_mgr;
|
||||
end
|
||||
hr := fdispatchs.QueryInterface(fdispatchs._getptr_(),riid,ppvObject);
|
||||
return hr;
|
||||
end
|
||||
function LockServer(lk:integer):integer;stdcall;
|
||||
begin
|
||||
return 1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function CoRegisterClassObject(rclsid:pointer;pUnk:pointer;dwClsContext:integer;flags:integer;var lpdwRegister:integer):integer; stdcall; external "ole32.dll" name "CoRegisterClassObject";
|
||||
function CoRevokeClassObject(var lpdwRegister:integer):integer; stdcall; external "ole32.dll" name "CoRevokeClassObject";
|
||||
function WSAStartup(q:short;d:pointer):integer; stdcall; external "Ws2_32.dll" name "WSAStartup";
|
||||
function CoInitializeEx(q:pointer;d:integer):integer; stdcall; external "ole32.dll" name "CoInitializeEx";
|
||||
procedure VariantToObj2(L:pointer; V:pointer; var o:TObject;isIndex:integer);cdecl;external "tslkrnl.dll" name "VariantToObj2";
|
||||
procedure ObjToVariantRef(L:pointer;o:TObject; v:pointer; IsExcel:integer);cdecl;external "tslkrnl.dll" name "ObjToVariantRef";
|
||||
function TS_GetGlobalL():pointer;cdecl;external "TSSVRAPI.dll" name "TS_GetGlobalL";
|
||||
function uaw_wcslen(s:pointer):integer;stdcall;external "Kernel32.dll" name "uaw_wcslen";
|
||||
function WideCharToMultiByte(CodePage:integer;dwFlags:integer;lpWideCharStr:pointer;
|
||||
cchWideChar:integer;var lpMultiByteStr:string;cbMultiByte:integer;
|
||||
lpDefaultChar:pointer;var lpUsedDefaultChar:integer):integer;stdcall;external "Kernel32.dll" name "WideCharToMultiByte";
|
||||
|
||||
|
||||
|
||||
|
||||
initialization
|
||||
end.
|
||||
Loading…
Reference in New Issue