(***********************************************)
(*                                             *)
(* Evaluate Calculator                         *)
(* Copyright (c) 1999 by TMT Development Corp. *)
(* Author: Vadim Bodrov, TMT Development Corp. *)
(*                                             *)
(* Targets:                                    *)
(*   WIN32 GUI application                     *)
(*                                             *)
(***********************************************)

{$ifndef __WIN32__}
{$define INVALID_TARGET}
{$endif}
{$ifndef __GUI__}
{$define INVALID_TARGET}
{$endif}
{$ifdef INVALID_TARGET}
  This program must be compiled as Win32 GUI application only
{$endif}

program Calc;

uses Windows, Messages, CommDlg, Math, Strings;

{$r calc.res}

const
  EDIT_BOX        = 1000;
  DEC_BOX         = 1001;
  HEX_BOX         = 1002;
  EXP_BOX         = 1003;
  BIN_BOX         = 1004;

  MAIN_DIALOG     = 0101;
  ABOUT_BOX       = 0102;

var
  maindlg: THandle;
  Msg:     TMsg;
  Buffer:  array[0..255] of Char;
  ErrCode: Longint;
  Res:     Extended;
  ResStr:  string;

procedure DlgSetText(CtrlID: THandle; Text: String);
begin
  SendDlgItemMessage(maindlg, CtrlID, WM_SETTEXT, 0, Longint(StrPCopy(Buffer, Text)));
end;

procedure doEvaluate;
begin
  SendDlgItemMessage(maindlg, EDIT_BOX, WM_GETTEXT, 255, Longint(@Buffer));
  if StrPas(Buffer) = '' then
    Buffer[0] := '0';
  Evaluate(StrPas(Buffer), Res, ErrCode);
  if ErrCode = 0 then
  begin
    ResStr := FloatToStr(res);
    DlgSetText(EDIT_BOX, ResStr);
  end;
end;

procedure doCalculate;
begin
  Evaluate(StrPas(Buffer), Res, ErrCode);
  if ErrCode = 0 then
  begin
    Str(Res, ResStr);
    DlgSetText(EXP_BOX, ResStr);
    ResStr := Fix(Res, 0, 0);
    DlgSetText(DEC_BOX, ResStr);
    if (Res <= high(LongInt)) and (Res >= Low(LongInt)) then
    begin
      ResStr := Hex(DWord(Trunc(Res)));
      DlgSetText(HEX_BOX, ResStr);
      ResStr := Bin(Trunc(Res));
      DlgSetText(BIN_BOX, ResStr);
    end else
    begin
      ResStr := 'Overflow';
      DlgSetText(HEX_BOX, ResStr);
      DlgSetText(BIN_BOX, ResStr);
    end;
    end else
    begin
      ResStr := 'Error';
      DlgSetText(DEC_BOX, ResStr);
      DlgSetText(HEX_BOX, ResStr);
      DlgSetText(EXP_BOX, ResStr);
      DlgSetText(BIN_BOX, ResStr);
    end;
end;

function AboutDlgProc conv arg_stdcall (Dialog: HWND; Mess: UINT; WParam: WParam; LParam: LParam): LongInt;
begin
  case Mess of
    WM_CLOSE:
      begin
        EndDialog(Dialog, 0);
        Result := 1;
      end;

    WM_COMMAND:
      begin
        if LoWord(WParam) = IDOK then
        begin
          SendMessage(Dialog, WM_CLOSE, 0, 0);
          Result := 0;
        end;
      end;
    else
      Result := 0;
  end;
end;

function MainDlgProc conv arg_stdcall (Dialog: HWND; Mess: UINT; WParam: WParam; LParam: LParam): LongInt;
begin
  Result := 0;
  case Mess of
  WM_CLOSE:
    DestroyWindow(Dialog);

  WM_COMMAND:
    begin
      case LoWord(WParam) of
        IDHELP:
          DialogBoxParam(hInstance, MAKEINTRESOURCE(ABOUT_BOX), maindlg, @AboutDlgProc, 0);

        IDOK:
          doEvaluate;

        IDCLOSE:
          DestroyWindow(Dialog);

        EDIT_BOX:
          begin
            SendDlgItemMessage(maindlg, EDIT_BOX, WM_GETTEXT, 255, Longint(@Buffer));
            if HiWord(WParam) = EN_CHANGE then doCalculate;
          end;
        end;
      end;

      WM_DESTROY:
        PostQuitMessage(0);
  end;
end;

begin
  maindlg := CreateDialog(hInstance, MakeIntResource(MAIN_DIALOG), 0, @MainDlgProc);
  ShowWindow(maindlg, SW_SHOW);
  SendMessage(mainDlg, WM_SETICON, ICON_SMALL, LoadIcon(hInstance, 'MAINICON'));
  doEvaluate;
  while GetMessage(Msg, 0, 0, 0) do
  begin
    TranslateMessage(Msg);
    DispatchMessage(Msg);
  end;
end.