有一用Delphi做成的现成系统,我手头只有可执行程序,没有源代码,也没有文档,该系统有很多的BPL文件,我现在需要调用一下该系统的功能,我如何去着手?怎样分析这些BPL文件,还有如何调用里面的函数,类啊什么的??大家帮忙提供一下思路。。
解决方案 »
- 求助高人-----------关于动态生成的Shape的问题?
- 字符串转换为窗体控件类时碰到的问题
- 奇怪的语法有误,有大家帮忙看看,谢谢!
- 发分!
- 高手們快快進來!!!急急.......(圖象多及媒體)
- 奇怪!我的DELPHI5怎么了???????
- 为什么所有应用程序都打不开(直接双击应用程序)?
- 怎样调用外部程序?
- 请问可不可以不添加ODBC数据源名而用Database控件连接Access数据库,怎么连?
- 初学问题,关于MIDAS,为什么出这种错?
- 那位达人知道CB6的TNMStrm控件与CB2007的那个控件功能相似?
- 怎样使treeview双击的时候下级节点仍然保持展开状态和怎样使父级节点图标显示正常?
主要是这部分Dynamically loaded BPLsBPLs are just as simple. Well almost.We dynamically load the package by using the LoadPackage function.function LoadPackage(const Name: string): HMODULE;We create TPersistentClass of the class we wish to instantiate by using the GetClass function.function GetClass(const AClassName: string):
TPersistentClass;Instantiate an object of the loaded class and use it.And when we are done, unload the package using the UnloadPackage procedure.procedure UnloadPackage(Module: HMODULE);Let us go back to our example and make a few changes: 1. Select "Project1.exe" from the project manager.
2. Right-click and select "Options..."
3. Select the "Packages" tab.
4. Remove "Package1" from the "Runtime packages" edit-box section and OK the options.
5. On Delphi's toolbar, click on the "Remove file from project" button.
6. Select "Unit2 | Form2" from the list and then "OK."
7. Now go to the "Unit1.pas" source and remove Unit2 from its uses clause. (These steps are required to remove any link to Unit2 and the package we wish to load dynamically.)
8. Go to the source of Button1's OnClick event.
9. Add two variables of type HModule and TPersistentClass. var
PackageModule: HModule;
AClass: TPersistentClass; 10. Load the package Package1 by using the LoadPackage function. PackageModule := LoadPackage('Package1.bpl'); 11. Check that the Package Module is not 0 (zero).
12. Create a persistent class using the GetClass function, passing it the name of the form within the package as its parameter: AClass := GetClass('TForm2'); 13. If the persistent class is not nil, create and use an instance of the class just a before. with TComponentClass(AClass).Create(Application)
as TCustomForm do
begin
ShowModal;
Free;
end; 14. Finally, unload the package using the UnloadPackage procedure: UnloadPackage(PackageModule); 15. Save the project.Here is the complete listing of the OnClick event:procedure TForm1.Button1Click(Sender: TObject);
var
PackageModule: HModule;
AClass: TPersistentClass;
begin
PackageModule := LoadPackage('Package1.bpl');
if PackageModule <> 0 then
begin
AClass := GetClass('TForm2'); if AClass <> nil then
with TComponentClass(AClass).Create(Application)
as TCustomForm do
begin
ShowModal;
Free;
end; UnloadPackage(PackageModule);
end;
end;Unfortunately that's not the end of it.The problem is that the GetClass function requires the class to be registered before the function can find it. Usually form classes and component classes that are referenced in a form declaration (instance variables) are automatically registered when the form is loaded. But the form isn't loaded yet. So where should we register the class? The answer: in the package. Each unit in the package is initialized when the package is loaded and finalized when the package is unloaded.Let's return to our example and make a few changes: 1. Double-click on "Package1.bpl" in the project manager; this will activate the package editor.
2. Click on the + symbol next to "Unit2" in the "Contains" section. This will expand the unit tree.
3. Double-click on "Unit2.pas" to activate the unit's source code.
4. Scroll down to the end of the file and add an initialization section.
5. Register the form's class using the RegisterClass procedure: RegisterClass(TForm2); 6. Add a finalization section.
7. Un-register the form's class using the UnRegisterClass procedure: UnRegisterClass(TForm2); 8. Finally, save and compile the package.Now we can safely run the "Project1" application - it will function just as before, but with the added benefit of being able to load the package when you want to.
FinallyMake sure you compile any project that uses packages (static or dynamic) with runtime packages turned on: "Project | Options | Packages | Build with runtime packages."You must be careful that when you unload a package you destroy any objects using those classes and un-register any classes that were registered.This procedure may help:procedure DoUnloadPackage(Module: HModule);
var
i: Integer;
M: TMemoryBasicInformation;
begin
{ Make sure there aren't any instances of any
of the classes from Module instantiated, if
so then free them. (This assumes that the
classes are owned by the application) } for i := Application.ComponentCount - 1 downto 0 do
begin
VirtualQuery(
GetClass(Application.Components[i].ClassName),
M, SizeOf(M));
if (Module = 0) or
(HMODULE(M.AllocationBase) = Module) then
Application.Components[i].Free;
end;
UnRegisterModuleClasses(Module);
UnLoadPackage(Module);
end;An application requires "knowledge" of the registered class names prior to loading the package. One way to improve this would be to create a registration mechanism to inform the application of all the class names registered by the package.