Нет ли косяков в применении 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);
}
Re: Нет ли косяков в применении BitBlt
От: Maxim S. Shatskih Россия  
Дата: 22.05.08 20:01
Оценка:
Что мешает не создавать объект DIB section, а саллоцировать pixels VirtualAllocом, потом их точно так же заполнить, заполнить еще заголовок и позвать StretchDIBits? это будет работать?
Занимайтесь LoveCraftом, а не WarCraftом!
Re[2]: Нет ли косяков в применении BitBlt
От: romuld  
Дата: 23.05.08 10:25
Оценка:
Здравствуйте, Maxim S. Shatskih, Вы писали:

MSS>Что мешает не создавать объект DIB section, а саллоцировать pixels VirtualAllocом, потом их точно так же заполнить, заполнить еще заголовок и позвать StretchDIBits? это будет работать?



Ничто не мешает, но повторюсь, что подобный текст используется в сторонней библиотеке, и на ее разработчиков влиять сложно, хотя попробовать можно. Все таки хотелось бы понять, этот текст — корректен или нет?
Re: Нет ли косяков в применении BitBlt
От: Аноним  
Дата: 23.05.08 10:35
Оценка:
R>Ниже приведен текст.
R>Ни одна из win32 функций не выдает ошибки, в т.ч. и BitBlt, а выпадает драйвер принтера (отдельный процесс).
Если непривилегированный код вызывает отказ в системном сервисе это всегда баг в сервисе (в данном случае в драйвере принтера). Хотя конечно это не гарантирует отсутствия проблема в коде приложения
Re[2]: Нет ли косяков в применении BitBlt
От: FractalizeR  
Дата: 23.05.08 10:43
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Если непривилегированный код вызывает отказ в системном сервисе это всегда баг в сервисе (в данном случае в драйвере принтера). Хотя конечно это не гарантирует отсутствия проблема в коде приложения


Забавная какая фраза... И что она означает?
Re[3]: Нет ли косяков в применении BitBlt
От: Аноним  
Дата: 23.05.08 10:57
Оценка:
FR>Забавная какая фраза... И что она означает?
Что драйвер принтера точно кривой. Но это совсем не означает правильности кода изза которого проявляются баги драйвера принтера
Re[4]: Нет ли косяков в применении BitBlt
От: romuld  
Дата: 23.05.08 11:01
Оценка:
Здравствуйте, Аноним, Вы писали:

FR>>Забавная какая фраза... И что она означает?

А>Что драйвер принтера точно кривой. Но это совсем не означает правильности кода изза которого проявляются баги драйвера принтера

Может вы сможете оценить правильность кода? Уже пытался бодаться с техподдержкой — говорят, раз из других программ печатает, значит вы сами виноваты.
Re[2]: Нет ли косяков в применении BitBlt
От: romuld  
Дата: 23.05.08 13:59
Оценка:
Здравствуйте, Maxim S. Shatskih, Вы писали:

MSS>Что мешает не создавать объект DIB section, а саллоцировать pixels VirtualAllocом, потом их точно так же заполнить, заполнить еще заголовок и позвать StretchDIBits? это будет работать?


Попробовал — да, так работает.
Следовательно, вопрос можно уточнить: возбраняется ли применение BitBlt и StretchBlt с соурс-контекстом, в который выбрана HBITMAP, полученая от CreateDibSection?
Re[5]: Нет ли косяков в применении BitBlt
От: Аноним  
Дата: 23.05.08 16:53
Оценка:
R>Может вы сможете оценить правильность кода? Уже пытался бодаться с техподдержкой — говорят, раз из других программ печатает, значит вы сами виноваты.
А что изменит зание того что у вас правильно? Фиксить по любому вам придется то
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.