Delphi VCL DLL窗体调用错误(访问冲突)

soat7uwm  于 2022-11-04  发布在  其他
关注(0)|答案(1)|浏览(301)

我正在尝试从主窗体向DLL调用ChildForm。
当我取出cxDBTreeList时,我在创建它时收到一个错误...
如果我再次删除cxDBTreeList,它将正常工作,不会出现任何错误。
在TcxEditDBRegisteredRepositoryItems.GetItemByDataBinding事件中,结果似乎为空。
如果cxDBTreeList为空,则在TcxScrollBarPainter.getMinThumbnailSize事件中,结果似乎为空。
@ DLL表单
第一个
@主表单

unit Unit1;
...
var
  Form1: TForm1;
  DLLHandle: THandle;
  DLLForm : TForm;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
type
  TDLLProc = function(App: TApplication): TForm;
var
  AProcedure : TDLLProc;
  MessageStr : String;
begin
  DLLHandle := LoadLibrary(PChar( 'Project1.dll' ));
  if (DLLHandle > 32) then
  begin
    @AProcedure := GetProcAddress( DLLHandle, PChar( 'CreateDLLForm' ) );
    if (@AProcedure <> nil ) then
    begin
      DLLForm := AProcedure(Application);
      with DLLForm do
      begin
        Width := 500;
        Height := 500;
      end;
      Application.ProcessMessages;
    end
    else
    begin
      MessageStr :=  'Not find dll file1';
      ShowMessage( MessageStr );
    end;
  end
  else
  begin
    MessageStr :=  'Not find dll file2';
    ShowMessage( MessageStr );
  end;
end;
cnwbcb6i

cnwbcb6i1#

你在这里缺少一些基础知识,阅读 Delphi 编码器提供的链接。只要你明白你将有多个,正如大卫指出的,如果你不使用或不能使用包,你仍然可以在DLL中使用窗体。在释放DLL之前,你需要保存并恢复DLL的应用程序句柄,否则你可能会有其他问题。要做的最简单的事情就是尽可能地将DLL中的窗体作为一个独立的程序/进程来处理,如果不使用大量的方法甚至回调,您将永远无法从主EXE中与DLL中的窗体进行交互。我在这里不会详细介绍,但我已经包含了两个选项来显示下面的窗体。您调用SetApplicationHandle、调用其中一个show form方法,然后调用ResetApplicationHandle。

var
  fOldAppHandle: THandle;

procedure SetApplicationHandle(Value: THandle); stdcall;
begin
  fOldAppHandle := Application.Handle;
  Application.Handle := Value;
end;

function ShowForm1: Integer; stdcall;
begin
  Form1 := TForm1.Create(nil);
  try
    Result := Form1.ShowModal;
  finally
    Form1.Free;
  end;
end;

function ShowForm1WithSize(H, W: Integer): Integer; stdcall;
begin
  Form1 := TForm1.Create(nil);
  try
    Form1.Width := W;
    Form1.Height := H;
    Result := Form1.ShowModal;
  finally
    Form1.Free;
  end;
end;

procedure ResetApplicationHandle; stdcall;
begin
  Application.Handle := fOldAppHandle;
end;

exports
  SetApplicationHandle,
  ResetApplicationHandle,
  ShowForm1,
  ShowForm1WithSize;

相关问题