604
社区成员
发帖
与我相关
我的任务
分享
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, LPVOID lpvReserved)
{
FrmMain=new TFrmMain(NULL);
FrmMain->ShowModal();
}
DllApplication:=Application;
DLLProc := @DLLUnloadProc;
void __fastcall TFrmMain::N1Click(TObject *Sender)
{
Visible=!Visible;
N1->Checked=!N1->Checked;
}
/*
不知道你是不是想实现在主程序中插入子菜单到dll中的某个窗体中呢,如果是这样,请参考下面的代码
*/
/***************************
结构体定义文件
*****************************/
typedef struct TModule{
TMainMenu* TrayMenu;
TForm* MainForm;
} TModule ;
/***********************************************
Project2.dll 源文件
**********************************************/
extern "C" {
void __declspec(dllexport) __stdcall InitializeForm(void);
void __declspec(dllexport) __stdcall UnitializeForm(void);
bool __declspec(dllexport) __stdcall GetInfo( TModule& moudle);
}
bool __stdcall GetInfo( TModule& moudle){
if(!FrmMain || !(FrmMain->TrayMenu) ) return false;
moudle.TrayMenu =FrmMain->TrayMenu ;
moudle.MainForm = FrmMain;
return true;
}
void __stdcall InitializeForm(void){
FrmMain = 0;
FrmMain = new TFrmMain(0);
if(!FrmMain){
throw Exception("create frmMain form failed!");
}
}
void __stdcall UnitializeForm(void){
if(FrmMain){
delete FrmMain;
FrmMain =0 ;
}
}
/*****************************************************************
exe源文件
*****************************************************************/
typedef void __stdcall (*ptrInitializeForm)(void);
typedef void __stdcall (*ptrUnitializeForm)(void);
typedef bool __stdcall(*ptrGetInfo)( TModule& moudle);
HINSTANCE hDLL;
ptrInitializeForm InitializeForm=0;
ptrUnitializeForm UnitializeForm=0;
ptrGetInfo GetInfo=0;
TModule module ;
module.TrayMenu =0 ;
module.MainForm =0 ;
hDLL=::LoadLibrary("Project2.dll");
if (hDLL){
try
{
try
{
InitializeForm=(ptrInitializeForm)::GetProcAddress(hDLL,"InitializeForm");
if(InitializeForm)
InitializeForm();
else
throw Exception("error at function InitializeForm!");
UnitializeForm=(ptrUnitializeForm)::GetProcAddress(hDLL,"UnitializeForm");
if(!UnitializeForm)
throw Exception("error at function UnitializeForm!");
GetInfo=( ptrGetInfo)::GetProcAddress(hDLL,"GetInfo");
if(GetInfo){
GetInfo(module);
TMenuItem *newItem =new TMenuItem(module.TrayMenu);
newItem->Caption="新增菜单";
module.TrayMenu->Items->Add(newItem);
newItem =new TMenuItem(module.TrayMenu);
newItem->Caption="新增菜单子菜单";
module.TrayMenu->Items->Items[0]->Add(newItem);//再在刚加入的菜单下面插入1个子菜单
module.MainForm->ShowModal(); //Show出来,看看是否插入菜单成功了
}
else
throw Exception("error at function GetInfo !");
}
catch(Exception& e){
ShowMessage(e.Message);
}
}
__finally
{
UnitializeForm(); //释放窗体内存
::FreeLibrary(hDLL);//释放库
}
}
/*
在DLL中Application对象就不是真实的Application了
procedure TCustomForm.CreateParams(var Params: TCreateParams);
//....
WndParent := Application.Handle;
//....
所以Application.Handle的值就是0
当创建DLL窗体时,需要把当前运用程序的Application.Handle传递给DLL的Application.Handle
这样操作系统才不会把DLL中的窗体看成是另外一个运用程序的窗体
在释放的时候,需要将DLL中的Application.Handle复原(赋值为0)
这样当窗体关闭的时候系统才不会认为是当前运用程序关闭
*/
class TModLoader : public TThread
{
private:
char* FPath;
protected:
void __fastcall Execute();
public:
__fastcall TModLoader(bool CreateSuspended,char* DllPath);
};
//---------------------------------------------------------------------------
__fastcall TModLoader::TModLoader(bool CreateSuspended,char* DllPath)
: TThread(CreateSuspended)
{
FPath=DllPath;
}
//---------------------------------------------------------------------------
void Load(char* DllPath)
{
TModLoader *Thread;
Thread = new TModLoader(false,DllPath);
// 稍后把 Thread 的句柄放入链表
}
//---------------------------------------------------------------------------
void __fastcall TModLoader::Execute()
{
MessageBox(0,FPath,"",MB_OK);
HINSTANCE hDLL;
pGetInfo GetInfo;
hDLL=LoadLibrary(FPath);
if (hDLL!=0) {
GetInfo=(pGetInfo)GetProcAddress(hDLL,"GetInfo");
if (GetInfo!=NULL) {
TMenuItem *Item;
//Item=FrmMain->PopMenu->Items;
Item = GetInfo().TrayMenu;
FrmMain->P2->Add(Item);
//FrmMain->P2->Items->Insert(0,Item);
}
} else ExitThread(0);
while (!Terminated) {
if (WaitMessage()) {
Application->ProcessMessages();
}
}
}
//---------------------------------------------------------------------------
TModule _export _stdcall GetInfo()
{
TModule Mod;
Mod.TrayMenu=FrmMain->TrayMenu->Items;
Mod.MainForm=FrmMain;
return Mod;
}
#pragma argsused
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, LPVOID lpvReserved)
{
FrmMain=new TFrmMain(NULL);
return 1;
}
typedef TModule __stdcall (*pGetInfo)();
typedef struct TModule{
TMenuItem *TrayMenu;
TForm *MainForm;
} TModule ;
HINSTANCE hDLL;
pGetInfo GetInfo;
hDLL=LoadLibrary((char*)DLLPath);
if (hDLL!=0) {
GetInfo=(pGetInfo)GetProcAddress(hDLL,"GetInfo");
if (GetInfo!=NULL) {
TMenuItem *Item;
Item = GetInfo().TrayMenu;
FrmMain->P2->Add(Item);
// P2为一个TMenuItem
}
} else ExitThread(0);
1, 否
2. Application这个全局的TApplication对象指针是指当前加载dll的那个exe程序的TApplication对象指针
3. 没有demo,dll和exe差不多,就是new->dll wizard .然后往里面加入窗体,再接着code
4. 不清楚你是怎么操作PopMenu的
5. 记住这一点,你不能把一个Visible=true的窗体ShowModal,
通常你设置窗体的Visible=true实质上是在调用该窗体的Show()方法!ShowModal是把窗体以模态
方式显示出来,关于模态窗体的特性,你可以详细查看百度的介绍!