Нет ли косяков в применении BitBlt
От: romuld  
Дата: 22.05.08 09:44
Оценка:
Здравствуйте!
Обнаружилась проблема, не удается на один из принтеров печатать битмапы. Делает это сторонняя библиотека, покопавшись в ее текстах, я сделал тестовое Win32 приложение, которое аналогичным образом вроде все замечательно воспроизводит.

Но терзают меня сомнения, можно ли так писать?

Т.к. ни одна из программ, что под рукой (Paint, PaintShopPro, Photoshop), проблем с этим принтером не испытывает. Прежде чем доказывать что то поддержке производителя драйвера (HP DeskJet 4500), хочу спросить здесь.

Ниже приведен текст.
Ни одна из win32 функций не выдает ошибки, в т.ч. и BitBlt, а выпадает драйвер принтера (отдельный процесс).

способ1.
В эту функцию передается контекст принтера, а также размер битмапки и куда ее рисовать.
Она создает DIB , заполняет его всякой фигней, и отправляет на принтер.
bool DrawBitmap(HDC hDC, int xx, int yy, int ww, int hh)
{
    // drawing without scaling

    // Define the header
    BITMAPINFO bmi;
    memset(&bmi, 0, sizeof(bmi));
    bmi.bmiHeader.biSize        = sizeof(BITMAPINFOHEADER);
    bmi.bmiHeader.biWidth       = ww;
    bmi.bmiHeader.biHeight      = -hh;
    bmi.bmiHeader.biPlanes      = 1;
    bmi.bmiHeader.biBitCount    = 32;
    bmi.bmiHeader.biCompression = BI_RGB;
    bmi.bmiHeader.biSizeImage   = ww * hh * 4;

    // Create the pixmap
    DWORD w;
    uchar *pixels = 0;
    HBITMAP bitm = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, (void **) &pixels, 0, 0);
    if (!bitm) {
        w = GetLastError();
        return false;
    }
    if (!pixels) {
        return false;
    }

    // Fill DIB pixels
    int x, y;
    int * data = (int*)pixels;
    for (y = 0; y < hh; y++)
    {
        for (x = 0; x < ww; x++)
        {
            int value;
            if (x%4 == 0)
                value = RGB(0,255,0);
            else if (y%4 == 0)
                value = RGB(0,0,255);
            else value = RGB(255,0,0);
            data[y * ww + x] = value;
        }
    }


    // create DC for DIB
    HDC bitDC = CreateCompatibleDC(hDC);
    // select DIB into new DC
    HGDIOBJ old_bitmap = SelectObject(bitDC, bitm);
    if (!old_bitmap) 
    {
        w = GetLastError();
        return false;
    }
    // BitBlt from new DC to printer DC
    if (!BitBlt(hDC,
        xx, yy, ww, hh,
        bitDC,
        0,0, SRCCOPY))
    {
        w = GetLastError();
        return false;
    }

    // cleaning
    SelectObject(bitDC, old_bitmap);
    DeleteObject(bitm); 
    DeleteDC(bitDC);

    return true;
}


способ2.
В эту функцию передается контекст принтера.
Она функция загружает Bitmap из ресурсов, и просто рисует ее на принтер
void DrawBitmap(HDC hDC)
{
    // draw without scaling

    DWORD dwErr;
    // Loading bitmap from resources
    HANDLE bitm = LoadImage(hInst, MAKEINTRESOURCE(IDB_BITMAP_BIG),
                            IMAGE_BITMAP, 0, 0,
                            LR_CREATEDIBSECTION);

    if (!bitm) 
    {
        dwErr = GetLastError();
        return;
    }

    // Get size
    BITMAP info;
    GetObject(bitm, sizeof(info), &info);

    HBITMAP bitmap = (HBITMAP)bitm;

    // Create DC for bitmap
    HDC bitDC = CreateCompatibleDC(hDC);
    // Select bitmap into new context
    HGDIOBJ old_bitmap = SelectObject(bitDC, bitm);
    if (!old_bitmap) 
    {
        dwErr = GetLastError();
        return;
    }
    // BitBlt bitmap into printer DC
    if (!BitBlt(hDC,
        0, 0, 
        info.bmWidth, info.bmHeight,
        bitDC,
        0,0, SRCCOPY))
    {
        dwErr = GetLastError();
        return;
    }

    // cleaning
    SelectObject(bitDC,old_bitmap);
    DeleteObject(bitmap); 
    DeleteDC(bitDC);
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.