客户端数据校验器
来源:互联网 发布:手机淘宝网店怎么登陆 编辑:程序博客网 时间:2024/04/30 14:48
本文中的validator.cpp存在2个bug,见"客户端数据校验器中的2个bug"一文.(2014-6-27)
1.用途
简化客户端输入/编辑操作的编程。可大幅减少代码量,并易于维护和扩展。.支持从对象直接加载到控件和把控件数据更新到对象
.自动根据校验规则控制输入
.支持TEdit,TComboBox,TDatetimePicker
限制:
.仅支持对象的成员类型为基本数据类型和string
2..定义
头文件:validator.h
名字空间:ns_validator
#include <vcl.h>#include <stdio.h>#include <assert.h>#include <string>#include <vector>#include <ComCtrls.hpp>#pragma hdrstop#include "NullForm.h"#include "auto_pointer.h"#include "code_table_mgr.h"using namespace std;//---------------------------------------------------------------------------namespace ns_validator {//---------------------------------------------------------------------------///< 有效字符类型///< 1-数字(0-9) 2-字母(a-z,A-Z) 9-指定字符(若干)enum VALID_CHARSET_TYPE { CS_DIGIT=1,CS_ALPHA=2,CS_STRING=9};//---------------------------------------------------------------------------///< 有效字符规则struct CValidCharSet { VALID_CHARSET_TYPE type_; string chars_; ///< 当type_==9时,表示有效的字符};//---------------------------------------------------------------------------///< 数据绑定控件基类class CBindControl {public: virtual int CheckInput(char ch) { return 1; } virtual int CheckInput(char ch,char **out) { return 1; } virtual string GetValue() = 0; ///< 获取控件的值 virtual void SetValue(const char *value) = 0; ///< 设置控件值 virtual void SetOnKeyPress(TKeyPressEvent e) {} virtual void SetFocus() = 0;};//---------------------------------------------------------------------------///< CEdit编辑框控件class CEdit : public CBindControl { TEdit *control_;public: CEdit(TEdit *control); void SetOnKeyPress(TKeyPressEvent e); int CheckInput(char ch,char **out); string GetValue(); void SetValue(const char *value); void SetFocus() { control_->SetFocus(); }};//---------------------------------------------------------------------------///< 通用码表类struct CCodeTableBase { string code_; ///< 编码 string name_; ///< 名称 CCodeTableBase(const char *code,const char *name):code_(code),name_(name) { }};//---------------------------------------------------------------------------///< CComboBox组合框控件class CComboBox : public CBindControl { short flag_; ///< 0-不使用码表 1-使用码表的code_值 2-使用码表的name_值 CCodeTableMgr<CCodeTableBase,string> *code_table_; ///< 码表 TComboBox *control_;public: CComboBox(TComboBox *control,short flag=0,CCodeTableMgr<CCodeTableBase,string> *code_table=0); string GetValue(); void SetValue(const char *value); void SetFocus() { control_->SetFocus(); }};//---------------------------------------------------------------------------///< CDateTimePicker日期时间选取控件class CDateTimePicker : public CBindControl { TDateTimePicker *control_; short flag_; ///< 1-日期时间 2-日期 3-时间public: CDateTimePicker(TDateTimePicker *control,int flag=1); string GetValue(); void SetValue(const char *value); void SetFocus() { control_->SetFocus(); }};//---------------------------------------------------------------------------///< 校验器基类class CValidatorBase {protected: CAutoVector<CValidCharSet*> v_ch_set_; ///< 有效字符限定,如果为空则表示允许任何字符 unsigned int max_len_; ///< 最大长度(0:表示不限制) unsigned int min_len_; ///<最小长度(0:表示不限制) bool null_flag_; ///< 是否允许为空 TfrmNull *null_form_; ///< 用于检查按键的窗体(内部隐藏)public: CBindControl *control_; ///< 绑定的控件public: CValidatorBase(); virtual ~CValidatorBase(); ///< 设置最小长度 void SetMinLength(unsigned int min_len) { min_len_ = min_len; } ///< 设置最大长度 void SetMaxLength(unsigned int max_len) { max_len_ = max_len; } ///< 取最小长度 unsigned int GetMinLength() const { return min_len_; } ///< 取最大长度 unsigned int GetMaxLength() const { return max_len_; } ///< 设置有效字符 void AddValidChar(VALID_CHARSET_TYPE type); void AddValidChar(const char *s); ///< 设置允许空标志 void SetNullFlag(bool flag) { null_flag_ = flag; } ///< 取允许空标志 bool GetNullFlag() const { return null_flag_; } ///< 绑定控件 void BindControl(CBindControl *control); ///< 获取控件内容 int GetText(string &text); ///< 设置控件内容 void SetText(const char *text); int CheckChar(char ch); ///< 检查字符的有效性 virtual int CheckInput(char ch); ///< 检查是否可以接受输入字符 virtual int Check(void *val,int flag=1) = 0; ///< 校验值有效性 1-有效 0-无效 virtual int CheckText(const char *text,int flag) = 0; ///< 校验值的有效性 flag=0时不检查最小值和最小长度(输入过程中)};//---------------------------------------------------------------------------///< 数值范围模板类template <class T> class CNumberRange {protected: short range_prop_; ///< 值范围属性 bit-0: 是否有最大限制 bit-1:是否有最小限制 bit-2:最大限制是否排除边界值(0-不排除 1-排除) bit3-最小限制是否排除边界值 T max_value_; ///< 最大值 T min_value_; ///< 最小值public: CNumberRange() { range_prop_ = 0; max_value_ = 0; min_value_ = 0; } ///< 设置最大值 void SetMaxValue(T value,short flag=0) { max_value_ = value; range_prop_ |= 1; ///< 有最大限制 if (flag) range_prop_ |= 1<<2; ///< 是否排除边界值 } ///< 设置最小值 void SetMinValue(T value,short flag=0) { min_value_ = value; range_prop_ |= 1<<1; if (flag) { range_prop_ |= 1<<3; } } ///< 取最大值 T GetMinValue() const { return min_value_; } ///< 取最小值 T GetMaxValue() const { return max_value_; } ///< 取范围属性 short GetRangeProp() const { return range_prop_; } ///< 检查一个值是否在范围内 ///< flag=0不检查最小值 bool Check(T value,short flag) { if (range_prop_&1) { ///< 有最大值限制 if (range_prop_&(1<<2)) {///< 排除边界值 if (value>max_value_) return false; } else { if (value>=max_value_) return false; } } if (flag) { if (range_prop_&(1<<1)) { ///< 有最小值限制 if (range_prop_&(1<<3)) {///< 排除边界值 if (value<min_value_) return false; } else { if (value<=min_value_) return false; } } } return true; } };//---------------------------------------------------------------------------///< 整数校验器class CIntValidator : public CValidatorBase,public CNumberRange<long> {public: CIntValidator(); int Check(void *val,int flag); ///< 校验合法性 int CheckText(const char *text,int flag);};//---------------------------------------------------------------------------///< 小数数值校验器///< 长度包括符号位和小数点class CDecimalValidator : public CValidatorBase,public CNumberRange<double> { unsigned short scale_; ///< 最大小数位数public: CDecimalValidator(); ///< 设置最大小数位数 void SetScale(unsigned short scale) { scale_ = scale; } ///< 取最大小数位数 unsigned short GetScale() const { return scale_; } int Check(void *val,int flag); int CheckText(const char *text,int flag);};//---------------------------------------------------------------------------///< 字符串校验器/// @todo 引入正则表达式,支持各种文本模式class CStringValidator : public CValidatorBase {public: CStringValidator(); CStringValidator(unsigned int min_len,unsigned int max_len); int Check(void *val,int flag); int CheckText(const char *text,int flag);};//---------------------------------------------------------------------------///< 对象校验成员绑定信息struct CValidatorBindInfo {unsigned short offset_; ///< 成员在对象中的偏移 string desc_; ///< 成员描述string var_type_; ///< 变量类型,字段类型 CValidatorBase *validator_; ///< 校验器 CBindControl *control_; ///< 控件 CValidatorBindInfo(unsigned short offset,const char *val_type,CValidatorBase *validator,const char *desc):offset_(offset),var_type_(val_type),validator_(validator),control_(0) { if (desc) desc_ = desc; } ~CValidatorBindInfo() { if (control_) delete control_; }};//---------------------------------------------------------------------------#define ORM_FIELD_TYPE_INT"int"#define ORM_FIELD_TYPE_UINT"uint"#define ORM_FIELD_TYPE_SHORT"short"#define ORM_FIELD_TYPE_USHORT"ushort"#define ORM_FIELD_TYPE_LONG"long"#define ORM_FIELD_TYPE_ULONG"ulong"#define ORM_FIELD_TYPE_INT64"int64"#define ORM_FIELD_TYPE_UINT64"uint64"#define ORM_FIELD_TYPE_CHAR"char"#define ORM_FIELD_TYPE_UCHAR"uchar"#define ORM_FIELD_TYPE_STRING"string"#define ORM_FIELD_TYPE_BOOL"bool"#define ORM_FIELD_TYPE_FLOAT"float"#define ORM_FIELD_TYPE_DOUBLE"double"#define ORM_FIELD_TYPE_INT1"int1"#define ORM_FIELD_TYPE_UINT1"uint1"#define OFFSETOF(TYPE,VAR) (int)&(((TYPE*)0)->VAR)#define NEW_VALIDATOR_BIND(TYPE,VAR,VAL_TYPE,CHECKER,DESC) \ new CValidatorBindInfo(OFFSETOF(TYPE,VAR),VAL_TYPE,CHECKER,DESC)//---------------------------------------------------------------------------///< 对象校验器template <class T> class CObjectValidator { vector<CValidatorBindInfo*> bind_info_; int err_code_; ///< 校验失败的错误码(@todo 待定义) CValidatorBindInfo *err_vbi_; ///< 校验失败的绑定项 bool auto_hint_; ///< 校验失败时自动提示 bool auto_focus_; ///< 自动设置焦点 ///< 查找指定成员对应的绑定信息 CValidatorBindInfo* Find(int offset);public: CObjectValidator():err_code_(0),err_vbi_(0),auto_hint_(true),auto_focus_(true) { } ~CObjectValidator() { vector<CValidatorBindInfo*>::iterator iter = bind_info_.begin(); while(iter!=bind_info_.end()) { delete *iter; iter++; } } ///< 设置(校验失败时)自动提示标志 void SetAutoHint(bool value) { auto_hint_ = value; } ///< 设置(校验失败时)自动设置输入焦点标志 void SetAutoFocus(bool value) { auto_focus_ = value;} ///< 设置指定成员的校验器 int SetValidator(CValidatorBindInfo* v) { bind_info_.push_back(v); return 0; } ///< 绑定成员与控件 int BindControl(int offset,CBindControl *control); ///< 控件支持: TEdit, int Update(T *obj); ///< 把控件内容更新对象 int Load(T *obj); ///< 把对象内容加载到控件 int Check(T *obj); ///< 检查对象值的有效性,@return 0-无效 1-有效 string GetErrorInfo(); ///< 获取校验错误信息};//---------------------------------------------------------------------------template <class T> string CObjectValidator<T>::GetErrorInfo() { string err; if (err_vbi_==0) return err; err += "数据项'"; err += err_vbi_->desc_.c_str(); err += "'无效"; return err;}//---------------------------------------------------------------------------template <class T> CValidatorBindInfo* CObjectValidator<T>::Find(int offset) { vector<CValidatorBindInfo*>::iterator iter = bind_info_.begin(); while(iter!=bind_info_.end()) { CValidatorBindInfo *vbi = *iter; if (vbi->offset_==offset) return vbi; iter++; } return 0;}//---------------------------------------------------------------------------template <class T> int CObjectValidator<T>::BindControl(int offset,CBindControl *control) { CValidatorBindInfo* vbi = Find(offset); if (vbi==0) return -1; vbi->control_ = control; vbi->validator_->BindControl(control); return 0;}//---------------------------------------------------------------------------template <class T> int CObjectValidator<T>::Update(T *obj) { vector<CValidatorBindInfo*>::iterator iter = bind_info_.begin(); while(iter!=bind_info_.end()) { CValidatorBindInfo *vbi = *iter; if (vbi->control_==0) { ///< 如果成员未与控件绑定则不处理 iter++; continue; } char *p = (char*)obj+vbi->offset_; string sVal; vbi->validator_->GetText(sVal);string type_name = vbi->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 { iter++; ///< 不支持的数据类型 continue;} iter++; } return 0;}//---------------------------------------------------------------------------template <class T> int CObjectValidator<T>::Load(T *obj) { vector<CValidatorBindInfo*>::iterator iter = bind_info_.begin(); while(iter!=bind_info_.end()) { CValidatorBindInfo *vbi = *iter; char *p = (char*)obj+vbi->offset_;string type_name = vbi->var_type_.c_str(); char buffer[20];if (type_name==ORM_FIELD_TYPE_LONG||type_name==ORM_FIELD_TYPE_ULONG) { sprintf(buffer,"%d",*(long*)p); vbi->validator_->SetText(buffer);}else if (type_name==ORM_FIELD_TYPE_INT||type_name==ORM_FIELD_TYPE_UINT) { sprintf(buffer,"%d",*(int*)p); vbi->validator_->SetText(buffer);} else if (type_name==ORM_FIELD_TYPE_SHORT||type_name==ORM_FIELD_TYPE_USHORT) { sprintf(buffer,"%d",*(short*)p); vbi->validator_->SetText(buffer);} else if (type_name==ORM_FIELD_TYPE_INT1||type_name==ORM_FIELD_TYPE_UINT1) { sprintf(buffer,"%c",*p); vbi->validator_->SetText(buffer);}else if (type_name==ORM_FIELD_TYPE_FLOAT) { vbi->validator_->SetText(p);} else if (type_name==ORM_FIELD_TYPE_DOUBLE) { sprintf(buffer,"%.3f",*(double*)p); ///< @todo: 根据长度定义确定格式 vbi->validator_->SetText(buffer);} else if (type_name==ORM_FIELD_TYPE_STRING) { string s = *(string*)p; vbi->validator_->SetText(s.c_str());} else if (type_name==ORM_FIELD_TYPE_CHAR||type_name==ORM_FIELD_TYPE_UCHAR) { vbi->validator_->SetText(p);} else if (type_name==ORM_FIELD_TYPE_INT64||type_name==ORM_FIELD_TYPE_UINT64) { sprintf(buffer,"%I64d",*(__int64*)p); vbi->validator_->SetText(buffer);} else if (type_name==ORM_FIELD_TYPE_BOOL) { sprintf(buffer,"%d",*(bool*)p); vbi->validator_->SetText(buffer);}else { iter++; ///< 不支持的数据类型 continue;} iter++; } return 0;}//---------------------------------------------------------------------------template <class T> int CObjectValidator<T>::Check(T *obj) { vector<CValidatorBindInfo*>::iterator iter = bind_info_.begin(); while(iter!=bind_info_.end()) { CValidatorBindInfo *vbi = *iter; char *p = (char*)obj+vbi->offset_;string type_name = vbi->var_type_.c_str(); int ret = 0;if (type_name==ORM_FIELD_TYPE_LONG||type_name==ORM_FIELD_TYPE_ULONG) {ret = vbi->validator_->Check((void*)*(long*)p);}else if (type_name==ORM_FIELD_TYPE_INT||type_name==ORM_FIELD_TYPE_UINT) {ret = vbi->validator_->Check((void*)*(int*)p);} else if (type_name==ORM_FIELD_TYPE_SHORT||type_name==ORM_FIELD_TYPE_USHORT) {ret = vbi->validator_->Check((void*)*(short*)p);} else if (type_name==ORM_FIELD_TYPE_INT1||type_name==ORM_FIELD_TYPE_UINT1) { ret = vbi->validator_->Check((void*)*p);}else if (type_name==ORM_FIELD_TYPE_FLOAT) {ret = vbi->validator_->Check((void*)p);} else if (type_name==ORM_FIELD_TYPE_DOUBLE) {ret = vbi->validator_->Check((void*)p);} else if (type_name==ORM_FIELD_TYPE_STRING) { string s = *(string*)p;ret = vbi->validator_->Check((void*)s.c_str());} else if (type_name==ORM_FIELD_TYPE_CHAR||type_name==ORM_FIELD_TYPE_UCHAR) {ret = vbi->validator_->Check((void*)p);} else if (type_name==ORM_FIELD_TYPE_INT64||type_name==ORM_FIELD_TYPE_UINT64) {ret = vbi->validator_->Check((void*)*(__int64*)p);} else if (type_name==ORM_FIELD_TYPE_BOOL) {ret = vbi->validator_->Check((void*)*(bool*)p);}else { iter++; ///< 不支持的数据类型 continue;} if (ret==0) { err_vbi_ = vbi; if (auto_hint_) { string err_msg = GetErrorInfo(); ShowMessage(err_msg.c_str()); } if (auto_focus_) { vbi->validator_->control_->SetFocus(); } return 0; } iter++; } return 1;}};
3.实现
实现文件:validator.cpp
#pragma hdrstop#include "validator.h"#include "NullForm.h"using namespace ns_validator;#pragma package(smart_init)//---------------------------------------------------------------------------CValidatorBase::CValidatorBase():max_len_(0),min_len_(0),control_(0),null_form_(0),null_flag_(true) {}//---------------------------------------------------------------------------CValidatorBase::~CValidatorBase() { if (null_form_) delete null_form_;}//---------------------------------------------------------------------------int CValidatorBase::CheckChar(char ch) { if (v_ch_set_.empty()) return 1; CAutoVector<CValidCharSet*>::iterator iter = v_ch_set_.begin(); while(iter!=v_ch_set_.end()) { CValidCharSet *vcs = *iter; switch(vcs->type_) { case CS_DIGIT: if (isdigit(ch)) return 1; case CS_ALPHA: if (isalpha(ch)==0) return 1; default: if (strchr(vcs->chars_.c_str(),ch)) return 1; } iter++; } return 0;}//---------------------------------------------------------------------------int CValidatorBase::CheckInput(char ch) { ///< 检查当前输入字符 if (CheckChar(ch)==0) { ///< 字符是否有效 return 0; } char *Buffer = 0; if (control_->CheckInput(ch,&Buffer)==0) { return 0; } int Size = strlen(Buffer); if (max_len_) { if (Size>max_len_) { delete []Buffer; return 0; } } int ret = CheckText(Buffer,0); delete []Buffer; return ret;}//---------------------------------------------------------------------------///< 设置有效字符void CValidatorBase::AddValidChar(VALID_CHARSET_TYPE type) { CValidCharSet *vcs = new CValidCharSet; vcs->type_ = type; v_ch_set_.push_back(vcs);}//---------------------------------------------------------------------------void CValidatorBase::AddValidChar(const char *s) { CValidCharSet *vcs = new CValidCharSet; vcs->type_ = CS_STRING; vcs->chars_ = s; v_ch_set_.push_back(vcs);}//---------------------------------------------------------------------------void CValidatorBase::BindControl(CBindControl *control) { control_ = control; null_form_ = new TfrmNull(0); null_form_->Visible = false; null_form_->SetValidator(this); control_->SetOnKeyPress(null_form_->EditKeyPress);}//---------------------------------------------------------------------------int CValidatorBase::GetText(string &text) { text = control_->GetValue(); return 0;}//---------------------------------------------------------------------------void CValidatorBase::SetText(const char *text) { control_->SetValue((char*)text);}//---------------------------------------------------------------------------CIntValidator::CIntValidator() { AddValidChar(CS_DIGIT);}//---------------------------------------------------------------------------int CIntValidator::Check(void *val,int flag) { ///< 校验合法性 long nval = (long)val; return CNumberRange<long>::Check(nval,flag);}//---------------------------------------------------------------------------int CIntValidator::CheckText(const char *text,int flag) { long val = atol(text); return Check((char*)val,flag);}//---------------------------------------------------------------------------CDecimalValidator::CDecimalValidator():scale_(2) { AddValidChar(CS_DIGIT); AddValidChar("."); ///< 允许小数点}//---------------------------------------------------------------------------int CDecimalValidator::Check(void *val,int flag) { double fval = *(double*)val; return CNumberRange<double>::Check(fval,flag);}//---------------------------------------------------------------------------int CDecimalValidator::CheckText(const char *text,int flag) { double val = atof(text); if (Check((void*)&val,flag)==0) return 0; if (scale_) { ///< 检查小数长度 const char *p = strchr(text,'.'); if (p) { int scale_n = strlen(p)-1; if (scale_n>scale_) return 0; } } return 1;}//---------------------------------------------------------------------------CStringValidator::CStringValidator(){}//---------------------------------------------------------------------------CStringValidator::CStringValidator(unsigned int min_len,unsigned int max_len) { min_len_ = min_len; max_len_ = max_len;}//---------------------------------------------------------------------------int CStringValidator::Check(void *val,int flag) { const char *sz_val = (const char*)val; int len = strlen(sz_val); if (flag) { if (min_len_) { if (len<min_len_) return 0; } } if (max_len_) { if (len>max_len_) return 0; } if (!v_ch_set_.empty()) { ///< 检查是否是有效字符 const char *p = sz_val; while(*p!='\0') { if (CheckChar(*p)==0) return 0; p++; }; } return 1;}//---------------------------------------------------------------------------int CStringValidator::CheckText(const char *text,int flag) { return Check((char*)text,flag);}//---------------------------------------------------------------------------CEdit::CEdit(TEdit *control):control_(control) {}//---------------------------------------------------------------------------void CEdit::SetOnKeyPress(TKeyPressEvent e) { control_->OnKeyPress = e;}//---------------------------------------------------------------------------int CEdit::CheckInput(char ch,char **out) { int Size = control_->GetTextLen(); ///< 当前已接收内容的长度 int sel_pos = control_->SelStart; ///< 对接受此输入后的结果进行检查(不检查最小值和最小长度:因正在输入过程) char *Buffer = new char[Size+2]; control_->GetTextBuf(Buffer,Size+2); int sel_len = control_->SelLength; if (sel_len>0) { memcpy(&Buffer[sel_pos],&Buffer[sel_pos+sel_len],Size-sel_pos-sel_len+1); Size = strlen(Buffer); } int k = Size; while(k>=sel_pos) { char ch = Buffer[k]; Buffer[k+1] = ch; k--; } Buffer[sel_pos] = ch; Buffer[Size+1] = '\0'; *out = Buffer; return 1;}//---------------------------------------------------------------------------string CEdit::GetValue() { return control_->Text.c_str();}//---------------------------------------------------------------------------void CEdit::SetValue(const char *value) { control_->Text = value;}//---------------------------------------------------------------------------CComboBox::CComboBox(TComboBox *control,short flag,CCodeTableMgr<CCodeTableBase,string> *code_table) :control_(control),flag_(flag),code_table_(code_table) {}//---------------------------------------------------------------------------string CComboBox::GetValue() {// assert(control_->ItemIndex!=-1); if (control_->ItemIndex==-1) { return string(); } if (flag_==1) { int count = code_table_->GetSize(); for (int i=0;i<count;i++) { CCodeTableBase *item = (*code_table_)[i]; if (stricmp(item->name_.c_str(),control_->Text.c_str())) { return item->code_; } } } return control_->Text.c_str();}//---------------------------------------------------------------------------void CComboBox::SetValue(const char *value) { if (flag_==1) { int count = code_table_->GetSize(); for (int i=0;i<count;i++) { CCodeTableBase *item = (*code_table_)[i]; if (stricmp(item->name_.c_str(),control_->Text.c_str())) { control_->ItemIndex = i; return; } } } control_->ItemIndex = -1;}//---------------------------------------------------------------------------CDateTimePicker::CDateTimePicker(TDateTimePicker *control,int flag):control_(control),flag_(flag) {}//---------------------------------------------------------------------------string CDateTimePicker::GetValue() { TDateTime dt = control_->DateTime; AnsiString result; switch(flag_) { case 1: result = dt.FormatString("yyyy-mm-dd hh:nn:ss"); break; case 2: result = dt.FormatString("yyyy-mm-dd"); break; case 3: result = dt.FormatString("hh:nn:ss"); break; } return result.c_str();}//---------------------------------------------------------------------------void CDateTimePicker::SetValue(const char *value) { AnsiString s(value); TDateTime dt(s); control_->DateTime = dt;}
NullForm.cpp
void __fastcall TfrmNull::EditKeyPress(TObject *Sender, char &Key) { if (iscntrl(Key)) { ///< 删除等操作 return; } assert(validator_!=0); if (validator_->CheckInput(Key)==0) { Key = 0; return; }}
4.示例:
#include "validator.h"
using namespace ns_validator;
//---------------------------------------------------------------------------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); ov_.SetValidator(NEW_VALIDATOR_BIND(CGYBGoods, m_strGoodsid,ORM_FIELD_TYPE_STRING,sv,"商品GTIN")); ///< 零售价:小数数值,长度(8,3)--长度8位(含小数点和小数位),小数位最大3位,只能是正数,有效字符:0-9,'.' CDecimalValidator *dv = new CDecimalValidator; dv->SetMaxLength(8); dv->SetScale(3); ov_.SetValidator(NEW_VALIDATOR_BIND(CGYBGoods,m_dRetailPrice,ORM_FIELD_TYPE_DOUBLE,dv,"建议零售价")); ///< 装箱数 CIntValidator *iv = new CIntValidator; iv->SetMaxLength(6); ov_.SetValidator(NEW_VALIDATOR_BIND(CGYBGoods,m_iBoxCount,ORM_FIELD_TYPE_INT,iv,"装箱数")); ///< 税率 dv = new CDecimalValidator; ov_.SetValidator(NEW_VALIDATOR_BIND(CGYBGoods,m_dTaxRate,ORM_FIELD_TYPE_DOUBLE,dv,"税率")); sv = new CStringValidator; ov_.SetValidator(NEW_VALIDATOR_BIND(CGYBGoods,m_strOrderBegin,ORM_FIELD_TYPE_STRING,sv,"订单开始日期")); sv = new CStringValidator; ov_.SetValidator(NEW_VALIDATOR_BIND(CGYBGoods,m_strOrderEnd,ORM_FIELD_TYPE_STRING,sv,"订单截止日期")); ///< 绑定控件 ov_.BindControl(OFFSETOF(CGYBGoods, m_strGoodsid),new CEdit(edtGTIN)); ov_.BindControl(OFFSETOF(CGYBGoods, m_dRetailPrice),new CEdit(edtPrice)); ov_.BindControl(OFFSETOF(CGYBGoods, m_iBoxCount),new CEdit(edtBoxNum)); ///< 税率绑定的是TComboBox ov_.BindControl(OFFSETOF(CGYBGoods, m_dTaxRate),new CComboBox(cbTaxRate,1,&tax_rate_code_tbl_)); ///< 销售开始和截止日期绑定的是TDatTimePicker ov_.BindControl(OFFSETOF(CGYBGoods, m_strOrderBegin),new CDateTimePicker(dtpSaleBegin,2)); ov_.BindControl(OFFSETOF(CGYBGoods, m_strOrderEnd),new CDateTimePicker(dtpSaleEnd,2)); ///< 初始化税率码表 tax_rate_code_tbl_.Add("1",new CCodeTableBase("1","0.015")); tax_rate_code_tbl_.Add("2",new CCodeTableBase("2","0.013")); int item_num = tax_rate_code_tbl_.GetSize(); for (int i=0;i<item_num;i++) { CCodeTableBase *item = tax_rate_code_tbl_[i]; cbTaxRate->Items->AddObject(item->name_.c_str(),(TObject*)item); } return;}//---------------------------------------------------------------------------void __fastcall TForm1::btnOkClick(TObject *Sender){ int ret = 0; ///< 把控件内容更新到对象 ret = ov_.Update(&goods_); ///< 从对象加载到控件 goods_.m_strGoodsid = "134"; goods_.m_dRetailPrice = 12.01; goods_.m_iBoxCount = 120; goods_.m_dTaxRate = 1; goods_.m_strOrderBegin = "2013-1-1"; goods_.m_strOrderEnd = "2014-1-15"; ret = ov_.Load(&goods_); ///< 校验对象数据 ret = ov_.Check(&goods_); return;}
- 客户端数据校验器
- 用Javascript校验客户端数据
- 客户端数据校验器中的2个bug
- 用Javascript校验客户端数据1.2
- 用Javascript校验客户端数据(1)
- javascript进行客户端数据的校验
- 客户端校验
- 客户端数据校验的通用解决之道----妙用自定义属性 (JS)
- struts2之数据校验器
- 数据校验
- 数据校验
- 数据校验
- 数据校验
- 数据校验
- struts客户端校验
- Struts2使用客户端校验
- 客户端js校验及服务器端校验安全问题
- 服务器端校验(更重要)和客户端校验
- Android 下通过jni读取i2c数据
- 时间字段的读取
- css中的*代表对所有控件起作用
- UVa 10069 - Distinct Subsequences
- Eclipse用法和技巧七:自动生成get和set方法2
- 客户端数据校验器
- 操作系统μC/OS-II的特点
- android 工程开发问题Failed java.util.EmptyStackException
- "*.exe不是有效的Win32程序" 解决办法
- UVa 10911 - Forming Quiz Teams
- firefox不能显示下载进度窗口
- PKG_CONFIG_PATH
- 转载Java内部类的使用小结
- 软件工程--软件过程模型