MF C: Как вы печатаете DI Bitmap на принтер? - PullRequest
0 голосов
/ 22 февраля 2020

Я использую MF C и пытаюсь использовать OnPrint() для печати содержимого битовой карты DI. Я знаю, как получить мое растровое изображение, я знаю ::StretchDIBit, чтобы добраться до D C, но для этого мне нужно знать размер бумаги и сказать, подходит ли нормальный размер растрового изображения, просто используйте это, если слишком большой, сделайте его меньше. А где взять размер страницы? Как связать ширину / высоту моего растрового изображения DI с выводом на страницу принтера?

Отправка ::StretchDIBit для некоторых случайных значений для тестирования:

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

Напечатано, но оно было растянуто несоразмерно. Если я просто отправлю его на __super::OnPrint(), оно будет напечатано, но очень маленьким Я бы предпочел, чтобы он просто использовал OnDraw(), который прекрасно выводит на экран, и это то, что делает __super::OnPrint(), но как мне настроить его для печати правильного размера и пропорции?

TIA !!

РЕДАКТИРОВАТЬ:

Исходя из ответа ниже, это не сработало. Ничего не напечатано. Если я использовал MM_ISOTROPI C при отображении на CView (не печатая), то ничего не показывалось, поэтому я с ума сошел с условным режимом карты. Вот полный код, включая масштабирование, поддерживаемое в окне CView. Что отсутствует / не так?

TIA !!

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);
    }

Это сработало! Но теперь я должен спросить о точечных рисунках и точности вывода в другом вопросе.

1 Ответ

0 голосов
/ 23 февраля 2020

Ответ:

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
  }
}
...