T-Rex wrote:
Лучше обзови его как-то по-другому и расскажи текстуально что менял, а я выложу на wxwidgets.info, так больше народу посмотрит
Если свой класс делать ясное дело нужно по другому назвать, а что менять я написал вроде только знак в условии перед WXK_START с больше на равно.
Итак, проблема: wxTextValidator не отрабатывает русские символы.
Типа решение
(смех да и только) я ж говорил ошибка то досадная.
Вот мой клас потомок уже исправленный
myvaltext.h - абсолютно одинаков с оригинальным оригинален
Code: Select all
#pragma once
#ifndef myvaltextH
#define myvaltextH
//#include "wx/defs.h"
#include "wx/wxprec.h"
//#ifndef WX_PRECOMP
#include "wx/wx.h"
//#endif
#if wxUSE_VALIDATORS && wxUSE_TEXTCTRL
#include "wx/textctrl.h"
#include "wx/validate.h"
#define wxFILTER_NONE 0x0000
#define wxFILTER_ASCII 0x0001
#define wxFILTER_ALPHA 0x0002
#define wxFILTER_ALPHANUMERIC 0x0004
#define wxFILTER_NUMERIC 0x0008
#define wxFILTER_INCLUDE_LIST 0x0010
#define wxFILTER_EXCLUDE_LIST 0x0020
#define wxFILTER_INCLUDE_CHAR_LIST 0x0040
#define wxFILTER_EXCLUDE_CHAR_LIST 0x0080
class MyTextValidator: public wxValidator
{
DECLARE_DYNAMIC_CLASS(MyTextValidator)
public:
MyTextValidator(long style = wxFILTER_NONE, wxString *val = 0);
MyTextValidator(const MyTextValidator& val);
virtual ~MyTextValidator(){}
// Make a clone of this validator (or return NULL) - currently necessary
// if you're passing a reference to a validator.
// Another possibility is to always pass a pointer to a new validator
// (so the calling code can use a copy constructor of the relevant class).
virtual wxObject *Clone() const { return new MyTextValidator(*this); }
bool Copy(const MyTextValidator& val);
// Called when the value in the window must be validated.
// This function can pop up an error message.
virtual bool Validate(wxWindow *parent);
// Called to transfer data to the window
virtual bool TransferToWindow();
// Called to transfer data from the window
virtual bool TransferFromWindow();
// ACCESSORS
inline long GetStyle() const { return m_validatorStyle; }
inline void SetStyle(long style) { m_validatorStyle = style; }
#if WXWIN_COMPATIBILITY_2_4
wxDEPRECATED( void SetIncludeList(const wxStringList& list) );
wxDEPRECATED( wxStringList& GetIncludeList() );
wxDEPRECATED( void SetExcludeList(const wxStringList& list) );
wxDEPRECATED( wxStringList& GetExcludeList() );
wxDEPRECATED( bool IsInCharIncludeList(const wxString& val) );
wxDEPRECATED( bool IsNotInCharExcludeList(const wxString& val) );
#endif
void SetIncludes(const wxArrayString& includes) { m_includes = includes; }
inline wxArrayString& GetIncludes() { return m_includes; }
void SetExcludes(const wxArrayString& excludes) { m_excludes = excludes; }
inline wxArrayString& GetExcludes() { return m_excludes; }
bool IsInCharIncludes(const wxString& val);
bool IsNotInCharExcludes(const wxString& val);
// Filter keystrokes
void OnChar(wxKeyEvent& event);
DECLARE_EVENT_TABLE()
protected:
long m_validatorStyle;
wxString * m_stringValue;
#if WXWIN_COMPATIBILITY_2_4
wxStringList m_includeList;
wxStringList m_excludeList;
#endif
wxArrayString m_includes;
wxArrayString m_excludes;
bool CheckValidator() const
{
wxCHECK_MSG( m_validatorWindow, false,
_T("No window associated with validator") );
wxCHECK_MSG( m_validatorWindow->IsKindOf(CLASSINFO(wxTextCtrl)), false,
_T("MyTextValidator is only for wxTextCtrl's") );
return true;
}
private:
// Cannot use
// DECLARE_NO_COPY_CLASS(MyTextValidator)
// because copy constructor is explicitly declared above;
// but no copy assignment operator is defined, so declare
// it private to prevent the compiler from defining it:
MyTextValidator& operator=(const MyTextValidator&);
};
#endif
// wxUSE_VALIDATORS && wxUSE_TEXTCTRL
#endif
myvaltext.cpp - тоже практически то же самое толко как и сказал выше знак поменял в условии в обработке OnChar. Я там в коде пометил где.
Code: Select all
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#if wxUSE_VALIDATORS && wxUSE_TEXTCTRL
#include "myvaltext.h"
#ifndef WX_PRECOMP
#include <stdio.h>
#include "wx/textctrl.h"
#include "wx/utils.h"
#include "wx/msgdlg.h"
#include "wx/intl.h"
#endif
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#ifdef __SALFORDC__
#include <clib.h>
#endif
IMPLEMENT_DYNAMIC_CLASS(MyTextValidator, wxValidator)
BEGIN_EVENT_TABLE(MyTextValidator, wxValidator)
EVT_CHAR(MyTextValidator::OnChar)
END_EVENT_TABLE()
static bool wxIsNumeric(const wxString& val);
MyTextValidator::MyTextValidator(long style, wxString *val)
{
m_validatorStyle = style;
m_stringValue = val;
/*
m_refData = new wxVTextRefData;
M_VTEXTDATA->m_validatorStyle = style;
M_VTEXTDATA->m_stringValue = val;
*/
}
MyTextValidator::MyTextValidator(const MyTextValidator& val)
: wxValidator()
{
Copy(val);
}
bool MyTextValidator::Copy(const MyTextValidator& val)
{
wxValidator::Copy(val);
m_validatorStyle = val.m_validatorStyle;
m_stringValue = val.m_stringValue;
m_includes = val.m_includes;
m_excludes = val.m_excludes;
return true;
}
static bool wxIsAlpha(const wxString& val)
{
int i;
for ( i = 0; i < (int)val.length(); i++)
{
if (!wxIsalpha(val[i]))
return false;
}
return true;
}
static bool wxIsAlphaNumeric(const wxString& val)
{
int i;
for ( i = 0; i < (int)val.length(); i++)
{
if (!wxIsalnum(val[i]))
return false;
}
return true;
}
// Called when the value in the window must be validated.
// This function can pop up an error message.
bool MyTextValidator::Validate(wxWindow *parent)
{
if( !CheckValidator() )
return false;
wxTextCtrl *control = (wxTextCtrl *) m_validatorWindow;
// If window is disabled, simply return
if ( !control->IsEnabled() )
return true;
wxString val(control->GetValue());
bool ok = true;
// NB: this format string should contian exactly one '%s'
wxString errormsg;
bool includes = (m_validatorStyle & wxFILTER_INCLUDE_LIST) != 0;
if ( includes || (m_validatorStyle & wxFILTER_EXCLUDE_LIST) )
{
// if includes, it's only ok to have the members of the list,
// otherwise it's only ok to have non-members
ok = includes == (m_includes.Index(val) != wxNOT_FOUND);
if ( !ok )
{
errormsg = _("'%s' is invalid");
}
}
else if ( (m_validatorStyle & wxFILTER_ASCII) && !val.IsAscii() )
{
ok = false;
errormsg = _("'%s' should only contain ASCII characters.");
}
else if ( (m_validatorStyle & wxFILTER_ALPHA) && !wxIsAlpha(val) )
{
ok = false;
errormsg = _("'%s' should only contain alphabetic characters.");
}
else if ( (m_validatorStyle & wxFILTER_ALPHANUMERIC) && !wxIsAlphaNumeric(val))
{
ok = false;
errormsg = _("'%s' should only contain alphabetic or numeric characters.");
}
else if ( (m_validatorStyle & wxFILTER_NUMERIC) && !wxIsNumeric(val))
{
ok = false;
errormsg = _("'%s' should be numeric.");
}
else if ( (m_validatorStyle & wxFILTER_INCLUDE_CHAR_LIST) && !IsInCharIncludes(val))
{
//it's only ok to have the members of the list
errormsg = _("'%s' is invalid");
ok = false;
}
else if ( (m_validatorStyle & wxFILTER_EXCLUDE_CHAR_LIST) && !IsNotInCharExcludes(val))
{
// it's only ok to have non-members of the list
errormsg = _("'%s' is invalid");
ok = false;
}
if ( !ok )
{
wxASSERT_MSG( !errormsg.empty(), _T("you forgot to set errormsg") );
m_validatorWindow->SetFocus();
wxString buf;
buf.Printf(errormsg, val.c_str());
wxMessageBox(buf, _("Validation conflict"),
wxOK | wxICON_EXCLAMATION, parent);
}
return ok;
}
// Called to transfer data to the window
bool MyTextValidator::TransferToWindow(void)
{
if( !CheckValidator() )
return false;
if ( m_stringValue )
{
wxTextCtrl *control = (wxTextCtrl *) m_validatorWindow;
control->SetValue(* m_stringValue);
}
return true;
}
// Called to transfer data to the window
bool MyTextValidator::TransferFromWindow(void)
{
if( !CheckValidator() )
return false;
if ( m_stringValue )
{
wxTextCtrl *control = (wxTextCtrl *) m_validatorWindow;
*m_stringValue = control->GetValue();
}
return true;
}
#if WXWIN_COMPATIBILITY_2_4
inline void wxCopyStringListToArrayString(wxArrayString& to, const wxStringList& from)
{
to.Clear();
for ( wxStringList::compatibility_iterator pNode = from.GetFirst();
pNode;
pNode = pNode->GetNext() )
{
to.Add(pNode->GetData());
}
}
inline void wxCopyArrayStringToStringList(wxStringList& to, const wxArrayString& from)
{
to.Clear();
for(size_t i = 0; i < from.GetCount(); ++i)
to.Add(from[i]);
}
wxStringList& MyTextValidator::GetIncludeList()
{
wxCopyArrayStringToStringList(m_includeList, m_includes);
return m_includeList;
}
wxStringList& MyTextValidator::GetExcludeList()
{
wxCopyArrayStringToStringList(m_excludeList, m_excludes);
return m_excludeList;
}
void MyTextValidator::SetIncludeList(const wxStringList& list)
{
wxCopyStringListToArrayString(m_includes, list);
}
void MyTextValidator::SetExcludeList(const wxStringList& list)
{
wxCopyStringListToArrayString(m_excludes, list);
}
bool MyTextValidator::IsInCharIncludeList(const wxString& val)
{
return IsInCharIncludes(val);
}
bool MyTextValidator::IsNotInCharExcludeList(const wxString& val)
{
return IsNotInCharExcludes(val);
}
#endif //compat 2.4
bool MyTextValidator::IsInCharIncludes(const wxString& val)
{
size_t i;
for ( i = 0; i < val.length(); i++)
{
if (m_includes.Index((wxString) val[i]) == wxNOT_FOUND)
return false;
}
return true;
}
bool MyTextValidator::IsNotInCharExcludes(const wxString& val)
{
size_t i;
for ( i = 0; i < val.length(); i++)
{
if (m_excludes.Index((wxString) val[i]) != wxNOT_FOUND)
return false;
}
return true;
}
void MyTextValidator::OnChar(wxKeyEvent& event)
{
/*
if ( !M_VTEXTDATA )
return;
*/
if ( m_validatorWindow )
{
int keyCode = event.GetKeyCode();
int test = WXK_START;
// we don't filter special keys and Delete
if (
!(keyCode < WXK_SPACE || keyCode == WXK_DELETE || keyCode /*тут поменял*/== WXK_START) &&
(
((m_validatorStyle & wxFILTER_INCLUDE_CHAR_LIST) && !IsInCharIncludes(wxString((wxChar) keyCode, 1))) ||
((m_validatorStyle & wxFILTER_EXCLUDE_CHAR_LIST) && !IsNotInCharExcludes(wxString((wxChar) keyCode, 1))) ||
((m_validatorStyle & wxFILTER_ASCII) && !isascii(keyCode)) ||
((m_validatorStyle & wxFILTER_ALPHA) && !wxIsalpha(keyCode)) ||
((m_validatorStyle & wxFILTER_ALPHANUMERIC) && !wxIsalnum(keyCode)) ||
((m_validatorStyle & wxFILTER_NUMERIC) && !wxIsdigit(keyCode)
&& keyCode != wxT('.') && keyCode != wxT(',') && keyCode != wxT('-') && keyCode != wxT('+') && keyCode != wxT('e') && keyCode != wxT('E'))
)
)
{
if ( !wxValidator::IsSilent() )
wxBell();
// eat message
return;
}
}
event.Skip();
}
static bool wxIsNumeric(const wxString& val)
{
int i;
for ( i = 0; i < (int)val.length(); i++)
{
// Allow for "," (French) as well as "." -- in future we should
// use wxSystemSettings or other to do better localisation
if ((!wxIsdigit(val[i])) && (val[i] != wxT('.')) && (val[i] != wxT(',')) && (val[i] != wxT('e')) && (val[i] != wxT('E')) && (val[i] != wxT('+')) && (val[i] != wxT('-')))
return false;
}
return true;
}
#endif
Пользовать так
Code: Select all
wxTextCtrl *Sum = new wxTextCtrl(Panel1, ID_TEXTCTRL1, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_TEXTCTRL1"));
MyTextValidator validator(wxFILTER_INCLUDE_CHAR_LIST);
wxArrayString list;
wxString valid_chars(wxT("0123456789,."));
size_t len = valid_chars.Length();
for (size_t i=0; i<len; i++)
list.Add(wxString(valid_chars.GetChar(i)));
validator.SetIncludes(list);
Sum->SetValidator(validator);
Теперь в TextCtrl Sum можно вводить только цифры и точку с запятой при чем это работает и с русскими буквами. Вставку через буфер обмена это не касается с буфером как то по другому надо.
К стати wxTextValidator работает ТОЛЬКО для wxTextCtrl если в классе который я показал, поменять обявления wxTextCtrl на wxComboBox будет работать для ComboBox