見たところ、おかしな点は無いような気がしますが・・・
以下は、私の使っているHDCの内容をBMPに出力する関数です。
bool SaveWindowImageForBMP(HDC hDC, int width, int height, const char *file_name)
{
if (file_name == NULL){
return false;
}
DWORD dwSize, dwFSize, dwWidth, dwHeight, dwLength;
HANDLE fh;
LPBITMAPFILEHEADER lpHead;
LPBITMAPINFOHEADER lpInfo;
LPBYTE lpBuf,lpPixel;
HDC hdcMem;
HBITMAP hBMP,hOld;
dwWidth=width;
dwHeight=height;
if ((dwWidth*2) % 4==0){ // バッファの1ラインの長さを計算
dwLength=dwWidth*2;
}
else {
dwLength=dwWidth*2+(4-(dwWidth*2) % 4);
}
// 書き込み用バッファのサイズ計算
dwFSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+dwLength*dwHeight;
// バッファ確保とポインタ設定
lpBuf=(LPBYTE)GlobalAlloc(GPTR,dwFSize);
lpHead=(LPBITMAPFILEHEADER)lpBuf;
lpInfo=(LPBITMAPINFOHEADER)(lpBuf+sizeof(BITMAPFILEHEADER));
lpPixel=lpBuf+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
// 16ビットBMPファイルのヘッダ作成
lpHead->bfType='M'*256+'B';
lpHead->bfSize=dwFSize;
lpHead->bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
lpInfo->biSize=sizeof(BITMAPINFOHEADER);
lpInfo->biWidth=dwWidth;
lpInfo->biHeight=dwHeight;
lpInfo->biPlanes=1;
lpInfo->biBitCount=16;
// ウインドウのデバイスコンテキスト互換のBITMAP作成
hBMP=CreateCompatibleBitmap(hDC,dwWidth,dwHeight);
// BITMAPにウインドウのクライアント領域をコピー
hdcMem=::CreateCompatibleDC(hDC);
hOld=(HBITMAP)::SelectObject(hdcMem,hBMP);
::BitBlt(hdcMem,0,0,dwWidth,dwHeight,hDC,0,0,SRCCOPY);
::SelectObject(hdcMem,hOld);
::GetDIBits(hDC,hBMP,0,dwHeight,lpPixel,(LPBITMAPINFO)lpInfo,DIB_RGB_COLORS);
::DeleteObject(hBMP);
::DeleteObject(hdcMem);
// バッファをファイルに書き出す
fh=CreateFile(file_name,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
if(fh == INVALID_HANDLE_VALUE){
GlobalFree(lpBuf); //確保したメモリの開放
return false;
}
if (WriteFile(fh,lpBuf,dwFSize,&dwSize,NULL) == 0){
CloseHandle(fh);
GlobalFree(lpBuf); //確保したメモリの開放
return false;
}
CloseHandle(fh);
GlobalFree(lpBuf); //確保したメモリの開放
return true;
}
お礼
引き続き回答有難うございます。 自分でもなぜモノクロ以外だと正常に描画できないのか、プリンタDCからだと描画が正常にできないのか分かりません・・。 自分はVC++ Ver1.51を使用しているのでtettsuさんに書いていただいたソースコードと大きく変わるところといえば WriteFile関数の所なのかなと自分では思っています。 私のコードだと、ファイルに書き込むとき以下のようにループさせなければいけないので、szBufferの確保が正常に出来ていないのかとも考えたりしています。 _lwriteだと一度で書き込むことが出来ないみたいなので・・。 lCount = (long)LtpBitmapFH.bfSize - sizeof (BITMAPFILEHEADER); lBuffCnt = 0; while(1) { if (lCount<=lBuffCnt) break; Liret = _lwrite( hF,&szBuffer[lBuffCnt], 1); lBuffCnt = lBuffCnt + 1; } ここまで書いて頂いたのに自分で解消できず申しわけ有りません。 自分でももう少し進展するまで締め切るのを待とうと思います。 もし後ほどお気づきになるようなことがありましたら又アドバイスいただけると幸いです。
補足
アクティブウインドウからのビットマップ作成に成功しました。 ビットマップのサイズを小さくして作成してみた所、カラーでも正常に作成できたので、LlnSelObj が 65534 を超えてしまった場合に正常に出ないような気がしてヒュージに変えてみた所、正常に出力されました。 有り難うございました。 char _huge *a; a = (char *)GlobalLock(hDIB); LlnSelObj = (long)LtpBitmapFH.bfSize - sizeof (BITMAPFILEHEADER); LlnBuffCnt = 0; while(1) { if (LlnSelObj<=LlnBuffCnt) break; Liret = _lwrite( hF,a, 40); a = a + 40; LlnBuffCnt+=40; }