PDA

Просмотр полной версии : Печать и SDK. Помогите разобраться!



HumVee
06.08.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
15.09.2004, 10:12
сам столкнулся с этой проблемой, поискал в яндексе по formatrange и попал сюда )))
твой пост натолкнул где копать и нашелся косяк!
все заработало как надо.
все просто, но выложу решение чуть позже, так как сейчас с другого компа, на котором нет моего исходника.
а у меня такой вопрос - ты, как я посмотрел, еще всякие вопросы относительно винапи и ричедита задаешь тут на форуме - чего-то кодишь? если не секрет.
-----------
в двух словах - косяк тут:
lTextAmt = SendMessage(hwndRichEdit, WM_GETTEXTLENGTH, 0, 0);
-----------
ну а кусок моего кода - позже )))
-----
да, ответить можно на vito^rbcmail.ru
------
ааа, увидел-увидел - текстовй редактор пишешь )) - на чем если не секрет и почему винапи тебя так интересует?
просто я такую фигню в свободное время делаю - С++ и WinAPI

vito333
24.09.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
24.10.2004, 01:04
Сорри, давно не заглядывал на форум.
vito333, спасибо огромное, сейчас буду проверять.
Да, я в свободное время пытаюсь написать текстовый редактор, вроде Bred'a (на си).
Винапи интересует потому что быстро и очень компактно.