文本框创建方法

本文介绍如何在Windows环境下使用API自定义一个文本编辑控件,包括创建控件、绘制字符、处理键盘事件等功能,实现类似文本编辑器的基本操作。

 

第一次写博客,尽量以后写的好一点!

 

#include <windows.h>
static int CreatePosX, CreatePosY;//插入符的位置
static int nCaretOffsetY;//y的位置
static TCHAR *pCharMath;//字符缓冲区
static TEXTMETRIC tm;//字体的信息,比如字体的高和宽
static int nCharWide, nCharHigh;//字符的宽度和高度
static int nTVWide, nTVHigh;//窗口的宽度和高度
static int nCharLine, nCharRow;//每行每列字符的数目
#define BUFFER(x,y) *(pCharMath+y*nCharLine+x)//二维数组的某一位置
static LRESULT CALLBACK DrawProc(HWND, UINT, WPARAM, LPARAM);//消息处理函数声明
static HWND DrawEdit(HWND hwnd, int x, int y, int wide, int High, int id)
{
    HWND Hwnd;
    WNDCLASS DrawEdits;
    HINSTANCE hInst = GetModuleHandle(NULL);
    DrawEdits.cbClsExtra = 0;
    DrawEdits.cbWndExtra = 0;
    DrawEdits.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    DrawEdits.hCursor = LoadCursor(NULL, IDC_IBEAM);
    DrawEdits.hIcon = LoadIcon(NULL, IDI_ERROR);
    DrawEdits.hInstance = hInst;
    DrawEdits.lpfnWndProc = DrawProc;
    DrawEdits.lpszClassName = TEXT("文本框");
    DrawEdits.lpszMenuName = NULL;
    DrawEdits.style = CS_HREDRAW | CS_VREDRAW;
    if (!RegisterClass(&DrawEdits))
    {
        MessageBox(NULL, TEXT("注册失败"), TEXT("警告"), MB_OK);
        return 0;
    }
    Hwnd = CreateWindow(TEXT("文本框"), NULL, WS_CHILD | WS_VISIBLE, x, y, wide, High, hwnd, NULL, hInst, NULL);
    return Hwnd;
}
static void DrawChar(HDC hDC, int x, int y, TCHAR *str, int num)
{
    RECT rect;
    SelectObject(hDC, GetStockObject(SYSTEM_FIXED_FONT));
    SetTextColor(hDC, RGB(255, 0, 0));//设置字体颜色
    SetBkMode(hDC, TRANSPARENT);
    rect.left = x;
    rect.top = y;
    rect.right = x + num * nCharWide;
    rect.bottom = y + nCharHigh;
    FillRect(hDC, &rect, (HBRUSH)GetStockObject(BLACK_BRUSH));
    TextOut(hDC, CreatePosX * nCharWide, CreatePosY * nCharHigh,
        &BUFFER(CreatePosX, CreatePosY), nCharLine - CreatePosX);
}
static LRESULT CALLBACK DrawProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    int x, y;//循环变量
    HDC hdc;//设备句柄变量
    switch (msg)
    {
    case WM_CREATE:
        hdc = GetDC(hWnd);//获取设备句柄
        SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));//设置字体的宽度高度(现在是等宽字体SYSTEM_FIXED_FONT)
        GetTextMetrics(hdc, &tm);//获取字体的信息
        ReleaseDC(hWnd, hdc);//释放设备的句柄
        nCharWide = tm.tmAveCharWidth;//字体的宽度
        nCharHigh = tm.tmHeight;//字体的高度
        SetTextColor(hdc, RGB(255, 255, 255));//设置字体颜色
        nCaretOffsetY = 12;//插入符位置偏移
        return 0;
    case WM_SIZE:
        nTVWide = LOWORD(lParam);//窗口宽度
        nCharLine = max(1, nTVWide / nCharWide);//一行可以存多少个字符
        nTVHigh = LOWORD(lParam);//窗口高度
        nCharRow = max(1, nTVHigh / nCharHigh);//一列可以存多少个字符
        if (pCharMath != NULL)//判断字符缓冲区是否有字符,如果有就释放这个缓冲区
        {
            free(pCharMath);//如果有就释放这个缓冲区
        }
        pCharMath = (TCHAR*)malloc(nCharLine*nCharRow);
        if (pCharMath)
        {
            for (x = 0; x < nCharLine; x++)
            {
                for (y = 0; y < nCharRow; y++)
                {
                    BUFFER(x, y) == ' ';//初始化这个二维数组让每个位置都为空格
                }
            }
        }
        SetCaretPos(0, nCaretOffsetY);
        return 0;
    case WM_LBUTTONDOWN:
        SetFocus(hWnd);
        break;
    case WM_KEYDOWN:
        switch (wParam)
        {
        case VK_HOME:
            CreatePosX = 0;
            break;
        case VK_END:
            CreatePosX = nCharLine - 1;
            break;
        case VK_PRIOR:
            CreatePosY = 0;
            break;
        case VK_NEXT:
            CreatePosY = nCharRow - 1;
            break;
        case VK_LEFT:
            CreatePosX = max(CreatePosX - 1, 0);
        case VK_RIGHT:
            CreatePosX = max(CreatePosX + 1, nCharLine - 1);
            break;
        case VK_UP:
            CreatePosY = (CreatePosY , -1);
            break;
        case VK_DOWN:
            CreatePosY = (CreatePosY + 1, nCharRow - 1);
            break;
        case DELETE:
            for (x = CreatePosX; x < nCharLine; x++)
            {
                BUFFER(x, CreatePosY) = BUFFER(x + 1, CreatePosY);
            }
            BUFFER(nCharLine - 1, CreatePosY) = ' ';
            HideCaret(hWnd);
            hdc = GetDC(hWnd);
            DrawChar(hdc, CreatePosX*nCharWide, CreatePosY*nCharHigh, &BUFFER(CreatePosX, CreatePosY), nCharLine - CreatePosX / nCharWide);
            ReleaseDC(hWnd, hdc);
            ShowCaret(hWnd);
            break;
        }
        SetCaretPos(CreatePosX*nCharWide, CreatePosY*nCharHigh + nCaretOffsetY);
        return 0;
    case WM_SHOWWINDOW:
        SetFocus(hWnd);
        break;
    case WM_SETFOCUS:
        CreateCaret(hWnd, NULL, 2, nCharHigh);
        SetCaretPos(CreatePosX*nCharWide, CreatePosY*nCharLine + nCaretOffsetY);
        ShowCaret(hWnd);
        break;
    case WM_KILLFOCUS:
    case WM_DESTROY:
        HideCaret(hWnd);//隐藏插入符
        DestroyCaret();//发送关闭消息
        break;
    case WM_CHAR:
        switch (wParam)
        {
        case 0X08:
            if (CreatePosX > 0)
            {
                CreatePosX--;
                SendMessage(hWnd, WM_KEYDOWN, VK_DELETE, 1L);
            }
            break;
        case 0X09:
            do
            {
                SendMessage(hWnd, WM_CHAR, TEXT(' '), 2L);
            } while (CreatePosX % 4 != 0);
            break;
        case 0X0D:
            CreatePosX = 0;
            if (++CreatePosY == nCharRow)
            {
                CreatePosY = 0;
            }
            break;
        case 0X1B:
        case 0X0A:
            MessageBeep((UINT)-1);
            break;
        default:
            BUFFER(CreatePosX, CreatePosY) = (TCHAR)wParam;
            HideCaret(hWnd);
            hdc = GetDC(hWnd);
            DrawChar(hdc, CreatePosX*nCharWide, CreatePosY*nCharHigh, &BUFFER(CreatePosX, CreatePosY), -1);
            ReleaseDC(hWnd, hdc);
            ShowCaret(hWnd);
            if (++CreatePosX == nCharLine)
            {
                CreatePosX = 0;
                if (++CreatePosY == 0)
                {
                    CreatePosY = 0;
                }
            }
            break;
        }
        SetCaretPos(CreatePosX*nCharWide, CreatePosY*nCharHigh + nCaretOffsetY);
        return 0;
    case WM_PAINT:
    {
                     PAINTSTRUCT ps;
                     hdc = BeginPaint(hWnd, &ps);
                     SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));
                     SetBkMode(hdc, TRANSPARENT);
                     SetTextColor(hdc, RGB(255, 255, 255));
                     for (y = 0; y < nCharLine; y++)
                     {
                         TextOut(hdc, 0, y*nCharHigh, &BUFFER(0, y), nCharLine);
                     }
                     EndPaint(hWnd, &ps);
    }
        return 0;
    default:
        break;
    }
    return DefWindowProc(hWnd, msg, wParam, lParam);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值