Question

I have a little problem. I want to have an Edit control in which is a text (something like this: "ABC@") . This string must be non editable so that the user shouldn't be able to delete it. The user should be able to type a text after the sign '@' only. I know how to make text readonly in editbox. I use EM_SETREADONLY message

//global variables
 #define ID_TEXTBOX 1
 static HWND hwndTextBox;

//in WndProc function
  case WM_CREATE:
    {

      hwndTextBox = CreateWindow(TEXT("EDIT"),TEXT("abc@"),WS_VISIBLE | WS_CHILD | WS_BORDER   ,70,100, 200,25,hWnd,(HMENU)ID_TEXTBOX,NULL,NULL);

      if(!hwndTextBox )
        {
            MessageBox(hWnd,"Failed","Failed",MB_OK);
            return FALSE;
        }

      SendMessage(hwndTextBox,EM_SETREADONLY,TRUE ,NULL);

      break;

    }

but the code makes whole text readonly and of course does not solve my problem.

Was it helpful?

Solution

Use a RichEdit control instead of an Edit control. Use the EM_SETCHARFORMAT message to mark individual characters, or ranges of characters, as "protected". Use the EM_SETEVENTMASK message to register for EN_PROTECTED notifications from the RichEdit. That way, if a user tries to modify one or more protected characters for any reason, the RichEdit will ask for your permission before allowing the modification.

OTHER TIPS

This is probably not what you're looking for, but it may mimic the required functionality with just a bit of code overhead.

You can subclass the edit control and then through WM_CHAR message capture any of the user input that may modify the edit box contents. Once the message is received by your procedure, you detect the current selection (that is the caret position) in the edit box and if it's anywhere inside the first four characters you simply don't allow the change. This is a bit crude method, but it should work.

Example in assembly, sorry I'm not proficient enough in C and C is such a drag :D

    invoke SetWindowLong,hEditBox,GWL_WNDPROC,offset EditProc
    mov DefEditProc,eax
    ...

EditProc proc hWnd:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
    cmp uMsg,WM_CHAR
    je @WM_CHAR
    cmp uMsg,WM_KEYUP
    je @WM_KEYUP

@DEFAULT:
    invoke CallWindowProc,DefEditProc,hWnd,uMsg,wParam,lParam 
    ret
@EXIT:
    xor eax,eax
    ret

;=============
@WM_KEYUP:
    mov eax,wParam          ; you will need this if you want to process the delete key
    cmp ax,VK_DELETE
    je @VK_DELETE
    jmp @DEFAULT

;=============
@WM_CHAR:
    mov eax,wParam
    cmp ax,VK_BACK          ; this is for the backspace key
    je @BACKSPACE
    cmp ax,VK_0
    jb @EXIT                ; if null is returned, the char will not be passed to the edit box
    cmp ax,VK_9
    ja @EXIT
    jmp @NUMBER

;---
@VK_DELETE:
@NUMBER:
    invoke SendMessage,hWnd,EM_GETSEL,offset start,0        ; the caret position through text selection, we just need the starting position
    cmp start,3
    ja @DEFAULT     ; if the caret is placed somewhere past the 4th charater, allow user input
    jmp @EXIT

;---    
@BACKSPACE:
    invoke SendMessage,hWnd,EM_GETSEL,offset start,0
    cmp start,4
    ja @DEFAULT     ; since you're deleting one character to the left, you need to factor that in for backspace
    jmp @EXIT

EditProc endp

It's very cut, you hopefully get the gist of it. This example only allows the digits (0-9), the DEL and BACKSPACE keys through. You can expand to meet your needs.

Regards

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top