Calculator using Windows GUI

vegaseat 1 Tallied Votes 6K Views Share

A little calculator written in BCX basic and then translated to C code and modified to compile with Dev C++ (GCC/G++). Once you find your way past the standard GUI gibberish you can figure it out.
For those who need some hand holding with the Dev C++ IDE:
In the IDE go to FILE, then NEW, then Project, select Windows Application, give it a name like Calc1 then click OK. A filesave dialog box comes up, create a new folder, might as well call it Calc1, open it and save Calc1.dev there. The DevCpp IDE comes up with a bare bones template, select and delete that and cut and paste this code into the empty editor page. Now compile and run.

// a very simple and only mildly scientific calculator
// original BCX basic by Kevin Diggins
// modified from BCX generated C code for Dev C++
// allows only one operation at a time (need to improve this):
// 4 * 5 + 3 has to solved via 4 * 5 = then + 3 =
// a Dev-C++ tested Windows Application by  vegaseat  03oct2004

#include <cstdio>
#include <cmath>
#include <string>
#include <windows.h>

#define SPACE  " "

static HINSTANCE BCX_hInstance;
static int     BCX_ScaleX;
static int     BCX_ScaleY;
static char    BCX_ClassName[2048];
static HWND    Form1;
static HWND    Edit1;
static double  Op1;
static double  Op2;
static long    OpFlag;
static long    EqFlag;
static long    Code;

// some macros used
#define Show(Window) RedrawWindow(Window,0,0,0);ShowWindow(Window,SW_SHOW);
#define VAL(a) (double)atof(a)

int     str_cmp(char*, char*);
HWND    BCX_Form(char*,int=0,int=0,int=250,int=150,int=0,int=0);
HWND    BCX_Edit(char*,HWND,int,int,int,int,int,int=0,int=-1);
HWND    BCX_Button(char*,HWND,int=0,int=0,int=0,int=0,int=0,int=0,int=-1);
char*   BCX_Get_Text(HWND);
int     BCX_Set_Text(HWND,char*);
HFONT   BCX_Set_Font (char *,int,int=0,int=0,int=0,int=0);
LRESULT Set_Color (int,int,int,int);
char*   BCX_TmpStr(size_t);
char*   trim (char*);
char*   str (double);
int     instr(char*,char*,int=0,int=0);
char    *_stristr_(char*,char*);

void    FormLoad (void);
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
void    ProcessNumber (int);
void    ProcessOperator (int);

// standard main for windows GUI
int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrev,LPSTR CmdLine,int CmdShow)
{
 WNDCLASS Wc;
 MSG      Msg;
 // *****************************
 strcpy(BCX_ClassName,"CALC1");
 // ************************************
 // Scale Dialog Units To Screen Units
 // ************************************
 RECT rc          =  {0,0,4,8};
 MapDialogRect       (NULL,&rc);
 BCX_ScaleX       =  rc.right/2;
 BCX_ScaleY       =  rc.bottom/4;
 BCX_hInstance    =  hInst;
 // ******************************************************
 Wc.style         =  CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
 Wc.lpfnWndProc   =  WndProc;
 Wc.cbClsExtra    =  0;
 Wc.cbWndExtra    =  0;
 Wc.hInstance     =  hInst;
 Wc.hIcon         =  LoadIcon(NULL,IDI_WINLOGO);
 Wc.hCursor       =  LoadCursor(NULL,IDC_ARROW);
 Wc.hbrBackground =  (HBRUSH)(COLOR_BTNFACE+1);
 Wc.lpszMenuName  =  NULL;
 Wc.lpszClassName =  BCX_ClassName;
 RegisterClass(&Wc);

 FormLoad();
 // message loop, windows GUI functions via messages
 while(GetMessage(&Msg,NULL,0,0))
   {
    HWND hActiveWindow = GetActiveWindow();
    if(!IsWindow(hActiveWindow) || !IsDialogMessage(hActiveWindow,&Msg))
      {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
      }
    }
 return Msg.wParam;
}


// circular storage to prevent memory leaks
char *BCX_TmpStr (size_t Bites)
{
  static int   StrCnt;
  static char *StrFunc[2048];
  StrCnt=(StrCnt + 1) & 2047;
  if(StrFunc[StrCnt]) free (StrFunc[StrCnt]);
  return StrFunc[StrCnt]=(char*)calloc(Bites+128,sizeof(char));
}


// fancy string compare
int str_cmp (char *a, char *b)
{
  register int counter;
  counter=counter^counter;
  while(1)
  {
    if((a[counter]^b[counter]))
    {
      if((UINT) a[counter]>= (UINT) b[counter])
      {
        return  1;
      }
      return -1;
    }
    if(!a[counter]) return 0;
    counter++;
  }
  return 0;
}


// remove certain leading and trailing characters
char *trim (char *S)
{
  register int i = strlen(S);
  char *strtmp = BCX_TmpStr(i);
  strcpy(strtmp,S);
  while(i--)
  {
   if(S[i]!=0  &&
      S[i]!=9  &&
      S[i]!=10 &&
      S[i]!=11 &&
      S[i]!=13 &&
      S[i]!=32) break;
  }
  strtmp[++i]=0;
  if (strtmp)
  {
    while(*(strtmp+1) &&
     *strtmp=='\x00' ||
     *strtmp=='\x09' ||
     *strtmp=='\x0A' ||
     *strtmp=='\x0B' ||
     *strtmp=='\x0D' ||
    (*strtmp=='\x20' ))
     strtmp++;
  }
  return strtmp;
}


// sets accuracy
char *str (double d)
{
  register char *strtmp = BCX_TmpStr(16);
  sprintf(strtmp,"% .15G",d);
  return strtmp;
}


// returns the position where a substring is located in a string
int instr(char* mane,char* match,int offset,int sensflag)
{
  register char *s;
  if (!mane || !match || ! *match || offset>(int)strlen(mane)) return 0;
  if (sensflag)
    s = _stristr_(offset>0 ? mane+offset-1 : mane,match);
  else
    s = strstr (offset>0 ? mane+offset-1 : mane,match);
  return s ? (int)(s-mane)+1 : 0;
}


// supports instr()
char *_stristr_(char *String, char *Pattern)
{
  register char *pptr, *sptr, *start;
  register UINT  slen, plen;
  for (start = (char *)String,
    pptr  = (char *)Pattern,
    slen  = strlen(String),
    plen  = strlen(Pattern);
    slen >= plen;
    start++, slen--)
  {
    while (toupper(*start) != toupper(*Pattern))
    {
      start++;
      slen--;
      if (slen < plen) return(0);
    }
    sptr = start;
    pptr = (char *)Pattern;
    while (toupper(*sptr) == toupper(*pptr))
    {
      sptr++;
      pptr++;
      if (!*pptr) return (start);
    }
  }
  return(0);
}


// created the form
HWND BCX_Form(char *Caption, int X, int Y, int W, int H, int Style, int Exstyle)
{
   HWND  A;
   // assign default style
   if (!Style)
   {
      Style = WS_MINIMIZEBOX  |
      WS_SIZEBOX      |
      WS_CAPTION      |
      WS_MAXIMIZEBOX  |
      WS_POPUP        |
      WS_SYSMENU;
   }
   A = CreateWindowEx(Exstyle,BCX_ClassName,Caption,
     Style,
     X*BCX_ScaleX,
     Y*BCX_ScaleY,
     (4+W)*BCX_ScaleX,
     (12+H)*BCX_ScaleY,
     NULL,(HMENU)NULL,BCX_hInstance,NULL);
   SendMessage(A,(UINT)WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),
     (LPARAM)MAKELPARAM(FALSE,0));
   return A;
}


// create the various calculator buttons
HWND BCX_Button
(char* Text,HWND hWnd,int id,int X,int Y,int W,int H,int Style,int Exstyle)
{ 
  HWND  A;
  // assign default style
  if(!Style)
  {
    Style=WS_CHILD | WS_VISIBLE | BS_MULTILINE | BS_PUSHBUTTON | WS_TABSTOP;
  }
  if(Exstyle==-1)
  {
    Exstyle=WS_EX_STATICEDGE;
  }
  A = CreateWindowEx(Exstyle,"button",Text,Style,
    X*BCX_ScaleX, Y*BCX_ScaleY, W*BCX_ScaleX, H*BCX_ScaleY,
    hWnd,(HMENU)id,BCX_hInstance,NULL);
  SendMessage(A,(UINT)WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),
    (LPARAM)MAKELPARAM(FALSE,0));
  if (W==0)
  {
    HDC  hdc=GetDC(A);
    SIZE  size;
    GetTextExtentPoint32(hdc,Text,strlen(Text),&size);
    ReleaseDC(A,hdc);
    MoveWindow(A,X*BCX_ScaleX,Y*BCX_ScaleY,(int)(size.cx+(size.cx*0.5)),(int)(size.cy+(size.cy*0.32)),TRUE);
  }
  return A;
}


// create the edit box to display entry and result
HWND BCX_Edit
(char* Text,HWND hWnd,int id,int X,int Y,int W,int H,int Style,int Exstyle)
{ 
  HWND  A;
  // assign default style
  if (!Style)
  {
      Style = WS_CHILD | WS_VISIBLE | ES_WANTRETURN |
              WS_VSCROLL | ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL;
  }
  if (Exstyle==-1)
  {
      Exstyle = WS_EX_CLIENTEDGE;
  }
  A = CreateWindowEx(Exstyle,"edit",Text, Style,
      X*BCX_ScaleX, Y*BCX_ScaleY, W*BCX_ScaleX, H*BCX_ScaleY,
      hWnd,(HMENU)id,BCX_hInstance,NULL);
      
  SendMessage(A,(UINT)WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),
    (LPARAM)MAKELPARAM(FALSE,0));
  return A;
}


char *BCX_Get_Text(HWND hWnd)
{
  int tmpint;
  tmpint = 1 + GetWindowTextLength(hWnd);
  char *strtmp = BCX_TmpStr(tmpint);
  GetWindowText(hWnd,strtmp,tmpint);
  return strtmp;
}


int BCX_Set_Text(HWND hWnd, char *Text)
{
  return SetWindowText(hWnd,Text);
}


LRESULT Set_Color (int TxtColr,int BkColr,int wParam,int lParam)
{
  static HBRUSH  ReUsableBrush;
  DeleteObject(ReUsableBrush);
  ReUsableBrush=CreateSolidBrush(BkColr);
  SetTextColor((HDC)wParam,TxtColr);
  SetBkColor((HDC)wParam,BkColr);
  return (LRESULT)ReUsableBrush;
}


HFONT BCX_Set_Font (char *Font,int Size,int Bold,int Italic,int Underline,int StrikeThru)
{
  HDC hDC = GetDC(HWND_DESKTOP);
  int CyPixels = GetDeviceCaps(hDC,LOGPIXELSY);
  ReleaseDC(HWND_DESKTOP,hDC);
  return CreateFont(0-(Size*CyPixels)/72,0,0,0,Bold,Italic,Underline,StrikeThru,
  0,OUT_TT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,FF_DONTCARE,Font);
}


// details like corner coordinates,width,length,text,font
void FormLoad (void)
  {
    Form1 = BCX_Form("One op calculator ...",67,42,185,130);
    Edit1 = BCX_Edit(SPACE,Form1,99,-1,3,200,20);
    SendMessage(Edit1,(UINT)WM_SETFONT,(WPARAM)BCX_Set_Font("Verdana",14),1);
    BCX_Button("0",Form1,100,6,97,50,20);
    BCX_Button("1",Form1,101,6,74,20,20);
    BCX_Button("2",Form1,102,36,74,20,20);
    BCX_Button("3",Form1,103,66,74,20,20);
    BCX_Button("4",Form1,104,6,52,20,20);
    BCX_Button("5",Form1,105,36,52,20,20);
    BCX_Button("6",Form1,106,66,52,20,20);
    BCX_Button("7",Form1,107,6,29,20,20);
    BCX_Button("8",Form1,108,36,29,20,20);
    BCX_Button("9",Form1,109,66,29,20,20);
    BCX_Button(".",Form1,110,66,96,20,20);
    BCX_Button("CE",Form1,112,132,29,20,20);
    BCX_Button("-",Form1,113,132,52,20,20);
    BCX_Button("/",Form1,114,132,74,20,20);
    BCX_Button("%",Form1,115,132,96,20,20);
    BCX_Button("C",Form1,116,103,29,20,20);
    BCX_Button("+",Form1,117,103,52,20,20);
    
    BCX_Button("X",Form1,118,103,74,20,20);
    BCX_Button("=",Form1,119,103,96,20,20);
    BCX_Button("1/X",Form1,120,162,29,20,20);
    BCX_Button("X^2",Form1,121,162,52,20,20);
    BCX_Button("SQR",Form1,122,162,74,20,20);
    BCX_Button("neg",Form1,123,162,96,20,20);

    Show(Form1);
  }


LRESULT CALLBACK WndProc (HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
  while(1)
  {
  if(LOWORD(wParam)>99&&LOWORD(wParam)<110)
    {
      ProcessNumber(LOWORD(wParam)-100);
      break;
    }
  if(LOWORD(wParam)>109)
    {
      ProcessOperator(LOWORD(wParam));
    }
  break;
  }
  if((HWND)lParam==Edit1 && Msg==WM_CTLCOLOREDIT)
    return Set_Color(RGB(0,225,0),RGB(0,0,0),wParam,lParam);
  // tidy up and exit program
  if(Msg==WM_DESTROY)
  {
       UnregisterClass(BCX_ClassName,BCX_hInstance);
       PostQuitMessage(0);
  }
 return DefWindowProc(hWnd,Msg,wParam,lParam);
}


void ProcessNumber (int Digit)
{
  char A[2048];
  strcpy(A,(char*)BCX_Get_Text(Edit1));
  if(str_cmp(A,SPACE)==0)
  {
      *A=0;
  }
  if(EqFlag)
  {
      *A=0;
      EqFlag=FALSE;
  }
  if(OpFlag)
  {
      *A=0;
      BCX_Set_Text(Edit1,"");
      OpFlag=FALSE;
  }
  sprintf(A,"%s%s",A,trim(str(Digit)));
  BCX_Set_Text(Edit1,A);
}


void ProcessOperator (int Operator)
{
  char A[2048];
  strcpy(A,(char*)BCX_Get_Text(Edit1));
  if(str_cmp(A,SPACE)==0)
  {
      *A=0;
  }
  while(1)
  {
  if(Operator==110)   //  .   period
  {
      if(EqFlag)
      {
          *A=0;
          EqFlag=FALSE;
      }
      if(OpFlag)
      {
          *A=0;
          BCX_Set_Text(Edit1,"");
          OpFlag=FALSE;
      }
      if(instr(A,".")==0)
      {
          sprintf(A,"%s%s",A,".");
      }
      BCX_Set_Text(Edit1,A);
      break;
    }
    if(Operator==112)     // CE   clear last entry
    {
      BCX_Set_Text(Edit1,SPACE);
      EqFlag=FALSE;
      break;
    }
    if(Operator==113)     // -   subtract
    {
      Op1=VAL(BCX_Get_Text(Edit1));
      Code=4;
      OpFlag=TRUE;
      EqFlag=FALSE;
      break;
    }
    if(Operator==114)      //  /   divide
    {
      Op1=VAL(BCX_Get_Text(Edit1));
      Code=2;
      OpFlag=TRUE;
      EqFlag=FALSE;
      break;
    }
    if(Operator==115)     //  %  percent to decimal
    {
      Op2=VAL(BCX_Get_Text(Edit1))/100;
      BCX_Set_Text(Edit1,trim(str(Op2)));
      EqFlag=FALSE;
      break;
    }
    if(Operator==116)      //  C   clear all
    {
      BCX_Set_Text(Edit1,SPACE);
      Op1=0;
      Op2=0;
      Code=0;
      EqFlag=FALSE;
      break;
    }
    if(Operator==117)      //  +   add
    {
      Op1=VAL(BCX_Get_Text(Edit1));
      Code=3;
      OpFlag=TRUE;
      EqFlag=FALSE;
      break;
    }
    if(Operator==118)     //  x    multiply
    {
      Op1=VAL(BCX_Get_Text(Edit1));
      Code=1;
      OpFlag=TRUE;
      EqFlag=FALSE;
      break;
    }
    if(Operator==119)       //  =  equals
    {
      Op2=VAL(BCX_Get_Text(Edit1));
      OpFlag=FALSE;
      EqFlag=TRUE;
      while(1)
      {
        if(Code==1)
        {
          Op1*=Op2;
          break;
        }
        if(Code==2)
        {
          Op1/=Op2;
          break;
        }
        if(Code==3)
        {
          Op1+=Op2;
          break;
        }
        if(Code==4)
        {
          Op1-=Op2;
        }
      break;
      }
      strcpy(A,(char*)trim(str(Op1)));
      if(instr(A,"INF"))
      {
        strcpy(A,"Error: Divison by zero");
      }
      BCX_Set_Text(Edit1,A);
      Op2=0;
      break;
    }
    if(Operator==120)     //  1/x   invert
    {
      BCX_Set_Text(Edit1,str(1/VAL(BCX_Get_Text(Edit1))));
      OpFlag=TRUE;
      EqFlag=FALSE;
      break;
    }
    if(Operator==121)     //   x^2    square
    {
      BCX_Set_Text(Edit1,str(VAL(BCX_Get_Text(Edit1))*VAL(BCX_Get_Text(Edit1))));
      OpFlag=TRUE;
      EqFlag=FALSE;
      break;
    }
    if(Operator==122)     //  sqrt   square-root
    {
      BCX_Set_Text(Edit1,str(sqrt(VAL(BCX_Get_Text(Edit1)))));
      OpFlag=TRUE;
      EqFlag=FALSE;
      break;
    }
    if(Operator==123)     //  neg = negate
    {
      BCX_Set_Text(Edit1,str(-1*VAL(BCX_Get_Text(Edit1))));
      OpFlag=TRUE;
      EqFlag=FALSE;
    }
    break;
  }
}

// ****************  credit to Kevin  **************************
//   Created with BCX -- The BASIC To C Translator (ver 5.02)
//  BCX (c) 1999, 2000, 2001, 2002, 2003, 2004 by Kevin Diggins
// *************************************************************
vegaseat 1,735 DaniWeb's Hypocrite Team Colleague

Narue,
see what you did?! This was my first snippet posted on DaniWeb because you wanted to know what BCX could do!

vegaseat 1,735 DaniWeb's Hypocrite Team Colleague

A note on header files, the good old workhorse for C++ is the iostream header file, but beware. The one that comes with DevCpp, and likely others too, is a monster. It itself includes other headers, which in turn include more headers and so on. If you follow the internal includes with an editor you find stdio.h and math.h are there too! The result seems to be a rather bloated executable file. So sometimes it is best and cut the middle-man, here iostream, and get a cute and tiny exe file. Just comment out the line
#define CPP_HEADER

vegaseat 1,735 DaniWeb's Hypocrite Team Colleague

Found some time and was able to replace the iostream header. Now this baby has only a 16k footprint, like a little calculator should have.

Gary King 37 PHP/vBulletin Guru Team Colleague

[Linker error] undefined reference to `GetStockObject@4'

I get a bunch of errors when trying to Compile & Run this.

vegaseat 1,735 DaniWeb's Hypocrite Team Colleague

What compiler are you using, and are you compiling this as a Windows Application?

TheEliteOne 0 Newbie Poster

I tried to compile that source code as a .cpp on the DevC++ compiler and I got a few errors, here is a picture of the errors that I got:

http://img810.imageshack.us/img810/774/guiexamplepic.jpg

Please help, I would love to have this source code as an example, I am just now getting into GUI C++ Programming.

Thanks

EDIT:

Sorry for posting in a thread that hasn't had a post in 6 years lol..... didn't see it until I posted, but I hope that I could get an answer before a staff member "fixes" this (As in closes it or deleted my post) if I can, thanks.

saqib_3 0 Newbie Poster

plz i need a scinetific calculator in this code urgently

rproffitt 2,662 "Nothing to see here." Moderator

To saqib_3. If you need something urgently, why bury it in a 12 year old discussion?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.