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 |
多谢! |