我在DLL中封装一个非模式窗体,程序如下:
DLL窗体程序:
unit DLLFrm;
//==============================================================================
//本程序由杨明学参照《高级编程》书写;
//
//程序封装一个非模式窗体于DLL中,并结合我们的权限要求对按钮进行控制;此只是一个
//范例程序,在具体的过程中可以进行修改,如可以增加和删除按钮的个数,在增加和减少
//按钮的个数的同时应修改ShowDllFrm的参数的个数。
//
//版本:0.9  ,本版有一个BUG。
//
//完成时间:2003年6月2日
//==============================================================================
interfaceuses
  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;interfaceuses
  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。

解决方案 »

  1.   

    最好参考一下《Delphi 5开发人员指南》,上面讲的非常清楚!国内作者写的书以该都是什么高级、高手、速成、宝典之类的,内容空洞,几乎和垃圾等同,所以建议参考一些国外作者写的书籍,哪怕是翻译的也比大部分国内作者写的书强!!!
      

  2.   

    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;
      

  3.   

    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);
      

  4.   

    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;