VB编写的DLL,对应的使用Delphi如何编写?(用于AutoCAD开发) ( 积分: 100 )

  • 主题发起人 主题发起人 inessence
  • 开始时间 开始时间
I

inessence

Unregistered / Unconfirmed
GUEST, unregistred user!
打算在AutoCAD中使用VBA中调用Delphi编写的DLL,只找到一个调用VB编写的DLL的例子,叫什么ActiveX DLL(不知道概念对不对),调用格式涉及到类模块,高手给看一下,这样的DLL在Delphi中如何编写?

以下是转载的有关使用VB建立DLL的过程:
在VB中先新建工程,选择active dll,这样生成一个名为工程1含class1类模块的DLL工程,在工程属性里修改工程名为dllcad(最好改为英文的,不然在引用时就是一个乱码),修改类名为classcad,再添加窗体formha(我的工程中只有一个窗体formha),把窗体中的代码END改为UNLOAD ME,在类模块中加入如下代码:
public sub GOGO()
formha.show
end sub

在AutoCAD VBA中用以下的代码就可以调用DLL了:
Set a=AutoCAD.GetInterfaceObject("dllcad.classcad")
a.GOGO
注:VBA调用DLL原文为LISP代码,我转换了一下,除了不能肯定"dllcad.classcad"是否有引号,格式应当没有错误。

附VBA帮助中关于GetInterfaceObject说明
Accepts a program ID and attempts to load it into AutoCAD as an in-process server.

RetVal = object.GetInterfaceObject(ProgID)

Object
Application
The object or objects this method applies to.

ProgID
String; input-only
The program ID of the interface object to return.

RetVal
Object
The interface object matching the program ID.

帮助的Example中ProgID给了个令人摸不着头脑的例子,令我更不敢肯定调用参数的格式了
Dim poly As Object
Set poly = ThisDrawing.Application.GetInterfaceObject("Polycad.Application")
还有,调用DLL中的例程,不用明确指定DLL的文件名吗?
 
打算在AutoCAD中使用VBA中调用Delphi编写的DLL,只找到一个调用VB编写的DLL的例子,叫什么ActiveX DLL(不知道概念对不对),调用格式涉及到类模块,高手给看一下,这样的DLL在Delphi中如何编写?

以下是转载的有关使用VB建立DLL的过程:
在VB中先新建工程,选择active dll,这样生成一个名为工程1含class1类模块的DLL工程,在工程属性里修改工程名为dllcad(最好改为英文的,不然在引用时就是一个乱码),修改类名为classcad,再添加窗体formha(我的工程中只有一个窗体formha),把窗体中的代码END改为UNLOAD ME,在类模块中加入如下代码:
public sub GOGO()
formha.show
end sub

在AutoCAD VBA中用以下的代码就可以调用DLL了:
Set a=AutoCAD.GetInterfaceObject("dllcad.classcad")
a.GOGO
注:VBA调用DLL原文为LISP代码,我转换了一下,除了不能肯定"dllcad.classcad"是否有引号,格式应当没有错误。

附VBA帮助中关于GetInterfaceObject说明
Accepts a program ID and attempts to load it into AutoCAD as an in-process server.

RetVal = object.GetInterfaceObject(ProgID)

Object
Application
The object or objects this method applies to.

ProgID
String; input-only
The program ID of the interface object to return.

RetVal
Object
The interface object matching the program ID.

帮助的Example中ProgID给了个令人摸不着头脑的例子,令我更不敢肯定调用参数的格式了
Dim poly As Object
Set poly = ThisDrawing.Application.GetInterfaceObject("Polycad.Application")
还有,调用DLL中的例程,不用明确指定DLL的文件名吗?
 
Delphi 里 new activex library
然后 new Automation Object
ProgID 是 Project name.CoClass name
 
我正在看COM部分,很辛苦,看来你很精通此道,多指点
正在研究有窗体界面的自动化服务器,能不能给一个简单的例子的代码。
功能:控制器传一个integer给服务器,这个integer在服务器窗体的编辑框显示出来,用户可以更改,按确定按钮后,将更改后结果返回控制器。
拜托,一定把新建的步骤讲一下,如哪一步用new->ActiveX的哪一个向导
 
▲包含窗体的进程内自动化服务器 (in-process Automation server,DLL)
by lazybones
第一步,建立ActiveX Library
File->New->Other->ActiveX Library,存盘取名inprocess
第二步,添加Automation Object
File->New->Other->Automation Object,CoClass Name取名getstring,选择Igetstring,单击New Property按钮旁边的下拉箭头,增加一个Read Only的属性thestring,Type为 BSTR,单击New Method,增加一个freeform方法,再单击New Method,增加一个showmodelform方法,单击Parameters标签,Name为str,Type为BSTR,刷新
第三步,添加窗体
File->New->Form,添加一个编辑框。全部保存
第四部,完善代码
首先需要在unit1中uses unit2,再完成代码,编译、注册

//ActiveX Library

library inprocess;

uses
ComServ,
inprocess_TLB in 'inprocess_TLB.pas',
Unit1 in 'Unit1.pas',
Unit2 in 'Unit2.pas' {Form2};

exports
DllGetClassObject,
DllCanUnloadNow,
DllRegisterServer,
DllUnregisterServer;

{$R *.TLB}

{$R *.RES}

begin
end.



//Automation Object

unit Unit1;

{$WARN SYMBOL_PLATFORM OFF}

interface

uses
ComObj, ActiveX, inprocess_TLB, StdVcl,unit2;

type
Tgetstring = class(TAutoObject, Igetstring)
protected
function Get_thestring: WideString; safecall;
procedure freeform; safecall;
procedure showmodelform(const str: WideString); safecall;

end;

implementation

uses ComServ;

function Tgetstring.Get_thestring: WideString;
begin
result:=form2.Edit1.Text;
end;

procedure Tgetstring.freeform;
begin
form2.Free;
end;

procedure Tgetstring.showmodelform(const str: WideString);
begin
form2:=TForm2.Create(nil);
form2.Edit1.Text:=str;
form2.ShowModal;//注意,和上一句顺序不能颠倒
end;

initialization
TAutoObjectFactory.Create(ComServer, Tgetstring, Class_getstring,
ciMultiInstance, tmApartment);
end.



//Automation Object(TLB)

unit inprocess_TLB;

// ************************************************************************ //
// WARNING
// -------
// The types declared in this file were generated from data read from a
// Type Library. If this type library is explicitly or indirectly (via
// another type library referring to this type library) re-imported, or the
// 'Refresh' command of the Type Library Editor activated while editing the
// Type Library, the contents of this file will be regenerated and all
// manual modifications will be lost.
// ************************************************************************ //

// PASTLWTR : 1.2
// File generated on 2005-7-23 23:17:31 from Type Library described below.

// ************************************************************************ //
// Type Lib: C:/Documents and Settings/Administrator/My Documents/Borland Studio Projects/ooo/inprocess.tlb (1)
// LIBID: {5B026064-6CED-4AEB-9AF4-7B246AF2518B}
// LCID: 0
// Helpfile:
// HelpString: inprocess Library
// DepndLst:
// (1) v2.0 stdole, (C:/WINDOWS/system32/stdole2.tlb)
// ************************************************************************ //
{$TYPEDADDRESS OFF} // Unit must be compiled without type-checked pointers.
{$WARN SYMBOL_PLATFORM OFF}
{$WRITEABLECONST ON}
{$VARPROPSETTER ON}
interface

uses Windows, ActiveX, Classes, Graphics, StdVCL, Variants;


// *********************************************************************//
// GUIDS declared in the TypeLibrary. Following prefixes are used:
// Type Libraries : LIBID_xxxx
// CoClasses : CLASS_xxxx
// DISPInterfaces : DIID_xxxx
// Non-DISP interfaces: IID_xxxx
// *********************************************************************//
const
// TypeLibrary Major and minor versions
inprocessMajorVersion = 1;
inprocessMinorVersion = 0;

LIBID_inprocess: TGUID = '{5B026064-6CED-4AEB-9AF4-7B246AF2518B}';

IID_Igetstring: TGUID = '{D2D01F47-D4EB-4D87-91F5-AF6600E8DFAF}';
CLASS_getstring: TGUID = '{A2E7576F-16DC-404C-8145-9F0F0BE50868}';
type

// *********************************************************************//
// Forward declaration of types defined in TypeLibrary
// *********************************************************************//
Igetstring = interface;
IgetstringDisp = dispinterface;

// *********************************************************************//
// Declaration of CoClasses defined in Type Library
// (NOTE: Here we map each CoClass to its Default Interface)
// *********************************************************************//
getstring = Igetstring;


// *********************************************************************//
// Interface: Igetstring
// Flags: (4416) Dual OleAutomation Dispatchable
// GUID: {D2D01F47-D4EB-4D87-91F5-AF6600E8DFAF}
// *********************************************************************//
Igetstring = interface(IDispatch)
['{D2D01F47-D4EB-4D87-91F5-AF6600E8DFAF}']
function Get_thestring: WideString; safecall;
procedure freeform; safecall;
procedure showmodelform(const str: WideString); safecall;
property thestring: WideString read Get_thestring;
end;

// *********************************************************************//
// DispIntf: IgetstringDisp
// Flags: (4416) Dual OleAutomation Dispatchable
// GUID: {D2D01F47-D4EB-4D87-91F5-AF6600E8DFAF}
// *********************************************************************//
IgetstringDisp = dispinterface
['{D2D01F47-D4EB-4D87-91F5-AF6600E8DFAF}']
property thestring: WideString readonly dispid 201;
procedure freeform; dispid 202;
procedure showmodelform(const str: WideString); dispid 203;
end;

// *********************************************************************//
// The Class Cogetstring provides a Create and CreateRemote method to
// create instances of the default interface Igetstring exposed by
// the CoClass getstring. The functions are intended to be used by
// clients wishing to automate the CoClass objects exposed by the
// server of this typelibrary.
// *********************************************************************//
Cogetstring = class
class function Create: Igetstring;
class function CreateRemote(const MachineName: string): Igetstring;
end;

implementation

uses ComObj;

class function Cogetstring.Create: Igetstring;
begin
Result := CreateComObject(CLASS_getstring) as Igetstring;
end;

class function Cogetstring.CreateRemote(const MachineName: string): Igetstring;
begin
Result := CreateRemoteComObject(MachineName, CLASS_getstring) as Igetstring;
end;

end.



// Form2

unit Unit2;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm2 = class(TForm)
Edit1: TEdit;
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form2: TForm2;

implementation

{$R *.dfm}

end.



‘VBA控制器代码

Private Sub CommandButton1_Click()
Dim auto
Dim ret
Set auto = CreateObject("inprocess.getstring")
auto.showmodelform ("Welcom")
ret = auto.thestring
auto.freeform
MsgBox ret
End Sub

总结:
1、 曲折地实现了预想的功能。
2、 实验显示,在CreateObject之后,Show或ShowModel之前,对于控制器来说,服务器的窗体及控件不可用;而一旦ShowModel,进程则停留在服务器,只有在窗体关闭后,进程才回到控制器,总之,控制器不能直接通过服务器的属性来对其进行设定很不爽。
3、 下一课题是如何将数据库封装成服务器,在控制器和服务器之间传递复杂数据类型。
 
补充改进见
http://www.delphibbs.com/delphibbs/DispQ.asp?LID=3028135
 
后退
顶部