关于组件制作的问题:

kingcaiyao 2002-07-10 07:45:18
我从TWinControl派生一个组件,目的是生成一个DBLookupComboBox,但问题出现了,当包编译,安装成功后。我将我的这个组件放到窗体上时,错误出现表现“control has no parent window",但事实上我已经重载CreateWnd函数。令人奇怪的是,如果我不是生成TDBLookupCombobOX,而是其它则没有问题。附代码,希望大家讨论:
//---------------------------------------------------------------------------
#ifndef KingLookupH
#define KingLookupH
//---------------------------------------------------------------------------
#include <SysUtils.hpp>
#include <Controls.hpp>
#include <Classes.hpp>
#include <Forms.hpp>
#include <DBCtrls.hpp>
//---------------------------------------------------------------------------
class PACKAGE TKingLookup : public TWinControl
{
private:
TDBLookupComboBox FLookup;
protected:
virtual __fastcall ~TKingLookup();
virtual void __fastcall CreateWnd();
public:
__fastcall TKingLookup(TComponent* Owner);
__published:
};
//---------------------------------------------------------------------------
#endif
.cpp File
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "KingLookup.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
// ValidCtrCheck is used to assure that the components created do not have
// any pure virtual functions.
//

static inline void ValidCtrCheck(TKingLookup *)
{
new TKingLookup(NULL);
}
//---------------------------------------------------------------------------
__fastcall TKingLookup::TKingLookup(TComponent* Owner)
: TDBLookupComboBox(Owner)
{
FLookup=new TDBLookupComboBox(this);
FLookup->Parent=this;
FLookup->Font->Color=clWhite;
FLookup->Color=clBlack;
FLookup->Left=Left;
FLookup->Top=Top+21;
FLookup->Width=100;
FLookup->Height=21;


}
//---------------------------------------------------------------------------
__fastcall TKingLookup::~TKingLookup()
{
if(FLookup)
{
delete FLookup;
}
}
void __fastcall TKingLookup::CreateWnd()
{
TWinControl::CreateWnd();
}
namespace Kinglookup
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TKingLookup)};
RegisterComponents("AKing", classes, 0);
}
}
//---------------------------------------------------------------------------
奇怪的是,这么一个简单的代码,莫非TDBLookupComboBox这个类本身还有其它的问题?
...全文
40 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
Borlandor 2002-07-11
  • 打赏
  • 举报
回复
OK,很不错,应该从TCustomControl中继承。
kingcaiyao 2002-07-11
  • 打赏
  • 举报
回复
我将我的代码贴如下:
//---------------------------------------------------------------------------

#ifndef KingKingH
#define KingKingH
//---------------------------------------------------------------------------
#include <SysUtils.hpp>
#include <Controls.hpp>
#include <Classes.hpp>
#include <Forms.hpp>
#include <dsgnintf.hpp>
//---------------------------------------------------------------------------
class PACKAGE TKingKing : public TCustomControl
{
private:
TDBLookupComboBox *FLookup;
TEdit *FEdit;
TDataSource *FDataSource;
TDataSource *FListSource;
AnsiString FListField;
AnsiString FKeyField;
AnsiString FDataField;

protected:
virtual void __fastcall Paint();
virtual __fastcall ~TKingKing();
public:
__fastcall TKingKing(TComponent* Owner);
void __fastcall SetDataSource(TDataSource *DataSource);
void __fastcall SetListSource(TDataSource *DataSource);
void __fastcall SetKeyField(AnsiString Field);
void __fastcall SetDataField(AnsiString Field);
void __fastcall SetListField(AnsiString Field);

__published:
__property TDataSource* DataSource={read=FDataSource,write=SetDataSource};
__property TDataSource *ListSource={read=FListSource,write=SetListSource};
__property AnsiString KeyField={read=FKeyField,write=SetKeyField};
__property AnsiString ListField={read=FListField,write=SetListField};
__property AnsiString DataField={read=FDataField,write=SetDataField};
};
//DataField PropertyEditor
class TDataFieldProperty:public TStringProperty
{
public:
TPropertyAttributes __fastcall GetAttributes()
{
return TPropertyAttributes()<<paValueList;
}
void __fastcall GetValues(TGetStrProc Proc)
{
Proc("None");
TDataSet *pDataSet;
TKingKing *pDCBX=dynamic_cast<TKingKing*>(GetComponent(0));
if(pDCBX)
{ if(pDCBX->DataSource)
{
pDataSet=pDCBX->DataSource->DataSet;
if(pDataSet)
{
TStrings *pList=new TStringList();
pDataSet->GetFieldNames(pList);

for(int i=0;i<pList->Count;i++)
{
Proc(pList->Strings[i]);
}
delete pList;
}
}
}
}
};
//ListField PropertyEditor
class TListFieldProperty:public TStringProperty
{
public:
TPropertyAttributes __fastcall GetAttributes()
{
return TPropertyAttributes()<<paValueList;
}
void __fastcall GetValues(TGetStrProc Proc)
{
Proc("None");
TDataSet *pDataSet;
TKingKing *pDCBX=dynamic_cast<TKingKing*>(GetComponent(0));
if(pDCBX)
{ if(pDCBX->ListSource)
{
pDataSet=pDCBX->ListSource->DataSet;
if(pDataSet)
{
TStrings *pList=new TStringList();
pDataSet->GetFieldNames(pList);
for(int i=0;i<pList->Count;i++)
{
Proc(pList->Strings[i]);
}
delete pList;
}
}
}
}
};
//KeyField PropertyEditor
class TKeyFieldProperty:public TStringProperty
{
public:
TPropertyAttributes __fastcall GetAttributes()
{
return TPropertyAttributes()<<paValueList;
}
void __fastcall GetValues(TGetStrProc Proc)
{
Proc("None");
TDataSet *pDataSet;
TKingKing *pDCBX=dynamic_cast<TKingKing*>(GetComponent(0));
if(pDCBX)
{ if(pDCBX->ListSource)
{
pDataSet=pDCBX->ListSource->DataSet;
if(pDataSet)
{
TStrings *pList=new TStringList();
pDataSet->GetFieldNames(pList);
for(int i=0;i<pList->Count;i++)
{
Proc(pList->Strings[i]);
}
delete pList;
}
}
}
}
};

//---------------------------------------------------------------------------
#endif
.cpp File
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "KingKing.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
// ValidCtrCheck is used to assure that the components created do not have
// any pure virtual functions.
//

static inline void ValidCtrCheck(TKingKing *)
{
new TKingKing(NULL);
}
//---------------------------------------------------------------------------
TTypeInfo *AnsiStringInfo()
{
TTypeInfo *pTypeInfo=new TTypeInfo;
pTypeInfo->Kind=tkLString;
pTypeInfo->Name="AnsiString";
return pTypeInfo;
}

__fastcall TKingKing::TKingKing(TComponent* Owner)
: TCustomControl(Owner)
{
FLookup=new TDBLookupComboBox(this);
FEdit=new TEdit(this);
Width = 150;
Height=46;

}
//---------------------------------------------------------------------------
void __fastcall TKingKing::Paint()
{

Width = 150;
Height=46;
FLookup->Parent=this;
FLookup->Left=0;
FLookup->Top=0;
FLookup->Width=145;
FLookup->Height=21;

FEdit->Parent=this;
FEdit->Left=0;
FEdit->Top=FLookup->Height;
FEdit->Width=80;
FEdit->Height=21;
}
void __fastcall TKingKing::SetDataSource(TDataSource *DataSource)
{
FDataSource=DataSource;
}
//--------------------------------------------------------------------------
void __fastcall TKingKing::SetListSource(TDataSource *DataSource)
{
FListSource=DataSource;
}
//--------------------------------------------------------------------------
void __fastcall TKingKing::SetKeyField(AnsiString Field)
{
FKeyField=Field;
}
void __fastcall TKingKing::SetListField(AnsiString Field)
{
FListField=Field;
}
void __fastcall TKingKing::SetDataField(AnsiString Field)
{
FDataField=Field;
}

__fastcall TKingKing::~TKingKing()
{
if(FLookup)
{
delete FLookup;
}
if(FEdit)
{
delete FEdit;
}

}


namespace Kingking
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TKingKing)};
RegisterPropertyEditor(AnsiStringInfo(),__classid(TKingKing),"DataField",__classid(TDataFieldProperty));
RegisterPropertyEditor(AnsiStringInfo(),__classid(TKingKing),"ListField",__classid(TListFieldProperty));
RegisterPropertyEditor(AnsiStringInfo(),__classid(TKingKing),"KeyField",__classid(TKeyFieldProperty));
RegisterComponents("AKing", classes, 0);
}
}
//---------------------------------------------------------------------------
kingcaiyao 2002-07-11
  • 打赏
  • 举报
回复
问题差不多已被我找到了。因为我对两个组件进行比较发现:TDBLookupComboBox和TDBComboBox发现,首先它们的继承的类层次不同,其中TDBComboBox的继承层次有TCustomComboBox(而这个类是TComboBox的父类),而TDBLookupComboBox的最直接父类就是TCustomControl,这恰恰证明TDBLookupComboBox是放在Paint函数中被画出来的。而我的错误代码是从TWinControl继承下来的,而父类为TWinControl控件的最大特点就是自已能够画出自已,而TCustomControl则需要自已画自已(用Paint方法),据此可以判断TDBLookupComboBox为什么在设计期间就已经有了句柄的理由就是在从TCustomControl继承的过程序,TDBLookupComboBox不仅重载了Paint方法,还重载了CreateWnd方法。而如果你从TWinControl继承,再动态生成一个TDBLookupComboBox就会出现错误提示”该控件没有父窗口“。
欢迎各位网友参与讨论。
kingcaiyao 2002-07-10
  • 打赏
  • 举报
回复
看来c++ builder和Delphi论坛对组件有研究的人比较少。
dupenf 2002-07-10
  • 打赏
  • 举报
回复
代码没看到阿
netlib 2002-07-10
  • 打赏
  • 举报
回复
老大,帖错论坛了 。
例行更新,不过本次有新组件加入,感觉这次的组件早就应该有了,居然到现在才加入进来,不管怎么说有总比没有好。这次还是以改进为主,改进项占了大多数。废话不多说具体内容大家看更新说明吧!另外由于经常收到chm格式文件无法用的反馈,其实不是无法用,只是要授权。虽然已经解释多遍,但是依然有人不知道,索性就取消chm格式的文档了,今后统一采用exe+pdf格式,由于目前尚无时间制作pdf格式的api文档,所以1.5版中只有exe的,pdf格式将在下一版中提供。 jQuery EasyUI 1.5版本更新内容: Bug(修复) combobox:修复在加载包含所选项数据的时候不会触发“onSelect”事件的BUG; datagrid:修复在字段设置为一个空值的时候导致在某些情况下“updateRow”方法无法正常工作的BUG。 Improvement(改进) 一个label标签可以被关联到任意表单的字段上; combobox:改进在下拉项中“select”和“unselect”的规则; combobox:添加“limitToList”属性来限制只能输入在列表项中的内容; combogrid:允许用户快速克隆组件; form:添加“dirty”属性,允许用户只发送变更的字段内容; form:添加“resetDirty”方法; datagrid:允许用户在没有数据的时候显示一条消息(比如:无记录); textbox:添加“label”、“labelWidth”、“labelPosition”和“labelAlign”属性; spinner:添加“spinAlign”属性; calendar:允许用户在日历组件上显示周数(今年的第几周); window:添加“constrain”属性。 New Plugin(新组件) passwordbox:该插件允许用户在具有更好交互功能的输入框中输入密码; combotreegrid:该插件结合了combobox和treegrid组件
(题外话:从本次开始 我新增了jQuery EasyUI的专题页面 大家可以关注我的专题页来及时获取最新的EasyUI资源 专题页地址如下http:http://download.csdn.net/album/detail/343 同时也希望转载的那些朋友能保留我资源的说明及出处地址 我花那么多精力制作出来的 你们鼠标点两下就给我转走了还不注明出处 实在是不厚道 本来就是本着分享精神的 为的就是聚集一点人气和提供一个优良的环境来一起学习进步的 请不要抹杀掉我的热情 谢谢 )   时隔4个月之久 EasyUI终于迎来大版本更新了 本次更新内容诸多 除了常规维护外 还新增了3个新组件 都很实用 详细的可以阅读更新说明 里面给了详细的解读 另外 从该版本开始我将会逐步的将EasyUI官方以及第三方较好的插件API整合到API文档当中 并且会对这些插件做一些简单的Demo实现 存放到配套提供的程序包demo文件夹下 以便大家学习和使用 本期文档中将官方提供的所有附加插件的API都整理并存放到Extension节点下了 这些扩展的demo在附带的程序包中已经提供 可以用于参考使用 jQuery EasyUI 1 4版本更新内容: Bug(修复) menu:修复在删除一个菜单项的时候该菜单无法正确自适应高度的问题; datagrid:修复在datagrid宽度太小的时候“fitColumns”方法无法正常工作的问题 Improvement(改进) EasyUI的所有组件已经支持非固定 百分比大小的尺寸设置; menu:添加“showItem” “hideItem”和“resize”方法; menu:基于窗体大小自动调整高度; menu:添加“duration”属性 该属性允许用户自定义隐藏菜单动画的持续时间 以毫秒为单位; validatebox:添加“onBeforeValidate”和“onValidate”事件; combo:从该版本开始combo组件扩展自textbox组件(textbox是1 4中新增的组件); combo:添加“panelMinWidth” “panelMaxWidth” “panelMinHeight”和“panelMaxHeight”属性; searchbox:从该版本开始searchbox组件扩展自textbox组件(textbox是1 4中新增的组件); tree:添加“getRoot”方法 用于返回通过“nodeEl”参数指定的节点的顶部父节点元素 注意:官网的英文API中该函数的说明有误 其说明是none 无参数 实际这里是需要参数的 ; tree:添加“queryParams”属性; datetimebox:添加“spinnerWidth”属性; panel:添加“doLayout”方法 用于控制面板内组件的大小; panel:添加“clear”方法 用于清除面板内的内容; datagrid:允许用户设置百分比宽度的列(该功能真是千呼万唤始出来啊 ); form:添加“ajax” “novalidate”和“queryParams”属性; linkbutton:添加“resize”方法 New Plugin(新组件) textbox:该组件是一个增强的输入字段 它可以让用户非常简单的构建一个表单; datetimespinner:该组件是一个日期和时间的微调组件 它允许我们选择一个特定的日期或时间; filebox:filebox 该组件表单元素中用于上传文件的文件框工具组件 ">(题外话:从本次开始 我新增了jQuery EasyUI的专题页面 大家可以关注我的专题页来及时获取
最近比较忙,抽空做了最新版的API,本次的主要精力就是放在了pdf版的文档上面,看了上一版好多人反应说希望保留chm格式的,所以这一版继续提供chm格式的文档给大家了,现在的版本中包含了PDF、EXE和CHM 3种格式的文档,相信应该可以满足大家的需要了。此外我个人推荐大家使用PDF格式的文档,因为PDF是全新制作的,内容进行了完整校对,所以错漏的地方比EXE和CHM格式要少很多。其它废话就不多说了。更新内容自己看更新说明吧! jQuery EasyUI 1.5.1版本更新内容: Bug(修复) datagrid:修复在调用“updateRow”方法之后选中和复选行标志丢失的问题; tabs:修复在调用“update”方法的时候导致标签栏工具错位的问题; window:修复在窗体高度设置为“auto”时,当移动窗体后窗体会丢失的问题; messager:修复在现实进度消息窗口后立即关闭该窗口会导致程序发生异常的问题; form:修复“clear”方法无法清除combobox组件选择的下拉项的问题。 Improvement(改进) textbox:可以用“cls”属性添加自定义样式; numberbox:允许用户使用意大利货币格式; combo:添加“multivalue”属性,允许用户决定如何提交多个值; combobox:添加“reversed”属性; combobox:添加“onClick”事件; combogrid:添加“reversed”属性; treegrid:使用Shift键启用多值选择。 New Plugin(新组件) tagbox:允许用户在表单字段上添加标签。

5,392

社区成员

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

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