Google Search

Google Search Results

Tuesday, September 9, 2008

TEdit control for money/currency values

Here is some code for a TEdit derived control that auto-formats for currency/money. I know a couple of the includes you will not have, like psparts and vclutils, but once you try to compile it should be obvious what you need to add to get it to compile (if anything). Actually I'll go ahead and include vclutils.h in another blog, but I can't include psparts.h because it contains a lot of things I don't want to (or cannot) share, it probably isn't even needed. This one does derive from another class I call TPSEdit, but just change to TEdit and you should be fine (TPSEdit doesn't do much)... the main thing to learn from this anyway are the little tricks, which you can then use for other stuff, like the Paint() event:

----- PSMoneyEdit.cpp --------

#include
#include
#include "vclutils.h"
#include "psparts.h"
#include "PSMoneyEdit.h"
#pragma package(smart_init)

static const double min = 0.00;
static const double max = 10000000.00;

static double TextToDoubleFieldValue(char *text,int decimal_count)
{
AnsiString t = AnsiString(text).Trim();
int l = t.Length();
BOOL neg = l && (t[1] == '-' t[1] == '(');
AnsiString w;
AnsiString d;
BOOL dec = FALSE;
for(int x=1;x<=l;x++)
{
if(t[x] == '.')
dec = TRUE;

if(isdigit(t[x]))
{
if(dec)
d = d + t[x];
else
w = w + t[x];
}
}

l = w.Length();
if(l > 8)
{
if(neg)
return(min);
else
return(max);
}

if(neg)
w = "-" + w;

if(decimal_count && !d.IsEmpty())
w = w + '.' + d.SubString(1,decimal_count);

double ret = atof(w.c_str());
if(ret < min)
ret = min;
else if(ret > max)
ret = max;

return(ret);
}

__fastcall TPSMoneyEditEdit::TPSMoneyEditEdit(TComponent* Owner)
: inherited(Owner)
{
}

void __fastcall TPSMoneyEditEdit::WndProc(TMessage &Message)
{
if(Message.Msg == CN_KEYDOWN)
{
if(Message.WParam == VK_RETURN)
{
if(FTabOnReturn)
Message.WParam = VK_TAB;
else
Message.WParam = 0;
}
}

inherited::WndProc(Message);
}

void __fastcall TPSMoneyEditEdit::CreateWnd(void)
{
inherited::CreateWnd();
}

void __fastcall TPSMoneyEditEdit::DoEnter(void)
{
inherited::DoEnter();
SelectAll();
}

void __fastcall TPSMoneyEditEdit::DoExit(void)
{
double v = Owner->Value;
Owner->Value = v;
inherited::DoExit();
}

void __fastcall TPSMoneyEditEdit::ChangeScale(int M, int D)
{
M;
D;
}

__fastcall TPSMoneyEdit::TPSMoneyEdit(TComponent* Owner)
: inherited(Owner)
{
EditCtrl = new TPSMoneyEditEdit(this);
EditCtrl->AutoSize = FALSE;
EditCtrl->BorderStyle = bsNone;
Height = 21;
Width = 100;
Text = "0.00";
FBorder = TRUE;
Alignment = taRightJustify;
FDecimalCount = 2;
MaxLength = 10 + (FDecimalCount ? FDecimalCount + 1 : 0);
}

void __fastcall TPSMoneyEdit::SetValue(double val)
{
if(val < min)
val = min;
else if(val > max)
val = max;
Text = FloatToStrF(val,ffNumber,15,FDecimalCount);
}

double __fastcall TPSMoneyEdit::GetValue(void)
{
return(TextToDoubleFieldValue(Text.c_str(),FDecimalCount));
}

void TPSMoneyEdit::SetRects(void)
{
if(!EditCtrl !Parent)
return;

TRect rc = BoundsRect;

InflateRect(&rc,-2,-2);

Canvas->Font = EditCtrl->Font;
Canvas->Font->PixelsPerInch = EditCtrl->Font->PixelsPerInch;

int h = Canvas->TextHeight("A");
rc.top += Floor((float)(rc.Height() - h) / 2);
rc.bottom = rc.top + h;

rc.left += Canvas->TextWidth(FPrefix);

EditCtrl->BoundsRect = rc;
}

void __fastcall TPSMoneyEdit::SetPrefix(AnsiString val)
{
if(val == FPrefix)
return;

FPrefix = val;

SetRects();

Invalidate();
}

void __fastcall TPSMoneyEdit::SetDecimalCount(int val)
{
if(val == FDecimalCount)
return;

FDecimalCount = val;

Value = Value;

MaxLength = 10 + (FDecimalCount ? FDecimalCount + 1 : 0);
}

void __fastcall TPSMoneyEdit::SetParent(TWinControl* AParent)
{
inherited::SetParent(AParent);
EditCtrl->Parent = AParent;
SetRects();
}

void __fastcall TPSMoneyEdit::Paint(void)
{
TCanvas *c = Canvas;
TRect rc = ClientRect;
c->Brush->Color = EditCtrl->Color;
c->FillRect(rc);
if(FBorder)
DrawEdge(c->Handle,&rc,EDGE_SUNKEN,BF_RECT);

rc.left += 2;
if(!rc.Height() % 2)
rc.bottom -= 1;

c->Font = EditCtrl->Font;
c->Font->PixelsPerInch = EditCtrl->Font->PixelsPerInch;

DrawText(c->Handle,FPrefix.c_str(),-1,&rc,DT_NOPREFIXDT_LEFTDT_VCENTERDT_SINGLELINE);

inherited::Paint();
}

void __fastcall TPSMoneyEdit::Resize(void)
{
inherited::Resize();
SetRects();
}

void __fastcall TPSMoneyEdit::MouseDown(TMouseButton Button,TShiftState Shift,int X,int Y)
{
if(ComponentState.Contains(csDesigning))
inherited::MouseDown(Button,Shift,X,Y);
}

void __fastcall TPSMoneyEdit::MouseUp(TMouseButton Button,TShiftState Shift,int X,int Y)
{
if(ComponentState.Contains(csDesigning))
inherited::MouseUp(Button,Shift,X,Y);
}

void __fastcall TPSMoneyEdit::SetBounds(int ALeft, int ATop, int AWidth, int AHeight)
{
inherited::SetBounds(ALeft,ATop,AWidth,AHeight);
if(ComponentState.Contains(csLoading))
SetRects();
}

void __fastcall TPSMoneyEdit::SetBorder(bool val)
{
if(FBorder == val)
return;

FBorder = val;

SetRects();
}

void __fastcall TPSMoneyEdit::CMVisibleChanged(TMessage &msg)
{
EditCtrl->Visible = Visible;
#pragma warn -parm
}
#pragma warn .parm

void __fastcall TPSMoneyEdit::CMEnabledChanged(TMessage &msg)
{
EditCtrl->Enabled = Enabled;
#pragma warn -parm
}
#pragma warn .parm

void __fastcall TPSMoneyEdit::WMContextMenu(TWMContextMenu &msg)
{
if(!EditCtrl !EditCtrl->Focused())
msg.Result = 1;
else
inherited::Dispatch((void*)&msg);
}

namespace Psmoneyedit
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TPSMoneyEdit)};
RegisterComponents("ERIC", classes, 0);
}
}

static inline void ValidCtrCheck(TPSMoneyEdit *)
{
new TPSMoneyEdit(NULL);
}


--------- PSMoneyEdit.h -------------

#ifndef PSMoneyEditH
#define PSMoneyEditH

#include
#include
#include
#include
#include "PSEdit.h"

class PACKAGE TPSMoneyEdit;

class PACKAGE TPSMoneyEditEdit : public TPSEdit
{
typedef TPSEdit inherited;
protected:
void __fastcall WndProc(TMessage &Message);
void __fastcall CreateWnd(void);
DYNAMIC void __fastcall DoEnter(void);
DYNAMIC void __fastcall DoExit(void);
DYNAMIC void __fastcall ChangeScale(int M, int D);
TPSMoneyEdit* __fastcall GetMoneyOwner(void){return((TPSMoneyEdit*)inherited::Owner);}
__property TPSMoneyEdit* Owner = {read=GetMoneyOwner};
public:
__fastcall TPSMoneyEditEdit(TComponent* Owner);
__published:
};

class PACKAGE TPSMoneyEdit : public TPaintBox
{
friend TPSMoneyEditEdit;
typedef TPaintBox inherited;
protected:
int FDecimalCount;
AnsiString FPrefix;
bool FBorder;
void __fastcall SetValue(double val);
double __fastcall GetValue(void);
void __fastcall SetPrefix(AnsiString val);
void __fastcall SetDecimalCount(int val);
void __fastcall SetBorder(bool val);
void __fastcall SetParent(TWinControl* AParent);

TAlignment __fastcall GetAlignment(void){return(EditCtrl->Alignment);}
void __fastcall SetAlignment(TAlignment val){EditCtrl->Alignment = val;}
bool __fastcall GetReadOnly(void){return(EditCtrl->ReadOnly);}
void __fastcall SetReadOnly(bool val){EditCtrl->ReadOnly = val;}
bool __fastcall GetParentColor(void){return(EditCtrl->ParentColor);}
void __fastcall SetParentColor(bool val){EditCtrl->ParentColor = val;}
int __fastcall GetMaxLength(void){return(EditCtrl->MaxLength);}
void __fastcall SetMaxLength(int val){EditCtrl->MaxLength = val;}
AnsiString __fastcall GetText(void){return(EditCtrl->Text);}
void __fastcall SetText(AnsiString val){EditCtrl->Text = val;}
bool __fastcall GetTabStop(void){return(EditCtrl->TabStop);}
void __fastcall SetTabStop(bool val){EditCtrl->TabStop = val;}
TTabOrder __fastcall GetTabOrder(void){return(EditCtrl->TabOrder);}
void __fastcall SetTabOrder(TTabOrder val){EditCtrl->TabOrder = val;}
TNotifyEvent __fastcall GetOnEnter(void){return(EditCtrl->OnEnter);}
void __fastcall SetOnEnter(TNotifyEvent val){EditCtrl->OnEnter = val;}
TNotifyEvent __fastcall GetOnExit(void){return(EditCtrl->OnExit);}
void __fastcall SetOnExit(TNotifyEvent val){EditCtrl->OnExit = val;}
TKeyEvent __fastcall GetOnKeyDown(void){return(EditCtrl->OnKeyDown);}
void __fastcall SetOnKeyDown(TKeyEvent val){EditCtrl->OnKeyDown = val;}
bool __fastcall GetTabOnReturn(void){return(EditCtrl->TabOnReturn);}
void __fastcall SetTabOnReturn(bool val){EditCtrl->TabOnReturn = val;}
int __fastcall GetSelStart(void){return(EditCtrl->SelStart);}
void __fastcall SetSelStart(int val){EditCtrl->SelStart = val;}
TPopupMenu* __fastcall _GetPopupMenu(void){return(EditCtrl->PopupMenu);}
void __fastcall SetPopupMenu(TPopupMenu* val){EditCtrl->PopupMenu = val;}

__property int MaxLength = {read=GetMaxLength,write=SetMaxLength};

void __fastcall Paint(void);
DYNAMIC void __fastcall Resize(void);
DYNAMIC void __fastcall MouseDown(TMouseButton Button,TShiftState Shift,int X,int Y);
DYNAMIC void __fastcall MouseUp(TMouseButton Button,TShiftState Shift,int X,int Y);
void __fastcall SetBounds(int ALeft, int ATop, int AWidth, int AHeight);
void __fastcall CMVisibleChanged(TMessage &msg);
void __fastcall CMEnabledChanged(TMessage &msg);
void __fastcall WMContextMenu(TWMContextMenu &msg);
BEGIN_MESSAGE_MAP
VCL_MESSAGE_HANDLER(CM_VISIBLECHANGED,TMessage,CMVisibleChanged);
VCL_MESSAGE_HANDLER(CM_ENABLEDCHANGED,TMessage,CMEnabledChanged);
VCL_MESSAGE_HANDLER(WM_CONTEXTMENU,TWMContextMenu,WMContextMenu);
END_MESSAGE_MAP(inherited);
public:
TPSMoneyEditEdit *EditCtrl;
__fastcall TPSMoneyEdit(TComponent* Owner);
__property double Value = {read=GetValue,write=SetValue,stored=false};
__property AnsiString Text = {read=GetText,write=SetText};
__property int SelStart = {read=GetSelStart,write=SetSelStart,nodefault};

BOOL Focused(void){return(EditCtrl->Focused());}
BOOL CanFocus(void){return(EditCtrl->CanFocus());}
void SetFocus(void){return(EditCtrl->SetFocus());}
void SetRects(void);
__published:
__property AnsiString Prefix = {read=FPrefix,write=SetPrefix};
__property int DecimalCount = {read=FDecimalCount,write=SetDecimalCount,default=2};
__property bool Border = {read=FBorder,write=SetBorder,default=TRUE};
__property TAlignment Alignment = {read=GetAlignment,write=SetAlignment,default=taRightJustify};
__property bool ReadOnly = {read=GetReadOnly,write=SetReadOnly,default=FALSE};
__property bool ParentColor = {read=GetParentColor,write=SetParentColor,default=1};
__property bool TabStop = {read=GetTabStop,write=SetTabStop,default=TRUE};
__property TTabOrder TabOrder = {read=GetTabOrder,write=SetTabOrder,default=-1};
__property TNotifyEvent OnEnter = {read=GetOnEnter,write=SetOnEnter};
__property TNotifyEvent OnExit = {read=GetOnExit,write=SetOnExit};
__property TKeyEvent OnKeyDown = {read=GetOnKeyDown,write=SetOnKeyDown};
__property bool TabOnReturn = {read=GetTabOnReturn,write=SetTabOnReturn,default=TRUE};
__property TPopupMenu* PopupMenu = {read=_GetPopupMenu,write=SetPopupMenu};
};

#endif

No comments: