8

私は 1 つのフォームを持つ DLL を開発しました。以下のコードを使用してスタイルを設定しました。

library TestLib;

uses Vcl.Themes, Vcl.Styles,....
.
.
exports
   function1,
   function2;

begin
   TStyleManager.TrySetStyle('Style1');
end.

この dll をロードして function1 を呼び出すと、このフォームが開きます。スタイルが適用されたフォームが開きます。

そのウィンドウを最小化すると、アクセス違反が発生します。最大化と復元を含むすべてが正常に機能しています。また、すべての機能が正常に動作しています。

このフォームの最小化イベントによって生成されたメッセージを処理していないと思います。ご意見をお聞かせください。

注:スタイルを削除すると、すべて正常に動作します。

Call Stack

:0976742b TWinControl.HandleNeeded + $3
:0978ad8a TStyleManager.HandleMessage + $56
:09762a3c TWinControl.DoHandleStyleMessage + $14
:0972e6be TCustomForm.WndProc + $612
:09763c2b TWinControl.MainWndProc + $2F

更新:SSCCE

Project1.EXE (Unit1.pas/dfm の 1 つの形式を持つ)

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    function InitDLL: Boolean;
  end;

var
  Form1: TForm1;

implementation

const
   cLIBRARY = 'Project2.dll';

var
   DLLHandle : THandle;
   showfrm: procedure;

procedure TForm1.Button1Click(Sender: TObject);
begin
   if InitDLL then
      showfrm;
end;

function TForm1.InitDLL: Boolean;
begin
   if DLLHandle = 0 then
   begin
      DLLHandle := LoadLibrary(PChar(cLIBRARY));
      if DLLHandle <> 0 then
      begin
         @showfrm := GetProcAddress(DLLHandle, 'showfrm');
      end
      else
      begin
         Result := False;
         raise Exception.Create('Error loading DLL: ' + cLIBRARY);
      end;
   end;

   Result := (DLLHandle > 0);
end;

{$R *.dfm}

end.

任意のフォームとして unit2 を持ち、そのフォームを呼び出す unit3 を持つ 1 つの DLL Project2.dll を作成します。スタイル (AnyStyle1 など) をこの dll にリソースとして追加します。

library Project2;

{ Important note about DLL memory management: ShareMem must be the
  first unit in your library's USES clause AND your project's (select
  Project-View Source) USES clause if your DLL exports any procedures or
  functions that pass strings as parameters or function results. This
  applies to all strings passed to and from your DLL--even those that
  are nested in records and classes. ShareMem is the interface unit to
  the BORLNDMM.DLL shared memory manager, which must be deployed along
  with your DLL. To avoid using BORLNDMM.DLL, pass string information
  using PChar or ShortString parameters. }

{$R *.dres}

uses
  ShareMem,
  Vcl.Themes,
  Vcl.Styles,
  Vcl.Dialogs,
  System.SysUtils,
  System.Classes,
  Unit2 in 'Unit2.pas' {Form2},
  Unit3 in 'Unit3.pas';

{$R *.res}

exports
showfrm;

begin
   if TStyleManager.TrySetStyle('AnyStyle1') then
   begin
      ShowMessage('True');
   end
   else
      ShowMessage('False');
end.

unit3.pas

unit Unit3;

interface

uses Unit2;

   procedure showfrm;

implementation
   procedure showfrm;
   begin
      with TForm2.Create(nil) do
         Show;
   end;
end.

Unit2 ウィンドウの最小化ボタンを押します。アクセス違反になります。

4

3 に答える 3

0

「ランタイム パッケージ」を有効にして、同じバージョンの RAD Studio で dll と exe の両方をコンパイルする必要があります。この場合のみ、dll のフォームが正しく動作することが保証されます。

于 2013-08-29T08:58:20.727 に答える