从DLL中创建的Form嵌入其他Form之,某些控件不能正常运行,抛出“Control has no parent window”的错误

xuqingxin 2008-04-25 10:27:12
我做了一个Form,名字为fmDLL,里面有个2Panel和一个Spiltter。一个Panle的Align设为alLeft,另一个设为alClient。Splitter的Align设为alLeft。现在我写了一个DLL,这个DLL有两个函数,分别是创建和销毁这个fmDLL。创建的函数会穿入一个TCustomForm,fmDLL的Parent就设为这个Form。这样fmDLLForm就嵌入到一个新的Form中了。在Debug模式下,编译这个DLL,然后被其他程序调用,程序可以正常运行。把它Release之后,再被其他程序调用,问题就来了。点击Spiltter想要拖动它,出现“Control “Spiltter1” has no parent window”的错误。问题好像在fmDLLForm的Parent这里,因为如果不给它设置Parent,就是不让它嵌入其他窗口,就能正常运行。一嵌入其他窗口,就有问题了。请问大家知道怎么解决吗?

下面是fmDLL的DFM文件内容。
object fmDLL: TfmDLL
Left = 192
Top = 114
Width = 570
Height = 411
Caption = 'fmDLL'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object Splitter1: TSplitter
Left = 201
Top = 0
Width = 3
Height = 377
Cursor = crHSplit
end
object Panel1: TPanel
Left = 0
Top = 0
Width = 201
Height = 377
Align = alLeft
Caption = 'Panel1'
TabOrder = 0
end
object Panel2: TPanel
Left = 204
Top = 0
Width = 358
Height = 377
Align = alClient
Caption = 'Panel2'
TabOrder = 1
end
end


下面是生成DLL的内容。
//---------------------------------------------------------------------------

#include <vcl.h>
#include <windows.h>
#pragma hdrstop
#include "FormDLL.h"
//---------------------------------------------------------------------------
// Important note about DLL memory management when your DLL uses the
// static version of the RunTime Library:
//
// If your DLL exports any functions that pass String objects (or structs/
// classes containing nested Strings) as parameter or function results,
// you will need to add the library MEMMGR.LIB to both the DLL project and
// any other projects that use the DLL. You will also need to use MEMMGR.LIB
// if any other projects which use the DLL will be performing new or delete
// operations on any non-TObject-derived classes which are exported from the
// DLL. Adding MEMMGR.LIB to your project will change the DLL and its calling
// EXE's to use the BORLNDMM.DLL as their memory manager. In these cases,
// the file BORLNDMM.DLL should be deployed along with your DLL.
//
// To avoid using BORLNDMM.DLL, pass string information using "char *" or
// ShortString parameters.
//
// If your DLL uses the dynamic version of the RTL, you do not need to
// explicitly add MEMMGR.LIB as this will be done implicitly for you
//---------------------------------------------------------------------------

extern "C" __declspec(dllexport) __stdcall void CreateFrom(TCustomForm *ParentForm);
extern "C" __declspec(dllexport) __stdcall void DestoryFrom();

#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
return 1;
}
//---------------------------------------------------------------------------
void __stdcall CreateFrom(TCustomForm *ParentForm)
{
if (ParentForm != NULL) {
fmDLL = new TfmDLL(ParentForm);
fmDLL->Parent = ParentForm;
fmDLL->Align = alClient;
fmDLL->BorderStyle = bsNone;
fmDLL->Visible = true;
}
}

void __stdcall DestoryFrom()
{
if (fmDLL != NULL) {
delete fmDLL;
fmDLL = NULL;
}
}


下面是调用DLL的程序内容。
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"

typedef void (__stdcall *DLL_FUN_1)(TCustomForm *);
typedef void (__stdcall *DLL_FUN_0)();
DLL_FUN_1 createForm;
DLL_FUN_0 destroyForm;

TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormCreate(TObject *Sender)
{
m_hInstance = LoadLibrary("Project1.dll");
if (m_hInstance != NULL) {
createForm = (DLL_FUN_1)GetProcAddress(m_hInstance, "CreateFrom");
destroyForm = (DLL_FUN_0)GetProcAddress(m_hInstance, "DestoryFrom");
} else {
createForm = NULL;
destroyForm = NULL;
}
if (createForm != NULL) {
createForm(this);
m_bCreated = true;
} else {
m_bCreated = false;
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
if (m_bCreated && destroyForm != NULL) {
destroyForm();
m_bCreated = false;
}
if (m_hInstance != NULL) {
FreeLibrary(m_hInstance);
}
}
//---------------------------------------------------------------------------
...全文
134 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
xuqingxin 2008-04-29
  • 打赏
  • 举报
回复
Release模式下不能正常显示,如何跟踪啊?Lixinag能不能讲得更详细些?
Lixinag 2008-04-26
  • 打赏
  • 举报
回复
这个问题我遇到过,好像是控件指向值不合理,你仔细跟踪下值
w88529593 2008-04-25
  • 打赏
  • 举报
回复
关注……

604

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder VCL组件使用和开发
社区管理员
  • VCL组件使用和开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧