Last updated: 4. 3.1998, 23: 1
<*/NOWARN:F*>
MODULE HexCalc;
(*----------------------------------------
HEXCALC.C --- Hexadecimal Calculator
(c) Charles Petzold, 1996
HexCalc.mod --- Translation to Stony Brook Modula-2
(c) Peter Stadler, 1997
----------------------------------------*)
IMPORT WINUSER;
IMPORT WIN32;
IMPORT WINX;
IMPORT WINGDI;
IMPORT CharClass;
IMPORT FormatString;
IMPORT SYSTEM;
%IF WIN32 %THEN
<*/Resource:HexCalc.res*>
%ELSE
%END
CONST
szAppName = "HexCalc";
VAR
hwnd : WIN32.HWND;
msg : WINUSER.MSG;
wc : WINUSER.WNDCLASSEX;
bNewNumber : BOOLEAN;
iOperation : CARDINAL;
iNumber : WIN32.UINT;
iFirstNum : WIN32.UINT;
hButton : WIN32.HWND;
(*++++*****************************************************************)
PROCEDURE ShowNumber (hwnd : WIN32.HWND;
iNumber : WIN32.UINT);
(**********************************************************************)
VAR
szBuffer : ARRAY[0..19] OF CHAR;
BEGIN
FormatString.CardToHexStr(iNumber, szBuffer);
WINUSER.SetDlgItemText (hwnd, WINUSER.VK_ESCAPE,szBuffer);
END ShowNumber;
(*++++*****************************************************************)
PROCEDURE CalcIt (iFirstNum : WIN32.UINT;
iOperation: CARDINAL;
iNum : WIN32.UINT) : WIN32.DWORD;
(**********************************************************************)
BEGIN
CASE (iOperation) OF
| ORD('=') : RETURN iNum;
| ORD('+') : RETURN iFirstNum + iNum;
| ORD('-') : RETURN iFirstNum - iNum;
| ORD('*') : RETURN iFirstNum * iNum;
| ORD('&') : RETURN iFirstNum BAND iNum;
| ORD('|') : RETURN iFirstNum BOR iNum;
| ORD('^') : RETURN iFirstNum BXOR iNum;
| ORD('<') : RETURN iFirstNum SHL iNum;
| ORD('>') : RETURN iFirstNum SHR iNum;
| ORD('/') : IF(iNum=0) THEN
RETURN MAX(CARDINAL);
ELSE
RETURN iFirstNum / iNum;
END;
| ORD('%') : IF(iNum=0) THEN
RETURN MAX(CARDINAL);;
ELSE
RETURN iFirstNum REM iNum;
END;
ELSE
RETURN 0;
END;
END CalcIt;
<*/PUSH*>
%IF WIN32 %THEN
<*/CALLS:WIN32SYSTEM*>
%ELSE
<*/CALLS:WINSYSTEM*>
%END
(*++++*****************************************************************)
PROCEDURE WndProc (hwnd : WIN32.HWND;
(**********************************************************************)
iMsg : WIN32.UINT;
wParam : WIN32.WPARAM;
lParam : WIN32.LPARAM) : WIN32.LRESULT [EXPORT];
VAR
c : WIN32.UINT;
BEGIN
CASE (iMsg) OF
| WINUSER.WM_KEYDOWN : (* left arrow --> backspace *)
IF (wParam = WINUSER.VK_LEFT) THEN
wParam := WINUSER.VK_BACK;
END;
(* fall through *)
| WINUSER.WM_CHAR :
wParam := ORD(WINUSER.CharUpper(CHR(wParam)));
IF (wParam = WINUSER.VK_RETURN) THEN
wParam := ORD('=');
END;
hButton := WINUSER.GetDlgItem (hwnd, wParam);
IF (hButton # NIL) THEN
WINUSER.SendMessage (hButton, WINUSER.BM_SETSTATE, 1, 0);
WINUSER.SendMessage (hButton, WINUSER.BM_SETSTATE, 0, 0);
ELSE
WINUSER.MessageBeep (0);
(*break; *)
END;
(* fall through *)
| WINUSER.WM_COMMAND :
WINUSER.SetFocus (hwnd);
IF (WINUSER.LOWORD (wParam) = WINUSER.VK_BACK) THEN (* backspace *)
iNumber := iNumber/16;
ShowNumber (hwnd, iNumber);
ELSIF (WINUSER.LOWORD (wParam) = WINUSER.VK_ESCAPE) THEN (* escape *)
iNumber := 0;
ShowNumber (hwnd, iNumber);
ELSIF (FormatString.IsHexadecimalDigit (WINUSER.LOWORD (wParam))) THEN (* hex digit *)
IF (bNewNumber) THEN
iFirstNum := iNumber;
iNumber := 0;
END;
bNewNumber := FALSE;
IF (iNumber <= (MAX(CARDINAL) SHR 4 )) THEN
IF(CharClass.IsNumeric(CHR(wParam))) THEN
c := ORD('0');
ELSE
c := ORD('A')-10;
END;
iNumber := 16 * iNumber + wParam - c;
ShowNumber (hwnd, iNumber);
ELSE
WINUSER.MessageBeep (0);
END;
ELSE (* operation *)
IF (bNewNumber=FALSE) THEN
iNumber := CalcIt(iFirstNum, iOperation, iNumber);
ShowNumber (hwnd,iNumber);
END;
bNewNumber := TRUE;
iOperation := WINUSER.LOWORD (wParam);
END;
RETURN 0;
| WINUSER.WM_DESTROY :
WINUSER.PostQuitMessage (0);
RETURN 0;
ELSE
RETURN WINUSER.DefWindowProc (hwnd, iMsg, wParam, lParam);
END;
RETURN WINUSER.DefWindowProc (hwnd, iMsg, wParam, lParam);
END WndProc;
<*/POP*>
(*++++*****************************************************************)
PROCEDURE InitApplication () : BOOLEAN;
(**********************************************************************)
VAR rc : CARDINAL;
BEGIN
wc.cbSize := SIZE(wc);
wc.style := WINUSER.CS_HREDRAW BOR WINUSER.CS_VREDRAW;
wc.lpfnWndProc := WndProc;
wc.cbClsExtra := 0;
wc.cbWndExtra := WINUSER.DLGWINDOWEXTRA;
wc.hInstance := WINX.Instance;
wc.hIcon := WINUSER.LoadIcon (wc.hInstance,szAppName);
wc.hCursor := WINUSER.LoadCursor (NIL, WINUSER.IDC_ARROW^);
wc.hbrBackground := SYSTEM.CAST(WIN32.HBRUSH, WINUSER.COLOR_WINDOW+1);
wc.lpszMenuName := NIL;
wc.lpszClassName := SYSTEM.ADR(szAppName);
wc.hIconSm := WINUSER.LoadIcon (wc.hInstance,szAppName);
rc := WINUSER.RegisterClassEx(wc);
RETURN rc#0;
END InitApplication;
(*++++*****************************************************************)
PROCEDURE InitMainWindow () : BOOLEAN;
(**********************************************************************)
BEGIN
hwnd := WINUSER.CreateDialog (WINX.Instance,
szAppName,
SYSTEM.CAST(WIN32.HWND,0),
SYSTEM.CAST(WINUSER.DLGPROC,NIL));
IF hwnd = NIL THEN
RETURN FALSE;
END;
WINUSER.ShowWindow (hwnd, WINUSER.SW_SHOWDEFAULT);
WINUSER.UpdateWindow (hwnd);
RETURN TRUE;
END InitMainWindow;
BEGIN
bNewNumber := TRUE;
iOperation := ORD('=');
IF InitApplication() AND InitMainWindow() THEN
WHILE (WINUSER.GetMessage(msg,NIL,0,0)) DO
WINUSER.TranslateMessage(msg);
WINUSER.DispatchMessage(msg);
END;
END;
END HexCalc.