文章目录
问题说明:如标题
当我在做一个作业时,我需要实时更新某个点的位置,但是呢,每当我拖拽窗口的时候,我发现了两个问题
- 第一个问题是,我发现该点的所以移动的区域突然就和鼠标错开了,且我和我再次将窗口拖回原处就正常,因此我思考到是绘图画面与实际窗口所在画面的偏差。(但是此时所在一些插画等其任然在当前窗口)
- 为了解决第一个问题,我做了如下代码
HWND hwnd = GetHWnd();
RECT rect;
GetWindowRect(hwnd, &rect);
setorigin(rect.left, rect.top);
于是出现了第二个问题,就是绘图窗口也出现了问题绘图窗口页偏移了,于是我就更加确定了,是鼠标所在读取窗口(不知道为什么鼠标读取的那个“区域”没有更新,但是easyX提供的窗口自动更新了),没有跟随移动的缘故。
解决方案
上面问题已经搞清楚了,核心问题就是鼠标读取的窗口位置没有实时更新,windows里面有两个API
GetClientRect
ScreenToClient
通过这两个API,就能解决鼠标读取便宜的情况。
GetClientRect:是获取当对于客户机使用的窗口而言其所在的相对坐标。
解释:windows的窗口绘画呢,不同窗口似乎有各自绘画坐标(你在拖动的时候实际你的窗口动效是停止的),这就导致呢,你拖动窗口,那个窗口陷入了暂停,在其世界绝对坐标中运动。你拖动的时候呢,是直接使得窗口移动了。但是你鼠标监听的那个不属于窗口世界。
ScreenToClient:这就是一个转换API,他把你鼠标监听所在的实际位置,转换过去那边的坐标,使其最终和你的坐标对齐。
#include <windows.h>
#include <graphics.h>
#include <iostream>
int main()
{
initgraph(640, 480); // 初始化 easyX 窗口
HWND hwnd = GetHWnd(); // 获取窗口句柄
while (true)
{
// 获取鼠标在屏幕中的绝对位置
POINT cursorPos;
GetCursorPos(&cursorPos);
// 将屏幕坐标转换为窗口客户区相对坐标
//这个代码可以去尝试注释和取消注释试一试
// ScreenToClient(hwnd, &cursorPos);
// 清除屏幕并绘制鼠标所在位置的点
cleardevice(); // 清除屏幕以避免残留
setfillcolor(RED);
fillellipse(cursorPos.x, cursorPos.y, cursorPos.x + 60, cursorPos.y + 60); // 在鼠标所在位置绘制一个点
// 判断是否按下了退出键
if (GetAsyncKeyState(VK_ESCAPE)) break;
Sleep(10); // 控制刷新频率,避免占用过多资源
}
closegraph(); // 关闭窗口
return 0;
}