如何让鼠标移动无延迟?
我正在制作一个程序,让我单击两个同心圆的中心,然后通过鼠标移动来更改它的位置,我可以对其半径执行相同的操作。 问题是,鼠标移动后会出现圆圈绘制的延迟响应,从而使半径跟随鼠标移动,而不是在移动过程中完全相同的位置。
你们知道如何让它像这样工作吗?根据图纸确定点。
一些处理鼠标点击和移动的代码:
void DemoApp::OnLButtonDown(FLOAT pixelX, FLOAT pixelY)
{
SetCapture(m_hwnd);
mouseRegion = DPIScale::PixelsToDips(pixelX, pixelY);
FLOAT xDifference = centerCircles.x - mouseRegion.x;
FLOAT yDifference = centerCircles.y - mouseRegion.y;
FLOAT distanceToCenter = sqrtf(xDifference*xDifference + yDifference*yDifference);
if(distanceToCenter < 10.0f)
{
centerMove = true;
minimumRadiusCircleMove = false;
maximumRadiusCircleMove = false;
}
else if((distanceToCenter > (minimumRadius - 1.0f)) && (distanceToCenter < (minimumRadius + 1.0f)))
{
minimumRadiusCircleMove = true;
centerMove = false;
maximumRadiusCircleMove = false;
}
else if((distanceToCenter > (maximumRadius - 1.0f)) && (distanceToCenter < (maximumRadius + 1.0f)))
{
maximumRadiusCircleMove = true;
centerMove = false;
minimumRadiusCircleMove = false;
}
else
{
centerMove = false;
minimumRadiusCircleMove = false;
maximumRadiusCircleMove = false;
}
InvalidateRect(m_hwnd, NULL, FALSE);
}
void DemoApp::OnMouseMove(int pixelX, int pixelY, DWORD flags)
{
if (flags & MK_LBUTTON)
{
if(centerMove)
{
centerCircles = DPIScale::PixelsToDips(pixelX, pixelY);
FLOAT distanceLeftToCenterCircles = abs(centerCircles.x - bitmapTopLeft);
FLOAT distanceTopToCenterCircles = abs(centerCircles.y - bitmapTopRight);
percentageFromLeft = distanceLeftToCenterCircles / displaySizeWidth;
percentageFromTop = distanceTopToCenterCircles / displaySizeHeight;
}
else if(minimumRadiusCircleMove)
{
radiusSelection = DPIScale::PixelsToDips(pixelX, pixelY);
FLOAT xDifference = centerCircles.x - radiusSelection.x;
FLOAT yDifference = centerCircles.y - radiusSelection.y;
minimumRadius = sqrtf(xDifference*xDifference + yDifference*yDifference);
minimumRadiusPercentage = minimumRadius/(displaySizeWidth/2);
}
else if(maximumRadiusCircleMove)
{
radiusSelection = DPIScale::PixelsToDips(pixelX, pixelY);
FLOAT xDifference = centerCircles.x - radiusSelection.x;
FLOAT yDifference = centerCircles.y - radiusSelection.y;
maximumRadius = sqrtf(xDifference*xDifference + yDifference*yDifference);
maximumRadiusPercentage = maximumRadius/(displaySizeWidth/2);
}
InvalidateRect(m_hwnd, NULL, FALSE);
}
}
void DemoApp::OnLButtonUp()
{
ReleaseCapture();
}
I'm making a program that let me click on the center of two concentric circles and, by mouse move, change it's position and i can do the same with it's radii.
The thing is that the mouse movement is followed by a delay response from the circles drawing making the radius follow the mouse instead of being exactly in the same position during the movement.
Would you guys know how to make it work like that? pin point following by the drawing.
a bit of the code that treats the mouse clicking and movements:
void DemoApp::OnLButtonDown(FLOAT pixelX, FLOAT pixelY)
{
SetCapture(m_hwnd);
mouseRegion = DPIScale::PixelsToDips(pixelX, pixelY);
FLOAT xDifference = centerCircles.x - mouseRegion.x;
FLOAT yDifference = centerCircles.y - mouseRegion.y;
FLOAT distanceToCenter = sqrtf(xDifference*xDifference + yDifference*yDifference);
if(distanceToCenter < 10.0f)
{
centerMove = true;
minimumRadiusCircleMove = false;
maximumRadiusCircleMove = false;
}
else if((distanceToCenter > (minimumRadius - 1.0f)) && (distanceToCenter < (minimumRadius + 1.0f)))
{
minimumRadiusCircleMove = true;
centerMove = false;
maximumRadiusCircleMove = false;
}
else if((distanceToCenter > (maximumRadius - 1.0f)) && (distanceToCenter < (maximumRadius + 1.0f)))
{
maximumRadiusCircleMove = true;
centerMove = false;
minimumRadiusCircleMove = false;
}
else
{
centerMove = false;
minimumRadiusCircleMove = false;
maximumRadiusCircleMove = false;
}
InvalidateRect(m_hwnd, NULL, FALSE);
}
void DemoApp::OnMouseMove(int pixelX, int pixelY, DWORD flags)
{
if (flags & MK_LBUTTON)
{
if(centerMove)
{
centerCircles = DPIScale::PixelsToDips(pixelX, pixelY);
FLOAT distanceLeftToCenterCircles = abs(centerCircles.x - bitmapTopLeft);
FLOAT distanceTopToCenterCircles = abs(centerCircles.y - bitmapTopRight);
percentageFromLeft = distanceLeftToCenterCircles / displaySizeWidth;
percentageFromTop = distanceTopToCenterCircles / displaySizeHeight;
}
else if(minimumRadiusCircleMove)
{
radiusSelection = DPIScale::PixelsToDips(pixelX, pixelY);
FLOAT xDifference = centerCircles.x - radiusSelection.x;
FLOAT yDifference = centerCircles.y - radiusSelection.y;
minimumRadius = sqrtf(xDifference*xDifference + yDifference*yDifference);
minimumRadiusPercentage = minimumRadius/(displaySizeWidth/2);
}
else if(maximumRadiusCircleMove)
{
radiusSelection = DPIScale::PixelsToDips(pixelX, pixelY);
FLOAT xDifference = centerCircles.x - radiusSelection.x;
FLOAT yDifference = centerCircles.y - radiusSelection.y;
maximumRadius = sqrtf(xDifference*xDifference + yDifference*yDifference);
maximumRadiusPercentage = maximumRadius/(displaySizeWidth/2);
}
InvalidateRect(m_hwnd, NULL, FALSE);
}
}
void DemoApp::OnLButtonUp()
{
ReleaseCapture();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
根据 MSDN ( http://msdn.microsoft .com/en-us/library/dd145002%28v=vs.85%29.aspx ) InvalidateRect 不会导致窗口被重新绘制直到下一个 WM_PAINT 和“只要窗口的更新区域不为空并且该窗口的应用程序队列中没有其他消息,系统就会向该窗口发送 WM_PAINT 消息。”所以这不是立竿见影的。
我在 MSDN 上找到了一个可能的解决方案 Drawing without the WM_PAINT消息
According to MSDN ( http://msdn.microsoft.com/en-us/library/dd145002%28v=vs.85%29.aspx ) InvalidateRect doesn’t cause the window to be repainted until the next WM_PAINT and "The system sends a WM_PAINT message to a window whenever its update region is not empty and there are no other messages in the application queue for that window." so it’s not immediate.
I found a possible solution on MSDN here Drawing Without the WM_PAINT Message
我找到了解决这个问题的办法!
这比预期的简单,您所要做的就是在创建渲染目标时添加一个标志,这样鼠标移动的响应速度会更快:
该标志是:D2D1_PRESENT_OPTIONS_IMMEDIATELY。
i've found a solution to that problem!
It's way simple than expected, all you got to do is add a flag while creating the render target, that way the mousemove will respond way faster:
the flag is: D2D1_PRESENT_OPTIONS_IMMEDIATELY.