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> ...
随机推荐
- 基于Python和TensorFlow实现BERT模型应用
本文分享自华为云社区<使用Python实现深度学习模型:BERT模型教程>,作者: Echo_Wish. BERT(Bidirectional Encoder Representation ...
- 前端 Array.sort() 源码学习
源码地址 V8源码Array 710行开始为sort()相关 Array.sort()方法是那种排序呢? 去看源码主要是源于这个问题 // In-place QuickSort algorithm. ...
- 【进阶篇】Java 项目中对使用递归的理解分享
[进阶篇]Java 项目中对使用递归的理解分享 目录 [进阶篇]Java 项目中对使用递归的理解分享 前言 一.什么是递归 1.1基本概念 1.2优缺点 1.3与迭代的区别 二.实际案例 三.改进方案 ...
- test20230824总结
A 怎么是重构树板子,放在图上都是水题. B 考场上只打了一个暴力,赛后发现似乎是很可做的 C 是一个考察状态设计的 dp 以后要多刷 D 是一道数据结构优化 dp 考场上写出来了却因为空间问题挂了 ...
- 用python处理html代码的转义与还原-转
本篇博客来源: 用python处理html代码的转义与还原 'tag>aaa</tag> # 转义还原 str_out = html.unescape(str_out) print( ...
- 为什么springboot推荐使用Thymeleaf?
前端那么多好的框架 为什么springboot推荐使用Thymeleaf? 前端框架和模板引擎不是一种东西: 模板引擎:Thymeleaf.freemarker.JSP. 前端框架:vue.angul ...
- ROS2开发BUG记录:在将 use_sim_timer 置为 true 时,节点的 Timer_Callback 行为“异常”
问题: 在将 use_sim_timer 置为 true 时,节点 Timer_Callback 行为 "异常" .在回调函数中,使用 self.get_logger().info ...
- rem适配布局
没有一张图解决不了的事 https://www.processon.com/mindmap/5e3a589be4b021dc2899f511 <link rel="stylesheet ...
- Mybatis XXXMapper.xml映射文件配置
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "- ...
- 小产品,快变现,Solo社区共建者 James 专访
采访人:徐小夕. 本次受邀采访的嘉宾是Solo社区计划负责人&Solo社区联合创建者 James Pan(老潘). 专访内容 1. Solo社区创建的背景 随着国内软件市场内卷加剧,加上大环境 ...