F
fjx_jwf
Unregistered / Unconfirmed
GUEST, unregistred user!
//如果正确http://www.delphibbs.com/delphibbs/dispq.asp?lid=2148966上的50分也是你的
我在主程序exe中打开dll中子窗口的mainmenu菜单后关闭这个子窗口,然后重复这个操作后关闭主程序就会报错,也就是不能连续调用两次,但只要不用子窗口的mainmenu就不会报错,那位大哥帮我瞧一下呀
另外只要dll中的子窗口不是childform类型的也不会报错
//dll的调用程序如下
unit MainUnit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, Menus, publicUnit, Grids, DB, ADODB,
DBClient, MConnect, SConnect;
type
TfrmMain = class(TForm)
MainMenu1: TMainMenu;
N1: TMenuItem;
Panel1: TPanel;
Button1: TButton;
Button2: TButton;
procedure N1Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
procedure WMGetDlgCode(var msgIn: TWMGetDlgCode)
message WM_GETDLGCODE;
public
{ Public declarations }
end;
type
tnet=array[0..3] of pchar;
var
frmMain: TfrmMain;
function ShowDllForm(App: TApplication
ACaption: string
sc: TScreen): Longint;
stdcall
external 'prjDll.dll';
//function openform(App:TApplication;sc:tscreen;netpara:tnet):Longint;
//stdcall;External'../rzbinfo/reportbuild/reportbuild.dll';
//function openForm(App: TApplication;sc: TScreen;netpara:tnet): Longint;
//stdcall;external'../rzbinfo/reportbuild/reportbuild.dll';
implementation
{$R *.dfm}
procedure TfrmMain.N1Click(Sender: TObject);
begin
ShowDllForm(Application, '子窗体', Screen);
end;
procedure TfrmMain.WMGetDlgCode(var msgIn: TWMGetDlgCode);
begin
inherited;
msgIn.Result := msgIn.Result or DLGC_WANTTAB;
end;
procedure TfrmMain.Button1Click(Sender: TObject);
//var
//netp:tnet;
begin
{netp[0]:=pchar(socketconnection1.Address);
netp[1]:=pchar(inttostr(socketconnection1.Port));
netp[2]:=pchar(socketconnection1.ServerName);
netp[3]:=pchar(socketconnection1.ServerGUID);
openForm(Application,Screen,netp);}
end;
procedure TfrmMain.Button2Click(Sender: TObject);
begin
ShowDllForm(Application, '子窗体', Screen);
end;
end.
//dll如下
library prjDLL;
uses
SysUtils,
Classes,
Windows,
Forms,
childUnit in 'childUnit.pas' {frmChild},
Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
var
DLLApp: TApplication;
DLLScreen:TScreen;
function ShowDllForm(App:TApplication
ACaption:String
sc:TScreen):Longint;stdcall;
begin
Application := App;
Screen:=sc;
if not Assigned(frmChild) then
frmChild:=TfrmChild.Create(Application);
Result:=Longint(frmChild);
frmChild.Caption := ACaption;
frmChild.Show;
end;
procedure DLLUnloadProc(Reason : Integer);
begin
if Reason = DLL_PROCESS_DETACH then begin
Application := DLLApp;//恢复
Screen:=DLLScreen;
end;
end;
exports
ShowDllForm;
begin
DLLApp := Application
//保存 DLL 中初始的 Application 对象
DLLScreen:=Screen;
DLLProc := @DLLUnloadProc
//保证 DLL 卸载时恢复原来的 Application
end.
//frmchild如下
unit childUnit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, publicUnit, Grids, DB, ADODB, DBGrids, Menus, StdCtrls;
type
TfrmChild = class(TForm)
ComboBox1: TComboBox;
MainMenu1: TMainMenu;
xxx1: TMenuItem;
xxxx1: TMenuItem;
xxxx2: TMenuItem;
procedure FormClose(Sender: TObject
var Action: TCloseAction);
procedure FormKeyPress(Sender: TObject
var Key: Char);
procedure FormCreate(Sender: TObject);
procedure xxxx2Click(Sender: TObject);
private
procedure WMGetDlgCode(var msgIn: TWMGetDlgCode);
message WM_GETDLGCODE;
public
end;
var
frmChild: TfrmChild;
implementation
uses Unit1;
{$R *.dfm}
procedure TfrmChild.FormClose(Sender: TObject
var Action: TCloseAction);
begin
FreeAndNil(frmChild);
end;
procedure TfrmChild.FormKeyPress(Sender: TObject
var Key: Char);
begin
if Key = #9 then // Char(VK_tab) then
if not (ActiveControl is TDBGrid) then
begin
Key := #0;
Perform(WM_NEXTDLGCTL, 0, 0);
end;
end;
procedure TfrmChild.WMGetDlgCode(var msgIn: TWMGetDlgCode);
begin
inherited;
msgIn.Result := msgIn.Result or DLGC_WANTTAB;
end;
procedure TfrmChild.FormCreate(Sender: TObject);
begin
combobox1.Items.AddStrings(screen.fonts);
Self.KeyPreview := True;
end;
procedure TfrmChild.xxxx2Click(Sender: TObject);
begin
form1:=tform1.create(self);
form1.showmodal;
form1.free;
end;
end.
//form1就是一个空白的tform;
我在主程序exe中打开dll中子窗口的mainmenu菜单后关闭这个子窗口,然后重复这个操作后关闭主程序就会报错,也就是不能连续调用两次,但只要不用子窗口的mainmenu就不会报错,那位大哥帮我瞧一下呀
另外只要dll中的子窗口不是childform类型的也不会报错
//dll的调用程序如下
unit MainUnit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, Menus, publicUnit, Grids, DB, ADODB,
DBClient, MConnect, SConnect;
type
TfrmMain = class(TForm)
MainMenu1: TMainMenu;
N1: TMenuItem;
Panel1: TPanel;
Button1: TButton;
Button2: TButton;
procedure N1Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
procedure WMGetDlgCode(var msgIn: TWMGetDlgCode)
message WM_GETDLGCODE;
public
{ Public declarations }
end;
type
tnet=array[0..3] of pchar;
var
frmMain: TfrmMain;
function ShowDllForm(App: TApplication
ACaption: string
sc: TScreen): Longint;
stdcall
external 'prjDll.dll';
//function openform(App:TApplication;sc:tscreen;netpara:tnet):Longint;
//stdcall;External'../rzbinfo/reportbuild/reportbuild.dll';
//function openForm(App: TApplication;sc: TScreen;netpara:tnet): Longint;
//stdcall;external'../rzbinfo/reportbuild/reportbuild.dll';
implementation
{$R *.dfm}
procedure TfrmMain.N1Click(Sender: TObject);
begin
ShowDllForm(Application, '子窗体', Screen);
end;
procedure TfrmMain.WMGetDlgCode(var msgIn: TWMGetDlgCode);
begin
inherited;
msgIn.Result := msgIn.Result or DLGC_WANTTAB;
end;
procedure TfrmMain.Button1Click(Sender: TObject);
//var
//netp:tnet;
begin
{netp[0]:=pchar(socketconnection1.Address);
netp[1]:=pchar(inttostr(socketconnection1.Port));
netp[2]:=pchar(socketconnection1.ServerName);
netp[3]:=pchar(socketconnection1.ServerGUID);
openForm(Application,Screen,netp);}
end;
procedure TfrmMain.Button2Click(Sender: TObject);
begin
ShowDllForm(Application, '子窗体', Screen);
end;
end.
//dll如下
library prjDLL;
uses
SysUtils,
Classes,
Windows,
Forms,
childUnit in 'childUnit.pas' {frmChild},
Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
var
DLLApp: TApplication;
DLLScreen:TScreen;
function ShowDllForm(App:TApplication
ACaption:String
sc:TScreen):Longint;stdcall;
begin
Application := App;
Screen:=sc;
if not Assigned(frmChild) then
frmChild:=TfrmChild.Create(Application);
Result:=Longint(frmChild);
frmChild.Caption := ACaption;
frmChild.Show;
end;
procedure DLLUnloadProc(Reason : Integer);
begin
if Reason = DLL_PROCESS_DETACH then begin
Application := DLLApp;//恢复
Screen:=DLLScreen;
end;
end;
exports
ShowDllForm;
begin
DLLApp := Application
//保存 DLL 中初始的 Application 对象
DLLScreen:=Screen;
DLLProc := @DLLUnloadProc
//保证 DLL 卸载时恢复原来的 Application
end.
//frmchild如下
unit childUnit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, publicUnit, Grids, DB, ADODB, DBGrids, Menus, StdCtrls;
type
TfrmChild = class(TForm)
ComboBox1: TComboBox;
MainMenu1: TMainMenu;
xxx1: TMenuItem;
xxxx1: TMenuItem;
xxxx2: TMenuItem;
procedure FormClose(Sender: TObject
var Action: TCloseAction);
procedure FormKeyPress(Sender: TObject
var Key: Char);
procedure FormCreate(Sender: TObject);
procedure xxxx2Click(Sender: TObject);
private
procedure WMGetDlgCode(var msgIn: TWMGetDlgCode);
message WM_GETDLGCODE;
public
end;
var
frmChild: TfrmChild;
implementation
uses Unit1;
{$R *.dfm}
procedure TfrmChild.FormClose(Sender: TObject
var Action: TCloseAction);
begin
FreeAndNil(frmChild);
end;
procedure TfrmChild.FormKeyPress(Sender: TObject
var Key: Char);
begin
if Key = #9 then // Char(VK_tab) then
if not (ActiveControl is TDBGrid) then
begin
Key := #0;
Perform(WM_NEXTDLGCTL, 0, 0);
end;
end;
procedure TfrmChild.WMGetDlgCode(var msgIn: TWMGetDlgCode);
begin
inherited;
msgIn.Result := msgIn.Result or DLGC_WANTTAB;
end;
procedure TfrmChild.FormCreate(Sender: TObject);
begin
combobox1.Items.AddStrings(screen.fonts);
Self.KeyPreview := True;
end;
procedure TfrmChild.xxxx2Click(Sender: TObject);
begin
form1:=tform1.create(self);
form1.showmodal;
form1.free;
end;
end.
//form1就是一个空白的tform;