Gui calculator

Windows specific questions.
Löwenherz
Posts: 46
Joined: Aug 27, 2008 6:26
Location: Bad Sooden-Allendorf, Germany

Gui calculator

Post by Löwenherz »

Hi all
Made this little calculator example (SDK style) with a gui and Input Mask only the result edit Box doesn't Work correct perhaps anybody can Help , thanks Löwenherz

Code: Select all

' Freebasic test code, 16-03-2024
' calculator gui 
 
#include "windows.bi"

' Constants for controls
Const IDC_NUM1 = 1001
Const IDC_NUM2 = 1002
Const IDC_RESULT = 1003
Const IDC_ADD = 2001
Const IDC_SUBTRACT = 2002
Const IDC_MULTIPLY = 2003
Const IDC_DIVIDE = 2004
Const IDC_CALCULATE = 2005

Function WndProc(ByVal hWnd As HWND, ByVal uMsg As UINT, ByVal wParam As WPARAM, ByVal lParam As LPARAM) As LRESULT
    Select Case uMsg
        Case WM_CREATE
            ' Create edit boxes for numbers
            CreateWindowEx(0, "EDIT", "", WS_CHILD Or WS_VISIBLE Or WS_BORDER Or ES_NUMBER, 50, 50, 100, 20, hWnd, IDC_NUM1, GetModuleHandle(Null), ByVal Null)
            CreateWindowEx(0, "EDIT", "", WS_CHILD Or WS_VISIBLE Or WS_BORDER Or ES_NUMBER, 200, 50, 100, 20, hWnd, IDC_NUM2, GetModuleHandle(Null), ByVal Null)
            
            ' Create radio buttons for operations
            CreateWindowEx(0, "BUTTON", "+", WS_CHILD Or WS_VISIBLE Or BS_AUTORADIOBUTTON, 50, 100, 50, 20, hWnd, IDC_ADD, GetModuleHandle(Null), ByVal Null)
            CreateWindowEx(0, "BUTTON", "-", WS_CHILD Or WS_VISIBLE Or BS_AUTORADIOBUTTON, 100, 100, 50, 20, hWnd, IDC_SUBTRACT, GetModuleHandle(Null), ByVal Null)
            CreateWindowEx(0, "BUTTON", "*", WS_CHILD Or WS_VISIBLE Or BS_AUTORADIOBUTTON, 150, 100, 50, 20, hWnd, IDC_MULTIPLY, GetModuleHandle(Null), ByVal Null)
            CreateWindowEx(0, "BUTTON", "/", WS_CHILD Or WS_VISIBLE Or BS_AUTORADIOBUTTON, 200, 100, 50, 20, hWnd, IDC_DIVIDE, GetModuleHandle(Null), ByVal Null)
            
            ' Create button for calculation
            CreateWindowEx(0, "BUTTON", "=", WS_CHILD Or WS_VISIBLE Or BS_AUTORADIOBUTTON, 250, 100, 50, 20, hWnd, IDC_CALCULATE, GetModuleHandle(Null), ByVal Null)
            
            ' Create edit box for result
            CreateWindowEx(0, "EDIT", "", WS_CHILD Or WS_VISIBLE Or WS_BORDER Or ES_NUMBER Or ES_READONLY, 50, 150, 250, 20, hWnd, IDC_RESULT, GetModuleHandle(Null), ByVal Null)
            
            ' Set default operation to addition
            SendDlgItemMessage(hWnd, IDC_ADD, BM_SETCHECK, BST_CHECKED, 0)

   Case WM_COMMAND
    If HIWORD(wParam) = BN_CLICKED Then
        Dim operation As String

        ' Get selected operation
        Select Case LOWORD(wParam)
            Case IDC_ADD
                operation = "+"
            Case IDC_SUBTRACT
                operation = "-"
            Case IDC_MULTIPLY
                operation = "*"
            Case IDC_DIVIDE
                operation = "/"
            Case IDC_CALCULATE
                Dim num1 As Double
                Dim num2 As Double
                Dim result As Double
                
                '-------- problem zone ------------------------- //
                
                GetDlgItemText(hWnd, IDC_NUM1, Str$(num1), 20) ' ???
                GetDlgItemText(hWnd, IDC_NUM2, Str$(num2), 20) ' ???
          
                ' Get input numbers
                'num1 = Val(GetDlgItemText(hWnd, IDC_NUM1))  ' ???
                'num2 = Val(GetDlgItemText(hWnd, IDC_NUM2))  ' ???
                 
                '-------- problem zone ends ------------------------- //

                ' Perform calculation based on selected operation
                Select Case operation
                    Case "+"
                        result = num1 + num2
                    Case "-"
                        result = num1 - num2
                    Case "*"
                        result = num1 * num2
                    Case "/"
                        If num2 <> 0 Then
                            result = num1 / num2
                        Else
                            Print "Cannot divide by zero!", , "Error"
                            Exit Function
                        End If
                End Select

                ' Display result
                SetDlgItemText(hWnd, IDC_RESULT, Str(result))
        End Select
    End If
 
    	Case WM_CLOSE
            DestroyWindow(hWnd)
        Case WM_DESTROY
            PostQuitMessage(0)
        Case Else
            Return DefWindowProc(hWnd, uMsg, wParam, lParam)
    End Select
    Return 0
End Function

Function WinMain(ByVal hInstance As HINSTANCE, ByVal hPrevInstance As HINSTANCE, ByVal lpCmdLine As LPSTR, ByVal nCmdShow As Integer) As Integer
    Dim wc As WNDCLASSEX
    Dim hWnd As HWND
    Dim msg As MSG
    
    ' Register window class
    wc.cbSize = SizeOf(WNDCLASSEX)
    wc.style = CS_HREDRAW Or CS_VREDRAW
    wc.lpfnWndProc = @WndProc
    wc.cbClsExtra = 0
    wc.cbWndExtra = 0
    wc.hInstance = hInstance
    wc.hIcon = LoadIcon(Null, IDI_APPLICATION)
    wc.hIconSm = LoadIcon(Null, IDI_APPLICATION)
    wc.hCursor = LoadCursor(Null, IDC_ARROW)
    wc.hbrBackground = GetStockObject(WHITE_BRUSH)
    wc.lpszMenuName = Null
    wc.lpszClassName = StrPtr("InputMaskClass")
    
    If RegisterClassEx(@wc) = 0 Then
        Print "Window Registration Failed!", , "Error"
        Function = 0
        Exit Function
    End If
    
    ' Create the window
    hWnd = CreateWindowEx(0, StrPtr("InputMaskClass"), StrPtr("Input Mask Example"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 400, 300, Null, Null, hInstance, Null)
    
    If hWnd = 0 Then
        Print "Window Creation Failed!", , "Error"
        Function = 0
        Exit Function
    End If
    
    ' Show and update the window
    ShowWindow(hWnd, nCmdShow)
    UpdateWindow(hWnd)
    
    ' Message loop
    While GetMessage(@msg, Null, 0, 0) > 0
        TranslateMessage(@msg)
        DispatchMessage(@msg)
    Wend
    
    Function = msg.wParam
End Function

WinMain(GetModuleHandle(Null), Null, Command(), SW_SHOWNORMAL)
SARG
Posts: 1768
Joined: May 27, 2005 7:15
Location: FRANCE

Re: Gui calculator

Post by SARG »

- GetDlgItemText expects a string ptr. And same for SetDlgItemText
- You should also add a cast in createwindow to avoid warnings.
eg cast(HMENU, IDC_NUM1)
- I added a 'case else' for select operation : default addition otherwise result zero

Code: Select all

' Freebasic test code, 16-03-2024
' calculator gui 
 
#include "windows.bi"

' Constants for controls
Const IDC_NUM1 = 1001
Const IDC_NUM2 = 1002
Const IDC_RESULT = 1003
Const IDC_ADD = 2001
Const IDC_SUBTRACT = 2002
Const IDC_MULTIPLY = 2003
Const IDC_DIVIDE = 2004
Const IDC_CALCULATE = 2005

Function WndProc(ByVal hWnd As HWND, ByVal uMsg As UINT, ByVal wParam As WPARAM, ByVal lParam As LPARAM) As LRESULT
    Select Case uMsg
        Case WM_CREATE
            ' Create edit boxes for numbers
            CreateWindowEx(0, "EDIT", "", WS_CHILD Or WS_VISIBLE Or WS_BORDER Or ES_NUMBER, 50, 50, 100, 20, hWnd, IDC_NUM1, GetModuleHandle(Null), ByVal Null)
            CreateWindowEx(0, "EDIT", "", WS_CHILD Or WS_VISIBLE Or WS_BORDER Or ES_NUMBER, 200, 50, 100, 20, hWnd, IDC_NUM2, GetModuleHandle(Null), ByVal Null)
            
            ' Create radio buttons for operations
            CreateWindowEx(0, "BUTTON", "+", WS_CHILD Or WS_VISIBLE Or BS_AUTORADIOBUTTON, 50, 100, 50, 20, hWnd, IDC_ADD, GetModuleHandle(Null), ByVal Null)
            CreateWindowEx(0, "BUTTON", "-", WS_CHILD Or WS_VISIBLE Or BS_AUTORADIOBUTTON, 100, 100, 50, 20, hWnd, IDC_SUBTRACT, GetModuleHandle(Null), ByVal Null)
            CreateWindowEx(0, "BUTTON", "*", WS_CHILD Or WS_VISIBLE Or BS_AUTORADIOBUTTON, 150, 100, 50, 20, hWnd, IDC_MULTIPLY, GetModuleHandle(Null), ByVal Null)
            CreateWindowEx(0, "BUTTON", "/", WS_CHILD Or WS_VISIBLE Or BS_AUTORADIOBUTTON, 200, 100, 50, 20, hWnd, IDC_DIVIDE, GetModuleHandle(Null), ByVal Null)
            
            ' Create button for calculation
            CreateWindowEx(0, "BUTTON", "=", WS_CHILD Or WS_VISIBLE Or BS_AUTORADIOBUTTON, 250, 100, 50, 20, hWnd, IDC_CALCULATE, GetModuleHandle(Null), ByVal Null)
            
            ' Create edit box for result
            CreateWindowEx(0, "EDIT", "", WS_CHILD Or WS_VISIBLE Or WS_BORDER Or ES_NUMBER Or ES_READONLY, 50, 150, 250, 20, hWnd, IDC_RESULT, GetModuleHandle(Null), ByVal Null)
            
            ' Set default operation to addition
            SendDlgItemMessage(hWnd, IDC_ADD, BM_SETCHECK, BST_CHECKED, 0)

   Case WM_COMMAND
    If HIWORD(wParam) = BN_CLICKED Then
        dim operation As String
 
        ' Get selected operation
        Select Case LOWORD(wParam)
            Case IDC_ADD
                operation = "+"
            Case IDC_SUBTRACT
                operation = "-"
            Case IDC_MULTIPLY
                operation = "*"
            Case IDC_DIVIDE
                operation = "/"
            Case IDC_CALCULATE
                Dim num1 As Double
                Dim num2 As Double
                Dim result As Double
                dim as string snum1=space(21)
                dim as string snum2=space(21)
                dim as string sresult=space(21)
                '-------- problem zone ------------------------- //
                
                GetDlgItemText(hWnd, IDC_NUM1, strptr(snum1), 20) ' ???
                GetDlgItemText(hWnd, IDC_NUM2, strptr(snum2), 20) ' ???
				num1= val(snum1)
				num2= val(snum2)

                ' Get input numbers
                'num1 = Val(GetDlgItemText(hWnd, IDC_NUM1))  ' ???
                'num2 = Val(GetDlgItemText(hWnd, IDC_NUM2))  ' ???
                 
                '-------- problem zone ends ------------------------- //

                ' Perform calculation based on selected operation
                Select Case operation
                    Case "+"
                        result = num1 + num2
                    Case "-"
                        result = num1 - num2
                    Case "*"
                        result = num1 * num2
                    Case "/"
                        If num2 <> 0 Then
                            result = num1 / num2
                        Else
                            Print "Cannot divide by zero!", , "Error"
                            Exit Function
                        End If
                    case else
                    ''default addition otherwise result = zero
                    result = num1 + num2
                End Select
				sresult=str(result)
                ' Display result
                SetDlgItemText(hWnd, IDC_RESULT, Strptr(sresult))
        End Select
    End If
 
    	Case WM_CLOSE
            DestroyWindow(hWnd)
        Case WM_DESTROY
            PostQuitMessage(0)
        Case Else
            Return DefWindowProc(hWnd, uMsg, wParam, lParam)
    End Select
    Return 0
End Function

Function WinMain(ByVal hInstance As HINSTANCE, ByVal hPrevInstance As HINSTANCE, ByVal lpCmdLine As LPSTR, ByVal nCmdShow As Integer) As Integer
    Dim wc As WNDCLASSEX
    Dim hWnd As HWND
    Dim msg As MSG
    
    ' Register window class
    wc.cbSize = SizeOf(WNDCLASSEX)
    wc.style = CS_HREDRAW Or CS_VREDRAW
    wc.lpfnWndProc = @WndProc
    wc.cbClsExtra = 0
    wc.cbWndExtra = 0
    wc.hInstance = hInstance
    wc.hIcon = LoadIcon(Null, IDI_APPLICATION)
    wc.hIconSm = LoadIcon(Null, IDI_APPLICATION)
    wc.hCursor = LoadCursor(Null, IDC_ARROW)
    wc.hbrBackground = GetStockObject(WHITE_BRUSH)
    wc.lpszMenuName = Null
    wc.lpszClassName = StrPtr("InputMaskClass")
    
    If RegisterClassEx(@wc) = 0 Then
        Print "Window Registration Failed!", , "Error"
        Function = 0
        Exit Function
    End If
    
    ' Create the window
    hWnd = CreateWindowEx(0, StrPtr("InputMaskClass"), StrPtr("Input Mask Example"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 400, 300, Null, Null, hInstance, Null)
    
    If hWnd = 0 Then
        Print "Window Creation Failed!", , "Error"
        Function = 0
        Exit Function
    End If
    
    ' Show and update the window
    ShowWindow(hWnd, nCmdShow)
    UpdateWindow(hWnd)
    
    ' Message loop
    While GetMessage(@msg, Null, 0, 0) > 0
        TranslateMessage(@msg)
        DispatchMessage(@msg)
    Wend
    
    Function = msg.wParam
End Function

WinMain(GetModuleHandle(Null), Null, Command(), SW_SHOWNORMAL)
Löwenherz
Posts: 46
Joined: Aug 27, 2008 6:26
Location: Bad Sooden-Allendorf, Germany

Re: Gui calculator

Post by Löwenherz »

Many thanks for fast reply help and comments its helpful sarg :)

I am Not anymore very familiär with freebasic language and must learn some Syntax and commands new again started over 16 years ago with freebasic then paused cause launching Family and much more...
Thanks, Löwenherz
PaulSquires
Posts: 1002
Joined: Jul 14, 2005 23:41

Re: Gui calculator

Post by PaulSquires »

This looks like code that you posted over on my planetsquires forum?
https://www.planetsquires.com/protect/f ... pic=4757.0

Here is the code reply that I posted for you:

Code: Select all

'
' mini calculator GUI by frank bruebach, 20:06 MEZ PM, 16.03.2024
' freebasic
#define UNICODE
#define _WIN32_WINNT &h0602
#INCLUDE ONCE "Afx/CWindow.inc"
#INCLUDE ONCE "Afx/AfxGdiPlus.inc"
#INCLUDE ONCE "Afx/AfxMenu.inc"
USING Afx
' // Menu identifiers
ENUM
    IDM_UNDO = 5000   ' Undo
    IDM_REDO          ' Redo
    IDM_HOME          ' Home
    IDM_SAVE          ' Save
    IDM_EXIT          ' Exit
END ENUM

' Constants for controls
ENUM
    IDC_NUM1 = 1000
    IDC_NUM2
    IDC_RESULT
    IDC_ADD
    IDC_SUBTRACT
    IDC_MULTIPLY
    IDC_DIVIDE
    IDC_CALCULATE
END ENUM

DECLARE FUNCTION WinMain (BYVAL hInstance AS HINSTANCE, _
                          BYVAL hPrevInstance AS HINSTANCE, _
                          BYVAL szCmdLine AS ZSTRING PTR, _
                          BYVAL nCmdShow AS LONG) AS LONG

   END WinMain(GetModuleHandleW(NULL), NULL, COMMAND(), SW_NORMAL)

' // Forward declaration
DECLARE FUNCTION WndProc (BYVAL hwnd AS HWND, BYVAL uMsg AS UINT, BYVAL wParam AS WPARAM, BYVAL lParam AS LPARAM) AS LRESULT

' ========================================================================================
' Build the menu
' ========================================================================================
FUNCTION BuildMenu () AS HMENU
   DIM hMenu AS HMENU
   DIM hPopUpMenu AS HMENU

   hMenu = CreateMenu
   hPopUpMenu = CreatePopUpMenu
      AppendMenuW hMenu, MF_POPUP OR MF_ENABLED, CAST(UINT_PTR, hPopUpMenu), "&File"
         AppendMenuW hPopUpMenu, MF_ENABLED, IDM_UNDO, "&Undo" & CHR(9) & "Ctrl+U"
         AppendMenuW hPopUpMenu, MF_ENABLED, IDM_REDO, "&Redo" & CHR(9) & "Ctrl+R"
         AppendMenuW hPopUpMenu, MF_ENABLED, IDM_HOME, "&Home" & CHR(9) & "Ctrl+H"
         AppendMenuW hPopUpMenu, MF_ENABLED, IDM_SAVE, "&Save" & CHR(9) & "Ctrl+S"
         AppendMenuW hPopUpMenu, MF_ENABLED, IDM_EXIT, "E&xit" & CHR(9) & "Alt+F4"
   FUNCTION = hMenu

END FUNCTION
'  =================================================================================
FUNCTION WinMain (BYVAL hInstance AS HINSTANCE, _
                  BYVAL hPrevInstance AS HINSTANCE, _
                  BYVAL szCmdLine AS ZSTRING PTR, _
                  BYVAL nCmdShow AS LONG) AS LONG
   ' // Set process DPI aware
   AfxSetProcessDPIAware

   ' // Create the main window
   DIM pWindow AS CWindow
   pWindow.Create(NULL, "mini Calculator GUI", @WndProc)
   pWindow.SetClientSize(400, 350)
   pWindow.Center

   ' // Add a button -> but I needed here some Radiobuttons too ;)
   pWindow.AddControl("Button", , IDCANCEL, "&Close", 280, 280, 75, 23)
   pWindow.AddControl("Edit",, IDC_NUM1, "", 50, 50, 75, 23)
   pWindow.AddControl("Edit",, IDC_NUM2, "", 200, 50, 75, 23)
   pWindow.AddControl("RADIOBUTTON",, IDC_ADD, "+", 50, 100, 30, 23, WS_GROUP)
   pWindow.AddControl("RADIOBUTTON",, IDC_SUBTRACT, "-", 100, 100, 30, 23)
   pWindow.AddControl("RADIOBUTTON",, IDC_MULTIPLY, "*", 150, 100, 30, 23)
   pWindow.AddControl("RADIOBUTTON",, IDC_DIVIDE, "/", 200, 100, 30, 23)
   pWindow.AddControl("BUTTON",, IDC_CALCULATE, "=", 250, 100, 75, 23)
   pWindow.AddControl("Edit",, IDC_RESULT, "", 50, 150, 75, 23)
   '
   ' ------------------ problem zone ----------------------------- //
   ' Set default operation to addition
   ' SendDlgItemMessage(hWnd, IDC_ADD, BM_SETCHECK, BST_CHECKED, 0)
   CheckRadioButton(pWindow.hWindow, IDC_ADD, IDC_DIVIDE, IDC_ADD)
   ' ------------------ problem zone ----------------------------- //
  
   ' // Create the menu
   DIM hMenu AS HMENU = BuildMenu
   SetMenu pWindow.hWindow, hMenu

   ' // Add icons to the items of the File menu
   DIM hSubMenu AS HMENU = GetSubMenu(hMenu, 0)
   AfxAddIconToMenuItem(hSubMenu, 0, TRUE, AfxGdipIconFromRes(hInstance, "IDI_ARROW_LEFT_32"))
   AfxAddIconToMenuItem(hSubMenu, 1, TRUE, AfxGdipIconFromRes(hInstance, "IDI_ARROW_RIGHT_32"))
   AfxAddIconToMenuItem(hSubMenu, 2, TRUE, AfxGdipIconFromRes(hInstance, "IDI_HOME_32"))
   AfxAddIconToMenuItem(hSubMenu, 3, TRUE, AfxGdipIconFromRes(hInstance, "IDI_SAVE_32"))
  
   SetFocus GetDlgItem(pWindow.hWindow, IDC_NUM1)
  
   ' // Dispatch Windows messages
   FUNCTION = pWindow.DoEvents(nCmdShow)
END FUNCTION
' ========================================================================================

' ========================================================================================
' Main window callback procedure
' ========================================================================================
FUNCTION WndProc (BYVAL hwnd AS HWND, BYVAL uMsg AS UINT, BYVAL wParam AS WPARAM, BYVAL lParam AS LPARAM) AS LRESULT
 
     SELECT CASE uMsg
         CASE WM_COMMAND

             IF GET_WM_COMMAND_CMD(wParam, lParam) = BN_CLICKED THEN

                 SELECT CASE GET_WM_COMMAND_ID(wParam, lParam)
                     CASE IDCANCEL
                         ' // If ESC key pressed, close the application sending an WM_CLOSE message
                         SendMessageW hwnd, WM_CLOSE, 0, 0
                         EXIT FUNCTION
                        
                     CASE IDC_CALCULATE
                         dim as double num1 = val(AfxGetWindowText(GetDlgItem(hwnd, IDC_NUM1)))
                         dim as double num2 = val(AfxGetWindowText(GetDlgItem(hwnd, IDC_NUM2)))
                         Dim as double result

                         ' Perform calculation based on selected operation
                         if Button_GetCheck(GetDlgItem(hwnd,IDC_ADD)) = BST_CHECKED then
                             result = num1 + num2
                         end if
                         if Button_GetCheck(GetDlgItem(hwnd,IDC_SUBTRACT)) = BST_CHECKED then
                             result = num1 - num2
                         end if
                         if Button_GetCheck(GetDlgItem(hwnd,IDC_MULTIPLY)) = BST_CHECKED then
                             result = num1 * num2
                         end if
                         if Button_GetCheck(GetDlgItem(hwnd,IDC_DIVIDE)) = BST_CHECKED then
                             If num2 <> 0 Then
                                 result = num1 / num2
                             Else
                                 Print "Cannot divide by zero!", , "Error"
                                 Exit Function
                             End If
                         end if
                        AfxSetWindowText(GetDlgItem(hwnd, IDC_RESULT), str(result))             

                     CASE IDM_UNDO
                         MessageBox hwnd, "Undo option clicked", "Menu", MB_OK
                         EXIT FUNCTION
                     CASE IDM_REDO
                         MessageBox hwnd, "Redo option clicked", "Menu", MB_OK
                         EXIT FUNCTION
                     CASE IDM_HOME
                         MessageBox hwnd, "Home option clicked", "Menu", MB_OK
                         EXIT FUNCTION
                     CASE IDM_SAVE
                         MessageBox hwnd, "Save option clicked", "Menu", MB_OK
                         EXIT FUNCTION
                     CASE IDM_EXIT
                         SendMessageW hwnd, WM_CLOSE, 0, 0
                         EXIT FUNCTION
            
                 END SELECT
             END IF
              
        CASE WM_DESTROY
         ' // End the application by sending an WM_QUIT message
         PostQuitMessage(0)
         EXIT FUNCTION
    END SELECT

    ' // Default processing of Windows messages
    FUNCTION = DefWindowProcW(hWnd, uMsg, wParam, lParam)
END FUNCTION
' ========================================================================================

Löwenherz
Posts: 46
Joined: Aug 27, 2008 6:26
Location: Bad Sooden-Allendorf, Germany

Re: Gui calculator

Post by Löwenherz »

Hello Paul thanks again and yes thats me :)
But I am Not guilty lol :-D

I was curious to See how a usual freebasic Code Works with WinFBE Editor and jose's headers...
I heard some weeks ago of winfbx forum and your Editor its so great in my eyes

During Last ten years I have lost interest in programming with Powerbasic or freebasic and studied again..

But During Corona time and more time for Family by Home Office working I was starting again with programming

I Like this Forum very and the Help you can get Here is fast and helpful

Nice sunday, Frank
Lothar Schirm
Posts: 438
Joined: Sep 28, 2013 15:08
Location: Germany

Re: Gui calculator

Post by Lothar Schirm »

I wonder while you use the ES_NUMBER style in your edit boxes. By this way you cannot use decimals (e.g. 123.567), only integers.
RNBW
Posts: 267
Joined: Apr 11, 2015 11:06
Location: UK

Re: Gui calculator

Post by RNBW »

Lothar Schirm wrote: Mar 18, 2024 15:00 I wonder while you use the ES_NUMBER style in your edit boxes. By this way you cannot use decimals (e.g. 123.567), only integers.
As Lothar says ES_NUMBER does not permit the entry of decimals. You may like to look at this code below that will allow the entry of decimals into an Editbox.

Code: Select all

'=============================================
'  NUMERIC INPUT IN AN EDITBOX
'  File Name: NumericEntryIntoAnEditbox_WinGUI_2.bas
'  -------------------
'  This does a check for 0-9 and - or . and prevents entry of all other
'  characters.   It ensures that "-" can only be placed at the start of
'  the number entry.  It also ensures that only one "." or "-"   can be
'  entered.
'  It also ensures that if .123 is entered it displays 0.123 and if
'  -.123 is entered -0.123 is displayed.
'  It also allows the programmer to restrict the number of characters
'  to be entered (including "-" and "."
'  Code by RNBW. 
'============================================

#Include "WinGUI.bi"

Dim As HWND Window_Main, Button_Ok, Edit_1
Dim As MSG msg
dim As String txt, oldtxt
Dim As Integer pos0   


Function num(ByVal txt As String) As String
	'Function to check that character input is 0-9, - or .
	'The number of characters that can be entered will depend
	'on the width of the Editbox and the size of the font.
	'The Programmer is to check this and enter the maximum number
	'of characters in the variable numChars
	
	Dim As String num1
	Dim As Integer i, a, t, maxNumChars
	
' enter the maximum number of characters to be entered and displayed
' in the Editbox.
' This will be dependent on the size of the Editbox and the size of font.
' The programmer will have to calculate this.  I do it by simply typing in
' characters in the Editbox and counting them when it is full and not
' scrolling horizontally	
	maxNumChars	= 12	
	For i = 1 To maxNumChars	
		a = Asc(Mid(txt,i,1))
		if a = 46 then t = t + 1
		if (a = 46) and (t > 1) then a = 0    'only DOT after FIRST is cleared
		if a = 45 and i>1 then a = 0          'so really almost anything do, not just 8
		if a = 46 and i = 1 then num1 = "0" + num1
		If a = 45 Or a = 46 or a > 47 and a < 58 then num1 = num1 + Chr(a)
	Next
	
	a=asc(mid(txt,1,1))
	if a = 45 and mid(txt,2,1) = "." then num1 = "-0" + num1
	
	Return num1
	
End Function


'Create a window with an Editbox:
Window_Main = Window_New   (100, 100, 400, 150, "Numeric Entry Filter!")
Var Label_txt = Label_New  (10, 10, 150, 20, "Enter numbers:",, Window_Main)
Edit_1 = EditBox_New       (150, 10, 100, 20, "", ES_RIGHT, Window_Main)

'Set timer to 300 miliseconds: increasingit is not eligible. this value shows the character entered 
'and then removed if it is not eligible.
SetTimer(Window_Main, 0, 300, 0 )

Do
	WaitEvent(Window_Main,msg)
	Select Case msg.message
		Case WM_TIMER
			'Check contents of the edit box every 300 millisecinds
			txt = EditBox_GetText(Edit_1)   'get text from edit box
			oldtxt = txt      'make text the oldtext
			txt = num(txt)  'gets new text from function num(txt) which does the checking
			If oldtxt <> txt Then
				EditBox_SetText(Edit_1, txt)   'if old text is not the same as the new text then use new text
				pos0 = Len(txt)   'position of character is the length of the current text
				SendMessage(Edit_1, EM_SETSEL, pos0, pos0)
			End If
		Case WM_LBUTTONDOWN
			If msg.hwnd = Button_Ok Then Print EditBox_GetText(Edit_1)  'print text to console
	End Select
Loop Until Window_Event_Close(Window_Main, msg)

End
This uses Lothar Schirm's Simple GUI Library WinGUI (not the modified version) although it would be wise to investigate the modified version.
Lothar Schirm
Posts: 438
Joined: Sep 28, 2013 15:08
Location: Germany

Re: Gui calculator

Post by Lothar Schirm »

Hi RNBW, a small mistake: Button_Ok is not created in the window, so message WM_LBUTTONDOWN will not work as expected. :o
This is the code modified for WinLib.bi (the modified version of WinGUI.bi):

Code: Select all

'
=============================================
'  NUMERIC INPUT IN A TEXTBOX 
'  File Name: NumericEntry.bas
'  -------------------
'  This does a check for 0-9 and - or . and prevents entry of all other
'  characters.   It ensures that "-" can only be placed at the start of
'  the number entry.  It also ensures that only one "." or "-"   can be
'  entered.
'  It also ensures that if .123 is entered it displays 0.123 and if
'  -.123 is entered -0.123 is displayed.
'  It also allows the programmer to restrict the number of characters
'  to be entered (including "-" and "."
'  Code by RNBW - modified for WinLib.bi by Lothar Schirm. 
'============================================

#Include "WinLib.bi"

Dim Shared As HWND Window_Main, Button_Ok, Text_1

Function num(ByVal txt As String) As String
	'Function to check that character input is 0-9, - or .
	'The number of characters that can be entered will depend
	'on the width of the Textbox and the size of the font.
	'The Programmer is to check this and enter the maximum number
	'of characters in the variable numChars
	
	Dim As String num1
	Dim As Integer i, a, t, maxNumChars
	
' enter the maximum number of characters to be entered and displayed
' in the Textbox.
' This will be dependent on the size of the Textbox and the size of font.
' The programmer will have to calculate this.  I do it by simply typing in
' characters in the Textbox and counting them when it is full and not
' scrolling horizontally	
	maxNumChars	= 12	
	For i = 1 To maxNumChars	
		a = Asc(Mid(txt,i,1))
		if a = 46 then t = t + 1
		if (a = 46) and (t > 1) then a = 0    'only DOT after FIRST is cleared
		if a = 45 and i>1 then a = 0          'so really almost anything do, not just 8
		if a = 46 and i = 1 then num1 = "0" + num1
		If a = 45 Or a = 46 or a > 47 and a < 58 then num1 = num1 + Chr(a)
	Next
	
	a=asc(mid(txt,1,1))
	if a = 45 and mid(txt,2,1) = "." then num1 = "-0" + num1
	
	Return num1
	
End Function


Function WndProc(ByVal hWnd As HWND, ByVal message As UINT, ByVal wParam As WPARAM, _
                 ByVal lParam As LPARAM ) As LRESULT
  
  dim As String txt, oldtxt
	Dim As Integer pos0
  
	Select Case message
	
		Case WM_CREATE
		            
			'Create a textbox and a button:
			Var Label_txt = Label_New (10, 10, 150, 20, "Enter numbers:",, hWnd)
			Text_1 = TextBox_New       	(150, 10, 100, 20, "", ES_RIGHT, hWnd)
			Button_Ok = Button_New		(150, 40, 100, 20, "Ok",, hWnd)
			
			'Set timer to 300 miliseconds: increasingit is not eligible. this value shows the character entered 
			'and then removed if it is not eligible.
			SetTimer(hWnd, 0, 300, 0 )
			
		Case WM_TIMER
		
			'Check contents of the textbox every 300 millisecinds
			txt = TextBox_GetText(text_1)   'get text from edit box
			oldtxt = txt      'make text the oldtext
			txt = num(txt)  'gets new text from function num(txt) which does the checking
			If oldtxt <> txt Then
				TextBox_SetText(Text_1, txt)   'if old text is not the same as the new text then use new text
				pos0 = Len(txt)   'position of character is the length of the current text
				SendMessage(Text_1, EM_SETSEL, pos0, pos0)
			End If
			
		Case WM_COMMAND
		
			Select Case lParam
				Case Button_Ok
					Print TextBox_GetText(Text_1)  'print text to console
			End Select
					
		Case WM_DESTROY
			PostQuitMessage(0)
			Exit Function
			
	End Select
	
	Return DefWindowProc(hWnd, message, wParam, lParam)    
    
End Function


'Register the window class, create a window and run the program:
RegisterWindowClass("WindowClass", @WndProc)
Window_Main = Window_New("WindowClass", 100, 100, 400, 150, "Numeric Entry Filter!")
RunMessageLoop()

End
RNBW
Posts: 267
Joined: Apr 11, 2015 11:06
Location: UK

Re: Gui calculator

Post by RNBW »

Hi Lothar
Hope you are keeping well.
Thanks for pointing out my error. It's a bit of copy and paste from another program that had Button_OK in it. In this program it's not needed so all reference to it can and should be deleted.

Thank you for producing the program in your modified version of your Simple GUI Library using WinLib.bi. I really must get round to using your template. I've had my hands pretty full elsewhere for the last year, but your template looks pretty good to me and gives an easy way in to Windows GUI Programming.

All the very best
Ray
Lothar Schirm
Posts: 438
Joined: Sep 28, 2013 15:08
Location: Germany

Re: Gui calculator

Post by Lothar Schirm »

Hi Ray,

thank you very much for your interest. "WinLib" has been downloaded more than 160 times now, but meanwhile I prefer to write small GUI programs directly by using pure Windows API. I use some templates for creating a window and all basic controls which can be modified easily. Especially in Function WinMain the code for registering the window class and the message loop remains unchanged, only the parameters for the main window have to be modified. Otherwise I am afraid I will loose what I have learnt about Windows API up to now.

Some years ago, I used FireFly. What do you think about WinFBE? For me it seems to be quite different.

Best regards
Lothar
Löwenherz
Posts: 46
Joined: Aug 27, 2008 6:26
Location: Bad Sooden-Allendorf, Germany

Re: Gui calculator

Post by Löwenherz »

Hello thanks for Feedback, delete simple ES_NUMBER of edit Boxen, add more
Thanks, Frank

Replace These two lines and 123.4567 Input must Go

Code: Select all

Case WM_CREATE
            ' Create edit boxes for numbers 'no ES_NUMBER OR
            CreateWindowEx(0, "EDIT", "", WS_CHILD Or WS_VISIBLE Or WS_BORDER Or ES_MULTILINE Or ES_AUTOHSCROLL, 50, 50, 100, 20, hWnd, IDC_NUM1, GetModuleHandle(Null), ByVal Null)
            CreateWindowEx(0, "EDIT", "", WS_CHILD Or WS_VISIBLE Or WS_BORDER Or ES_MULTILINE Or ES_AUTOHSCROLL, 200, 50, 100, 20, hWnd, IDC_NUM2, GetModuleHandle(Null), ByVal Null)
        
        
RNBW
Posts: 267
Joined: Apr 11, 2015 11:06
Location: UK

Re: Gui calculator

Post by RNBW »

11I
Lothar Schirm wrote: Mar 22, 2024 15:47 Hi Ray,

thank you very much for your interest. "WinLib" has been downloaded more than 160 times now, but meanwhile ......
......
......

Some years ago, I used FireFly. What do you think about WinFBE? For me it seems to be quite different.

Best regards
Lothar
Hi Lothar
I tried WinFBE some time ago and I found it hard to get my head around. For GUI programming I use your Simple WinGUI (I'll get round to using your modified version when I can find time) for rough and ready programming to make sure something works, then I use VANYA's Windows 9 library. Reminder to me: I must start using your modified library, it will save a lot of work!

All the best
Ray.
Lothar Schirm
Posts: 438
Joined: Sep 28, 2013 15:08
Location: Germany

Re: Gui calculator

Post by Lothar Schirm »

RNBW wrote: Mar 23, 2024 13:47
I tried WinFBE some time ago and I found it hard to get my head around.
That's what I am feeling too.
PaulSquires
Posts: 1002
Joined: Jul 14, 2005 23:41

Re: Gui calculator

Post by PaulSquires »

Maybe I should have stuck with using pure WinAPI functionality like I did with FireFly, however, I found that many users of FireFly did not understand (or did not want to do the work to understand) the WinAPI. So for WinFBE, I tried to make more of a object type of implementation similar to the old style Visual Basic stuff which has proven to be just "okay". The abstraction is not what I enjoy but I thought that it would be better for users new to Windows programming.
cavelamb
Posts: 52
Joined: Jan 04, 2010 9:03
Location: earth

Re: Gui calculator

Post by cavelamb »

Could someone post a full version of this calculator, please?
I think it would be a great learning tool.

Richard
Post Reply