Конференция "Прочее" » Проблема с печатью этикеток на разных принтерах
 
  • Unbekannt © (06.07.16 16:53) [0]
    Для производственных целей я написал программку, которая из ЧПУ-машин считывает данные инструментов, а потом данные выбранных инструментов печатает на этикетки. Прблема в том, что дома тестировал на струйном принтере Canon Pixma MP 780 с этикетками в две колонки и четыре ряда - всё отлично. На работе уже около двух лет при печти на сетевой лазерный принтер HP-какойто тоже всё было отлично. Но возникла необходимость печатать на лазерник DELL-3460 и появилась проблема: если на HP-принтере вставлять лист с этикетками в верхний лоток, в котором щёчки для установки размеры (левая и правая) сдвигаются и раздвигаются так, что позиция листа находится всегда в середине - принтер коррекно распозаёт заданный из моей программы размер и позицию листа в зависимости от положения щёчек и печатает корректно, но на принтере DELL лист на верхнем лотке также находится всегда в середине, но печатает зараза, как если бы лист находился у левого края.
      Пож. подскажите где собака зарыта.
  • Unbekannt © (06.07.16 16:59) [1]
    Да, нужно заметить, что при печати из Office конвертов этот самый Dell положение конверта определяет правилно.
  • Inovet © (06.07.16 17:13) [2]
    Чего-то конкретного по этим моделям принтеров подсказать не смогу, но смогу предположить, что были использованы низкоуровневые команды для конкретного вида принтеров. Чтобы было универсально, надо печатать на абстрактный холст (Canvas), тогда везде будет более менее одинаково - ОС разрулит конкретику на уровне драйверов.
  • Unbekannt © (06.07.16 17:24) [3]
    Именно всё на Printer.Canvas и печатаю.
  • Unbekannt © (06.07.16 17:32) [4]

    procedure SetSeitenGrosse(Papier: Integer; SeitenBreite, SeitenHoehe: Integer);
    var
     Device: array[0..255] of char;
     Driver: array[0..255] of char;
     Port: array[0..255] of char;
     hDMode: THandle;
     PDMode: PDEVMODE;  
    begin
     Printer.PrinterIndex := Printer.PrinterIndex;
     Printer.GetPrinter(Device, Driver, Port, hDMode);
     if hDMode <> 0 then
     begin
       pDMode := GlobalLock(hDMode);
       if pDMode <> nil then begin
         pDMode^.dmFields := pDMode^.dmFields or
                             DM_PAPERSIZE or
                             DM_PAPERWIDTH or
                             DM_PAPERLENGTH;
         pDMode^.dmPaperSize := Papier;
         pDMode^.dmPaperWidth := SeitenBreite * 10;
         pDMode^.dmPaperLength := SeitenHoehe * 10;
         if Papier <> DMPAPER_A4 then
         begin
           pDMode^.dmFields := pDMode^.dmFields or DMBIN_AUTO;
           pDMode^.dmDefaultSource := DMBIN_AUTO;
         end else
         begin
           pDMode^.dmFields := pDMode^.dmFields or DMBIN_CASSETTE;
           pDMode^.dmDefaultSource := DMBIN_CASSETTE;
         end;

         GlobalUnlock(hDMode);
       end;
     end;
    end;




    procedure EtiketteBeschriften(const AStr: string; ACanvas: TCanvas; ARec: TRect; AbstX, AbstY: Integer);
    var
     Rec: TRect;
    begin
     Rec.Left := ARec.Left + AbstX;
     Rec.Right := ARec.Right - AbstX;
     Rec.Top := ARec.Top + AbstY;
     Rec.Bottom := ARec.Bottom - AbstY;
     ACanvas.Font.Name := FontName;
     ACanvas.Font.Style := Form1.FontStyle;
     ACanvas.Brush.Color := clWhite;
     ACanvas.Font.Size := Form1.EtiketteFontSize;
     DrawText(ACanvas.Handle, PChar(AStr),Length(AStr),Rec,DT_LEFT or DT_TOP);
    end;




    procedure FormulareDrucken;
    var
     XPixProInch,YPixProInch: Integer;

     function XmmToPrn(MassX: Double): Integer;
     begin
       Result := Round(XPixProInch / 25.4 * MassX);
     end;
     function YmmToPrn(MassY: Double): Integer;
     begin
       Result := Round(YPixProInch / 25.4 * MassY);
     end;

    var
     AbstandOben, AbstandLinks: Integer;
     EtiketteNr: Integer;
     i: Integer;
     Etikette: TEtikette;
     NextEtikette: TEtikette;
     Formular, NextFormular: TPaintBox;
     Rec, tmpRec: TRect;
     tmpStr: string;
     DateStr: string;
    begin
     Printer.Orientation := poPortrait;
     XPixProInch := GetDeviceCaps(Printer.Handle,LOGPIXELSX);
     YPixProInch := GetDeviceCaps(Printer.Handle,LOGPIXELSY);
     AbstandOben := GetDeviceCaps(Printer.Handle,PHYSICALOFFSETY);
     AbstandLinks := GetDeviceCaps(Printer.Handle,PHYSICALOFFSETX);

     EtiketteNr := 0;
     NextFormular := nil;
     DateStr := DateToStr(Date);
     if PrinterSupportsDuplex then
       ZweiseitigDruckAus;

     SetSeitenGrosse(DMPAPER_USER, Form1.UpDownBBreite.Position, Form1.UpDownBHoehe.Position);
     Printer.BeginDoc;
     try
       with Form1 do
       begin
         for i := 0 to ListView1.Items.Count - 1 do
         begin
           if ListView1.Items[i].Checked then
           begin
             Etikette := TEtikette(EtikettenList.Items[EtiketteNr]^);
             Formular := TPaintBox(Etikette.PBox);
             Rec := TRect(Etikette.mmRect);
             Rec.Left := XmmToPrn(Rec.Left + KorrLinks) - AbstandLinks;
             Rec.Right := XmmToPrn(Rec.Right + KorrLinks) - AbstandLinks;
             Rec.Bottom := YmmToPrn(Rec.Bottom + KorrOben) - AbstandOben;
             Rec.Top := YmmToPrn(Rec.Top + KorrOben) - AbstandOben;
             if RectDrucken then
               Printer.Canvas.Rectangle(Rec);

             tmpStr := 'Nr.:'+ListView1.Items[i].Caption+'; '+
                       ListView1.Items[i].SubItems.Strings[0]+
                       #10#13+'Duplo:'+ListView1.Items[i].SubItems.Strings[1]+
                       '    Wkz.Type:'+ListView1.Items[i].SubItems[2]+
                       #10#13+'L1:'+ListView1.Items[i].SubItems.Strings[3]+
                       '  L1Korr:'+ListView1.Items[i].SubItems.Strings[4]+
                       #10#13+'R1:'+ListView1.Items[i].SubItems.Strings[5]+
                       '   R1Korr: '+ListView1.Items[i].SubItems.Strings[6]+
                       #10#13+'V.St.Z:'+ListView1.Items[i].SubItems.Strings[11]+
                       ' R.St.Z:'+ListView1.Items[i].SubItems.Strings[12];

             EtiketteBeschriften(tmpStr,Printer.Canvas,Rec,XmmToPrn(1.5),YmmToPrn(1.5));

             tmpRec.Bottom := Rec.Bottom-YmmToPrn(3);
             tmpRec.Top := tmpRec.Bottom-Printer.Canvas.TextHeight('W')+YmmToPrn(0.2);
             tmpRec.Left := Rec.Left + XmmToPrn(2);
             tmpRec.Right := tmpRec.Left + Printer.Canvas.TextWidth('BAZ-'+EdMaschinenNr.Text)+XmmToPrn(0.1);
             DrawText(Printer.Canvas.Handle,PChar('BAZ-'+EdMaschinenNr.Text),
                      Length('BAZ-'+EdMaschinenNr.Text),tmpRec,
                      DT_LEFT or DT_BOTTOM or DT_WORDBREAK);

             tmpRec.Right := Rec.Right - XmmToPrn(4);
             tmpRec.Left :=tmpRec.Right-Printer.Canvas.TextWidth(DateStr)-XmmToPrn(2);

             DrawText(Printer.Canvas.Handle,PChar(DateStr),Length(DateStr),tmpRec,
                      DT_LEFT or DT_BOTTOM or DT_WORDBREAK);

             if EtiketteNr < EtikettenList.Count - 1 then
             begin
               NextEtikette := TEtikette(EtikettenList.Items[EtiketteNr+1]^);
               NextFormular := TPaintBox(NextEtikette.PBox);
             end;
             if NextFormular <> Formular then
               Printer.NewPage;

             Inc(EtiketteNr);
             if EtiketteNr > EtikettenList.Count - 1 then
               Break;
           end;
         end;
       end;
     finally
       Printer.EndDoc;
     end;

    end;

  • Unbekannt © (07.07.16 16:38) [5]
    Как видно - никто не сталкивался с подобной проблемой. Это хорошо. Плохо только, что мне здесь некому помочь. :(
  • xayam © (07.07.16 16:57) [6]

    > Printer.Canvas

    вот из архивов не знаю поможет или нет

    http://delphimaster.net/view/1-1149771296
  • Unbekannt © (07.07.16 17:33) [7]
    xayam ©   (07.07.16 16:57) [6]

    Спасибо, однако это я уже видел. С выводом на холст у меня проблем нет. Проблема в определении позиции листа, если он находится не у левого края на принтере DELL-3460. Конечно, если будет выбран этот принтер для печати можно тупо сместить позицию, но это криво. Office же правильно определяет, кроме того - если опять сменится принтер на какой-нибудь другой, а там ещё хрень какая?
     Вот и спрашиваю, наверняка есть то, о чём я не вкурсе, но что обязательно нужно учитывать. Скорее нужно некий параметр считывать из специфических настроек принтеров.
  • Unbekannt © (07.07.16 17:42) [8]
    Хотя может и так, но как-то криво это всё.

    http://delphimaster.net/view/1-1149771296
    Sergey Masloff   (2006-06-08 21:35) [7]
    Джо ©   (2006-06-08 21:52) [8]
    Джо ©   (2006-06-08 21:55) [9]
  • Kilkennycat © (07.07.16 18:08) [9]

    > Unbekannt ©   (07.07.16 16:38) [5]

    я сталкивался, давно, но мое решение не поможет в силу некрасивости - под каждый принтер делал свой вывод.
  • Unbekannt © (07.07.16 18:30) [10]
    Kilkennycat ©   (07.07.16 18:08) [9]

    Значит они правы?

    Корректировка у меня предусмотренна, но так, на всякий случай, которой не приходилось пользоваться. Предполагал просто, что некоторые этикетки могут быть накленны на лист не точно, ну там 1-2мм, а тут 60-70мм.

    Но меня смущает то, что Office определяет правильно положение конверта.
  • Kilkennycat © (07.07.16 20:44) [11]

    > Unbekannt ©   (07.07.16 18:30) [10]

    Ну, есть два варианта: 1) мы чего-то не знаем и 2) оффисс позволяет себе роскошь знать про все принтеры. В принципе, оффис может себе такое позволить... хотя это и громоздко.
 
Конференция "Прочее" » Проблема с печатью этикеток на разных принтерах
Есть новые Нет новых   [134432   +19][b:0][p:0.005]