Модераторы: feodorv, GremlinProg, xvr, Fixin

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> отрисовка hbitmap в контексте принтера 
:(
    Опции темы
dadrum
Дата 25.3.2009, 14:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 17
Регистрация: 13.4.2007

Репутация: нет
Всего: нет



   Здравствуйте, подскажите почему в контекст принтера не получается вывести изображение (причем на форму выводится), хотя текст и графические примитивы печатаются отлично.

пытаюсь вывести изображение так:
Код

    int w=abs(px2-px1);
    int h=abs(py2-py1);
    HDC hdcMem = CreateCompatibleDC( hdc );
    SelectObject( hdcMem, a->Bitmap );
    StretchBlt( hdc, posleft+px1, postop+py1, w, h, hdcMem, 0, 0, a->BitmapW, a->BitmapH , SRCCOPY );
    DeleteDC( hdcMem );


hdc- контекст принтера
a->Bitmap - предварительно загруженный битмап
PM MAIL ICQ   Вверх
Alexeis
Дата 25.3.2009, 16:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 7
Всего: 459



dadrum, а bitblt работает?

Добавлено через 2 минуты и 45 секунд
В справке написано так
Цитата(http://msdn.microsoft.com/en-us/library/dd145120(VS.85).aspx)

Not all devices support the StretchBlt function. For more information, see the GetDeviceCaps.


Добавлено через 6 минут и 38 секунд
Хотя про BitBlt тоже так написано
Цитата

Not all devices support the BitBlt function. For more information, see the RC_BITBLT raster capability entry in the GetDeviceCaps function as well as the following functions: MaskBlt, PlgBlt, and StretchBlt.



--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
dadrum
Дата 25.3.2009, 17:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 17
Регистрация: 13.4.2007

Репутация: нет
Всего: нет



Цитата

а bitblt работает?


не работает
PM MAIL ICQ   Вверх
Alexeis
Дата 25.3.2009, 17:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 7
Всего: 459



dadrum, проверьте возможности принтера функцией GetDeviceCaps , с параметром RASTERCAPS на RC_BITBLT и RC_STRETCHBLT. Если нет, то ничего не поделаешь.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
dadrum
Дата 25.3.2009, 17:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 17
Регистрация: 13.4.2007

Репутация: нет
Всего: нет



Цитата

проверьте возможности принтера функцией GetDeviceCaps , с параметром RASTERCAPS на RC_BITBLT и RC_STRETCHBLT. Если нет, то ничего не поделаешь.


проверил, поддерживаются
PM MAIL ICQ   Вверх
GremlinProg
Дата 25.3.2009, 18:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



у принтера просто более крупная метрика, посмотри внимательно, возможно твой битмап, если он достаточно темный и крупный, выходит на бумаге в виде точки или оч. маленького прямоугольника

используй для преобразований координат DPtoLP и LPtoDP,
либо вручную, как в примере: http://msdn.microsoft.com/en-us/library/dd162865(VS.85).aspx
там тоже используется растяжка, но уже с сохранением пропорций


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
dadrum
Дата 27.3.2009, 09:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 17
Регистрация: 13.4.2007

Репутация: нет
Всего: нет



Дело в том, что и с метрикой вроде всё ок и с принтером...
Устанавливается метрика 0,01 мм
Код

SetMapMode(pPDX->hDC, MM_HIMETRIC);

и в коде
Код

StretchBlt( hdc, posleft+px1, postop+py1, w, h, hdcMem, 0, 0, a->BitmapW, a->BitmapH , SRCCOPY );

posleft+px1 = 0
postop+py1 = 0
w = 3492  = 34 мм
h = 4656 = 46 мм
a->BitmapW = 450 pix
a->BitmapH = 600 pix
и Rectangle по этим координаиам - на бумаге печатается ... 
блин, головоломка!
PM MAIL ICQ   Вверх
GremlinProg
Дата 27.3.2009, 11:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



ну, тогда можно попробовать сменить совместимый девайс для битмапа
Цитата(dadrum @  25.3.2009,  16:06 Найти цитируемый пост)
HDC hdcMem = CreateCompatibleDC( hdc );

за шаблон взять не принтер, а десктоп

ну и вообще, посмотреть, что собственно возвращает сама StretchBlt, и если не TRUE, то GetLastError ("ERR,hr" - в watch'е)

Добавлено через 3 минуты и 59 секунд
Цитата(dadrum @  27.3.2009,  11:52 Найти цитируемый пост)
SetMapMode(pPDX->hDC, MM_HIMETRIC);

я бы не советовал так делать только потому, что метрику задает драйвер принтера, который, как известно, можно всегда сменить, как и сам принтер, естессно (а пример из MSDN работать будет одинаково всегда)

Добавлено через 7 минут и 20 секунд
кстати, заметил разницу, откуда уже появилось три девайса?
или третий - это вариации на тему hdcMem?


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
dadrum
Дата 27.3.2009, 12:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 17
Регистрация: 13.4.2007

Репутация: нет
Всего: нет



В приведенном ранее коде, StretchBlt возвращает true.
А если сделать 
Код

HDC hdcMem = CreateCompatibleDC( NULL );

StretchBlt возвращает ошибку "неверно задан параметр"
(в обоих вариантах битмап на форму выводится а на принтер нет)
Цитата

кстати, заметил разницу, откуда уже появилось три девайса?
или третий - это вариации на тему hdcMem?


pPDX->hDC - используется в форме выбора принтера, этот же указатель передается в функцию отрисовки, т.е. в изначальном примере hdc - это pPDX->hDC  smile 

может надо что-то менять в настройках битмапа?
PM MAIL ICQ   Вверх
GremlinProg
Дата 27.3.2009, 15:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(dadrum @  27.3.2009,  14:46 Найти цитируемый пост)
StretchBlt возвращает ошибку "неверно задан параметр"

контекст десктопа можно получить с помощью вызова GetDC(NULL), а просто NULL - не есть контекст


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
dadrum
Дата 27.3.2009, 16:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 17
Регистрация: 13.4.2007

Репутация: нет
Всего: нет



Код

HDC desk=GetDC(NULL);
HDC hdcMem = CreateCompatibleDC( desk );

та же ошибка ...
PM MAIL ICQ   Вверх
GremlinProg
Дата 27.3.2009, 16:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



кстати парный ReleaseDC(0,hdcScreen) к нему тоже нужен

если и это не поможет, то возможно принтер просто настроен на "черновую" печать, тогда он в принципе может пропускать битмапы (эту галочку надо снять в настройках принтера)


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
dadrum
Дата 27.3.2009, 16:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 17
Регистрация: 13.4.2007

Репутация: нет
Всего: нет



я уже запарил наверна =) 
не помогает, какое бы качество печать ни поставил - чистый лист

Цитата

кстати парный ReleaseDC(0,hdcScreen) к нему тоже нужен

это само собой

может нужно копать в формате HBITMAP ?

Это сообщение отредактировал(а) dadrum - 27.3.2009, 16:30
PM MAIL ICQ   Вверх
GremlinProg
Дата 27.3.2009, 16:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(dadrum @  27.3.2009,  18:29 Найти цитируемый пост)
может нужно копать в формате HBITMAP ?

я бы к битмапу в последнюю очередь придирался

надо попробовать чо-нить напечатать, один момент


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
GremlinProg
Дата 27.3.2009, 18:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



немного подкорректировал пример из MSDN,
на бумагу картинка выходит:
Код

    DIBSECTION dib;
    PRINTDLG pd;
    DOCINFO di;
    HGDIOBJ hBitmap;
    HDC hScreenDC;
    FLOAT fLogPelsX1;
    FLOAT fLogPelsX2;
    FLOAT fLogPelsY1;
    FLOAT fLogPelsY2;
    FLOAT fScaleX;
    FLOAT fScaleY;
    int cWidthPels;
    int cHeightPels;
    int xLeft;
    int yTop;

    hBitmap    = ::LoadImage(NULL,_T("C:\\WINDOWS\\На рыбалку.bmp"),IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION | LR_LOADFROMFILE);
    ::GetObject(hBitmap,sizeof(dib),&dib);
    
    memset( &di, 0, sizeof(di) );
    di.cbSize = sizeof(DOCINFO);
    di.lpszDocName = TEXT("Bitmap Printing Test");
    di.lpszOutput =  NULL;
    di.lpszDatatype =  NULL;
    di.fwType = 0;

    memset( &pd, 0, sizeof(pd) );
    pd.lStructSize = sizeof( pd );
    pd.Flags = PD_RETURNDC;

    ::PrintDlg(&pd);
    ::StartDoc(pd.hDC,&di);
    ::StartPage(pd.hDC);

    hScreenDC    = ::GetDC(NULL);
    fLogPelsX1 = (float) ::GetDeviceCaps(hScreenDC, LOGPIXELSX);
    fLogPelsY1 = (float) ::GetDeviceCaps(hScreenDC, LOGPIXELSY);
    ::ReleaseDC(NULL,hScreenDC);

    fLogPelsX2 = (float) ::GetDeviceCaps(pd.hDC, LOGPIXELSX);
    fLogPelsY2 = (float) ::GetDeviceCaps(pd.hDC, LOGPIXELSY);

    if (fLogPelsX1 > fLogPelsX2)
        fScaleX = (fLogPelsX1 / fLogPelsX2);
    else fScaleX = (fLogPelsX2 / fLogPelsX1);

    if (fLogPelsY1 > fLogPelsY2)
        fScaleY = (fLogPelsY1 / fLogPelsY2);
    else fScaleY = (fLogPelsY2 / fLogPelsY1);

    cWidthPels = ::GetDeviceCaps(pd.hDC, HORZRES);
    xLeft = ((cWidthPels / 2) - ((int) (((float) dib.dsBmih.biWidth)
            * fScaleX)) / 2);
    cHeightPels = ::GetDeviceCaps(pd.hDC, VERTRES);
    yTop = ((cHeightPels / 2) - ((int) (((float) dib.dsBmih.biHeight)
            * fScaleY)) / 2);
    ::StretchDIBits(
        pd.hDC, xLeft, yTop, (int) ((float) dib.dsBmih.biWidth
        * fScaleX), (int) ((float) dib.dsBmih.biHeight * fScaleY), 0, 0,
        dib.dsBmih.biWidth, dib.dsBmih.biHeight, dib.dsBm.bmBits, (BITMAPINFO*)&dib.dsBmih, DIB_RGB_COLORS,
        SRCCOPY
    );
    ::EndPage(pd.hDC);
    ::EndDoc(pd.hDC);
    ::DeleteObject(hBitmap);
    ::DeleteDC(pd.hDC);


с размерами тут проблем нет: рисунок выводится в оригинальном масштабе по центру
правда у меня, по крайней мере, рисунок выводится мнохромный (не grayscale, как ожидал на Canon LBP-810)


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0853 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.