news 2026/9/27 16:07:27

C++ 控制台鼠标字符坐标获取:用 windows.h 读取光标位置与 TaoToken 配置骨架

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C++ 控制台鼠标字符坐标获取:用 windows.h 读取光标位置与 TaoToken 配置骨架

1. 控制台里拿到鼠标字符坐标,到底难在哪

如果你写过 Windows 控制台小游戏、终端菜单、字符画编辑器,大概率会遇到同一个问题:鼠标点下去,我想知道它落在第几行第几列,而不是像素坐标。windows.h里其实早就给齐了工具,只是几个 API 拼起来容易踩坑,比如坐标系原点不对、字体尺寸取错、窗口缩放后行列偏移。

这篇就围绕「C++ 控制台鼠标字符坐标获取」这件事,把GetCursorPos、ScreenToClient、GetCurrentConsoleFont三个函数串成一条能直接编译运行的链路,输出鼠标当前所在的字符行列。同时给出一份config.toml骨架,把 TaoToken 的统一 Key / API 通道写进去,方便你后续在这个控制台程序里接 AI 能力,比如让模型根据点击坐标生成内容、做终端里的智能补全。

适合谁看:会一点 C++、用过windows.h、想在控制台里做交互(点击、拾取、菜单)的人;以及想把 AI 调用统一收口到一个配置文件里的开发者。下面所有代码都在 Windows + MinGW / MSVC 下实测可编译,坐标读取部分不依赖任何第三方库。

2. 前置准备:TaoToken 统一 Key 与 API 通道

在写坐标代码之前,先把后面要用的 AI 通道配置好,避免代码写完还要回头补。TaoToken 的作用是把多家模型的调用统一到一个 Key 和一套 API 地址上,你不需要为每个模型单独记 base_url 和鉴权方式。

官网入口在这里,注册和查看文档都从这进:

https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=

API 基地址(代码里填这个,注意不带任何跟踪参数):

https://taotoken.net/api

拿到 Key 的路径是:登录后进控制台,在 API Keys 页面创建一个新 Key。这个 Key 就是后面config.toml里api_key字段的值。相关页面:

模型对话 https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_campaign=rewrite Coding Plan https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_campaign=rewrite 控制台 https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_campaign=rewrite API Keys https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_campaign=rewrite 接入文档 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_campaign=rewrite

注意:Key 只创建一次就够,多个工具共用同一个 Key,靠config.toml里的model字段区分调用哪个模型。不要把 Key 硬编码进.cpp源码,提交到仓库会泄露。

如果你后面要做长期编码或 Agent 类工具,可以看 Coding Plan 那条链接;只是临时验证模型返回,用模型对话页面更直接。接入细节以接入文档为准。

3. 可复制配置:坐标读取代码 + config.toml 骨架

3.1 三个核心 API 的分工

先把原理讲清楚,不然改代码时容易懵。

GetCursorPos(&p)拿到的是鼠标在屏幕上的像素坐标,原点是整个屏幕左上角。这个坐标不能直接用来算字符行列,因为控制台窗口可能不在屏幕左上角。

ScreenToClient(GetForegroundWindow(), &p)把屏幕像素坐标转换成「相对于当前前台窗口客户区」的像素坐标。转换后p.x、p.y就是鼠标在窗口内的像素位置,原点变成窗口客户区左上角。

GetCurrentConsoleFont(GetStdHandle(STD_OUTPUT_HANDLE), FALSE, &a)拿到当前控制台字体信息,其中a.dwFontSize.X是单个字符宽度(像素),a.dwFontSize.Y是单个字符高度(像素)。用客户区像素坐标分别除以这两个值,就得到字符行列。

3.2 最小可运行坐标读取程序

新建mouse_pos.cpp,内容如下:

#include <windows.h> #include <iostream> using namespace std; int main() { POINT p; CONSOLE_FONT_INFO fontInfo; for (;;) { system("cls"); // 1. 获取鼠标屏幕像素坐标 GetCursorPos(&p); // 2. 转换为当前前台窗口客户区像素坐标 ScreenToClient(GetForegroundWindow(), &p); // 3. 获取控制台字体尺寸 GetCurrentConsoleFont( GetStdHandle(STD_OUTPUT_HANDLE), FALSE, &fontInfo ); // 4. 像素坐标 / 字符尺寸 = 字符行列 int col = p.x / fontInfo.dwFontSize.X; int row = p.y / fontInfo.dwFontSize.Y; cout << "字符坐标 -> 列: " << col << " 行: " << row << endl; cout << "像素坐标 -> x: " << p.x << " y: " << p.y << endl; Sleep(100); } return 0; }

编译命令(MinGW 为例):

g++ mouse_pos.cpp -o mouse_pos.exe -lgdi32 -luser32

MSVC 下用:

cl mouse_pos.cpp user32.lib gdi32.lib

运行后移动鼠标,窗口里会实时刷新行列值。这里有个细节:dwFontSize.X和dwFontSize.Y在部分终端下可能返回 0,直接除会崩,所以生产代码里要加保护,见第 5 节排障。

3.3 config.toml 骨架

在项目根目录建config.toml,把 TaoToken 通道写进去。字段设计成后续接 AI 工具时直接读:

# TaoToken 统一接入配置 [taotoken] base_url = "https://taotoken.net/api" api_key = "sk-你的Key填这里" model = "claude-sonnet-4-20250514" timeout_seconds = 60 # 控制台交互相关 [console] refresh_ms = 100 font_width = 8 font_height = 16 enable_click = true

base_url固定填https://taotoken.net/api,不要加尾斜杠。api_key从 API Keys 页面复制。model按你实际要用的模型名填,接入文档里有完整列表。[console]段是给坐标程序读的,refresh_ms控制刷新频率,font_width/height是兜底值,当GetCurrentConsoleFont返回 0 时用它。

读取这个配置的 C++ 片段(不引第三方库,简单解析):

#include <fstream> #include <string> #include <map> map<string, string> loadConfig(const string& path) { map<string, string> cfg; ifstream fin(path); string line; while (getline(fin, line)) { // 跳过注释和空行 if (line.empty() || line[0] == '#' || line[0] == '[') continue; auto pos = line.find('='); if (pos == string::npos) continue; string key = line.substr(0, pos); string val = line.substr(pos + 1); // 去掉首尾空格和引号 auto trim = [](string& s) { size_t a = s.find_first_not_of(" \t\""); size_t b = s.find_last_not_of(" \t\""); if (a == string::npos) { s = ""; return; } s = s.substr(a, b - a + 1); }; trim(key); trim(val); cfg[key] = val; } return cfg; }

调用时auto cfg = loadConfig("config.toml");,然后cfg["base_url"]、cfg["api_key"]就能取到值。这样坐标程序和 AI 调用共用一份配置,改 Key 只改一个文件。

4. 验证请求:编译运行与成功结果

4.1 编译并运行坐标程序

按 3.2 的命令编译,双击或命令行运行mouse_pos.exe。窗口打开后,把鼠标移到控制台窗口内不同位置,观察输出。

成功结果长这样:

字符坐标 -> 列: 12 行: 5 像素坐标 -> x: 96 y: 80 字符坐标 -> 列: 30 行: 10 像素坐标 -> x: 240 y: 160

行列值随鼠标移动连续变化,且鼠标停在同一个字符格内时行列不变,说明换算正确。如果行列跳动很大或始终为 0,看第 5 节。

4.2 验证 TaoToken 通道是否通

配置写好后,用一条 curl 验证 Key 和 base_url 是否可用:

curl https://taotoken.net/api/v1/messages \ -H "Content-Type: application/json" \ -H "x-api-key: sk-你的Key" \ -H "anthropic-version: 2023-06-01" \ -d '{ "model": "claude-sonnet-4-20250514", "max_tokens": 64, "messages": [{"role":"user","content":"回复 OK 两个字母"}] }'

返回里能看到content字段带文本,就说明通道正常。这一步和坐标程序是独立的,先确认通道通,再把 AI 调用接进控制台逻辑,排障时能快速定位是网络问题还是代码问题。

4.3 把坐标和 AI 调用串起来

一个典型用法:鼠标点击控制台某个字符格,把该格坐标发给模型,让模型返回该位置应该显示的内容。核心逻辑:

if (GetAsyncKeyState(VK_LBUTTON) & 0x8000) { int col = p.x / fontInfo.dwFontSize.X; int row = p.y / fontInfo.dwFontSize.Y; // 用 col/row 拼 prompt,走 config.toml 里的 base_url + api_key string prompt = "坐标(" + to_string(col) + "," + to_string(row) + ")处生成一个字符"; // 调用 TaoToken 接口,把返回字符画到该位置 }

GetAsyncKeyState(VK_LBUTTON) & 0x8000判断左键是否按下,配合坐标换算就能做点击拾取。注意点击检测要放在循环里,且和Sleep配合,不然会重复触发。

5. 本篇常见错排查

5.1 行列始终为 0 或除零崩溃

最常见原因是dwFontSize.X或dwFontSize.Y返回 0。某些终端、某些字体设置下GetCurrentConsoleFont拿不到有效尺寸。解决方式是加兜底:

int fw = fontInfo.dwFontSize.X > 0 ? fontInfo.dwFontSize.X : 8; int fh = fontInfo.dwFontSize.Y > 0 ? fontInfo.dwFontSize.Y : 16; int col = p.x / fw; int row = p.y / fh;

8和16就是config.toml里font_width、font_height的默认值,保持一致。

5.2 坐标原点不对,行列整体偏移

ScreenToClient的第二个参数必须是「鼠标所在的那个窗口」的句柄。如果你用GetForegroundWindow()但鼠标其实在另一个窗口上,换算就会偏。更稳的做法是用WindowFromPoint先拿到鼠标下的窗口:

POINT p; GetCursorPos(&p); HWND hwnd = WindowFromPoint(p); ScreenToClient(hwnd, &p);

这样无论鼠标在哪个窗口,坐标都相对该窗口客户区,符合「原点为当前操作窗口」的需求。

5.3 窗口缩放 / DPI 导致行列不准

高 DPI 屏上,系统可能对窗口做缩放,GetCursorPos返回的是物理像素,而字体尺寸是逻辑像素,两者不匹配。在main开头声明 DPI 感知:

SetProcessDPIAware();

或者用清单文件声明dpiAware。加完之后行列换算会一致。如果不想动 DPI,就在config.toml里把font_width/height按实际缩放比例调大。

5.4 config.toml 读不到值

检查三点:文件是否和 exe 同目录(相对路径基于工作目录,不是源码目录);api_key是否带了多余空格或引号(解析函数已去引号,但手写时容易多打空格);base_url是否误加了尾斜杠。用cfg["base_url"]打印出来确认。

5.5 点击重复触发

GetAsyncKeyState在按键持续按下时会一直返回按下状态,导致一次点击触发多次。加一个状态变量记录上次是否已处理:

static bool lastPressed = false; bool nowPressed = (GetAsyncKeyState(VK_LBUTTON) & 0x8000) != 0; if (nowPressed && !lastPressed) { // 只在按下的瞬间处理一次 } lastPressed = nowPressed;

6. 后续接入与配置收口

坐标读取本身不复杂,难的是把它和后续 AI 能力接起来时,Key、base_url、模型名散落在各处。把 TaoToken 通道统一写进config.toml,坐标程序、AI 调用、日志模块都读同一份配置,改一处全生效。

需要 Key 和通道信息时走这几个入口:

API Keys https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_campaign=rewrite 接入文档 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_campaign=rewrite 模型对话 https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_campaign=rewrite Coding Plan https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_campaign=rewrite

排障和接入细节看接入文档,验证模型返回看模型对话,长期编码或 Agent 场景看 Coding Plan。坐标代码先跑通,再把config.toml里的base_url和api_key填上,用 4.2 的 curl 确认通道,最后把点击逻辑和模型调用拼起来。整个过程不需要改坐标换算部分,那三个 API 的组合是稳定的。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/27 16:06:55

网站建设运维情况自查报告避坑速查手册

网站建设运维情况自查报告避坑速查手册 找建站公司最头疼啥?怕被坑高价,怕交付后烂尾,更怕那些看似专业的“运维承诺”全是虚的。很多老板签完合同才发现,所谓的“全托管运维”就是换个马甲收二次服务费,或者网站挂了三天没人管,数据丢了才想起找客服。别急着骂街,今天这份 速查手册…

作者头像 李华
网站建设 2026/9/27 16:06:39

高端网站设计新感觉建站多少钱:改需求不拖一周的避坑指南

高端网站设计新感觉建站多少钱:改需求不拖一周的避坑指南 改个按钮颜色,建站公司拖你整整一周?这种憋屈事儿,做过网站的项目经理肯定没少经历。别急着骂街,先看看合同里那个“需求变更”条款。很多人觉得高端网站设计新感觉建站就是找家大牌公司砸钱,其实真不是。这行水太深, 高端网站设计新感觉建站多少钱…

作者头像 李华
网站建设 2026/9/27 16:06:33

网站建站时间全解析:保姆级教程揭秘从0到1的周期

网站建站时间全解析:保姆级教程揭秘从0到1的周期 域名选好了吗?服务器配置看懂了吗?别急,很多人卡在第一步就懵了。 域名服务器搞不懂 ,建站就像没头苍蝇。这篇 保姆级建站教程 ,直接给你掰扯清楚网站建站时间到底要多久,别被那些“三天上线”忽悠了。 网站建站时间一般要多久? 核心结论:基础展示型网站…

作者头像 李华
网站建设 2026/9/27 16:06:18

营销型网站建设的注意事项最佳实践

营销型网站建设注意事项,选哪家好?避开这5个坑省5万 域名服务器搞不懂,建站就像盲人摸象。很多老板找服务商,一问“哪家好”,对方立刻报出高大上的价格,转头就把你绕晕在“高防IP”和“CDN加速”里。…

作者头像 李华
网站建设 2026/9/27 16:06:12

网站开发岗位就业分析:新手怎么选技术栈避坑

网站开发岗位就业分析:新手怎么选技术栈避坑 改个需求建站公司拖一周,这种憋屈事儿你遇到过没?很多刚入行的朋友,或者正打算从其他行业转行到浙江做网站开发的新手,最头疼的就是这个。看着别人写代码飞起,自己连环境都配不明白,更别提应对甲方的各种奇葩需求了。这时候, 怎么选…

作者头像 李华
网站建设 2026/9/27 16:06:09

企业网站源码怎么获取选哪家好

不懂代码想做企业站?源码获取渠道与多少钱全解析 想给公司搞个官网,结果打开记事本看代码,全是天书。很多老板或运营刚接手网站项目时,第一反应不是找开发,而是问一句:企业网站源码怎么获取?这背后藏着一个巨大的认知误区:你以为源码是个“文件”,下载下来就能用,其实它是一套复杂的逻辑、数据库和服务器环境的组…

作者头像 李华