Announcement

Collapse
No announcement yet.

Auswahl des Druckerschachtes

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Auswahl des Druckerschachtes

    Ich möchte programmgesteuert auf einem beliebigen Drucker den Druckerschacht (Papierquelle) auswählen. Der Anwender soll nicht den Umweg über den Dialog "PrinterSetup" machen müssen.

    Da Delphi (das Objekt TPrinter) derartiges nicht anbietet, muss es wohl mit dem Windows-API gemacht werden. Gerade damit habe ich aber kaum Erfahrung.

    Wer hat vielleicht eine Komponente (möglichst mit Quellcode) oder kann mir bei der API-Programmierung unter die Arme greifen?

    Gruß

    Michael R. Schäfer - Mannheim

  • #2
    Hallo,

    im Ordner Win16-API habe ich bereits einige der Alternativen vorgestellt. Je nach Druckertreiber reicht es aus, die Papiergrösse zu definieren. Ansonsten kann der Schacht definiert werden. Das folgende Beispiel sollte den manuellen Einzug aktivieren:
    <pre>
    uses Printers, WinSpool;

    procedure TForm1.Button1Click(Sender: TObject);
    var
    aDevice : array[0..255] of char;
    aDriver : array[0..255] of char;
    aPort : array[0..255] of char;
    hDMode : THandle;
    PDMode : PDEVMODE;
    begin
    Printer.PrinterIndex := -1;
    Printer.GetPrinter(aDevice, aDriver, aPort, hDMode);
    if hDMode <> 0 then begin
    pDMode := GlobalLock(hDMode);
    if pDMode <> nil then begin
    pDMode^.dmFields := pDMode^.dmFields or DM_PAPERSIZE;
    pDMode^.dmPaperSize := DMPAPER_A4;
    pDMode^.dmFields := pDMode^.dmFields or DM_DEFAULTSOURCE;
    pDMode^.dmDefaultSource := DMBIN_MANUAL;
    GlobalUnlock(hDMode);
    end;
    end;
    with Printer do
    begin
    PrinterIndex := Printer.PrinterIndex;
    BeginDoc;
    Canvas.TextOut(100,100, 'Aus welchem Schacht kommt dieses Blatt?');
    EndDoc;
    end;
    end;
    </pre&gt

    Comment


    • #3
      Ich habe die kleine Routine ausprobiert, leider ohne den gewünschten Erfolg.
      Egal, was ich als DefaultSource (dmbin_cassette oder dmbin_lower usw.) einstelle, auf meinem Laserdrucker HP Laserjet 6p kommt das Papier immer aus dem manuellen Einzug (wenn dort Papier eingelegt ist). Wenn ich die Papierquelle im PrinterSetup einstelle, funktioniert es dagegen richtig.

      Liegt es vielleicht an Windows NT 4.0 (SP 5) oder gibt es noch einen Trick??

      Comment


      • #4
        Hallo,

        dann probiere es bei Deinem Druckertreiber einmal auf die harte Tour - das dmField-Recordfeld wird komplett überschrieben. Mit dem folgenden Aufruf kann ich unter NT 4 SP5 je nach Auskommentierung zwischen dem Standard-Einzug und dem manuellen Einzug wechseln.
        <pre>
        uses Printers, WinSpool;

        procedure TForm1.Button1Click(Sender: TObject);
        var
        aDevice : array[0..255] of char;
        aDriver : array[0..255] of char;
        aPort : array[0..255] of char;
        hDMode : THandle;
        PDMode : PDEVMODE;
        begin
        Printer.PrinterIndex := -1;
        Printer.GetPrinter(aDevice, aDriver, aPort, hDMode);
        if hDMode <> 0 then begin
        pDMode := GlobalLock(hDMode);
        if pDMode <> nil then begin
        pDMode^.dmFields := DM_DEFAULTSOURCE;
        //pDMode^.dmDefaultSource := DMBIN_MANUAL;
        pDMode^.dmDefaultSource := DMBIN_AUTO ;
        GlobalUnlock(hDMode);
        end;
        end;
        with Printer do
        begin
        PrinterIndex := Printer.PrinterIndex;
        BeginDoc;
        Canvas.TextOut(100,100, 'Aus welchem Schacht kommt dieses Blatt?');
        EndDoc;
        end;
        end;
        </pre&gt

        Comment


        • #5
          Hallo,

          ich hatte das gleiche Problem. Zusätzlich benötigte ich die Liste der für den Drucker zur Verfügung stehenden Papiergrößen und Papierquellen
          unabhängig von einem bestehenden Setupdialog. Die folgende Unit inkl. eines Testprogramms löst das Problem. Zusätzlich liefert sie die Papiergrößen in 1/10 mm Einheiten und nicht in logischen Einheiten.
          Die Unit war ursprünglich für den C++-Builder geschrieben. Bei Bedarf hab ich den Code auch hierfür zur Verfügung.

          unit mmprinter;

          interface

          uses Windows, Winspool, SysUtils, Classes, printers;

          type
          TmmPrinter = class(TPrinter)
          protected
          FPaperSources: TStrings;
          FPaperSizes: TStrings;
          FPaperSourceIndex: integer;
          FPaperSizeIndex: integer;
          ADevice: array[0..255] of char;
          ADriver: array[0..255] of char;
          APort: array[0..256] of char;
          hDMode: THandle;

          function GetPaperSizes: TStrings;
          function GetPaperSources: TStrings;
          procedure SetPaperSizeIndex(Value: integer);
          procedure SetPaperSourceIndex(Value: integer);
          function GetPageHeight_mm: integer;
          function GetPageWidth_mm: integer;
          public
          constructor Create;
          destructor Destroy; override;
          property PaperSizes: TStrings read GetPaperSizes;
          property PaperSources: TStrings read GetPaperSources;
          property PaperSizeIndex: integer read FPaperSizeIndex write SetPaperSizeIndex;
          property PaperSourceIndex: integer read FPaperSourceIndex write SetPaperSourceIndex;
          property PageHeight_mm: integer read GetPageHeight_mm;
          property PageWidth_mm: integer read GetPageWidth_mm;
          end;

          {
          function mmPrinter: TmmPrinter;
          function SetmmPrinter(NewPrinter: TmmPrinter): TmmPrinter;
          }

          implementation

          uses Consts;

          constructor TmmPrinter.Create;
          begin
          FPaperSizeIndex := -1;
          FPaperSourceIndex := -1;
          end;

          destructor TmmPrinter.Destroy;
          begin
          FPaperSizes.Free;
          FPaperSizes := nil;
          FPaperSources.Free;
          FPaperSources := nil;
          end;

          function TmmPrinter.GetPaperSources: TStrings;
          var
          pDevMode: PDeviceMode;
          bin: array[0..255,0..23] of char;
          i: DWORD;
          Res: DWORD;
          begin
          if (FPaperSources = nil) then begin
          try
          FPaperSources := TStringList.Create;
          except
          FPaperSources.Free;
          FPaperSources := nil;
          raise;
          end;
          end;

          FPaperSources.Clear;
          GetPrinter(ADevice,ADriver,APort,hDMode);
          pDevMode := nil;
          {Res := DeviceCapabilities(ADevice,APort,DC_BINNAMES,bin[0][0],pDevMode);}
          for i := 0 to Res-1 do begin
          FPaperSources.Add(bin[i]);
          end;

          Result := FPaperSources;
          end;

          function TmmPrinter.GetPaperSizes: TStrings;
          var
          pDevMode: PDeviceMode;
          pl: array[0..255,0..63] of char;
          i: DWORD;
          Res: DWORD;
          begin
          if (FPaperSizes = nil) then begin
          try
          FPaperSizes := TStringList.Create;
          except
          FPaperSizes.Free;
          FPaperSizes := nil;
          raise;
          end;
          end;
          FPaperSizes.Clear;
          GetPrinter(ADevice,ADriver,APort,hDMode);
          {Res = DeviceCapabilities(ADevice,APort,DC_PAPERNAMES,&(p l[0][0]),pDevMode);}
          for i := 0 to Res-1 do begin
          FPaperSizes.Add(pl[i]);
          end;
          Result := FPaperSizes;
          end;

          function TmmPrinter.GetPageHeight_mm: integer;
          var
          pDevMode: PDeviceMode;
          p: array [0..99] of TPoint;
          Res: DWORD;
          begin
          GetPrinter(ADevice,ADriver,APort,hDMode);
          {Res = DeviceCapabilities(ADevice,APort,DC_PAPERSIZE,(LPT STR)&(p[0]),pDevMode);}
          if (FPaperSizeIndex <= Res) then begin
          Result := p[FPaperSizeIndex].y;
          end
          else begin
          Result := 0;
          end;
          end;

          function TmmPrinter.GetPageWidth_mm: integer;
          var
          pDevMode: PDeviceMode;
          p: array [0..99] of TPoint;
          Res: DWORD;
          begin
          GetPrinter(ADevice,ADriver,APort,hDMode);
          {Res = DeviceCapabilities(ADevice,APort,DC_PAPERSIZE,(LPT STR)&(p[0]),pDevMode);}

          Comment


          • #6
            Hallo,

            ich hatte das gleiche Problem. Zusätzlich benötigte ich die Liste der für den Drucker zur Verfügung stehenden Papiergrößen und Papierquellen unabhängig von einem bestehenden Setupdialog. Die folgende Unit löst das Problem. Zusätzlich liefert sie die Papiergrößen in 1/10 mm Einheiten und nicht in logischen Einheiten. Die Unit war ursprünglich für den C++-Builder geschrieben. Bei Bedarf hab ich den Code auch hierfür zur Verfügung.

            unit mmprinters;<br>

            interface<br>

            uses Windows, Winspool, SysUtils, Classes, printers;<br>

            type<br>
            TmmPrinter = class(TPrinter)<br>
            protected<br>
            FPaperSources: TStrings;<br>
            FPaperSizes: TStrings;<br>
            FPaperSourceIndex: integer;<br>
            FPaperSizeIndex: integer;<br>
            ADevice: array[0..255] of char;<br>
            ADriver: array[0..255] of char;<br>
            APort: array[0..256] of char;<br>
            hDMode: THandle;<br>

            function GetPaperSizes: TStrings;<br>
            function GetPaperSources: TStrings;<br>
            procedure SetPaperSizeIndex(Value: integer);<br>
            procedure SetPaperSourceIndex(Value: integer);<br>
            function GetPageHeight_mm: integer;<br>
            function GetPageWidth_mm: integer;<br>
            public<br>
            constructor Create;<br>
            destructor Destroy; override;<br>
            property PaperSizes: TStrings read GetPaperSizes;<br>
            property PaperSources: TStrings read GetPaperSources;
            property PaperSizeIndex: integer read FPaperSizeIndex write SetPaperSizeIndex;<br>
            property PaperSourceIndex: integer read FPaperSourceIndex write SetPaperSourceIndex;<br>
            property PageHeight_mm: integer read GetPageHeight_mm;<br>
            property PageWidth_mm: integer read GetPageWidth_mm;<br>
            end;<br>

            function mmPrinter: TmmPrinter;<br>
            function SetmmPrinter(NewPrinter: TmmPrinter): TmmPrinter;<br>

            implementation<br>

            uses Consts;<br>
            var<br>
            FmmPrinter: TmmPrinter = nil;<br>

            constructor TmmPrinter.Create;<br>
            begin<br>
            FPaperSizeIndex := -1;<br>
            FPaperSourceIndex := -1;<br>
            end;<br>

            destructor TmmPrinter.Destroy;<br>
            begin<br>
            FPaperSizes.Free;<br>
            FPaperSizes := nil;<br>
            FPaperSources.Free;<br>
            FPaperSources := nil;<br>
            end;<br>

            function TmmPrinter.GetPaperSources: TStrings;<br>
            var<br>
            pDevMode: PDeviceMode;<br>
            bin: array[0..255,0..23] of char;<br>
            i: DWORD;<br>
            Res: DWORD;<br>
            begin<br>
            if (FPaperSources = nil) then begin<br>
            try<br>
            FPaperSources := TStringList.Create;<br>
            except<br>
            FPaperSources.Free;<br>
            FPaperSources := nil;<br>
            raise;<br>
            end;<br>
            end;<br>

            FPaperSources.Clear;<br>
            GetPrinter(ADevice,ADriver,APort,hDMode);<br>
            pDevMode := nil;<br>
            Res := DeviceCapabilities(ADevice,APort,DC_BINNAMES,PCHAR (@(bin[0][0])),pDevMode);<br>
            for i := 0 to Res-1 do begin<br>
            FPaperSources.Add(bin[i]);<br>
            end;<br>

            Result := FPaperSources;<br>
            end;<br>

            function TmmPrinter.GetPaperSizes: TStrings;<br>
            var<br>
            pDevMode: PDeviceMode;<br>
            pl: array[0..255,0..63] of char;<br>
            i: DWORD;<br>
            Res: DWORD;<br>
            begin<br>
            if (FPaperSizes = nil) then begin<br>
            try<br>
            FPaperSizes := TStringList.Create;<br>
            except<br>
            FPaperSizes.Free;<br>
            FPaperSizes := nil;<br>
            raise;<br>
            end;<br>
            end;<br>
            FPaperSizes.Clear;<br>
            GetPrinter(ADevice,ADriver,APort,hDMode);<br>
            pDevMode := nil;<br>
            Res := DeviceCapabilities(ADevice,APort,DC_PAPERNAMES,PCH AR(@(pl[0][0])),pDevMode);<br>
            for i := 0 to Res-1 do begin<br>
            FPaperSizes.Add(pl[i]);<br>
            end;<br>
            Result := FPaperSizes;<br>
            end;<br>

            &#10

            Comment


            • #7
              function TmmPrinter.GetPageHeight_mm: integer;<br>
              var<br>
              pDevMode: PDeviceMode;<br>
              p: array [0..99] of TPoint;<br>
              Res: DWORD;<br>
              begin<br>
              GetPrinter(ADevice,ADriver,APort,hDMode);<br>
              pDevMode := nil;<br>
              Res := DeviceCapabilities(ADevice,APort,DC_PAPERSIZE,PCHA R(@p[0]),pDevMode);<br>
              if (FPaperSizeIndex <= integer(Res)) then begin<br>
              Result := p[FPaperSizeIndex].y;<br>
              end<br>
              else begin<br>
              Result := 0;<br>
              end;<br>
              end;<br>

              function TmmPrinter.GetPageWidth_mm: integer;<br>
              var<br>
              pDevMode: PDeviceMode;<br>
              p: array [0..99] of TPoint;<br>
              Res: DWORD;<br>
              begin<br>
              GetPrinter(ADevice,ADriver,APort,hDMode);<br>
              pDevMode := nil;<br>
              Res := DeviceCapabilities(ADevice,APort,DC_PAPERSIZE,PCHA R(@p[0]),pDevMode);<br>
              if (FPaperSizeIndex <= integer(Res)) then begin<br>
              Result := p[FPaperSizeIndex].x;<br>
              end<br>
              else begin<br>
              Result := 0;<br>
              end;<br>
              end;<br>

              procedure TmmPrinter.SetPaperSizeIndex(Value: integer);<br>
              var<br>
              pDevMode : PDeviceMode;<br>
              p: array [0..99] of WORD;<br>
              Res: DWORD;<br>
              begin<br>
              if (Printing) then raise EPrinter.Create(SPrinting);<br>
              if ((Value < 0) or (Value >= PaperSizes.Count)) then exit;<br>
              FPaperSizeIndex := Value;<br>
              GetPrinter(ADevice,ADriver,APort,hDMode);<br>
              {<br>
              Ohne Handle auf eine DevMode-Struktur geht nichts. Deshalb wird <br>durch den Aufruf
              von SetPrinter das Handle besorgt<br>
              }<br>
              if (hDMode = 0) then begin<br>
              SetPrinter(ADevice,ADriver,APort,hDMode);<br>
              GetPrinter(ADevice,ADriver,APort,hDMode);<br>
              end;<br>
              pDevMode := nil;<br>
              Res := DeviceCapabilities(ADevice,APort,DC_PAPERS,PCHAR(@ p[0]),pDevMode);<br>
              if (FPaperSizeIndex <= integer(Res)) then begin<br>
              if (hDMode <> 0) then begin<br>
              pDevMode := GlobalLock(hDMode);<br>
              if (pDevMode <> nil) then begin<br>
              pDevMode^.dmPaperSize := p[FPaperSizeIndex];<br>
              end;<br>
              GlobalUnlock(hDMode);<br>
              end;<br>
              end;<br>
              end;<br>

              procedure TmmPrinter.SetPaperSourceIndex(Value: integer);<br>
              var<br>
              pDevMode : PDeviceMode;<br>
              p: array [0..99] of WORD;<br>
              Res: DWORD;<br>
              begin<br>
              if (Printing) then raise EPrinter.Create(SPrinting);<br>
              if ((Value < 0) or (Value >= PaperSources.Count)) then exit;<br>
              FPaperSourceIndex := Value;<br>
              GetPrinter(ADevice,ADriver,APort,hDMode);<br>
              {<br>
              Ohne Handle auf eine DevMode-Struktur geht nichts. Deshalb wird <br>durch den Aufruf
              von SetPrinter das Handle besorgt<br>
              }<br>
              if (hDMode = 0) then begin<br>
              SetPrinter(ADevice,ADriver,APort,hDMode);<br>
              GetPrinter(ADevice,ADriver,APort,hDMode);<br>
              end;<br>
              pDevMode := nil;<br>
              Res := DeviceCapabilities(ADevice,APort,DC_BINS,PCHAR(@p[0]),pDevMode);<br>
              if (FPaperSourceIndex <= integer(Res)) then begin<br>
              if (hDMode <> 0) then begin<br>
              pDevMode := GlobalLock(hDMode);<br>
              if (pDevMode <> nil) then begin<br>
              pDevMode^.dmFields := (DM_DEFAULTSOURCE or DM_PAPERSIZE);<br>
              pDevMode^.dmDefaultSource := p[FPaperSourceIndex];<br>
              end;<br>
              GlobalUnlock(hDMode);<br>
              end;<br>
              end;<br>
              end;<br>

              function mmPrinter: TmmPrinter;<br>
              begin<br>
              if (FmmPrinter = nil) then FmmPrinter := TmmPrinter.Create;<br>
              Result := FmmPrinter;<br>
              end;<br>

              function SetmmPrinter(NewPrinter: TmmPrinter): TmmPrinter;<br>
              begin<br>
              Result := FmmPrinter;<br>
              FmmPrinter := NewPrinter;<br>
              end;<br>

              end.<br&gt

              Comment


              • #8
                Und wenn alles nicht funktioniert (mit Spezialdruckern-TT und speziellen Properties), dann lege einfach mehrere Drucker in der Druckersteuerung an, die die entsprechend konfigurierten Eigenschaften besitzen. Quick and dirty.<p>
                <p>
                Mfg Carsten Jockenhöfe

                Comment

                Working...
                X