Announcement

Collapse
No announcement yet.

How should a sub/super class decimal field behave

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

  • How should a sub/super class decimal field behave

    I'm working on a superclass numeric entry field with a fixed max number of digits to the left and to the right of the decimal.

    So far the field acts this way.

    1. If the field is empty, digits are inserted until a '.' is entered and then as additional digits are entered they are placed to the right of the decimal until the the decimal max digits is reached and then moves to the next field.

    2. If the field is not empty and the insertion point is to the left of the '.' it overwrites the digit below it. This occurs until it gets to the decimal point and then it starts to insert digits. If the insertion point is to the right, it just overwrites until the last position is reached and then moves to the next field.

    3. If the user places the insertion point to the left of the decimal and presses the '.' key then all digits to the right of the insertion point are truncated up to the old decimal place and the field repositions so that the '.' is in the right place.

    4. The Del and Backspace key do as you would expect.

    5. The minus sign can only be entered only in the first position

    6. Upon entering the field any commas are removed and when exiting commas are introduced.

    7. Ctrl-F brings up a calculator whose final value is put into the field when the calculator is dismissed.

    The windows calculator works a little different. It starts with 0. and each digit is inserted until you press the '.' and then all digits are entered to the right of the decimal. No arrow or insertion points are allowed.

    I'm interested in what are really good standards for this type of entry. I'm wondering if I should disallow the arrows and/or the insertion pointer like the windows calculator does and how I would do that.

    Our customers want heads down data-entry where the field fills and automatically moves to the next field etc.

    Bob Mechler

  • #2
    I'm not sure there are 'standards' for this kind of thing.

    Personally I'd look at either eschewing decimal point entry and using an implied number of decimals (you see this with "money" applications), OR

    Just subclassing the control and picking off the WM_CHAR messages and disallowing non-numeric digits, more than one decimal point or + or - other than as the first character.

    But you can do all the stuff you want to do the same way: pick off WM_CHAR messages, inspect the current text and decide if you want to allow this character at this point or not.

    Here's a subclass proc I recently created to allow only valid hex digits... if nothing else it's a starting point for you.

    Code:
    FUNCTION DelimiterHexEditProc (BYVAL hWnd AS LONG, BYVAL wMSG AS LONG, BYVAL wPAram AS LONG, BYVAL lParam AS LONG) AS LONG
    
      STATIC dwProc AS DWORD, BeenHere AS LONG
      LOCAL szProp AS ASCIIZ * 64
      LOCAL  idCtrl AS LONG
      LOCAL  szText AS ASCIIZ * %MAX_PATH, lText AS LONG
      LOCAL  ichar  AS LONG
    
    
      IF ISFALSE beenHere THEN
          BeenHere = %TRUE
          szProp   = $PROP_OLD_WNDPROC
          dwProc   = getProp (hWnd, szProp)
      END IF
    
      SELECT CASE AS LONG wMSg
    
             CASE %WM_GETDLGCODE
                 'FUNCTION =  %DLGC_WANTALLKEYS     ' With DLCG_WANTCHARS all regular keys work but no WM-CHAR message
                 FUNCTION = %DLGC_WANTCHARS         ' doc says "WM_CHAR messages"
                 'FUNCTION   = %DLGC_WANTMESSAGE
                 EXIT FUNCTION
    
             CASE  %WM_CHAR                      '"An application should return zero if it processes this message. "
                ' LOWRD wparam = "the character code of the key"
                 IF wparam = %VK_TAB THEN
                     ' standard TAB behavior
                       SetFocus       GetnextDlgTabItem(GetParent(hWnd), hWnd, (GetKeyState(%VK_SHIFT) < 0))
                       FUNCTION = 0
                       EXIT FUNCTION
    
                 ELSE  ' not tab
                    iChar  = LOWRD(WParam)
    
    HERE IS WHERE YOU CAN GET THE EXISTING TEXT OF CONTROL AND DECIDE 
    IF YOU WANT TO ALLOW THE PROPOSED NEW CHARACTER
                    SELECT CASE AS LONG iChar
                        CASE &h30 TO &h39, &h41 TO &h46, _    ' OK characters 0-9 and A-F
                             &h61 TO &h66, _                  ' lower case a-f, will be uppercased when they get in
                             %VK_TAB, %VK_HOME, %VK_END, %VK_BACK, _      ' expected control characters
                             %VK_RIGHT, %VK_LEFT, %VK_INSERT, %VK_DELETE, _
                             %vK_ESCAPE
                            EXIT SELECT                      ' allow normal processing
                        CASE ELSE
                            MessageBeep  %MB_ICONHAND
                            FUNCTION = 0
                            EXIT FUNCTION    ' bypass normal processing
                    END SELECT
                 END IF
    
           END SELECT
           ' if message not handled (if handled proc was exited), call default handler
           FUNCTION = CallWindowProc (dwProc, hWnd, wMsg, wParam,lparam)
    
    END FUNCTION
    Michael Mattias
    Tal Systems Inc. (retired)
    Racine WI USA
    [email protected]
    http://www.talsystems.com

    Comment


    • #3
      Originally posted by Michael Mattias View Post
      ... eschewing decimal point entry and using an implied number of decimals (you see this with "money" applications)
      If you are doing money counting then you will probably want to use a double-zero key too, so to enter $1.00 you would punch <1><00>.

      Comment


      • #4
        Calculator-style entry.
        I will be moving my Visual Basic code to PowerBASIC on this soon.
        Before doing so, I will search to see if a good solution now exists.
        How long is an idea? Write it down.

        Comment


        • #5
          Going back to Bob's original question, I suppose that it would be a good thing - well, an education, at least - to look at the LOCALE variables which might apply to such a control (I've just discovered Locale, as you might guess). This is snipped from the Win32 Programmer's Reference:

          LOCALE_ILZERO

          Specifier for leading zeros in decimal fields. The maximum number of characters allowed for this string is 2. The specifier can be one of the following values:

          0 No leading zeros
          1 Leading zeros


          LOCALE_INEGNUMBER

          Negative number mode. The mode can be one of these values:

          0 (1.1)
          1 -1.1
          2 - 1.1
          3 1.1-
          4 1.1 -


          LOCALE_SNATIVEDIGITS

          Native equivalents to ASCII 0 through 9.

          LOCALE_SCURRENCY

          String used as the local monetary symbol.

          LOCALE_SINTLSYMBOL

          Three characters of the international monetary symbol specified in ISO 4217, "Codes for the Representation of Currencies and Funds," followed by the character separating this string from the amount.

          LOCALE_SMONDECIMALSEP

          Character(s) used as the monetary decimal separator.

          LOCALE_SMONTHOUSANDSEP

          Character(s) used as the monetary separator between groups of digits to the left of the decimal.

          LOCALE_SMONGROUPING

          Sizes for each group of monetary digits to the left of the decimal. An explicit size is needed for each group; sizes are separated by semicolons. If the last value is zero, the preceding value is repeated. To group thousands, specify 3;0, for example.

          LOCALE_ICURRDIGITS

          Number of fractional digits for the local monetary format. The maximum number of characters allowed for this string is 3.

          LOCALE_IINTLCURRDIGITS

          Number of fractional digits for the international monetary format. The maximum number of characters allowed for this string is 3.

          LOCALE_ICURRENCY

          Positive currency mode. The maximum number of characters allowed for this string is 2. The mode can be one of the following values:

          0 Prefix, no separation
          1 Suffix, no separation
          2 Prefix, 1-char. separation
          3 Suffix, 1-char. separation


          LOCALE_INEGCURR

          Negative currency mode. The maximum number of characters allowed for this string is 3. The mode can be one of the following values:

          0 ($1.1)
          1 -$1.1
          2 $-1.1
          3 $1.1-
          4 (1.1$)
          5 -1.1$
          6 1.1-$
          7 1.1$-
          8 -1.1 $ (space before $)
          9 -$ 1.1 (space after $)
          10 1.1 $- (space before $)
          11 $ 1.1- (space after $)
          12 $ -1.1 (space after $)
          13 1.1- $ (space before $)
          14 ($ 1.1) (space after $)
          15 (1.1 $) (space before $)

          Comment

          Working...
          X