如何显示背景图片并以dll窗体居中显示面板?

时间:2018-12-04 12:27:53

标签: delphi dll vcl delphi-10-seattle

我想加载一张图像,该图像将成为驻留在dll中的最大化Form的背景。

从Vcl表单应用程序调用dll,但遇到无法在Form上加载背景图像的麻烦,dll总是崩溃。

感谢您的帮助。

================================================ ==========================

可执行

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

type
  TForm2 = class(TForm)
    btn1: TButton;
    procedure btn1Click(Sender: TObject);
  end;

var
  Form2: TForm2;

implementation  {$R *.dfm}

procedure LoadDLL;
type
  TShowformPtr = procedure; stdcall;
var
  HDLL: THandle;
  Recv: TShowformPtr;
begin
  HDLL := LoadLibrary('lib.dll');
  if HDLL <> 0 then
  begin
    @Recv := GetProcAddress(HDLL, 'Recv');
    if @Recv <> nil then
    Recv;
  end;
  //FreeLibrary(HDLL);
end;

procedure TForm2.btn1Click(Sender: TObject);
begin
LoadDLL;
end;

end.

Dll

主要:

library Project2;
uses
  SysUtils, Classes, Unit1, Unit2;

{$R *.res}

procedure Recv; stdcall;
begin
  showform;
end;

exports
  Recv;

begin
end.

Unit1(表格):

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    img1: TImage;
    pnl1: TPanel;
    procedure FormShow(Sender: TObject);
  private
    { Private declarations }
    procedure CreateParams(var Params: TCreateParams); override;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
   Params.WndParent:= Application.Handle;
  Params.ExStyle := Params.ExStyle or WS_EX_TOPMOST or WS_EX_TRANSPARENT;
  Params.ExStyle := WS_EX_TRANSPARENT or WS_EX_TOPMOST;
end;

procedure TForm1.FormShow(Sender: TObject);
begin
  brush.Style := bsclear;
  img1.Picture.LoadFromFile(IncludeTrailingBackslash(GetCurrentDir) + 'background.bmp');
  SetWindowPos(Form1.handle, HWND_TOPMOST, Form1.Left, Form1.Top, Form1.Width,
    Form1.Height, 0);

  ShowWindow(Application.handle, SW_HIDE);

  pnl1.Top := (self.Height div 2) - (pnl1.Height div 2);
  pnl1.Left := (self.Width div 2) - (pnl1.Width div 2);
end;

end.

Unit2:

unit Unit2;

interface

Uses
  windows,
  Unit1,
  SysUtils;

  procedure showform;

implementation

procedure showform;
begin
  Form1 := TForm1.Create(Form1);
  sleep(100);
  Form1.Show;
  Form1.Pnl1.Visible := True;
end;

end.

1 个答案:

答案 0 :(得分:0)

您的问题有很多问题,因此,考虑到缺乏细节,我将尽力回答。

  1. 您正在使用表单,因此您正在构建VCL应用程序。您需要让IDE将VCL框架分配给您的项目。

  2. 此行完全错误:

    Form1 := TForm1.Create(Form1);  
    

    rare circumstances中显示一个自己的内容。我会说很有可能,这就是您的应用程序崩溃的原因。有关DLL中的表单的详细信息,请参见this

    如果无法正确调试应用程序,请在该行之前发出蜂鸣声,然后在其后发出蜂鸣声(在它们之间进行延迟)。

  3. 我认为您的问题应该称为“如何调试Delphi项目”。

    您需要做的是获取程序崩溃的确切行。这将使您了解为什么会出现错误/崩溃(顺便说一句,您从未显示确切的错误消息)。

    去检查HadShi(推荐)或EurekaLog(越野车)或Smartinspect(我从未尝试过。价格与其他两个相似)。确保您正在调试模式下运行,已打开集成调试器(请参阅IDE选项),并且EXE / DLL中的debug information is present

    PS:如果没有上面显示的三个记录器之一,您仍然可以调试应用程序。只需将您的项目正确配置为在调试模式下运行即可!

    要调试DLL,请参见“运行->参数”菜单。定义一个主机应用程序,该应用程序将加载您的DLL。如果错误是DLL,则调试器将进行控制,并将光标置于生成崩溃的代码行中。

  4. 我不知道您要达到的最终目的/目标是什么。因此,我必须警告您,您可能需要考虑以下问题:

    • Do you need to use ShareMM

    • 为什么要将此构建为DLL?无法将应用程序编写为单个EXE吗?还是两个相互通信的EXE?