如何让DBLookupComboBox能够输入,我的办法是做一个组合的控件,在它的下方(当然也可以是上方)加一个小编辑框,我已经完成了代码的80%,我是从TCustomControl继承下来,在我的代码后会有解释我为什么要从这个类继承,而不是从TWinControl继承,请大家先看代码:
.h File
//---------------------------------------------------------------------------
#ifndef KingKingH #define KingKingH //--------------------------------------------------------------------------- #include <SysUtils.hpp> #include <Controls.hpp> #include <Classes.hpp> #include <Forms.hpp> #include <dsgnintf.hpp> #include <db.hpp>
//--------------------------------------------------------------------------- class PACKAGE TKingKing : public TCustomControl { private: TDBLookupComboBox *FLookup; TEdit *FEdit; TDataSource *FDataSource; TDataSource *FListSource; AnsiString FListField; AnsiString FKeyField; AnsiString FDataField; int FBaudRate;
protected: virtual void __fastcall Paint(); virtual __fastcall ~TKingKing(); virtual void __fastcall CreateWnd(); 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); void __fastcall SetBaudRate(int BaudRate); void __fastcall DoMyJob(TObject *Sender,WORD &Key,TShiftState Shift);
__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}; __property int BaudRate={read=FBaudRate,write=SetBaudRate}; }; class TDataOfFieldProperty:public TStringProperty { public: TPropertyAttributes __fastcall GetAttributes() { return TPropertyAttributes()<<paValueList; } void __fastcall GetValues(TGetStrProc Proc) { Proc("None"); TStrings *pList=new TStringList();; TKingKing *pDCBX=dynamic_cast<TKingKing*>(GetComponent(0)); if(pDCBX) { if(pDCBX->DataSource) { TDataSet *pDataSet=pDCBX->DataSource->DataSet; if(pDataSet) { pDataSet->GetFieldNames(pList); for(int i=0;i<pList->Count;i++) { Proc(pList->Strings[i]); } } } } delete pList; }
}; //List Field class TListOfFieldProperty:public TStringProperty { public: TPropertyAttributes __fastcall GetAttributes() { return TPropertyAttributes()<<paValueList; } void __fastcall GetValues(TGetStrProc Proc) { Proc("None"); TStrings *pList=new TStringList(); TKingKing *pDCBX=dynamic_cast<TKingKing*>(GetComponent(0)); if(pDCBX) { if(pDCBX->ListSource) { TDataSet *pDataSet=pDCBX->ListSource->DataSet; if(pDataSet) { pDataSet->GetFieldNames(pList); for(int i=0;i<pList->Count;i++) { Proc(pList->Strings[i]); } } } } delete pList; }
}; //KeyField class TKeyOfFieldProperty:public TStringProperty { public: TPropertyAttributes __fastcall GetAttributes() { return TPropertyAttributes()<<paValueList; } void __fastcall GetValues(TGetStrProc Proc) { Proc("None"); TStrings *pList=new TStringList(); TKingKing *pDCBX=dynamic_cast<TKingKing*>(GetComponent(0)); if(pDCBX) { if(pDCBX->ListSource) { TDataSet *pDataSet=pDCBX->ListSource->DataSet; if(pDataSet) { pDataSet->GetFieldNames(pList); for(int i=0;i<pList->Count;i++) { Proc(pList->Strings[i]); } } } } delete pList; }
}; class TBaudRateProperty:public TIntegerProperty //Announcement:The property is only used to test. { TPropertyAttributes __fastcall GetAttributes() { return TPropertyAttributes()<<paValueList; } void __fastcall GetValues(TGetStrProc Proc) { Proc("9600"); Proc("14400"); Proc("28800"); Proc("57600"); } };
//--------------------------------------------------------------------------- #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; } TTypeInfo *IntInfo() { TTypeInfo *pTypeInfo=new TTypeInfo; pTypeInfo->Kind=tkInteger; pTypeInfo->Name="Integer"; return pTypeInfo; }
__fastcall TKingKing::TKingKing(TComponent* Owner) : TCustomControl(Owner) { FLookup=new TDBLookupComboBox(this); FEdit=new TEdit(this); FEdit->OnKeyDown=DoMyJob; Width = 150; Height=46;
} //--------------------------------------------------------------------------- void __fastcall TKingKing::CreateWnd() { TCustomControl::CreateWnd(); FLookup->DataSource=DataSource; FLookup->ListSource=ListSource; FLookup->DataField=DataField; FLookup->ListField=ListField; FLookup->KeyField=KeyField;
} //---------------------------------------------------------------------------- void __fastcall TKingKing::DoMyJob(TObject *Sender,WORD &Key,TShiftState Shift) { if(Key==13) { FLookup->KeyField=FEdit->Text; } } //-------------------------------------------------------------------------
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; } void __fastcall TKingKing::SetBaudRate(int BaudRate) { FBaudRate=BaudRate; }
__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(TDataOfFieldProperty)); RegisterPropertyEditor(AnsiStringInfo(),__classid(TKingKing),"ListField",__classid(TListOfFieldProperty)); RegisterPropertyEditor(AnsiStringInfo(),__classid(TKingKing),"KeyField",__classid(TKeyOfFieldProperty)); RegisterPropertyEditor(IntInfo(),__classid(TKingKing),"BaudRate",__classid(TBaudRateProperty)); RegisterComponents("AKing", classes, 0); } } //---------------------------------------------------------------------------
那为什么我不从TWinControl继承,而从TCustomControl继承,我从类的层次来看这个问题:
我对两个组件进行比较发现:TDBLookupComboBox和TDBComboBox发现,首先它们的继承的类层次不同,其中TDBComboBox的继承层次有TCustomComboBox(而这个类是TComboBox的父类),而TDBLookupComboBox的最直接父类就是TCustomControl,这恰恰证明TDBLookupComboBox是放在Paint函数中被画出来的。而我的错误代码是从TWinControl继承下来的,而父类为TWinControl控件的最大特点就是自已能够画出自已,而TCustomControl则需要自已画自已(用Paint方法),据此可以判断TDBLookupComboBox为什么在设计期间就已经有了句柄的理由就是在从TCustomControl继承的过程序,TDBLookupComboBox不仅重载了Paint方法,还重载了CreateWnd方法。而如果你从TWinControl继承,再动态生成一个TDBLookupComboBox就会出现错误提示”该控件没有父窗口“。 我的代码基本上已经完成,唯一的一部分就是编辑框的OnKeyDown中的代码,你可自已根据需要来完成。

|