`
lujar
  • 浏览: 512196 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Dll窗体调用解

阅读更多

//Project1==========================================================================

//调用窗体 Begin

unit CMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Menus, ExtCtrls, utchild;

const
 WM_CALLBACK = WM_USER + 100;

type
  TShowForm   = function (App: TApplication; CallProc: Pointer; FormID: Integer; ParentForm: TForm; ParentContralHandle: HWND): Tform; stdcall;
  TActiveForm = function : LongInt; stdcall;
  TCloseForm  = function : LongInt; stdcall;

  TfrmMain = class(TForm)
    MainMenu1: TMainMenu;
    Open1: TMenuItem;
    mmFileOpen: TMenuItem;
    mmFileClose: TMenuItem;
    Panel1: TPanel;
    mmFileOpenFrm: TMenuItem;
    mmFileCloseFrm: TMenuItem;
    Report1: TMenuItem;
    N1111: TMenuItem;
    Panel2: TPanel;
    Change1: TMenuItem;
    procedure mmFileOpenClick(Sender: TObject);
    procedure mmFileCloseClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure mmFileOpenFrmClick(Sender: TObject);
    procedure N1111Click(Sender: TObject);
    procedure Change1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    FLibHandle  : THandle;
    FShowForm   : TShowForm;
    FActiveForm : TActiveForm;
    FCloseForm  : TCloseForm;
    List : TList;
    //FFrm: TForm1;
    procedure CallPostMessage(ID:Integer);
    procedure BackCallMessage(var Msg: TMessage); message WM_CALLBACK;

    procedure WMHotKey(var Msg: TWMHotKey); message WM_HOTKEY;
    function GetSysFocus: Integer;
  public
    { Public declarations }
    procedure WMACTIVATEAPP(var Msg: TMessage); message WM_ACTIVATEAPP;
  end;

var
  frmMain: TfrmMain;
  FFrm: TForm1;
implementation
const id_SnapShot = 115; //定义热键标识符

{$R *.dfm}
procedure TfrmMain.WMHotKey(var Msg: TWMHotKey);
var
  H: THandle;
begin
  if Msg.HotKey = id_SnapShot then
  begin
    H := GetSysFocus;
    while IsWindow(H) and (H <> frmMain.Handle) do
    begin
      SendMessage(H,WM_NEXTDLGCTL,0,0);
      H := GetParent(H);
    end;
  end;
end;

function TfrmMain.GetSysFocus: Integer;
var
  hOtherWin,OtherThreadID,hFocusWin:integer;
begin
  hOtherWin:=GetForegroundWindow;
  OtherThreadID:=GetWindowThreadProcessID(hOtherWin,nil);
  if AttachThreadInput(GetcurrentThreadID,OtherThreadID,True) then
  begin
    hFocusWin:=GetFocus;
    result:=GetFocus;
  if HFocusWin<>0 then
  try
  //
  finally
    AttachThreadInput(GetcurrentThreadID,OtherThreadID,False);
  end;
  end
  else result:=GetFocus;
end;

procedure TfrmMain.WMACTIVATEAPP(var Msg: TMessage);
begin
  if Boolean(Msg.WParam) then
    RegisterHotKey(frmMain.Handle, id_SnapShot, 0, VK_TAB)
  else
    UnRegisterHotKey(frmMain.Handle, id_SnapShot);
end;

procedure CallBackProc(ID:Integer); stdcall;
begin
  frmMain.CallPostMessage(ID);
end;

procedure TfrmMain.CallPostMessage(ID: Integer);
begin
 PostMessage(self.Handle, WM_CALLBACK, ID, 0);
end;

procedure TfrmMain.BackCallMessage(var Msg: TMessage);
begin
 if Msg.Msg = WM_CALLBACK then
 begin
   if Msg.WParam = FLibHandle then
   begin
     FreeLibrary(FLibHandle);
     FLibHandle := 0;
   end;
 end;
end;

procedure TfrmMain.mmFileOpenClick(Sender: TObject);
var
 FarPointer : FarProc;
begin
 if FLibHandle = 0 then
 begin
   try
     FLibHandle := LoadLibrary('Project2.dll');
   except
     FLibHandle := 0;
   end;
   if FLibHandle <> 0 then
   begin
     FarPointer  := GetProcAddress(FLibHandle, 'ShowForm');
     FShowForm   := FarPointer;
     FarPointer  :=  GetProcAddress(FLibHandle, 'ActiveForm');
     FActiveForm := FarPointer;
     FarPointer  := GetProcAddress(FLibHandle, 'CloseForm');
     FCloseForm  := FarPointer;
     if Assigned(FShowForm) then
       //FShowForm(Application, @CallBackProc, FLibHandle, self, panel1.Handle);
       List.add(FShowForm(Application, @CallBackProc, FLibHandle, self, panel1.Handle));
   end;
 end
 else
 begin
   if Assigned(FActiveForm) then
   begin
     FActiveForm;
   end;
 end;
end;

procedure TfrmMain.mmFileCloseClick(Sender: TObject);
begin
 if FLibHandle <> 0 then
   FCloseForm;

end;

procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  if FLibHandle <> 0 then
    FCloseForm;
  if assigned(FFrm) then
    FreeAndNil(FFrm);
end;

procedure TfrmMain.mmFileOpenFrmClick(Sender: TObject);
begin
  if not assigned(FFrm) then
  begin
    FFrm := TForm1.Create(nil);
    with FFrm do
    begin
      ParentWindow := panel1.Handle;
      align := alClient;
      BorderStyle := bsNone;
      BorderIcons := [];
    end;
  end;
  FFrm.Show;
end;

procedure TfrmMain.N1111Click(Sender: TObject);
begin
  FFrm.Edit2.Text := 'abc';
 
end;

procedure TfrmMain.Change1Click(Sender: TObject);
begin
  if FFrm.ParentWindow = Panel1.handle then
    FFrm.ParentWindow := Panel2.handle
  else
    FFrm.ParentWindow := Panel1.handle
end;

procedure TfrmMain.FormCreate(Sender: TObject);
begin
  List := TList.Create;
end;

end.
//调用窗体End

//Project2.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. }

uses
  SysUtils,
  Classes,
  Forms,
  Windows,
  Controls,
  Unit2 in 'Unit2.pas' {frmChild},
  Unit1 in 'Unit1.pas' {frmChildCustomer};

{$R *.res}

//function ShowForm(App: TApplication; CallProc: Pointer; CallID: Integer; ParentForm: TForm; ParentContral: HWND): LongInt; stdcall;
function ShowForm(App: TApplication; CallProc: Pointer; CallID: Integer; ParentForm: TForm; ParentContral: HWND): TForm; stdcall;
begin
 Application   := App;
 @FreeProc     := CallProc;
 ProcID        := CallID;

 frmChild      := TfrmChild.Create(ParentForm);
 frmChild.ParentWindow := ParentContral;
 frmChild.Align := alClient;
 frmChild.BorderStyle := bsNone;
 frmChild.BorderIcons := [];
 //SetWindowLong(frmChild.Handle,GWL_STYLE,GetWindowLong(ParentForm.Handle,GWL_STYLE));

 //Result        := Longint(frmChild);
 Result := frmChild;
 frmChild.Show;
 frmChild.BringToFront;
end;

function ActiveForm: LongInt; stdcall;
begin
 if Assigned(frmChild) then
 begin
   frmChild.BringToFront;
   frmChild.SetFocus;
 end;
 Result := 0;
end;

function CloseForm: LongInt;stdcall;
begin
 if Assigned(frmChild) then
 begin
   frmChild.Close;
 end;
 Result := 0;
end;

exports
 ShowForm,  ActiveForm,  CloseForm;

{Dll Entry Point}
procedure ExitDll(Reason: Integer);
begin
 if Reason = DLL_PROCESS_DETACH then // detaching from process
 begin
   // restore application
   Application := DllApp;
 end;
end;

begin
 // backup application
 DllApp  := Application;
 DllProc := @ExitDll;
end.

 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, cxStyles, cxCustomData, cxGraphics, cxFilter, cxData,
  cxDataStorage, cxEdit, DB, cxDBData, cxGridLevel, cxClasses, cxControls,
  cxGridCustomView, cxGridCustomTableView, cxGridTableView,
  cxGridDBTableView, cxGrid, ExtCtrls, dxBar, cxLookAndFeels, dxSkinsForm;

type
  TFreeProc = procedure (ProcID: Integer); stdcall;

  TfrmChildCustomer = class(TForm)
    dxBarManager1: TdxBarManager;
    dxBarManager1Bar1: TdxBar;
    dxBarButton1: TdxBarButton;
    dxBarButton2: TdxBarButton;
    dxBarButton3: TdxBarButton;
    dxBarButton4: TdxBarButton;
    dxBarButton5: TdxBarButton;
    dxBarButton6: TdxBarButton;
    dxBarButton7: TdxBarButton;
    Panel1: TPanel;
    cxGrid1DBTableView1: TcxGridDBTableView;
    cxGrid1Level1: TcxGridLevel;
    cxGrid1: TcxGrid;
    dxSkinController1: TdxSkinController;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormDestroy(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  frmChildCustomer: TfrmChildCustomer;
  FreeProc   : TFreeProc;     //if childform is free(close), notify parent process
  ProcID     : Integer;       //handle that is loaded from parent process
  DllApp        : TApplication;  //a copy of dll application

implementation

{$R *.dfm}


procedure TfrmChildCustomer.Button1Click(Sender: TObject);
begin
  close;
end;

procedure TfrmChildCustomer.FormClose(Sender: TObject;
  var Action: TCloseAction);
begin
  Action := caFree;
end;

procedure TfrmChildCustomer.FormDestroy(Sender: TObject);
begin
  if Assigned(@FreeProc) then
    FreeProc(ProcID);
end;

end.
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Unit1;

type

  TfrmChild = class(TfrmChildCustomer)
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  frmChild: TfrmChild;

implementation

{$R *.dfm}

end.

 

分享到:
评论

相关推荐

    Delphi创建Dll和调用Dll示例(包含Dll窗体调用)

    Delphi创建Dll和调用Dll示例(包含Dll窗体调用) 网上介绍比较杂乱,特地整理了一份Demo代大家学习参考。 1.socketA_dll 为dll工程目录。 2.LoadDllDemo 为【静态调用】dll工程目录。 3.LoadDllDemo_动态调用 为...

    调用DLL中窗体相关演示源码.rar_DLL 窗体_delphi dll窗体_delphi调用dll_dll窗体

    本资源“调用DLL中窗体相关演示源码.rar_DLL 窗体_delphi dll窗体_delphi调用dll_dll窗体”是一个与Delphi编程相关的示例,它演示了如何在DLL(动态链接库)中创建和使用窗体,并且展示了如何从Delphi主应用程序中...

    主程序调用打开DLL窗体,DLL窗体发消息控制主程序

    本文将深入探讨“主程序调用打开DLL窗体,DLL窗体发消息控制主程序”这一主题,以及如何实现这个过程。 首先,我们需要理解DLL的基本概念。DLL是一种包含可由多个程序同时使用的函数和资源的库。它允许多个应用程序...

    DLL窗体的创建与调用

    在进行DLL窗体调用时,要确保DLL和调用程序的兼容性,包括平台、位数(32位或64位)以及Delphi版本。另外,调试DLL可能会比较复杂,因为需要同时调试主程序和DLL,可能需要利用Delphi的远程调试功能或者日志记录来...

    Delphi XE2+Dev 主窗体Panle嵌入DLL窗体源码

    Delphi XE2+Dev 主窗体Panle嵌入DLL窗体源码是一个关于在Delphi XE2集成开发环境中实现动态链接库(DLL)窗体与主程序窗体集成的技术示例。这个源码提供了如何将DLL中的窗口组件无缝嵌入到主应用程序的Panel控件中的...

    DELPHI 简单调用DLL窗体源码

    DELPHI简单调用DLL窗体源码是一个关于在Delphi编程环境中,如何创建和使用动态链接库(DLL)来实现窗体交互的实例。在Windows应用程序开发中,DLL是一种非常重要的技术,它允许多个程序共享同一块内存空间中的代码和...

    delphi 从外部Dll中调用子窗体

    本文将深入探讨如何在Delphi中从外部DLL调用子窗体,以及涉及的相关知识点。 首先,理解DLL的基本概念是必要的。DLL是一种可执行文件格式,它包含可被多个程序同时使用的函数和资源。通过使用DLL,开发者可以减少...

    简单调用DLL窗体源码.rar

    本资源“简单调用DLL窗体源码.rar”显然是一个Delphi编程相关的示例,它展示了如何在Delphi应用中调用DLL中的函数来实现特定功能。下面我们将深入探讨Delphi与DLL交互的关键知识点。 1. **DLL的基本概念**:DLL是...

    调用DLL中窗体相关源码

    "调用DLL中窗体相关源码"的主题涉及Windows编程,特别是使用C++、C#或VB.NET等语言时如何通过DLL来创建和控制用户界面(UI)元素,比如窗口(Window)。 1. DLL的基本概念: DLL文件包含可执行代码和数据,可以被多...

    带参的dll窗体制作与调用源码

    在提供的"delphi_dll窗体调用_源文件"中,我们可以看到Delphi语言的实现。Delphi是一种面向对象的Pascal方言,它具有强大的Windows API和VCL(Visual Component Library)支持,非常适合创建DLL窗体。源代码应该包含...

    DLL封装窗体 ,通过调用DLL打开

    标题“DLL封装窗体,通过调用DLL打开”指的是将窗体(通常在GUI应用程序中)的实现封装到一个DLL文件中,然后在需要时通过调用该DLL来显示和操作这些窗体。这种方式有助于代码重用和模块化,同时可以减少应用程序的...

    从外部Dll中调用子窗体

    在Windows编程中,有时我们需要在外部动态链接库(DLL)中操作或调用应用程序的子窗体。这个过程涉及到进程间通信(IPC)和Windows API的深入理解。本文将详细探讨如何实现“从外部Dll中调用子窗体”的技术。 首先...

    C++ Builder MDI 调用 DLL 子窗体(基于 BCB2010)

    本篇文章将深入探讨如何在C++ Builder 2010中调用DLL(动态链接库)来实现MDI子窗体的创建和交互。 首先,我们需要了解DLL的作用。DLL是一种共享代码的机制,它可以被多个应用程序同时调用,减少了内存占用并提高了...

    简单的dll 窗体文件操作

    在"简单delphi_窗体调用"的压缩包文件中,可能包含了示例代码,包括DLL项目的源码和主应用程序的源码。通过研究这些代码,你可以更好地理解如何在实际项目中实现DLL窗体的调用。 总结来说,"简单的dll 窗体文件操作...

    动态调用DLL中窗体源码.zip_DLL 窗体_goneiqq_prjmain.exe_动态调用DLL中窗体源码

    这个项目展示了如何在实际工程中应用动态调用DLL窗体的方法。 总结来说,这个压缩包包含的源码示例主要教我们如何将窗体功能封装到DLL中,以便在主程序(prjmain.exe)中动态调用。这对于大型软件项目尤其有用,...

    delphi 调用dll中的窗体

    本篇文章将深入探讨如何在Delphi中调用DLL中的窗体,并以"Project"和"dll"这两个文件夹中的示例为参考。 首先,我们来理解DLL的工作原理。DLL文件包含了可执行代码和数据,这些资源可以在运行时被多个程序加载和...

    让VB可以调用DLL控件中的窗体为MDI子窗体

    下面将详细介绍如何实现VB调用DLL控件中的窗体作为MDI子窗体。 首先,我们要创建一个标准的ActiveX DLL工程。ActiveX DLL是可以在不同应用程序之间共享的组件,它包含了可以被其他程序调用的函数和方法。设置工程名...

    Delphi 封装窗体成DLL

    综上所述,"Delphi 封装窗体成 DLL" 主要是通过创建 DLL 工程,编写导出函数来显示和管理窗体,然后在主应用程序中调用这些函数,实现窗体的跨进程使用。这种方法可以有效地减少代码重复,提高软件的可维护性。通过...

Global site tag (gtag.js) - Google Analytics