-
Для производственных целей я написал программку, которая из ЧПУ-машин считывает данные инструментов, а потом данные выбранных инструментов печатает на этикетки. Прблема в том, что дома тестировал на струйном принтере Canon Pixma MP 780 с этикетками в две колонки и четыре ряда - всё отлично. На работе уже около двух лет при печти на сетевой лазерный принтер HP-какойто тоже всё было отлично. Но возникла необходимость печатать на лазерник DELL-3460 и появилась проблема: если на HP-принтере вставлять лист с этикетками в верхний лоток, в котором щёчки для установки размеры (левая и правая) сдвигаются и раздвигаются так, что позиция листа находится всегда в середине - принтер коррекно распозаёт заданный из моей программы размер и позицию листа в зависимости от положения щёчек и печатает корректно, но на принтере DELL лист на верхнем лотке также находится всегда в середине, но печатает зараза, как если бы лист находился у левого края. Пож. подскажите где собака зарыта.
-
Да, нужно заметить, что при печати из Office конвертов этот самый Dell положение конверта определяет правилно.
-
Чего-то конкретного по этим моделям принтеров подсказать не смогу, но смогу предположить, что были использованы низкоуровневые команды для конкретного вида принтеров. Чтобы было универсально, надо печатать на абстрактный холст (Canvas), тогда везде будет более менее одинаково - ОС разрулит конкретику на уровне драйверов.
-
Именно всё на Printer.Canvas и печатаю.
-
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;
-
Как видно - никто не сталкивался с подобной проблемой. Это хорошо. Плохо только, что мне здесь некому помочь. :(
-
-
xayam © (07.07.16 16:57) [6]
Спасибо, однако это я уже видел. С выводом на холст у меня проблем нет. Проблема в определении позиции листа, если он находится не у левого края на принтере DELL-3460. Конечно, если будет выбран этот принтер для печати можно тупо сместить позицию, но это криво. Office же правильно определяет, кроме того - если опять сменится принтер на какой-нибудь другой, а там ещё хрень какая? Вот и спрашиваю, наверняка есть то, о чём я не вкурсе, но что обязательно нужно учитывать. Скорее нужно некий параметр считывать из специфических настроек принтеров.
-
-
> Unbekannt © (07.07.16 16:38) [5]
я сталкивался, давно, но мое решение не поможет в силу некрасивости - под каждый принтер делал свой вывод.
-
Kilkennycat © (07.07.16 18:08) [9]
Значит они правы?
Корректировка у меня предусмотренна, но так, на всякий случай, которой не приходилось пользоваться. Предполагал просто, что некоторые этикетки могут быть накленны на лист не точно, ну там 1-2мм, а тут 60-70мм.
Но меня смущает то, что Office определяет правильно положение конверта.
-
> Unbekannt © (07.07.16 18:30) [10]
Ну, есть два варианта: 1) мы чего-то не знаем и 2) оффисс позволяет себе роскошь знать про все принтеры. В принципе, оффис может себе такое позволить... хотя это и громоздко.
|