YOU CAN CODE!

 

With The Case Of UCanCode.net  Release The Power OF  Visual C++ !   HomeProducts | PurchaseSupport | Downloads  
Download Evaluation
Pricing & Purchase?
E-XD++Visual C++/ MFC Products
Overview
Features Tour 
Electronic Form Solution
Visualization & HMI Solution
Power system HMI Solution
CAD Drawing and Printing Solution

Bar code labeling Solution
Workflow Solution

Coal industry HMI Solution
Instrumentation Gauge Solution

Report Printing Solution
Graphical modeling Solution
GIS mapping solution

Visio graphics solution
Industrial control SCADA &HMI Solution
BPM business process Solution

Industrial monitoring Solution
Flowchart and diagramming Solution
Organization Diagram Solution

Graphic editor Source Code
UML drawing editor Source Code
Map Diagramming Solution

Architectural Graphic Drawing Solution
Request Evaluation
Purchase
ActiveX COM Products
Overview
Download
Purchase
Technical Support
  General Q & A
Discussion Board
Contact Us

Links

Get Ready to Unleash the Power of UCanCode .NET


UCanCode Software focuses on general application software development. We provide complete solution for developers. No matter you want to develop a simple database workflow application, or an large flow/diagram based system, our product will provide a complete solution for you. Our product had been used by hundreds of top companies around the world!

"100% source code provided! Free you from not daring to use components because of unable to master the key technology of components!"


Date-Time Edit Control A simple masked date-time editor. VC++ Article Source Code and GetWindowText

 
 By Tri VU KHAC

Introduction

Many articles about the masked edit control could be discovered from MFC sites. Their Date Time Edit controls show some faults such as out-of-range values are not verified, slow processing, etc. Why? Maybe because they are too general and cover many things.

This VDateTimeEdit class based on MaskEdit's idea is very simple and understandable for any programmer. You can choose either numeric keys or up/down keys to change the date & time displayed. The Date-Time display is configurable by SetMask().

Mask convention:

DD Day   hh Hour
MM Month   mm minute
YYYY Year   ss second

Enjoy yourself and please report me the bugs you have found.

Source Code

Collapse
/////////////////////////////////////////////////////////////////////////////
// VDateTimeEdit window

const UINT WM_DATETIME_EDIT = ::RegisterWindowMessage("WM_DATETIME_EDIT");
#define DTE_DATETIMECHANGED 0x0001

class VDateTimeEdit : public CEdit
{
// Construction
public:
    VDateTimeEdit();

// Attributes
public:

// Operations
public:

// Overrides
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(VDateTimeEdit)
    protected:
    virtual void PreSubclassWindow();
    //}}AFX_VIRTUAL

// Implementation
public:
    CString GetMask() const {return m_strMask;}
    void SetMask(CString mask);
    COleDateTime GetDateTime();
    COleDateTime GetDateTime(CString str);
    void SetDateTime(COleDateTime dt);

    virtual ~VDateTimeEdit();

    // Generated message map functions
protected:
    afx_msg void OnContextMenu(CWnd*, CPoint point);

    CString m_strMask;
    //{{AFX_MSG(VDateTimeEdit)
    afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
    afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags);
    afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
    afx_msg void OnMouseMove(UINT nFlags, CPoint point);
    //}}AFX_MSG

    DECLARE_MESSAGE_MAP()
};


bool VAtoi(CString str, int &res)
{
    str.Remove(char(32));
    if (str.IsEmpty()) return false;
    bool error = false;
    for (int i = 0; i < str.GetLength() && !error; i++) {
        int c = ::tolower(str[i]);
        error = !(
            (c >= '0' && c <= '9')
            || ((c == '-' || c == '+') && i == 0)
            );
    }
    if (!error) res = atoi(LPCTSTR(str));
    return !error;
}

template<class TYPE>
void VSetInRange(TYPE &x, TYPE min, TYPE max) 
{
    ASSERT(min<=max);
    if (x < min) x = min; else if (x > max) x = max;
}

/************************** VDateTimeEdit **************************/

VDateTimeEdit::VDateTimeEdit()
{
    m_strMask = _T("DD/MM/YYYY hh:mm:ss");
}

VDateTimeEdit::~VDateTimeEdit()
{

}


BEGIN_MESSAGE_MAP(VDateTimeEdit, CEdit)
    ON_WM_CONTEXTMENU()
    //{{AFX_MSG_MAP(VDateTimeEdit)
    ON_WM_CHAR()
    ON_WM_KEYUP()
    ON_WM_KEYDOWN()
    ON_WM_MOUSEMOVE()
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

///////////////////////////////////////////////////////////////////////////
// VDateTimeEdit message handlers

void VDateTimeEdit::OnChar(UINT nChar, UINT /*nRepCnt*/, UINT /*nFlags*/) 
{
    CString old;
    GetWindowText(old);
    int pos;
    TCHAR c;
    GetSel(pos, pos);
    switch (nChar) {
        case VK_BACK: pos--;
            break;
        case VK_UP: pos--;
            break;
        case '0':case '1':case '2':case '3':
        case '4':case '5':case '6':case '7':
        case '8':case '9':
            if (pos < old.GetLength()
                  && pos < m_strMask.GetLength()
                  && (UINT)old[pos] != nChar
                  && ((c = m_strMask[pos]) == 'D' || 
                  c == 'M' || c == 'Y' || c == 'h' 
                  || c == 'm' || c == 's')) {
                CString str = old;
                str.SetAt(pos, (TCHAR)nChar);
                COleDateTime dt = GetDateTime(str);
                if (dt.GetStatus() == COleDateTime::valid) SetDateTime(dt);
            }
            if (++pos < m_strMask.GetLength())
                for ( c = m_strMask[pos]; pos < m_strMask.GetLength() 
                    && c != 'D' && 
                    c != 'M' && c != 'Y' && 
                    c != 'h' && c != 'm' && c != 's';
                  c = m_strMask[pos]) pos++;
            break;
        default:
            if (++pos < m_strMask.GetLength())
                for ( c = m_strMask[pos]; pos < m_strMask.GetLength() 
                      && c != 'D' && c != 'M' 
                      && c != 'Y' && c != 'h' 
                      && c != 'm' && c != 's';
                    c = m_strMask[pos]) pos++;
            break;
    }
    SetSel(pos, pos);
}

void VDateTimeEdit::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
    CEdit::OnKeyUp(nChar, nRepCnt, nFlags);
}

void VDateTimeEdit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
    switch (nChar) {
        case VK_DELETE:case VK_INSERT:
            break;
        case VK_UP: case VK_DOWN:
            {
                CString old;
                GetWindowText(old);
                int pos;
                GetSel(pos, pos);
                if (pos < m_strMask.GetLength()) {
                    TCHAR c = m_strMask[pos];
                    if (c != 'D' && c != 'M' && 
                      c != 'Y' && c != 'h' && 
                      c != 'm' && c != 's')
                        if (--pos >= 0) c = m_strMask[pos];
                    tm t;
                    COleDateTime dt = GetDateTime();
                    t.tm_mday = dt.GetDay();
                    t.tm_mon = dt.GetMonth();
                    t.tm_year = dt.GetYear();
                    t.tm_hour = dt.GetHour();
                    t.tm_min = dt.GetMinute();
                    t.tm_sec = dt.GetSecond();
                    switch (c) {
                        case 'D':
                            t.tm_mday += (nChar!=VK_UP) ? -1 : 1;
                            break;
                        case 'M':
                            t.tm_mon += (nChar!=VK_UP) ? -1 : 1;
                            break;
                        case 'Y':
                            t.tm_year += (nChar!=VK_UP) ? -1 : 1;
                            break;
                        case 'h':
                            t.tm_hour += (nChar!=VK_UP) ? -1 : 1;
                            break;
                        case 'm':
                            t.tm_min += (nChar!=VK_UP) ? -1 : 1;
                            break;
                        case 's':
                            t.tm_sec += (nChar!=VK_UP) ? -1 : 1;
                            break;
                        default    :
                             CEdit::OnKeyDown(nChar, nRepCnt, nFlags);
                            break;
                    }
                    dt.SetDateTime(t.tm_year, t.tm_mon, t.tm_mday, 
                                      t.tm_hour, t.tm_min, t.tm_sec);
                    if (dt.GetStatus() == COleDateTime::valid) 
                        SetDateTime(dt);
                } else CEdit::OnKeyDown(nChar, nRepCnt, nFlags);
            }
            break;
        default:
            CEdit::OnKeyDown(nChar, nRepCnt, nFlags);
            break;
    }
}

void VDateTimeEdit::OnMouseMove(UINT nFlags, CPoint point) 
{
    // TODO: Add your message handler code here and/or call default
    
    CEdit::OnMouseMove(nFlags, point);
}

void VDateTimeEdit::PreSubclassWindow() 
{
    SetDateTime(COleDateTime::GetCurrentTime());
    CEdit::PreSubclassWindow();
}

void VDateTimeEdit::SetDateTime(COleDateTime dt)
{
    CString str;
    int i, n = m_strMask.GetLength();
    for (i = 0; i < n; i++) {
        CString s;
        int val;
        TCHAR c = m_strMask[i];
        switch (c) {
            case 'D':case 'M':case 'Y':case 'h':case 'm':case 's':
                for (; i < n; i++) {
                    if (m_strMask[i] == c) s += c;
                    else {i--; break;}
                }
                break;
            default :
                break;
        }
        CString format;
        format.Format("%%0%dd", s.GetLength());
        switch (c) {
            case 'D':
                val = dt.GetDay();
                ::VSetInRange(val, 0, 31);
                s.Format(format, val);
                break;
            case 'M':
                val = dt.GetMonth();
                ::VSetInRange(val, 1, 12);
                s.Format(format, val);
                break;
            case 'Y':
                val = dt.GetYear();
                ::VSetInRange(val, 1900, 9990);
                s.Format(format, val);
                break;
            case 'h':
                val = dt.GetHour();
                ::VSetInRange(val, 0, 23);
                s.Format(format, val);
                break;
            case 'm':
                val = dt.GetMinute();
                ::VSetInRange(val, 0, 59);
                s.Format(format, val);
                break;
            case 's':
                val = dt.GetSecond();
                ::VSetInRange(val, 0, 59);
                s.Format(format, val);
                break;
            default :
                s = c;
                break;
        }
        str += s;
    }
    int pos;
    GetSel(pos, pos);
    SetWindowText(str);
    SetSel(pos, pos);
    CWnd *pOwner = GetParent();
    if (pOwner != NULL) 
      pOwner->PostMessage(WM_DATETIME_EDIT, 
                  (WPARAM)DTE_DATETIMECHANGED, (LPARAM)0);
}

COleDateTime VDateTimeEdit::GetDateTime()
{
    CString str;
    GetWindowText(str);
    return GetDateTime(str);
}

COleDateTime VDateTimeEdit::GetDateTime(CString str)
{
    tm t;
    COleDateTime dt;
    dt.SetStatus(COleDateTime::invalid);
    CTime::GetCurrentTime().GetLocalTm(&t);
    t.tm_mon += 1;
    t.tm_year += 1900;

    int i, n = m_strMask.GetLength();
    for (i = 0; i < n; i++) {
        CString s;
        TCHAR c = m_strMask[i];
        switch (c) {
            case 'D':case 'M':case 'Y':case 'h':case 'm':case 's':
                for ( ; i < n; i++) {
                    if (str.GetLength() <= s.GetLength()) break;
                    if (m_strMask[i] == c) s += str[s.GetLength()];
                    else {i--; break;}
                }
                break;
            default :
                if (str.GetLength() < 0 || str[0] != (s = c)) return dt;
                break;
        }
        str = str.Right(str.GetLength() - s.GetLength());
        int val;
        switch (c) {
            case 'D':
                if (!::VAtoi(s, val)) return dt;
                ::VSetInRange(val, 1, 31);
                t.tm_mday = val;
                break;
            case 'M':
                if (!::VAtoi(s, val)) return dt;
                ::VSetInRange(val, 1, 12);
                t.tm_mon = val;
                break;
            case 'Y':
                if (!::VAtoi(s, val)) return dt;
                ::VSetInRange(val, 1900, 9990);
                t.tm_year = val;
                break;
            case 'h':
                if (!::VAtoi(s, val)) return dt;
                ::VSetInRange(val, 0, 23);
                t.tm_hour = val;
                break;
            case 'm':
                if (!::VAtoi(s, val)) return dt;
                ::VSetInRange(val, 0, 59);
                t.tm_min = val;
                break;
            case 's':
                if (!::VAtoi(s, val)) return dt;
                ::VSetInRange(val, 0, 59);
                t.tm_sec = val;
                break;
            default :
                break;
        }
    }
    dt.SetStatus(COleDateTime::valid);
    dt.SetDateTime(t.tm_year, t.tm_mon, 
            t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
    return dt;
}

void VDateTimeEdit::OnContextMenu(CWnd*, CPoint)
{
}

void VDateTimeEdit::SetMask(CString mask) {
    COleDateTime time = GetDateTime();
    m_strMask = mask;
    SetDateTime(time);
}

That's it!

 

 

 

Copyright ?1998-2009 UCanCode.Net Software , all rights reserved.
Other product and company names herein may be the trademarks of their respective owners.

Please direct your questions or comments to webmaster@ucancode.net