DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: webb123
今日帖子: 36
在线用户: 20
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 jupt (jupt) ★☆☆☆☆ -
普通会员
2014/8/29 8:53:59
标题:
动态调用dll内封装的窗体发现从exe传入任何handle到dll内部handle值变了,搜索很久发现网上没有类似相关资料,请大家帮着指导分析下 浏览:1497
加入我的收藏
楼主: 这个问题一直困扰好多时候了,一直卡着没有解决,无法使用Dll封装窗体。我想使用动态加载dll调用非模式窗体,看了很多教程,都是早几年的,我用的是delphi XE5。
按照网上实例做了(最简单的那种,仅显示无任何代码封装的窗体),一直报错,我跟踪了下,发现在dll窗体内我不把exe传进来的AppHandle赋值到Application.handle就可以用TForm.Create(Application)生成,一赋值报无效的句柄,再查传入前Exe的Application.handle与Dll内传入参数handle不一样,这是什么情况?
请高手们帮忙解答,哎,做了很多实验,一直没有解决,网上也没有新出来的教程实例,都是一些老文章,没有Delphi XE5平台下的文章(我都怀疑是否Delphi平台问题引起的)

下面是我的源码
Dll工程文件:

library mydll;

{ 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,
  Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

//此处也试过把dll里面窗体showform函数放到这里来,问题依旧
//正常情况下这边应该还有一些dll卸载机制以及Dll的Application.handle还原机制,和我发现的问题没有什么太大关系,暂时没有加上去
exports
  showform;
begin
end.


Dll的窗体文件:

unit Unit1;
interface

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

type
  TForm1 = class(TForm)
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  procedure showform(ff:THandle);stdcall;

implementation

{$R *.dfm}

procedure showform(ff: THandle);stdcall;
var
  A: THandle;
begin
  a := Application.Handle;   //默认这个A值竟然是exe的application.handle
  Application.Handle := ff;  //传递进来的ff竟然不等于exe的application.handle,很无奈,颠覆了我学到的Dll的知识,但是又发现网上竟然没有类似的问题
  Form1:=TForm1.Create(Application);
  Form1.Show;
end;
end.

exe文件的源码:

unit Unitmain;
interface

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

type
  TForm1 = class(TForm)
    btn1: TButton;
    procedure btn1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation
uses Math;

{$R *.dfm}

procedure TForm1.btn1Click(Sender: TObject);
var
  showform: procedure(ff: THandle);
  hnd: THandle;
begin
  hnd := LoadLibrary(PChar('mydll.dll'));
  if hnd>0 then
  begin
    @showform := GetProcAddress(hnd,PChar('showform'));
    if @showform <> nil then
        showform(Application.Handle);
  end;
end;

end.
----------------------------------------------
-
作者:
男 o_o (友谊长存) ★☆☆☆☆ -
盒子活跃会员
2014/8/29 9:54:55
1楼: 有代码就是空易找问题,是调用写错了
var
  showform: procedure(ff: THandle);stdcall;//加上

----------------------------------------------
生活在于创新,生命在于感情
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2014/8/29 10:04:52
2楼: 1 楼很仔细,让我知道了 DLL 、 EXE、DELPHI 、XE5 和 XE6 等 还是可以信任的。谢谢。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 pengshaomin (我爱编程) ★☆☆☆☆ -
普通会员
2014/8/29 10:16:56
3楼: 推荐用接口
----------------------------------------------
-
作者:
男 jupt (jupt) ★☆☆☆☆ -
普通会员
2014/8/29 10:22:53
4楼: 回复1楼:
谢谢,终于发现问题所在了,实验了一下确实如此
静态调用dll的时候没有问题原来静态的时候已经加了stdcall了。

回复3楼:
谢谢指引,把这个问题解决了,就可以进行下一步学习了
----------------------------------------------
-
作者:
男 ptdelphi (Delphi) ▲▲▲▲△ -
普通会员
2014/8/29 14:46:41
5楼: 不要怀疑是否Delphi平台问题,问题总是能解决的
----------------------------------------------
还可以更好
作者:
男 tree2005 (Hello) ★☆☆☆☆ -
普通会员
2014/8/29 16:25:57
6楼:   这个好像需要查反编译的代码,才可以发现Stdcall和fastcall的区别。
----------------------------------------------
-
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2014/8/29 16:45:15
7楼: 楼上的,书上 百度上 谷歌上都有介绍,何必自己去反编译?
----------------------------------------------
(C)(P)Flying Wang
作者:
男 wr960204 (武稀松) ★☆☆☆☆ -
盒子活跃会员
2014/8/31 12:20:45
8楼: 1000个怀疑Delphi平台有问题的999个是自己的问题
----------------------------------------------
武稀松http://www.raysoftware.cn
作者:
男 tree2005 (Hello) ★☆☆☆☆ -
普通会员
2014/9/1 11:48:26
9楼: To Flying wang,

   人家是这样找到原因的。查Baidu什么的,也是一种方法。不过,没有怀疑到这个关键词,不知道查什么呀。
----------------------------------------------
-
作者:
男 nevergrief (孤独骑士) ★☆☆☆☆ -
盒子活跃会员
2014/9/1 15:56:12
10楼: Dll封装窗体,这是老生常谈的问题了,网上多的是例子啊,何必自己动脑筋?
----------------------------------------------
只有偏执狂才能生存!
作者:
男 lsuper (lsuper) ★☆☆☆☆ -
盒子活跃会员
2014/9/1 16:36:59
11楼: 所有 exe、dll 带 rtl、vcl 吧,否则有你受的,血的教训啊 ~~~
----------------------------------------------
-
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行93.75毫秒 RSS