News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

An Edit Control that does NOT accept numbers

Started by hfheatherfox07, February 11, 2013, 10:29:09 PM

Previous topic - Next topic

hfheatherfox07

Hello,
I am looking to make an Edit Control that does NOT accept numbers , Is that possible with out sub classing ?
I tried this and made a mess
I have used this tut for reference
http://www.dreamincode.net/forums/topic/241936-masm-superclassing/
Should I use a char table Like

.data
char db "0123456789",0

Thank You!
Your code and your skills will be assimilated. Your programming language is irrelevant.
We are the ASM Borg and you will become part of us. Compile and be assembled.

fearless

If its just a single edit control, then yes, subclassing is the way to go, for more than a few, then superclassing is the most viable option.

Here is some sample subclassing code that might help (not tested):

.CONST
IDC_TxtOnlyEditBox                EQU 1001 ; change to whatever constant required for editbox

.DATA?
hTxtOnlyEditBox                   dd ? ; Handle to editbox that is to contain text only
OldTxtOnlyEditBoxProc             dd ? ; Handle to default procedure for subclassing text only editbox to only allow text - no numbers

.CODE
DialogProc proc hWnd: HWND, uMsg: UINT, wParam: WPARAM, lParam: LPARAM
    mov eax, uMsg
    .if eax==WM_INITDIALOG
        Invoke GetDlgItem, hWin, IDC_TxtOnlyEditBox ; get editbox handle
        mov hTxtOnlyEditBox, eax ; save editbox handle
        invoke SetWindowLong,hTxtOnlyEditBox,GWL_WNDPROC,addr TxtOnlyEditBoxProc ; point editbox to new proc
        mov OldTxtOnlyEditBoxProc,eax ; save old proc - needed for the subclass proc to call original proc
        Invoke SendMessage, hTxtOnlyEditBox, EM_SETLIMITTEXT, 20, 0 ; set limit for amount of text, 20 chars
        .
        .       
       
;======================================================================
; Subclass for editbox to display text only
;======================================================================
TxtOnlyEditBoxProc    PROC hEdit:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
    .if uMsg==WM_CHAR
        mov eax,wParam
        .if (al>="a" && al<="z") || (al>="A" && al<="Z") || al==VK_BACK
            invoke CallWindowProc,OldTxtOnlyEditBoxProc,hEdit,uMsg,eax,lParam
            ret
        .endif
    .elseif uMsg==WM_KEYDOWN
        mov eax,wParam
        .if al==VK_RETURN
            invoke SetFocus,hEdit
        .else
            invoke CallWindowProc,OldTxtOnlyEditBoxProc,hEdit,uMsg,wParam,lParam
            ret
        .endif
    .else
        invoke CallWindowProc,OldTxtOnlyEditBoxProc,hEdit,uMsg,wParam,lParam
        ret
    .endif
    xor eax,eax
    ret
TxtOnlyEditBoxProc endp         


hfheatherfox07

Thank you!
I thought I can get away with no subclassing ,
I was hoping lol

Thank again :)
Your code and your skills will be assimilated. Your programming language is irrelevant.
We are the ASM Borg and you will become part of us. Compile and be assembled.

hutch--

The action is to use a simple subclass so you can process the character messages and either allow or disallow the characters you want or don't want. All you need to do is specify the ASCII character range(s) you want and exclude the rest. If you wanted to allow everything except numbers, you would throw away the ASCII number range and allow the rest.

Have a look at this example. >>>> \masm32\examples\exampl01\filtinpt

hfheatherfox07

lol
Example one and I missed it !  :icon_redface:
When I download a new version of masm32 I always look at the example for new ones
Whoops ....
Thank you hutch !
That sounds good
:biggrin:
Your code and your skills will be assimilated. Your programming language is irrelevant.
We are the ASM Borg and you will become part of us. Compile and be assembled.

dedndave


MichaelW

This is a more or less stupid solution, and it took more code than I thought it would, but I was curious if it could be made to work. Basically, it depends on an invisible ES_NUMBER edit control to detect decimal digit inputs, and bypasses further processing of the input.

;==============================================================================
    include \masm32\include\masm32rt.inc
;==============================================================================
;-----------------------------------------------------------------
; Same as MASM32 DlgEdit macro, but without the WS_VISIBLE style.
;-----------------------------------------------------------------
DlgEdit_ MACRO dstyle,tx,ty,wd,ht,ctlID
  align_4 edi
  mov DWORD PTR [edi+0],  WS_CHILD or dstyle
  mov WORD  PTR [edi+8],  tx
  mov WORD  PTR [edi+10], ty
  mov WORD  PTR [edi+12], wd
  mov WORD  PTR [edi+14], ht
  mov WORD  PTR [edi+16], ctlID
  mov WORD  PTR [edi+18], 0FFFFh
  mov WORD  PTR [edi+20], 0081h   ;; edit control
  add edi, 26
ENDM
;==============================================================================
loword MACRO arg
    IFNDEF __loword_macro_return_var__
      .data
        __loword_macro_return_var__ dd 0
      .code
    ENDIF
    push arg
    pop __loword_macro_return_var__
    and __loword_macro_return_var__, 0ffffh
    EXITM <__loword_macro_return_var__>
ENDM
hiword MACRO arg
    IFNDEF __hiword_macro_return_var__
      .data
        __hiword_macro_return_var__ dd 0
      .code
    ENDIF
    push arg
    pop __hiword_macro_return_var__
    shr __hiword_macro_return_var__, 16
    EXITM <__hiword_macro_return_var__>
ENDM
;==============================================================================
IDC_EDIT_NON equ 1000
IDC_EDIT_NUM equ 1001
;==============================================================================
    .data
      hWnd        HWND  0
      hwndEditNon HWND  0
      hwndEditNum HWND  0
      en_change   dd    0
      msg         MSG   <>
    .code
;==============================================================================
DlgProc proc hwndDlg:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
    SWITCH uMsg
        CASE WM_INITDIALOG
            invoke GetDlgItem, hwndDlg, IDC_EDIT_NON
            mov hwndEditNon, eax
            invoke GetDlgItem, hwndDlg, IDC_EDIT_NUM
            mov hwndEditNum, eax
        CASE WM_COMMAND
            SWITCH hiword( wParam )
                CASE EN_CHANGE
                    ;-----------------------------------------------------
                    ; Set en_change flag for ES_NUMBER edit control only.
                    ;-----------------------------------------------------
                    .IF loword( wParam ) == IDC_EDIT_NUM
                        mov en_change, 1
                    .ENDIF
                CASE BN_CLICKED
                    .IF loword( wParam ) == IDCANCEL
                        invoke DestroyWindow, hwndDlg
                    .ENDIF
            ENDSW
        CASE WM_CLOSE
            invoke DestroyWindow, hwndDlg
        CASE WM_DESTROY
            invoke PostQuitMessage, 0
    ENDSW
    return 0
DlgProc endp
;==============================================================================
start:
;==============================================================================
    Dialog "test_window", \
           "MS Sans Serif",10, \
           WS_VISIBLE or WS_OVERLAPPED or WS_SYSMENU or DS_CENTER, \
           2,0,0,150,140,1024
    DlgEdit_ WS_BORDER or ES_MULTILINE or WS_VSCROLL or WS_HSCROLL or \
             ES_AUTOVSCROLL or ES_AUTOHSCROLL or ES_NUMBER, \
             10,10,126,100,IDC_EDIT_NUM
    DlgEdit  WS_BORDER or ES_MULTILINE or WS_VSCROLL or WS_HSCROLL or \
             ES_AUTOVSCROLL or ES_AUTOHSCROLL or ES_WANTRETURN, \
             10,10,126,108,IDC_EDIT_NON
    CallModelessDialog NULL,0,DlgProc,NULL
    mov hWnd, eax
  msgLoop:
    invoke GetMessage, ADDR msg, NULL, 0, 0
    .IF eax != 0
        mov eax, msg.hwnd
        .IF eax == hwndEditNon
            ;------------------------------------------------------------------
            ; For the WM_CHAR messsage, filter out the problem character codes
            ; and send the message to the ES_NUMBER edit control.
            ;------------------------------------------------------------------
            .IF msg.message == WM_CHAR
                .IF msg.wParam != VK_RETURN && \
                    msg.wParam != VK_BACK && \
                    msg.wParam != VK_TAB
                    invoke SendMessage, hwndEditNum, msg.message,
                                        msg.wParam, msg.lParam
                .ENDIF
            .ENDIF
            ;--------------------------------------------------------------
            ; If the sent message triggered an EN_CHANGE notification from
            ; the ES_NUMBER edit control, clear the en_change flag and
            ; bypass further processing of the current message, effectively
            ; discarding it.
            ;--------------------------------------------------------------
            .IF en_change
                mov en_change, 0
                jmp msgLoop
            .ENDIF
            ;--------------------------------------------------------------
            ; And while we are filtering messages:
            ;
            ; A multi-line edit control responds to the tab key by doing a
            ; select all, instead of doing what most people would expect.
            ; To modify this behavior, without having to subclass the edit
            ; control, we intercept the tab key in the message loop, get
            ; the current insertion point, kill any existing selection (by
            ; selecting a zero-length range at the insertion point), and
            ; insert a tab character, then bypass further processing of
            ; the message.
            ;--------------------------------------------------------------
            .IF msg.message == WM_KEYDOWN && msg.wParam == VK_TAB
                push eax
                mov eax, esp
                invoke SendMessage, hwndEditNon, EM_GETSEL, eax, 0
                pop eax
                invoke SendMessage, hwndEditNon, EM_SETSEL, eax, eax
                invoke SendMessage, hwndEditNon, EM_REPLACESEL, 0, chr$(VK_TAB)
                jmp msgLoop
            .ENDIF
        .ELSEIF eax == hwndEditNum
            ;---------------------------------------------------
            ; Bypass all other ES_NUMBER edit control messages.
            ;---------------------------------------------------
            jmp msgLoop
        .ENDIF
        invoke IsDialogMessage, hWnd, ADDR msg
        jmp msgLoop
    .ENDIF
    exit
;==============================================================================
end start


Well Microsoft, here's another nice mess you've gotten us into.

hfheatherfox07

Your code and your skills will be assimilated. Your programming language is irrelevant.
We are the ASM Borg and you will become part of us. Compile and be assembled.

hutch--

ere is a test piece with a subclassed edit control that excludes numbers.