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> ...
随机推荐
- 实验7.Vlan划分实验
# 实验7.Vlan划分实验 本实验用于划分Vlan,并对划分的Vlan做隔离测试. 实验组 拓扑 Vlan隔离配置 在配置vlan前,测试PC1234互通 具体配置vlan 这里给出其中一台交换机的 ...
- Xilinx-HDF的文件内容
Xilinx-HDF文件 原文:分享:HDF文件的更多用途 Xilnx Vivado能导出HDF文件,给Xilnx SDK创建软件工程.HDF文件的还可以有更多用途. HDF文件是一个zip文件,可以 ...
- Freertos学习:08-信号量
--- title: rtos-freertos-08-ipc-semaphore date: 2020-06-23 11:01:12 categories: tags: - freertos - i ...
- 【workerman】uniapp+thinkPHP5使用GatewayWorker实现实时通讯
前言 之前公司需要一个内部的通讯软件,就叫我做一个.通讯软件嘛,就离不开通讯了,然后我就想到了长连接.这里本人用的是GatewayWorker框架. 什么是GatewayWorker框架? Gatew ...
- vue3 'alex' is defined but never used
解决方法 在package.json中的rules下加入 "no-unused-vars":"off" 即可
- 算法金 | 来了,pandas 2.0
大侠幸会,在下全网同名「算法金」 0 基础转 AI 上岸,多个算法赛 Top 「日更万日,让更多人享受智能乐趣」 今日 210+/10000,内含 Pandas 是一个强大的数据分析库,广泛应用于科学 ...
- 2024-07-27:用go语言,给定一个正整数数组,最开始可以对数组中的元素进行增加操作,每个元素最多加1。 然后从修改后的数组中选出一个或多个元素,使得这些元素排序后是连续的。 要求找出最多可以选
2024-07-27:用go语言,给定一个正整数数组,最开始可以对数组中的元素进行增加操作,每个元素最多加1. 然后从修改后的数组中选出一个或多个元素,使得这些元素排序后是连续的. 要求找出最多可以选 ...
- python与c/java的异
1.注释 #为单行注释 """ 这里是多行注释 """ ''' 这个也可以是多行注释 ''' 2.赋值 在python中赋值不需要特定变量的 ...
- NPIO在指定位置插入新列(附案例和代码)
背景: I could be mistaken as I am not that familiar with NPOI, however, after a minor search, it appea ...
- idea2020修改help的vm options之后导致idea打不开的问题
如图所示,如果你修改了VM参数,导致启动没反应,证明你的参数配置有误. 这个时候你可能会想着直接修改idea安装目录bin中的配置文件,但是这个文件并不是你在idea中修改的配置文件,所以你修改这里的 ...