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

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

void CPictureZoomCtrl::OnDraw(
  CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)

PictureZoom使用一个标志来识别图片是否具有 已加载或未加载: 隐藏,复制Code

if (m_bNoPicture)
  return;

第一步是创建一个兼容的DC需要容纳的图片: 隐藏,复制Code

CDC mdc; // memory DC
mdc.CreateCompatibleDC(pdc);
CBitmap* pOld = mdc.SelectObject(&m_Picture);

为防止在绘制拉伸或缩小的图片时出现干扰色彩, 正确设置颜色模式: 隐藏,复制Code

pdc->SetStretchBltMode(COLORONCOLOR);
mdc.SetStretchBltMode(COLORONCOLOR);

为了处理图片,我们需要它的尺寸: 隐藏,复制Code

m_Picture.UnrealizeObject();
BITMAP BM;
m_Picture.GetBitmap(&BM);

接下来的部分有点棘手,因为我们需要区分三种方法 展示图片的方法。第一种是在不保留外观的情况下绘制 原图比例: 隐藏,复制Code

if (!m_bAspectRatio)
  pdc->StretchBlt(0, 0, rcBounds.Width(),
    rcBounds.Height(),&mdc, 0, 0,
    BM.bmWidth, BM.bmHeight, SRCCOPY);

下一组不同于其他两种情况: 隐藏,复制Code

else
{
  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;

另外两种情况中的第一种是图片需要被剪切 在顶部和底部以缩放的方式绘制它在整个给定的窗口。 第一步是计算左上角 在源(未缩放!)位图: 隐藏,复制Code

if (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;

因为我对图片的中心显示有点不满意, 我决定也允许一些对齐设置: 隐藏,复制Code

if (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(见宽对高)。 隐藏,复制Code

else
{
  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

原文地址:https://www.cnblogs.com/Dincat/p/13473219.html