Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 21.09.2021, 15:16   #1
ldor108
Новичок
Джуниор
 
Регистрация: 21.09.2021
Сообщений: 2
По умолчанию Печать содержимого окна инструментами Winapi

Добрый день!
Я пытаюсь научится печатать содержимое окна. Из того, что я нашел в интернете, все выглядит очень просто, также как и рисование в окне. Только лишь надо сначала выбрать принтер, да еще добавить функции StartDoc и StartPage в начале и EndDoc и EndPage в конце печати. Только почему-то не получается. Принтер выбрать удается и он начинает работать, но выдает пустую страницу. Если вместо реального принтера выбрать pdf файл, то файл создается. Но при попытке открыть его выдается сообщение о "внутренней ошибке".
Внизу привожу мой пробный код. Этот код просто пытается нарисовать одну линию в качестве пробной печати. Пытался также вместо линии копировать содержимое всего окна через BitBlt, результат тот же самый - пустая страница или pdf файл с "внутренней ошибкой".
У кого-то есть идея, что я здесь упустил?
Код:
PRINTDLG pd;
DOCINFO di = {0};
HPEN hpen;
.......
di.cbSize = sizeof(DOCINFO);
di.lpszDocName = "Printout";
hpen = CreatePen(PS_SOLID, 2, RGB(256,0,0));
// Initialize PRINTDLG
ZeroMemory(&pd, sizeof(pd));
pd.lStructSize = sizeof(pd);
pd.hwndOwner   = hwnd;
pd.hDevMode    = NULL;     // Don't forget to free or store hDevMode.
pd.hDevNames   = NULL;     // Don't forget to free or store hDevNames.
pd.Flags       = PD_USEDEVMODECOPIESANDCOLLATE | PD_RETURNDC;
pd.nCopies     = 1;
pd.nFromPage   = 1;
pd.nToPage     = 1;
pd.nMinPage    = 1;
pd.nMaxPage    = 1;

PrintDlg(&pd);
SelectObject(pd.hDC, hpen);
StartDoc(pd.hDC, &di);
StartPage(pd.hDC);
MoveToEx(pd.hDC, 10,100,NULL);
LineTo(pd.hDC,20,200);
EndPage(pd.hDC);
EndDoc(pd.hDC);
DeleteObject(hpen);
ldor108 вне форума Ответить с цитированием
Старый 21.09.2021, 20:56   #2
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,493
По умолчанию

Попробуйте сделать линию потолще, например 200, вместо 2...
Кроме того, хорошая практика проверять коды ошибок вызываемых функций.
waleri вне форума Ответить с цитированием
Старый 22.09.2021, 09:22   #3
alexcoder
Форумчанин
 
Регистрация: 31.05.2009
Сообщений: 786
По умолчанию

Код:
PRINTDLG pd;
				RECT rc;
				GetClientRect(hwnd, &rc);
				ZeroMemory(&pd, sizeof(pd));
				pd.lStructSize = sizeof(pd);
				pd.hwndOwner = hwnd;
				pd.hDevMode = NULL;
				pd.hDevNames = NULL;
				pd.Flags = PD_RETURNDC | PD_SELECTION;
				pd.nCopies = 1;
				pd.nFromPage = 0;
				pd.nToPage = 0;
				pd.nMinPage = 0;
				pd.nMaxPage = 0;
//dialog pechati
				if (PrintDlg(&pd))
				{
					HDC printerDC = pd.hDC;	//poluchaem kontekst vybrannogo printera
					DOCINFO di;
					memset(&di, 0, sizeof(di));
					di.cbSize = sizeof(di);
					// Opredelyaem razreshenie printera po vertikali
					int cx = GetDeviceCaps(printerDC, HORZRES);
					int cy = GetDeviceCaps(printerDC, VERTRES);
					//iskhodnye razmery oblasti pechati
					int wsrc = ...;
					int hsrc = ...;
					//i ee koordinaty
					int xsrc = ...;
					int ysrc = ...;
					//vychislyaem masshtaby po osyam
					double scalex = (double)cx / (double)wsrc;
					double scaley = (double)cy / (double)hsrc;
					//vybiraem men'shij ih nih, chtoby vsya vybrannaya oblast' bez iskazhenij pomestilas' na liste
					double scale = min(scalex, scaley);
					//razmer oblasti pechati
					int wdst = wsrc*scale;
					int hdst = hsrc*scale;
					//nachalo pechati
					StartDoc(printerDC, &di);
					StartPage(printerDC);
					//sdelat' kopiyu pechataemogo izobrazheniya, a to napryamuyu ne na vse printery vyvoditsya
					HDC copy = CreateCompatibleDC(hdc);
					HBITMAP bmcopy = CreateCompatibleBitmap(hdc, wdst, hdst);
					SelectObject(copy, bmcopy);
					//natyanut' oblast' pechati
					StretchBlt(copy, 0, 0, wdst, hdst, hdc, xsrc, ysrc, wsrc, hsrc, SRCCOPY);
					//I vyvod na printer
					BitBlt(printerDC, 0, 0, wdst, hdst, copy, 0, 0, SRCCOPY);
					//Zakonchit' pechat'
					EndPage(printerDC);
					EndDoc(printerDC);
					//Udalit' nenuzhnye deskriptory
					DeleteDC(pd.hDC);
					DeleteObject(bmcopy);
					DeleteDC(copy);
				}
У меня так печатает
Помощь с программами:
vk.com/alexcoder1
e-mail: informatik101@mail.ru
alexcoder вне форума Ответить с цитированием
Старый 22.09.2021, 10:42   #4
ldor108
Новичок
Джуниор
 
Регистрация: 21.09.2021
Сообщений: 2
По умолчанию

Спасибо, так получилось. Наверное дело в том что, как Вы написали в коментариях, напрямую не на все принтеры выдается
ldor108 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Вывод на печать всего содержимого формы vkontakte Общие вопросы Delphi 3 22.08.2012 12:26
печать содержимого dbgrid-? Evgenii БД в Delphi 4 07.05.2010 14:03
Печать содержимого TMemo vakyla Помощь студентам 9 06.01.2010 23:25
Печать содержимого DBGrid XATAB БД в Delphi 6 10.03.2009 08:35
Печать содержимого DB Grid Prisian БД в Delphi 4 06.09.2007 23:02