Finde keinen Einstieg in GDI



  • Hi Leute.

    Kurz zu meinem Auftrag:
    Ich möchte ein Bild (erstmal egal in welchem Format das vorliegt) mit Hilfe der Windows-API Funktionen direkt auf dem Standard-Drucker ausdrucken. Diese ganze Funktionalität soll am Besten in einer dll laufen. Diese rufe ich dann einfach mit dem zu druckenden Bild von woanders her auf.

    Mittlerweile hab ich soweit recherchiert, dass ich weiß, dass die GDI Bibliothek unter Windows dafür geeignet wäre. Leider bekomme ich es nichtmal hin auch nur einen Programmrahmen zum Laufen zu bringen.

    Die MSDN hat zwar viele tolle Beispiele, aber sagt nicht, welche Header man einbinden muss um die Funktionen und Structs überhaupt verwenden zu können.

    Könnte mir das mal bitte jemand grob erklären, wie dass mit nem GDI Programm funktioniert, damit ich einen Einstieg finde? Oder vielleicht einen einfacheren Weg zeigen um mein eigentliches Problem zu lösen?

    Danke schonmal.



  • ab hier geht es los
    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/devcons_0g6r.asp

    DarthZiu schrieb:

    Die MSDN hat zwar viele tolle Beispiele, aber sagt nicht, welche Header man einbinden muss um die Funktionen und Structs überhaupt verwenden zu können.

    jede funktion in der msdn hat ein requirements punkt dort ist alles erklärt
    bsp:
    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/devcons_5g83.asp

    msdn schrieb:

    Requirements
    Windows NT/2000/XP/Vista: Included in Windows NT 3.1 and later.
    Windows 95/98/Me: Included in Windows 95 and later.
    Header: Declared in Wingdi.h; include Windows.h.
    Library: Use Gdi32.lib.
    Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000/XP. Also supported by Microsoft Layer for Unicode.

    d.h. windows.h inkludieren und gdi32.lib mitlinken fertig



  • Ui, wie kann man nur so blind sein?

    Danke dir für die rasche Hilfe.



  • So, jetzt habe ich zwar das Programm zum Laufen gebracht und kann auch schon Text drucken, aber mit den Bildern klappt es immer noch nicht.

    Bisher habe ich versucht mit LoadImage() ein Bild zu laden, aber es hat nie geklappt. (Kann es sein, dass LoadImage() nur Bilder aus Ressourcen des Projektes nimmt? Ich möchte aber ein Bild aus dem Dateisystem laden).

    _declspec (dllexport) int printImage()
    {
    	HDC drucker = CreateDC("WINSPOOL", "MeinInstallierterDrucker", NULL, NULL);
    
    	HBITMAP bitmap, oldbitmap;
    
    	HDC hdcbitmap;
    
    	char *bild = pfad;
    
    	bitmap  = (HBITMAP) LoadImage(0, "C:\barcode.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
    
    	if (!bitmap) return 3;
    
    	hdcbitmap = CreateCompatibleDC (NULL);
    	oldbitmap = (HBITMAP)SelectObject (hdcbitmap, bitmap);
    
    	int err = BitBlt (drucker, 0, 0, 0, 0, hdcbitmap,0,0, SRCCOPY);
    	if(err == 0)
    		return 6;
    
    	DeleteDC(drucker);
    
    	return 0;
    }
    

    So etwa dachte ich mir das. Sagt mir bitte mal jemand wo mein Denkfehler liegt und wie man das besser lösen kann?



  • afaik brauchst du bei loadimage eine instanz wenn du vom dateisystem laden möchtest.

    LoadImage(GetModuleHandle(NULL)/* evtl casten */, ....
    


  • So, habe es wirklich hinbekommen. Für alle, die mal ein ähnliches Prob haben ist hier der fertige Code für die dll.

    #include <Windows.h>
    
    _declspec (dllexport) int printImage(char imagePath[], char printer[], int leftMargin, int topMargin);
    
    _declspec (dllexport) int printImage(char imagePath[], char printer[], int leftMargin, int topMargin)
            {
    	// Name des Druckers
    	char *pPrinter = printer;
    
    	// linken und oberen Abstand zum Papierrand
    	int left = leftMargin;
    	int top = topMargin;
    
    	// Device Context für diesen Drucker holen
    	HDC drucker = CreateDC("WINSPOOL", pPrinter, NULL, NULL);
    	if(!drucker)
    		return 1;
    
    	// Struktur, die den Druckauftrag identifiziert
    	DOCINFO dokument_info;
    	memset(&dokument_info, 0, sizeof(DOCINFO));
    	dokument_info.cbSize	= sizeof(DOCINFO);
    	dokument_info.lpszDocName	= "label";
    
    	// Pfad zum Bild (Escape-Sequenz in C++ nicht vergessen: C:\\bild.bmp)
    	char *pBild = imagePath;
    
    	HBITMAP bitmap, oldbitmap;
    	HDC hdcbitmap;
    
    	// Bild laden
    	bitmap  = (HBITMAP) LoadImage(GetModuleHandle(NULL), pBild, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
    	if (!bitmap)
    		return 2;
    
    	// Speicherbereich für das Bitmap holen
    	hdcbitmap = CreateCompatibleDC (NULL);
    	if(!hdcbitmap)
    		return 3;
    
    	// Daten des Bitmap in den internen Speicher holen
    	oldbitmap = (HBITMAP) SelectObject (hdcbitmap, bitmap);
    	if(!oldbitmap)
    		return 4;
    
    	// bm_info ist eine Struktur in der nach dem Laden mit GetObject() die Headerinformationen des Bitmaps stehen
    	// Wir wollen die Breite und Höhe des Bitmaps
    	BITMAP bm_info;
    	GetObject(bitmap, sizeof(BITMAP), &bm_info);
    
    	// Druckauftrag starten
    	StartDoc(drucker, &dokument_info);
    	StartPage(drucker);
    
    	// Bitmap auf den Drucker schreiben
    	if(BitBlt(drucker, left, top, bm_info.bmWidth, bm_info.bmHeight, hdcbitmap,0,0, SRCCOPY) == 0)
    		return 5;
    
    	// Druckauftrag beenden
    	EndPage(drucker);
    	EndDoc(drucker);
    
    	// Aufräumen
            DeleteDC(drucker);
            SelectObject(hdcbitmap, oldbitmap);
            DeleteObject(bitmap);
            DeleteDC(hdcbitmap);
    
    	return 0;
    }
    
    /****************** ERROR CODES ********************************
    
      0 - Alles okay
      1 - Drucker konnte nicht gefunden werden
      2 - Bild konnte nicht geladen werden
      3 - Konnte keinen Speicherplatz allokieren
      4 - Konnte Bild nicht in den Speicher laden
      5 - Konnte nicht drucken
    
    ****************************************************************/
    

    Edit: Danke für den Tip mit dem Aufräumen. 👍



  • Aufräumen nicht vergessen:

    SelectObject(hdcbitmap, oldbitmap);
    DeleteObject(bitmap);
    DeleteDC(hdcbitmap);
    

Anmelden zum Antworten