Win32 插入符光标跟随的打字小程序

1.先创建插入符光标

在WM_CREATE消息中

LRESULT OnCreate(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
    
    HDC hdc = GetDC(hWnd);
    //获取字体信息
TEXTMETRIC txtInfo; GetTextMetrics(hdc, &txtInfo);
//创建插入符
CreateCaret(hWnd, NULL, txtInfo.tmAveCharWidth/8, txtInfo.tmHeight);
    //显示插入符
    ShowCaret(hWnd);

    ReleaseDC(hWnd, hdc);
    return LRESULT();
}

2.定义两个全局变量

//全局变量
POINT g_point = { 0 };//保存鼠标点下的点的位置
CString g_string;        //保存输入的字符串

3.在鼠标按下消息中.WM_LBUTTONDOWN

LRESULT OnLButtonDown(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
       //获取鼠标点下时的点的坐标
    POINT pt;
    pt.x = GET_X_LPARAM(lParam);
    pt.y = GET_Y_LPARAM(lParam);
        //设置插入符的位置
    SetCaretPos(pt.x,pt.y);
        //把点的坐标保存到全局变量中
    g_point = pt;
        //清空字符串
    g_string.Empty();

    return LRESULT();
}

 

3.在键盘消息WM_CHAR中处理字符绘制和光标跟

LRESULT OnChar(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
    //获得键入的字符
    UINT nChar = (TCHAR)wParam;
    
    HDC hdc = GetDC(hWnd);
    

    if (nChar == VK_RETURN)//换行
    {
        g_string.Empty();    //清空字符串
        TEXTMETRIC txtInfo;
        GetTextMetrics(hdc, &txtInfo);//获取字符的高度
        g_point.y = g_point.y + txtInfo.tmHeight;//设置插入符Y坐标的位置
    }
    else if (nChar == VK_BACK)//退格
    {
        //获取背景色
        COLORREF color = GetBkColor(hdc);
        //设置文本颜色
        COLORREF oldColor = SetTextColor(hdc, color);
        //用背景色擦除字符串
        TextOut(hdc, g_point.x, g_point.y, g_string, g_string.GetLength());
        //去掉最后一个字符
        g_string = g_string.Left(g_string.GetLength() - 1);
        //重新设置文本颜色为原来的颜色
        SetTextColor(hdc, oldColor);
    }
    else
    {
        g_string += (TCHAR)nChar;//键入的字符累加到字符串中
    }

    //获得字符串的像素宽度与高度
    SIZE size = { 0 };
    GetTextExtentPoint32(hdc, g_string, g_string.GetLength(), &size);

    int x = g_point.x + size.cx;
    int y = g_point.y;
    SetCaretPos(x, y);//重新设置光标位置

    //绘制字符串到窗口上
    TextOut(hdc,g_point.x, g_point.y, g_string,g_string.GetLength());

    ReleaseDC(hWnd, hdc);
    return LRESULT();
}

 

 

目前就先学到这里,以后有时间再进一步的去学习.

 

程序源码:

#include<windows.h>
#include <windowsx.h> //这是要用GET_X_LPARAM,GET_Y_LPARAM宏
#include <atlstr.h>  //字符串类CString

//全局变量
POINT g_point = { 0 };
CString g_string;

//函数的前置声明
LRESULT CALLBACK lpWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
LRESULT OnCreate(HWND hWnd, WPARAM wParam, LPARAM lParam);     //WM_CREATE
LRESULT OnLButtonDown(HWND hWnd, WPARAM wParam, LPARAM lParam);//WM_LBUTTONDOWN
LRESULT OnChar(HWND hWnd, WPARAM wParam, LPARAM lParam);       //WM_CHAR

int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, 
    _In_ LPSTR lpCmdLine, _In_ int nShowCmd)
{
    //设计窗口类
    TCHAR className[] = TEXT("myClass");//窗口类名称

    //填充窗口类结构体
    WNDCLASSEX wndClass = { 0 };
    wndClass.cbSize = sizeof(WNDCLASSEX);
    //判断是否是系统注册了的类
    if (!GetClassInfoEx(hInstance, className, &wndClass))
    {
        wndClass.cbClsExtra = 0;
        wndClass.cbWndExtra = 0;
        wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
        wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
        wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
        wndClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
        wndClass.hInstance = hInstance;
        wndClass.lpfnWndProc = lpWindowProc;
        wndClass.lpszClassName = className;
        wndClass.lpszMenuName = NULL;
        wndClass.style = CS_VREDRAW | CS_HREDRAW;

        //注册窗口类
        if (!RegisterClassEx(&wndClass))
        {
            return 1;
        }
    }

    //创建窗口
    HWND hwnd = ::CreateWindowEx(0,className, TEXT("我的窗口"), 
WS_OVERLAPPEDWINDOW,
100, 100, 600, 400, NULL, NULL, hInstance, 0);

if (!hwnd) {
return 1;
}

//显示并更新窗口
::ShowWindow(hwnd, nShowCmd); ::UpdateWindow(hwnd);

//消息循环 MSG msg;

while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(
&msg);
DispatchMessage(
&msg);
}
    //销毁插入符
DestroyCaret();
return msg.lParam; } LRESULT CALLBACK lpWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_DESTROY: PostQuitMessage(0); break; case WM_CREATE: return OnCreate( hWnd,wParam, lParam); case WM_LBUTTONDOWN: return OnLButtonDown(hWnd, wParam, lParam); case WM_CHAR: return OnChar(hWnd, wParam, lParam); } return DefWindowProc(hWnd, uMsg, wParam, lParam); } LRESULT OnCreate(HWND hWnd, WPARAM wParam, LPARAM lParam) { //获取字体信息 HDC hdc = GetDC(hWnd); TEXTMETRIC txtInfo; GetTextMetrics(hdc, &txtInfo); //创建插入符 CreateCaret(hWnd, NULL, txtInfo.tmAveCharWidth/8, txtInfo.tmHeight); ShowCaret(hWnd); ReleaseDC(hWnd, hdc); return LRESULT(); } LRESULT OnLButtonDown(HWND hWnd, WPARAM wParam, LPARAM lParam) { POINT pt; pt.x = GET_X_LPARAM(lParam); pt.y = GET_Y_LPARAM(lParam); SetCaretPos(pt.x,pt.y);//设置插入符位置 g_point = pt; g_string.Empty(); return LRESULT(); } LRESULT OnChar(HWND hWnd, WPARAM wParam, LPARAM lParam) { //获得键入的字符 UINT nChar = (TCHAR)wParam; HDC hdc = GetDC(hWnd); if (nChar == VK_RETURN)//换行 { g_string.Empty(); //清空字符串 TEXTMETRIC txtInfo; GetTextMetrics(hdc, &txtInfo);//获取字符的高度 g_point.y = g_point.y + txtInfo.tmHeight;//设置插入符Y坐标的位置 } else if (nChar == VK_BACK)//退格 { //获取背景色 COLORREF color = GetBkColor(hdc); //设置文本颜色 COLORREF oldColor = SetTextColor(hdc, color); //用背景色擦除字符串 TextOut(hdc, g_point.x, g_point.y, g_string, g_string.GetLength()); //去掉最后一个字符 g_string = g_string.Left(g_string.GetLength() - 1); //重新设置文本颜色为原来的颜色 SetTextColor(hdc, oldColor); } else { g_string += (TCHAR)nChar;//键入的字符累加到字符串中 } //获得字符串的像素宽度与高度 SIZE size = { 0 }; GetTextExtentPoint32(hdc, g_string, g_string.GetLength(), &size); int x = g_point.x + size.cx; int y = g_point.y; SetCaretPos(x, y);//重新设置光标位置 //绘制字符串到窗口上 TextOut(hdc,g_point.x, g_point.y, g_string,g_string.GetLength()); ReleaseDC(hWnd, hdc); return LRESULT(); }

 

posted @ 2021-05-31 18:38  初吻给了烟灬  阅读(253)  评论(0)    收藏  举报