win32直接在窗口中输入文字,将窗口当做编辑框

7879 人浏览 | 时间: 2016-01-04 13:53:41 | 作者: codexia 会员文章,禁止转载

    窗口就是一个平板一样,感觉只能画东西,然而我突然想直接在上面打字,将窗口当做编辑框一样使用,一下子就蒙了。那么编辑框要具备什么条件呢?百度一查,没有资料,懒得仔细查了。
    好吧,自己想或许还要快些。我想,输入文字,不就是要响应WM_CHAR消息嘛,然后将这个字符存入字符数组即可。如果要删除字符,自然就是将对应数组元素删除。不过为了简单,现在只支持退格键删除字符,即删除最后一个字符。

    实现的程序效果如下图所示:

直接在窗口中输入文字,将窗口当做编辑框,可以用退格键删除输入的文字

【直接在窗口中输入文字,将窗口当做编辑框,可以用退格键删除输入的文字】
    其实上面这一段的思路,大家都会有。问题是,如何让输入法可以将输入的文字放到我们的窗口上。实际上,这个问题看似复杂,实则很简单。或许你看书的时候,并没有领会到输入焦点的问题。只要你的窗口有焦点,键盘的输入的消息就以WM_CHAR消息的形式放入了你的程序的消息队列里,你就可以处理WM_CHAR得到输入的字符。而输入法怎么样,与你的程序无关。
    所以,这个看似问题的地方其实不是你要考虑的问题。你只管处理你的WM_CHAR或者直接处理WM_KEYDOWN消息即可。所以也就是前面说的处理WM_CHAR消息的逻辑了。
    要存储输入的文字,我们定义一个比较大的数组,并初始化为空字符串,代码如下:
TCHAR txt[1024]=_T("");
    然后每次输入,都将输入的字符存入字符串最后一个字符后面的一个元素即可。那么这个位置就可以由获取字符串字符个数的函数lstrlen来完成。我们开始初始化为空字符,也就是有意将字符数组全部元素设置为0,这样不管我们将字符输入到哪里,都是有空字符结尾的。
    将给一个输入的字符存入字符数组的代码如下:
txt[lstrlen(txt)]=ch;
    为了支持退格键删除字符,我们直接判断退格键字符的编码8(十进制),如果获取的字符编码为8,就表示输入了退格键,表示用户想删掉最后一个字符。所以此时不要将这个退格键字符存入数组,而是要将字符数组最后一个字符设置为空字符,一来可以删除这个字符,而来也将字符串的结尾设置正确。
txt[lstrlen(txt)-1]=_T('');
    记得要将字符串的字数减一之后当做最后一个字符的索引,因为C/C++中,字符数组是以0开始编号索引的。
    注意,这里的赋值是单引号,不是双引号。我们在VS中使用的中性字符来处理,所有都加入了_T宏包含字符或者字符串。
    删除字符串中的字符的实现方法,可以参考《win32使用退格键BackSpace从后到前的删除字符串的字符》,文章里有更加详细的说明和额外的方法分析。
#include "windows.h"
#include <tchar.h>
TCHAR cjjjs[100]=_T("【C++技术网http:www.cjjjs.com】请直接输入文字");
TCHAR txt[1024]=_T("");
LRESULT CALLBACK WinProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
    HDC hdc;
    PAINTSTRUCT ps;
    switch (message)
    {
    case WM_PAINT:
        hdc = BeginPaint(hwnd,&ps);
        SelectObject(hdc,GetStockObject(SYSTEM_FIXED_FONT));
        TextOut(hdc,0,100,cjjjs,lstrlen(cjjjs));
        TextOut(hdc,0,0,txt,lstrlen(txt));
        EndPaint(hwnd,&ps);
        return 0;
     case WM_CHAR:
         {
             TCHAR ch=(TCHAR)wParam;            
             if (ch==8)
             {
                 txt[lstrlen(txt)-1]=_T('');
             }
             else
             {
                 txt[lstrlen(txt)]=ch;
             }
         }
        InvalidateRect(hwnd,NULL,TRUE);//刷新显示结果
        return 0;
     case WM_RBUTTONDOWN:
         {
             txt[0]=_T('');
            InvalidateRect(hwnd,NULL,TRUE);
         }
         return 0;
     case WM_DESTROY:
         PostQuitMessage(0); 
         return 0;
     default:
         return DefWindowProc(hwnd, message, wParam, lParam);
    }
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrev,LPSTR lpCmd,int iShow)
{
    TCHAR ClassName[] = _T("MyClass");
    TCHAR title1[] = _T("C++技术网http://www.cjjjs.com");
    WNDCLASS wndClass;
    wndClass.cbClsExtra=0;
    wndClass.cbWndExtra=0;
    wndClass.hbrBackground= (HBRUSH)GetStockObject(WHITE_BRUSH);
    wndClass.hCursor=LoadCursor(NULL,IDC_HAND);
    wndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
    wndClass.hInstance = hInstance;
    wndClass.lpfnWndProc = WinProc;
    wndClass.lpszClassName = ClassName;
    wndClass.lpszMenuName=NULL;
    wndClass.style=CS_HREDRAW|CS_VREDRAW;

    if(!RegisterClass(&wndClass))return 0;
    HWND hwnd = CreateWindow(ClassName,title1,WS_OVERLAPPEDWINDOW,0,0,650,400,NULL,NULL,hInstance,NULL);
    ShowWindow(hwnd,SW_SHOWNORMAL);

    MSG msg;
    while (GetMessage(&msg,NULL,0,0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}
当前文章为会员文章,请前往[用户中心]开通会员后继续阅读。

相关阅读