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.