客户端数据校验器介绍了基于对象的数据输入时校验的实现,适应于业务对象的操作.
在开发查询功能时,查询条件可能是对若干项简单变量的过滤(当然也可以定义查询条件对象).
本文就是对基于简单类型变量的输入控制和校验的实现.
客户端数据校验器在OnKeyPress处理上有以下增强(文档未更新).
原有实现中截获控件的OnKeyPress后,开发人员自定义的OnKeyPress代码被校验器忽略,限制了开发人员对控件的控制能力。
一个可预见的情况是,如果需要增加Enter模拟Tab功能,则无法支持。
客户端数据校验器todo:
.非空项的界面提醒标记:提示方式可外部指定,如在输入控件之后显示一个红色的星号(*).
.支持TCheckBox,TRadio
代码如下:
在开发查询功能时,查询条件可能是对若干项简单变量的过滤(当然也可以定义查询条件对象).
本文就是对基于简单类型变量的输入控制和校验的实现.
客户端数据校验器在OnKeyPress处理上有以下增强(文档未更新).
原有实现中截获控件的OnKeyPress后,开发人员自定义的OnKeyPress代码被校验器忽略,限制了开发人员对控件的控制能力。
一个可预见的情况是,如果需要增加Enter模拟Tab功能,则无法支持。
客户端数据校验器todo:
.非空项的界面提醒标记:提示方式可外部指定,如在输入控件之后显示一个红色的星号(*).
.支持TCheckBox,TRadio
代码如下:
///< 简单类型变量校验器
template <class T> class CVarValidator {
T *var_;
CValidatorBase *validator_;
CBindControl *control_;
string var_type_;
public:
string var_desc_; ///< 变量描述
public:
CVarValidator():var_(0),validator_(0),control_(0) {
}
CVarValidator(T *var,CValidatorBase *validator,string var_type):var_(var),validator_(validator),var_type_(var_type),control_(0) {
}
~CVarValidator() {
if (control_) delete control_;
}
void SetVar(T *var,const char *var_type,const char *desc) {
var_ = var;
var_type_ = var_type;
if (desc) var_desc_ = desc;
}
void SetValidator(CValidatorBase *v) { validator_ = v; }
void BindControl(CBindControl *control) { validator_->BindControl(control); }
int Load() {
char buffer[20];
string type_name = var_type_;
char *p = (char*)var_;
if (type_name==ORM_FIELD_TYPE_LONG||type_name==ORM_FIELD_TYPE_ULONG) {
sprintf(buffer,"%d",*(long*)p);
validator_->SetText(buffer);
}
else if (type_name==ORM_FIELD_TYPE_INT||type_name==ORM_FIELD_TYPE_UINT) {
sprintf(buffer,"%d",*(int*)p);
validator_->SetText(buffer);
} else if (type_name==ORM_FIELD_TYPE_SHORT||type_name==ORM_FIELD_TYPE_USHORT) {
sprintf(buffer,"%d",*(short*)p);
validator_->SetText(buffer);
} else if (type_name==ORM_FIELD_TYPE_INT1||type_name==ORM_FIELD_TYPE_UINT1) {
sprintf(buffer,"%c",*p);
validator_->SetText(buffer);
}
else if (type_name==ORM_FIELD_TYPE_FLOAT) {
validator_->SetText(p);
} else if (type_name==ORM_FIELD_TYPE_DOUBLE) {
sprintf(buffer,"%.3f",*(double*)p); ///< @todo: 根据长度定义确定格式
validator_->SetText(buffer);
} else if (type_name==ORM_FIELD_TYPE_STRING) {
string s = *(string*)p;
validator_->SetText(s.c_str());
} else if (type_name==ORM_FIELD_TYPE_CHAR||type_name==ORM_FIELD_TYPE_UCHAR) {
validator_->SetText(p);
} else if (type_name==ORM_FIELD_TYPE_INT64||type_name==ORM_FIELD_TYPE_UINT64) {
sprintf(buffer,"%I64d",*(__int64*)p);
validator_->SetText(buffer);
} else if (type_name==ORM_FIELD_TYPE_BOOL) {
sprintf(buffer,"%d",*(bool*)p);
validator_->SetText(buffer);
}
else {
return -1;
}
return 0;
}
int Update() {
char *p = (char*)var_;
string sVal;
validator_->GetText(sVal);
string type_name = var_type_.c_str();
if (type_name==ORM_FIELD_TYPE_LONG||type_name==ORM_FIELD_TYPE_ULONG) {
*(long*)p = atol(sVal.c_str());
}
else if (type_name==ORM_FIELD_TYPE_INT||type_name==ORM_FIELD_TYPE_UINT) {
*(int*)p = atoi(sVal.c_str());
} else if (type_name==ORM_FIELD_TYPE_SHORT||type_name==ORM_FIELD_TYPE_USHORT) {
*(short*)p = (short)atoi(sVal.c_str());
} else if (type_name==ORM_FIELD_TYPE_INT1||type_name==ORM_FIELD_TYPE_UINT1) {
*p = sVal[0];
}
else if (type_name==ORM_FIELD_TYPE_FLOAT) {
*(float*)p = (float)atof(sVal.c_str());
} else if (type_name==ORM_FIELD_TYPE_DOUBLE) {
*(double*)p = atof(sVal.c_str());
} else if (type_name==ORM_FIELD_TYPE_STRING) {
*(string*)p = sVal.c_str();
} else if (type_name==ORM_FIELD_TYPE_CHAR||type_name==ORM_FIELD_TYPE_UCHAR) {
strcpy(p,sVal.c_str());//,fb->fld_size_);
} else if (type_name==ORM_FIELD_TYPE_INT64||type_name==ORM_FIELD_TYPE_UINT64) {
*(__int64*)p = _atoi64(sVal.c_str());
} else if (type_name==ORM_FIELD_TYPE_BOOL) {
*(bool*)p = sVal[0]=='1';
}
else {
return -1;
}
return 0;
}
int Check() {
char *p = (char*)var_;
string type_name = var_type_.c_str();
int ret = 0;
if (type_name==ORM_FIELD_TYPE_LONG||type_name==ORM_FIELD_TYPE_ULONG) {
ret = validator_->Check((void*)*(long*)p);
}
else if (type_name==ORM_FIELD_TYPE_INT||type_name==ORM_FIELD_TYPE_UINT) {
ret = validator_->Check((void*)*(int*)p);
} else if (type_name==ORM_FIELD_TYPE_SHORT||type_name==ORM_FIELD_TYPE_USHORT) {
ret = validator_->Check((void*)*(short*)p);
} else if (type_name==ORM_FIELD_TYPE_INT1||type_name==ORM_FIELD_TYPE_UINT1) {
ret = validator_->Check((void*)*p);
}
else if (type_name==ORM_FIELD_TYPE_FLOAT) {
ret = validator_->Check((void*)p);
} else if (type_name==ORM_FIELD_TYPE_DOUBLE) {
ret = validator_->Check((void*)p);
} else if (type_name==ORM_FIELD_TYPE_STRING) {
string s = *(string*)p;
ret = validator_->Check((void*)s.c_str());
} else if (type_name==ORM_FIELD_TYPE_CHAR||type_name==ORM_FIELD_TYPE_UCHAR) {
ret = validator_->Check((void*)p);
} else if (type_name==ORM_FIELD_TYPE_INT64||type_name==ORM_FIELD_TYPE_UINT64) {
ret = validator_->Check((void*)*(__int64*)p);
} else if (type_name==ORM_FIELD_TYPE_BOOL) {
ret = validator_->Check((void*)*(bool*)p);
}
else {
return 0;
}
return ret;
}
};
测试代码如下:
TForm定义:
class TForm1 : public TForm
{
__published: // IDE-managed Components
void __fastcall FormCreate(TObject *Sender);
void __fastcall edtVarKeyPress(TObject *Sender, char &Key);
void __fastcall btnTestVarClick(TObject *Sender);
private: // User declarations
string alone_var_; ///< 变量
CVarValidator<string> val_v_; ///< 简单类型变量校验器
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
TForm实现:
void __fastcall TForm1::FormCreate(TObject *Sender)
{
///< 商品GTIN:不能为空,并且必须是13个字符宽
CStringValidator *sv = new CStringValidator;
sv->SetMinLength(13);
sv->SetMaxLength(13);
sv->SetNullFlag(false); ///< 不允许为空
sv->AddValidChar(CS_DIGIT);
val_v_.SetVar(&alone_var_,ORM_FIELD_TYPE_STRING,"商品GTIN");
val_v_.SetValidator(sv);
val_v_.BindControl(new CEdit(edtVar));
return;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::btnTestVarClick(TObject *Sender)
{
int rv = 0;
rv = val_v_.Update();
rv = val_v_.Check();
ShowMessageFmt("'%s'%s,errcode=%d",ARRAYOFCONST((val_v_.var_desc_.c_str(),rv==0 ? "无效":"OK",rv)));
alone_var_ = "1234567890123";
rv = val_v_.Load();
return;
}