Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Bitmap an den Drucker senden (https://www.delphipraxis.net/110139-bitmap-den-drucker-senden.html)

Moony 13. Mär 2008 14:45


Bitmap an den Drucker senden
 
Hallo zusammen!

Ich habe lediglich ein Druckerhandle und möchte an diesen Drucker eine Bitmap schicken. wie mache ich das am besten?

Danke & Gruß, Moony

Luckie 13. Mär 2008 15:00

Re: Bitmap an den Drucker senden
 
Zeichne auf den Canvas des Druckers. Siehe dazu Hier im Forum suchenBeginDoc und Hier im Forum suchenEndDoc.

Moony 13. Mär 2008 15:04

Re: Bitmap an den Drucker senden
 
Das ist schon alles klar. Mein Problem ist, dass über ein anderes Modul der BeginDoc aufgerufen wird. Somit gibt es ein Druckerhandle von meiner Application muß ich dann ann dieses Druckerhandle & dieses Dokument Daten an den Drucker schicken (in meinem Fall eine Bitmap). Anschließend wird über das Modul das EndDoc aufgerufen und somit der Auftrag abgeschlossen.

Ich habe also lediglich das Druckerhandle und an dieses muss ich meine Bitmap schicken.

Normalerweise mache ich das über Canvas.StretchDraw(), aber ich habe nur das Handle und mit diesem muß ich weiterarbeiten.

Luckie 13. Mär 2008 15:09

Re: Bitmap an den Drucker senden
 
Zitat:

Zitat von Moony
Das ist schon alles klar.

Und warum sagst du da snicht gleich?
Zitat:

Mein Problem ist, dass über ein anderes Modul der BeginDoc aufgerufen wird. Somit gibt es ein Druckerhandle von meiner Application muß ich dann ann dieses Druckerhandle & dieses Dokument Daten an den Drucker schicken (in meinem Fall eine Bitmap). Anschließend wird über das Modul das EndDoc aufgerufen und somit der Auftrag abgeschlossen.
Warum hast du das nicht gleich in deinem ersten Beitrag geschrieben?


Zitat:

Normalerweise mache ich das über Canvas.StretchDraw(), aber ich habe nur das Handle und mit diesem muß ich weiterarbeiten.
Dann hol dir doch mit dem Handle mittel MSDN-Library durchsuchenGetDC den DC für den Drucker.

Moony 13. Mär 2008 15:13

Re: Bitmap an den Drucker senden
 
Aber danach habe ich doch wieder ein Handle und ich brauche doch das Canvas von meinem Handle oder sehe ich das falsch?

Oder soll ich mir danach ein TCanvas erzeugen und diesem mein Handle zuweisen?

Moony 13. Mär 2008 16:27

Re: Bitmap an den Drucker senden
 
Ich habe das jetzt folgendermaßen gemacht, aber irgendwie will er nicht wirklich:

Delphi-Quellcode:
  myCanvas := TCanvas.Create;
  myGraphic := TBitmap.Create;
  myGraphic.LoadFromFile(ExtractFilePath(Application.ExeName) +  '!NewCard.bmp');
  myCanvas.Handle := PrntHandle; // PrntHandle ist das Druckerhandle was ich habe.
  X := GetDeviceCaps(PrntHandle,PHYSICALOFFSETX);
  Y := GetDeviceCaps(PrntHandle,PHYSICALOFFSETY);
  rc := Rect(0 - X, 0 - Y, 1027, 648);

  myCanvas.StretchDraw(rc, myGraphic);

Larsi 13. Mär 2008 16:34

Re: Bitmap an den Drucker senden
 
Wie hasten das geschaft dass dein zweiter post lehr ist? geht das? fehler bei meinem firefox?

Moony 13. Mär 2008 16:36

Re: Bitmap an den Drucker senden
 
Wie meinst du das denn? mein Post ist gar nicht leer...da steht mein quellcode drin.

bluesbear 13. Mär 2008 16:44

Re: Bitmap an den Drucker senden
 
Zitat:

Zitat von Moony
Wie meinst du das denn? mein Post ist gar nicht leer...da steht mein quellcode drin.

Also bei mir ist #3 auch leer (Opera), jfyi

Moony 13. Mär 2008 16:47

Re: Bitmap an den Drucker senden
 
Stimmt, jetzt müßte das sichtbar ssein. wahrsheinlich war das ein Anzeigefehler.

Kannst du mir denn bei meinem Problem weiterhelfen????

:cry:

bluesbear 13. Mär 2008 17:03

Re: Bitmap an den Drucker senden
 
Zitat:

Zitat von Moony
Kannst du mir denn bei meinem Problem weiterhelfen????

Nicht wirklich, hab ich bei nem Drucker noch nie gemacht, müsste also selber experimentieren. Als erstes würde ich es ohne TCanvas versuchen. Also mit API Funktionen, die ein Handle nehmen. StretchBlt vielleicht?

jfheins 13. Mär 2008 17:20

Re: Bitmap an den Drucker senden
 
Besorg die mit getdc nen DeviceContext und hau dann mit stretchblt dein bild drauf - oder besorg die mit getdc nen DC und weise diesen an Canvas.Handle zu und benutzte dann das canvas ;)

Alle Angaben ohne Gewehr ähh ... Gewähr ^^ ;)

Moony 13. Mär 2008 17:27

Re: Bitmap an den Drucker senden
 
Wie mache ich das im Klartext? Die GetDC-Routine liefert mir doch ein Handle zurück.

jfheins 13. Mär 2008 17:33

Re: Bitmap an den Drucker senden
 
Schon, aber ein Handle auf einen DeviceContext !!

Du kannst ein Fenster haben, das hat ein Handle. Mit GetDC bekommst du nun das Handle für den Zeichenbereich, mit dem zu malen kannst ;)

Oder: Form1.Drawline geht ja auch nicht, obwohl es doch auch nur ein Objekt ist :zwinker:

bluesbear 13. Mär 2008 17:59

Re: Bitmap an den Drucker senden
 
Zitat:

Zitat von jfheins
Schon, aber ein Handle auf einen DeviceContext !!

Öhh... ja, das hatte ich unklugerweise vorausgesetzt, daß er so ein Handle am wickel hat.

jfheins 13. Mär 2008 19:57

Re: Bitmap an den Drucker senden
 
ich bin jetzt auch etwas durcheinander ... "druckerhandle" gibt bei Google nur 100 Treffer, also scheint das nicht gerade .... weit verbreitet ^^

Wenns ein Handle auf einen DeviceContext ist, kann man es zum zeichnen benutzen (z.B. in StretchBlt reinstecken) und wenn nicht, muss man sich eben ein passendes Handle besorgen. Wird übrigens häufig mit HDC referenziert (<> HWND)

Ist ja im Grunde ganz einfach, oder nicht? :gruebel:

Zur Not einfach Trial&Error: Wenns so nicht geht, mal mit nem GetDC(druckerhandle) probieren :stupid:

Moony 14. Mär 2008 07:28

Re: Bitmap an den Drucker senden
 
Ok,soweit verstanden. Dann hole ich mir ein Handle auf den DeviceContext so:

Delphi-Quellcode:
var myHDC : HDC;

  myHDC := GetDC(PrntHandle);
und wie gehts weiter? Das ist hier mein Problem. Entweder stehe ich hier auf der Leitung, oder ich weiß es nicht... :wall:

matashen 14. Mär 2008 08:55

Re: Bitmap an den Drucker senden
 
Machs über die Windows API dann klappts auch. Über Delphi Canvas ists Mist.

Ich hab hierzu schonmal was gepostet findest du hier

Moony 14. Mär 2008 09:07

Re: Bitmap an den Drucker senden
 
Laut deinem Post übergibst du an die Routine ein Canvas. Welches Canvas? Ich besitze lediglich das Handle für den Drucker bzw. Druckauftrag.

matashen 14. Mär 2008 09:29

Re: Bitmap an den Drucker senden
 
Naja dein Bild eben, das ist doch in einem Canvas zum Beispiel TBitmap, TImage(was auch wiederum Bitmap.canvas hat) etc.

Da ist doch genug Canvas

Gruß Matthias

Moony 14. Mär 2008 09:38

Re: Bitmap an den Drucker senden
 
Hab das jetzt folgendermaßen gemacht:

Delphi-Quellcode:
  myGraphic := TBitmap.Create;
  myGraphic.LoadFromFile(ExtractFilePath(Application.ExeName) +  '!NewCard.bmp');
  X := GetDeviceCaps(PrntHandle,PHYSICALOFFSETX);
  Y := GetDeviceCaps(PrntHandle,PHYSICALOFFSETY);

  GetDIBSizes(myGraphic.Handle, HeaderSize, ImageSize);

  Bitmapheader := VirtualAlloc(nil, HeaderSize, MEM_COMMIT, PAGE_READWRITE);
  BitmapImage := VirtualAlloc(nil, ImageSize, MEM_COMMIT, PAGE_READWRITE);
  try
    StretchDIBits(PrntHandle, 0 - X, 0 - Y, 1027, 648, 0, 0,
             myGraphic.Width, myGraphic.Height, BitmapImage,
             TBitmapInfo(BitmapHeader^), DIB_RGB_COLORS, SRCCOPY);

    // Diese Funktion sagt einer DLL lediglich dass sie den Druckauftrag beenden kann -> EndDoc
    Result := _DCContinue(ICE_SMART_CARD_GOOD);
  finally
    VirtualFree(Bitmapheader, 0, MEM_FREE);
    VirtualFree(bitmapimage, 0, MEM_FREE);
  end;
Er fängt dann an was zu drucken, aber es kommt nicht raus.

Wenn das nicht funktioniert, gibt es eine Möglichkeit anhand meines Handle, das Canvas des Drucker zu ermitteln? Dann könnte ich wenigstens darauf zeichnen.

Wenn ich es so mache

Delphi-Quellcode:
  myGraphic := TBitmap.Create;
  myGraphic.LoadFromFile(ExtractFilePath(Application.ExeName) +  '!NewCard.bmp');
  X := GetDeviceCaps(PrntHandle,PHYSICALOFFSETX);
  Y := GetDeviceCaps(PrntHandle,PHYSICALOFFSETY);

  GetDIBSizes(myGraphic.Handle, HeaderSize, ImageSize);

  Bitmapheader := VirtualAlloc(nil, HeaderSize, MEM_COMMIT, PAGE_READWRITE);
  BitmapImage := VirtualAlloc(nil, ImageSize, MEM_COMMIT, PAGE_READWRITE);
  try
    TextOut(PrntHandle, 0 - X, 0 - Y, PChar('Test'), Length('Test'));

    // Diese Funktion sagt einer DLL lediglich dass sie den Druckauftrag beenden kann -> EndDoc
    Result := _DCContinue(ICE_SMART_CARD_GOOD);
  finally
    VirtualFree(Bitmapheader, 0, MEM_FREE);
    VirtualFree(bitmapimage, 0, MEM_FREE);
  end;
dann wir der Text gedruckt. Warum dann nicht mit dem Bild??? :wall: :wall:

matashen 14. Mär 2008 10:10

Re: Bitmap an den Drucker senden
 
Und was ist mit dem restlichen Code der bei meinem Link leigt (In der gleichen Antwort).
Hast du Codeoptimierung durch weglassen gemacht.

Hast du den damaligen Thread komplett gelesen/verstanden.

Im übrigen gibt es zu dem Thema noch weitere Threads wenn du also in der Suche Bitmap Drucken eingibst hast du jede menge Treffer.

Auch ganz viel Code hab ich da schon vreöffentlicht und erklärungen abgegeben.

Hab jetzt nicht die Zeit den Code zum xten mal hier reinzukopieren und nochmal erklären.

Zerpflück ihn und versuch in zu verstehen dann gehts auch

Gruß Matthias

Moony 14. Mär 2008 12:34

Re: Bitmap an den Drucker senden
 
Im anschließenden Code startest du den druckjob, setzt die Größen des Druckers, rufst die funktion zum schreiben der bitmap und beendest den druckjob.
Ich hab doch hier keine optimierung betrieben. Und das schrieben der Bitmap habe ich aus der vorherigen Routine umgesetzt.

Moony 14. Mär 2008 15:18

Re: Bitmap an den Drucker senden
 
Ich bitte euch um Hilfe!!! Ich möchte ja begreifen, warum er das nicht macht.

:cry:

matashen 14. Mär 2008 19:11

Re: Bitmap an den Drucker senden
 
Dein Fehler liegt vermutlich lediglich in der Zeile wo das Bild gedruckt werden soll


StretchDIBits(PrntHandle, 0 - X, 0 - Y, 1027, 648, 0, 0,
Druckerhandle,device.left=0-X ??? Wenn du beim Nullpunkt X Absziehst wo wird vermutlich das Bild ausgegeben links neben dem Papier? gleiches Gilt für 0-Y hast du schonmal den wert einfach auf 0 gestezt// Hab ich kommentiert mit Destination = ZIEL

myGraphic.Width, myGraphic.Height, BitmapImage,
TBitmapInfo(BitmapHeader^), DIB_RGB_COLORS, SRCCOPY);

Mal kurz die Zeile zerpflückt

Gruß Matthias

Moony 17. Mär 2008 13:42

Re: Bitmap an den Drucker senden
 
Das hilft auch nicht!

Habe die DestX & DestY auf 0 gesetzt und wird immer noch nicht gedruckt...

SirThornberry 17. Mär 2008 13:52

Re: Bitmap an den Drucker senden
 
GetDC funktioniert nur für Fenster aber doch nicht für alle möglichen Handles?!

Moony 17. Mär 2008 15:03

Re: Bitmap an den Drucker senden
 
Das mag sein.

Folgend seht ihr meinen letzten Code, der zwar dem Drucker sagt: ok, drucken,aber es wird nichts gedruckt.

Delphi-Quellcode:
  ...
  myGraphic := TBitmap.Create;
  if FileExists(ExtractFilePath(Application.ExeName) +  '!NewCard.bmp') then
    myGraphic.LoadFromFile(ExtractFilePath(Application.ExeName) +  '!NewCard.bmp');
 
  X := GetDeviceCaps(PrntHandle,PHYSICALOFFSETX);
  Y := GetDeviceCaps(PrntHandle,PHYSICALOFFSETY);

  GetDIBSizes(myGraphic.Handle, HeaderSize, ImageSize);

  Bitmapheader := VirtualAlloc(nil, HeaderSize, MEM_COMMIT, PAGE_READWRITE);
  BitmapImage := VirtualAlloc(nil, ImageSize, MEM_COMMIT, PAGE_READWRITE);
  try
    StretchDIBits(PrntHandle, 0, 0, 1027, 648, 0, 0, myGraphic.Width, myGraphic.Height, BitmapImage, TBitmapInfo(BitmapHeader^),                                                                                              DIB_RGB_COLORS, SRCCOPY);
  finally
    ...
  end;
Noch mal erklärt:
Ich bekomme ein Druckerhandle. Dieses Handle hält einen angefangenen Druckauftrag fest. Über dieses Handle muß ich die zu druckenden Daten an den Drucker schicken. Anschließend wird über eine andere Applikation der Druckauftrag mit diesem Handle beendet.

Ich hoffe das ist soweit verständlich erläutert.

Vjay 17. Mär 2008 15:09

Re: Bitmap an den Drucker senden
 
Und

Canvas.Handle:= getDC( prnhandle);

funtkioniert definitiv nicht?

SirThornberry 17. Mär 2008 15:15

Re: Bitmap an den Drucker senden
 
Zitat:

Zitat von Vjay
Und

Canvas.Handle:= getDC( prnhandle);

funtkioniert definitiv nicht?

Hast du das ausprobiert? laut msdn erwartet GetDC ein Fensterhandle und in den letzten Posts wurde auch schon auf GetDC verwiesen was aber nicht zu funktionieren scheint.

Moony 17. Mär 2008 15:18

Re: Bitmap an den Drucker senden
 
Ich besitze keinen Canvas.

Hier der Verlauf:

1. Ich rufe eine andere Applikation auf, diese Applikation erstellt mit CreateDC ein Handle. Dieses Handle bekomme ich von dieser Applikation zurück.

2. Zurück bei mir muß ich diesem Handle meine Druckdaten mitteilen.

3. Ich sage der anderen Applikation, dass Sie den Druckauftrag abschließen und ausführen kann.

Das Problem ist also, dass ich lediglich ein Handle bekomme und damit weiter arbeiten muss. Ich habe keinen Canvas. Deshalb war zu aller erst meine Frage wie ich das Canvas eines Druckers anhand des Handles bekomme. So wie ich bei meinem letzten Beitrag Daten an den Drucker schicke kommt es zumindest zu keinem Fehler, aber der Drucker druckt nichts.

Was die Funktion GetDC betrifft:
Mit GetDC bekomme ich ein weiteres Handle und ich weiß immer noch nicht was ich dann mit einem wieteren Handle anfangen soll?

Vjay 17. Mär 2008 15:19

Re: Bitmap an den Drucker senden
 
Nein und der Drucker steht zuweit weg als ich da mal gucken gehen würde ob was rauskommt.
Naja es war von getDC die Rede und von Canvas.handle := printerHandle, aber nicht davon beides kombiniert einzusetzen (oder ich habs übersehen) ;-)

Vjay 17. Mär 2008 15:21

Re: Bitmap an den Drucker senden
 
Naja mit CreatDC ist der Devicecontext, den du dem Canvas.handle zuweisen kannst, generell schonmal da.

Der Fehler liegt dann woanders, z.B. dass du nicht im richtigen Koordinatensystem druckst (somit wird dein Bitmap weggeworfen(geclippt)) und es kommt eine leere Seite heraus.

Moony 17. Mär 2008 15:31

Re: Bitmap an den Drucker senden
 
Und wie kann man das beheben? Ich wüßte jetzt nicht, dass ich im System bin...

Zur kleinen Info:

Wenn ich einen TextOut() ausführe, dann wird dieser gedruckt. Das was mir aber wichtig ist, ist eine Bilddatei an den Drucker zu schicken.

Vjay 17. Mär 2008 15:48

Re: Bitmap an den Drucker senden
 
Sorry, überlesen. Also ausgehend von deinem Beispiel versuch mal folgendes:

Delphi-Quellcode:
C:= TCanvas.create;
C.handle:= Printerhandle;
C.TextOut(0-x, 0-y, 'schnickschnackschnuck');
C.draw(0-x, 0-y, myGraphic);
C.stretchDraw(Rect( 0-x, 0-y, -1, -1), myGraphic);
C.free;
// drucken
Was siehst du, Text, dein Bild, dein Bild ganzsseitig?

Moony 17. Mär 2008 16:09

Re: Bitmap an den Drucker senden
 
Also bis auf das die Druckereinstellungen nicht stimmen wurde zumindest das Bild draufgedruckt!!!! Ich werde das morgen weiter unter die Lupe, wie man das optimieren kann.

Kann ich denn noch die richtigen Druckereinstellungen setzen?

Moony 19. Mär 2008 10:08

Re: Bitmap an den Drucker senden
 
So, habe das jetzt bei mir eingebaut und habe nur noch ein Problem:

Wie schicke ich ihm ne zweite Seite?

Ich habe das so versucht:

Delphi-Quellcode:
  myGraphic := TBitmap.Create;
  myCanvasF := TCanvas.Create;
  myCanvasB := TCanvas.Create;
  try
    if FileExists(ExtractFilePath(Application.ExeName) +  '!NewCard.bmp') then
      myGraphic.LoadFromFile(ExtractFilePath(Application.ExeName) +  '!NewCard.bmp');

    myCanvasF.Handle := PrntHandle;
    X := GetDeviceCaps(PrntHandle,PHYSICALOFFSETX);
    Y := GetDeviceCaps(PrntHandle,PHYSICALOFFSETY);

    GetDIBSizes(myGraphic.Handle, HeaderSize, ImageSize);

    myCanvasF.Draw(0-X, 0-Y, myGraphic);
    myCanvasF.StretchDraw(Rect(0-X, 0-Y, 1027, 648), myGraphic);

    if FileExists(ExtractFilePath(Application.ExeName) +  '!NewCard2.bmp') then
    begin
      if @_DCStartPage <> nil then
        _DCStartPage();

      myGraphic.LoadFromFile(ExtractFilePath(Application.ExeName) +  '!NewCard2.bmp');

      myCanvasB.Handle := PrntHandle;
      myCanvasB.Draw(0-X, 0-Y, myGraphic);
      myCanvasB.StretchDraw(Rect(0-X, 0-Y, 1027, 648), myGraphic);
    end;
  finally
    myGraphic.Free;
    myCanvasF.Free;
    myCanvasB.Free;
  end;
  Result := _DCContinue(0);
Bei diesem Code wird die zweite Seite auf die erste Seite gedruckt und die erste gar nicht.
Alle Funktionen mit dem Underscore sind aus einer anderen Applikation die aufgerufen werden und die den Druckjob verwalten.

Vjay 19. Mär 2008 13:21

Re: Bitmap an den Drucker senden
 
Teile der anderen Awendung, die den Druckjob verwaltet mit, eine neue Seite zu erstellen und dir den Devicecontext zu übermitteln.

Um eine neue Seite selber zu erstellen benötigst du mehr als das DC-Handle.


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:18 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz