Thanks to NageswaraRao who helped on a xBrowser problem with arrays of size 0.
Now I have a kind of undo in my calculator.
I hope many of you have some input.
Regards,
Otto
Code: Select all
/*********************************************************************/
/* */
/* ProcName......: MsgCalc.prg */
/* Author........: Lorenzo Gadaleta */
/* Note..........: Usage Sample : */
/* If you want e ret value in your get : */
/* oGet:VarPut( MsgCalc([nValue]) ) */
/* oGet:Refresh() */
/* Else */
/* MsgCalc() */
/* */
/*********************************************************************/
#include "FiveWin.ch"
#include "InKey.ch"
#include "xbrowse.ch"
#define BIF_RETURNONLYFSDIRS 1
#define BIF_DONTGOBELOWDOMAIN 2
#define MAX_PATH 260
#define PAD_LEFT 0
#define PAD_RIGHT 1
#define PAD_CENTER 2
STATIC aStruc:={}
STATIC oBrw
FUNCTION MsgCalc(nVal)
// Here for languages pesonalization
LOCAL cTitle := "Calculator "
LOCAL cPastMsg := "&Einfügen"
LOCAL cConfirmMsg := " B&estätigen "
LOCAL cAbortMsg := " &End "
LOCAL cPict := "@E 999,999,999,999,999.99"
// End languages personalization
LOCAL n := 100
LOCAL nInit := 0
LOCAL oDlg, oFont, oCursor, oRes, cRes := ""
LOCAL nMemo:=0, nOpe
LOCAL oGet, cGet := Space(100), oBtnOk, oBtnAb, oBtn
LOCAL cLastOpe := "+"
LOCAL oBt1,oBt2,oBt3,oBt4,oBt5,oBt6,oBt7,oBt8,oBt9,oBt0,oBtC
LOCAL oBSum, oBMin, oBMol, oBDiv, oBPer, oBCan, oBRes
LOCAL lRet := .F.
local oClearEntryKey
aadd(aStruc,{"",0,0})
DEFAULT nVal := 0
nInit := nVal
DEFINE FONT oFont NAME "MS Reference Sans Serif" SIZE 0, -12
DEFINE CURSOR oCursor HAND
DEFINE DIALOG oDlg SIZE 405, 405 TITLE cTitle PIXEL FONT oFont
oBrw := TXBrowse():New( oDlg )
oBrw:nTop := 5
oBrw:nLeft := 5
oBrw:nBottom := 90
oBrw:nRight := 180
oBrw:SetArray( aStruc)
oBrw:nMarqueeStyle := MARQSTYLE_HIGHLROW
oBrw:nColDividerStyle := LINESTYLE_BLACK
oBrw:lColDividerComplete := .t.
oBrw:aCols[1]:cHeader := 'Key'
oBrw:aCols[1]:nWidth := 60
oBrw:aCols[1]:nDataStrAlign := AL_CENTER
oBrw:aCols[1]:nEditType := EDIT_GET_LISTBOX
oBrw:aCols[1]:aEditListTxt := {"+", "-", "*", "/"}
oBrw:aCols[1]:bOnPostEdit := {|o,x| aStruc[ oBrw:nArrayAt, 1 ] := x, update_total(oRes,oGet) }
oBrw:aCols[1]:aEditListBound := {"+", "-", "*", "/"}
oBrw:aCols[1]:bClrEdit := oBrw:bClrStd
oBrw:aCols[2]:cHeader := 'Value'
oBrw:aCols[2]:nWidth := 80
oBrw:aCols[2]:nDataStrAlign := AL_RIGHT
oBrw:aCols[2]:bEditvalue := { || aStruc[ oBrw:nArrayAt, 2 ] }
oBrw:aCols[2]:cEditPicture := "@Z 999 999 999.99"
oBrw:aCols[2]:nEditType := EDIT_GET
oBrw:aCols[2]:bOnPostEdit := {|o,x| aStruc[ oBrw:nArrayAt, 2 ] := x, update_total(oRes,oGet) }
oBrw:aCols[2]:bStrData := { || Transform( aStruc[oBrw:nArrayAt][2], "@Z 999 999 999.99" )}
oBrw:aCols[2]:nEditType := EDIT_GET_BUTTON
oBrw:aCols[2]:bEditBlock := {|| Del_line(), update_total(oRes,oGet) }
oBrw:aCols[3]:cHeader := 'Total'
oBrw:aCols[3]:nWidth := 80
oBrw:aCols[3]:nDataStrAlign := AL_RIGHT
oBrw:aCols[3]:bStrData := { || Transform( aStruc[oBrw:nArrayAt][3], "@Z 999 999 999.99" )}
oBrw:CreateFromCode()
@ 100,0.5 GET oGet VAR cGet OF oDlg PIXEL SIZE 95,10
oGet:bChange := {|nKey,nFlag,oB|(Chr(nKey)$"0123456789.,")} // Logical
oGet:bKeyDown := { | nKey | VerKey(nKey,oBSum,oBMin,oBMol,oBDiv,oBPer,oBCan,oBRes,oGet) }
@ 120,5.6 GET oRes VAR cRes OF oDlg PIXEL SIZE 55,10 RIGHT COLOR CLR_RED,CLR_WHITE READONLY
*@ 1.3,1 BUTTON oBtn PROMPT cPastMsg OF oDlg ACTION (oBCan:Click(),SayNum(oGet,nVal)) FONT oFont SIZE 38,10
// Numbers
@ 140 , 1 BUTTON oBt1 PROMPT "1" OF oDlg ACTION SayNum(oGet,1) FONT oFont PIXEL SIZE 30,10
@ 140 , 36 BUTTON oBt2 PROMPT "2" OF oDlg ACTION SayNum(oGet,2) FONT oFont PIXEL SIZE 30,10
@ 140 , 70 BUTTON oBt3 PROMPT "3" OF oDlg ACTION SayNum(oGet,3) FONT oFont PIXEL SIZE 30,10
@ 155 , 1 BUTTON oBt4 PROMPT "4" OF oDlg ACTION SayNum(oGet,4) FONT oFont PIXEL SIZE 30,10
@ 155 , 36 BUTTON oBt5 PROMPT "5" OF oDlg ACTION SayNum(oGet,5) FONT oFont PIXEL SIZE 30,10
@ 155 , 70 BUTTON oBt6 PROMPT "6" OF oDlg ACTION SayNum(oGet,6) FONT oFont PIXEL SIZE 30,10
@ 170 , 1 BUTTON oBt7 PROMPT "7" OF oDlg ACTION SayNum(oGet,7) FONT oFont PIXEL SIZE 30,10
@ 170 , 36 BUTTON oBt8 PROMPT "8" OF oDlg ACTION SayNum(oGet,8) FONT oFont PIXEL SIZE 30,10
@ 170 , 70 BUTTON oBt9 PROMPT "9" OF oDlg ACTION SayNum(oGet,9) FONT oFont PIXEL SIZE 30,10
@ 185 , 1 BUTTON oBt0 PROMPT " 0 " OF oDlg ACTION SayNum(oGet,0) FONT oFont PIXEL SIZE 30,10
@ 185 , 70 BUTTON oBtC PROMPT "." OF oDlg ACTION SayNum(oGet,".") FONT oFont PIXEL SIZE 30,10
// Operators
n:=3
@ 95,120 BUTTON oBSum PROMPT " + " OF oDlg ACTION (CalcRes(cLastOpe,@nMemo,oGet,oRes,cPict),cLastOpe:="+") FONT oFont PIXEL SIZE 30,10
@ 95,160 BUTTON oBMin PROMPT " - " OF oDlg ACTION (CalcRes(cLastOpe,@nMemo,oGet,oRes,cPict),cLastOpe:="-") FONT oFont PIXEL SIZE 30,10
@ 110,120 BUTTON oBMol PROMPT " * " OF oDlg ACTION (CalcRes(cLastOpe,@nMemo,oGet,oRes,cPict),cLastOpe:="*") FONT oFont PIXEL SIZE 30,10
@ 110,160 BUTTON oBDiv PROMPT " / " OF oDlg ACTION (CalcRes(cLastOpe,@nMemo,oGet,oRes,cPict),cLastOpe:="/") FONT oFont PIXEL SIZE 30,10
// @ 125,130 BUTTON oBPer PROMPT " % " OF oDlg ACTION (CalcRes(cLastOpe,@nMemo,oGet,oRes,cPict),cLastOpe:="%") FONT oFont PIXEL SIZE 30,10
@ 125,160 BUTTON oBCan PROMPT "&C " OF oDlg ACTION ;
(;
ASIZE(aStruc,0),;
oBrw:refresh(),;
cLastOpe:="+",;
nMemo:=0,;
oRes:cText(""),;
oGet:cText(Space(100)),;
oGet:SetFocus());
FONT oFont PIXEL SIZE 30,10
@ 140,160 BUTTON oClearEntryKey PROMPT " C&E " OF oDlg ACTION ClearEntryKey(oGet) FONT oFont PIXEL SIZE 30,10
@ 140,120 BUTTON oBRes PROMPT " = " OF oDlg ACTION (CalcRes(cLastOpe,@nMemo,oGet,oRes,cPict),cLastOpe:="") FONT oFont PIXEL SIZE 30,10 DEFAULT
// Exit
*@ n+7.3,1 BUTTON oBtnOk PROMPT cConfirmMsg OF oDlg ACTION (lRet:=.T.,oDlg:End()) FONT oFont SIZE 46,13
@155,120 BUTTON oBtnAb PROMPT cAbortMsg OF oDlg ACTION (lRet:=.F.,oDlg:End()) FONT oFont PIXEL SIZE 46,13 CANCEL
@185,120 BUTTON " Print" OF oDlg ACTION Prn_Calculation(aStruc) FONT oFont PIXEL SIZE 46,13
// Cursors
aEval(oDlg:aControls,{|oC|iif(oC:ClassName()="TBUTTON",oC:oCursor:=oCursor,)})
ACTIVATE DIALOG oDlg CENTER;
ON INIT (ASIZE(aStruc,0), oBrw:refresh());
ON PAINT (oGet:SetFocus());
VALID (oCursor:End(),oFont:End(),.T.)
RETURN iif(lRet,nMemo,nInit)
STATIC FUNCTION SayNum(oGet,xNum)
LOCAL cText := StrTran( Alltrim(oGet:cText()), ",", ".")
if ValType(xNum) == "C"
if !"."$cText
oGet:cText( padR(cText+".",100) )
else
Tone(300)
end
else
oGet:cText( padR(cText+cValToChar(xNum),100) )
end
oGet:SetFocus()
RETURN NIL
STATIC FUNCTION CalcRes(cOpe,nMemo,oGet,oRes,cPict)
LOCAL cVal := StrTran( Alltrim(oGet:cText()), ",", ".")
LOCAL nVal := Val(cVal)
if !left(cVal,1) $ "0123456789."
cVal := Substr(cVal,2)
nVal := Val(cVal)
end
if !right(cVal,1) $ "0123456789."
cVal := Left(cVal,Len(cVal)-1)
nVal := Val(cVal)
end
if cOpe == "+"
nMemo += nVal
elseif cOpe == "-"
nMemo -= nVal
elseif cOpe == "*"
nMemo *= nVal
elseif cOpe == "/"
nMemo /= nVal
elseif cOpe == "%"
nMemo := nMemo*nVal/100
end
oGet:cText( Space(100) )
oRes:cText( Tran(nMemo,"@E 999,999,999,999,999.99") )
//xBrowser
IF len(ALLTRIM(cVal))=0
else
aadd(aStruc,{cOpe,VAL(cVal),nMemo})
ENDIF
oBrw:GoBottom()
oBrw:Refresh()
oGet:SetFocus()
RETURN NIL
STATIC FUNCTION VerKey(nKey,oBSum, oBMin, oBMol, oBDiv, oBPer, oBCan, oBRes,oGet)
local nPos
if nKey == 107 // "+"
oBSum:Click()
elseif nKey == 8 // "<-"
BackSpace(oGet)
nPos := (len(ALLTRIM(oGet:cText())))
oGet:SetPos( nPos+1 )
elseif nKey == 109 // "-"
oBMin:Click()
elseif nKey == 106 // "*"
oBMol:Click()
elseif nKey == 111 // "/"
oBDiv:Click()
end
RETURN 0
func ClearEntryKey(oGet)
oGet:cText := space(100)
oGet:SetFocus()
return nil
func BackSpace(oGet)
local cGetTemp
cGetTemp := left(ALLTRIM(oGet:cText()),(len(ALLTRIM(oGet:cText()))-1))
oGet:cText := cGetTemp + space(100)
oGet:SetFocus()
return nil
function Prn_Calculation(aStruc)
local oPrn, oFont, oPen
Local nLinI, nColI, nLinF, nColF
LOCAL I , nRow
LOCAL cVal
LOCAL cTotal
nRow:=2
PRINT oPrn NAME "Impresión en Vertical.." PREVIEW
DEFINE FONT oFont NAME "Arial" SIZE 0, -10 BOLD OF oPrn
DEFINE PEN oPen WIDTH 2 OF oPrn
oPrn:SetPage(9) // A4
oPrn:SetPortrait() //Vertical
PAGE
nLinI := 0.90
nColI := 0.90
nLinF := 28.6
nColF := 20.0
oPrn:Cmtr2Pix(@nLinI, @nColI)
oPrn:cmtr2Pix(@nLinF, @nColF)
oPrn:Box(nLinI, nColI, nLinF, nColF, oPen )
oPrn:cmSay( 1.0, 1.0, dtoc(date())+ " " + time(), oFont,,CLR_BLACK,,PAD_LEFT )
oPrn:cmSay( 1.0, 10.5, "Berechnung", oFont,,CLR_BLACK,,PAD_CENTER )
FOR I := 1 TO len(aStruc)
cVal := Transform( aStruc[I][2], "@Z 999 999 999.99" )
cTotal := Transform( aStruc[I][3], "@Z 999 999 999.99" )
oPrn:cmSay( nRow + I*0.6, 3.0, aStruc[I][1] , oFont,,CLR_BLACK,,PAD_LEFT )
oPrn:cmSay( nRow + I*0.6, 4.0, cVal , oFont,,CLR_BLACK,,PAD_LEFT )
IF I > 1
IF aStruc[I][1] = "*" .OR. aStruc[I][1]="/" .OR. aStruc[I][1]="%"
oPrn:cmSay( nRow + (I-1) *0.6, 7.0, "= "+ str(aStruc[I-1][3]) , oFont,,CLR_BLACK,,PAD_LEFT )
oPrn:Line( nRow + (I-1) *0.6, 0, nRow + (I-1) *0.6, 15)
ENDIF
ENDIF
NEXT
oPrn:cmSay( nRow + (I+2)*0.6, 7.0, cTotal , oFont,,CLR_BLACK,,PAD_LEFT )
ENDPAGE
ENDPRINT
return nil
func update_total(oRes,oGet)
local I,nTotal:=0
FOR I := 1 TO len(aStruc)
if aStruc[I][1] == "+"
nTotal += aStruc[I][2]
elseif aStruc[I][1] == "-"
nTotal -= aStruc[I][2]
elseif aStruc[I][1] == "*"
nTotal *= aStruc[I][2]
elseif aStruc[I][1] == "/"
nTotal /= aStruc[I][2]
elseif aStruc[I][1] == "%"
nTotal := nTotal*aStruc[I][2]/100
end
aStruc[I][3]:= nTotal
NEXT
oRes:cText( Tran(nTotal,"@E 999,999,999,999,999.99") )
oBrw:GoBottom()
oBrw:Refresh()
oGet:SetFocus()
return nil
func Del_line()
IF len(aStruc)>0
ADel( aStruc, oBrw:nArrayAt )
ASize( aStruc, Len( aStruc ) - 1 )
oBrw:Refresh()
oBrw:GoBottom()
oBrw:Refresh()
else
ASIZE(aStruc,0)
oBrw:refresh()
endif
return NIL
Changes in cBrowser-class (by NageswaraRao suggested)
Code: Select all
METHOD Refresh( lComplete ) CLASS TXBrowse
DEFAULT lComplete := .F.
::KeyCount()
if lComplete
::nRowSel = 1
::nArrayAt = 1
else
::nRowSel = Max( 1, Min( ::nRowSel, ::nLen ) )
::nArrayAt = Min( ::nArrayAt, ::nLen )
if ::nArrayAt == 0 .and. ::nLen > 0
::nArrayAt := 1
endif
endif
::GetDisplayCols()
return Super:Refresh( .T. )