CZoomCtrl:一个带缩放和滚动功能的图片控件
一个用于显示任意大小图片的滚动子窗口。
引言
我正在开发一个用于显示某种图表的对话框。如果数据点很多,显示会变得密集,用户会想要放大以仔细查看。为了支持这一点,我需要一个具有虚拟空间、视口和滚动条的 owner-draw 子控件——就像一个 CWnd
等效于 CScrollView
的东西。我想我可以很容易地找到这样的东西,或者使用 CWnd
的滚动功能快速构建一个。
几天过去了。我没有找到一个。我现在有一个简单的解决方案,但花了一些功夫,所以我想把它放在这里,以防万一它能为其他人节省时间。
背景
处理滚动条很麻烦。CWnd
函数会显示它们,但您必须自己处理所有用户操作(请参阅viewscrl.cpp中的大量代码)。我尝试利用其他滚动条处理程序,例如使控件成为 CEdit
的子类,然后尝试 CScrollView
。我下载了一个 ScroomDialog (由 CodeGuru 上的 miteshpandey 编写) 的副本,它是从 CScrollView
代码中提取并修改为可在 CDialog
上工作的代码块。
作为 CStatic
图片控件的基础,这些都不能很好地工作。但是,我找到了一个有用的类 CScrollHelper
(由 CodeProject 上的 nschan 编写),它可以管理滚动条而无需太多累赘。感谢 nschan!我稍微修改过的您的类版本包含在此处。
使用代码
CZoomCtrl
是 CWnd
的子类,可以很容易地作为 CStatic
放入对话框中。它有一个内部管理的 CScrollHelper
。您的工作是提供一个绘制方法和一个缩放因子,控件会处理其余的事情。
交付机制是一个带有缩放控件和两个按钮的小对话框应用程序 (VS2003)
- 缩放 将图片放大 1.2 倍,每次点击都会放大。滚动条会在第一次点击时出现。
- 适应 会回到默认状态:完整绘图会缩放以适应窗口。
要在您自己的对话框中使用该控件
- 将这四个文件添加到您的项目中:zoomctrl.cpp/h, ScrollHelper.cpp/h。
- 创建
CZoomCtrl
的子类并重写Draw
方法 - 将一个图片控件 (
CStatic
) 添加到您的对话框。它不需要特殊的属性——默认的 Frame 类型是可以的。如果您喜欢,可以添加边框。给它一个 ID,例如IDC_ZOOM_CTRL
。 - 将成员添加到您的对话框 h 和 cpp 文件中
- 此时,您可以尝试一下了。但是很快,您就会想给用户一种缩放和取消缩放的方法。这是演示应用程序的缩放按钮的样子
class CMyZoomCtrl : public CZoomCtrl
{ ...
virtual void Draw(CDC *pDC)
{
// fill background
CRect rClient;
GetClientRect(rClient);
pDC->FillRect(&rClient, &CBrush(RGB(255,255,255)));
// define virtual coords
CRect rVirt(0, 0, 5000, 5000);
PrepDC(pDC, rVirt, rClient);
// do your drawing
pDC->MoveTo(0, 0);
pDC->LineTo(5000, 5000);
}
};
您的 Draw
方法必须做三件事:擦除背景,设置虚拟坐标系,以及绘制您的内容。虚拟坐标由一个原点为零的矩形定义。这些可以是您喜欢的任何内容,但是如果您不希望您的绘图变形,则虚拟矩形应与客户端的形状相同。在这些坐标中绘制之前,您必须调用 PrepDC
。
include "zoomctrl.h"
class CMyDialog
{ ...
CZoomCtrl m_zoomCtrl;
void CMyDialog::DoDataExchange(CDataExchange* pDX)
{ ...
DDX_Control(pDX, IDC_ZOOM_CTRL, m_zoomCtrl);
void CZoomCtrlDemoDlg::OnBnClickedZoom()
{
m_zoomFactor *= 1.2;
m_zoomCtrl.SetZoomFactor(m_zoomFactor);
m_zoomCtrl.AdjustScrollbars();
m_zoomCtrl.Invalidate();
}
对话框的成员会跟踪其缩放因子。取消缩放会将其设置回 1.0。您的可以更复杂。
历史
- 原始发布 - 2008年3月25日。