嗨,我现在正在用 C++ 编写一个 win32 应用程序,但我真的很难放大窗口的内容。这是我开始完成缩放的伪代码:
// point One
int XPointOne = -200;
int YPointTwo = 0;
// point Two
int XPointTwo = 200;
int YPointTwo = 0;
// Draw point function.
DrawPoint(XCoordinate * ScalingFactor, YCoordinate * ScalingFactor) {
....
}
我的坐标系设置为使其原点位于窗口的中心。我想在使用鼠标滚轮时进行缩放。上述解决方案的问题是缩放总是从窗口的中心发生。当您的鼠标不在窗口的中心时,这有点难看。我想放大鼠标所在的区域,但我找不到合适的算法来计算 x 和 y 方向的偏移量。例如,如果鼠标具有坐标 (-200, 0),则点 1 应具有坐标 (-200, 0),点 2 应具有坐标 (600, 0),且比例因子为 2。我已经尝试了很多东西,但没有让它工作,尤其是当鼠标在缩放之间移动到其他位置时,一切都搞砸了。任何人都知道如何解决这个问题?
这是我的应用程序的一些示例代码。第一个片段是我处理 WM_MOUSEWHEEL 消息的回调函数。
VOID OnMouseWheel(WPARAM const& WParam, LPARAM const& LParam) {
if(GET_WHEEL_DELTA_WPARAM(WParam) > 0)
{
// Zoom in
Draw.ScaleFactor += 0.1;
}
else
{
// Zoom out
}
}
Draw 只是一个包装 GDI 函数的类。它有一个比例因子成员。下面的代码片段是我的 Draw 对象的 DrawCircle 成员函数,它使用比例因子在屏幕上正确显示圆。
VOID DrawCircle(DOUBLE const& XCoordinate, DOUBLE const& YCoordinate, DOUBLE const& Radius, COLORREF const& Color) {
HBRUSH Brush = CreateSolidBrush(Color);
HBRUSH OldBrush = (HBRUSH)SelectObject(this->MemoryDC, Brush);
Ellipse(this->MemoryDC, (INT) ((XCoordinate - Radius) * this->ScaleFactor),
-(INT)((YCoordinate + Radius) * this->ScaleFactor),
(INT)((XCoordinate + Radius) * this->ScaleFactor),
-(INT)((YCoordinate - Radius) * this->ScaleFactor));
SelectObject(this->MemoryDC, OldBrush);
DeleteObject(Brush);
}
如您所见,我的 DrawCircle 函数在应用当前比例因子时没有考虑鼠标位置。
编辑
好的,我更接近解决方案这里是我的鼠标回调函数的更新版本。
VOID OnMouseWheel(WPARAM const& WParam, LPARAM const& LParam) {
// Get Mouse position in real coordinates and not window coordinates.
INT XOffset = (Window.GetClientWidth() / -2) + XMousePos;
INT YOffset = (Window.GetClientHeight() / 2) - YMousePos;
if(GET_WHEEL_DELTA_WPARAM(WParam) > 0)
{
Draw.ScaleFactor += 0.1;
Draw.XOffsetScale = -XOffset * (Draw.ScaleFactor - 1.0);
Draw.YOffsetScale = YOffset * (Draw.ScaleFactor - 1.0);
}
else
{
// ...
}
}
这是绘制圆圈的函数。
VOID DrawCircle(DOUBLE const& XCoordinate, DOUBLE const& YCoordinate, DOUBLE const& Radius, COLORREF const& Color) {
HBRUSH Brush = CreateSolidBrush(Color);
HBRUSH OldBrush = (HBRUSH)SelectObject(this->MemoryDC, Brush);
Ellipse(this->MemoryDC, (INT) ((XCoordinate - Radius) * this->ScaleFactor + XOffsetScale) ,
-(INT)((YCoordinate + Radius) * this->ScaleFactor - YOffsetScale),
(INT)((XCoordinate + Radius) * this->ScaleFactor + XOffsetScale),
-(INT)((YCoordinate - Radius) * this->ScaleFactor - YOffsetScale));
SelectObject(this->MemoryDC, OldBrush);
DeleteObject(Brush);
}
只要我将鼠标保持在同一位置,这确实有效,但是当我移动到另一个位置时,它不会按预期缩放一次,然后它会再次正确缩放。也许这有点帮助。
提前致谢!
解决了
好的,我现在解决了我的问题。我只是根据鼠标位置乘以缩放因子移动了坐标系的原点。感谢您的回答。