クリップボードにコピーした画面の画像を再度読み込みビットマップのハンドル(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 );
少し、進捗あったので、ご報告します。
下記のようにしたら、仮想プリンタに表示されました。
しかし、ビットマップハンドルから、ビットマップデータを取得して
印刷。というのは、正しい流れなのか、
無駄な処理をしているのかが、わかりません。
どなたか、ご指摘いただけると助かります。
よろしくお願いします。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 ); // 正常終了
}
ツイート | ![]() |