Tutorials zu Drucken !?



  • Hast du mittlerweile was gefunden ansonsten könnte ich dir meinen funktionierenden Drucker Code anbieten. Der ist eigentlich einfach zu verstehen und ich denk mal das die Kommentare auch eindeutig sind.



  • kann ja nicht schaden, zeig mal her 😉



  • Behandelt dein Code auch Drucken in einer dialogbasierenden Anwendung? Ich finde immer nur etwas, wo man Funktionen der CView - Klasse nimmt.
    Oder wie heissen genau die Befehle. Den Rest kann ich mir wahrscheinlich zusammenschustern. 😉



  • Weil mir die eingebauten Funktionen nicht gefallen haben, habe ich meine eigenen gebastelt.
    Statt im Doc kann man die auch im Dialog aufrufen:

    void CBasisDoc::DruckBeginnen(CDC& dc)
    {
    	// Druckjob anlegen
    	DOCINFO docInfo;
    	docInfo.cbSize = sizeof(DOCINFO);
    	docInfo.lpszDocName = _T("Mein Programm");
    	docInfo.lpszOutput = (LPTSTR)NULL;
    	docInfo.fwType = 0;
    
    	// Druckdialog anlegen aber nicht aufrufen
    	CPrintDialog dlg(FALSE); 
    	dlg.GetDefaults();
    
    	// DC anlegen
    	dc.Attach(dlg.GetPrinterDC()); 
    
    	// MapMode ändern (Each logical unit is 0.1 millimeter. Positive x is to the right; positive y is up.)
    	dc.SetMapMode(MM_LOMETRIC);
    
    	// Drucken beginnen
    	dc.StartDoc(&docInfo);
    	dc.StartPage();
    }
    void CBasisDoc::DruckBeenden(CDC& dc)
    {
    	// Drucken beenden
    	dc.EndPage();
    	dc.EndDoc();
    }
    

    Aufgerufen wird das so:

    CDC dcDrucker;
    	CBasisDoc::DruckBeginnen(dcDrucker);
    
    // Hier kann jetzt auf dem Drucker-DC gemalt werden, wie man das von Scribble kennt.
    
    	CBasisDoc::DruckBeenden(dcDrucker);
    


  • Also der Druckercode ist für ein Musik Datenbank Programm.
    Ich arbeite mit ner CListCtrl. guck es dir einfach mal an wenn de was nicht verstehst kannste ja bescheid sagen.

    void PrintList(CListCtrl &list);
    
    void Suche_Speicher::OnbtnPrint() 
    {
    
    	PrintList(m_ListDataFound);    
    
    }
    
    void PrintList(CListCtrl &list)
    {
        CDC             dc;
        CPrintDialog    printDlg(FALSE);
        CRect           r;
        int             nHeight;
    
        // ask the user to select a printer
        if (printDlg.DoModal() == IDCANCEL)
            return;
    
        // Attach a printer DC
        dc.Attach(printDlg.GetPrinterDC());
        dc.m_bPrinting = TRUE;
    
        // use Textmappingmode, that's easiest to map the fontsize
        dc.SetMapMode(MM_TEXT);
    
        // setup font specifics
        LOGFONT LogFont;
    
        CFont	aFont, *oldFont;
    
        LogFont.lfHeight = -MulDiv(10, GetDeviceCaps(dc, LOGPIXELSY), 72);
        LogFont.lfWidth = 0;
        LogFont.lfEscapement = 0;
        LogFont.lfOrientation = 0;
        LogFont.lfWeight = 0;
        LogFont.lfItalic = false;
        LogFont.lfUnderline = 0;
        LogFont.lfStrikeOut = 0;
        LogFont.lfCharSet = ANSI_CHARSET;
        LogFont.lfOutPrecision = OUT_TT_PRECIS;
        LogFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
        LogFont.lfQuality = DEFAULT_QUALITY;
        LogFont.lfPitchAndFamily = DEFAULT_PITCH | FF_SWISS;
        lstrcpy (LogFont.lfFaceName, "MS Sans Serif");
        dc.SetBkMode(OPAQUE);
        aFont.CreateFontIndirect ( &LogFont );
        // ok, we've build the font, now use it
        oldFont = dc.SelectObject( &aFont );
    
        // Get the application title
        CString strTitle;
        strTitle.LoadString(AFX_IDS_APP_TITLE);
    
        // Initialise print document details
    
        DOCINFO di;
        ::ZeroMemory (&di, sizeof (DOCINFO));
        di.cbSize = sizeof (DOCINFO);
        // application title appears in the spooler view
        di.lpszDocName = strTitle;
    
    //*****************Begin a new print job**************************************************
    	CString Line;	
    
    	BOOL bPrintingOK = dc.StartDoc( &di );
    
        // Get the printing extents and store in the m_rectDraw field of a
        // CPrintInfo object
        CPrintInfo Info;
        int w = dc.GetDeviceCaps(HORZRES);
        int h = dc.GetDeviceCaps(VERTRES);
        Info.m_rectDraw.SetRect(0,0, w, h);
    
        const char *startAt = LPCTSTR(Line);
        int totalDone = 0;
        int lengthToGo = Line.GetLength();
    
     //   for (UINT page = Info.GetMinPage();
      //  bPrintingOK ; page++)
    
            // begin new page
    		int page  = Info.GetMinPage();
            dc.StartPage();
            Info.m_nCurPage = page;
    
            // calc how much text fits on one page
            r = Info.m_rectDraw;
            r.bottom = r.top;
            int i = 0;
            while (r.bottom < Info.m_rectDraw.bottom && (totalDone + i < lengthToGo) )
            {
                r.right = Info.m_rectDraw.right;
                nHeight = dc.DrawText(startAt, i++, r,
                    DT_CALCRECT|DT_WORDBREAK|DT_NOCLIP|DT_EXPANDTABS);
            }
            // go one back to assure correct height
            if (r.bottom >= Info.m_rectDraw.bottom)
                i--;
    
    		//Print all entries from the list
    
    		int y = 0;
    		for (int item = 0; item<list.GetItemCount(); item++)
    		{
    			CRect rect( 0, 0, 300, 50 );
    			rect = Info.m_rectDraw;
    			rect.OffsetRect( 0, y );
    
    			for ( int subItem = 0; subItem < 5; ++subItem )
    			{
    				Line =  list.GetItemText( item, subItem );
    				dc.DrawText( 
    						LPCTSTR(Line), 
    						Line.GetLength(), 
    						rect, 
    						DT_WORDBREAK|DT_NOCLIP|DT_EXPANDTABS);
    				rect.OffsetRect( 600 + 20, 0 );
    			}
    
    			y += 50;
    		}
    
    	// end page
    	bPrintingOK = (dc.EndPage() > 0);
    
        // end a print job
        if (bPrintingOK)
            dc.EndDoc();
        else
            // abort job.
            dc.AbortDoc();
    
        // restore font
        dc.SelectObject(oldFont);
        // free font memory
        aFont.DeleteObject();
        // detach the printer DC
        dc.Detach();
    }
    

    Eigentlich müssteste verstehen wie der Ablauf ist ansonsten Frag einfach

    Gruss Silver



  • jo ist wirklich ganz gut zu verstehen, danke euch.

    @estartu: hast du schon mit den dynamischen steruelementen angefangen ?? 😉



  • jo.. hab den Code mal getestet und er scheint Problemlos zu Funktionieren. Währe ja auch vllt was für die FAQ, aber dann mach vorher noch Multipage Support rein... weil im moment kann man nur eine Seite drucken...



  • @Red Skall: Nein, momentan male ich Checkboxen (siehe anderer Thread). 🙄
    Dann male ich Radiobuttons...

    Für die dynamischen Controls muss ich noch nen Zettel kriegen, der mal wieder auf sich warten lässt. 😉



  • Hallo nochmals
    war das mit dem Multipage Support an mich @ (D)Evil 😕



  • @Silvercreast: Danke dir, funktioniert super... 👍 aber ich kann auch nur eine Seite drucken... 😕



  • Ok Moment hmm ich hätte es auch mal ausprobieren sollen mehrere zu drucken dann wäre mir das wahrscheinlich aufgefallen hups 🙄 Ok ich kümmer mich drum das zu ändern, erstmal gucken wie ich das mache. 😃 Dann setz ich den überarbeiteten Code hier rein.

    Gruss Silver



  • @estartu_de: aso 😉

    @(D)Evil: das ist ja kein problem:
    alles von StartDoc() bis EndDoc() in eine schleife und dann in der schleife rgendwas auf den DC schreiben 💡



  • die Standartversion von OnBeginPrinting sieht so aus

    void CTtestView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
    {
    	// ZU ERLEDIGEN: Zusätzliche Initialisierung vor dem Drucken hier einfügen
    }
    

    Hier muss das Kommentar von den Paramtern entfernt werden
    ->void CTtestView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo)

    Innerhalb der OnBeginPrinting() Funktion muss die Anzahl der zu druckenden Seiten festgelegt werden. Dies geschieht mit hilfe von
    void SetMaxPage( UINT nMaxPage )
    z.B. pInfo->SetMaxPage(3);

    Desweiteren müssen die Informationen über en Drucker-Gerätekontext mit Hilfe von
    GetDeviceCaps() beschafft werden.
    z.b.:
    int pageHeight = pDC->getDeviceCaps(VERTRES);
    int logPixelsY = pDC->getDeviceCaps(LOGPIXELSY);
    ...
    VERTRES z.b. ist eine Konstante die die Pixel in Vertikaler Richtung angibt die bedruckt werden können. die Horizontale Konstatnte wäre HORZRES.
    Insgesamt gibt es 29 versch. Konstaten die ich jetzt hier nicht alle aufzählen möchte ^^

    mit diesen Werten kann man dann z.b. Berechnen was noch auf eine Seite passt und was nicht.

    Hat man das alles hinter sich und schaut sich das an freut man sich das man auf mehreren Seiten etwas sieht. Aber halt! da steht immer das gleiche.

    Den Ursprung festlegen:

    Damit die zweite und folgenden seiten korrekt ausgegeben werden muss man MFC noch mitteilen wo die Seitenanfänge liegen.
    Dazu muss man zuerst OnPrepareDC() überschreiben:
    z.b. so:

    void CPrint1View::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo)
    {
      if (pDC->IsPrinting())
      {
         int pageHeight = pDC->GetDeviceCaps(VERTRES);
         int originY = pageHeight * (pInfo->m_nCurPage - 1);
         pDC->SetViewportOrg(0,-originY);
      }
      CView:: OnPrepareDC(pDC,pInfo);
    }
    

    OnPrepareDC() wird aufgerufe, kurz bevor Daten auf den Bildschirm bzw auf den Drucker ausgegeben werden.

    So das ganze hab ich mehr oder weniger aus einem Buch abgepinselt ich hoff mal ich hab nichts vergessen. 🙄

    ich hoff es hilft das ganze auf mehrere Seiten zu erweitern



  • aso, falls ich mal mit MDI / SDI arbeite hab ich ja jetzt was 😉
    ich benutzte ja immer nur Dialogfelder



  • Taelan, eines hast du vergessen:
    Welches Buch? 😉

    Aber die Beschreibung ist super! 👍
    Ich such mal durch die Faq, wenn da noch nix in der Art ist, kommts rein. 🙂

    Nein, das scheint es noch nicht zu geben...
    Mach bitte mal die schöne Erklärung von eben mit Quellangabe als neuen Beitrag mit einer sprechenden Überschrift, ich verschiebe es dann. 🙂



  • Oh sry vor lauter tippen doch tatsächlich die Quelle vergessen ^^
    Das Buch heisst:
    Visual C++.Net, Markt+Technik von Kate Gregory ISBN: 3827264596

    kann ich absoluten Einsteigern eher weniger empfehlen aber wenn man sich mal etwas mit VC++/MFC zurechtgefunden hat ist es wirklich gut

    @Redskall
    Huch das mit dem Dialogbasiert hab ich wohl großzügig überlesen ^^
    Kommt daher das ich mich dran gewöhnt hab SDI/MDI Anwendungen mit CFormViews zu machen



  • @Taelan: no problem 😉
    würde eigentlich auch gerne mal mit FormViews arbeiten aber traue mich nicht ^^



  • Ist eigentlich ganz einfach
    neues projekt und auf der letzten Seite wo du die Dateinamen ändern kannst auf CFormView stellen.
    Dann kannst du deine Sachen wie üblich im ressourcen Editor zeichnen.

    Das einzige was im ersten moment etwas komisch ist, ist das umschalten zwischen versch. Formviews in einer SDI anwendung. Aber zum Glück hab ich 2 nette Informatiker hier die mir das geschrieben haben 😃



  • Taelan schrieb:

    Ist eigentlich ganz einfach
    neues projekt und auf der letzten Seite wo du die Dateinamen ändern kannst auf CFormView stellen.
    Dann kannst du deine Sachen wie üblich im ressourcen Editor zeichnen.

    Das einzige was im ersten moment etwas komisch ist, ist das umschalten zwischen versch. Formviews in einer SDI anwendung. Aber zum Glück hab ich 2 nette Informatiker hier die mir das geschrieben haben 😃

    Jupp, es ist wirklich einfach, ich habe genau das hier. 🙂
    Wegen Umschalten, guck mal in die FAQ. 😉

    Taelan, machst du den Beitrag? 🙂



  • habe schon mal ne anwendung gebastelt zum ausprobieren und kahm genau das was du meinst mit 'etwas komisch' 😉

    ich versuche es demnächst wenn ich zeit dafür hab !!

    danke für die motivation, und sorry für den missbrauch des threads ^^


Anmelden zum Antworten