Drucken: Papierorientierung dynamisch ändern



  • Hi Leute,

    ich habe ein Problem: In meiner MDI-Applikation muss ich beim Drucken von X Blättern die ersten (X-1) Blätter im Hochformat drucken und das letzte Blatt im Querformat.
    Leider schaffe ich es weder, das Format auf Hochformat umzustellen, falls der User im Druckerdialog Querformat gewählt hat, noch schaffe ich es, das Format für die letzte Seite auf Querformat zu stellen...

    Hier ist mein Code:

    void CMyView::OnPrint(CDC* pDC, CPrintInfo* pInfo) 
    {
    	DEVMODE *pDevMode = (DEVMODE*)::GlobalLock(pInfo->m_pPD->m_pd.hDevMode) ;
    	// set orientation to portrait
    	if(pDevMode->dmOrientation==DMORIENT_LANDSCAPE)
    	{
    		pDevMode->dmOrientation = DMORIENT_PORTRAIT;
    		pDevMode->dmPelsHeight=pDC->GetDeviceCaps(HORZRES);
    		pDevMode->dmPelsWidth=pDC->GetDeviceCaps(VERTRES);
    		pDC->ResetDC(pDevMode);
    	}
    
    	CBaseAppView::OnPrint(pDC, pInfo);
    
    	if(pInfo->m_nCurPage+1==pInfo->GetMaxPage())
    	{
    		pDC->EndPage();
    		DEVMODE *pDevMode = (DEVMODE*)::GlobalLock(pInfo->m_pPD->m_pd.hDevMode) ;
    		// set orientation to landscape
    		pDevMode->dmOrientation = DMORIENT_LANDSCAPE ;
    		pDevMode->dmPelsHeight=pDC->GetDeviceCaps(HORZRES);
    		pDevMode->dmPelsWidth=pDC->GetDeviceCaps(VERTRES);
    		pDC->ResetDC(pDevMode);
    		::GlobalUnlock(pInfo->m_pPD->m_pd.hDevMode) ;
    		pDC->StartPage();
    		m_control.OnPrint(pDC, pInfo);
    	}
    }
    

    Ich verwende zum Drucken einen PDF-Generator-Treiber und wenn ich im Druckdialog Querformat eingestellt habe, dann sind die ersten Seiten im Querformat, nur die letzte Seite ist im Hochformat, das Bild allerdings ist um 90 Grad gedreht aufgrund dieser Zuweisung:

    pDevMode->dmPelsHeight=pDC->GetDeviceCaps(HORZRES);
    		pDevMode->dmPelsWidth=pDC->GetDeviceCaps(VERTRES);
    

    Ich bin langsam am Ende mit meinem Latein und würde mich sehr über Hilfe freuen.
    Leider ist es ziemlich dringend, sollte bis morgen allerspätestens fertig sein 😞

    Danke schonmal!



  • Ich bin mir nicht ganz sicher, ob das reicht, was Du da tust.

    Wir hatten vor ca. 5 Jahren dasselbe Problem. Die Umstellung der Seitenausrichtung wurde jedoch über den Druckdialog und nicht nur über DEVMODE realisiert:

    void PrinterData::SetOrientation(const PrnOrient &wert)
    {
        PRINTDLG *pd = (PRINTDLG *)printData;
        DEVMODE* dm = (DEVMODE*)GlobalLock(pd->hDevMode);
    #ifndef _CPP_BUILDER
        dm->dmOrientation = ((wert == PrnOHoch) ? DMORIENT_PORTRAIT : DMORIENT_LANDSCAPE);
    #else
        dm->dmOrientation = static_cast<short>(((wert == PrnOHoch) ? DMORIENT_PORTRAIT : DMORIENT_LANDSCAPE));
    #endif
        GlobalUnlock(pd->hDevMode);
    }
    

    Ich hatte seinerzeit nichts mit der Druckerei zu tun, kann mich jedoch nicht an das von Dir beschriebene Problem erinnern. Ich meine jedoch, das es irgendwelche Unterschiede zwischen CPrintInfo und dem Druckerdialog selbst gab. (Ist jedoch alles schon mindestens fünf Jahre her).

    Weiterhin fällt mir auf, dass Du den Speicher nur sperrst, aber erst bei der letzten Seite wieder freigibst.

    Wann wird eigentlich der Druckdialog aufgerufen? Vor "CMyView::OnPrint" oder durch "CBaseAppView::OnPrint(pDC, pInfo)"?

    Ich hoffe das hilft Dir weiter.



  • Hallo Manfred,

    erstmal vielen Dank für deine Antwort.

    Das fehlende GlobalUnlock fehlt nur hier, im Quellcode hatte ich es drin.
    Dein Quellcode ist doch im Grunde exakt das, was ich mache, insofern hilft er mir kein Stück weiter 😞

    Der PrintDialog wird ganz normal in der DoPreparePrinting von CView aufgerufen.



  • Wenn du den Druckdialog nicht brauchst, dann gib grundsätzlich vor, eine Vorschau zu machen, dann kommt der nicht. 😃

    Ich hätte auch noch Code, wie man komplett ohne Frameworkunterstützung an den DruckerDC kommt. 🙂 Frag, wenn du ihn haben magst.

    So als Idee:
    Kann man einen Memory-DC machen, der eine Seite im Querformat ist - da dann reinmalen und ihn gedreht auf den Drucker-DC blitten (oder wie das mit den ...blt-Funktionen heißen mag)?



  • Hallo estartu_de,

    den Druckerdialog benötige ich schon.

    Deine Lösung mit dem MemDC, welcher das Format einer Seite im Querformat hat, verwende ich momentan:
    Ich habe besagten MemDC. In diesen wird mein Bild gemalt. Und dann drehe ich per PlgBlt den MemDC auf die hochformatige Seite. Funktioniert eigentlich recht gut. Aber ist nichtsdestotrotz nur eine Behelfslösung.



  • Im Grunde identisch, aber nicht exakt. Wie schon gesagt, kann ich mich an Diskussionen über Differenzen zwischen CPrintInfo und PRINTDLG erinnern (trotz meiner fortgeschrittenen Senilität). 😉 Dabei ging m. E. es um Differenzen zwischen der Standard-Einstellung und temporär geänderten Einstellungen.

    Ich habe das Programm nochmals ausgegraben und getestet. Die Problemstellung ist (umgekehrt) identisch. Es sind zunächst sechs Seiten im Querformat auszugeben und anschließend eine Seite im Hochformat. Es funktioniert, egal ob im Druckdialog Hoch- oder Querformat angegeben werden (getestet mit HP-Laserjet Druckertreiber).

    Einen Unterschied gibt es allerdings doch noch. Da die Seitennummerierung auf der letzten Seite ausgesetzt werden musste, wird diese in einem seperaten Druckjob ausgegeben. Daher erhalte ich beim Acrobat PDF-Treiber auch nur diese Seite angezeigt (Rest wird dabei wohl überschrieben). Aber auch hier ist es unerheblich, ob im Treiber zuvor Hoch- oder Querformat angegeben wurde. Die Seite erscheint generell im Hochformat.

    Eine weitere Code-Stelle, welche sich mit DMORIENT_PORTRAIT/DMORIENT_LANDSCAPE befaßt, finde ich im gesamten Projekt nicht.

    Einen Versuch, ist es vielleicht wert.



  • Hm, wenn ich einen seperaten Druckjob generieren würde, würde das auch bei mir ohne Probleme funktionieren.

    Aber jetzt wo du es sagst... Ich habe was gelesen, irgendwann gestern Nacht... Ich such's mal schnell.

    ach ja, hier:

    http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q167345

    Da wird auch davon gesprochen, dass die Einstellungen noch irgendwie übernommen werden müssen. Hab es gestern Nacht aber wieder vergessen. War einfach schon zu spät... Wenn ich herausfinde, wie ich diesen Printer-Handle bekomm, teste ich es mal aus.



  • Ich weiß nicht, ob das ein Hobbyprojekt von dir ist oder wie das aussieht, aber wäre es möglich mir den Quellcode zukommen zu lassen? Möglicherweise auch nur den relevanten Ausschnitt?



  • Hobbyprojekt ist gut 🤡

    Ich suche gerade und blicke nicht ganz durch. Irgendwie wird im Konstruktor das printdata mit 0 gebügelt und zwischendrin gefüllt. Alle relevanten Informationen werden über "(PRINTDLG *)printData;" geholt. Die ganze Klasse befasst sich ausschließlich mit Lesen und Setzen der Druckereinstellungen incl. Speicherung in einer INI-Datei.

    Mit 1000 Zeilen ist das Ding für dieses Forum ein bisschen zu dick. Ich kann Dir den Quelltext gerne an Deine Mailadresse zusenden.

    Du kannst das auch direkt verwenden. Die Rechte liegen ausschließlich bei mir (ist ja auch sonst keiner mehr da). 😞



  • Hallo Manfred,

    das wäre sehr nett. Ich habe dir meine eMail-Adresse an deine Adresse geschickt, die ich auf deiner Homepage gefunden habe.



  • Hallo,

    ich habe momentan ein ähnliches Problem, möchte alle Seiten bis auf die zweite im Hochformat, die Zweite aber im Querformat drucken. Gibt es inzwischen eine Lösung für das Problem??



  • Wohl nicht wirklich: Meines Wissens hat es dEUs bei seiner Behelfslösung, einfach zwei Druckjops zu generieren belassen.



  • Ich habe es jetzt einigermaßen mit dem Code von Seite 1 hinbekommen, nur ist noch ein Problem: Wenn ich StartPage() und EndPage() aufrufe, werden die Seiten zwar richtig gedreht, aber nach jeder bedruckten Seite kommt noch eine leere. Rufe ich kein StartPage() und EndPage() auf, werden die Seiten in der Seitenansicht zwar gedreht, aber nicht im Ausdruck... 😞
    Hier mal der Code (nicht bereinigt oder so)

    void CPlanProgView::OnPrint(CDC* pDC, CPrintInfo* pInfo) 
    {
    	CPlanProgDoc* pDoc = GetDocument();
    
    	CRect rcClient;
    	GetClientRect(&rcClient);
    	rcClient = m_rcPrintRect;
    
    	pDC->DPtoLP(&rcClient);
    	pDC->SetMapMode(MM_LOMETRIC);
    
    	CRect TabellenRect;
    	TabellenRect.SetRect(10,-10,2800,-500);
    
    	int nCurPage=pInfo->m_nCurPage;
    
    	DEVMODE *pDevMode = (DEVMODE*)::GlobalLock(pInfo->m_pPD->m_pd.hDevMode) ; 
    
    	if(nCurPage==1)
    	{
    		DOCINFO MyDocInfo;
    		MyDocInfo.cbSize = sizeof(DOCINFO);
    		MyDocInfo.lpszDocName = "Auslegung";
    		MyDocInfo.lpszOutput = NULL;
    		MyDocInfo.lpszDatatype=NULL;
    		MyDocInfo.fwType=NULL;
    
    		pDC->StartDoc(&MyDocInfo);
    
    		pDevMode->dmOrientation = DMORIENT_PORTRAIT; 
    		pDevMode->dmPelsHeight = pDC->GetDeviceCaps(HORZRES); 
    		pDevMode->dmPelsWidth = pDC->GetDeviceCaps(VERTRES); 
    		pDC->ResetDC(pDevMode); 
    		pDC->SetMapMode(MM_LOMETRIC);
    		pDC->StartPage();	
    		DrawProjektdaten(pDC,pDoc);
    
    	}
    	else if(nCurPage==2)
    	{
    		pDC->EndPage();
    
           	pDevMode->dmOrientation = DMORIENT_LANDSCAPE; 
    		pDevMode->dmPelsHeight = pDC->GetDeviceCaps(HORZRES); 
    		pDevMode->dmPelsWidth = pDC->GetDeviceCaps(VERTRES); 
    
            pDC->ResetDC(pDevMode); 
    		pDC->SetMapMode(MM_LOMETRIC);
    		pDC->StartPage();	
    		DrawTabelle(pDC,TabellenRect, pDoc);
    
    	}
    	else if(nCurPage==3)
    	{
    		pDC->EndPage(); 
    		pDevMode->dmOrientation = DMORIENT_PORTRAIT; 
    		pDevMode->dmPelsHeight = pDC->GetDeviceCaps(HORZRES); 
    		pDevMode->dmPelsWidth = pDC->GetDeviceCaps(VERTRES);
    
            pDC->ResetDC(pDevMode); 
    		pDC->SetMapMode(MM_LOMETRIC);
    
    		pDC->StartPage();	
    		DrawStrangschema(pDC,pDoc);
    
    	}
    	else if(nCurPage==4)
    	{
    		pDC->EndPage(); 
    		pDevMode->dmOrientation = DMORIENT_PORTRAIT; 
    		pDevMode->dmPelsHeight = pDC->GetDeviceCaps(HORZRES); 
    		pDevMode->dmPelsWidth = pDC->GetDeviceCaps(VERTRES);
    
            pDC->ResetDC(pDevMode); 
    
    		pDC->StartPage();	
    		pDC->SetMapMode(MM_LOMETRIC);
    		DrawHaus(pDC,pDoc);
    		pDC->EndPage();
    		pDC->EndDoc();
    
    	}
    	::GlobalUnlock(pInfo->m_pPD->m_pd.hDevMode) ;
    
    }
    

    Ohne die Start und EndPage's wird nicht gedreht...



  • Also irgendwie wird die Orientierung nur übernommen, wenn vorher ein EndPage() kommt. Ich schaffe es z. B. nicht, die erste Seite querformat auszugeben.
    Hat den niemand mehr ein ähnliches Problem gehabt und könnte evtl. weiterhelfen??


Anmelden zum Antworten