关于在DLL中封装窗体的问题
我在DLL中封装一个非模式窗体,程序如下:
DLL窗体程序:
unit DLLFrm;
//==============================================================================
//本程序由杨明学参照《高级编程》书写;
//
//程序封装一个非模式窗体于DLL中,并结合我们的权限要求对按钮进行控制;此只是一个
//范例程序,在具体的过程中可以进行修改,如可以增加和删除按钮的个数,在增加和减少
//按钮的个数的同时应修改ShowDllFrm的参数的个数。
//
//版本:0.9 ,本版有一个BUG。
//
//完成时间:2003年6月2日
//==============================================================================
interface
uses
SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
Forms, Dialogs, Grids, Calendar, ComCtrls, StdCtrls, Buttons, DBGrids;
type
TDLLForm = class(TForm)
trv: TTreeView;
StatusBar1: TStatusBar;
btnAdd: TBitBtn;
GroupBox1: TGroupBox;
dtpHappenTime: TDateTimePicker;
Label2: TLabel;
Label4: TLabel;
Label5: TLabel;
mmoDeal: TMemo;
mmoQuestion: TMemo;
Label6: TLabel;
Label1: TLabel;
Label3: TLabel;
cboPersonName: TComboBox;
cboHappenUnit: TComboBox;
cboDepartment: TComboBox;
btnmodify: TBitBtn;
btnSave: TBitBtn;
BtnReport: TBitBtn;
BtnExit: TBitBtn;
BtnPrint: TBitBtn;
BtnDelete: TBitBtn;
procedure BtnExitClick(Sender: TObject);
end;
{ Declare the export function }
function ShowDllFrm(AHandle: THandle; ACaption: String;bBtnAdd:boolean;
bBtnDelete:boolean;bBtnModify:boolean;bBtnSave:boolean;bBtnReport
:boolean;bBtnPrint:boolean): Longint; stdCall;
procedure CloseDllFrm(AFormRef: Longint); stdcall;
implementation
//uses DLLFrm;
{$R *.DFM}
//==============================================================================
//
//本文件的主函数,用于显示非模式窗体,同时传入按钮控制变量。
//
//函数名: ShowDllFrm
//
//参数:Ahandle:Thandle 传入调用本窗体的程序句柄;
//Acaption:string 传入本窗体的窗体标题,本例中没有使用
//以下的boolean变量可以根据自己的需要而增减,传入按钮控制
//
//返回值:Longint;
//
//==============================================================================
function ShowDllFrm(AHandle: THandle; ACaption: String;bBtnAdd:boolean;
bBtnDelete:boolean;bBtnModify:boolean;bBtnSave:boolean;bBtnReport
:boolean;bBtnPrint:boolean): Longint;
var
DLLForm: TDllForm; //引用本窗体
begin
// Copy application handle to DLL's TApplication object
Application.Handle := AHandle;
DLLForm := TDLLForm.Create(Application);
Result := Longint(DLLForm);
if bBtnDelete then //以下判断为确定按钮的可用与否
DLLForm.BtnDelete.Enabled:=true;
if bBtnPrint then
DLLForm.BtnPrint.Enabled:=true;
if bBtnReport then
DLLForm.BtnReport.Enabled:=true;
if bBtnSave then
DLLForm.btnSave.Enabled:=true;
if bBtnModify then
DLLForm.btnmodify.Enabled:=true;
if bBtnAdd then
DLLForm.btnAdd.Enabled:=true;
// DLLForm.Caption := ACaption;
DLLForm.Show; //显示该窗体
end;
procedure CloseDllFrm(AFormRef: Longint);
begin
if AFormRef > 0 then
TDLLForm(AFormRef).Release;
end;
procedure TDLLForm.BtnExitClick(Sender: TObject);
begin
close;
end;
end.
PROJECT程序如下:
library DllPrj;
uses
ShareMem,
SysUtils,
Classes,
DLLFrm in 'DLLFrm.pas' {DLLForm};
exports
ShowDllFrm,
CloseDllFrm;
begin
end.
测试程序如下:
unit MainFrm;
interface
uses
SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
Forms, Dialogs, StdCtrls;
type
TMainForm = class(TForm)
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
FFormRef: TForm;
end;
var
MainForm: TMainForm;
function ShowDllFrm(AHandle: THandle; ACaption: String;bBtnAdd:boolean;
bBtnDelete:boolean;bBtnModify:boolean;bBtnSave:boolean;bBtnReport
:boolean;bBtnPrint:boolean): Longint;StdCall;
external 'DllPrj.DLL';
procedure CloseDllFrm(AFormRef: Longint); stdcall;
external 'DllPrj.DLL';
implementation
{$R *.DFM}
procedure TMainForm.FormCreate(Sender: TObject);
begin
FFormRef := nil; // Initialize the FFormRef field to nil.
end;
procedure TMainForm.Button1Click(Sender: TObject);
begin
if not Assigned(FFormRef) then
FFormRef := TForm(ShowDllFrm(Application.Handle, Caption,false,true,
true,true,true,true));
end;
end.
在调试时出现的问题是,当BUTTON1按下后正常显示所需的窗体,窗体也可以正常关闭,但是在不关闭测试程序的情况下,再次按下BUTTON1时就不能正常显示所需的窗体了。请问怎么解决????
给分100。
问题点数:0、回复次数:8Top
1 楼duxin(小伍)回复于 2003-06-04 15:02:30 得分 0
先签个到慢慢看Top
2 楼Delphi_Li(Delphi Li)回复于 2003-06-04 15:27:32 得分 0
最好参考一下《Delphi 5开发人员指南》,上面讲的非常清楚!国内作者写的书以该都是什么高级、高手、速成、宝典之类的,内容空洞,几乎和垃圾等同,所以建议参考一些国外作者写的书籍,哪怕是翻译的也比大部分国内作者写的书强!!!Top
3 楼duxin(小伍)回复于 2003-06-04 15:54:12 得分 0
if bBtnSave then
DLLForm.btnSave.Enabled:=true;
if bBtnModify then
DLLForm.btnmodify.Enabled:=true;
if bBtnAdd then
DLLForm.btnAdd.Enabled:=true;
// DLLForm.Caption := ACaption;-------------好像是这里为什么注释他
DLLForm.Show; //显示该窗体
end;
procedure CloseDllFrm(AFormRef: Longint);
begin
if AFormRef > 0 then
TDLLForm(AFormRef).Release;
end;
Top
4 楼duxin(小伍)回复于 2003-06-04 15:56:31 得分 0
取消试试
我看了几编没发现什么大错误
要还不行我也帮不了你啦Top
5 楼ymxue(ymxue)回复于 2003-06-04 16:20:21 得分 0
这个不是问题,只是传入的参数不用罢了。谢谢了。Top
6 楼qwertyasd(昊)回复于 2003-06-04 16:30:36 得分 0
提示什么错误?
Top
7 楼Linux2001(闭关开发中)回复于 2003-06-04 16:38:10 得分 0
function ShowDllFrm(AHandle: THandle; ACaption: String;bBtnAdd:boolean;
bBtnDelete:boolean;bBtnModify:boolean;bBtnSave:boolean;bBtnReport
:boolean;bBtnPrint:boolean): Longint;
var
DLLForm: TDllForm; //引用本窗体
begin
// Copy application handle to DLL's TApplication object
Application.Handle := AHandle; //把这一句注释掉
DLLForm := TDLLForm.Create(Application);
Result := Longint(DLLForm);
Top
8 楼zjybestzjybest(zjybestzjybest)回复于 2003-06-04 22:19:07 得分 0
procedure TMainForm.Button1Click(Sender: TObject);
begin
//你关闭的时候没有把FFormRef清掉所以不能创建拉,
//建议用主窗口中调用CloseDllFrm(FFormRef)关闭DLL中的非模式窗口
//然后FFormRef:=nil;把上述操作放在一个事件中
if not Assigned(FFormRef) then
FFormRef := TForm(ShowDllFrm(Application.Handle, Caption,false,true,
true,true,true,true));
end;
Top



