问题如下:
1.我在DLL中生成了查询,怎么样在BUTTION中(生成报表)
调用其报表窗口并且又怎么传送主调窗口的参数
2.怎样创建其窗口(我已建,不知怎么调用)
3.出错信息
access violation at address 00324cf1 in modul 'ybymzs.dll',read of
address 0000035c
1.我在DLL中生成了查询,怎么样在BUTTION中(生成报表)
调用其报表窗口并且又怎么传送主调窗口的参数
2.怎样创建其窗口(我已建,不知怎么调用)
3.出错信息
access violation at address 00324cf1 in modul 'ybymzs.dll',read of
address 0000035c
我的理解:
主窗体和DLL窗体的工程选项都要编译成运行期包,在Project\Option\Package
"Build runtime package"之类的复选框。LoadLibrary('<your DLL path>\ybymzs.dll');
proc:= GetProcAddress('<Function Name>') ;
Proc(<parameter>);
////////////////////////////////
(1)MDIChildDLL.cpp
#include <vcl.h>
#include <windows.h>
#pragma hdrstop
#include "MDIChild.h"
#include "SDIForm.h"#pragma argsused
TApplication *ThisApp = NULL;
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
if ( (reason == DLL_PROCESS_DETACH) && (ThisApp) )
Application = ThisApp;
return 1;
}extern "C" void __declspec(dllexport)ShowMDIChildForm(TApplication *CallingApp);void ShowMDIChildForm(TApplication *CallingApp)
{
if (!ThisApp)
{
ThisApp = Application;
Application = CallingApp;
}
Child = new TChild(Application);
Child->Show();
}extern "C" void __declspec(dllexport)ShowMyForm(void);void ShowMyForm(void)
{
MyForm = new TMyForm(NULL);
MyForm->ShowModal();
delete MyForm;
}
/////////////////////////////////////////
///////////////////////////////////////////
(2)MDIChild.h
#ifndef MDIChildH
#define MDIChildH#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>class TChild : public TForm
{
__published: // IDE-managed Components
TLabel *Label1;
void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
private: // User declarations
public: // User declarations
__fastcall TChild(TComponent* Owner);
};extern PACKAGE TChild *Child;#endif
///////////////////////////////////////////////
///////////////////////////////////////////////
(3)MDIChild.cpp
#include <vcl.h>
#pragma hdrstop#include "MDIChild.h"#pragma package(smart_init)
#pragma resource "*.dfm"
TChild *Child;__fastcall TChild::TChild(TComponent* Owner)
: TForm(Owner)
{
}void __fastcall TChild::FormClose(TObject *Sender, TCloseAction &Action)
{
Action = caFree;
}
///////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
(4)ParentForm.h 调用dll的例子的头文件
#ifndef ParentFormH
#define ParentFormH#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <Menus.hpp>class TParent : public TForm
{
__published: // IDE-managed Components
TMainMenu *MainMenu1;
TMenuItem *File1;
TMenuItem *New1;
TMenuItem *Exit1;
TMenuItem *NewPackage1;
TMenuItem *ShowSDIForm1;
void __fastcall New1Click(TObject *Sender);
void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
void __fastcall NewPackage1Click(TObject *Sender);
void __fastcall ShowSDIForm1Click(TObject *Sender);
private: // User declarations
HINSTANCE Dll;
Windows::HINST Package;
public: // User declarations
__fastcall TParent(TComponent* Owner);
};
extern PACKAGE TParent *Parent;
#endif
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
(5)ParentForm.cpp 具体调用代码
#include <vcl.h>
#pragma hdrstop#include "ParentForm.h"#pragma package(smart_init)
#pragma resource "*.dfm"
TParent *Parent;__fastcall TParent::TParent(TComponent* Owner)
: TForm(Owner)
{
Dll = NULL;
Package = NULL;
}void __fastcall TParent::New1Click(TObject *Sender)
{
typedef void __declspec(dllimport)ShowChildType(TApplication *);
ShowChildType *ShowMDIChild; if (!Dll)
Dll = LoadLibrary("MDIChildDLL.dll"); if (Dll)
{
// Get the address of the function.
ShowMDIChild = (ShowChildType *)GetProcAddress
(Dll, "_ShowMDIChildForm");
if (ShowMDIChild)
ShowMDIChild(Application);
else
{
ShowMessage(SysErrorMessage(GetLastError()));
FreeLibrary(Dll);
} }
else
{
ShowMessage(SysErrorMessage(GetLastError()));
ShowMessage("Unable to load the DLL");
}
}void __fastcall TParent::FormClose(TObject *Sender, TCloseAction &Action)
{
while (MDIChildCount)
MDIChildren[0]->Free(); if (Dll)
FreeLibrary(Dll);
if (Package)
UnloadPackage(Package);
}void __fastcall TParent::NewPackage1Click(TObject *Sender)
{
typedef void __declspec(dllimport)ShowChildPkType(void);
ShowChildPkType *ShowPackageChild;
if (!Package)
Package = LoadPackage("MDIChildPackage.bpl");
if (Package)
{
ShowPackageChild = (ShowChildPkType *)GetProcAddress
(HINSTANCE)Package, "_ShowMDIChildPkForm");
if (ShowPackageChild)
ShowPackageChild();
else
{
ShowMessage(SysErrorMessage(GetLastError()));
UnloadPackage(Package);
} }
else
{
ShowMessage(SysErrorMessage(GetLastError()));
ShowMessage("Unable to load the Package");
}
}void __fastcall TParent::ShowSDIForm1Click(TObject *Sender)
{
typedef void __declspec(dllimport)ShowSDIType(void);
ShowSDIType *ShowSDIForm; if (!Dll)
Dll = LoadLibrary("MDIChildDLL.dll"); if (Dll)
{
ShowSDIForm = (ShowSDIType *)GetProcAddress
(Dll, "_ShowMyForm");
if (ShowSDIForm)
ShowSDIForm();
else
{
ShowMessage(SysErrorMessage(GetLastError()));
FreeLibrary(Dll);
} }
else
{
ShowMessage(SysErrorMessage(GetLastError()));
ShowMessage("Unable to load the DLL");
}
}
////////////////////////////////////////////////////////////////
在DLL中放置MDI子窗体一般碰到的问题是该子窗体不能找到它的父窗体,所以你就必须欺骗DLL认为它是包含了父窗体的应用程序的一部分。关键就是:
void ShowMDIChildForm(TApplication *CallingApp)
{
if (!ThisApp)
{
ThisApp = Application;
Application = CallingApp;
}
Child = new TChild(Application);
Child->Show();
}
和
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
if ( (reason == DLL_PROCESS_DETACH) && (ThisApp) )
Application = ThisApp;
return 1;
}