Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум на Исходниках.RU > Visual C++ / MFC / WTL > Как правильно печатать многостраничный файл?


Автор: erslgoeirjh 10.07.19, 08:14
Есть текстовой файл results.txt . Его нужно вывести на принтер.
При этом этот файл может иметь как одну страницу, так и две страницы--его размер неизвестен.

Если этот файл имеет одну страницу, то проблем с его печатью не возникает. Вот код:

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    void CPrintSolvedNUDialog::OnBnClickedOk()
    // если была нажата кнопка "Печать"
    {
        // TODO: добавьте свой код обработчика уведомлений
        int  i, n, len, cyChar, cyPage, yPos, strcount, xlpPrinter, ylpPrinter;
        char  s[256];
        CString  myString;
        LPCSTR  pzText;
        LPTSTR  lpszText;
        DWORD  size = MAX_PATH;
        TCHAR  temp[MAX_PATH];
        TEXTMETRIC  txtm;
        LOGFONT lf, lf2;
        CFont  myFont, myFont2;
        FILE *f;
     
        strcount = 0;
        CPrintDialog  cp(FALSE);
        if (cp.DoModal()==IDOK)
        {
            CDC  printDC;
            printDC.Attach(cp.GetPrinterDC());
            cyPage = printDC.GetDeviceCaps(VERTRES);
            printDC.GetTextMetrics(&txtm);
            cyChar = txtm.tmHeight + txtm.tmExternalLeading;
            yPos = 0;
            xlpPrinter = ::GetDeviceCaps(printDC,LOGPIXELSX);
            ylpPrinter = ::GetDeviceCaps(printDC,LOGPIXELSY);
            DOCINFO  docinfo;
            ::ZeroMemory(&docinfo,sizeof(DOCINFO));
            docinfo.cbSize = sizeof(docinfo);
            docinfo.lpszDocName = "Simple";
            docinfo.lpszOutput = NULL;
            docinfo.lpszDatatype = "RAW";
            docinfo.fwType = 0;
            CFont *savedFont;
            savedFont = printDC.GetCurrentFont();
            savedFont->GetLogFont(&lf);
            savedFont->GetLogFont(&lf2);
            strcpy(lf.lfFaceName,"Courier New");
            lf.lfHeight = 15;
            lf.lfWidth = 6;
            lf.lfHeight = (int)(((long double)lf.lfHeight/72.0)*(long double)ylpPrinter);
            lf.lfWidth = (int)(((long double)lf.lfWidth/72.0)*(long double)xlpPrinter);
            myFont.CreateFontIndirectA(&lf);
            strcpy(lf2.lfFaceName,"Courier New");
            lf2.lfHeight = 18;
            lf2.lfWidth = 6;
            lf2.lfHeight = (int)(((long double)lf2.lfHeight/72.0)*(long double)ylpPrinter);
            lf2.lfWidth = (int)(((long double)lf2.lfWidth/72.0)*(long double)xlpPrinter);
            myFont2.CreateFontIndirectA(&lf2);
            printDC.SelectObject(&myFont);
            if (printDC.StartDoc(&docinfo)>0)
            {
                if (printDC.StartPage()>0)
                {
                    f = fopen("results.txt","rt");
                    while (!feof(f))
                    {
                        fgets(s,256,f);
                        len = strlen(s);
                        pzText = (LPCSTR)s;
                        if (strcount==2)
                            printDC.TextOutA(500,yPos,pzText,len);
                        else
                            printDC.TextOutA(320,yPos,pzText,len);
                        yPos += cyChar;
                        strcount++;
                        if (strcount==2)
                            printDC.SelectObject(&myFont2);
                        else if (strcount==3)
                            printDC.SelectObject(&myFont);
                    }
                    fclose(f);
                    printDC.EndPage();
                }
                printDC.EndDoc();
            }
            printDC.SelectObject(savedFont);
            printDC.Detach();
        }
        //CDialogEx::OnOK();
    }


Как сделать так, чтобы печать правильно шла и в том случае, когда файл results.txt имеет две страницы?

Автор: ЫукпШ 10.07.19, 08:48
Цитата erslgoeirjh @
Как сделать так, чтобы печать правильно шла и в том случае, когда файл results.txt имеет две страницы?

Давно делал, все детали не помню.
---
Если мы точно знаем, какой макет (общий вид страницы), то можем определять
вертикальный размер печати при данном количестве строк.
Когда при некотором количестве строк превышается допустимый
размер для одной страницы, тогда печатаем допустимое количество строк.
Следующую допустимую по количеству строк порцию - на следующей
странице и.т.д.
Для этого можно пытаться делать DC в памяти, совместимый с DC принтера.
(Для конкретного DC и фонта всегда можно точно определить размер текста.)
Как то так.
---
Ещё полезно делать мета-данные для каждой страницы - это позволит
делать просмотр перед печатью.
---
Такие опыты лучше делать с виртуальным принтером, чтобы ресурсы
принтера не тратить.

Powered by Invision Power Board (https://www.invisionboard.com)
© Invision Power Services (https://www.invisionpower.com)