フォーム付DLLでActionMainMenuBarを使用した時

解決


しんや  2007-12-06 02:27:36  No: 28840

お世話になっております。
勉強でフォーム付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.


KHE00221  URL  2007-12-06 04:08:12  No: 28841

簡単に調べてみたところ

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内にあるのかが不明です


しんや  2007-12-06 23:15:17  No: 28842

KHE00221様  ご回答ありがとうございます。

Application.Handle=0をするタイミングでこのようになるとはわかりませんでした。
まだまだ勉強が足りませんね、ありがとうございます。

>>FreeLibrary(0);
>>がDLL内にあるのかが不明です
最初はExe側に置いていたのですが色々やっててDLL内でやってもエラーにならなかったのでそのままでした(汗)

KHE00221様のご指摘により自分が色々思い込みで勘違いしていた事にも気付きました。ありがとうございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加