お世話になっております。
勉強でフォーム付DLLを作成しエラーなく呼び出し・終了ができるところまではできたのですが、DLL側のフォームにActionMainMenuBarを配置した場合にExe側からDLLフォームを2回以上呼び出してフォームを最小化などの操作した場合にエラーが発生するようになりました。
色々調べていたのですがActionMainMenuBarに原因があるようでDLL側のフォームを閉じる際にActionMainMenuBarをFreeするとエラーは出なくなりました。
ボタンやラベルなどを配置しても特にエラーにはならないのですがActionMainMenuBarを配置しFreeしてあげないとエラーになるのがよくわかりません。
私自身がなにか変なことをしているのかもしれませんがソースを記載させて頂きます。
環境は
WindowsXP SP2
Delphi7 Pro(Update2)
どうぞよろしくお願いします。
--- Exe側(抜粋) ---
type
TDLL_TEST = procedure (hWnd:THandle);stdcall;
var
DLL_TEST : TDLL_TEST;
procedure TForm1.Button1Click(Sender: TObject);
begin
@DLL_TEST := GetProcAddress(LoadLibrary(PChar('Project2.dll')),PChar('DLL_TEST'));
DLL_TEST(Application.Handle);
end;
---DLL側---
library Project2;
uses
Windows,
Forms,
Unit2 in 'Unit2.pas' {Form2};
//Form2にはActionMainMenuBarとActionManagerのみ貼り付けています。
{$R *.res}
procedure DLL_TEST(hWnd:THandle);stdcall;
begin
try
Application.Handle := hWnd;
Form2 := TForm2.Create(Application);
Form2.ShowModal;
finally
Form2.ActionMainMenuBar1.Free;
//↑を追加したらエラーが出なくなった。
Application.Handle := 0;
FreeLibrary(0);
Form2.Release;
end;
end;
exports
DLL_TEST;
begin
end.
簡単に調べてみたところ
ActionMainManuBar.Destroy で Application.Handle を使用していますが
destructor TCustomActionMainMenuBar.Destroy;
var
Hook: TWindowHook;
begin
Hook := MainWndHook;
SendMessage(Application.Handle, CM_WINDOWHOOK, 1, Integer(@@Hook));
inherited;
end;
のでフォームが閉じる前に Application.Handle を 0 にしてはいけません
Form2.Free;
Application.Handle := 0;
もしくは
Form2.Release;
Application.ProcessMessages; //CM_RELEASEを処理させる
Application.Handle := 0;
Release でCM_RELEASE PostMessage をそのまま処理が戻ってきて
Free される前に Application.Handle := 0;が実行されてしまい
TCustomActionMainMenuBar.Destroy を実行する際に Application.Handle に
0が入ってしまっています
TCustomActionMainMenuBar.Destroy で MessageBox(0,PChar(IntToStr(Application.Handle)),'',0) とやればわかるでしょう
CM_RELEASE を SendMessage に変えるとエラーが出ません。
あと
FreeLibrary(0);
がDLL内にあるのかが不明です
KHE00221様 ご回答ありがとうございます。
Application.Handle=0をするタイミングでこのようになるとはわかりませんでした。
まだまだ勉強が足りませんね、ありがとうございます。
>>FreeLibrary(0);
>>がDLL内にあるのかが不明です
最初はExe側に置いていたのですが色々やっててDLL内でやってもエラーにならなかったのでそのままでした(汗)
KHE00221様のご指摘により自分が色々思い込みで勘違いしていた事にも気付きました。ありがとうございました。
ツイート | ![]() |