私は 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 ウィンドウの最小化ボタンを押します。アクセス違反になります。