在DELPHI中自绘制了一个表格,在不同的打印机上打出的表格大小不样。打印出的表格实际大小应该一样才对。请问应如何设置打印参数(打印之前的几个WINDOWS API如何调用)。最好有示例代码。

解决方案 »

  1.   

    实际打出来不一样才对,因为不同的打印机,它们的分辨率也是不同的
    给你一段代码用用?unit mPrint;interfaceuses
      Windows, Classes, SysUtils, Forms, Graphics, Printers, Dialogs;  procedure SetPaperHeight(Value:integer);
      Procedure SetPaperWidth(Value:integer);
      //打印文字部分
      procedure PrintText(X, Y: Extended; Txt: string; m_Font : TFont);
      //打印线条 guofeng
      Procedure PrintLine(x,y,x1,y1:Extended);
      procedure GetOffsetPos;
      //字符宽度
      function AvgCharWidth: Word;
      //字符高度
      function CharHeight: Word;
    //设置纸张时显示实际的纸张值
      function PosChangX(PosX:integer):integer;
      function PosChangY(PosY:integer):integer;
    implementationvar
     OffSetX, OffSetY: Integer;//取得字符的高度
    function CharHeight: Word;
    var
      Metrics: TTextMetric;
    begin
     GetTextMetrics(Printer.Canvas.Handle, Metrics);
     Result := Metrics.tmHeight;
    end;//file://取得字符的平均宽度
    function AvgCharWidth: Word;
    var
     Metrics: TTextMetric;
    begin
     GetTextMetrics(Printer.Canvas.Handle, Metrics);
     Result := Metrics.tmAveCharWidth;
    end;//file://取得纸张的物理尺寸---单位:点
    function GetPhicalPaper: TPoint;
    var
     PageSize : TPoint;
    begin
     //PageSize.X; 纸张物理宽度-单位:点
     //PageSize.Y; 纸张物理高度-单位:点
     Escape(Printer.Handle, GETPHYSPAGESIZE, 0,nil,@PageSize);
     Result := PageSize;
    end;//file://2.取得纸张的逻辑宽度--可打印区域
    //file://取得纸张的逻辑尺寸
    function PaperLogicSize: TPoint;
    var
     APoint: TPoint;
    begin
     APoint.X := Printer.PageWidth;
     APoint.Y := Printer.PageHeight;
     Result := APoint;
    end;//file://纸张水平对垂直方向的纵横比例
    function HVLogincRatio: Extended;
    var
     AP: TPoint;
    begin
     Ap := PaperLogicSize;
     Result := Ap.y/Ap.X;
    end;//file://取得纸张的横向偏移量-单位:点
    function GetOffSetX: Integer;
    begin
     Result := GetDeviceCaps(Printer.Handle, PhysicalOffSetX);
    end;//file://取得纸张的纵向偏移量-单位:点
    function GetOffSetY: Integer;
    begin
     Result := GetDeviceCaps(Printer.Handle, PhysicalOffSetY);
    end;//file://毫米单位转换为英寸单位
    function MmToInch(Length: Extended): Extended;
    begin
     Result := Length/25.4;
    end;//file://英寸单位转换为毫米单位
    function InchToMm(Length: Extended): Extended;
    begin
     Result := Length*25.4;
    end;//file://取得水平方向每英寸打印机的点数
    function HPointsPerInch: Integer;
    begin
     Result := GetDeviceCaps(Printer.Handle, LOGPIXELSX);
    // ShowMessage(IntToStr(Result));
    end;//file://取得纵向方向每英寸打印机的光栅数
    function VPointsPerInch: Integer;
    begin
     Result := GetDeviceCaps(Printer.Handle, LOGPIXELSY)
    end;//file://横向点单位转换为毫米单位
    function XPointToMm(Pos: Integer): Extended;
    begin
     Result := Pos*25.4/HPointsPerInch;
    end;//file://纵向点单位转换为毫米单位
    function YPointToMm(Pos: Integer): Extended;
    begin
     Result := Pos*25.4/VPointsPerInch;
    end;//file://设置纸张高度-单位:mm
    procedure SetPaperHeight(Value: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
    //file://自定义纸张最小高度127mm
      if Value <  127 then Value := 127;
      //自定义纸张最大高度432mm
     if Value >  432 then Value := 432;
      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_PAPERLENGTH;
         pDMode^.dmPaperSize := DMPAPER_USER;
         pDMode^.dmPaperLength := Value * 10;
         pDMode^.dmFields := pDMode^.dmFields or DMBIN_MANUAL;
         pDMode^.dmDefaultSource := DMBIN_MANUAL;
         GlobalUnlock(hDMode);
        end;
       end;
       Printer.PrinterIndex := Printer.PrinterIndex;
    end;// //设置纸张宽度:单位--mm
    Procedure SetPaperWidth(Value: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
     //自定义纸张最小宽度76mm if Value <  76 then Value := 76;
      //自定义纸张最大宽度216mm
     if Value >  216 then Value := 216;  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;
        pDMode^.dmPaperSize := DMPAPER_USER;
         //将毫米单位转换为0.1mm单位
        pDMode^.dmPaperWidth := Value * 10;
        pDMode^.dmFields := pDMode^.dmFields or DMBIN_MANUAL;
        pDMode^.dmDefaultSource := DMBIN_MANUAL;
        GlobalUnlock(hDMode);
       end;
      end;
      Printer.PrinterIndex := Printer.PrinterIndex;
    end;procedure GetOffsetPos;
    var
     Fn: TStrings;
     FileName: string;
    begin
    try
     Fn := TStringList.Create;
     FileName := ExtractFilePath(Application.ExeName) + 'PrnPosSet.ini';
     if FileExists(FileName) then
     begin
      Fn.LoadFromFile(FileName);
      OffSetX := StrToInt(Fn.Values['X']);
      OffSetY := StrToInt(Fn.Values['Y']);
     end
      else
      begin
       Fn.Values['X'] := '160';
       Fn.Values['Y'] := '-20';   OffSetX := 60;
       OffSetY := -20;   Fn.SaveToFile(FileName);
      end;
     finally
       Fn.Free;
     end;
    end;// //在 (Xmm, Ymm)处按指定配置文件信息和字体输出字符串
    procedure PrintText(X, Y: Extended; Txt: string;  m_Font : TFont);
    var
     Px, Py: Integer;
    // TempInt:integer;
    begin
     GetOffsetPos();
    //打开配置文件,读出横向和纵向偏移量
     X := X + OffSetX;
     Y := Y + OffSetY; Px := Round(X/90 * HPointsPerInch);
     Py := Round(Y/90 * VPointsPerInch); Py := Py - GetOffSetY-CharHeight-2;
     Px := Px - GetOffSetX; Printer.Canvas.Font.Assign(m_Font);
     Printer.Canvas.TextOut(Px, Py, Txt);
    end;//增加画线部分 gzf
    procedure PrintLine(X,Y,X1,Y1: Extended);
    var
     Px, Py: Integer;
     Px1, Py1: Integer;
    begin
      GetOffsetPos();
    //打开配置文件,读出横向和纵向偏移量  画线部分的起点
     X := X + OffSetX;
     Y := Y + OffSetY; Px := Round(X/90 * HPointsPerInch);
     Py := Round(Y/90 * VPointsPerInch); Py := Py - GetOffSetY;
     Px := Px - GetOffSetX;//打开配置文件,读出横向和纵向偏移量  画线部分的终点
     X1:= X1 + OffSetX;
     Y1 := Y1 + OffSetY; Px1 := Round(X1/90 * HPointsPerInch);
     Py1 := Round(Y1/90 * VPointsPerInch); Py1 := Py1 - GetOffSetY;
     Px1 := Px1 - GetOffSetX; with Printer.Canvas do
      begin
        MoveTo(px,py);
        LineTo(px1,py1);
      end;
    end;function PosChangX(PosX:integer):integer;
    var
      TempX:integer;
    begin
      TempX:=PosX;
      TempX:=Round(TempX/90 * HPointsPerInch);
      Result:=TempX- GetOffSetX;
    end;function PosChangY(PosY:integer):integer;
    var
      TempY:integer;
    begin
      TempY:=PosY;
      TempY:=Round(TempY/90 * HPointsPerInch);
      Result:=TempY- GetOffSetY;
    end;
    end.