Здравствуйте, RussianFellow, Вы писали:
RF>Есть диалоговое интерфейсное MFC-приложение. RF>Как правильно организовать из него программную печать информации на принтер?
Ну там есть функционал весь, но он сосредоточен в CDocument.
По идее, можно создать документ и вызвать его печать.
Здравствуйте, MasterZiv, Вы писали:
RF>>Есть диалоговое интерфейсное MFC-приложение. RF>>Как правильно организовать из него программную печать информации на принтер?
MZ>Ну там есть функционал весь, но он сосредоточен в CDocument. MZ>По идее, можно создать документ и вызвать его печать.
А следующий вопрос будет про Print Preview...
Поддержка печати сделана в Document/View модели.
Самый простой способ будет переделать "диалоговое" MFC-приложение в Document/View.
Я вообще не представляю себе для чего нужны эти диалоговые проложения, кроме простейших случаев.
Здравствуйте, MasterZiv, Вы писали:
MZ>Ну там есть функционал весь, но он сосредоточен в CDocument. MZ>По идее, можно создать документ и вызвать его печать.
Здравствуйте, VladFein, Вы писали:
VF>Здравствуйте, RussianFellow, Вы писали:
RF>>А структура CPrintInfo?
VF>
VF>Самый простой способ будет переделать "диалоговое" MFC-приложение в Document/View.
В связи с этим у меня два вопроса:
1) Можно ли вывести на принтер из программы текстовую информацию без использования Document/View?
То есть имеются три строки "строка1", "строка2", "строка3" типа char* (или, допустим, типа char[80], или типа std::string). Можно ли их вывести из программы на принтер без использования Document/View ?
2) В диалоговом приложении создаётся одно из диалоговых окон (которое активизируется при нажатии кнопки в другом окне) и в котором находится многострочное текстовое поле (типа CEdit, CRichEdit или CListCtrl), в котором находится текстовая информация. Можно ли к этому диалоговому окну как-то привязать объект класса CView (или его потомка), чтобы работала печать через Document/View только для этого диалогового окна (не применяя Document/View для всего диалогового приложения)?
Нужные действия — рисуем всякие фигуры, выводим текст, всё как в обычном обработчике WM_PAINT, только там с системой координат и шрифтами надо ещё разобраться, я уже подробностей не помню.
void CPrintSolvedNUDialog::OnBnClickedOk()
// если была нажата кнопка "Печать"
{
// TODO: добавьте свой код обработчика уведомленийint i, n;
CString myString;
LPCSTR pzText;
DWORD size = MAX_PATH;
TCHAR temp[MAX_PATH];
m_IDC_EDIT1.GetWindowTextA(myString);
n = myString.GetLength();
pzText = (LPCSTR)myString;
GetDefaultPrinter(temp,&size);
HDC hDC = CreateDC(NULL,temp,NULL,NULL);
if (hDC)
{
DOCINFO docinfo;
docinfo.cbSize = sizeof(docinfo);
docinfo.lpszDocName = "Simple";
docinfo.lpszOutput = NULL;
docinfo.lpszDatatype = "EMF";
docinfo.fwType = 0;
if (StartDoc(hDC,&docinfo)>0)
{
if (StartPage(hDC)>0)
{
TextOut(hDC,0,0,pzText,80);
EndPage(hDC);
}
EndDoc(hDC);
}
DeleteDC(hDC);
}
CDialogEx::OnOK();
}
Этот пример работает. Но он работает для одной строки, находящейся в многострочном текстовом поле CEdit.
А как правильно сделать так, чтобы этот пример работал и для тех случаев, когда в текстовом поле CEdit находятся несколько строк?
Следует ли сделать цикл считывания строк из m_IDC_EDIT1 (CEdit) внутри
if (StartPage(hDC>0))
{
//...
}
и там же выводить их на печать, или же цикл считывания строк из m_IDC_EDIT1 лучше сделать перед HDC hDC = CreateDC(NULL,temp,NULL,NULL);
--записать их в массив строк, а внутри
if (StartPage(hDC>0))
{
//...
}
работать с этим массивом строк?
Число выводимых строк примерно равно 55--60, так что они все дожны уместиться на одном листе.
Здравствуйте, RussianFellow, Вы писали:
RF>работать с этим массивом строк? RF>Число выводимых строк примерно равно 55--60, так что они все дожны уместиться на одном листе.
Вы поищите примеры рисования с помощью GDI. Если я правильно помню, DrawText может переносить текст внутри заданной области. Можно также оценить минимально необходимый размер области с помощью функций из того же семейства.
Но вообще, это всё очень низкоуровнево и неудобно. У документа могут быть поля, они могут быть разных размеров, ориентация листа может быть разной, вы это всё обязаны учитывать. Я бы на вашем месте попытался сделать вывод в Word, или просто в RTF, или в HTML.
Здравствуйте, RussianFellow, Вы писали:
RF>Этот пример работает. Но он работает для одной строки, находящейся в многострочном текстовом поле CEdit. RF>А как правильно сделать так, чтобы этот пример работал и для тех случаев, когда в текстовом поле CEdit находятся несколько строк?
Да совершенно пофиг как получать строки, просто зачем строки копировать во временный буфер? Пустая трата времени
Внутри цикла получать и тут же выводить.
Только это всё имеет смысл для действительно примитивных документов в пару строк, если структура документа предполагается хоть сколько-нибудь сложная — лучше использовать какое-то готовое средство. Генератор отчетов какой-нибудь, для MFC вроде был Crystal Reports, или перейти на doc/view, там есть вариант когда вью будет диалогом, сложностей особых не должно возникнуть.
RF>Число выводимых строк примерно равно 55--60, так что они все дожны уместиться на одном листе.
При таком подходе только хардкор — всё придется учитывать самому, размеры строк, размеры отступов, высоту шрифта и т.д.
Такой вопрос: как задать имя шрифта, размерность шрифта, атрибуты шрифта (обычный шрифт, толстый шрифт, наклонный шрифт), который будет выводиться на печать? И можно ли задать расстояние между строками, которые выводятся на печать?
Здравствуйте, RussianFellow, Вы писали:
RF>Такой вопрос: как задать имя шрифта, размерность шрифта, атрибуты шрифта (обычный шрифт, толстый шрифт, наклонный шрифт), который будет выводиться на печать? И можно ли задать расстояние между строками, которые выводятся на печать?
Создать контекст
Создать шрифт с необходимыми атрибутами
Загрузить шрифт в выполняемый контекст, получив дескриптор выгруженного объекта
Нарисовать строку/строки
Загрузить старый сохраненный дескриптор
Удалить шрифт
Удалить контекст
Здравствуйте, RussianFellow, Вы писали:
RF>Такой вопрос: как задать имя шрифта, размерность шрифта, атрибуты шрифта (обычный шрифт, толстый шрифт, наклонный шрифт), который будет выводиться на печать?
CrteateFont — там все параметры шрифта задаются.
RF> И можно ли задать расстояние между строками, которые выводятся на печать?
Конечно можно, в твоем примере расстояние между строками задается этим выражением yPos += cyChar;
Измени cyChar и будет или больше или меньше расстояние
Вообще вывод на печать практически не отличается от рисования на экране, просто в случае печати используется контекст принтера.
Здравствуйте, Evgeniy Skvortsov, Вы писали:
ES>Вообще вывод на печать практически не отличается от рисования на экране, просто в случае печати используется контекст принтера.
Функция setOutputInfo класса CPrintSolvedNUDialog--передача диалогу структуры aps типа addparstruct, в которой содержится много полей, для вывода в текстовое окно диалога:
Функция OnInitDialog класса CPrintSolvedNUDialog, в которой осуществляется вывод информации из структуры aps в многострочное текстовое поле (класс CEdit):
Функция OnBnClickedOk класса CPrintSolvedNUDialog--в неё осуществляется вывод информации, находящейся в многострочном текстовом поле (класс CEdit) на принтер:
И проблема заключается в следующем: вместо нормального вывода строк у меня на печать выводится что-то типа
Результаты решения краевой задачи по определению орбиты КА Мерный интер?ээээ<<<<<<<<<<<<<<<< ъ;М}фWNet Provider Class<<<<<<<<<<<<<<<<<<<<
Мерный интервал (дата/время): 2017.04.22/01:06: 9.184 — 2017.0ээээ<<<<<<<<<<<<<<<<ою?ээээ<<<<<<<< ъ;М}фWNet Provider Class<<<<<<<<
D | 1452HHHHHHHHHHHээээ<<<<<<<<ою
V | 1452HHHHHHHHHHH<<<<<<<<ээээ<<<<<<<<ою
?ээээ<<<<<<<< ъ;М{фWNet Provider Class
То есть у меня не выводятся правильно на печать переходы на новые строки, строки не всегда выводятся полностью (хотя длина любой из выводимых строк меньше 80 символов), не выводятся пустые строки--но зато выводится абракадабра.
В чём причина этого? Можно ли решить эту проблему и если да, то как её решить?
Ошибка скорее всего в твоих адских выкрутасах с получением строк.
Я попытался собрать этот кусок, но он даже не компилируется, там куча ошибок, как у тебя это запускается, я
(наверно у тебя проект не юникодный)
Запусти под отладчиком и посмотри что оказывается в pzText перед вызовом TextOut.
Здравствуйте, RussianFellow, Вы писали: RF>То есть у меня не выводятся правильно на печать переходы на новые строки, строки не всегда выводятся полностью (хотя длина любой из выводимых строк меньше 80 символов), не выводятся пустые строки--но зато выводится абракадабра.
int len = m_IDC_EDIT1.LineLength(i);
if (len>0)
{
m_IDC_EDIT1.GetLine(i,myString.GetBuffer(len),len);
myString.ReleaseBuffer();
}
else
myString = " ";
myString = myString + "\r\n"; // <- это лишнее
pzText = myString.GetBuffer();
TextOut(hDC,0,yPos,pzText,len); // <- здесь надо указать длину строки, а не 90
Здравствуйте, RussianFellow, Вы писали: RF>И ещё вопрос: как программно выдать на печать текстовой файл из MFC-приложения?
Я думаю. что это не сложно. Прочитайте содержимое файла в контрол CEdit и печатайте его стандартными методами.
Подсказка: CEdit — наследник CWnd.
И ещё вопрос:
RF>Функция OnBnClickedOk класса CPrintSolvedNUDialog--в неё осуществляется вывод информации, находящейся в многострочном текстовом поле (класс CEdit) на принтер:
RF>
Здравствуйте, Nikita123, Вы писали:
N>Я думаю. что это не сложно. Прочитайте содержимое файла в контрол CEdit и печатайте его стандартными методами. N>Подсказка: CEdit — наследник CWnd.
Я решил это по-другому (фрагмент кода):
if (StartDoc(hDC,&docinfo)>0)
{
if (StartPage(hDC)>0)
{
f = fopen("results.txt","rt");
while (!feof(f))
{
fgets(s,256,f);
len = strlen(s);
pzText = (LPCSTR)s;
TextOut(hDC,0,yPos,pzText,len);
yPos += cyChar;
}
fclose(f);
EndPage(hDC);
}
EndDoc(hDC);
}
Здравствуйте, RussianFellow, Вы писали:
RF>Есть диалоговое интерфейсное MFC-приложение. RF>Как правильно организовать из него программную печать информации на принтер?