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();
}
Win32 插入符光标跟随的打字小程序的更多相关文章
- [转]wxParse-微信小程序富文本解析组件
本文转自:https://github.com/icindy/wxParse 基本使用方法 Copy文件夹wxParse - wxParse/ -wxParse.js(必须存在) -html2json ...
- 【Windows编程】系列第十篇:文本插入符
大家知道,在使用微软的编程环境创建工程时会让你选择是控制台模式还是Windows应用程序.如果选择控制台的console模式,就会在运行时出现一个黑洞洞的字符模式窗口,里面就有等待输入一闪一闪的插入符 ...
- 小程序实现sql插入语句转换成Laravel迁移语句
sql的插入语句长这样: INSERT INTO `media` (`MediaID`, `type`, `filename`, `title`) VALUES (1, 'word', 'word1. ...
- 关于bootstrap--排版(标题、强调、背景、插入符等)
1. 2.标题:<h1>这是主标题<small>这是副标题,为当前字号65%,灰色(#999)</small></h1>. 3.段落:<p> ...
- 微信小程序tab切换,可滑动切换,导航栏跟随滚动实现
简介 看到今日头条小程序页面可以滑动切换,而且tab导航条也会跟着滚动,点击tab导航,页面滑动,切导航栏也会跟着滚动,就想着要怎么实现这个功能 像商城类商品类目如果做成左右滑动切换类目用户体验应该会 ...
- 微信小程序input组件抖动及textarea组件光标错位解决方案
问题一: 使用微信小程序input组件时,在移动端唤起focus或blur事件时,因光标占位导致内容出现叠影及抖动现象. 解决方案: 用<textarea>组件代替了<input/& ...
- MFC中插入符的生成
响应WM_CREATE消息的代码如下: int CTextView::OnCreate(LPCREATESTRUCT lpCreateStruct) { ) ; // 插入符在窗口重绘的过程中不会消失 ...
- 小程序插入html代码
转自:https://blog.csdn.net/BetterGG/article/details/81027291 一.首先,html 分 2 种情况: 1.我在做详情页开发的时候发现获取到的数据是 ...
- 插入符的创建(MFC)
int CDrawRectangleDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) { ) ; // TODO: 在此添加您专用的创建代码 CreateSol ...
- 吴裕雄 Bootstrap 前端框架开发——Bootstrap 辅助类:插入符
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
随机推荐
- CLR via C# 笔记 -- 可空值类型(19)
1. 值类型的变量永远不会为null,所有需要使用System.Nullable<T> 2. 操作数是null,结构是null:==.!=操作数都为null,则返回true:<.&g ...
- 让matplotlib在绘图时显示中文
让matplotlib绘图时显示中文. 安装中文字体 apt install fonts-wqy-microhei 清除matplotlib的缓存 rm -rf ~/.cache/matplot ...
- 【ClickHouse】4:clickhouse基本操作二 建库建表导数据
背景介绍: 有三台CentOS7服务器安装了ClickHouse HostName IP 安装程序 程序端口 centf8118.sharding1.db 192.168.81.18 clickhou ...
- JVM(Java虚拟机) 整理(一):基础理论
JVM整体结构 本文主要说的是HotSpot虚拟机, JVM 全称是 Java Virtual Machine,中文译名:Java虚拟机 简化一下: Java字节码文件 Class文件本质上是一个以8 ...
- P3749 题解
既然是求最大值而且有收益有代价,所以考虑建立一个最大权封闭子图模型. 收益 正的美味值是收益,所以假若 \(d_{i,j} \geq 0\) 则建边 \((s,pos_{i,j},d_{i,j})\) ...
- FFmpeg开发笔记(三十八)APP如何访问SRS推流的RTMP直播地址
<FFmpeg开发实战:从零基础到短视频上线>一书在第10章介绍了轻量级流媒体服务器MediaMTX,通过该工具可以测试RTSP/RTMP等流媒体协议的推拉流.不过MediaMTX的功能 ...
- 9. 嵌套的 CMake
9. 嵌套的 CMake 如果项目很大,或者项目中有很多的源码目录,在通过 CMake 管理项目的时候如果只使用一个 CMakeLists.txt ,那么这个文件相对会比较复杂,有一种化繁为简的方式就 ...
- 移动web开发适配秘籍Rem
目录 移动web开发的特点 Rem 布局适配原理 Media Query(媒体查询) scss 工程使用函数计算 JS动态获取屏幕的宽度 直接将html 的 font-size 设置成 100px 移 ...
- linux系统是未来_大小写敏感_case_sensitive_编程原生态
修改 py 文件 回忆上次内容 上次尝试了 两个vim 同时打开 同一py文件 vim出现了Error 有各种选择 错误拼写 pront 导致 运行时 出现了NameError ...
- 使用后台模板,cnpm install报错