• 自定义控件wxIpCtrl –(Ip Address)


    wxIpCtrl派生自wxPanel,构造函数看起来象这样:

    class wxIpCtrl : public wxPanel
    {
       
    public:
       wxIpCtrl(wxWindow *parent, wxWindowID id = wxID_ANY, const wxString& ipaddr = wxT("192.168.1.12"), long style = wxIPCTRL_DEFAULT_STYLE);
    
       wxString GetValue() const;
      ...
    };
    

    GetValue 的返回值是wxString类型,这也就是读取这个控件里用户交互的东东。

    因为派生自wxPanel,所以把它当成wxPanel来用就可以了,象下面这样就可以产生它的一个实例:

    wxIpCtrl* Panel1 = new wxIpCtrl(this, wxID_ANY);
    

    运行下面的例子程序的效果图:

    客户程序:

    TestMain.cpp

    /***************************************************************
     * Name:      TestMain.cpp
     * Purpose:   Code for Application Frame
     * Author:    XCool
     * Created:   2012-04-05
     * Copyright: 
     * License:   LGPL
     **************************************************************/
    
    #include "TestMain.h"
    #include <wx/msgdlg.h>
    
    //(*InternalHeaders(TestDialog)
    #include <wx/intl.h>
    #include <wx/string.h>
    //*)
    
    //helper functions
    enum wxbuildinfoformat {
        short_f, long_f };
    
    wxString wxbuildinfo(wxbuildinfoformat format)
    {
        wxString wxbuild(wxVERSION_STRING);
    
        if (format == long_f )
        {
    #if defined(__WXMSW__)
            wxbuild << _T("-Windows");
    #elif defined(__UNIX__)
            wxbuild << _T("-Linux");
    #endif
    
    #if wxUSE_UNICODE
            wxbuild << _T("-Unicode build");
    #else
            wxbuild << _T("-ANSI build");
    #endif // wxUSE_UNICODE
        }
    
        return wxbuild;
    }
    
    //(*IdInit(TestDialog)
    const long TestDialog::ID_PANEL1 = wxNewId();
    //*)
    
    BEGIN_EVENT_TABLE(TestDialog,wxDialog)
        //(*EventTable(TestDialog)
        //*)
    END_EVENT_TABLE()
    
    TestDialog::TestDialog(wxWindow* parent,wxWindowID id)
    {
        //(*Initialize(TestDialog)
        wxFlexGridSizer* FlexGridSizer1;
    
        Create(parent, id, _("wxWidgets app"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE, _T("id"));
        SetClientSize(wxSize(348,239));
        BoxSizer1 = new wxBoxSizer(wxHORIZONTAL);
        FlexGridSizer1 = new wxFlexGridSizer(0, 3, 0, 0);
        Panel1 = new wxIpCtrl(this, ID_PANEL1/*, wxDefaultPosition, wxSize(137,67), wxTAB_TRAVERSAL, _T("ID_PANEL1")*/);
        FlexGridSizer1->Add(Panel1, 1, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
        BoxSizer1->Add(FlexGridSizer1, 1, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
        SetSizer(BoxSizer1);
        BoxSizer1->SetSizeHints(this);
        //*)
    }
    
    TestDialog::~TestDialog()
    {
        //(*Destroy(TestDialog)
        //*)
    }
    
    void TestDialog::OnQuit(wxCommandEvent& event)
    {
        Close();
    }
    
    void TestDialog::OnAbout(wxCommandEvent& event)
    {
        wxString msg = wxbuildinfo(long_f);
        wxMessageBox(msg, _("Welcome to..."));
    }
    

    TestMain.h

    /***************************************************************
     * Name:      TestMain.h
     * Purpose:   Defines Application Frame
     * Author:    XCool
     * Created:   2012-04-05
     * Copyright: 
     * License:   LGPL
     **************************************************************/
    
    #ifndef TESTMAIN_H
    #define TESTMAIN_H
    
    //(*Headers(TestDialog)
    #include <wx/sizer.h>
    #include <wx/panel.h>
    #include <wx/dialog.h>
    //*)
    #include "wxipctrl.h"
    class TestDialog: public wxDialog
    {
        public:
    
            TestDialog(wxWindow* parent,wxWindowID id = -1);
            virtual ~TestDialog();
    
        private:
    
            //(*Handlers(TestDialog)
            void OnQuit(wxCommandEvent& event);
            void OnAbout(wxCommandEvent& event);
            //*)
    
            //(*Identifiers(TestDialog)
            static const long ID_PANEL1;
            //*)
    
            //(*Declarations(TestDialog)
            wxIpCtrl* Panel1;
            wxBoxSizer* BoxSizer1;
            //*)
    
            DECLARE_EVENT_TABLE()
    };
    
    #endif // TESTMAIN_H
    

     TestApp.cpp

    /***************************************************************
     * Name:      TestApp.cpp
     * Purpose:   Code for Application Class
     * Author:    XCool
     * Created:   2012-04-05
     * Copyright: 
     * License:   LGPL
     **************************************************************/
    
    #include "TestApp.h"
    
    //(*AppHeaders
    #include "TestMain.h"
    #include <wx/image.h>
    //*)
    
    IMPLEMENT_APP(TestApp);
    
    bool TestApp::OnInit()
    {
        //(*AppInitialize
        bool wxsOK = true;
        wxInitAllImageHandlers();
        if ( wxsOK )
        {
        	TestDialog Dlg(0);
        	SetTopWindow(&Dlg);
        	Dlg.ShowModal();
        	wxsOK = false;
        }
        //*)
        return wxsOK;
    
    }
    

     TestApp.h

    /***************************************************************
     * Name:      TestApp.h
     * Purpose:   Defines Application Class
     * Author:    XCool
     * Created:   2012-04-05
     * Copyright: 
     * License:   LGPL
     **************************************************************/
    
    #ifndef TESTAPP_H
    #define TESTAPP_H
    
    #include <wx/app.h>
    
    class TestApp : public wxApp
    {
        public:
            virtual bool OnInit();
    };
    
    #endif // TESTAPP_H
    

     以下为自定义控件 wxIpCtrl的源码:

    wxIpCtrl.h

     

    #ifndef WXIPCTRL_H_INCLUDED
    #define WXIPCTRL_H_INCLUDED
    
    #include <wx/wx.h>
    
    DECLARE_EVENT_TYPE(wxEVT_IPCTRL_CHANGED, wxID_ANY);
    
    
    // wxIpCtrl styles
    #define wxIPCTRL_D_CLASS         1
    #define wxIPCTRL_ALL_CLASSES    2
    #define wxIPCTRL_SUBNET_MASK     wxIPCTRL_ALL_CLASSES
    #define wxIPCTRL_DEFAULT_STYLE   0
    
    
    /**
     * \class wxIPCtrl
     */
    class wxIpCtrl : public wxPanel
    {
       long          m_ipStyle;
       wxArrayString m_defaultValue;
    
       wxBoxSizer* m_sizer;
    
       wxTextCtrl* m_editIP1;
       wxTextCtrl* m_editIP2;
       wxTextCtrl* m_editIP3;
       wxTextCtrl* m_editIP4;
    
       wxStaticText* m_dot1;
       wxStaticText* m_dot2;
       wxStaticText* m_dot3;
    
    public:
       wxIpCtrl(wxWindow *parent, wxWindowID id = wxID_ANY, const wxString& ipaddr = wxT("192.168.1.12"), long style = wxIPCTRL_DEFAULT_STYLE);
    
       wxString GetValue() const;
       bool SetValue(const wxString& ipaddr);
    
       void SetStyle(long style) { m_ipStyle = style; }
       long GetStyle() { return m_ipStyle; }
    
       virtual bool Enable(bool enable = true);
    
    protected:
       void CreateGui();
       wxTextCtrl* CreateTextCtrl();
       wxStaticText* CreateDot();
    
       bool CheckIp(const wxString& ipaddr, wxArrayString& ipParts) const;
       bool CheckRange(const wxString& value, unsigned long min, unsigned long max) const;
       void DoSetValue(const wxArrayString& ipParts);
       void DoSetDefaultValue();
    
       virtual void OnChar(wxKeyEvent& event);
       virtual void OnTextUpdated(wxCommandEvent& event);
    };
    
    
    #endif // WXIPCTRL_H_INCLUDED
    

     wxIpCtrl.cpp

    #include "wxipctrl.h"
    #include <wx/regex.h>
    #include <wx/msgdlg.h>
    
    DEFINE_EVENT_TYPE(wxEVT_IPCTRL_CHANGED);
    
    static
    bool in_range(unsigned long value, unsigned long min, unsigned long max)
    {
       return min <= value && value <= max;
    }
    
    /**
     *
     */
    wxIpCtrl::wxIpCtrl(wxWindow *parent, wxWindowID id, const wxString& ipaddr, long style)
    : wxPanel(parent, id, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER|wxTAB_TRAVERSAL)
    , m_ipStyle(style)
    {
       CreateGui();
    
       m_defaultValue.Add( wxT("192") );
       m_defaultValue.Add( wxT("168") );
       m_defaultValue.Add( wxT("1") );
       m_defaultValue.Add( wxT("12") );
    
       if (m_ipStyle & wxIPCTRL_D_CLASS) {
          m_defaultValue.Item(0) = wxT("224");
       }
    
       SetValue(ipaddr);
    
       Connect( wxEVT_CHAR, wxKeyEventHandler( wxIpCtrl::OnChar ) );
       m_editIP1->Connect( wxEVT_CHAR, wxKeyEventHandler( wxIpCtrl::OnChar ), NULL, this );
       m_editIP1->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( wxIpCtrl::OnTextUpdated ), NULL, this );
       m_editIP2->Connect( wxEVT_CHAR, wxKeyEventHandler( wxIpCtrl::OnChar ), NULL, this );
       m_editIP2->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( wxIpCtrl::OnTextUpdated ), NULL, this );
       m_editIP3->Connect( wxEVT_CHAR, wxKeyEventHandler( wxIpCtrl::OnChar ), NULL, this );
       m_editIP3->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( wxIpCtrl::OnTextUpdated ), NULL, this );
       m_editIP4->Connect( wxEVT_CHAR, wxKeyEventHandler( wxIpCtrl::OnChar ), NULL, this );
       m_editIP4->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( wxIpCtrl::OnTextUpdated ), NULL, this );
    }
    
    /**
     *
     */
    void wxIpCtrl::CreateGui()
    {
       SetBackgroundColour(*wxWHITE);
    
       m_sizer = new wxBoxSizer(wxHORIZONTAL);
    
       m_editIP1 = CreateTextCtrl();
       m_dot1    = CreateDot();
       m_editIP2 = CreateTextCtrl();
       m_dot2    = CreateDot();
       m_editIP3 = CreateTextCtrl();
       m_dot3    = CreateDot();
       m_editIP4 = CreateTextCtrl();
    
       SetSizer(m_sizer);
       Layout();
       m_sizer->Fit(this);
    }
    
    /**
     *
     */
    wxTextCtrl* wxIpCtrl::CreateTextCtrl()
    {
       wxTextCtrl* txtCtrl = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(27, 15), wxNO_BORDER|wxTE_RIGHT);
       txtCtrl->SetMaxLength(3);
       m_sizer->Add(txtCtrl, 0, wxALIGN_BOTTOM|wxTOP, 5);
       return txtCtrl;
    }
    
    /**
     *
     */
    wxStaticText* wxIpCtrl::CreateDot()
    {
       wxStaticText* staticTxt = new wxStaticText( this, wxID_ANY, _("."), wxDefaultPosition, wxDefaultSize, 0 );
       staticTxt->Wrap( -1 );
       m_sizer->Add(staticTxt, 0, wxALIGN_BOTTOM, 5);
       return staticTxt;
    }
    
    /**
     *
     */
    bool wxIpCtrl::Enable(bool enable)
    {
       wxColour bkColour = enable ? wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW) : wxSystemSettings::GetColour(wxSYS_COLOUR_MENU);
       SetBackgroundColour(bkColour);
       m_editIP1->SetBackgroundColour(bkColour);
       m_editIP2->SetBackgroundColour(bkColour);
       m_editIP3->SetBackgroundColour(bkColour);
       m_editIP4->SetBackgroundColour(bkColour);
       m_dot1->SetBackgroundColour(bkColour);
       m_dot2->SetBackgroundColour(bkColour);
       m_dot3->SetBackgroundColour(bkColour);
       m_editIP1->SetEditable(enable);
       m_editIP2->SetEditable(enable);
       m_editIP3->SetEditable(enable);
       m_editIP4->SetEditable(enable);
       Refresh();
       return true;
    }
    
    /**
     *
     */
    wxString wxIpCtrl::GetValue() const
    {
       return  m_editIP1->GetValue() + wxT(".") + m_editIP2->GetValue() + wxT(".") + m_editIP3->GetValue() + wxT(".") + m_editIP4->GetValue();
    }
    
    /**
     *
     */
    bool wxIpCtrl::SetValue(const wxString& ipaddr)
    {
       wxArrayString ipParts;
       if (CheckIp(ipaddr, ipParts) == false) {
          DoSetDefaultValue();
          return false;
       }
       DoSetValue(ipParts);
       return true;
    }
    
    /**
     *
     */
    bool wxIpCtrl::CheckIp(const wxString& ipaddr, wxArrayString& ipParts) const
    {
       wxRegEx strregex(wxT("([0-9]{1,3})([.])([0-9]{1,3})([.])([0-9]{1,3})([.])([0-9]{1,3})"));
       if (!strregex.Matches(ipaddr)) {
          return false;
       }
    
       ipParts.clear();
       ipParts.Add( strregex.GetMatch(ipaddr, 1) );
       ipParts.Add( strregex.GetMatch(ipaddr, 3) );
       ipParts.Add( strregex.GetMatch(ipaddr, 5) );
       ipParts.Add( strregex.GetMatch(ipaddr, 7) );
    
       unsigned long ip1, ip2, ip3, ip4;
       ipParts[0].ToULong(&ip1);
       ipParts[1].ToULong(&ip2);
       ipParts[2].ToULong(&ip3);
       ipParts[3].ToULong(&ip4);
    
       if (m_ipStyle & wxIPCTRL_D_CLASS) {
          if (!in_range(ip1, 224, 239)) {
             return false;
          }
       }
       else if (m_ipStyle & wxIPCTRL_ALL_CLASSES) {
          if (!in_range(ip1, 0, 255)) {
             return false;
          }
       }
       else {
          if (!in_range(ip1, 1, 223)) {
             return false;
          }
       }
    
       if ( !in_range(ip2, 0, 255) || !in_range(ip3, 0, 255) || !in_range(ip4, 0, 255) ) {
          return false;
       }
       return true;
    }
    
    /**
     *
     */
    void wxIpCtrl::DoSetValue(const wxArrayString& ipParts)
    {
       assert(ipParts.size() == 4);
    
       m_editIP1->ChangeValue(ipParts[0]);
       m_editIP2->ChangeValue(ipParts[1]);
       m_editIP3->ChangeValue(ipParts[2]);
       m_editIP4->ChangeValue(ipParts[3]);
    }
    
    /**
     *
     */
    void wxIpCtrl::DoSetDefaultValue()
    {
       m_editIP1->ChangeValue(m_defaultValue[0]);
       m_editIP2->ChangeValue(m_defaultValue[1]);
       m_editIP3->ChangeValue(m_defaultValue[2]);
       m_editIP4->ChangeValue(m_defaultValue[3]);
    }
    
    /**
     *
     */
    void wxIpCtrl::OnChar(wxKeyEvent& event)
    {
       const wxObject* evtObject = event.GetEventObject();
    
       //if ((m_ipStyle & wxIPCTRL_D_CLASS) && (evtObject == m_editIP1) ) {
       //   // Do not allow to change the ip 1 (which must be 224)
       //   return;
       //}
    
       const int keyCode = event.GetKeyCode();
    
       if (keyCode >= '0' && keyCode <= '9') {
          event.Skip();
          return;
       }
    
       if (keyCode == '.') {
          // deal with '.'
          if (evtObject == m_editIP1 && m_editIP1->GetStringSelection().Length() != m_editIP1->GetValue().Length()) {
                m_editIP2->SetFocus();
                m_editIP2->SetSelection(-1, -1);
          }
          else if (evtObject == m_editIP2 && m_editIP2->GetStringSelection().Length() != m_editIP2->GetValue().Length()) {
                m_editIP3->SetFocus();
                m_editIP3->SetSelection(-1, -1);
          }
          else if (evtObject == m_editIP3 && m_editIP3->GetStringSelection().Length() != m_editIP3->GetValue().Length()) {
                m_editIP4->SetFocus();
                m_editIP4->SetSelection(-1, -1);
          }
       }
       else if (keyCode == WXK_BACK) {
          if (evtObject == m_editIP2 && m_editIP2->GetValue().IsEmpty()) {
             m_editIP1->SetFocus();
             m_editIP1->SetInsertionPointEnd();
          }
          else if (evtObject == m_editIP3 && m_editIP3->GetValue().IsEmpty()) {
             m_editIP2->SetFocus();
             m_editIP2->SetInsertionPointEnd();
          }
          else if (evtObject == m_editIP4 && m_editIP4->GetValue().IsEmpty()) {
             m_editIP3->SetFocus();
             m_editIP3->SetInsertionPointEnd();
          }
          event.Skip();
       }
       else if (keyCode == WXK_LEFT || keyCode == WXK_UP) {
          if (evtObject == m_editIP2 && m_editIP2->GetInsertionPoint() == 0) {
             m_editIP1->SetFocus();
             m_editIP1->SetInsertionPointEnd();
          }
          else if (evtObject == m_editIP3 && m_editIP3->GetInsertionPoint() == 0) {
             m_editIP2->SetFocus();
             m_editIP2->SetInsertionPointEnd();
          }
          else if (evtObject == m_editIP4 && m_editIP4->GetInsertionPoint() == 0) {
             m_editIP3->SetFocus();
             m_editIP3->SetInsertionPointEnd();
          }
          event.Skip();
       }
       else if (keyCode == WXK_RIGHT || keyCode == WXK_DOWN)   {
          if (evtObject == m_editIP1 && m_editIP1->GetInsertionPoint() == m_editIP1->GetLastPosition()) {
             m_editIP2->SetFocus();
             m_editIP2->SetInsertionPoint(0);
          }
          else if (evtObject == m_editIP2 && m_editIP2->GetInsertionPoint() == m_editIP2->GetLastPosition()) {
             m_editIP3->SetFocus();
             m_editIP3->SetInsertionPoint(0);
          }
          else if (evtObject == m_editIP3 && m_editIP3->GetInsertionPoint() == m_editIP3->GetLastPosition()) {
             m_editIP4->SetFocus();
             m_editIP4->SetInsertionPoint(0);
          }
          event.Skip();
       }
       else if (keyCode == WXK_TAB || keyCode == WXK_DELETE || keyCode == WXK_END || keyCode == WXK_HOME ) {
          event.Skip();
       }
    }
    
    /**
     *
     */
    void wxIpCtrl::OnTextUpdated(wxCommandEvent& event)
    {
       const wxString str = event.GetString();
       if (str.Length() == 0) {
          event.Skip();
          return;
       }
    
       bool bSendEvtChanged = false;
       const wxObject* evtObject = event.GetEventObject();
       if (evtObject == m_editIP1) {
          if (m_ipStyle & wxIPCTRL_ALL_CLASSES ||
             m_ipStyle & wxIPCTRL_D_CLASS ) {
             if (CheckRange(str, 0, 255)) {
                if (str.Length() == 3) {
                   m_editIP2->SetFocus();
                   m_editIP2->SetSelection(-1, -1);
                }
                bSendEvtChanged = true;
             }
             else {
                m_editIP1->SetValue(wxT("0"));
                m_editIP1->SetFocus();
                m_editIP1->SetSelection(-1, -1);
             }
          }
          else {
             if (CheckRange(str, 1, 223)) {
                if (str.Length() == 3) {
                   m_editIP2->SetFocus();
                   m_editIP2->SetSelection(-1, -1);
                }
                bSendEvtChanged = true;
             }
             else {
                m_editIP1->SetValue(wxT("1"));
                m_editIP1->SetFocus();
                m_editIP1->SetSelection(-1, -1);
             }
          }
       }
       else if (evtObject == m_editIP2) {
          if (CheckRange(str, 0, 255)) {
             if (str.Length() == 3) {
                m_editIP3->SetFocus();
                m_editIP3->SetSelection(-1, -1);
             }
             bSendEvtChanged = true;
          }
          else {
             m_editIP2->SetValue(wxT("0"));
             m_editIP2->SetFocus();
             m_editIP2->SetSelection(-1, -1);
          }
       }
       else if (evtObject == m_editIP3) {
          if (CheckRange(str, 0, 255)) {
             if (str.Length() == 3) {
                m_editIP4->SetFocus();
                m_editIP4->SetSelection(-1, -1);
             }
             bSendEvtChanged = true;
          }
          else {
             m_editIP3->SetValue(wxT("0"));
             m_editIP3->SetFocus();
             m_editIP3->SetSelection(-1, -1);
          }
       }
       else if (evtObject == m_editIP4) {
          if (CheckRange(str, 0, 255)) {
             // do nothing
             bSendEvtChanged = true;
          }
          else {
             m_editIP4->SetValue(wxT("0"));
             m_editIP4->SetFocus();
             m_editIP4->SetSelection(-1, -1);
          }
       }
    
       if (bSendEvtChanged) {
          wxCommandEvent evtChanged(wxEVT_IPCTRL_CHANGED, GetId());
          evtChanged.SetString(GetValue());
          evtChanged.SetEventObject(this);
          AddPendingEvent(evtChanged);
       }
    
       event.Skip();
    }
    
    /**
     *
     */
    bool wxIpCtrl::CheckRange(const wxString& value, unsigned long min, unsigned long max) const
    {
       unsigned long v = 0;
       value.ToULong(&v, 10);
    
       bool inRange = in_range(v, min, max);
       if (!inRange) {
          wxString msg = wxString::Format(_("Invalid value : %s"), value.c_str());
          ::wxMessageBox(msg, _("Invalid value"), wxOK | wxICON_EXCLAMATION, NULL);
       }
       return inRange;
    }
    
  • 相关阅读:
    kicad 基本操作
    RedHat centos中的上传下推脚本
    使用Node.js爬虫存储MySQL数据库
    解决vue和vue-template-compiler版本不同报错的问题
    Vue组件通信(父子组件通信)-学习笔记
    git 简单操作
    错误解决:redis.exceptions.ResponseError: unknown command 'SENTINEL'
    nginx做泛域名解析的域名的正则判断
    postman对字符串进行base64编码方法和变量的使用
    pymysql报错OperationalError: (2013, 'Lost connection to MySQL server during query')
  • 原文地址:https://www.cnblogs.com/godspeedsam/p/2433159.html
Copyright © 2020-2023  润新知