WinApi - 在编辑控件中将文本的一部分设置为不可编辑(半只读取编辑框)

时间:2012-12-14 07:31:56

标签: winapi editcontrol

我有点问题。我想要一个Edit控件,其中包含一个文本(类似于:“ABC @”)。此字符串必须是不可编辑的,以便用户不能删除它。用户应该只能在符号“@”后键入文本。我知道如何在编辑框中只读取文本。我使用EM_SETREADONLY消息

//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;

    }

但代码使整个文本只读,当然不能解决我的问题。

2 个答案:

答案 0 :(得分:2)

这可能不是您正在寻找的,但它可能只需要一点代码开销即可模仿所需的功能。

您可以对编辑控件进行子类化,然后通过WM_CHAR消息捕获可能修改编辑框内容的任何用户输入。一旦您的程序收到消息,您就会在编辑框中检测到当前选择(即插入位置),如果它在前四个字符内的任何位置,则您根本不允许更改。这有点粗糙,但它应该有效。

汇编中的示例,对不起我对C和C的熟练程度不够,这是一个拖累: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

它很受欢迎,你希望得到它的要点。此示例仅允许数字(0-9),DEL和BACKSPACE键通过。您可以扩展以满足您的需求。

此致

答案 1 :(得分:2)

使用RichEdit控件而不是Edit控件。使用EM_SETCHARFORMAT消息将单个字符或字符范围标记为“受保护”。使用EM_SETEVENTMASK消息注册RichEdit的EN_PROTECTED通知。这样,如果用户出于任何原因尝试修改一个或多个受保护的字符,RichEdit将在允许修改之前请求您的许可。