一个c++ OCX,用于在应用程序的任何窗口上绘图

下载source files - 21.2 Kb
下载demo project - 138 Kb

介绍
这个OCX让你可以缩放任何你喜欢的图片
窗口(至少)您的应用程序。有三个主要部分,
即加载所需的图片,Windows事件处理程序的重定向
然后画图。
Windows NT, Windows 2000和Windows XP只允许一个应用程序
重写自己窗口的Windows事件处理程序。这个例子
或多或少是自我解释。使用OleLoadPicture()加载图片。
图片将使用Windows标准图形API绘制
strechblt()函数。
要取代Windows事件处理程序,使用SetWindowLong()。
细节
绘图程序
主绘图是在ondraw方法中完成的。万一
OCX应该在其他窗口上绘制,而不是自己,它会直接调用ondraw。
因为OCX是使用MFC生成的,所以方法头是标准的
自动生成:
隐藏,复制Codevoid CPictureZoomCtrl::OnDraw(
CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
PictureZoom使用一个标志来识别图片是否具有
已加载或未加载:
隐藏,复制Codeif (m_bNoPicture)
return;

第一步是创建一个兼容的DC需要容纳的图片:
隐藏,复制CodeCDC mdc; // memory DC
mdc.CreateCompatibleDC(pdc);
CBitmap* pOld = mdc.SelectObject(&m_Picture);

为防止在绘制拉伸或缩小的图片时出现干扰色彩,
正确设置颜色模式:
隐藏,复制Codepdc->SetStretchBltMode(COLORONCOLOR);
mdc.SetStretchBltMode(COLORONCOLOR);

为了处理图片,我们需要它的尺寸:
隐藏,复制Codem_Picture.UnrealizeObject();
BITMAP BM;
m_Picture.GetBitmap(&BM);

接下来的部分有点棘手,因为我们需要区分三种方法
展示图片的方法。第一种是在不保留外观的情况下绘制
原图比例:
隐藏,复制Codeif (!m_bAspectRatio)
pdc->StretchBlt(0, 0, rcBounds.Width(),
rcBounds.Height(),&mdc, 0, 0,
BM.bmWidth, BM.bmHeight, SRCCOPY);

下一组不同于其他两种情况:
隐藏,复制Codeelse
{
double Strech = double(rcBounds.Width()) / double(BM.bmWidth);
int iHeight = Strech * BM.bmHeight;
int iWidth = Strech * BM.bmWidth;

int yMove = ((iHeight - rcBounds.Height()) / 2) / Strech;

另外两种情况中的第一种是图片需要被剪切
在顶部和底部以缩放的方式绘制它在整个给定的窗口。
第一步是计算左上角
在源(未缩放!)位图:
隐藏,复制Codeif (yMove >= 0)
{
// Strech for width
int xp = -m_xAdd;
int yp = yMove - m_yAdd;

if (xp < 0)
xp = 0;

if (yp < 0)
yp = 0;

if (xp > iWidth - rcBounds.Width())
xp = iWidth - rcBounds.Width();

if (yp > (iHeight - rcBounds.Height()) / Strech)
yp = (iHeight - rcBounds.Height()) / Strech;

因为我对图片的中心显示有点不满意,
我决定也允许一些对齐设置:
隐藏,复制Codeif (m_Align == TOP)
yp = 0;
else if (m_Align == BOTTOM)
yp = (iHeight - rcBounds.Height()) / Strech;

m_xAdd = -xp;
m_yAdd = yMove - yp;

第1种情况的最后一步是简单地对源矩形进行blit
在目标窗口上使用strechblt():
隐藏,复制Code // Blit only on the rectangle that is invalid
CRect SourceRect((rcInvalid.left * BM.bmWidth) /
rcBounds.Width() + xp,
(rcInvalid.top * (rcBounds.Height() / Strech)) /
rcBounds.Height() + yp,
(rcInvalid.right * BM.bmWidth) / rcBounds.Width()
+ xp, (rcInvalid.bottom * (rcBounds.Height() /
Strech)) / rcBounds.Height() + yp);
pdc->StretchBlt(rcInvalid.left, rcInvalid.top,
rcInvalid.Width(), rcInvalid.Height(),&mdc,
SourceRect.left, SourceRect.top,
SourceRect.right - SourceRect.left,
SourceRect.bottom - SourceRect.top, SRCCOPY);
}

第二种情况或多或少等于前一步。
唯一的区别是,图片现在会被截断
在左手和右手边。这发生时,当窗口
在此基础上绘制的比例小于1(见宽对高)。
隐藏,复制Codeelse
{
Strech = double(rcBounds.Height()) / double(BM.bmHeight);
int iHeight = Strech * BM.bmHeight;
int iWidth = Strech * BM.bmWidth;

int xMove = ((iWidth - rcBounds.Width()) / 2) / Strech;
int xp = xMove - m_xAdd;
int yp = -m_yAdd;

if (xp < 0)
xp = 0;

if (yp < 0)
yp = 0;

if (xp > (iWidth - rcBounds.Width()) / Strech)
xp = (iWidth - rcBounds.Width()) / Strech;

if (yp > iHeight - rcBounds.Height())
yp = iHeight - rcBounds.Height();

再次,我决定允许一些对齐(对窗口的左或右边界):
隐藏,复制Code if (m_Align == LEFT)
xp = 0;
else if (m_Align == RIGHT)
xp = (iWidth - rcBounds.Width()) / Strech;

m_xAdd = xMove - xp;
m_yAdd = -yp;

// Blit only on the rectangle that is invalid
CRect SourceRect((rcInvalid.left *
  rcBounds.Width()/Strech) / rcBounds.Width() +
  xp, (rcInvalid.top * BM.bmHeight) / rcBounds.Height()
  + yp, (rcInvalid.right * rcBounds.Width()/Strech)
  / rcBounds.Width() + xp, (rcInvalid.bottom * BM.bmHeight)
  / rcBounds.Height() + yp);
pdc->StretchBlt(rcInvalid.left, rcInvalid.top,
  rcInvalid.Width(), rcInvalid.Height(),&mdc,
  SourceRect.left, SourceRect.top,
  SourceRect.right - SourceRect.left,
  SourceRect.bottom - SourceRect.top, SRCCOPY);

}
}

绘制的最后一步是释放所有使用的资源:
隐藏,复制Code mdc.SelectObject(pOld);
mdc.DeleteDC();
}
这篇文章将在接下来的几天中尽快继续
工作和学习之间有更多的时间。

本文转载于:http://www.diyabc.com/frontweb/news10645.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值