ハードコピーしたビットマップを印刷するには?


シングルタスク  2004-02-23 21:06:43  No: 53213

クリップボードにコピーした画面の画像を再度読み込みビットマップのハンドル(HBITMAP)として保持している場合に、これを印刷するには?どのような処理の流れをたどればいいのでしょうか?
環境は、XP、VC++、MFCを使っていません。
(環境について、どのように表現すればよいのか、
よくわからないのですが、これでいいのでしょうか?)
いろいろと、資料を検索していたら、なんだかこんがらがってしまいました。下記では、プリンターに印刷はできるのですが、仮想プリンターには表示されません。どなたか、ご教授いただけないでしょうか?
よろしくお願いいたします。m(_ _)m

///////////////////////////////////////////////////////////////////
HANDLE      hPrinter = NULL;       // プリンタ オブジェクトのハンドル
HDC         hdcPrn = NULL;         // プリンタデバイス・ハンドル
BOOL        bError = FALSE;
DOCINFO     di;

//  プリンタの初期処理
if( InitPrinter( hInst ,hDlg, &hPrinter, &hdcPrn ) )
{
    return( -1 );
}
/* 印刷開始 */
di.cbSize       = sizeof(DOCINFO);
di.lpszDocName  = "Hard Copy";//(LPSTR)szMessage;
di.lpszOutput   = (LPSTR)NULL;
di.lpszDatatype = (LPSTR)NULL;
di.fwType       = 0;

if( StartDoc( hdcPrn, &di ) > 0 )
{
    StartPage(hdcPrn);

    int         ret = 0 ;
    HBITMAP     hBm;
                                // 各モニタのビットマップのハンドル
    HDC         pDC;
    HBITMAP     hOldBitmap;
                        // 各モニタのビットマップのハンドル
    RECT        Prnrect ;
    BITMAP      bmpBuf ;

    pDC = GetDC(NULL) ;
    ret = ClipboardRead(hDlg, &hBm);// クリップボードからBMPを読込む
    if (hBm){
        // ビットマップオブジェクトの選択
        ret = GetObject(hBm,sizeof(bmpBuf),&bmpBuf) ;
             hOldBitmap = (HBITMAP)SelectObject(pDC, hBm);
        if(GetClipBox(hdcPrn, &Prnrect)!=SIMPLEREGION){
            //ERROR
        }

    // コピー元のpDCからコピー先のhdcPrnへビットブロック転送する

        ret = StretchBlt(hdcPrn, Prnrect.left,
                            Prnrect.top, Prnrect.right-Prnrect.left,
                            Prnrect.bottom-Prnrect.top,
         pDC, 0, 0, bmpBuf.bmWidth,
                            bmpBuf.bmHeight, SRCCOPY);
        SelectObject(pDC, hOldBitmap);
    }

    //We're done... lets finish up
    EndPage(hdcPrn);
    EndDoc(hdcPrn);

    DeleteObject(hBm);
}
else
    bError = TRUE;

// プリンタの終了処理
DeleteDC( hdcPrn ); // デバイスの削除
ClosePrinter( hPrinter );


シングルタスク  2004-02-24 02:28:02  No: 53214

少し、進捗あったので、ご報告します。
下記のようにしたら、仮想プリンタに表示されました。
しかし、ビットマップハンドルから、ビットマップデータを取得して
印刷。というのは、正しい流れなのか、
無駄な処理をしているのかが、わかりません。
どなたか、ご指摘いただけると助かります。
よろしくお願いします。m(_ _)m

/****少し長くなりますが***********/
BITMAPINFO *GetBitmapInfoHeader(HBITMAP hBm, BITMAP *bmp){

int          iclrbits; // 画面の色のビット数
LPBITMAPINFO lpbmi; // BITMAPINFO構造体のポインタ

 // ビット数計算
 iclrbits = bmp->bmPlanes * bmp->bmBitsPixel;

 // (1,4,8,16,24,32のどれか)
 if ( iclrbits == 1 )      iclrbits = 1;
 else if( iclrbits <= 4 )  iclrbits = 4;
 else if( iclrbits <= 8 )  iclrbits = 8;
 else if( iclrbits <= 16 ) iclrbits = 16;
 else if( iclrbits <= 24 ) iclrbits = 24;
 else                      iclrbits = 32;

 if( iclrbits != 24 )
 {
   // メモリの確保
   lpbmi = (LPBITMAPINFO)malloc( sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * iclrbits );
   // 初期化
   memset( lpbmi, NULL, sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * iclrbits );
 }else
 {
   // メモリの確保
   lpbmi = (LPBITMAPINFO)malloc( sizeof(BITMAPINFOHEADER) );
   // 初期化
   memset( lpbmi, NULL, sizeof(BITMAPINFOHEADER) );
 }

 // この構造体に必要なバイト数
 lpbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
 // ビットマップの幅、高さ
 lpbmi->bmiHeader.biWidth = bmp->bmWidth;
 lpbmi->bmiHeader.biHeight = bmp->bmHeight;
 // ターゲット デバイスのプレーン数(1でなければならない)
 lpbmi->bmiHeader.biPlanes = bmp->bmPlanes;
 // ピクセルの色を示すのに必要なビット数
 lpbmi->bmiHeader.biBitCount = bmp->bmBitsPixel;
 // 圧縮されていない形式のビットマップ
 lpbmi->bmiHeader.biCompression = BI_RGB;
 // イメージのサイズ(バイト単位) (ここが何をしているのかわからない)
 lpbmi->bmiHeader.biSizeImage = (lpbmi->bmiHeader.biWidth + 7) / 8 * lpbmi->bmiHeader.biHeight * iclrbits;
 // 重要な色(0を指定した場合すべて重要)
 lpbmi->bmiHeader.biClrImportant = 0;
 
 return (lpbmi);
}
int  Print( HANDLE hInst, HWND hDlg, int flag)
{
  HANDLE    hPrinter = NULL;    // プリンタ オブジェクトのハンドル
  HDC      hdcPrn = NULL;      // プリンタデバイス・ハンドル
  BOOL    bError    = FALSE;
  DOCINFO    di;
  char    *PrintFname = NULL;

  // **********************************************************

  //  プリンタの初期処理
  if( InitPrinter( hInst ,hDlg, &hPrinter, &hdcPrn ) )
  {
    return(  -1 );
  }

  /* 印刷開始 */
  di.cbSize    = sizeof(DOCINFO);
  di.lpszDocName  = "Hard Copy";//(LPSTR)szMessage;
  di.lpszOutput  = (LPSTR)NULL;
  di.lpszDatatype  = (LPSTR)NULL;
  di.fwType  = 0;
  
  if(  StartDoc( hdcPrn, &di ) > 0 )
  {
    StartPage(hdcPrn);

    int      ret = 0 ;
    HBITMAP    hBm;        // クリップボードに保存されているビットマップのハンドル
    HBITMAP    hOldBitmap;      // 保存用ビットマップハンドル

    HDC pDC;            // モニタのデバイスコンテキスト

    RECT    Prnrect ;      // プリンターのサイズ取得用エリア
    BITMAP    bmpBuf ;      // ビットマップの情報
    BITMAPINFO  *infBuf = NULL ;  // ビットマップのヘッダー情報
    LPVOID    bits  = NULL ;    // ビットマップのデータ

    pDC = GetDC(NULL) ;
    ret = ClipboardRead(hDlg, &hBm);          // クリップボードからBMPを読み込む
    if (hBm){                      // 
      //ビットマップの情報取得
      ret = GetObject(hBm,sizeof(bmpBuf),&bmpBuf) ;

      // ビットマップオブジェクトの選択
      hOldBitmap = (HBITMAP)SelectObject(hdcPrn, hBm);
      if (GetClipBox(hdcPrn, &Prnrect)!=SIMPLEREGION){
        //ERROR
      }
      //BITMAPINFOHEADER情報設定
      infBuf = GetBitmapInfoHeader(hBm,&bmpBuf) ;
      bits = new BYTE[infBuf->bmiHeader.biSizeImage];
       // ディスプレイ用デバイスコンテキストを作成
       HDC hdc1 = CreateDC( "DISPLAY", NULL, NULL, NULL );       // RGBQUAD、カラーインデックスを取得する
       if( GetDIBits(hdc1,hBm,0,
         (WORD)infBuf->bmiHeader.biHeight,bits,infBuf,DIB_RGB_COLORS) == 0 )
       {
         free( bits );
         free( infBuf );
         return FALSE;
       }

      // コピー元のhDCからコピー先のhMemDCへビットブロック転送する
      ret = StretchDIBits(hdcPrn, Prnrect.left, Prnrect.top, 
          Prnrect.right-Prnrect.left, Prnrect.bottom-Prnrect.top, 
          0, 0, bmpBuf.bmWidth, bmpBuf.bmHeight, bits, infBuf, DIB_RGB_COLORS, SRCCOPY);
      SelectObject(pDC, hOldBitmap);
    
    }
    //We're done... lets finish up
    EndPage(hdcPrn);
    EndDoc(hdcPrn);

    free( bits );
    free( infBuf );
    DeleteObject(hBm);
  }
  else
    bError = TRUE;

  // プリンタの終了処理
  DeleteDC( hdcPrn );            // デバイスの削除
  ClosePrinter( hPrinter );

  return( 0 );        // 正常終了
}


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加