Здравствуйте!
Обнаружилась проблема, не удается на один из принтеров печатать битмапы. Делает это сторонняя библиотека, покопавшись в ее текстах, я сделал тестовое 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);
}
Что мешает не создавать объект DIB section, а саллоцировать pixels VirtualAllocом, потом их точно так же заполнить, заполнить еще заголовок и позвать StretchDIBits? это будет работать?
Здравствуйте, Maxim S. Shatskih, Вы писали:
MSS>Что мешает не создавать объект DIB section, а саллоцировать pixels VirtualAllocом, потом их точно так же заполнить, заполнить еще заголовок и позвать StretchDIBits? это будет работать?
Ничто не мешает, но повторюсь, что подобный текст используется в сторонней библиотеке, и на ее разработчиков влиять сложно, хотя попробовать можно. Все таки хотелось бы понять, этот текст — корректен или нет?
R>Ниже приведен текст.
R>Ни одна из win32 функций не выдает ошибки, в т.ч. и BitBlt, а выпадает драйвер принтера (отдельный процесс).
Если непривилегированный код вызывает отказ в системном сервисе это всегда баг в сервисе (в данном случае в драйвере принтера). Хотя конечно это не гарантирует отсутствия проблема в коде приложения
Здравствуйте, Аноним, Вы писали:
А>Если непривилегированный код вызывает отказ в системном сервисе это всегда баг в сервисе (в данном случае в драйвере принтера). Хотя конечно это не гарантирует отсутствия проблема в коде приложения
Забавная какая фраза... И что она означает?
Здравствуйте, Аноним, Вы писали:
FR>>Забавная какая фраза... И что она означает?
А>Что драйвер принтера точно кривой. Но это совсем не означает правильности кода изза которого проявляются баги драйвера принтера
Может вы сможете оценить правильность кода? Уже пытался бодаться с техподдержкой — говорят, раз из других программ печатает, значит вы сами виноваты.
Здравствуйте, Maxim S. Shatskih, Вы писали:
MSS>Что мешает не создавать объект DIB section, а саллоцировать pixels VirtualAllocом, потом их точно так же заполнить, заполнить еще заголовок и позвать StretchDIBits? это будет работать?
Попробовал — да, так работает.
Следовательно, вопрос можно уточнить: возбраняется ли применение BitBlt и StretchBlt с соурс-контекстом, в который выбрана HBITMAP, полученая от CreateDibSection?
R>Может вы сможете оценить правильность кода? Уже пытался бодаться с техподдержкой — говорят, раз из других программ печатает, значит вы сами виноваты.
А что изменит зание того что у вас правильно? Фиксить по любому вам придется то