0

我正在使用 MFC 并尝试使用OnPrint()打印 DI 位图的内容。我知道如何获取我的位图,我知道如何到达::StretchDIBitDC,但要做到这一点,我需要知道纸张尺寸,并想说是否适合正常位图尺寸,只需使用它,如果太大,制作它更小。但是我从哪里获得页面大小?如何将我的 DI 位图宽度/高度与打印机页面的输出相关联?

将 发送::StretchDIBit到一些随机值进行测试:

pDC->SetMapMode(MM_ISOTROPIC);
pDC->SetWindowExt(500, 500);
pDC->SetViewportExt(4500, 6500);

打印出来的,但拉伸不成比例。如果我只是简单地将它发送到__super::OnPrint()它打印但非常小。我宁愿让它只使用OnDraw()which 输出到屏幕上,这就是__super::OnPrint()它的作用,但是我如何设置它以打印正确的大小和比例?

蒂亚!!

编辑:

根据下面的答案,它没有用。什么都没有打印。如果我在(不打印)上显示时使用了 MM_ISOTROPIC,则CView没有显示任何内容,所以我有条件地使用地图模式。这是完整的代码,包括CView窗口中支持的缩放。有什么遗漏/错误?

蒂亚!!

void CMyImageView::OnDraw(CDC* pDCView)
{
  if (m_DIBData != NULL) {
    #define PALSIZE(x) ((x) > 8? 0: 1 << (x))

    // move different versions of bitmap header to bitmap structure
    BITMAP bm;
    if (m_DIBData->biSize == sizeof(BITMAPCOREHEADER)) {
      bm.bmWidth=((BITMAPCOREHEADER*)m_DIBData)->bcWidth;
      bm.bmHeight=((BITMAPCOREHEADER*)m_DIBData)->bcHeight;
      bm.bmBitsPixel=((BITMAPCOREHEADER*)m_DIBData)->bcBitCount;
      bm.bmType=BI_RGB;
      bm.bmBits=PBYTE(m_DIBData) + m_DIBData->biSize + PALSIZE(bm.bmBitsPixel) * 3;
    }
    else {
      bm.bmWidth=m_DIBData->biWidth;
      bm.bmHeight=m_DIBData->biHeight;
      bm.bmBitsPixel=m_DIBData->biBitCount;
      bm.bmType=m_DIBData->biCompression;
      long color=m_DIBData->biClrUsed ? m_DIBData->biClrUsed : PALSIZE(bm.bmBitsPixel);
      bm.bmBits=PBYTE(m_DIBData) + m_DIBData->biSize + color * 4;
    }

    CPoint point=GetScrollPosition();

    CRect rcClient(0, 0, 0, 0);

    if(pDCView->IsPrinting())
    {
      pDCView->SetMapMode(MM_ISOTROPIC);
      pDCView->SetWindowExt(bm.bmWidth, bm.bmHeight);

      rcClient.right=pDCView->GetDeviceCaps(HORZRES);
      rcClient.bottom=pDCView->GetDeviceCaps(VERTRES);

      // setup view
      pDCView->SetViewportExt(rcClient.right, rcClient.bottom);
    }
    else {
      ASSERT(MM_TEXT == pDCView->GetMapMode());
      ASSERT(CPoint(0, 0) == pDCView->GetViewportOrg());
      GetClientRect(rcClient);
    }

    const int cx=rcClient.right;      // view client area width
    const int cy=rcClient.bottom;     // view client area height
    const int bx=bm.bmWidth;          // source bitmap width
    const int by=bm.bmHeight;         // source bitmap height
    const int vx=(int)(bx * m_fZoom); // virtual document width
    const int vy=(int)(by * m_fZoom); // virtual document height
    const int xPos=point.x;           // horizontal scroll position
    const int yPos=point.y;           // vertical scroll position

    // source and destination coordinates and sizes
    int xSrc, ySrc, nSrcWidth, nSrcHeight, xDst, yDst, nDstWidth, nDstHeight;

    if (vx > cx) {
      xSrc=(int)(xPos / m_fZoom);
      nSrcWidth=bx - xSrc;
      xDst=0;
      nDstWidth=vx - xPos;
    }
    else {
      xSrc=0;
      nSrcWidth=bx;
      xDst=cx / 2 - vx / 2;
      nDstWidth=vx;
    }

    if (vy > cy) {
      ySrc=0;
      nSrcHeight=by;
      yDst=-yPos;
      nDstHeight=vy;
    }
    else {
      ySrc=0;
      nSrcHeight=by;
      yDst=cy / 2 - vy / 2;
      nDstHeight=vy;
    }

    ::StretchDIBits(pDCView->m_hDC,
                    xDst, yDst,                 // xy-coordinates of upper-left corner of dest. rect.
                    nDstWidth, nDstHeight,      // width & height of destination rectangle
                    xSrc, ySrc,                 // xy-coordinates of lower-left corner of source rect.
                    nSrcWidth, nSrcHeight,      // width & height of source rectangle
                    bm.bmBits,                  // address of array with DIB bits
                    (BITMAPINFO*)m_DIBData,     // address of structure with bitmap info
                    DIB_RGB_COLORS,             // usage flags
                    SRCCOPY);                   // raster operation code
  }
}

编辑:

所以我将IsPrinting上面的部分修改为:

    if(pDCView->IsPrinting())
    {
      pDCView->SetMapMode(MM_ISOTROPIC);
      // setup base size of item
      pDCView->SetWindowExt(bm.bmWidth, bm.bmHeight);
      rcClient.right=bm.bmWidth;
      rcClient.bottom=bm.bmHeight;

      // setup view output to full page
      int horzres=pDCView->GetDeviceCaps(HORZRES);
      int vertres=pDCView->GetDeviceCaps(VERTRES);
      pDCView->SetViewportExt(horzres, vertres);
    }

有效!但是现在我不得不在另一个问题中询问位图和精度输出。

4

1 回答 1

0

答案是:

void CMyImageView::OnDraw(CDC* pDCView)
{
  if (m_DIBData != NULL) {
    #define PALSIZE(x) ((x) > 8? 0: 1 << (x))

    // move different versions of bitmap header to bitmap structure
    BITMAP bm;
    if (m_DIBData->biSize == sizeof(BITMAPCOREHEADER)) {
      bm.bmWidth=((BITMAPCOREHEADER*)m_DIBData)->bcWidth;
      bm.bmHeight=((BITMAPCOREHEADER*)m_DIBData)->bcHeight;
      bm.bmBitsPixel=((BITMAPCOREHEADER*)m_DIBData)->bcBitCount;
      bm.bmType=BI_RGB;
      bm.bmBits=PBYTE(m_DIBData) + m_DIBData->biSize + PALSIZE(bm.bmBitsPixel) * 3;
    }
    else {
      bm.bmWidth=m_DIBData->biWidth;
      bm.bmHeight=m_DIBData->biHeight;
      bm.bmBitsPixel=m_DIBData->biBitCount;
      bm.bmType=m_DIBData->biCompression;
      long color=m_DIBData->biClrUsed ? m_DIBData->biClrUsed : PALSIZE(bm.bmBitsPixel);
      bm.bmBits=PBYTE(m_DIBData) + m_DIBData->biSize + color * 4;
    }

    CPoint point=GetScrollPosition();

    CRect rcClient(0, 0, 0, 0);

    if(pDCView->IsPrinting())
    {
      pDCView->SetMapMode(MM_ISOTROPIC);
      // setup base size of item
      pDCView->SetWindowExt(bm.bmWidth, bm.bmHeight);
      rcClient.right=bm.bmWidth;
      rcClient.bottom=bm.bmHeight;

      // setup view output to full page
      int horzres=pDCView->GetDeviceCaps(HORZRES);
      int vertres=pDCView->GetDeviceCaps(VERTRES);
      pDCView->SetViewportExt(horzres, vertres);
    }
    else {
      ASSERT(MM_TEXT == pDCView->GetMapMode());
      ASSERT(CPoint(0, 0) == pDCView->GetViewportOrg());
      GetClientRect(rcClient);
    }

    const int cx=rcClient.right;      // view client area width
    const int cy=rcClient.bottom;     // view client area height
    const int bx=bm.bmWidth;          // source bitmap width
    const int by=bm.bmHeight;         // source bitmap height
    const int vx=(int)(bx * m_fZoom); // virtual document width
    const int vy=(int)(by * m_fZoom); // virtual document height
    const int xPos=point.x;           // horizontal scroll position
    const int yPos=point.y;           // vertical scroll position

    // source and destination coordinates and sizes
    int xSrc, ySrc, nSrcWidth, nSrcHeight, xDst, yDst, nDstWidth, nDstHeight;

    if (vx > cx) {
      xSrc=(int)(xPos / m_fZoom);
      nSrcWidth=bx - xSrc;
      xDst=0;
      nDstWidth=vx - xPos;
    }
    else {
      xSrc=0;
      nSrcWidth=bx;
      xDst=cx / 2 - vx / 2;
      nDstWidth=vx;
    }

    if (vy > cy) {
      ySrc=0;
      nSrcHeight=by;
      yDst=-yPos;
      nDstHeight=vy;
    }
    else {
      ySrc=0;
      nSrcHeight=by;
      yDst=cy / 2 - vy / 2;
      nDstHeight=vy;
    }

    ::StretchDIBits(pDCView->m_hDC,
                    xDst, yDst,                 // xy-coordinates of upper-left corner of dest. rect.
                    nDstWidth, nDstHeight,      // width & height of destination rectangle
                    xSrc, ySrc,                 // xy-coordinates of lower-left corner of source rect.
                    nSrcWidth, nSrcHeight,      // width & height of source rectangle
                    bm.bmBits,                  // address of array with DIB bits
                    (BITMAPINFO*)m_DIBData,     // address of structure with bitmap info
                    DIB_RGB_COLORS,             // usage flags
                    SRCCOPY);                   // raster operation code
  }
}
于 2020-02-23T03:22:44.070 回答