Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » VC++ / MFC » Drucken aus Dialoganwendung

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
24.11.2002, 13:57 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


Wie kann man in einer Dialoganwendung "richtig" drucken, nicht nur Postscript?

Wenn ich folgendes mach versucht er 35000 seiten zu drucken:


C++:
CDC dc;
CPrintDialog printDlg(FALSE);

if (printDlg.DoModal() == IDCANCEL)
    return;

dc.Attach(printDlg.GetPrinterDC());
dc.m_bPrinting = TRUE;

DOCINFO di;
::ZeroMemory (&di, sizeof (DOCINFO));
di.cbSize = sizeof (DOCINFO);
di.lpszDocName = "Database";

BOOL bPrintingOK = dc.StartDoc(&di);

CPrintInfo Info;

Info.m_rectDraw.SetRect(0,0, dc.GetDeviceCaps(HORZRES), dc.GetDeviceCaps(VERTRES));

OnBeginPrinting(&dc, &Info);
for (UINT page = Info.GetMinPage(); page <= Info.GetMaxPage() && bPrintingOK; page++)
{
    dc.StartPage();
    Info.m_nCurPage = page;
    OnPrint(&dc, &Info);
    bPrintingOK = (dc.EndPage() > 0);
}
OnEndPrinting(&dc, &Info);

if (bPrintingOK)
    dc.EndDoc();
else
    dc.AbortDoc();

dc.Detach();

// ...

void CDlgClass::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo)
{
}

void CDlgClass::OnPrint(CDC* pDC, CPrintInfo* pInfo)
{
}

void CDlgClass::OnEndPrinting(CDC* pDC, CPrintInfo* pInfo)
{
}



--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
24.11.2002, 16:35 Uhr
Uwe
C/C++ Master
(Administrator)


Hallo Flo,
schaut so aus als ob Du nicht die aktuelle Seitenanzahl ermittelst und über SetMaxPage zuweist.
--
"Es ist schwierig, ein Programm wirklich idiotensicher zu machen, weil Idioten so genial sind."

Bis dann...
Uwe
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
24.11.2002, 17:01 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


Ah Hallo Uwe schon zurück?
Hab ich auch gemerkt, nur wie kann ich die Daten dann ohne CView drucken, hab die Daten in einem DHtmlDialog ...
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
24.11.2002, 21:47 Uhr
Uwe
C/C++ Master
(Administrator)


Hallo Flo,
quote]FloSoft postete
Ah Hallo Uwe schon zurück?
[/quote]
Kann man so nennen . Spass beiseite, Ohne Ansicht wird's etwas schwierig mit dem Drucken. Wenn es noch bis morgen Abend Zeit hat, kramse ich mal und poste etwas.
(Bei Deinem Bsp. hat Chris etwas vergessen )
--
"Es ist schwierig, ein Programm wirklich idiotensicher zu machen, weil Idioten so genial sind."

Bis dann...
Uwe
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
25.11.2002, 08:00 Uhr
FloSoft
Medialer Over-Flow
(Administrator)



Zitat:
Uwe postete
(Bei Deinem Bsp. hat Chris etwas vergessen )[/i]

Ähm welcher Chris und was für Bsp?

Lass dir ruhig zeit ...
Kann man nicht irgendwie ne View "simulieren"? Über die ich dann drucken kanm? Vielleicht kann man ja, da ich etwas drucken will was in einer TabCtrl liegt, irgendwie damit ne View "hinstöpseln"?
--
class God : public ChuckNorris { };

Dieser Post wurde am 25.11.2002 um 08:02 Uhr von FloSoft editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
26.11.2002, 19:27 Uhr
Uwe
C/C++ Master
(Administrator)


Hallo Flo,
hat zwar etwas länger gedauert aber...

Projektformat Dialoganwendung mit zwei Schaltflächen: IDC_OPEN_FILE und IDC_PRINT_FILE.
Hinzufügen einer von CDocument abgeleiteten Klasse, in dieser alles was notwendig ist "public:" machen.
Variable:
C++:
public:
      CStringList filelines_str ;

Funktion

C++:
void CMyDoc::OpenFile()
{
    mydlg d;

    if ( d.DoModal( ) == IDOK ){
        CStdioFile fr ( d.filepath_str, CFile::modeRead  ) ;//| CFile::typeText ) ;
        filelines_str.RemoveAll( ) ;
        CString str ;
        while ( fr.ReadString ( str ) ){
            filelines_str.AddTail ( str ) ;
        }
        SetTitle ( d.filename_str ) ;
    }

}
hinzufügen. "mydlg" ist von CDialog abgeleitet und dient der Auswahl der entsprechenden zu druckenden Datei. In diesem ist ein Eingabefeld (IDC_FILE_PHATH) und ein Button (IDC_BROWSE). Dem Eingabefeld ist
C++:
CString    filepath_str;
zugeordnet. Weithin existiert eine
C++:
CString filename_str ;
Variable, welch public ist.

C++:
BOOL mydlg::OnInitDialog()
{
    filepath_str = "Enter filename here or browse" ;
    return CDialog::OnInitDialog( ) ;
}

void mydlg::OnBrowse()
{
    CFileDialog f ( TRUE, NULL, NULL, NULL,
        "Text Files(*.txt)|*.txt|CPP Files(*.cpp,*.h)|*.cpp;*.h||" )  ;

    if ( f.DoModal( ) == IDOK ){
        CString s = f.GetPathName( ) ;
        filename_str = f.GetFileName( ) ;
        SetDlgItemText ( IDC_FILE_PHATH, s ) ;
    }    
}

Variablenliste der Hauptdialogklasse:

C++:
private:
    CMyDoc mydoc ;
    CFont scr_font, prn_font ;
    int scr_ht, scr_wd, prn_ht, prn_wd, linesperpage, charsperline, max_page ;
    CStringList prn_str ;



C++:
ON_BN_CLICKED(IDC_PRINT, OnPrintIt)


Dafür die Behandlung:

C++:
void CPrintItDlg::OnPrintIt()
{
    CDC dc;
    CPrintDialog printDlg(FALSE);

    if (printDlg.DoModal() == IDCANCEL)
        return;

    dc.Attach(printDlg.GetPrinterDC());
    dc.m_bPrinting = TRUE;

    DOCINFO di;
    ::ZeroMemory (&di, sizeof (DOCINFO));
    di.cbSize = sizeof (DOCINFO);
    di.lpszDocName = "Database";

    BOOL bPrintingOK = dc.StartDoc(&di);
    CPrintInfo Info;

    Info.m_rectDraw.SetRect(0,0, dc.GetDeviceCaps(HORZRES), dc.GetDeviceCaps(VERTRES));

    OnBeginPrinting(&dc, &Info);
    for (UINT page = Info.GetMinPage(); page <= Info.GetMaxPage() && bPrintingOK; page++){
        dc.StartPage();
        Info.m_nCurPage = page;
        OnPrint(&dc, &Info);
        bPrintingOK = (dc.EndPage() > 0);
    }
    OnEndPrinting(&dc, &Info);
    if (bPrintingOK)
        dc.EndDoc();
    else
        dc.AbortDoc();
    dc.Detach();

}


Und der Rest:

C++:
void CPrintItDlg::OnBeginPrinting(CDC *pDC, CPrintInfo *pInfo)
{
    pDC -> SetMapMode ( MM_LOENGLISH ) ;
    prn_font.CreatePointFont ( 100, "Arial", pDC ) ;
    CFont *prevfont = pDC -> SelectObject ( &prn_font ) ;

    TEXTMETRIC tm ;
    pDC -> GetTextMetrics ( &tm) ;
    prn_ht = tm.tmHeight + tm.tmExternalLeading ;
    prn_wd = tm.tmAveCharWidth + 1 ;

    // total number of pixels per page in device coordinates
    int vertpixels = pDC -> GetDeviceCaps ( VERTRES ) ;
    int horzpixels = pDC -> GetDeviceCaps ( HORZRES ) ;

    // convert into logical coordinates
    CSize sz ( horzpixels, vertpixels ) ;
    pDC -> DPtoLP ( &sz ) ;

    linesperpage = sz.cy / prn_ht ;
    charsperline = sz.cx / prn_wd ;
    
    // make space for header and footer
    linesperpage = linesperpage - 10 ;

    CString tempstr ;
    POSITION temppos = mydoc.filelines_str.GetHeadPosition( ) ;
    int tempcount = mydoc.filelines_str.GetCount( ) ;
    for ( int i = 0 ; i < tempcount ; i++ )
    {
        tempstr = mydoc.filelines_str.GetNext ( temppos ) ;
        prn_str.AddTail ( tempstr ) ;
    }

    POSITION pos = prn_str.GetHeadPosition( ) ;
    POSITION pos_prev1, pos_prev2 ;
    
    int count = prn_str.GetCount( ) ;

    CString str, pa ;
    for ( i = 0 ; i < count ; i++ )
    {
        if ( pos == NULL )
            break ;

        pos_prev1 = pos_prev2 = pos ;
        str = prn_str.GetNext ( pos ) ;

        str.Replace ( "\t", "    " ) ;

        int len = str.GetLength( ) ;
        if ( len > charsperline )
        {
            int linecount = max ( 1, ( len + ( charsperline - 1 ) ) / charsperline ) ;
    
            CString left_str ;
            int remain_len, left_len = 0 ;
            for ( int j = 0 ; j < linecount ; j++ )
            {
                left_str = str.Left ( charsperline ) ;
                prn_str.InsertAfter ( pos_prev2, left_str ) ;
                
                left_len += left_str.GetLength( ) ;
                remain_len = len - left_len ;
                
                prn_str.GetNext ( pos_prev2 ) ;
                str = str.Right ( remain_len ) ;
            }
            str = "" ;

            pa = prn_str.GetAt ( pos_prev1 ) ;
            prn_str.RemoveAt ( pos_prev1 ) ;
            pa.FreeExtra( ) ;
        }
        else
        {
            prn_str.InsertAfter ( pos_prev1, str ) ;
            pa = prn_str.GetAt ( pos_prev1 ) ;
            prn_str.RemoveAt ( pos_prev1 ) ;
            pa.FreeExtra( ) ;
        }
    }

    count = prn_str.GetCount( ) ;
    max_page = max ( 1, ( count + ( linesperpage - 1 ) ) / linesperpage ) ;
    pDC -> SelectObject ( prevfont ) ;
    pInfo -> SetMaxPage ( max_page ) ;
}

void CPrintItDlg::OnPrint(CDC *pDC, CPrintInfo *pInfo)
{
    CFont* prevfont = pDC -> SelectObject ( &prn_font ) ;

    TEXTMETRIC tm ;
    pDC -> GetTextMetrics ( &tm ) ;

    // center coordinate
    int horzpixels = pDC -> GetDeviceCaps ( HORZRES ) ;
    CSize sz ( horzpixels, 0 ) ; pDC -> DPtoLP ( &sz ) ;
    int center = sz.cx / 2 ;

    // printheader
    CString title = mydoc.GetTitle( ) ;
    UINT l = center - ( ( title.GetLength( ) / 2 )  * tm.tmAveCharWidth ) ;
    pDC -> TextOut ( l, 0, title ) ;

    // printpage
    int count = prn_str.GetCount( ) ;

    int start = ( ( pInfo -> m_nCurPage ) - 1 ) * linesperpage ;
    int end = start + linesperpage ;
    
    POSITION pos = prn_str.FindIndex ( linesperpage * ( ( pInfo -> m_nCurPage ) - 1 ) ) ;
    for ( int i = start, y = - ( prn_ht * 5 ) ; i < end && i < count ; i++ )
    {
        pDC -> TextOut ( 10, y, ( CString ) prn_str.GetNext ( pos ) ) ;
        y -= prn_ht ;
    }

    // printfooter
    CString pagenumber ;
    pagenumber.Format ( "%2d / %2d", pInfo -> m_nCurPage, max_page ) ;
    l = center - ( ( pagenumber.GetLength( ) / 2 )  * tm.tmAveCharWidth ) ;
    pDC -> TextOut ( l, - ( linesperpage + 5 + 3 ) * prn_ht, pagenumber ) ;

    pDC -> SelectObject ( prevfont ) ;
}

void CPrintItDlg::OnEndPrinting(CDC *pDC, CPrintInfo *pInfo)
{
    prn_str.RemoveAll( ) ;
    prn_font.DeleteObject( ) ;
}


Formatierung der Seite ist Dir überlassen. Bei Bedarf schick ich Dir das Projekt. Mit 'ner View was zu basteln geht nich gut ;-)
--
"Es ist schwierig, ein Programm wirklich idiotensicher zu machen, weil Idioten so genial sind."

Bis dann...
Uwe
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
26.11.2002, 20:17 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


hmm das Problem ist im Moment noch, das ich eben ne "vorformatierte" HTML-Datei hab, welche eben in nem DHTML-Dialog angezeigt wird, die möchte ich eben ausdrucken ...

Vielleicht mach ich das auch mit ner SDI-Anwendung, wenn mir einer sagt wie ich ne ListCtrl Links daneben bekomm:

|--|-------------|
|LC| HTMLView |
| | |
| | |
| | |
|--|-------------|
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ VC++ / MFC ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: