dll和exe里面两个单元文件之间互相引用(100分)

  • 主题发起人 主题发起人 可视化
  • 开始时间 开始时间

可视化

Unregistered / Unconfirmed
GUEST, unregistred user!
我在主窗体中动态创建的按钮,按钮的单击事件是BtnClick(Sender: TObject)如下:
procedure fmain.BtnClick(Sender: TObject);
begin
if fmain.suiBtnFlag.Caption='销售'+#13+'管理' then
OpenForm(MDIChildForm1);//打开窗体的一个方法
else if fmain.suiBtnFlag.Caption='客户'+#13+'管理' then
OpenForm(MDIChildForm2);
//(注意:问题就出在这里MDIChildForm1和MDIChildForm2是两个不同dll里的两个窗体。fmain是主窗体,它是exe文件里的主窗体。我在exe的主窗体里调用dll里的MDIChildForm1,这时候就要uses单元文件,而我的单元文件是在dll程序里,我不可能uses它。反过来,我要在dll里使用exe里的文件也要uses。这个问题怎么解决?或者换个思维方式也可以产生同样效果。)
end;
说白了就是 在dll里的一个单元文件和exe里面的一个单元文件之间互相引用的问题。
 
楼主,看你在另一帖找到答案了
来接分了
呵呵
 
这样能吗
干吗不直接add file加入到project
 
写函数OpenFormDLL(DllName:String):Boolean;就可以了。
将要调用的方法放在这个函数里。
简单实例如:
Function OpenFormDll(DllName,RunMod:String):Boolean;
var
LibHandle: THandle;
ShowForm: TShowForm;
begin
Result:=False;
LibHandle := LoadLibrary(PChar(DllName));
try
if LibHandle = HINSTANCE_ERROR then
raise EDLLLoadError.Create('Unable to Load DLL');
@ShowForm := GetProcAddress(LibHandle, PChar(RunMod));
if not (@ShowForm = nil) then
ShowForm;
finally
Result:=True;
end;
end;
 
增加难度,请放到记事本中阅读方便
*****************************************************************
主窗体main.pas:
function SetModualRight(MainForm:TForm;const UserNO,ADept: string;ARow,ACol: Integer;AParent: TWincontrol;suiFileTheme1:TsuiFileTheme;adoBtn,temp: TADOQuery):Integer;stdcall;
external 'D:/MyDoc/Sell/system/SysUnit.dll';

主窗体按钮单击事件(调用SysUnit.dll动态的创建好多按钮)
SetModualRight(Fmain,g_UserNO,'XS',3,5,pnl1,suiFileTheme1,fDM.adoBtn,fDM.temp);
——————————————————————————————————————————
所有动态库里的公用单元文件Base_Base.pas:
function SetModualRight(MainForm:TForm;const UserNO,ADept: string;ARow,ACol: Integer;
AParent: TWincontrol;suiFileTheme1:TsuiFileTheme;adoBtn,temp: TADOQuery):Integer;stdcall;
begin
......此处省略代码(这部分代码就是用循环语句创建的很多按钮)...........................
btn[i,j]:= TButton.Create(TPanel(AParent));
btn[i,j].parent:= AParent;
{注意:所有的按钮都在主窗体(main.pas)的不同的Panel上(每个模块一个小Panel,所有的小Panel都在同一个大Panel上)}
btn[i,j].OnClick:=fBase_Base.BtnClick; //注意:问题就在这里
......此处省略代码(这部分代码就是用循环语句创建的很多按钮)...........................
end;

procedure fBase_Base.BtnClick(Sender: TObject这里还要一些这样参数,才能识别是哪个模块,但是参数怎么传递呢?还要和动态创建的按钮的OnClick兼容);
begin
showmessag('你好')
end;
——————————————————————————————————
sys模块的SysUnit.dll里的一个单元文件sysunit.pas
procedure sysdll(这里的参数怎么写,怎么去传递呢?);
begin
if 动态创建的按钮.Caption='AA' then
打开窗体AA
else if 动态创建的按钮.Caption='BB' then
打开窗体BB;
end;
-----------------------------
xt模块xtUnit.dll里的一个单元文件xtUnit.pas
procedure xtdll(这里的参数怎么写,怎么去传递呢?);
begin
if 动态创建的按钮.Caption='CC' then
打开窗体CC
else if 动态创建的按钮.Caption='DD' then
打开窗体DD;
end;
-------------------------------------------------------------

procedure TfrmMain.OnCustomMenuCall(Sender: TObject);
var
aCMI : TCustomMenuItem;
cfa : TfrmDynaCustomQuery;
fci : TFormClassItem;
begin
aCMI := GBaseSysSetting.CustomMenuMgr.GetItem(Sender);
fci := FormClassMgrUnit.GFormClassMgr.GetItemByAliasName(aCMI.FormType);
if fci = nil then exit;
cfa := TfrmDynaCustomQuery(CallChildForm(Sender, fci.FormClass.ClassName));
cfa.CallAfterShow;
end;

----------------------------------------------------------------
总结:
现在按钮是能看到了,按道理说我在主窗体里单击我动态创建的按钮时,应该会有不同的窗体被打开才对,
但是现在什么都没有弹出来啊。为什么?不知道是我的思路不对还是缺少什么东西?应该怎么写才好?
 
上面的写错了,应该是这样的
************************************************
主窗体main.pas:
function SetModualRight(MainForm:TForm;const UserNO,ADept: string;ARow,ACol: Integer;AParent: TWincontrol;suiFileTheme1:TsuiFileTheme;adoBtn,temp: TADOQuery):Integer;stdcall;
external 'D:/MyDoc/Sell/system/SysUnit.dll';

主窗体按钮单击事件(调用SysUnit.dll动态的创建好多按钮)
SetModualRight(Fmain,g_UserNO,'XS',3,5,pnl1,suiFileTheme1,fDM.adoBtn,fDM.temp);
——————————————————————————————————————————
所有动态库里的公用单元文件Base_Base.pas:
function SetModualRight(MainForm:TForm;const UserNO,ADept: string;ARow,ACol: Integer;
AParent: TWincontrol;suiFileTheme1:TsuiFileTheme;adoBtn,temp: TADOQuery):Integer;stdcall;
begin
......此处省略代码(这部分代码就是用循环语句创建的很多按钮)...........................
btn[i,j]:= TButton.Create(TPanel(AParent));
btn[i,j].parent:= AParent;
{注意:所有的按钮都在主窗体(main.pas)的不同的Panel上(每个模块一个小Panel,所有的小Panel都在同一个大Panel上)}
btn[i,j].OnClick:=fBase_Base.BtnClick; //注意:问题就在这里
......此处省略代码(这部分代码就是用循环语句创建的很多按钮)...........................
end;

procedure fBase_Base.BtnClick(Sender: TObject这里还要一些这样参数,才能识别是哪个模块,但是参数怎么传递呢?还要和动态创建的按钮的OnClick兼容);
begin
if sys模块 then
sysdll()//在sysUnit.dll单元文件里的一个方法
else if xt模块 then
xtdll();//在xtUnit.dll单元文件里的一个方法
end;
——————————————————————————————————
sys模块的SysUnit.dll里的一个单元文件sysunit.pas
procedure sysdll(这里的参数怎么写,怎么去传递呢?);
begin
if 动态创建的按钮.Caption='AA' then
打开窗体AA
else if 动态创建的按钮.Caption='BB' then
打开窗体BB;
end;
-----------------------------
xt模块xtUnit.dll里的一个单元文件xtUnit.pas
procedure xtdll(这里的参数怎么写,怎么去传递呢?);
begin
if 动态创建的按钮.Caption='CC' then
打开窗体CC
else if 动态创建的按钮.Caption='DD' then
打开窗体DD;
end;
-------------------------------------------------------------
总结:
现在按钮是能看到了,按道理说我在主窗体里单击我动态创建的按钮时,应该会有不同的窗体被打开才对,
但是现在什么都没有弹出来啊。为什么?不知道是我的思路不对还是缺少什么东西?应该怎么写才好?
 
老兄,问题我给你总结一下,
主要就是想解决:当一个EXE程序调用一个DLL。让这个DLL在EXE程序的FORM上或是FORM的对象上动态创建一些对象,动态创建的对象的事件驱动要放在DLL里响应。

我已经搞清楚了,动态创建参数传递用指针传到DLL里就能创建了,只是事件定义和有CLASS的单元定义不一样,应该照以下定义才能在DLL里响应。注意红色部份

把分给我吧。

procedure xxxxx(vPanel: pointer); stdcall; export;
var
X, Y, Nu, ID: integer;
xPanel: TPanel;
Event: TNotifyEvent;
begin
xPanel := vPanel;
SetLength(rButton, 33);
Nu := (xPanel.Width) div 21;
X := 5;
Y := 5;
for ID := 0 to 32 do
begin
rButton[ID] := TPanel.Create(xPanel);
rButton[ID].Tag := 1;
rButton[ID].Caption := iif((ID + 1) < 10, '0', '') + inttostr(id + 1);
rButton[ID].top := Y;
rButton[ID].Left := X;
rButton[ID].Height := 20;
rButton[ID].Width := 20;
rButton[ID].Parent := xPanel;
[red] TMethod(Event).Data := rButton[ID];
TMethod(Event).Code := @ButtonRClick;[/red] rButton[ID].OnClick := Event;
X := iif(((ID + 1) mod NU) = 0, 5, X + 21);
Y := iif(((ID + 1) mod NU) = 0, Y + 21, y);
end;
end;
 
有点技术含量
 
虽然答案都不怎么满意,但也得分分啊!
 
后退
顶部