1

古い学校の MFC Windows CE プログラムを継承しており、それにいくつかの変更を加える必要があります。この一環として、テキストを含むモノクロ画像を作成し、それを画面に表示するだけでなく、画像の各行を一度に 1 つずつプリンターに送信する必要があります。

私はもともとビットマップを使用していましたが、DrawText() を使用してテスト文字列 (Hello World) を画面に表示することに成功しました (このコードは図 1 にあります)。しかし、ビットマップからラップデータを抽出しようとしている段階で壁にぶつかりました。私が取得しようとしているのは、黒または白を表す 1 または 0 の配列です。GetBitmapBits() を使用することを最初に考えていましたが、残念ながら、私が使用しているコードは非常に古いため、関数はまだサポートされていません。GetBitmap() を使用してから bmBits パラメータにアクセスすることで、この問題を回避できると考えました。ただし、これは常に null のように見えますが、これは次のリンクを見つけたときに確認されました.

私の次の試みは、リンクのアドバイスに従い、CreateCompatibleBitmap() の代わりに CreateDIBSection() を使用することでした。これは正しいパスのようで、必要なデータにアクセスできるはずですが、残念ながら DIB を表示できません (コードは図 2 にあります)。DIB のヘッダーの作成に何か問題があるのではないかと思いますが、何が間違っているのかわかりません。

ビットマップ内のデータにアクセスする方法について誰かが提案したり、DIB で何が間違っているかがわかったりする場合は、助けていただければ幸いです。

*** 図 1: ビットマップを作成して表示するコード

void CRunPage::OnPaint() 
{
    CPaintDC dc(this);          // property page device context for painting
    CBitmap mBmp;               // CBitmap object for displaying built-in bitmaps
    CDC mDCMem;                 // CDC object to handle built-in bitmap
    int iWidth, iHeight;        // dimension to draw on the screen

    int icurLabel,              // current label index of open print file
        iLabelNum;              // number of labels in open print file
    LPBITMAPINFOHEADER pBMIH;   // bitmap header object for current label
    LPBYTE pImage;              // bitmap data for current label
    CSize size;                 // size of label
    int PreviewLeft,PreviewTop,PreviewWidth,PreviewHeight;
    CRect Rect;
    BITMAP bm;
    LPVOID bmBits=NULL;

    // Calculate the preview area
    PreviewLeft=5;
    PreviewTop=5;
    GetDlgItem(IDC_RUN_NEXT)->GetWindowRect(&Rect);
    ScreenToClient(&Rect);
    PreviewWidth=Rect.left-PreviewLeft*2;
    GetDlgItem(IDC_RUN_WRAPTEXT)->GetWindowRect(&Rect);
    ScreenToClient(&Rect);
    PreviewHeight=Rect.top-PreviewTop*2;

    CRect textRect;
    CString testText(_T("Hello World"));

    CBitmap * pOldBitmap;
    CBrush whiteBrush, *pOldBrush;
    CPen blackPen, *pOldPen;


    mDCMem.CreateCompatibleDC(&dc);

    mBmp.CreateCompatibleBitmap(&dc, PreviewWidth+PreviewLeft*2, PreviewHeight+PreviewTop*2);
    //mBmp.CreateCompatibleBitmap(&dc, PreviewWidth, PreviewHeight);
    pOldBitmap = mDCMem.SelectObject(&mBmp);

    blackPen.CreatePen(PS_SOLID, 2, RGB(0, 0, 0));
    whiteBrush.CreateSolidBrush(RGB(255,255,255));

    textRect.SetRect(0,0,PreviewWidth, PreviewHeight);

    // this means behind the text will be a white box w/ a black boarder
    pOldBrush = mDCMem.SelectObject(&whiteBrush);
    pOldPen = mDCMem.SelectObject(&blackPen);

    //these commands draw on the memory-only context (mDCMem)
    mDCMem.Rectangle(&textRect);
    mDCMem.DrawText((LPCTSTR)testText, 11, &textRect, DT_CENTER|DT_VCENTER);

    mDCMem.SelectObject(pOldBrush);
    mDCMem.SelectObject(pOldPen);

    dc.StretchBlt(PreviewLeft,PreviewTop, PreviewWidth, PreviewHeight, & mDCMem, 0, 0, PreviewWidth, PreviewHeight, SRCCOPY);

    mDCMem.SelectObject(pOldBitmap);

}

*** 図 2: ビットマップの代わりに DIB を使用しようとする

void CRunPage::OnPaint() 
{

    CPaintDC dc(this);          // property page device context for painting

    CBitmap mBmp;               // CBitmap object for displaying built-in bitmaps
    CDC mDCMem;                 // CDC object to handle built-in bitmap
    int iWidth, iHeight;        // dimension to draw on the screen

    int icurLabel,              // current label index of open print file
        iLabelNum;              // number of labels in open print file
    LPBITMAPINFOHEADER pBMIH;   // bitmap header object for current label
    LPBYTE pImage;              // bitmap data for current label
    CSize size;                 // size of label
    int PreviewLeft,PreviewTop,PreviewWidth,PreviewHeight;
    CRect Rect;
    BITMAP bm;

    // Calculate the preview area
    PreviewLeft=5;
    PreviewTop=5;
    GetDlgItem(IDC_RUN_NEXT)->GetWindowRect(&Rect);
    ScreenToClient(&Rect);
    PreviewWidth=Rect.left-PreviewLeft*2;
    GetDlgItem(IDC_RUN_WRAPTEXT)->GetWindowRect(&Rect);
    ScreenToClient(&Rect);
    PreviewHeight=Rect.top-PreviewTop*2;

    CRect textRect;
    CString testText(_T("Hello World"));

    CBitmap * pOldBitmap;
    CBrush whiteBrush, *pOldBrush;
    CPen blackPen, *pOldPen;

    LPBYTE pFWandImageMem=NULL, pImageMem=NULL, pTemp=NULL;
    int i=0,j=0, buffSize=0, numBytesPerRow=0, bitmapWidthPix,bitmapHeightPix;

    char *numBytesPerRowString;
    char temp;
    void ** ppvBits;
    BITMAPINFOHEADER bmif;
    BITMAPINFO bmi;
    HBITMAP myDIB, myOldDIB;

    mDCMem.CreateCompatibleDC(&dc);

    //this rect is the area in which I can draw (its x,y location is set by BitBlt or StretchBlt
    //mBmp.CreateCompatibleBitmap(&dc, PreviewWidth+PreviewLeft*2, PreviewHeight+PreviewTop*2);

    bmif.biSize = sizeof(BITMAPINFOHEADER);
    bmif.biWidth = PreviewWidth+PreviewLeft*2;
    bmif.biHeight = -(PreviewHeight+PreviewTop*2);//- means top down (I think? I tried both ways and neither worked)
    bmif.biPlanes = 1;
    bmif.biBitCount = 1;
    bmif.biCompression = BI_RGB; // no compression
    bmif.biSizeImage = 0; // Size (bytes) if image - this can be set to 0 for uncompressed images
    bmif.biXPelsPerMeter = 0;
    bmif.biYPelsPerMeter = 0;
    bmif.biClrUsed =0;
    bmif.biClrImportant = 0;

    bmi.bmiColors[0].rgbBlue=0;
    bmi.bmiColors[0].rgbGreen=0;
    bmi.bmiColors[0].rgbRed=0;
    bmi.bmiColors[0].rgbReserved=0;
    bmi.bmiColors[1].rgbBlue=255;
    bmi.bmiColors[1].rgbGreen=255;
    bmi.bmiColors[1].rgbRed=255;
    bmi.bmiColors[1].rgbReserved=0;

    bmi.bmiHeader=bmif;

    myDIB = CreateDIBSection(dc.GetSafeHdc(), &bmi, DIB_RGB_COLORS, ppvBits, NULL, 0);

    myOldDIB = (HBITMAP)mDCMem.SelectObject(myDIB);//SelectObject(mDCMem, myDIB);
blackPen.CreatePen(PS_SOLID, 2, RGB(0, 0, 0));
whiteBrush.CreateSolidBrush(RGB(255,255,255));

textRect.SetRect(0,0,PreviewWidth, PreviewHeight);

// this means behind the text will be a white box w/ a black boarder
pOldBrush = mDCMem.SelectObject(&whiteBrush);
pOldPen = mDCMem.SelectObject(&blackPen);

//these commands draw on the memory-only context (mDCMem)
mDCMem.Rectangle(&textRect);
mDCMem.DrawText((LPCTSTR)testText, 11, &textRect, DT_CENTER|DT_VCENTER);

mDCMem.SelectObject(pOldBrush);
mDCMem.SelectObject(pOldPen);

dc.StretchBlt(PreviewLeft,PreviewTop, PreviewWidth, PreviewHeight, & mDCMem, 0, 0, PreviewWidth, PreviewHeight, SRCCOPY);

mDCMem.SelectObject(myOldDIB);

}

4

1 に答える 1