关于连续两次打开dll中子窗口的mainmenu菜单后报错的问题 (50分)

  • 主题发起人 主题发起人 fjx_jwf
  • 开始时间 开始时间
F

fjx_jwf

Unregistered / Unconfirmed
GUEST, unregistred user!
我在主程序exe中打开dll中子窗口的mainmenu菜单后关闭这个子窗口,然后重复这个操作后关闭主程序就会报错,也就是不能连续调用两次,但只要不用子窗口的mainmenu就不会报错,那位大哥帮我瞧一下呀

//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;
 
那位大哥帮帮忙呀
 
我不知道你的操作系统是什么的。记得有一本书《未公开的windows核心技术》(祖母级的,是介绍win31的)。里面说,win31中,菜单是系统资源,放在一个单独的堆(Heap)中,以后怎么实现的,我不是很清楚的了,估计你的问题也应该从这个角度去考虑。
要是修正意见的化,我觉得你还是,在设计时去掉这个菜单,在窗体的Create事件里面创建菜单,在Destroy事件中释放这个家伙,看看能不能行
 
win2000 server +delphi7
我的菜单有七八十项,在create中建立很麻烦呀, 另外我的dll中的窗口是子窗口,所以主程序调用dll中的子窗口时,子窗口的菜单就自动加到主程序上去了。能不能不让它加呀
 
真的没人知道如何解决吗?我真急呀
 
后退
顶部