Форум: "KOL";
Текущий архив: 2003.07.24;
Скачать: [xml.tar.bz2];
ВнизМожно ли перевести на KOL проект ActiveX библиотеки Найти похожие ветки
← →
Green_mkp (2002-08-31 11:26) [0]Я пока так и не нашел где в КОЛ переписаны модули для COM
← →
exchoper (2002-11-01 17:32) [1]Присоединяюсь к вопросу, очень надо написать мальнький ActiveX
← →
Boguslaw (2002-11-04 17:26) [2]Difficult but not impossible.... ;-)
← →
exchoper (2002-11-04 18:12) [3]А можно пример, очень актуально!!!
Заранее спасибо!
← →
Boguslaw (2002-11-05 21:07) [4]Some time ago I found article discussing problem how to write COM-server object in pure assembler.Well, I must say I was impressed! Unfortunately I"m not an assembler guru, and writing active-x seems to be much more complex than COM-server.
Anyway COM-server in KOL would be the first disscussed issue, I think.
Boguslaw
← →
Fantasist (2002-11-12 00:49) [5]А что конкретно надо? Если нужно написать не визуальный ActiveX то это сделать достадочно не сложно - могу привести пример, а ежели визуальный... То тут надо хорошенько почитать документацию по OLE. Или ждать пока кто-нибудь инкапсулирует все это дело.
← →
exchoper (2002-11-12 12:13) [6]Приведи пример невизуального или вышли, а то уменьшить размер помогла только кастрация модуля AXCtrls, но по-моему я что-то не так сделал :)
странно что никто не занимался уменьшением размера визуального, ведь это по-моему основной тупик Delphi где размер имеет значение, ну что за дела, если пустой AX занимает 400 кил, кому он такой нужен!?
← →
Fantasist (2002-11-16 09:07) [7]Прошу прощение за задержку - дела кой-какие.
Значит так. Вариант первый. Сразу скажу, что на самом деле этот вариант нужно переделать на более удачный. Что надо переделать первым делом скажу ниже.
library CalcDll;
uses
Windows,
SysUtils,
Classes, ActiveX;
const
IUnknown_IID:TGUID="{00000000-0000-0000-C000-000000000046}";
IClassFactory_IID:TGUID="{00000001-0000-0000-C000-000000000046}";
ICalc_IID:TGUID="{149D0FC0-43FE-11D6-A1F0-444553540000}";
ICalc2_IID:TGUID="{D79C6DC0-44B9-11D6-A1F0-444553540000}";
MyCalc_CLSID:TGUID="{2563AE40-AC27-11D6-A5C2-444553540000}";
type
HResult=Longint;
//Interfaces
IUnknown = object
private
this:pointer;
public
function QueryInterface(const IID: TGUID; out Obj): HResult; virtual; stdcall;
function AddRef: HResult; virtual; stdcall;
function Release: HResult; virtual; stdcall;
constructor Create;
end;
IClassFactory = object(IUnknown)
function CreateInstance(const unkOuter: pointer; const iid: TIID; out obj): HResult; virtual; stdcall;
function LockServer(fLock: BOOL): HResult; virtual; stdcall;
constructor Create;
end;
ICalcBase=object(IUnknown)
public
function SetOperands(x,y:integer):HResult; virtual; stdcall;
constructor Create;
end;
ICalc=object(ICalcBase)
function Sum(out Res):HResult; virtual; stdcall;
function Diff(out Res):HResult; virtual; stdcall;
constructor Create;
end;
ICalc2=object(ICalcBase)
function Mult(out Res):HResult; virtual; stdcall;
function Divide(out Res):HResult; virtual; stdcall;
constructor Create;
end;
//CoClass MyCalc
MyCalc=object
IUnknownVtlb:^IUnknown;
IClassFactoryVtlb:^IClassFactory;
ICalcVtlb:^ICalc;
ICalc2Vtlb:^ICalc2;
fx,fy:integer;
FRefCount:integer;
public
constructor Create;
destructor Destroy; virtual;
//ICalcBase
procedure SetOperands(x,y:integer); stdcall;
//ICalc
function Sum:integer; stdcall;
function Diff:integer; stdcall;
//ICalc2
function Mult:integer; stdcall;
function Divide:integer; stdcall;
//IUnknown
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
function AddRef:Longint; stdcall;
function Release:Longint; stdcall;
//IClassFactory
function CreateInstance(const unkOuter: pointer; const iid: TIID;out obj): HResult; stdcall;
function LockServer(fLock: BOOL): HResult; stdcall;
end;
const
S_OK = 0;
E_NOINTERFACE = HRESULT($80004002);
procedure MyCalc.SetOperands(x,y:integer);
begin
fx:=x; fy:=y;
end;
function MyCalc.Sum:integer;
begin
result:=fx+fy;
end;
function MyCalc.Diff:integer;
begin
result:=fx-fy;
end;
function MyCalc.Divide:integer;
begin
result:=fx div fy;
end;
function MyCalc.Mult:integer;
begin
result:=fx*fy;
end;
function GUIDComp(GUID1,GUID2:TGUID):boolean;
var
i:integer;
begin
// actually, we can use int64 for comparison
for i:=0 to 7 do
if GUID1.D4[i]<>GUID2.D4[i] then
begin
Result:=false;
exit;
end;
Result:=True and (GUID1.D1=GUID2.D1) and (GUID1.D2=GUID2.D2) and (GUID1.D3=GUID2.D3);
end;
← →
Fantasist (2002-11-16 09:08) [8]
function MyCalc.QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
begin
Result := S_OK;
if GUIDComp(IID,IUnknown_IID) then Pointer(Obj):=Pointer(Integer(IUnknownVtlb)+4) else
if GUIDComp(IID,IClassFactory_IID) then Pointer(Obj):=Pointer(Integer(IClassFactoryVtlb)+4) else
if GUIDComp(IID,ICalc_IID) then Pointer(Obj):=Pointer(Integer(ICalcVtlb)+4) else
if GUIDComp(IID,ICalc2_IID) then Pointer(Obj):=Pointer(Integer(ICalc2Vtlb)+4)
else
Result := E_NOINTERFACE;
end;
function MyCalc.AddRef:Longint;
begin
Result := InterlockedIncrement(FRefCount);
end;
function MyCalc.Release:Longint;
begin
Result := InterlockedDecrement(FRefCount);
if Result = 0 then
Dispose(@self);
end;
constructor MyCalc.Create;
begin
fx:=0;
fy:=0;
New(IUnknownVtlb,Create);
New(IClassFactoryVtlb,Create);
New(ICalcVtlb,Create);
New(ICalc2Vtlb,Create);
IUnknownVtlb^.this:=@self;
IClassFactoryVtlb^.this:=@self;
ICalcVtlb^.this:=@self;
ICalc2Vtlb^.this:=@self;
end;
destructor MyCalc.Destroy;
begin
Dispose(IUnknownVtlb);
Dispose(IClassFactoryVtlb);
Dispose(ICalcVtlb);
Dispose(ICalc2Vtlb);
end;
function MyCalc.CreateInstance(const unkOuter: pointer; const iid: TIID;out obj): HResult; stdcall;
var
Calc:^MyCalc;
begin
New(Calc,Create);
Result:=Calc^.QueryInterface(iid,obj);
if Result<>S_OK then
Dispose(Calc);
end;
function MyCalc.LockServer(fLock: BOOL): HResult; stdcall;
begin
if fLock then
AddRef
else
Release;
end;
{ IUnknown }
function IUnknown.AddRef: HResult;
begin
Result:=MyCalc(Pointer(Integer(@self)-4)^).AddRef;
end;
constructor IUnknown.Create;
begin
end;
function IUnknown.QueryInterface(const IID: TGUID; out Obj): HResult;
begin
Result:=MyCalc(Pointer(Integer(@self)-4)^).QueryInterface(IID,Obj);
end;
function IUnknown.Release: HResult;
begin
Result:=MyCalc(Pointer(Integer(@self)-4)^).Release;
end;
{ IClassFactory }
constructor IClassFactory.Create;
begin
end;
function IClassFactory.CreateInstance(const unkOuter: pointer; const iid: TIID; out obj): HResult;
begin
Result:=MyCalc(Pointer(Integer(@self)-4)^).CreateInstance(unkOuter,iid,obj);
end;
function IClassFactory.LockServer(fLock: BOOL): HResult;
begin
Result:=MyCalc(Pointer(Integer(@self)-4)^).lockServer(fLock);
end;
{ ICalcBase }
constructor ICalcBase.Create;
begin
end;
function ICalcBase.SetOperands(x, y: integer):HResult;
begin
Result:=S_OK;
try
MyCalc(Pointer(Integer(@self)-4)^).SetOperands(x,y);
except
Result:=E_UNEXPECTED;
end;
end;
{ ICalc }
constructor ICalc.Create;
begin
end;
function ICalc.Diff(out Res): HResult;
begin
Result:=S_OK;
try
Integer(Res):=MyCalc(Pointer(Integer(@self)-4)^).Diff;
except
Result:=E_UNEXPECTED;
end;
end;
function ICalc.Sum(out Res): HResult;
begin
Result:=S_OK;
try
Integer(Res):=MyCalc(Pointer(Integer(@self)-4)^).Sum;
except
Result:=E_UNEXPECTED;
end;
end;
{ ICalc2 }
constructor ICalc2.Create;
begin
end;
function ICalc2.Divide(out Res): HResult;
begin
Result:=S_OK;
try
Integer(Res):=MyCalc(Pointer(Integer(@self)-4)^).Divide;
except
Result:=E_UNEXPECTED;
end;
end;
function ICalc2.Mult(out Res): HResult;
begin
Result:=S_OK;
try
Integer(Res):=MyCalc(Pointer(Integer(@self)-4)^).Mult;
except
Result:=E_UNEXPECTED;
end;
end;
function DllGetClassObject(const CLSID, IID: TGUID; var Obj): HResult; stdcall;
var
Calc:^MyCalc;
pCalc:^Icalc;
begin
if not GUIDComp(MyCalc_CLSID,CLSID) then
begin
Result:=CLASS_E_CLASSNOTAVAILABLE;
exit;
end;
New(Calc,Create);
Result:=Calc^.QueryInterface(iid,obj);
if Result<>S_OK then
Dispose(Calc);
end;
exports
DllGetClassObject;
← →
Fantasist (2002-11-16 09:22) [9]Ну вот. Простой СоСlass с двумя стандартными интерфейсами IUnknown и IClassFactory, и тремя своими. Все служат просто для вычисления. SetOperands - установить операнды, Mult,Divide,Diff,Sum - получить соответсвующий результат. Пользователю предлагается использовать два(или один из двух) интерфейсов: ICalc - сложение/вычитание ICalc2 - умножение/деление.
Подход очень простой - формирование виртуальных таблиц и передача их пользователю как интерфейс. Методы в этих виртуальных таблицах перенаправляют вызов функции уже конктретно объекту.
Вот тут-то я и ошибся в подходе, уж очень долго не использовал Raw Object Pascal. На самом деле, в вышеприведенных объектах-интерфейсах нужно все виртуальные методы поменять на указатели, а в эти указатели уже записывать адреса методов того объекта, что нам нужен. А правильный self можно получать точно таким же способом, как я делаю это сейчас. Объем кода сократиться раза в три и небудет никаких редиректов.
← →
Karson (2002-11-17 03:39) [10]Fantasist, а не моглы бы вы сами исправить эту ошибку?
Просто не для всех это так просто, как может показаться.
← →
Fantasist (2002-11-17 07:58) [11]А ошибки на самом деле нет - все работает. Можете зарегестрировать этот компонент, и он будет работать. Но просто сам объем кода и способ разработки ужасающи (поэтому и выглядит непонятно). Но я над этим поработал. Открою только новую ветку.
← →
Camilla (2002-11-22 14:02) [12]Hi , Fantasist, do you speak English?
I"m Italian and know Russian a little, but not enough to understand all you write...
Do you have a working example of an activeX using KOl, maybe with associated HTML calling page?
SPASIBO BOLSHOE!!!!
Camilla
← →
Fantasist (2002-11-22 20:19) [13]Hi, Cammila. Yes, I do speak English. And I don"t know Italian at all, so you"re in better position.
Example posted above is working, but it does not help you much. To create your own ActiveX, you have to add and implement your own interfaces. And there is a trik. But I designed better way to implemenet COM interfaces with pure Object Pascal, and if you wait for couple days, I"ll present an example of it with explanations. But again I should warn - it will not be a complete OLE library but just a way to implement COM interfaces. I have an idea to write a special program, which will transform Delphi source code with Delphi interface implementation into pure Object Pascal code interface implementation. With that program it"ll be easy to translate VCL COM/OLE libraries to KOL library, but it"ll take a time to create such program.
Страницы: 1 вся ветка
Форум: "KOL";
Текущий архив: 2003.07.24;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.008 c