热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

dll释放时主程序最小化的问题解决

遇到了好几次了,在dll是调用窗体时,一关闭这个窗体(dll也就释放了),程序就最小化到任务栏了,

遇到了好几次了,在 dll 是调用窗体时,一关闭这个窗体(dll也就释放了),程序就最小化到任务栏了,在网上看到好多人都遇到过,今天问算是解决了

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

调用程序:

unit useDll;

interface

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

type
  TcrForm=function (const aHandle:THandle):pchar;stdcall;
  TDllE=class(exception);
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
     libHandle:THandle;
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  crForm:Tcrform;
begin
  libHandle:=windows.LoadLibrary('project1.dll');
  if (libHandle=0) or (libHandle=INVALID_HANDLE_VALUE) then
  begin
    TDlle.Create('load error');
    Exit;
  end;
  @crForm:=windows.GetProcAddress(libHandle,'crForm');
  if not (@crForm=nil) then
    crForm(application.Handle)
  else
    sysutils.RaiseLastWin32Error;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  if (libHandle<>0) and (libHandle<>INVALID_HANDLE_VALUE) then
  begin 
    windows.FreeLibrary(libHandle);
    libHandle:&#61;0;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  libHandle:&#61;0;
end;

end.

DLL程序。

library Project1;

uses
  SysUtils,
  Classes,
  forms,
  windows,
  dialogs,
  Unit1 in &#39;Unit1.pas&#39; {Form1};

//{$R *.res}
 //用了出口入口函数

procedure DllEntry(dllReason:dword);
begin
  case dllReason of
    windows.DLL_PROCESS_ATTACH:
    begin
    end;
    windows.DLL_PROCESS_DETACH:
    begin
      if fm<>nil then//再注意这里。
        fm.Free;
      Application.Handle:&#61;0;//注意这里。。。。
    end;
  end;// end case
end;

function crForm(const aHandle:THandle):pchar;stdcall;
begin
  application.Handle:&#61;aHandle;
  fm:&#61;tform1.Create(nil);
  result:&#61;pchar(&#39;ok&#39;);
  fm.Show;
end;

exports
  crForm;

begin
  dllProc:&#61;&#64;dllEntry;
  dllEntry(windows.DLL_PROCESS_ATTACH);
end.

unit Unit1;

interface

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

type
  TForm1 &#61; class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  fm:tform1 &#61; nil;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  Close;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action:&#61;caFree;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  fm:&#61;nil;
end;

end.

//&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;


至于为什么加了Application.Handle:&#61;0;就没有问题了&#xff0c;那得从Forms单元中TApplication对象的源码说起。 [609字节 aizb 2006-3-7 23:27:37 回复:0/3 版块:Delphi 系统及网络]
在Forms单元中我们可以看到TApplication对象的全部源码。不知道是不是Delphi的BUG&#xff0c;在TApplication创建的时候&#xff0c;我们知道程序作了一个判断&#xff1a;
  if not IsLibrary then CreateHandle;
就是说如果是当前程序不是运态链接库&#xff0c;则创建应用程序句柄&#xff0c;实际上是创建了一个大小为0,0的窗口。
而在释放的时候的判又是&#xff1a;
  if (FHandle <> 0) and FHandleCreated then
  begin
    if NewStyleControls then SendMessage(FHandle, WM_SETICON, 1, 0);
    DestroyWindow(FHandle);
  end;
也就是说无论是不是动态链接库&#xff0c;只有Application对象的Handle值不为0&#xff0c;并且FHandleCreated为True&#xff0c;都会执行到DestroyWindow函数&#xff0c;而DestroyWindow函数的执行将导致主应用程序中的Application对象创建的大于为0,0窗口失去句柄&#xff0c;一个窗口失败句柄会发生什么就未可知了。


不过说实话&#xff0c;我没有花时间去找FHandleCreated是在哪里赋值的&#xff0c;所以也许上面的解答也许是不正确的&#xff0c;也许是其他的问题&#xff0c;但是可以肯定的是跟Application.Handle有关。


仔细看了一下源码&#xff0c;发现2楼的回复是错误的&#xff0c;如果是动态链接库&#xff0c;FHandleCreated将始终为False&#xff0c;if (FHandle <> 0) and FHandleCreated then根本不会满足。 [242字节 aizb 2006-3-7 23:42:19 回复:0/4 版块:Delphi 系统及网络]
所以问题不在这里&#xff0c;经过分析&#xff0c;发现问题在Forms单元的finalization段中的一句&#xff1a;
if Application <> nil then DoneApplication;
DoneApplication函数中又有下面一句&#xff1a;
    if Handle <> 0 then ShowOwnedPopups(Handle, False);
再看看MSDN中对ShowOwnedPopups的介绍&#xff0c;它的作用是显示或隐藏由指定窗口所有的全部弹出式窗口。好了问题就是它了&#xff0c;结案。


十分感谢艾老师对我的帮助
看了艾老师的但当时还没有解决&#xff0c;原因是 d6 里有 bug &#xff0c;dll 的出口并没有执行。

另一种方式是传 handle 而不是传 application.handle


推荐阅读
  • FroggerTimeLimit:1000MSMemoryLimit:65536KTotalSubmissions:32257Accepted:10396DescriptionFr ... [详细]
  • IamusingmaterialDateTimepickerformyAndroidapp.ButIwanttocombinetheDateandTimepic ... [详细]
  • 1011-MarriageCeremoniesPDF(English)StatisticsForumTimeLimit:2second(s)MemoryLimit:32MBYouw ... [详细]
  • C#制作TextBox水印提示
    前言在使用C#的TextBox控件时,有时候会有以下需求:在用户没有输入文字时,TextBox有提示文字,如下图所示 ... [详细]
  • String字符串java.lang;基本标识Java字符串的一个重要特点就是字符串不可变。finalclassString没有子类字符串字面量也是一个String类的实例存储在字 ... [详细]
  • 22.Container With Most Water(能装最多水的容器)
    thecontainercontainsthemos ... [详细]
  • 2019.4.14第1001题:SumProblemProblemDescriptionHey,welcometoHDOJ(HangzhouDianziUniversityOnli ... [详细]
  • SortalinkedlistinO(nlogn)timeusingconstantspacecomplexity.这道题属于人生中第一次对链表进行操作,首先,不同于C++中的st ... [详细]
  • react里可以但是vue我不熟悉,没找到App.vue是父`这里我想加载导航这是路由 ... [详细]
  • IPVlan 详解
    文章目录简介Ipvlan2同节点Ns互通Ns内与宿主机通信第三种方法Ns到节点外部结论Ipvlan31.同节点Ns互通Ns内与宿主机通信Ns内到外部网络总结源码分析ipvlan收包 ... [详细]
  • 883.三维形体投影面积
    题目883.三维形体投影面积题目大意在nxn的网格grid中,我们放置了一些与x,y,z三轴对齐的1x1x1立方体。每个值vgri ... [详细]
  • JavaBean和Map 转换 用反射方法实现
    由于JavaBean(实体类)结构与Map类似,我们可以把JavaBean与Map进行转换 ... [详细]
  • iOS8之后系统把UIActionSheet和UIAlertView合并为了UIAlertController,使用就不比多说了,但在使用的过程中发现样式是固定的,点 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 超级简单加解密工具的方案和功能
    本文介绍了一个超级简单的加解密工具的方案和功能。该工具可以读取文件头,并根据特定长度进行加密,加密后将加密部分写入源文件。同时,该工具也支持解密操作。加密和解密过程是可逆的。本文还提到了一些相关的功能和使用方法,并给出了Python代码示例。 ... [详细]
author-avatar
A因为爱情Q_860
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有