C++ 如何让鼠标移动毫不延迟地工作?
我正在制作一个程序,让我点击两个同心圆的中心,通过鼠标移动,改变它的位置,我可以对它的半径做同样的操作。 问题是,鼠标移动后,圆圈的延迟响应使半径跟随鼠标,而不是在移动过程中完全处于相同的位置 你们知道怎么让它这样工作吗?图纸后面的销点 处理鼠标点击和移动的代码:C++ 如何让鼠标移动毫不延迟地工作?,c++,direct2d,C++,Direct2d,我正在制作一个程序,让我点击两个同心圆的中心,通过鼠标移动,改变它的位置,我可以对它的半径做同样的操作。 问题是,鼠标移动后,圆圈的延迟响应使半径跟随鼠标,而不是在移动过程中完全处于相同的位置 你们知道怎么让它这样工作吗?图纸后面的销点 处理鼠标点击和移动的代码: void DemoApp::OnLButtonDown(FLOAT pixelX, FLOAT pixelY) { SetCapture(m_hwnd); mouseRegion = DPIScale::Pixels
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();
}
void-DemoApp::OnLButtonDown(浮点像素x,浮点像素y)
{
SetCapture(m_hwnd);
mouseRegion=DPIScale::PixelsToDips(pixelX,pixelY);
FLOAT xDifference=中心圆.x-鼠标区域.x;
浮动y差异=中心圆.y-鼠标区域.y;
浮动距离中心=sqrtf(xDifference*xDifference+yDifference*yDifference);
如果(距离中心<10.0f)
{
centerMove=true;
minimumRadiusCircleMove=假;
maximumRadiusCircleMove=假;
}
否则,如果((距离中心>(最小半径-1.0f))和((距离中心<(最小半径+1.0f)))
{
最小半径圆周运动=真;
centerMove=false;
maximumRadiusCircleMove=假;
}
否则如果((距离中心>(最大半径-1.0f))&(距离中心<(最大半径+1.0f)))
{
maximumRadiusCircleMove=真;
centerMove=false;
minimumRadiusCircleMove=假;
}
其他的
{
centerMove=false;
minimumRadiusCircleMove=假;
maximumRadiusCircleMove=假;
}
无效(m_hwnd,NULL,FALSE);
}
void DemoApp::OnMouseMove(整数像素x、整数像素y、DWORD标志)
{
if(标志和按钮)
{
如果(中心移动)
{
中心圆=DPIScale::像素倾斜(像素x,像素y);
浮动距离LeftToCenterCircles=abs(centerCircles.x-bitmapTopLeft);
浮动距离topToCenterCircles=abs(centerCircles.y-bitmapTopRight);
percentageFromLeft=从左到中心圆的距离/displaySizeWidth;
percentageFromTop=到中心圆的距离/displaySizeHeight;
}
否则如果(最小半径圆周运动)
{
radiusSelection=DPIScale::PixelsToDips(像素x,像素y);
FLOAT xDifference=中心圆.x-半径选择.x;
浮动y差值=中心圆.y-半径选择.y;
最小半径=sqrtf(xDifference*xDifference+yDifference*yDifference);
最小半径百分比=最小半径/(显示尺寸宽度/2);
}
否则如果(最大半径圆周运动)
{
radiusSelection=DPIScale::PixelsToDips(像素x,像素y);
FLOAT xDifference=中心圆.x-半径选择.x;
浮动y差值=中心圆.y-半径选择.y;
最大半径=sqrtf(xDifference*xDifference+yDifference*yDifference);
最大半径百分比=最大半径/(显示尺寸宽度/2);
}
无效(m_hwnd,NULL,FALSE);
}
}
void DemoApp::OnLButtonUp()
{
释放捕获();
}
根据MSDN(),在下一次WM_绘制之前,系统不会导致窗口重新绘制,并且“只要窗口的更新区域不为空,并且该窗口的应用程序队列中没有其他消息,系统就会向该窗口发送WM_绘制消息。”因此它不是即时的
我在这里的MSDN上找到了一个可能的解决方案我找到了这个问题的解决方案 它比预期的简单,您只需在创建渲染目标时添加一个标志,这样mousemove的响应速度就会更快: 该标志为:D2D1\u立即显示\u选项
// Create Direct2d render target.
hr = m_pD2DFactory->CreateHwndRenderTarget(
D2D1::RenderTargetProperties(),
D2D1::HwndRenderTargetProperties(m_hwnd, size, D2D1_PRESENT_OPTIONS_IMMEDIATELY),
&m_pRenderTarget
);
这不仅仅是WM_PAINT,WM_MOUSEMOVE只在消息队列没有更好的事情做时发送。双重打击。我调用了render函数来重新绘制屏幕,这样它就不需要从mousemove函数调用WM_PAINT,但这没有什么区别。因为我在direct2d上,而不是在GDI上,所以我不能使用HDC。还有什么想法吗?感谢你的努力。