Noch 'ne Druckerfrage

Hi,
OpenPrinter gibt ein gültiges Handle zurück. Get LastError gibt 122 zurück(Puffer zu klein), das bezieht sich aber auf den ersten Aufruf von GetPrinter. Da kehrt sie mit dem Rückgabewert 0 zurück. Wenn ich neuen Speicher alloziert habe und die Funktion GetPrinter erneut aufrufe, kehrt sie mit dem Rückgabewert 1 zurück, aber im Puffer für die PRINTER_INFO_2 steht nichts.

Mfg

langer
 
Huuuuu,

ich habs geschafft!
Manchmal ist man ja wie vernagelt :( .

Hier der lauffähige Code:
Code:
	DWORD dwBytesNeeded;
	LPPRINTER_INFO_2 pPrinterInfo2=NULL;
	HANDLE phPrinter;
	DWORD sizeOfPrintInfo=0;
	int orientation;
	pPrinterInfo2=(LPPRINTER_INFO_2) new char [sizeOfPrintInfo];


	char szPrinter[50];
	DWORD zeichen = 50;
	GetDefaultPrinter(szPrinter, &zeichen);
	OpenPrinter(szPrinter,&phPrinter,NULL);
	if(!GetPrinter(phPrinter,2,(LPBYTE)pPrinterInfo2,sizeOfPrintInfo,&dwBytesNeeded))
	{
		delete[] pPrinterInfo2;
		pPrinterInfo2=NULL;
		pPrinterInfo2=(LPPRINTER_INFO_2) new char [dwBytesNeeded];
		GetPrinter(phPrinter,2,(LPBYTE)pPrinterInfo2,dwBytesNeeded,&dwBytesNeeded);
	}
Ich hab in der ersten Version versucht, pPrintInfo2 zweimal im Aufruf zu nutzen, daran mußte das scheitern. Nach Trennung in dwBytesNeeded und sizeOfPrintInfo klappt alles.

Dank an Endurion für die Tipps, über die Suche mit GetLastError bin ich weitergekommen (war einfach nur ein Hinweis, daß die Funktion eigentlich funktioniert, nur irgendwas im Aufruf falsch war).


Mfg

langer
 
Zuletzt bearbeitet:
Habe noch eine Frage zum DOCINFO.

Der Parameter Output ist mir ja klar, wenn ich auf den Drucker ausgeben will, setze ich ihn auf NULL. Aber was ist mit dem Parameter Dokumentenname? Welche Funktion hat denn dieser Parameter? Kann ja sein, dass es nur der Name ist, unter dem die Zeichenoperationen zum Drucker gesendet werden und der dann in den Druckerdialogen unter Dokumentenname steht. Dann kann ich den Namen wohl willkürlich wählen. Oder hat er eine andere Funktion? Aus der Beschreibung der DOCINFO in der MSDN kann ich das leider nicht genau ersehen.

Mfg

langer
 
Der Dokument-Name wird im Spooler (in dem lustigen kleinen Drucker-Icon in dem System-Tray rechts unten) angezeigt. Bzw. kriegst du den auch zu sehen, wenn du deinen Drucker über den Explorer aufmachst. Dort siehst du eine Liste der gerade zu druckenden Dokumente und da wird dann dieser Dokumenten-Name angezeigt. Auf den Druckvorgang selbst hat das überhaupt keinen Einfluss.
 
Da hatte ich das wohl doch richtig interpretiert. Aber zwischen Vermutung und Wissen ist eben ein Unterschied.
Also vielen Dank für die Antwort.

Mfg

langer
 
Wieder mal ein Druckerproblem:
Ich habe den direkten Druck von Dokumenten jetzt in meinem Projekt zu implementieren versucht
Code:
void CMainFrame::OnSgbVAlle()
{
	// TODO: Fügen Sie hier Ihren Befehlsbehandlungscode ein.
	int i;
	HDC m_hDC;
	DOCINFO docinfo;
	char szPrinter[50];
	DWORD zeichen = 50;
	CAbrDoc *pDoc=(CAbrDoc *)GetActiveDocument();
	CAbrView *pView=(CAbrView*)GetActiveView();
	GetDefaultPrinter(szPrinter, &zeichen);
	if(m_hDC=CreateHandleForPrinter(szPrinter))
	{
		memset(&docinfo,0,sizeof(docinfo));
		docinfo.cbSize=sizeof(docinfo);
		docinfo.lpszDocName=_T("SGB V - Alle Leistungsnachweise");
		if(StartDoc(m_hDC,&docinfo))
		{
			for(i=0;i<pDoc->m_Daten.GetSize();i++)
			{
				pDoc->m_Nummer=i+1;
				if(StartPage(m_hDC))
				{
					pView->Kopf_SGB_zeichnen((CDC*)m_hDC,0,-2000);
					pView->SGB_V_zeichnen((CDC*)m_hDC,0,-2000);
					pView->Datum_eintragen((CDC*)m_hDC,0,-2000);
					pView->SGB_V_eintragen((CDC*)m_hDC,0,-2000);
					pView->Ende_SGB_zeichnen((CDC*)m_hDC,0,-15900);
				}
				EndPage(m_hDC);
			}
			EndDoc(m_hDC);
		}
		::DeleteDC(m_hDC);
	}
	else
		MessageBox("Fehler beim Drucken","Information",MB_OK|MB_ICONINFORMATION);
}

In der Ansichtsklasse wird die erste Funktion auch ordnungsgemäß aufgerufen. Die ersten Schritte klappen auch. Aber wenn ich versuche, ein Object zuzuweisen, gibts eine Exception.
Code:
void CAbrView::Kopf_SGB_zeichnen(CDC *pDC,int offseth,int offsetv)
{
	CFont font10f,font7;
	CString buffer;
	CRect rectDraw;
	CAbrDoc* pDoc = GetDocument();
	CMainFrame* pMainFrame=(CMainFrame*)GetParentFrame();
	CPen schwarzer_Pen(PS_SOLID,50,RGB(0,0,0));
	CPen schwarzer_Pen1(PS_SOLID,20,RGB(0,0,0));
	font10f.CreatePointFont(pDoc->font10,"arial fett");
	font7.CreatePointFont(pDoc->font8print,"ms sansserif");
	CFont *pAlter_Font=pDC->SelectObject(&font10f);
               //hier gibts die Exception
Ich habe auch mal etwas auskommentiert, um zu testen. Es ergibt sich, daß immer, wenn ich auf den DeviceContext zugreifen will, eine Exception erfolgt. pDC ist aber ungleich NULL. Was mache ich da falsch. Die Zeichenroutine funktioniert beim Aufruf über OnPrint einwandfrei. Also muß es irgendwie an dem DC-Pointer liegen.

langer
 
Natürlich lags am Zeiger. Mit dem Zeiger kann ich auf keine Funktion zugreifen, sondern muß den Drucker über den Zeiger an einen DC binden. Dann klappts. Hier der lauffähige Code.
Code:
void CMainFrame::OnSgbVAlle()
{
	// TODO: Fügen Sie hier Ihren Befehlsbehandlungscode ein.
	int i;
	CDC dcPrinter;
	HDC m_hDC;
	DOCINFO docinfo;
	char szPrinter[50];
	DWORD zeichen = 50;
	CAbrDoc *pDoc=(CAbrDoc *)GetActiveDocument();
	CAbrView *pView=(CAbrView*)GetActiveView();
	Drucker_anpassen(2);
	GetDefaultPrinter(szPrinter, &zeichen);
	if(m_hDC=CreateHandleForPrinter(szPrinter))
	{
		dcPrinter.Attach(m_hDC);
		dcPrinter.SetMapMode(MM_HIMETRIC);
		memset(&docinfo,0,sizeof(docinfo));
		docinfo.cbSize=sizeof(docinfo);
		docinfo.lpszDocName=_T("SGB V - Alle Leistungsnachweise");
		if(dcPrinter.StartDoc(&docinfo))
		{
			for(i=0;i<pDoc->m_Daten.GetSize();i++)
			{
				pDoc->m_Nummer=i+1;
				if(dcPrinter.StartPage())
				{
					pView->Kopf_SGB_zeichnen(&dcPrinter,0,-2000);
					pView->SGB_V_zeichnen(&dcPrinter,0,-2000);
					pView->Datum_eintragen(&dcPrinter,0,-2000);
					pView->SGB_V_eintragen(&dcPrinter,0,-2000);
					pView->Ende_SGB_zeichnen(&dcPrinter,0,-15900);
				}
				dcPrinter.EndPage();
			}
			dcPrinter.EndDoc();
			pDoc->m_Nummer=0;
		}
		::DeleteDC(m_hDC);
	}
	else
		MessageBox("Fehler beim Drucken","Information",MB_OK|MB_ICONINFORMATION);
}
So klappen alle Zugriffe der Zeichenfunktionen auf den CDC

Mfg

langer
 
Nun klappt eigentlich alles beim Drucken. Trotzdem hab ich jetzt noch ein Problem:
Wie komme ich an den druckbaren Bereich? Wenn ich die Funktion OnPrint benutze, kann ich den über die PrintInfo-Struktur ermitteln. Nur habe ich hier keine PrintInfo-Struktur. Ich habe versucht, über die LPPRINTER_INFO_2-Struktur an die Werte zu kommen, aber da stehen nur die Papiergrößen drin, bei A4 also 29700 und 21000.
Wo also kriege ich die Informationen her?

Mfg

langer
 
Da das ja vom Drucker abhängt, könnte es mit GetDeviceCaps(HORZSIZE) und GetDeviceCaps(VERTSIZE) gehen. Bin mir da aber auch nicht sicher.
 
Die Idee mit GetDeviceCaps ist nicht schlecht. Da gibt es extra für PrinterDevices die Indexe PHYSICALHEIGHT, PHYSICALWIDTH, PHYSICALOFFSETX und PHYSICALOFFSETY. Ganz klar ist mir noch nicht, wie ich die Angaben interpretieren soll. Da muß ich noch ein bißchen experimentieren. Wenn ich's raushabe, poste ich das hier.

Mfg

langer
 

Neue Beiträge

Zurück