CEditNumber

CEditNumber adalah kelas turunan dari CEdit. Ditujukan agar input hanya bisa menerima angka, tanda minus dan separator desimal. Pun ada auto format dengan menggunakan local regional setting pada windows.

EditNumber.h

#if !defined(AFX_EDITNUMBER_H__1F33E9E6_0079_4051_B3F1_A592F3E8F186__INCLUDED_)
#define AFX_EDITNUMBER_H__1F33E9E6_0079_4051_B3F1_A592F3E8F186__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// EditNumber.h : header file
//

/////////////////////////////////////////////////////////////////////////////
// CEditNumber window

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

// Attributes
public:

// Operations
public:

// Overrides
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CEditNumber)
	public:
	virtual BOOL PreTranslateMessage(MSG* pMsg);
	//}}AFX_VIRTUAL

// Implementation
	void SetDecimanLength(UINT pr_ndec);
	void SetCNumberString(const char* p);
	void GetCNumberString(CString& p);

	static void NumberFormat(CString& res, char sep_dec, int n_dec, char sep_thousand, const char* val);
public:
	virtual ~CEditNumber();

	// Generated message map functions
protected:
	//{{AFX_MSG(CEditNumber)
	afx_msg void OnKillFocus(CWnd* pNewWnd);
	afx_msg void OnSetFocus(CWnd* pOldWnd);
	afx_msg void OnChange();
	afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
	//}}AFX_MSG

	DECLARE_MESSAGE_MAP()
private:
	char m_dec;
	char m_thousand;
	UINT n_dec;
};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_EDITNUMBER_H__1F33E9E6_0079_4051_B3F1_A592F3E8F186__INCLUDED_)

EditNumber.cpp

// EditNumber.cpp : implementation file
//

#include "stdafx.h"
#include "stdataadmin.h"
#include "EditNumber.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CEditNumber

CEditNumber::CEditNumber()
{
	char dec[10];
	if (! GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, dec, 10)) {
		sprintf(dec, ".");
	}

	m_dec = *dec;

	char thousand[10];
	if (! GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, thousand, 10)) {
		sprintf(thousand, ",");
	}

	m_thousand = *thousand;

	n_dec = 4;
}

CEditNumber::~CEditNumber()
{
}

BEGIN_MESSAGE_MAP(CEditNumber, CEdit)
	//{{AFX_MSG_MAP(CEditNumber)
	ON_WM_KILLFOCUS()
	ON_WM_SETFOCUS()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CEditNumber message handlers

BOOL CEditNumber::PreTranslateMessage(MSG* pMsg)
{
	// TODO: Add your specialized code here and/or call the base class

	if (pMsg->message == WM_CHAR) {
		int nVirtKey = (int) pMsg->wParam;

		if ((nVirtKey >= 32) && (nVirtKey <= 126)) {
			UINT maxlen = GetLimitText();
			char* buf = (char* ) malloc (maxlen+2);

			GetWindowText(buf, maxlen+1);

			if (nVirtKey == m_dec) {
				if (strchr(buf, m_dec)) {
					pMsg->wParam = 0;
				}
			}
			else
			if (nVirtKey == '-') {
				if ((strlen(buf) > 0) && (*buf == '-')) {
					pMsg->wParam = 0;
				}
				else {
					CPoint p = GetCaretPos();

					int n = CharFromPos(p);
					int nLineIndex = HIWORD(n);
					int nCharIndex = LOWORD(n);

					if (nCharIndex > 0) {
						pMsg->wParam = 0;
					}

				}
			}
			else
			if (nVirtKey == '0') {
				if (strlen(buf)) {
					if (*buf != m_dec) {
						CPoint p = GetCaretPos();

						int n = CharFromPos(p);
						int nLineIndex = HIWORD(n);
						int nCharIndex = LOWORD(n);

						if (nCharIndex == 0) {
							pMsg->wParam = 0;
						}
						else
						if (nCharIndex == 1) {
							if ((*buf == '-') || (*buf == '0')) {
								pMsg->wParam = 0;
							}
						}
					}
				}
			}
			else
			if (nVirtKey < '0') {
				pMsg->wParam = 0;
			}
			else
			if (nVirtKey > '9') {
				pMsg->wParam = 0;
			}

			free(buf);
		}
	}

	return CEdit::PreTranslateMessage(pMsg);
}

void CEditNumber::OnKillFocus(CWnd* pNewWnd)
{
	CEdit::OnKillFocus(pNewWnd);

	// TODO: Add your message handler code here

	CString ret;

	GetWindowText(ret);
	NumberFormat(ret, m_dec, n_dec, m_thousand, ret.GetBuffer(0));

	SetWindowText(ret.GetBuffer(0));
}

void CEditNumber::SetDecimanLength(UINT pr_ndec) {
	n_dec = pr_ndec;
}

void CEditNumber::NumberFormat(CString& res, char sep_dec, int n_dec, char sep_thousand, const char* val) {
	if (n_dec < 0) return;

	CString s = CString(val); // satuan tanpa separator
	CString dec = CString("");  // decimal

	s.TrimLeft(" ");
	s.TrimRight(" ");

	if (s.GetLength() == 0) {
		res = "0";
		res += sep_dec;
		for(int i=0; i < n_dec; i++) {
			res += "0";
		}

		return;
	}

	// pisahkan satuan dan decimal

	int pos = s.Find(sep_dec, 0);
	if (pos > -1) {
		dec = s.Right(s.GetLength()-pos-1);
		s = s.Left(pos);
	}

	// chek panjang n_dec

	if (dec.GetLength() > n_dec) {
		dec = dec.Left(n_dec);
	}
	else
	while (dec.GetLength() < n_dec) {
		dec += "0";
	}

	// tambahkan sep_dec

	res = "";
	if (sep_thousand == 0) {
		res = s;
	}
	else
	while(1) {
		if (s.GetLength() < 3) {
			res.Insert(0, s.Right(s.GetLength()));
			break;
		}

		res.Insert(0, s.Right(3));
		if (s.GetLength() > 3) {
			res.Insert(0, sep_thousand);
		}
		s = s.Left(s.GetLength()-3);
	}

	if (n_dec > 0) {
		res.Insert(res.GetLength(), sep_dec);
		res.Insert(res.GetLength(), dec);
	}

}

void CEditNumber::OnSetFocus(CWnd* pOldWnd)
{
	CEdit::OnSetFocus(pOldWnd);

	// TODO: Add your message handler code here	

	UINT maxlen = GetLimitText();

	CString s;
	GetWindowText(s);

	char temp[2];
	sprintf(temp,"%c", m_thousand);

	s.Replace(temp, "");

	int ndec = maxlen-s.GetLength();
	if (ndec > ((int) n_dec)) {
		ndec = n_dec;
	}
	else
	if (ndec < 0) {
		ndec = 0;
	}

	NumberFormat(s, m_dec, ndec, 0, s.GetBuffer(0));
	SetWindowText(s.GetBuffer(0));
}

void CEditNumber::SetCNumberString(const char* p) {
	char temp[2];
	sprintf(temp,"%c", m_dec);

	CString s;
	s.Replace(".", temp);

	NumberFormat(s, m_dec, n_dec, m_thousand, p);

	SetWindowText(s.GetBuffer(0));
}

void CEditNumber::GetCNumberString(CString& p) {
	GetWindowText(p);

	char temp[2];
	sprintf(temp,"%c", m_thousand);

	p.Replace(temp, "");

	sprintf(temp,"%c", m_dec);
	p.Replace(temp, ".");
}
MWN Hosting

Comments 1

  1. seomaster wrote:

    ??

    Posted 22 Aug 2008 at 8:00 am

Post a Comment

Your email is never published nor shared. Required fields are marked *