捐赠 | 广告 | 注册 | 发布 | 上传 | 关于我们    
  沪ICP备05001939号 DELPHI盒子 | 盒子论坛 | 盒子文章 | 盒子问答悬赏 | 最新更新 | 论坛检索 | 下载中心 | 高级搜索    
  精品专区 | 繁體中文 | 奖励公告栏 | 直通车账号登陆 | 关闭GOOGLE广告 | 临时留言    
 
广告
评论:Delphi程序启动技术概要
legend888888 34884 2008/7/7 14:43:34
very good
340340 21388 2006/2/7 8:55:51
感谢你的开源精神,向你们学习。
yuqing2099 19803 2005/12/7 22:43:44
直接转换居然通过了!
TApplication(WinInstance).ExeName
newshenliang 19477 2005/11/24 9:05:32
to shadowrain:
  我理解在项目中使用运行期包主要有几点好处:
  可以使用自己创建的包实现EXE和DLL之间共享内存、类、对象和公共全局变量等,这样为实现插件式开发提供了很多方便,这是使用运行期包的最主要原因。
  使用运行期包也可以大大减小EXE和DLL的大小,只需要发布特定的几个包,这样使多DLL构成的程序发布和更新方便很多!
shadowrain 19444 2005/11/23 15:38:12
to newshenliang:
    真的是非常抱歉,这几天没有时间上来看,非常感谢大家关心这个小例子。
    对于运行时包我想说几句。第一,在运行时包下编译后的程序和正常情况下编译后的程序的运行方式是完全不一样的。做个实验:随便编译一个程序,在Application.Initialize处设断点,然后查看CPU窗口的第三行,你会发现Application调用Initialize方法是完全不同的,正常情况是直接调用Call TApplication.Initialize,在运行时包是通过方法的地址调用。第二,由于执行流程不一样,所以在列举窗口的回调函数里的这一句的
WinInstance := GetWindowLong(hwnd, GWL_HINSTANCE);  //注意那个hwnd这个句柄是Application的句柄
在运行包时是Application这个对象的句柄,Application全局对象存在于vcl70.bpl中的,所以取模块长文件名会取到vcl70.bpl的路径。
    第三,我本人也是刚入门,没学过多少东西,都是瞎写写。我不太理解为什么要运行时包,特别是当你勾选了运行时包后,你必须同时发布在编辑框里所有的bpl包,甚至vcl7?0.bpl等等一大堆。你可以试一下,一个Hello World的程序在选运行包的情况下编译,单独把EXE文件放到干净的环境中运行,看能否正常运行?请有哪位朋友给解释解释。
    以上只是问题的原因讨论,解决方案我现在还没有时间弄。不过我简单看了一下刘麻子的方法,可能照猫画虎差不多吧。
    现在要干活了,希望有兴趣的朋友与我保证沟通、讨论。
    QQ:50038490
    MSN:shadowrain2008@hotmail.com
newshenliang 19433 2005/11/23 10:15:30
to liumazi:
  看了你推荐的网址,应该就是这个问题,因为我的程序中也用到了包来共享内存和全局变量。结果获取类所在模块名取到了vcl70.bpl而不是EXE,看了你写的三个函数,想尝试改一下,但是水平太低,没改出来!还请帮忙改一下上面的函数!

  同时帖出shadowrain调用部分的代码,想不透为什么获取当前模块名时取到的是EXE,是正确的?

  最后还是要感谢shadowrain、liumazi,向你们学习!

    {20 获取当前模块名 }
    SetLength(ModuleName, 200);
    GetModuleFileName (HInstance, PChar(ModuleName), Length (ModuleName));
    ModuleName := PChar(ModuleName); // 调整长度
    ShowMessage(ModuleName);  {这里获取到的模块是EXE,是正确的}
    {30 列表最初实例的窗口 }
    EnumWindows(@EnumWndProc, 0);
    if FoundWnd <> 0 then
    begin
      {40 最后显示最初实例的窗口 }
      if not IsWindowVisible(FoundWnd) then
        PostMessage(FoundWnd, wm_App, 0, 0);
      SetForegroundWindow(FoundWnd);
    end;
newshenliang 19431 2005/11/23 10:03:24
to shadowrain:
  我说的带包运行是指带运行期包运行,就是project->Options->Package->选中Build with runtime packages  然后再编译运行,这样回调函数列举的模块就变成了vcl70.bpl


function EnumWndProc(hwnd: THandle; Param: Cardinal): Bool; stdcall;
var
  ClassName, WinModuleName: string;
  WinInstance: THandle;
begin
  Result := True;
  SetLength(ClassName, 100);
  GetClassName (hwnd, PChar (ClassName), Length (ClassName));
  ClassName := PChar(ClassName);
  if ClassName = TfrmMain.ClassName then  
  begin
    ShowMessage(ClassName);{ ???不知道为什么总是出现三次?}
    {10 获取目标窗口的模块名 }
    SetLength(WinModuleName, 200);
    WinInstance := GetWindowLong(hwnd, GWL_HINSTANCE);
    GetModuleFileName (WinInstance, PChar (WinModuleName),
      Length(WinModuleName));
    WinModuleName := PChar(WinModuleName); // 调整长度
    showmessage(ModuleName+WinModuleName);{???这时WinModuleName总是vcl70.bpl}
    {20 比较模块名 }
    if WinModuleName = ModuleName then
    begin
      FoundWnd := Hwnd;
      Result := False; // 如果已找到,停止继续列举
    end;
  end;
end;
liumazi 19373 2005/11/21 23:11:26
to newshenliang: 你说的问题,是否类似于:http://www.delphibbs.com/delphibbs/dispq.asp?lid=3128578 ?
shadowrain 19356 2005/11/21 17:37:26
非常遗憾,我试着在winrar环境下打开EXE文件,但没有出现newshenliang 兄提到的BUG啊?
注册自定义消息?这个东西又不会重用,为什么还要再定义一个消息呢?太多没有必要的封装可能会导致可读性下降,我个人理解。
newshenliang 19343 2005/11/21 11:08:23
据说注册自定义消息是最简单快捷的方法,不知改怎样实现,那位高手可以指点一下!
newshenliang 19341 2005/11/21 10:50:47
非常好,非常感谢!
有点小问题不知怎样解决好,我的exe是带包运行的,回调函数列举的模块是vcl70.bpl而不是主窗体,结果无法重新显示主窗体,还请高手帮忙!
jmwl77 19324 2005/11/20 21:34:54
不错,顶一下~
masm 19303 2005/11/19 8:56:04
多谢!
第一页 上一页 下一页 最后页 有 13 条纪录 共1页 1 - 13
 用户名:
 密 码:
自动登陆(30天有效)
 
  DELPHI盒子版权所有 1999-2023 V4.01 粤ICP备10103342号-1 更新RSS列表