Announcement

Collapse
No announcement yet.

One Superclass fails but others work

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Chris Holbrook
    replied
    Originally posted by Edwin Knoppert View Post
    Are we 'hobby' or what?
    be nice now...

    Originally posted by Edwin Knoppert View Post
    Think logical please..
    I try, with a modicum of success...
    Originally posted by Edwin Knoppert View Post
    A windowprocedure is determined for a specific class.

    So if you have another class using the same wp, how can you make a difference?
    ...You probably know what you mean, but hang me if I do.
    .

    Leave a comment:


  • Edwin Knoppert
    replied
    Imo if you want to do it right, use WM_NOTIFY with custom NMHDR structure.
    It does not conflict with Windows unless you superclass a common control (like treeview and such)
    A common control is not a 'standard' control.
    The EDIT control is a 'standard' control.

    Leave a comment:


  • Michael Mattias
    replied
    > just create unique messages like %MYMESSAGE = 10000

    Um, I think you should make private messages based on %WM_USER. There's a whole numeric range reserved for application-specific messages.

    But if you want UNIQUE and cross-process, see RegisterWindowMessage() function.

    Leave a comment:


  • BOB MECHLER
    replied
    I've done that kind of thing before with subclasses I think. And if I need to change a property, just reissue the same command with new values.

    Thanks,

    Bob Mechler

    Leave a comment:


  • Edwin Knoppert
    replied
    It's like a listbox, it's lb_.. messages, just create unique messages like
    %MYMESSAGE = 10000

    SendMessage( hWndCtrl, %MYMESSAGE, wparam data here, lparam data here )

    This way you can set properties by capturing this message inside the custom wp.

    Leave a comment:


  • BOB MECHLER
    replied
    Thanks for your answer Edwin. The code is hard to read, that's why I left it alone! Need to study what's been said and really understand the code before I change it. Your explanation goes a long way toward that. I'll try the global Dword advice and not use the extrabytes as you suggested.

    Now the good news. SetProp and GetProp work great. The only real problem I had was passing data for FieldLen and FieldDec and was using CONTROL SET USER and/OR SetWindowLong. Neither of those worked but SetProp and GetProp did. They are a lot friendlier.

    Bob Mechler

    Leave a comment:


  • Edwin Knoppert
    replied
    Originally posted by Chris Holbrook View Post
    Why not?
    Are we 'hobby' or what?

    Think logical please..
    A windowprocedure is determined for a specific class.
    So if you have another class using the same wp, how can you make a difference?

    Bob, it's fairly simple.
    The GetClassInfoEx() obtains the class details of an existing class.
    The content of the structure received is what you will reuse to register a new class for.
    But.. with a slight change.. you want to add functionality to existing class behaviour therefore an alternative windowprocedure is required.

    Since you divert the orginal messages behaviour from Windows to your new windowprocedure, it will first pass your windows procedure, then you should pass the messages on to the original wp so a button or edit class etc can do his own job.
    Unless you wish to capture specific messages.
    It's similar to a hook.

    Since the class is known to the instance (not process per se) you can use a global dword to hold the previous windowproc.
    The example you are using makes it harder to read, it's not wrong per se but in fact you have used code harder to read and understand..
    Forget (remove) the call with hWnd = 0 stuff and use a global.

    Go back to the basics by obtaining the class info and reregister under a different name and procedure (nothing more).
    That's the basic use of a superclass.

    From experiance i know that you shouldn't mess with the extrabytes.
    These are also nonsense shortcuts to append extra data to a control.
    Like i said, use SetProp() API since it is much more friendly to use, since it can create an named atom instead of odd numbers and such.

    Leave a comment:


  • Chris Holbrook
    replied
    Originally posted by Michael Mattias;292602...no way in hell I would even think about trying to use DIALOG/CONTROL SET USER [b
    and[/b] Get/SetWindowLong on the same window/control. Sure, it might work but I really believe that would be tempting fate bigtime.
    If you wnated to take the CONTROL ?ET ... out of the loop, substitute get/setprop, don't forget to removeprop when you have finished with them. Or use the xtrabytes.

    Leave a comment:


  • Chris Holbrook
    replied
    Originally posted by Edwin Knoppert View Post
    You should never share a windowproc for different classes!
    Why not?

    Leave a comment:


  • BOB MECHLER
    replied
    I've worked with the production code and the example all morning. The example code using the same include files for creating the number entry superclass, the button superclass to call the calculator and the windows procedure for it have not failed once.

    However the same includes in the production code has worked and not worked at least three times.

    I tried changing CONTROL SET USER to SetWindowLong and did not have any different results.

    I think the CreateSuperClass procedure and template for it need to be changed. Is there another example of creating superclasses I can use that anyone knows of where I can make as many SuperClassed controls as I want or am I looking at making this one a subclass requiring deletion in the WM_DESTROY event.

    The only other difference that was odd was that in my production code I create calculated control ids and in my example code I use literal numbers.

    In the production code I use the array element + an offset which is based on the total number of controls the screen will have + 2000.

    When I use VI + V_OS& as the control id, it's value is 2032 as I'm creating the control but in the Superclassed Windows procedure GetDlgCtrlID(CBHNDL) returns 6 which is the value of VI.

    If I calculate V_CTRLID& = VI + V_OS& first and use V_CTRLID& as the id for creating the SuperClass the value returned in the SuperClassWindows Procedure is 2032. Strange. GetDlgCtrlID(CBHNDL) is supposed to return the control id the control was created with but depending on whether I use VI + V_OS& OR V_CTRLID& it returns a different value.

    When it doesn't return the correct id in the SuperClassed Windows procedure and I do a Control Get User with that wrong ID I get 0 instead of the FieldLen and the FieldDec.

    That's where I am at the moment.

    I think there is something fundamentally wrong with the CreateSuperClass procedure and the example windows procedure that I started with.

    It really shouldn't be this hard to add features to a standard windows control.

    Bob Mechler

    Leave a comment:


  • BOB MECHLER
    replied
    Here is a compilable example of the superclassed number entry.

    Main program code
    Code:
    #DIM NONE
    DEFINT A-Z
    #INCLUDE "WIN32API.INC"
    #INCLUDE "COMMCTRL.INC"
    #INCLUDE "SUPCALC.INC"
    #INCLUDE "SUPNUM.INC"
    
        FUNCTION CreateSuperClass(OldClassName AS STRING, NewClassName AS STRING, lpfnNewWndProc AS LONG, cbWndExtra AS LONG) AS LONG
           LOCAL wc AS WNDCLASSEX
           wc.cbSize = SIZEOF(wc)
           IF GetClassInfoEx(BYVAL 0&, BYVAL STRPTR(OldClassName), wc) THEN
              CallWindowProc lpfnNewWndProc, 0, 0, wc.lpfnWndProc, wc.cbWndExtra
              wc.hInstance = GetModuleHandle(BYVAL 0&)
              wc.lpszClassName = STRPTR(NewClassName)
              wc.lpfnWndProc = lpfnNewWndProc
              wc.cbWndExtra = wc.cbWndExtra + cbWndExtra
              FUNCTION = RegisterClassEx(wc)
           END IF
        END FUNCTION
    
        FUNCTION PBMAIN
          IF ISFALSE(CreateSuperClass("EDIT", "NEditNumber", CODEPTR(NEditNumberProc), 4)) THEN EXIT FUNCTION
          IF ISFALSE(CreateSuperClass("BUTTON", "NNumCalcButton", CODEPTR(NNumCalcButtonProc), 4)) THEN EXIT FUNCTION
    
          DIALOG NEW 0, "Test SUPNUM", 80 ,80 ,300, 200, %WS_CAPTION OR %WS_SYSMENU OR %WS_MAXIMIZEBOX TO hdlg&     
          
            CONTROL ADD LABEL, hdlg&,-1,"2 digit number",5,25,50,12
    
            CtrlClassName$ = "NNumCalcButton"                                      'superclassed name
    
            CONTROL ADD CtrlClassName$, hdlg&,1001, "?",68, 25, 11, 12, %WS_CHILD OR %WS_VISIBLE OR %BS_CENTER OR %BS_VCENTER,%WS_EX_LEFT OR %WS_EX_LTRREADING                   
    
            CONTROL SET USER hdlg&, 1001,1,11     'FieldLen
            CONTROL SET USER hdlg&, 1001,2,2      'FieldDec
    
            CONTROL ADD LABEL, hdlg&,-1,"4 digit number", 5,50,50,12
    
            CtrlClassName$ = "NEditNumber"                                          'superclassed name
    
            CONTROL ADD CtrlClassName$, hdlg&,1002, "",80,24,66,12, %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %ES_RIGHT, %WS_EX_LEFT OR %WS_EX_CLIENTEDGE   
    
            CONTROL SET USER hdlg&, 1002,1,11     'FieldLen
            CONTROL SET USER hdlg&, 1002,2,2      'FieldDec
            CONTROL SEND hdlg&,1002,%EM_LIMITTEXT,11,0 
          
            CtrlClassName$ = "NNumCalcButton"                                      'superclassed name
    
            CONTROL ADD CtrlClassName$, hdlg&,1003, "?",68, 49, 11, 12, %WS_CHILD OR %WS_VISIBLE OR %BS_CENTER OR %BS_VCENTER,%WS_EX_LEFT OR %WS_EX_LTRREADING                   
    
            CONTROL SET USER hdlg&, 1003,1,11     'FieldLen
            CONTROL SET USER hdlg&, 1003,2,4      'FieldDec
    
            CtrlClassName$ = "NEditNumber"                                          'superclassed name
    
            CONTROL ADD CtrlClassName$, hdlg&,1004, "",80,48,66,12, %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %ES_RIGHT, %WS_EX_LEFT OR %WS_EX_CLIENTEDGE   
          
            CONTROL SET USER hdlg&, 1004,1,11     'FieldLen
            CONTROL SET USER hdlg&, 1004,2,4      'FieldDec            
            CONTROL SEND hdlg&,1004,%EM_LIMITTEXT,11,0
    
            CONTROL ADD LABEL, hdlg&,-1,"Up,Down,Tab,Shift Tab,Enter all move between fields. " + $CRLF + _
            "The first field is limited to two decimal places and the second to 4 digits. " + $CRLF + _
            "The button will pull up a calculator and pressing ESC will put the value into the field " + $CRLF + _
            "and move to the next field. Insert and Overwrite mode don't work yet" + $CRLF + _
            "The precision the calculator is in will be what is returned, working on forcing the " + $CRLF + _
            "calculator to show the precision of the field" + $CRLF + _
            "The calculator was originated by Herman Kieskamp. I added keyboard accelerators and " + $CRLF + _
            "made it a function. Still needs some cleanup" + $CRLF + _
            "The CreateSuperClass function and the original template for the" + $CRLF + _
            "windows procedure was modeled after Semen's forum code" + $CRLF + _
            " " + $CRLF + _
            "The problem is that sometimes the Set User doesn't store a value and the control " + $CRLF + _
            "acts like it has no value for the decimal. " + $CRLF + _
            "This control using the same includes however seems to work just fine ",5,80,400,120
    
          DIALOG SHOW MODAL hdlg&  
    
        END FUNCTION
    My routine based on Semen's template SuperClass windows procedure
    SUPNUM.INC
    Code:
       CALLBACK FUNCTION NEditNumberProc
          STATIC OldProc AS LONG, OffsetWndExtra AS LONG
          LOCAL FieldL AS LONG,FieldD AS LONG,V_INSOVR AS LONG 
          LOCAL V_NKEYPOS AS LONG,sTXT AS STRING,Txt AS ASCIIZ * %MAX_PATH, zfName AS ASCIIZ * %MAX_PATH
          LOCAL ValidNumKeys AS STRING,FieldId as LONG
          LOCAL NumID AS LONG,V_DECPT AS LONG, V_TXTLEN AS LONG,Value AS DOUBLE
          DIM  Tlen AS LOCAL LONG
          IF CBHNDL = 0 THEN OldProc = CBWPARAM: OffsetWndExtra = CBLPARAM: EXIT FUNCTION
          ValidNumKeys$ = "-.0123456789" + CHR$(8)
          ValidNumKeysAbbrev$ = "[.-0-9]"
    
          'Control Id and Handle of Num
          NumID& = getdlgctrlid(CBHNDL)
          CONTROL GET USER GetParent(CBHNDL),NumID&,1 TO FieldL
          CONTROL GET USER GetParent(CBHNDL),NumID&,2 TO FieldD
          
          SELECT CASE CBMSG
           CASE %WM_GETDLGCODE
              FUNCTION = %DLGC_WANTALLKEYS: EXIT FUNCTION
           CASE %WM_KEYUP
             CONTROL SEND GetParent(CBHNDL),NumID&, %EM_GETSEL, 0, 0 TO V_NKEYPOS&     'Used to detect when field is filled           
             IF LOWRD(V_NKEYPOS&) = FieldL THEN
               SetFocus GetNextDlgTabItem(GetParent(CBHNDL), CBHNDL, 0) 'all ok, move to the next field
               EXIT FUNCTION
             END IF
           CASE %WM_KEYDOWN
             SELECT CASE CBWPARAM
               CASE %VK_UP,%VK_DOWN,%VK_RETURN,%VK_TAB  
                 IF CBWPARAM = %VK_UP OR (CBWPARAM = %VK_TAB AND GetAsyncKeyState(%VK_SHIFT)) THEN  
                   SetFocus GetNextDlgTabItem(GetParent(CBHNDL), CBHNDL, -1)
                 ELSE
                   SetFocus GetNextDlgTabItem(GetParent(CBHNDL), CBHNDL, 0)
                 END IF  
                 EXIT FUNCTION
               CASE %VK_INSERT
                 IF NOT V_INSOVR THEN
                   V_INSOVR = -1
                 SetWindowText GetParent(CBHNDL),"OVR"   
                 ELSEIF V_INSOVR THEN
                   V_INSOVR = 0
                 SetWindowText GetParent(CBHNDL),"INS"   
                 END IF
             END SELECT
           CASE %WM_CHAR
             GetWindowText CBHNDL, Txt, %MAX_PATH                                                            
             sTxt = TRIM$(Txt)
             IF INSTR(ValidNumKeys$,CHR$(CBWPARAM)) = 0 THEN EXIT FUNCTION
             KeyState = GetAsyncKeyState(%VK_OEM_MINUS) OR GetAsyncKeyState(%VK_OEM_PLUS)
             'IF INSTR("+-",CHR$(CBWPARAM)) > 0 AND KeyState <> &H8001 THEN EXIT FUNCTION
             IF CBWPARAM = %VK_RETURN THEN EXIT FUNCTION
             IF CBWPARAM = %VK_TAB THEN EXIT FUNCTION
             IF LEN(sTxt) > 0 AND INSTR(sTxt,"-") AND CHR$(CBWPARAM) = "-" THEN EXIT FUNCTION
             IF LEN(sTxt) > 0 AND INSTR(sTxt,"-") = 0 AND CHR$(CBWPARAM) = "-" THEN EXIT FUNCTION
             IF INSTR(sTxt,".") > 0 AND CHR$(CBWPARAM) = "." THEN EXIT FUNCTION 'allow only one decimal point
             IF CHR$(CBWPARAM) = "." AND FieldD = 0 THEN EXIT FUNCTION 'whole numbers only
             IF V_INSOVR THEN
               SendMessage CBHNDL, %EM_GETSEL, 0, 0 TO V_NKEYPOS&     'Used to detect when field is filled           
               V_NKEYPOS& = LOWRD(V_NKEYPOS&)
               SendMessage CBHNDL, %EM_SETSEL,V_NKEYPOS&,V_NKEYPOS& + 1  'Selects current character
               SendMessage CBHNDL, %WM_CLEAR,0,0                       'If nothing to clear doesn't act
             END IF                               
             GetWindowText CBHNDL,Txt,%MAX_PATH
             sTxt = TRIM$(Txt)
             IF LEN(sTxt) - INSTR(-1,sTxt,".") = FieldD - 1 AND INSTR(sTxt,".") > 0 AND CBWPARAM <> 8 THEN
               sTxt = sTxt + CHR$(CBWPARAM)
               SetWindowText CBHNDL, BYCOPY sTxt
               SetFocus GetNextDlgTabItem(GetParent(CBHNDL), CBHNDL, 0)           
               EXIT FUNCTION
             END IF
           CASE %WM_SETFOCUS
              GetWindowText CBHNDL, Txt, %MAX_PATH
              Txt = REMOVE$(Txt,",")
              IF VAL(Txt) = 0 THEN
                Txt = ""
              END IF
              SetWindowText CBHNDL, Txt
              SendMessage CBHNDL, %EM_SETSEL, 0, -1
              Value# = 0
           CASE %WM_KILLFOCUS 
             GetWindowText CBHNDL, Txt, %MAX_PATH 
             sTxt = TRIM$(Txt)
             IF FieldD > 0 THEN
               sTxt   = FORMAT$(Val(sTxt), "0,." + STRING$(FieldD,"0"))
             ELSE  
               STxt   = FORMAT$(VAL(sTxt),"0")
             END IF  
             SetWindowText CBHNDL, BYCOPY sTxt   
          END SELECT
          FUNCTION = CallWindowProc(OldProc, CBHNDL, CBMSG, CBWPARAM, CBLPARAM) 
             
       END FUNCTION
    
       CALLBACK FUNCTION NNumCalcButtonProc
          STATIC OldProc AS LONG, OffsetWndExtra AS LONG,FieldL AS LONG,FieldD AS LONG
          LOCAL Txt AS ASCIIZ * %MAX_PATH, sTxt AS STRING,ij AS LONG, MDigit AS STRING
          LOCAL NumButtonID AS LONG, NumID AS LONG,sx&,sy&,sxx&,syy&,tRect as RECT        
          IF CBHNDL = 0 THEN OldProc = CBWPARAM: OffsetWndExtra = CBLPARAM: EXIT FUNCTION
          SELECT CASE CBMSG
            CASE %WM_LBUTTONDOWN
              NumButtonID& = getdlgctrlid(CBHNDL)
              NumID& = NumButtonID& - (scr_NUM_FLD# * 2 ) 
              NumHandle& = GetDlgItem(GetParent(CBHNDL),NumID&)
              CONTROL GET USER GetParent(CBHNDL),NumButtonID&,1 TO FieldL
              CONTROL GET USER GetParent(CBHNDL),NumButtonID&,2 TO FieldD
              CONTROL GET LOC GetParent(CBHNDL),NumButtonID& to sx&,sy&                   
              sTxt = CalcIt(BYVAL GetParent(CBHNDL),BYVAL sx& + 75,BYVAL sy&,BYVAL "0")
              sTxt = REMOVE$(sTxt,",")
              SetFocus NumHandle& 
              IF FieldD > 0 THEN
                sTxt   = FORMAT$(Val(sTxt), "0." + STRING$(FieldD,"0"))
              ELSE  
                STxt   = FORMAT$(VAL(sTxt),"0")
              END IF
              sTxt = TRIM$(sTxt)
              IF LEN(sTxt) > 0 THEN
               For iCounter& = 1 To Len(sTxt)
                  iRet& = VkKeyScan(Asc(sTxt,iCounter&))
                  If (LoByt(iRet&) = -1) And (HiByt(iRet&) = -1) Then Iterate For 'cant do this char so skip
                  iVKcode% = LoByt(iRet&)
                  iTempShifted& = HiByt(iRet&)
                  If (iTempShifted& And 1) Then keybd_event %VK_SHIFT, MapVirtualKey(%VK_SHIFT, 0), 0, 0: Sleep 0     'hold down shift
                  If (iTempShifted& And 2) Then keybd_event %VK_CONTROL, MapVirtualKey(%VK_CONTROL, 0), 0, 0: Sleep 0 'hold down control
                  If (iTempShifted& And 4) Then keybd_event %VK_MENU, MapVirtualKey(%VK_MENU, 0), 0, 0: Sleep 0      'hold down alt
                  keybd_event iVKcode%, MapVirtualKey(iVKcode%, 0), 0, 0: Sleep 0                'key_down msg
                  keybd_event iVKcode%, MapVirtualKey(iVKcode%, 0), %KEYEVENTF_KEYUP, 0: Sleep 0 'key_up msg
                  If (iTempShifted& And 1) Then keybd_event %VK_SHIFT, MapVirtualKey(%VK_SHIFT, 0), %KEYEVENTF_KEYUP, 0: Sleep 0     'key_up msg
                  If (iTempShifted& And 2) Then keybd_event %VK_CONTROL, MapVirtualKey(%VK_CONTROL, 0), %KEYEVENTF_KEYUP, 0: Sleep 0 'key_up msg
                  If (iTempShifted& And 4) Then keybd_event %VK_MENU, MapVirtualKey(%VK_MENU, 0), %KEYEVENTF_KEYUP, 0: Sleep 0       'key_up msg
               Next iCounter& 
              END IF
              SetFocus GetNextDlgTabItem(GetParent(CBHNDL), CBHNDL, 0)
              SendMessage CBHNDL, %BM_SETSTYLE, %BS_PUSHBUTTON, %TRUE
              EXIT FUNCTION
          END SELECT    
          FUNCTION = CallWindowProc(OldProc, CBHNDL, CBMSG, CBWPARAM, CBLPARAM)
       END FUNCTION
    SUPCALC.INC code

    Code:
    'calc.bas ver 1.0 written by Herman Kieskamp.
    'A free to use simple calculator as dll or executable.
    'This code is put here for improvements, discussion and or use.
    'Please report improvements to the author at mail : [email protected] or on this forum
    'Keep in mind that I'm not a mathematician so error's might be possible, haven't extensively tested it.
    'It seems ok though !
    ' *************************************************************
    '       Code Generated by EZGUI Freeware Dialog Designer
    ' *************************************************************
    
     ' Remark out the Constants for Controls you Will use in your program !
    ' %NOANIMATE    = 1
    ' %NOBUTTON     = 1
     %NOCOMBO      = 1
     %NODRAGLIST   = 1
     %NOHEADER     = 1
     %NOIMAGELIST  = 1
     %NOLIST       = 1
     %NOLISTVIEW   = 1
     %NOSTATUSBAR  = 1
     %NOTABCONTROL = 1
     %NOTOOLBAR    = 1
    ' %NOTOOLTIPS   = 1 'maybe just add some tooltips later, although seems obsolete as anyone knows a basic calculator
     %NOTRACKBAR   = 1
     %NOTREEVIEW   = 1
    ' %NOUPDOWN     = 1
    %compile = 0
    '#INCLUDE "WIN32API.INC"   ' Must come first before other include files !
    '#INCLUDE "COMMCTRL.INC"
    %UDSTYLE = %WS_CHILD OR %WS_VISIBLE  OR %UDS_ARROWKEYS OR %UDS_SETBUDDYINT
    '#INCLUDE "COMMONG.INC"
    '#INCLUDE "GLOBALS2.INC"
    GLOBAL Udresult AS LONG
    GLOBAL pnewpos AS LONG
    ' *************************************************************
    ' *************************************************************
    '              EZGUI Library Constants and Declares
    ' *************************************************************
    DECLARE SUB EZLIB_InitFonts()
    DECLARE SUB EZLIB_DeleteFonts()
    DECLARE SUB EZLIB_FixSize(BYVAL hDlg&, BYVAL Style&, BYVAL HasMenu&)
    DECLARE FUNCTION EZLIB_IsTooltip(BYVAL lParam AS LONG) AS LONG
    DECLARE FUNCTION EZLIB_TooltipID(BYVAL lParam AS LONG) AS LONG
    DECLARE SUB EZLIB_SetTooltipText(BYVAL lParam AS LONG, TipText$)
    DECLARE FUNCTION EZLIB_IsTab(BYVAL lParam AS LONG) AS LONG
    DECLARE FUNCTION EZLIB_TabID(BYVAL lParam AS LONG) AS LONG
    DECLARE FUNCTION EZLIB_TabNum(BYVAL lParam AS LONG) AS LONG
    DECLARE SUB EZLIB_AddTabs(BYVAL hDlg AS LONG, BYVAL IDNum&, BYVAL TabText$)
    DECLARE SUB EZLIB_DefColors()
    DECLARE SUB EZLIB_DeleteBrushes()
    DECLARE FUNCTION EZLIB_QBColor(N&) AS LONG
    DECLARE SUB EZLIB_ShowControl(BYVAL hWnd&, BYVAL ID&, BYVAL SFlag&)
    ' *************************************************************
    '              Application Constants and Declares
    ' *************************************************************
    %FRMCALC_BTN1               = 100
    %FRMCALC_BTN2               = 105
    %FRMCALC_BTN3               = 110
    %FRMCALC_BTN4               = 115
    %FRMCALC_BTN5               = 120
    %FRMCALC_BTN6               = 125
    %FRMCALC_BTN7               = 130
    %FRMCALC_BTN8               = 135
    %FRMCALC_BTN9               = 140
    %FRMCALC_BTN0               = 150
    %FRMCALC_BTNKEER            = 155
    %FRMCALC_BTNDEEL            = 160
    %FRMCALC_BTNPLUS            = 165
    %FRMCALC_BTNMIN             = 170
    %FRMCALC_BTNIS              = 175
    %FRMCALC_BTNPLUSMIN         = 180
    %FRMCALC_BTNC               = 185
    %FRMCALC_BTNCE              = 190
    %FRMCALC_BTNM               = 195
    %FRMCALC_BTNM_2             = 200
    %FRMCALC_BTNMR              = 205
    %FRMCALC_BTNMC              = 210
    %FRMCALC_BTNBACKSPACE       = 215
    %UpDown                     = 216
    %BUDDY1                     = 217
    %BUDDY2                     = 218
    %FRMCALC_BTNEXIT            = 3   'WAS 1
    %FRMCALC_BTNPROCENT         = 220
    %FRMCALC_BTNdecimal         = 225
    %FRMCALC_BTNTAKE            = 230
    %FRMCALC_txtcalc            = 450
    DECLARE SUB ShowDialog_frmcalc(BYVAL hParent&)
    DECLARE CALLBACK FUNCTION frmcalc_DLGPROC
    ' --------------------------------------------------
    ' ------------------------------------------------
    DECLARE CALLBACK FUNCTION CBF_FRMCALC_BTN1()
    DECLARE CALLBACK FUNCTION CBF_FRMCALC_BTN2()
    DECLARE CALLBACK FUNCTION CBF_FRMCALC_BTN3()
    DECLARE CALLBACK FUNCTION CBF_FRMCALC_BTN4()
    DECLARE CALLBACK FUNCTION CBF_FRMCALC_BTN5()
    DECLARE CALLBACK FUNCTION CBF_FRMCALC_BTN6()
    DECLARE CALLBACK FUNCTION CBF_FRMCALC_BTN7()
    DECLARE CALLBACK FUNCTION CBF_FRMCALC_BTN8()
    DECLARE CALLBACK FUNCTION CBF_FRMCALC_BTN9()
    DECLARE CALLBACK FUNCTION CBF_FRMCALC_txtcalc()
    DECLARE CALLBACK FUNCTION CBF_FRMCALC_BTN0()
    DECLARE CALLBACK FUNCTION CBF_FRMCALC_BTNKEER()
    DECLARE CALLBACK FUNCTION CBF_FRMCALC_BTNDEEL()
    DECLARE CALLBACK FUNCTION CBF_FRMCALC_BTNPLUS()
    DECLARE CALLBACK FUNCTION CBF_FRMCALC_BTNMIN()
    DECLARE CALLBACK FUNCTION CBF_FRMCALC_BTNIS()
    DECLARE CALLBACK FUNCTION CBF_FRMCALC_BTNPLUSMIN()
    DECLARE CALLBACK FUNCTION CBF_FRMCALC_BTNC()
    DECLARE CALLBACK FUNCTION CBF_FRMCALC_BTNCE()
    DECLARE CALLBACK FUNCTION CBF_FRMCALC_BTNM()
    DECLARE CALLBACK FUNCTION CBF_FRMCALC_BTNM_2()
    DECLARE CALLBACK FUNCTION CBF_FRMCALC_BTNMR()
    DECLARE CALLBACK FUNCTION CBF_FRMCALC_BTNMC()
    DECLARE CALLBACK FUNCTION CBF_FRMCALC_BTNBACKSPACE()
    DECLARE CALLBACK FUNCTION CBF_FRMCALC_BTNPROCENT()
    DECLARE CALLBACK FUNCTION CBF_FRMCALC_BTNdecimal()
    DECLARE CALLBACK FUNCTION CBF_FRMCALC_BTNEXIT()
    DECLARE CALLBACK FUNCTION CBF_FRMCALC_BTNTAKE()
    
    ' (1) Put NEXT DIALOG Constant and Declare code after here :
    
    ' *************************************************************
    '            Application Global Variables and Types
    ' *************************************************************
    GLOBAL App_Brush&()
    GLOBAL App_Color&()
    GLOBAL App_Font&()
    
    GLOBAL hfrmcalc&    ' Dialog handle
    GLOBAL gtotaldb AS EXTENDED  'holds the calc value
    GLOBAL gmemstr AS STRING   'holds the memstring
    GLOBAL gsignstr AS STRING  'holds the calc type */+-=%
    GLOBAL goldsignstr AS STRING 'holds the 'before used' calc type */+-% when = is used
    GLOBAL gwhatstr AS STRING 'if is 'new' then the textbox will be overwritten when new ciphers are fed.
    GLOBAL gminsign AS LONG 'if 1 then negative, used for substractions
    GLOBAL gx AS LONG 'x position of window
    GLOBAL gy AS LONG 'y position of window
    GLOBAL gexitstr AS STRING 'what to bring back from the function
    GLOBAL winmsgs AS STRING
    GLOBAL iresult&,xx&,yy&
    GLOBAL LBPREC() AS STRING
    GLOBAL nprecision AS STRING
    GLOBAL nformat AS STRING
    
    ' (2) Put NEXT DIALOG Globals code after here :
    
    ' (2) NEXT DIALOG  -  Put Globals after here :
    
    #IF %compile  'when compiled ex
    ' *************************************************************
    '      Application Entrance
    ' *************************************************************
    'used with exe
      FUNCTION WINMAIN (BYVAL hCurInstance  AS LONG, _
                      BYVAL hPrevInstance AS LONG, _
                      lpszCmdLine         AS ASCIIZ PTR, _
                      BYVAL nCmdShow      AS LONG) EXPORT AS LONG
      DIM UDA AS GLOBAL UDACCEL
      DIM ptnmhdr AS GLOBAL NMHDR PTR      ' <-- Needed to implement DM filter
      DIM pnmud AS GLOBAL NM_UPDOWN PTR    ' <-- Needed to track iPos and iDelta
      LOCAL Count&
      LOCAL CC1 AS INIT_COMMON_CONTROLSEX
      CC1.dwSize=SIZEOF(CC1)
      CC1.dwICC=%ICC_WIN95_CLASSES
      InitCommonControlsEX CC1
      EZLIB_DefColors
      EZLIB_InitFonts
      ShowDialog_frmcalc 0
    
      DO
        DIALOG DOEVENTS TO Count&
      LOOP UNTIL Count&=0
    
      EZLIB_DeleteBrushes
      EZLIB_DeleteFonts
    END FUNCTION
    #ELSE
    ' *************************************************************
    '      DLL Entrance
    ' ***********************************************1312**************
    'When compiled DLL
    FUNCTION CALCIT(BYVAL parnthndl AS LONG, BYVAL locx AS LONG, BYVAL locy AS LONG, _
                               BYVAL startvalue AS STRING)  AS STRING
      DIM UDA AS GLOBAL UDACCEL
      DIM ptnmhdr AS GLOBAL NMHDR PTR      ' <-- Needed to implement DM filter
      DIM pnmud AS GLOBAL NM_UPDOWN PTR    ' <-- Needed to track iPos and iDelta
      LOCAL Count&
      LOCAL CC1 AS INIT_COMMON_CONTROLSEX
      CC1.dwSize=SIZEOF(CC1)
      CC1.dwICC=%ICC_WIN95_CLASSES
      InitCommonControlsEX CC1
      EZLIB_DefColors
      EZLIB_InitFonts
      gx&=locx 'pass parameters to globals so they will be visible troughout the app
      gy&=locy
      gtotaldb = 0 'initialize total
      ShowDialog_frmcalc parnthndl 'pass parentshandle to be able to close when parent shuts
        IF gexitstr<>"" AND gexitstr <> "0.00" THEN
        FUNCTION=gexitstr 'take last textbox value to calling parent
      END IF
      EZLIB_DeleteBrushes
      EZLIB_DeleteFonts
    END FUNCTION
    #ENDIF
    ' *************************************************************
    '                    Application Dialogs
    ' *************************************************************
    SUB ShowDialog_frmcalc(BYVAL hParent&)
      DIM LBPREC$(0:7)
      LBPREC$(0) = "0"
      LBPREC$(1) = "1"
      LBPREC$(2) = "2"
      LBPREC$(3) = "3"
      LBPREC$(4) = "4"
      LBPREC$(5) = "5"
      LBPREC$(6) = "6"
      LBPREC$(7) = "Float"
      LOCAL UDChoice AS LONG
      LOCAL Style&, ExStyle&
      '   hParent& = 0 if no parent Dialog
      'Style& = %WS_POPUP OR %WS_CLIPCHILDREN OR %WS_CLIPSIBLINGS OR %WS_BORDER OR %DS_MODALFRAME
      Style& = %WS_SYSMENU OR %WS_CLIPSIBLINGS OR %WS_CLIPCHILDREN
      ExStyle& = %WS_EX_TOOLWINDOW OR %WS_EX_TOPMOST                       'BM set topmost
      DIALOG NEW hParent&, "Calculator", gx&, gy&,  121,  140, Style&, ExStyle& TO hfrmcalc&
      'EZLIB_FixSize hfrmcalc&, Style&, 0
      'MAC_WINPOS(hfrmcalc&)
      ' Layer # 0
      CONTROL ADD "Button", hfrmcalc&,  %FRMCALC_BTN1,  "1", 5, 50, 15, 15, _
       %WS_CHILD OR %BS_NOTIFY OR %WS_VISIBLE OR %BS_PUSHBUTTON CALL CBF_FRMCALC_BTN1
      CONTROL ADD "Button", hfrmcalc&,  %FRMCALC_BTN2,  "2", 20, 50, 15, 15, _
       %WS_CHILD OR %BS_NOTIFY OR %WS_VISIBLE OR %BS_PUSHBUTTON CALL CBF_FRMCALC_BTN2
      CONTROL ADD "Button", hfrmcalc&,  %FRMCALC_BTN3,  "3", 35, 50, 15, 15, _
       %WS_CHILD OR %BS_NOTIFY OR %WS_VISIBLE OR %BS_PUSHBUTTON CALL CBF_FRMCALC_BTN3
      CONTROL ADD "Button", hfrmcalc&,  %FRMCALC_BTN4,  "4", 5, 35, 15, 15, _
       %WS_CHILD OR %BS_NOTIFY OR %WS_VISIBLE OR %BS_PUSHBUTTON CALL CBF_FRMCALC_BTN4
      CONTROL ADD "Button", hfrmcalc&,  %FRMCALC_BTN5,  "5", 20, 35, 15, 15, _
       %WS_CHILD OR %BS_NOTIFY OR %WS_VISIBLE OR %BS_PUSHBUTTON CALL CBF_FRMCALC_BTN5
      CONTROL ADD "Button", hfrmcalc&,  %FRMCALC_BTN6,  "6", 35, 35, 15, 15, _
       %WS_CHILD OR %BS_NOTIFY OR %WS_VISIBLE OR %BS_PUSHBUTTON  CALL CBF_FRMCALC_BTN6
      CONTROL ADD "Button", hfrmcalc&,  %FRMCALC_BTN7,  "7", 5, 20, 15, 15, _
       %WS_CHILD OR %BS_NOTIFY OR %WS_VISIBLE OR %BS_PUSHBUTTON CALL CBF_FRMCALC_BTN7
      CONTROL ADD "Button", hfrmcalc&,  %FRMCALC_BTN8,  "8", 20, 20, 15, 15, _
       %WS_CHILD OR %BS_NOTIFY OR %WS_VISIBLE OR %BS_PUSHBUTTON CALL CBF_FRMCALC_BTN8
      CONTROL ADD "Button", hfrmcalc&,  %FRMCALC_BTN9,  "9", 35, 20, 15, 15, _
       %WS_CHILD OR %BS_NOTIFY OR %WS_VISIBLE OR %BS_PUSHBUTTON CALL CBF_FRMCALC_BTN9
      ' - - - - - - - - - - - - - - - - - - - - - - - - -
      ' - - - - - - - - - - - - - - - - - - - - - - - - -
      CONTROL ADD TEXTBOX, hfrmcalc&,  %FRMCALC_txtcalc, "0.00", 5, 3, 109, 12, _
       %WS_CHILD OR %BS_NOTIFY OR %WS_VISIBLE OR %WS_BORDER OR %ES_RIGHT, %WS_EX_CLIENTEDGE,  CALL CBF_FRMCALC_txtcalc
      CONTROL ADD "Button", hfrmcalc&,  %FRMCALC_BTN0,  "0", 5, 65, 30, 15, _
       %WS_CHILD OR %BS_NOTIFY OR %WS_VISIBLE OR %BS_PUSHBUTTON CALL CBF_FRMCALC_BTN0
      CONTROL ADD "msctls_updown32",hfrmcalc&,%UpDown, "",30, 88, 0, 12,%UDSTYLE,%WS_EX_STATICEDGE
      CONTROL ADD TEXTBOX,hfrmcalc&,%buddy1,"2",5,88,25,12
      CONTROL SHOW STATE hfrmcalc&,%buddy1,%SW_HIDE
      CONTROL ADD LABEL,hfrmcalc&,%buddy2,"2",5,88,25,12,%SS_CENTER,%WS_EX_LEFT OR %WS_EX_clientedge
      CONTROL SEND hfrmcalc&, %UpDown, %UDM_SETRANGE,0&, MAKLNG (7,0)
      CONTROL SEND hfrmcalc&, %UpDown, %UDM_SETBUDDY,GetDlgItem(hfrmcalc&,%Buddy1),0&
      CALL newformat 'set initial precision
      CONTROL ADD "Button", hfrmcalc&,  %FRMCALC_BTNdecimal,  ".", 35, 65, 15, 15, _
       %WS_CHILD OR %BS_NOTIFY OR %WS_VISIBLE OR %BS_PUSHBUTTON CALL CBF_FRMCALC_BTNdecimal
      CONTROL ADD "Button", hfrmcalc&,  %FRMCALC_BTNKEER,  "x", 78, 45, 17, 13, _
       %WS_CHILD OR %BS_NOTIFY OR %WS_VISIBLE OR %BS_PUSHBUTTON CALL CBF_FRMCALC_BTNKEER
      CONTROL ADD "Button", hfrmcalc&,  %FRMCALC_BTNDEEL,  CHR$(247), 78, 58, 17, 13, _
       %WS_CHILD OR %BS_NOTIFY OR %WS_VISIBLE OR %BS_PUSHBUTTON CALL CBF_FRMCALC_BTNDEEL
      CONTROL ADD "Button", hfrmcalc&,  %FRMCALC_BTNPLUS,  "+", 61, 45, 17, 13, _
       %WS_CHILD OR %BS_NOTIFY OR %WS_VISIBLE OR %BS_PUSHBUTTON CALL CBF_FRMCALC_BTNPLUS
      CONTROL ADD "Button", hfrmcalc&,  %FRMCALC_BTNMIN,  "-", 61, 58, 17, 13, _
       %WS_CHILD OR %BS_NOTIFY OR %WS_VISIBLE OR %BS_PUSHBUTTON CALL CBF_FRMCALC_BTNMIN
      CONTROL SEND hFrmcalc&,  %FRMCALC_BTNMIN, %WM_SETFONT, App_Font&(1), %TRUE
      CONTROL ADD "Button", hfrmcalc&,  %FRMCALC_BTNIS,  "=", 61, 71, 34, 13, _
       %WS_CHILD OR %BS_NOTIFY OR %WS_VISIBLE OR %BS_PUSHBUTTON CALL CBF_FRMCALC_BTNIS
      CONTROL ADD "Button", hfrmcalc&,  %FRMCALC_BTNPLUSMIN,  "+/-", 61, 34, 34, 10, _
       %WS_CHILD OR %BS_NOTIFY OR %WS_VISIBLE OR %BS_PUSHBUTTON CALL CBF_FRMCALC_BTNPLUSMIN
      CONTROL ADD "Button", hfrmcalc&,  %FRMCALC_BTNC,  "C", 97, 20, 17, 13, _
       %WS_CHILD OR %BS_NOTIFY OR %WS_VISIBLE OR %BS_PUSHBUTTON CALL CBF_FRMCALC_BTNC
      CONTROL ADD "Button", hfrmcalc&,  %FRMCALC_BTNCE,  "CE", 97, 35, 17, 13, _
       %WS_CHILD OR %BS_NOTIFY OR %WS_VISIBLE OR %BS_PUSHBUTTON CALL CBF_FRMCALC_BTNCE
      CONTROL ADD "Button", hfrmcalc&,  %FRMCALC_BTNM,  "M+", 61, 86, 17, 13, _
       %WS_CHILD OR %BS_NOTIFY OR %WS_VISIBLE OR %BS_PUSHBUTTON  CALL CBF_FRMCALC_BTNM
      CONTROL ADD "Button", hfrmcalc&,  %FRMCALC_BTNM_2,  "M-", 79, 86, 17, 13, _
       %WS_CHILD OR %BS_NOTIFY OR %WS_VISIBLE OR %BS_PUSHBUTTON  CALL CBF_FRMCALC_BTNM_2
      CONTROL ADD "Button", hfrmcalc&,  %FRMCALC_BTNMR,  "MR", 97, 86, 17, 13, _
       %WS_CHILD OR %BS_NOTIFY OR %WS_VISIBLE OR %BS_PUSHBUTTON  CALL CBF_FRMCALC_BTNMR
      CONTROL ADD "Button", hfrmcalc&,  %FRMCALC_BTNMC,  "MC", 97, 71, 17, 13, _
       %WS_CHILD OR %BS_NOTIFY OR %WS_VISIBLE OR %BS_PUSHBUTTON CALL CBF_FRMCALC_BTNMC
      CONTROL ADD "Button", hfrmcalc&,  %FRMCALC_BTNBACKSPACE,  "BS <-", 61, 20, 34, 13, _
       %WS_CHILD OR %BS_NOTIFY OR %WS_VISIBLE OR %BS_PUSHBUTTON CALL CBF_FRMCALC_BTNBACKSPACE
      CONTROL ADD "Button", hfrmcalc&,  %FRMCALC_BTNPROCENT,  "%", 97, 53, 17, 13, _
       %WS_CHILD OR %BS_NOTIFY OR %WS_VISIBLE OR %BS_PUSHBUTTON  CALL CBF_FRMCALC_BTNPROCENT
    #IF %COMPILE
      'CONTROL ADD "Button", hfrmcalc&,  %FRMCALC_BTNEXIT,  "Quit", 5, 86, 45, 13, _
      ' %WS_CHILD OR %BS_NOTIFY OR %WS_VISIBLE CALL CBF_FRMCALC_BTNEXIT
    #ELSE
      CONTROL ADD "Button", hfrmcalc&,  %FRMCALC_BTNTAKE,  "OK", 5, 106, 25, 13, _
       %WS_CHILD OR %BS_NOTIFY OR %WS_VISIBLE CALL CBF_FRMCALC_BTNTAKE
      CONTROL ADD "Button", hfrmcalc&,  %FRMCALC_BTNEXIT,  "Quit", 30, 106, 30, 13, _
       %WS_CHILD OR %BS_NOTIFY OR %WS_VISIBLE CALL CBF_FRMCALC_BTNEXIT
    #ENDIF
     ' DIALOG SHOW MODELESS hfrmcalc& , CALL frmcalc_DLGPROC
      'Keyboard Accelerators BM
      DIM lRslt AS LONG
    
      DIM ac(0:33) AS ACCELAPI
      ac(0).fvirt = %FVIRTKEY
      ac(0).key   = %VK_NUMPAD1
      ac(0).cmd   = %FRMCALC_BTN1
      ac(1).fvirt = %FVIRTKEY
      ac(1).key   = %VK_NUMPAD2   '
      ac(1).cmd   = %FRMCALC_BTN2
      ac(2).fvirt = %FVIRTKEY
      ac(2).key   = %VK_NUMPAD3   '
      ac(2).cmd   = %FRMCALC_BTN3
      ac(3).fvirt = %FVIRTKEY
      ac(3).key   = %VK_NUMPAD4   '
      ac(3).cmd   = %FRMCALC_BTN4
      ac(4).fvirt = %FVIRTKEY
      ac(4).key   = %VK_NUMPAD5   '
      ac(4).cmd   = %FRMCALC_BTN5
      ac(5).fvirt = %FVIRTKEY
      ac(5).key   = %VK_NUMPAD6   '
      ac(5).cmd   = %FRMCALC_BTN6
      ac(6).fvirt = %FVIRTKEY
      ac(6).key   = %VK_NUMPAD7   '
      ac(6).cmd   = %FRMCALC_BTN7
      ac(7).fvirt = %FVIRTKEY
      ac(7).key   = %VK_NUMPAD8   '
      ac(7).cmd   = %FRMCALC_BTN8
      ac(8).fvirt = %FVIRTKEY
      ac(8).key   = %VK_NUMPAD9   '
      ac(8).cmd   = %FRMCALC_BTN9
      ac(9).fvirt = %FVIRTKEY
      ac(9).key   = %VK_NUMPAD0   '
      ac(9).cmd   = %FRMCALC_BTN0
      ac(10).fvirt = %FVIRTKEY
      ac(10).key   = %VK_DECIMAL   '
      ac(10).cmd   = %FRMCALC_BTNdecimal
      ac(11).fvirt = %FVIRTKEY
      ac(11).key   = %VK_MULTIPLY   '
      ac(11).cmd   = %FRMCALC_BTNKEER
      ac(12).fvirt = %FVIRTKEY
      ac(12).key   = %VK_DIVIDE   '
      ac(12).cmd   = %FRMCALC_BTNDEEL
      ac(13).fvirt = %FVIRTKEY
      ac(13).key   = %VK_ADD   '
      ac(13).cmd   = %FRMCALC_BTNPLUS
      ac(14).fvirt = %FVIRTKEY
      ac(14).key   = %VK_SUBTRACT   '
      ac(14).cmd   = %FRMCALC_BTNMIN
      ac(15).fvirt = 0
      ac(15).key   = 61   '
      ac(15).cmd   = %FRMCALC_BTNIS
      ac(16).fvirt = %FVIRTKEY
      ac(16).key   = %VK_BACK   '
      ac(16).cmd   = %FRMCALC_BTNBACKSPACE
      ac(17).fvirt = %FVIRTKEY
      ac(17).key   = %VK_1   '
      ac(17).cmd   = %FRMCALC_BTN1
      ac(18).fvirt = %FVIRTKEY
      ac(18).key   = %VK_2   '
      ac(18).cmd   = %FRMCALC_BTN2
      ac(19).fvirt = %FVIRTKEY
      ac(19).key   = %VK_3   '
      ac(19).cmd   = %FRMCALC_BTN3
      ac(20).fvirt = %FVIRTKEY
      ac(20).key   = %VK_4   '
      ac(20).cmd   = %FRMCALC_BTN4
      ac(21).fvirt = %FVIRTKEY
      ac(21).key   = %VK_5   '
      ac(21).cmd   = %FRMCALC_BTN5
      ac(22).fvirt = %FVIRTKEY
      ac(22).key   = %VK_6   '
      ac(22).cmd   = %FRMCALC_BTN6
      ac(23).fvirt = %FVIRTKEY
      ac(23).key   = %VK_7   '
      ac(23).cmd   = %FRMCALC_BTN7
      ac(24).fvirt = %FVIRTKEY
      ac(24).key   = %VK_8   '
      ac(24).cmd   = %FRMCALC_BTN8
      ac(25).fvirt = %FVIRTKEY
      ac(25).key   = %VK_9   '
      ac(25).cmd   = %FRMCALC_BTN9
      ac(26).fvirt = %FVIRTKEY
      ac(26).key   = %VK_0   '
      ac(26).cmd   = %FRMCALC_BTN0
      ac(27).fvirt = 0
      ac(27).key   = ASC(".")   '
      ac(27).cmd   = %FRMCALC_BTNdecimal
      ac(28).fvirt = 0
      ac(28).key   = ASC("*")   '
      ac(28).cmd   = %FRMCALC_BTNKEER
      ac(29).fvirt = 0
      ac(29).key   = ASC("/")   '
      ac(29).cmd   = %FRMCALC_BTNDEEL
      ac(30).fvirt = 0
      ac(30).key   = ASC("+")   '
      ac(30).cmd   = %FRMCALC_BTNPLUS
      ac(31).fvirt = 0
      ac(31).key   = ASC("-")   '
      ac(31).cmd   = %FRMCALC_BTNMIN
      ac(32).fvirt = %FVIRTKEY
      ac(32).key   = %VK_RETURN   '
      ac(32).cmd   = %FRMCALC_BTNIS
      ac(33).fvirt = %FVIRTKEY
      ac(33).key   = %VK_ESCAPE   '
      ac(33).cmd   = %FRMCALC_BTNTAKE
      ACCEL ATTACH hfrmcalc&, ac() TO lRslt
      'BM
      DIALOG UNITS hfrmcalc&, 122, 140 TO PIXELS xx&, yy&             'BM set topmost code
    'IF TRIM$(COMMAND$) > "" THEN
      'iresult& = SetWindowPos(hfrmcalc&,%HWND_TOPMOST,C2_WINPOS_X& + LEFT_X&,C2_WINPOS_Y& + LEFT_Y&,xx&,yy&,0)  'BM
    'ELSE
    '  iresult& = SetWindowPos(hfrmcalc&,%HWND_TOPMOST,0,0,xx&,yy&,0)  'BM
    'END IF
      DIALOG SHOW MODAL hfrmcalc& , CALL frmcalc_DLGPROC
    END SUB
    ' *************************************************************
    '                             Dialog Callback Procedure
    '                             for Form frmcalc
    '                             uses Global Handle - hfrmcalc&
    ' *************************************************************
    CALLBACK FUNCTION frmcalc_DLGPROC
      SELECT CASE CBMSG
        ' Common Windows Messages you may want to process
        ' -----------------------------------------------
        CASE %WM_TIMER
        CASE %WM_HSCROLL
        CASE %WM_VSCROLL
        CASE %WM_SIZE
          IF IsIconic(CBHNDL) THEN
            ShowWindow(hdlg1&,%SW_HIDE)
          ELSE
            ShowWindow(hdlg1&,%SW_SHOW)
          END IF
        CASE %WM_CLOSE
        CASE %WM_DESTROY
        CASE %WM_SYSCOMMAND
        CASE %WM_PAINT
        CASE %WM_CTLCOLORDLG
          IF CBLPARAM=CBHNDL THEN
            ' Dialogs colors
            SetTextColor CBWPARAM, App_Color&(0) 'all text on app will be black (there is none in this occasion)
            SetBkColor   CBWPARAM, App_Color&(1) 'background will be dark blue
            FUNCTION= App_Brush&(1)
          END IF
        CASE %WM_CTLCOLORMSGBOX , %WM_CTLCOLORBTN, %WM_CTLCOLOREDIT,_
             %WM_CTLCOLORSTATIC, %WM_CTLCOLORSCROLLBAR, %WM_CTLCOLORLISTBOX
          ' Control colors
          SELECT CASE GetDlgCtrlID(CBLPARAM)
            CASE %frmcalc_txtcalc
              LOCAL inpstr AS STRING
              CONTROL GET TEXT hfrmcalc&,%FRMCALC_TXTCALC TO inpstr 'check for negative value to be colored red.
              inpstr=LTRIM$(inpstr," ") 'strip off leading spaces
              inpstr=RTRIM$(inpstr," ") 'strip off trailing spaces
              IF LEFT$(inpstr,1)="-" THEN 'if negative sign preceeds value, color textbox value red
                SetTextColor CBWPARAM, App_Color&( 4) 'color textbox value red
                SetBkColor   CBWPARAM, App_Color&(15) 'color background white
                FUNCTION=App_Brush&(15) 'color background white
              ELSE 'no negative sign preceeds textbox value
                SetTextColor CBWPARAM, App_Color&(0)  'color text of textbox black
                SetBkColor   CBWPARAM, App_Color&(15) 'color background textbox white
                FUNCTION=App_Brush&(15)  'color background white
              END IF
            CASE ELSE
          END SELECT
        CASE %WM_NOTIFY
            ptnmhdr = CBLPARAM               ' <-- Needed to implement DM filter
            pnmud = CBLPARAM
            LOCAL proposednewposition AS LONG
            SELECT CASE @ptnmhdr.idFrom
                ' DM filter to trap notifications from UpDown common control
                CASE %UpDown
                    SELECT CASE @ptnmhdr.code
                        CASE %UDN_DELTAPOS
                            proposednewposition = @pnmud.ipos + @pnmud.idelta
                            IF proposednewposition >=0 AND proposednewposition <= 7 THEN
                              pnewpos = @pnmud.ipos + @pnmud.idelta
                            END IF
                            CONTROL SET TEXT hfrmcalc&, %buddy2, LBPREC$(pnewpos)
                            CALL newformat
                      END SELECT
            END SELECT
    
          IF EZLIB_IsTooltip(CBLPARAM) THEN
            SELECT CASE EZLIB_TooltipID(CBLPARAM)
              CASE  %FRMCALC_BTN1
                EZLIB_SetTooltipText CBLPARAM, "Control -  %FRMCALC_BTN1"
              CASE  %FRMCALC_BTN2
                EZLIB_SetTooltipText CBLPARAM, "Control -  %FRMCALC_BTN2"
              CASE  %FRMCALC_BTN3
                EZLIB_SetTooltipText CBLPARAM, "Control -  %FRMCALC_BTN3"
              CASE  %FRMCALC_BTN4
                EZLIB_SetTooltipText CBLPARAM, "Control -  %FRMCALC_BTN4"
              CASE  %FRMCALC_BTN5
                EZLIB_SetTooltipText CBLPARAM, "Control -  %FRMCALC_BTN5"
              CASE  %FRMCALC_BTN6
                EZLIB_SetTooltipText CBLPARAM, "Control -  %FRMCALC_BTN6"
              CASE  %FRMCALC_BTN7
                EZLIB_SetTooltipText CBLPARAM, "Control -  %FRMCALC_BTN7"
              CASE  %FRMCALC_BTN8
                EZLIB_SetTooltipText CBLPARAM, "Control -  %FRMCALC_BTN8"
              CASE  %FRMCALC_BTN9
                EZLIB_SetTooltipText CBLPARAM, "Control -  %FRMCALC_BTN9"
              CASE  %FRMCALC_BTN0
                EZLIB_SetTooltipText CBLPARAM, "Control -  %FRMCALC_BTN0"
              CASE  %FRMCALC_BTNKEER
                EZLIB_SetTooltipText CBLPARAM, "Control -  %FRMCALC_BTNKEER"
              CASE  %FRMCALC_BTNDEEL
                EZLIB_SetTooltipText CBLPARAM, "Control -  %FRMCALC_BTNDEEL"
              CASE  %FRMCALC_BTNPLUS
                EZLIB_SetTooltipText CBLPARAM, "Control -  %FRMCALC_BTNPLUS"
              CASE  %FRMCALC_BTNMIN
                EZLIB_SetTooltipText CBLPARAM, "Control -  %FRMCALC_BTNMIN"
              CASE  %FRMCALC_BTNIS
                EZLIB_SetTooltipText CBLPARAM, "Control -  %FRMCALC_BTNIS"
              CASE  %FRMCALC_BTNPLUSMIN
                EZLIB_SetTooltipText CBLPARAM, "Control -  %FRMCALC_BTNPLUSMIN"
              CASE  %FRMCALC_BTNC
                EZLIB_SetTooltipText CBLPARAM, "Control -  %FRMCALC_BTNC"
              CASE  %FRMCALC_BTNCE
                EZLIB_SetTooltipText CBLPARAM, "Control -  %FRMCALC_BTNCE"
              CASE  %FRMCALC_BTNM
                EZLIB_SetTooltipText CBLPARAM, "Control -  %FRMCALC_BTNM"
              CASE  %FRMCALC_BTNM_2
                EZLIB_SetTooltipText CBLPARAM, "Control -  %FRMCALC_BTNM_2"
              CASE  %FRMCALC_BTNMR
                EZLIB_SetTooltipText CBLPARAM, "Control -  %FRMCALC_BTNMR"
              CASE  %FRMCALC_BTNMC
                EZLIB_SetTooltipText CBLPARAM, "Control -  %FRMCALC_BTNMC"
              CASE  %FRMCALC_BTNBACKSPACE
                EZLIB_SetTooltipText CBLPARAM, "Control -  %FRMCALC_BTNBACKSPACE"
              CASE  %FRMCALC_BTNEXIT
                EZLIB_SetTooltipText CBLPARAM, "Control -  %FRMCALC_BTNEXIT"
              CASE  %FRMCALC_BTNPROCENT
                EZLIB_SetTooltipText CBLPARAM, "Control -  %FRMCALC_BTNPROCENT"
              CASE ELSE
            END SELECT
          END IF
        CASE %WM_COMMAND
          ' Process Messages to Controls that have no Callback Function
          ' and Process Messages to Menu Items
          SELECT CASE CBCTL
            CASE ELSE
          END SELECT
        CASE ELSE
      END SELECT
    END FUNCTION
    
    ' (3) Put NEXT DIALOG Creation / Dialog Procedure code after here :
    
    ' *************************************************************
    '              EZGUI Freeware Dialog Designer Library
    '
    '                   see web site at EZGUI.COM
    '
    ' Copyright (C) 2000, Christopher R. Boss , All Rights Reserved !
    '
    ' This code was Generated by the EZGUI Freeware Dialog Designer
    ' and may be used ROYALTY FREE, as long as this Copyright notice
    ' is kept with the source code.
    ' The Author also gives you the right to post this code on a
    ' web site and to distribute it to others.
    ' *************************************************************
    SUB EZLIB_InitFonts()
      REDIM App_Font(0 TO 5)
      App_Font(0)=GetStockObject(%SYSTEM_FONT)
      App_Font(1)=GetStockObject(%SYSTEM_FIXED_FONT)
      App_Font(2)=GetStockObject(%ANSI_VAR_FONT)
      App_Font(3)=GetStockObject(%ANSI_FIXED_FONT)
      App_Font(4)=GetStockObject(%DEFAULT_GUI_FONT)    ' MS Sans Serif
      App_Font(5)=GetStockObject(%OEM_FIXED_FONT)      ' Terminal Font
      END SUB
    ' -------------------------------------------------------------
    SUB EZLIB_DeleteFonts()
      LOCAL N&
      ' Fonts 0 to 5 do not need to be deleted
      FOR N&=6 TO UBOUND(App_Font)
        IF App_Font(N&)<>0 THEN DeleteObject App_Font(N&)
      NEXT N&
      END SUB
    ' -------------------------------------------------------------
    SUB EZLIB_FixSize(BYVAL hDlg&, BYVAL Style&, BYVAL HasMenu&)
      LOCAL X&, Y&, W&, H&, XX&, YY&
      DIALOG GET SIZE hDlg& TO X&, Y&
      IF (Style& AND %WS_CAPTION) = %WS_CAPTION THEN
        IF HasMenu& THEN
          H&=H&+GetSystemMetrics(%SM_CYCAPTION)
        END IF
      END IF
      IF (Style& AND %WS_HSCROLL) = %WS_HSCROLL THEN
        H&=H&+GetSystemMetrics(%SM_CYHSCROLL)
      END IF
      IF (Style& AND %WS_VSCROLL) = %WS_VSCROLL THEN
        W&=W&+GetSystemMetrics(%SM_CYVSCROLL)
      END IF
      DIALOG PIXELS hDlg&, W&, H& TO UNITS XX&, YY&
      X&=X&+XX&
      Y&=Y&+YY&
      DIALOG SET SIZE hDlg&, X&, Y&
    END SUB
    ' -------------------------------------------------------------
    FUNCTION EZLIB_IsTooltip(BYVAL lParam AS LONG) AS LONG
      LOCAL pNM AS NMHDR PTR
      pNM=lParam
      IF @pNM.code=%TTN_NEEDTEXT THEN FUNCTION=1 ELSE FUNCTION=0
    END FUNCTION
    ' -------------------------------------------------------------
    FUNCTION EZLIB_TooltipID(BYVAL lParam AS LONG) AS LONG
      LOCAL pNM AS NMHDR PTR, pTT AS TOOLTIPTEXT PTR
      LOCAL IDNum&, UF&
      IDNum&=0
      pNM=lParam
      IF @pNM.code=%TTN_NEEDTEXT THEN
        ' Check for Tooltip message
        pTT=lParam
        UF&[email protected] AND %TTF_IDISHWND
        IF UF&=%TTF_IDISHWND THEN
          IDNum&=GetDlgCtrlID(@pTT.hdr.idfrom)
        ELSE
          IDNum&[email protected]
        END IF
      END IF
      FUNCTION=IDNum&
    END FUNCTION
    ' -------------------------------------------------------------
    SUB EZLIB_SetTooltipText(BYVAL lParam AS LONG, TipText$)
      LOCAL pNM AS NMHDR PTR, pTT AS TOOLTIPTEXT PTR
      pNM=lParam
      IF @pNM.code=%TTN_NEEDTEXT THEN
        ' Check for Tooltip message
        pTT=lParam
        IF TipText$<>"" THEN
          @pTT.szText=LEFT$(TipText$, 79)+CHR$(0)
        END IF
      END IF
    END SUB
    
    ' -------------------------------------------------------------
    SUB EZLIB_DefColors()
      LOCAL T&
      REDIM App_Brush&(0 TO 31)
      REDIM App_Color&(0 TO 31)
      FOR T&=0 TO 31
        App_Brush&(T&)=CreateSolidBrush(EZLIB_QBColor(T&))
        App_Color&(T&)=EZLIB_QBColor(T&)
      NEXT T&
    END SUB
    ' -------------------------------------------------------------
    SUB EZLIB_DeleteBrushes()
      LOCAL T&
      FOR T&=0 TO 31
        DeleteObject App_Brush&(T&)
      NEXT T&
    END SUB
    ' -------------------------------------------------------------
    FUNCTION EZLIB_QBColor(N&) AS LONG
      LOCAL RV&
      SELECT CASE N&
        CASE 0
        RV&=RGB(0,0,0)       ' Black
      CASE 1
        RV&=RGB(0,0,128)     ' Blue
      CASE 2
        RV&=RGB(0,128,0)     ' Green
      CASE 3
        RV&=RGB(0,128,128)   ' Cyan
      CASE 4
        RV&=RGB(196,0,0)     ' Red
      CASE 5
        RV&=RGB(128,0,128)   ' Magenta (Purple)
      CASE 6
        RV&=RGB(128,64,0)    ' Brown
      CASE 7
        RV&=RGB(196,196,196) ' White
      CASE 8
        RV&=RGB(128,128,128) ' Gray
      CASE 9
        RV&=RGB(0,0, 255)    ' Lt. Blue
      CASE 10
        RV&=RGB(0,255,0)     ' Lt. Green
      CASE 11
        RV&=RGB(0,255,255)   ' Lt. Cyan
      CASE 12
        RV&=RGB(255,0,0)     ' Lt. Red
      CASE 13
        RV&=RGB(255,0,255)   ' Lt. magenta (Purple)
      CASE 14
        RV&=RGB(255,255,0)   ' Yellow
      CASE 15
        RV&=RGB(255,255,255) ' Bright White
      CASE 16   ' - Extended QB colors Pastel version -
        RV&=RGB(164,164,164)
      CASE 17
        RV&=RGB(128,160,255)
      CASE 18
        RV&=RGB(160,255,160)
      CASE 19
        RV&=RGB(160,255,255)
      CASE 20
        RV&=RGB(255,160,160)
      CASE 21
        RV&=RGB(255,160,255)
      CASE 22
        RV&=RGB(255,255,160)
      CASE 23
        RV&=RGB(212,212,212)
      CASE 24
        RV&=RGB(180,180,180)
      CASE 25
        RV&=RGB(188,220,255)
      CASE 26
        RV&= RGB(220,255,220)
      CASE 27
        RV&=RGB(220,255,255)
      CASE 28
        RV&=RGB(255,220,220)
      CASE 29
        RV&=RGB(255,220,255)
      CASE 30
        RV&=RGB(255,255,220)
      CASE 31
        RV&=RGB(228,228,228)
      CASE ELSE
        RV&=RGB(0,0,0)
      END SELECT
      FUNCTION=RV&
    END FUNCTION
     ' -------------------------------------------------------------
    SUB EZLIB_ShowControl(BYVAL hWnd&, BYVAL ID&, BYVAL SFlag&)
      LOCAL hCtrl&
      IF IsWindow(hWnd&) THEN
        IF ID&<>0 THEN
          hCtrl&=GetDlgItem(hWnd&,ID&)
          IF SFlag&=0 THEN
            ShowWindow hCtrl&, %SW_HIDE
          ELSE
            ShowWindow hCtrl&, %SW_SHOW
          END IF
        END IF
      END IF
    END SUB
     ' -------------------------------------------------------------
    ' *************************************************************
    '             End of EZGUI Dynamic Dialogs Library
    ' *************************************************************
    
    ' *************************************************************
    '  Application Callback Functions (or Procedures) for Controls
    ' *************************************************************
    ' ------------------------------------------------
    CALLBACK FUNCTION CBF_FRMCALC_BTN1
      IF CBCTLMSG=%BN_CLICKED OR CBCTLMSG = 1 THEN
        CALL getbutton("1")
      END IF
      IF CBCTLMSG=%BN_SETFOCUS THEN
      END IF
      IF CBCTLMSG=%BN_KILLFOCUS THEN
      END IF
    END FUNCTION
    ' ------------------------------------------------
    ' ------------------------------------------------
    CALLBACK FUNCTION CBF_FRMCALC_BTN2
      IF CBCTLMSG=%BN_CLICKED OR CBCTLMSG = 1 THEN
        CALL getbutton("2")
      END IF
      IF CBCTLMSG=%BN_SETFOCUS THEN
      END IF
      IF CBCTLMSG=%BN_KILLFOCUS THEN
      END IF
    END FUNCTION
    ' ------------------------------------------------
    ' ------------------------------------------------
    CALLBACK FUNCTION CBF_FRMCALC_BTN3
      IF CBCTLMSG=%BN_CLICKED OR CBCTLMSG = 1  THEN
        CALL getbutton("3")
      END IF
      IF CBCTLMSG=%BN_SETFOCUS THEN
      END IF
      IF CBCTLMSG=%BN_KILLFOCUS THEN
      END IF
    END FUNCTION
    ' ------------------------------------------------
    ' ------------------------------------------------
    CALLBACK FUNCTION CBF_FRMCALC_BTN4
      IF CBCTLMSG=%BN_CLICKED OR CBCTLMSG = 1  THEN
        CALL getbutton("4")
      END IF
      IF CBCTLMSG=%BN_SETFOCUS THEN
      END IF
      IF CBCTLMSG=%BN_KILLFOCUS THEN
      END IF
    END FUNCTION
    ' ------------------------------------------------
    ' ------------------------------------------------
    CALLBACK FUNCTION CBF_FRMCALC_BTN5
      IF CBCTLMSG=%BN_CLICKED OR CBCTLMSG = 1  THEN
        CALL getbutton("5")
      END IF
      IF CBCTLMSG=%BN_SETFOCUS THEN
      END IF
      IF CBCTLMSG=%BN_KILLFOCUS THEN
      END IF
    END FUNCTION
    ' ------------------------------------------------
    ' ------------------------------------------------
    CALLBACK FUNCTION CBF_FRMCALC_BTN6
      IF CBCTLMSG=%BN_CLICKED OR CBCTLMSG = 1  THEN
          CALL getbutton("6")
      END IF
      IF CBCTLMSG=%BN_SETFOCUS THEN
      END IF
      IF CBCTLMSG=%BN_KILLFOCUS THEN
      END IF
    END FUNCTION
    ' ------------------------------------------------
    ' ------------------------------------------------
    CALLBACK FUNCTION CBF_FRMCALC_BTN7
      IF CBCTLMSG=%BN_CLICKED OR CBCTLMSG = 1  THEN
        CALL getbutton("7")
      END IF
      IF CBCTLMSG=%BN_SETFOCUS THEN
      END IF
      IF CBCTLMSG=%BN_KILLFOCUS THEN
      END IF
    END FUNCTION
    ' ------------------------------------------------
    ' ------------------------------------------------
    CALLBACK FUNCTION CBF_FRMCALC_BTN8
      IF CBCTLMSG=%BN_CLICKED OR CBCTLMSG = 1  THEN
        CALL getbutton("8")
      END IF
      IF CBCTLMSG=%BN_SETFOCUS THEN
      END IF
      IF CBCTLMSG=%BN_KILLFOCUS THEN
      END IF
    END FUNCTION
    ' ------------------------------------------------
    ' ------------------------------------------------
    CALLBACK FUNCTION CBF_FRMCALC_BTN9
      IF CBCTLMSG=%BN_CLICKED OR CBCTLMSG = 1  THEN
        CALL getbutton("9")
      END IF
      IF CBCTLMSG=%BN_SETFOCUS THEN
      END IF
      IF CBCTLMSG=%BN_KILLFOCUS THEN
      END IF
    END FUNCTION
    ' ------------------------------------------------
    ' ------------------------------------------------
    ' ------------------------------------------------
    CALLBACK FUNCTION CBF_FRMCALC_TXTCALC
      IF CBCTLMSG=%EN_CHANGE THEN
      END IF
      IF CBCTLMSG=%EN_SETFOCUS THEN
      END IF
      IF CBCTLMSG=%EN_KILLFOCUS THEN
      END IF
    END FUNCTION
    ' ------------------------------------------------
    ' ------------------------------------------------
    CALLBACK FUNCTION CBF_FRMCALC_BTN0
      IF CBCTLMSG=%BN_CLICKED OR CBCTLMSG = 1  THEN
        CALL getbutton("0")
     END IF
      IF CBCTLMSG=%BN_SETFOCUS THEN
      END IF
      IF CBCTLMSG=%BN_KILLFOCUS THEN
      END IF
    END FUNCTION
    ' ------------------------------------------------
    ' ------------------------------------------------
    CALLBACK FUNCTION CBF_FRMCALC_BTNDECIMAL
      LOCAL inpstr AS STRING
      IF CBCTLMSG=%BN_CLICKED OR CBCTLMSG = 1  THEN
          CONTROL GET TEXT hfrmcalc&,%FRMCALC_txtcalc TO inpstr
          IF inpstr="0.00" OR gwhatstr = "new"  THEN inpstr=""
          IF TALLY(inpstr,".")=< 0 THEN 'if not already has a dot
            inpstr=inpstr+"."
            CONTROL SET TEXT hfrmcalc,%FRMCALC_txtcalc,inpstr
          END IF
          gwhatstr=""
      END IF
      IF CBCTLMSG=%BN_SETFOCUS THEN
      END IF
      IF CBCTLMSG=%BN_KILLFOCUS THEN
      END IF
    END FUNCTION
    ' ------------------------------------------------
    ' ------------------------------------------------
    CALLBACK FUNCTION CBF_FRMCALC_BTNKEER
      IF CBCTLMSG=%BN_CLICKED OR CBCTLMSG = 1 THEN
          gminsign=0 'reset substract flag
          CALL lastsum 'do last calc
          gwhatstr="new" 'clear last values and overwrite texbox with new added data
          gsignstr="*" 'preserve for next calc
      END IF
      IF CBCTLMSG=%BN_SETFOCUS THEN
      END IF
      IF CBCTLMSG=%BN_KILLFOCUS THEN
      END IF
    END FUNCTION
    ' ------------------------------------------------
    ' ------------------------------------------------
    CALLBACK FUNCTION CBF_FRMCALC_BTNDEEL
      IF CBCTLMSG=%BN_CLICKED OR CBCTLMSG = 1  THEN
          gminsign=0
          CALL lastsum
          gwhatstr="new"
          gsignstr="/"
      END IF
      IF CBCTLMSG=%BN_SETFOCUS THEN
      END IF
      IF CBCTLMSG=%BN_KILLFOCUS THEN
      END IF
    END FUNCTION
    ' ------------------------------------------------
    ' ------------------------------------------------
    CALLBACK FUNCTION CBF_FRMCALC_BTNPLUS
      IF CBCTLMSG=%BN_CLICKED OR CBCTLMSG = 1  THEN
          gminsign=0
          CALL lastsum
          gwhatstr="new"
          gsignstr="+"
      END IF
      IF CBCTLMSG=%BN_SETFOCUS THEN
      END IF
      IF CBCTLMSG=%BN_KILLFOCUS THEN
      END IF
    END FUNCTION
    ' ------------------------------------------------
    ' ------------------------------------------------
    CALLBACK FUNCTION CBF_FRMCALC_BTNMIN
      IF CBCTLMSG=%BN_CLICKED OR CBCTLMSG = 1  THEN
          CALL lastsum
          gminsign=1
          gwhatstr="new"
          gsignstr="-"
      END IF
      IF CBCTLMSG=%BN_SETFOCUS THEN
      END IF
      IF CBCTLMSG=%BN_KILLFOCUS THEN
      END IF
    END FUNCTION
    ' ------------------------------------------------
    ' ------------------------------------------------
    CALLBACK FUNCTION CBF_FRMCALC_BTNIS
      IF CBCTLMSG=%BN_CLICKED OR CBCTLMSG = 1  THEN
          goldsignstr=gsignstr 'preserve last calc because globalsignstring will be filled with =
          gsignstr="=" 'do before lastsum, so lastsum knows that is should calc now, and not the next turn
          CALL lastsum
          gwhatstr="new"
      END IF
      IF CBCTLMSG=%BN_SETFOCUS THEN
      END IF
      IF CBCTLMSG=%BN_KILLFOCUS THEN
      END IF
    END FUNCTION
    ' ------------------------------------------------
    ' ------------------------------------------------
    CALLBACK FUNCTION CBF_FRMCALC_BTNPLUSMIN
      LOCAL inpstr AS STRING
      IF CBCTLMSG=%BN_CLICKED THEN
        CONTROL GET TEXT hfrmcalc&,%FRMCALC_TXTCALC TO inpstr
        inpstr=LTRIM$(inpstr," ")
        inpstr=RTRIM$(inpstr," ")
        IF LEFT$(inpstr,1)="-" THEN  'toggle between positive and negative value
          gminsign=0
          inpstr=RIGHT$(inpstr,LEN(inpstr)-1)
        ELSE
          gminsign=1
          inpstr="-"+inpstr
        END IF
        CONTROL SET TEXT hfrmcalc,%FRMCALC_txtcalc,inpstr
      END IF
      IF CBCTLMSG=%BN_SETFOCUS THEN
      END IF
      IF CBCTLMSG=%BN_KILLFOCUS THEN
      END IF
    END FUNCTION
    ' ------------------------------------------------
    ' ------------------------------------------------
    CALLBACK FUNCTION CBF_FRMCALC_BTNC
      IF CBCTLMSG=%BN_CLICKED THEN
         gtotaldb=0  'reset all values (except memcell)
    '     inpstr=""
         gminsign=0
        CONTROL SET TEXT hfrmcalc,%FRMCALC_txtcalc,"0.00"
      END IF
      IF CBCTLMSG=%BN_SETFOCUS THEN
      END IF
      IF CBCTLMSG=%BN_KILLFOCUS THEN
      END IF
    END FUNCTION
    ' ------------------------------------------------
    ' ------------------------------------------------
    CALLBACK FUNCTION CBF_FRMCALC_BTNCE
      IF CBCTLMSG=%BN_CLICKED THEN
         gminsign=0 'only reset last value in textbox
         CONTROL SET TEXT hfrmcalc,%FRMCALC_txtcalc,""
      END IF
      IF CBCTLMSG=%BN_SETFOCUS THEN
      END IF
      IF CBCTLMSG=%BN_KILLFOCUS THEN
      END IF
    END FUNCTION
    ' ------------------------------------------------
    ' ------------------------------------------------
    CALLBACK FUNCTION CBF_FRMCALC_BTNM
      LOCAL inpstr AS STRING
      IF CBCTLMSG=%BN_CLICKED THEN
          CONTROL GET TEXT hfrmcalc&,%FRMCALC_txtcalc TO inpstr 'add textbox value with memvalue
             inpstr=REMOVE$(inpstr,ANY",")
             gmemstr=STR$(VAL(gmemstr)+VAL(inpstr))
      END IF
      IF CBCTLMSG=%BN_SETFOCUS THEN
      END IF
      IF CBCTLMSG=%BN_KILLFOCUS THEN
      END IF
    END FUNCTION
    ' ------------------------------------------------
    ' ------------------------------------------------
    CALLBACK FUNCTION CBF_FRMCALC_BTNM_2
      LOCAL inpstr AS STRING
      IF CBCTLMSG=%BN_CLICKED THEN
          CONTROL GET TEXT hfrmcalc&,%FRMCALC_txtcalc TO inpstr
            inpstr=REMOVE$(inpstr,ANY",")
            gmemstr=STR$(VAL(gmemstr)-VAL(inpstr)) 'substract textbox value from memvalue
      END IF
      IF CBCTLMSG=%BN_SETFOCUS THEN
      END IF
      IF CBCTLMSG=%BN_KILLFOCUS THEN
      END IF
    END FUNCTION
    ' ------------------------------------------------
    ' ------------------------------------------------
    CALLBACK FUNCTION CBF_FRMCALC_BTNMR
      IF CBCTLMSG=%BN_CLICKED THEN
          CONTROL SET TEXT hfrmcalc&,%FRMCALC_txtcalc,FORMAT$(VAL(gmemstr),nformat) 'fill textbox with memvalue
      END IF
      IF CBCTLMSG=%BN_SETFOCUS THEN
      END IF
      IF CBCTLMSG=%BN_KILLFOCUS THEN
      END IF
    END FUNCTION
    ' ------------------------------------------------
    ' ------------------------------------------------
    CALLBACK FUNCTION CBF_FRMCALC_BTNMC
      IF CBCTLMSG=%BN_CLICKED THEN
         gmemstr="" 'clear memvalue
      END IF
      IF CBCTLMSG=%BN_SETFOCUS THEN
      END IF
      IF CBCTLMSG=%BN_KILLFOCUS THEN
      END IF
    END FUNCTION
    ' ------------------------------------------------
    ' ------------------------------------------------
    CALLBACK FUNCTION CBF_FRMCALC_BTNBACKSPACE
      LOCAL inpstr AS STRING
      IF CBCTLMSG=%BN_CLICKED OR CBCTLMSG = 1  THEN
          CONTROL GET TEXT hfrmcalc&,%FRMCALC_txtcalc TO inpstr
          inpstr=LEFT$(inpstr,LEN(inpstr)-1) 'erase last sign from textbox (you can erase the negative sign !)
          CONTROL SET TEXT hfrmcalc,%FRMCALC_txtcalc,inpstr
      END IF
      IF CBCTLMSG=%BN_SETFOCUS THEN
      END IF
      IF CBCTLMSG=%BN_KILLFOCUS THEN
      END IF
    END FUNCTION
    ' ------------------------------------------------
    ' ------------------------------------------------
    CALLBACK FUNCTION CBF_FRMCALC_BTNEXIT
      IF CBCTLMSG=%BN_CLICKED THEN
           gexitstr="" 'if regular exit don't leave anything
           DIALOG END CBHNDL
      END IF
      IF CBCTLMSG=%BN_SETFOCUS THEN
      END IF
      IF CBCTLMSG=%BN_KILLFOCUS THEN
      END IF
    END FUNCTION
    ' ------------------------------------------------
    CALLBACK FUNCTION CBF_FRMCALC_BTNTAKE
      IF CBCTLMSG=%BN_CLICKED OR CBCTLMSG = 1 THEN
         #IF %compile
           gexitstr="" 'when exe don't leave anything
           DIALOG END CBHNDL
         #ELSE 'when dll
           CONTROL GET TEXT hfrmcalc&,%FRMCALC_txtcalc TO gexitstr 'preserve value to global for passing to exit function
           DIALOG END CBHNDL
         #ENDIF
      END IF
      IF CBCTLMSG=%BN_SETFOCUS THEN
      END IF
      IF CBCTLMSG=%BN_KILLFOCUS THEN
      END IF
    END FUNCTION
    ' ------------------------------------------------
    'percentage is always a part of a calculation, you just can't 10% without anything preceding.
    ' You either multiply,divide,add or substract percentages from amounts.
    ' For example add 19% VAT to the amount of $25,-- is '25+19% is 29.75'
    ' ------------------------------------------------
    CALLBACK FUNCTION CBF_FRMCALC_BTNPROCENT
      LOCAL tempval AS EXTENDED
      LOCAL inpstr AS STRING
      IF CBCTLMSG=%BN_CLICKED THEN
        CONTROL GET TEXT hfrmcalc,%FRMCALC_txtcalc TO inpstr
        inpstr=REMOVE$(inpstr,ANY",") 'remove any format$ comma's
        tempval=VAL(inpstr)
        CONTROL SET TEXT hfrmcalc,%FRMCALC_txtcalc,STR$((gtotaldb/100)*tempval) 'this is the actual percentage calc, put in the textbox
        CALL lastsum                                                            'to be used with the preceding calculation
        gwhatstr="new"
        gsignstr=""
      END IF
      IF CBCTLMSG=%BN_SETFOCUS THEN
      END IF
      IF CBCTLMSG=%BN_KILLFOCUS THEN
      END IF
    END FUNCTION
    ' ------------------------------------------------
    ' (4) Put NEXT DIALOG Callback / Subs code after here :
    ' *************************************************************
    '                     Put Your Code Here
    ' *************************************************************
    
    SUB newformat
      CONTROL GET TEXT hfrmcalc&,%buddy2 TO nprecision
      SELECT CASE TRIM$(nprecision)
        CASE "0"
          nformat = "############,###"
        CASE "1"
          nformat = "############,###.0"
        CASE "2"
          nformat = "############,###.00"
        CASE "3"
          nformat = "############,###.000"
        CASE "4"
          nformat = "############,###.0000"
        CASE "5"
          nformat = "############,###.00000"
        CASE "6"
          nformat = "############,###.000000"
        CASE ELSE
          nformat = "############,###.000000000000"
      END SELECT
      CONTROL SET TEXT hfrmcalc&,%FRMCALC_txtcalc,FORMAT$(gtotaldb,nformat)
    END SUB
    SUB lastsum
      LOCAL inpstr AS STRING
      LOCAL tempval AS EXTENDED
          CONTROL GET TEXT hfrmcalc&,%FRMCALC_txtcalc TO inpstr
          inpstr=REMOVE$(inpstr,ANY",")
          inpstr=LTRIM$(inpstr," ")
          inpstr=RTRIM$(inpstr," ")
          IF gminsign=1 AND TALLY(inpstr,"-") = 0 THEN
            CONTROL SET TEXT hfrmcalc&,%FRMCALC_txtcalc,"-"+inpstr
            CONTROL GET TEXT hfrmcalc&,%FRMCALC_txtcalc TO inpstr
            inpstr=LTRIM$(inpstr," ")
            inpstr=RTRIM$(inpstr," ")
          END IF
          IF LEFT$(inpstr,1)="-" THEN
                tempval=-VAL(inpstr)
                gminsign=0
           ELSE
                tempval=VAL(inpstr)
                gminsign=0
           END IF
          SELECT CASE gsignstr
            CASE "*"
              gtotaldb=gtotaldb*tempval
              CONTROL SET TEXT hfrmcalc&,%FRMCALC_txtcalc,FORMAT$(gtotaldb,nformat)
            CASE "/"
              gtotaldb=gtotaldb/tempval
              CONTROL SET TEXT hfrmcalc&,%FRMCALC_txtcalc,FORMAT$(gtotaldb,nformat)
            CASE "+"
              gtotaldb=gtotaldb+tempval
              CONTROL SET TEXT hfrmcalc&,%FRMCALC_txtcalc,FORMAT$(gtotaldb,nformat)
            CASE "-"
              gtotaldb=gtotaldb-tempval
              CONTROL SET TEXT hfrmcalc&,%FRMCALC_txtcalc,FORMAT$(gtotaldb,nformat)
            CASE "%"
                 CONTROL SET TEXT hfrmcalc,%FRMCALC_txtcalc,FORMAT$((gtotaldb/100)*tempval,nformat)
            CASE "="
              SELECT CASE goldsignstr
                CASE "*"
                  gtotaldb=gtotaldb*tempval
                CASE "/"
                  gtotaldb=gtotaldb/tempval
                CASE "+"
                  gtotaldb=gtotaldb+tempval
                CASE "-"
                  gtotaldb=gtotaldb-tempval
                CASE "%"
                  CONTROL SET TEXT hfrmcalc,%FRMCALC_txtcalc,FORMAT$((gtotaldb/100)*tempval,nformat)
              END SELECT
              CONTROL SET TEXT hfrmcalc&,%FRMCALC_txtcalc,FORMAT$(gtotaldb,nformat)
              gtotaldb=0
              gsignstr=""
              goldsignstr=""
            CASE ELSE
          END SELECT
          goldsignstr=gsignstr
          SETFOCUS hfrmcalc&
          CONTROL GET TEXT hfrmcalc&,%FRMCALC_txtcalc TO inpstr
          inpstr=REMOVE$(inpstr,ANY",")
          gtotaldb=VAL(inpstr)
    END SUB
    
    SUB getbutton(BYVAL btn AS STRING)
      LOCAL inpstr AS STRING
      LOCAL inpdb AS EXTENDED
      CONTROL GET TEXT hfrmcalc&,%FRMCALC_txtcalc TO inpstr
      IF inpstr="0.00" OR gwhatstr = "new" THEN inpstr=""
      inpstr=REMOVE$(inpstr,ANY",")
      inpstr=inpstr+btn
      inpdb=VAL(inpstr)
    '  CONTROL SET TEXT hfrmcalc&,%FRMCALC_txtcalc,FORMAT$(inpdb,nformat) 'Using this line adds always a dot after the first input
      CONTROL SET TEXT hfrmcalc&,%FRMCALC_txtcalc,inpstr
      gwhatstr=""
    END SUB
    Bob Mechler

    Leave a comment:


  • Michael Mattias
    replied
    >>As far as mixing DDT and SDK, I didn't know how to Get or Set User values in SDK.

    Well, then ask!

    My bad, you already did... and I answered.

    FWIW, no way in hell I would even think about trying to use DIALOG/CONTROL SET USER and Get/SetWindowLong on the same window/control. Sure, it might work but I really believe that would be tempting fate bigtime.

    Leave a comment:


  • BOB MECHLER
    replied
    As far as mixing DDT and SDK, I didn't know how to Get or Set User values in SDK. The other DDT code I think I can change to SDK only.

    The code is back working this morning in the same program. I will post a complete compileable example later today. Problem is, when I concentrate on this single function it works fine. It's only while it's working with several other Superclassed controls based on the Edit function that it breaks (sometimes). Code that works one minute and not the next is the hardest to debug. Thanks for the suggestions.

    This is some code that is very close to the original posted by Semen. This is what I started with.

    I did not do anything to the CreateSuperClass function. Originally this only allowed Enter to be go to the next field. I added the other code to test how it would operate with other keystrokes being trapped. I didn't change OldProc to Static, that's the way it was in the original but will try changing it as was suggested.

    Code:
       #COMPILE EXE
       #REGISTER NONE
       #DIM ALL
       #INCLUDE "WIN32API.INC"
       CALLBACK FUNCTION SuperEditProc
          STATIC OldProc AS LONG, OffsetWndExtra AS LONG
          IF CBHNDL = 0 THEN OldProc = CBWPARAM: OffsetWndExtra = CBLPARAM: EXIT FUNCTION
          SELECT CASE CBMSG
             CASE %WM_GETDLGCODE
                FUNCTION = %DLGC_WANTALLKEYS: EXIT FUNCTION
             CASE %WM_KEYDOWN
                SELECT CASE CBWPARAM
                  CASE %VK_UP:SetFocus GetNextDlgTabItem(GetParent(CBHNDL), CBHNDL, -1): EXIT FUNCTION
                  CASE %VK_DOWN:SetFocus GetNextDlgTabItem(GetParent(CBHNDL), CBHNDL, 0): EXIT FUNCTION
                  CASE %VK_F6: MSGBOX("F6 pressed"):CONTROL SET TEXT GetParent(CBHNDL),getdlgctrlid(CBHNDL),"New Text": EXIT FUNCTION
                  CASE ELSE
                    MSGBOX(STR$(GetDlgCtrlId(CBHNDL)))
                END SELECT
             CASE %WM_CHAR
                SELECT CASE CBWPARAM
                   CASE 13: SetFocus GetNextDlgTabItem(GetParent(CBHNDL), CBHNDL, 0): EXIT FUNCTION
                   CASE ASC("A") TO ASC("G"): EXIT FUNCTION
               END SELECT 
          END SELECT
          FUNCTION = CallWindowProc(OldProc, CBHNDL, CBMSG, CBWPARAM, CBLPARAM)
       END FUNCTION
       FUNCTION CreateSuperClass(OldClassName AS STRING, NewClassName AS STRING, lpfnNewWndProc AS LONG, cbWndExtra AS LONG) AS LONG
          LOCAL wc AS WNDCLASSEX
          wc.cbSize = SIZEOF(wc)
          IF GetClassInfoEx(BYVAL 0&, BYVAL STRPTR(OldClassName), wc) THEN
             CallWindowProc lpfnNewWndProc, 0, 0, wc.lpfnWndProc, wc.cbWndExtra
             wc.hInstance = GetModuleHandle(BYVAL 0&)
             wc.lpszClassName = STRPTR(NewClassName)
             wc.lpfnWndProc = lpfnNewWndProc
             wc.cbWndExtra = wc.cbWndExtra + cbWndExtra
             FUNCTION = RegisterClassEx(wc)
          END IF
       END FUNCTION
       CALLBACK FUNCTION OkProc
          MSGBOX "What do you want ?"
       END FUNCTION
    
       FUNCTION PBMAIN
          IF ISFALSE(CreateSuperClass("EDIT", "SuperEdit", CODEPTR(SuperEditProc), 4)) THEN EXIT FUNCTION
    
          LOCAL hDlg AS LONG, i AS LONG
          DIALOG NEW 0, "Test", , , 120, 100, %WS_CAPTION OR %WS_SYSMENU OR %WS_MAXIMIZEBOX TO hDlg
          FOR i = 1 TO 3
             CONTROL ADD "SuperEdit", hDlg, 100 + i, "Enter -> Tab", 10, 20 * i - 10, 100, 14, _
                %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP, %WS_EX_CLIENTEDGE
          NEXT
          CONTROL ADD BUTTON, hDlg, 201, "Ok", 10, 70, 100, 14 CALL OkProc
          DIALOG SHOW MODAL hDlg
       END FUNCTION
    BOB MECHLER

    Leave a comment:


  • Michael Mattias
    replied
    Code:
    CallWindowProc lpfnNewWndProc, 0, 0, wc.lpfnWndProc, wc.cbWndExtra
    If you want to make this 'phony' call to that window procedure with hWnd=0 to tell you "this is the phony call just to set the STATIC var for "oldwindowproc" you could just CALL the function, something like.
    Code:
    CALL NEditNumberProc (%NULL, %NULL, %NULL, OldProcAddress)
    Then in your function, test for null Hwnd and/or msg, and assign your static variable the value of CBLPARAM.

    Using "CallWindowProc" may be doing some stuff you really don't want happening.

    Seems "cleaner" anyway....

    If compiler rejects with 480 parameter mismatch error, you can call it with
    Code:
    CALL DWORD CODEPTR(NEditNumberProc) USING SendMessage (%NULL, %NULL, %NULL, OldProcAddress)

    (USING can use any function previously coded or DECLARED which takes exactly four long integers by value).
    Last edited by Michael Mattias; 7 Aug 2008, 08:34 AM.

    Leave a comment:


  • Edwin Knoppert
    replied
    You should never share a windowproc for different classes!

    Leave a comment:


  • Edwin Knoppert
    replied
    Originally posted by Chris Holbrook View Post
    In what circumstances do you think it will fail?
    It might fail since it wasn't designed to be used with SDK programming.
    It may currently work but what about a next PB update?

    >But that is his CallBack for the new window class ONLY. If you share a CB between classes then you need to have a global structure of hwnd & OldClassProc.
    I mis the point..

    A superclass is a global class definition, a Window is derived from a class.
    Doing the (odd) call to set a static inside a windowproc is totally useless.
    The class is global and thus a global prevproc is fine.

    Leave a comment:


  • Chris Holbrook
    replied
    Originally posted by Edwin Knoppert View Post
    It's pointless to maintain the prevproc address inside the windowproc. It's a class thing and not a window thing.
    But that is his CallBack for the new window class ONLY. If you share a CB between classes then you need to have a global structure of hwnd & OldClassProc.

    Leave a comment:


  • Chris Holbrook
    replied
    Originally posted by Edwin Knoppert View Post
    Then.. you are using a DDT style callback. Let's wait until that feature breaks
    In what circumstances do you think it will fail?

    Leave a comment:


  • Edwin Knoppert
    replied
    Then.. you are using a DDT style callback.
    Let's wait until that feature breaks
    Iow, make it a full SDK style callback.

    Leave a comment:


  • Edwin Knoppert
    replied
    Oh yukkie, the call set's static values in the windowproc, another eeek from me
    It's pointless to maintain the prevproc address inside the windowproc.
    It's a class thing and not a window thing.
    Therefore i recommend to move the prevproc outside this function and make it global.

    Leave a comment:

Working...
X
😀
🥰
🤢
😎
😡
👍
👎