Печать и SDK. Помогите разобраться!

Общие вопросы, не зависящие от языка реализации.

Модераторы: Duncon, Eugie, Romeo, Hawk

Ответить
HumVee
Сообщения: 16
Зарегистрирован: 30 май 2004, 02:17
Откуда: Минск

06 авг 2004, 18:54

Всем привет!
Кто-нибудь печатал содержимое RichEdit'a (не MFC) ?
В MSDN по этому поводу примеров вообще нет, но в нете нашёл функцию :

Код: Выделить всё

void PrintTheContents()
{
	FORMATRANGE fr;
	DOCINFO docInfo;
	LONG lTextOut, lTextAmt;
	PRINTDLG pd;

	// Initialize the PRINTDLG structure.

	pd.lStructSize = sizeof (PRINTDLG);
	pd.hwndOwner = hwndMain;
	pd.hDevMode = (HANDLE)NULL;
	pd.hDevNames = (HANDLE)NULL;
	pd.nFromPage = 0;
	pd.nToPage = 0;
	pd.nMinPage = 0;
	pd.nMaxPage = 0;
	pd.nCopies = 0;
	pd.hInstance = hInstance;
	pd.Flags = PD_RETURNDC | PD_NOPAGENUMS | PD_NOSELECTION | PD_PRINTSETUP;
	pd.lpfnSetupHook = (LPSETUPHOOKPROC)(FARPROC)NULL;
	pd.lpSetupTemplateName = (LPTSTR)NULL;
	pd.lpfnPrintHook = (LPPRINTHOOKPROC)(FARPROC)NULL;
	pd.lpPrintTemplateName = (LPTSTR)NULL;

	// Get the printer DC.

	if (PrintDlg (&pd) == TRUE)
	{
	// Fill out the FORMATRANGE structure for the RTF output.

		int 	nHorizRes = GetDeviceCaps(pd.hDC, HORZRES),
			nVertRes = GetDeviceCaps(pd.hDC, VERTRES),
			nLogPixelsX = GetDeviceCaps(pd.hDC, LOGPIXELSX),
			nLogPixelsY = GetDeviceCaps(pd.hDC, LOGPIXELSY);


		// Rendering to the same DC we are measuring.

		ZeroMemory(&fr, sizeof(fr));
		fr.hdc = fr.hdcTarget = pd.hDC;

		// Set up the page.

		fr.rcPage.left	 = fr.rcPage.top = 0;
		fr.rcPage.right	 = (nHorizRes/nLogPixelsX) * 1440;
		fr.rcPage.bottom	 = (nVertRes/nLogPixelsY) * 1440;

		// Set up 1" margins all around.

		fr.rc.left   = fr.rcPage.left + 1440;  // 1440 TWIPS = 1 inch.

		fr.rc.top    = fr.rcPage.top + 1440;
		fr.rc.right  = fr.rcPage.right - 1440;

		fr.rc.bottom = fr.rcPage.bottom - 1440;


		// Default the range of text to print as the entire document.

		fr.chrg.cpMin = 0;
		fr.chrg.cpMax = -1;

		// Fill out the DOCINFO structure.

		docInfo.cbSize = sizeof (DOCINFO);
		docInfo.lpszDocName = _T("a");
		docInfo.lpszOutput = NULL;

		// Be sure that the printer DC is in text mode.

		SetMapMode (pd.hDC, MM_TEXT);

		StartDoc (pd.hDC, &docInfo);
		StartPage (pd.hDC);

		// this line shows the display area when printing

		lTextOut = 0;
		lTextAmt = SendMessage(hwndRichEdit, WM_GETTEXTLENGTH, 0, 0);

		while (lTextOut < lTextAmt)
		{
			lTextOut = SendMessage(hwndRichEdit, EM_FORMATRANGE, TRUE,(LPARAM)&fr);
			if (lTextOut < lTextAmt)
			{
				EndPage (pd.hDC);
				StartPage (pd.hDC);
				fr.chrg.cpMin = lTextOut-1;
				fr.chrg.cpMax = -1;
			}
		}

		// Reset the formatting of the rich edit control.

		SendMessage(hwndRichEdit, EM_FORMATRANGE, TRUE, (LPARAM)NULL);

		// Finish the document.

		EndPage (pd.hDC);
		EndDoc (pd.hDC);

		// Delete the printer DC.

		DeleteDC (pd.hDC);
	}
}
Но проблема в том, что сообщение EM_FORMATRANGE всё время возвращает одно и то же значение, не обращая внимания на поля структуры fr.chrg, причём это значение меньше количества символов в контроле, из-за чего получается бесконечный цикл while (lTextOut < lTextAmt).
Если же под дебаггером изменить lTextOut так, чтобы оно было больше lTextAmt, то страница напечатается. И ещё: если текст мал(две небольшие строки) то всё печатается нормально.
P.S. Должен сказать, что принтера как такового у меня нет - я тренируюсь на проге, которая печатает в PDF. И с другими программами она работает отлично.
vito333
Сообщения: 6
Зарегистрирован: 14 сен 2004, 19:47

15 сен 2004, 10:12

сам столкнулся с этой проблемой, поискал в яндексе по formatrange и попал сюда )))
твой пост натолкнул где копать и нашелся косяк!
все заработало как надо.
все просто, но выложу решение чуть позже, так как сейчас с другого компа, на котором нет моего исходника.
а у меня такой вопрос - ты, как я посмотрел, еще всякие вопросы относительно винапи и ричедита задаешь тут на форуме - чего-то кодишь? если не секрет.
-----------
в двух словах - косяк тут:
lTextAmt = SendMessage(hwndRichEdit, WM_GETTEXTLENGTH, 0, 0);
-----------
ну а кусок моего кода - позже )))
-----
да, ответить можно на vito^rbcmail.ru
------
ааа, увидел-увидел - текстовй редактор пишешь )) - на чем если не секрет и почему винапи тебя так интересует?
просто я такую фигню в свободное время делаю - С++ и WinAPI
vito333
Сообщения: 6
Зарегистрирован: 14 сен 2004, 19:47

24 сен 2004, 18:06

// Определяем длину текста в байтах
//lTextSize = SendMessage(hRTF, WM_GETTEXTLENGTH, 0, 0); // так не работает !!!
//
lTextSize = (LONG)SendMessage(hRTF, EM_GETLINECOUNT, 0, 0); // получаем количество линий в ртф
lTextSize = (LONG)SendMessage(hRTF, EM_LINEINDEX, lTextSize-1, 0); //
lTextSize += (LONG)SendMessage(hRTF, EM_LINELENGTH, lTextSize, 0);
// Get exact text length
fr.chrg.cpMax = lTextSize;

// Цикл по всем страницам документа
while (lLastChar < lTextSize)
HumVee
Сообщения: 16
Зарегистрирован: 30 май 2004, 02:17
Откуда: Минск

24 окт 2004, 01:04

Сорри, давно не заглядывал на форум.
vito333, спасибо огромное, сейчас буду проверять.
Да, я в свободное время пытаюсь написать текстовый редактор, вроде Bred'a (на си).
Винапи интересует потому что быстро и очень компактно.
Ответить