单位要求做一个通用的票据打印程序,要求实现不同的票据格式可以自定义,票据的类型也可以增加,要求打印的格式和输入窗口上的格式格式一样,这样只要调整输入窗口上的内容格式就可以了,(不知道有没有说清楚)。
   现在的问题是,
   1。窗口上的格式和打印的格式怎么对应?
   2。是否可以用打印控件?想用FASTREPORT 但是实现不了这个功能
   3。是否要自己写打印控件来实现?
  脑子一团遭。
  谢谢

解决方案 »

  1.   

    自己很难写这种方式的软件,水平问题。换种思路吧,简单点。delhpi.ys168.com
      

  2.   

    可以用FastReport,完全可以实现,我都使用几年了.建议使用FastReport的升级板子:ReportMachine,里面应该有套打的例子.
    代码处理时,真对每一种票据定义一个套打格式文件,很简单.
      

  3.   

    用FastReport完全没有问题,而且可以利用它的多模板来针对多种票据格式。
    例如你可以在窗口上摆放一些TLabel控件作为票据上的内容,然后用代码做一个可以手动改变控件在窗口坐标(也就是Left和Top)的功能,然后在把这些属性数值保存到FastReport模板相应的
    控件(如:Memo等),就可以了。问题的关键是如何把窗口的控件和模板相应的控件对应上,如果程序要求不是太复杂的话,个人建议你可以把二者赋予相同的Name,这样就好处理了。
    这些实现起来还是有些复杂的,不过效果确很不错。
      

  4.   

    我用fastreport基本实现了楼主的想法。
      

  5.   

    Rave都一样OK
    直接End User Design都OK的
      

  6.   

    要写自己写程序的话也很简单。
    套打位置和实际设置不同原因是打印机和电脑分辨率不同。所以在实际编写程序中要注意,使用以下函数
    getdevicecaps(printer.handle,LOGPIXELSX); 获得DC的分辨率。
    getdevicecaps(getdc(0),LOGPIXELSX);获得屏幕分辨率LOGPIXELSY是y轴分辨率。
    返回是每英寸像素点个数。1 INCH =2.54CM
    利用这个就可以做到精确打印。如果还要获得其它设置,例如自定义纸张,当前纸张的大小等等...var
    Device : array[0..MAX_PATH] of char;
    Driver : array[0..MAX_PATH] of char;
    Port   : array[0..MAX_PATH] of char;
    hDMode : THandle;
    PDMode : PDEVMODE;//这个是打印机的设置数据.MS中为DEVMODE。
    pr:Tprinter;
    begin
     pr:=Tprinter.Create;
     pr.GetPrinter(device,driver,port,hdmode);
     pDMode := GlobalLock(hDMode); //锁定设置内存
     pagelength:=pDmode.dmPaperLength;//修改设置,读取设置
     pagewidth:=pDmode.dmPaperWidth;
     printDPI:=PDmode.dmPrintQuality;
     ...
     GlobalUnlock(hDMode); //释放打印机设置内存
     pr.free;
     
    end;
      

  7.   

    var
      Pixels: Integer;
      LeftOffset, TopOffset: integer;
      PaperWidth, PaperHeight: integer;
      scalex, scaley: integer;
    begin
      TopOffset := GetDeviceCaps(ACanvas.Handle, PHYSICALOFFSETY); //device unit
      LeftOffset := GetDeviceCaps(ACanvas.Handle, PHYSICALOFFSETX); // device unit
      Pixels := GetDeviceCaps(ACanvas.Handle, LOGPIXELSY);  // device unit
      PaperWidth := GetDeviceCaps(ACanvas.Handle, HORZRES); // device unit
      PaperHeight := GetDeviceCaps(ACanvas.Handle, VERTRES); // device unit
      SetMapMode(ACanvas.Handle, MM_ANISOTROPIC);
        Scalex := MulDiv(PaperNeedWidth, Pixels, 254);
        scaley := MulDiv(PaperNeedHeight, Pixels, 254);
        SetWindowExtEx(ACanvas.Handle, PaperNeedWidth, PaperNeedHeight, nil);
        SetViewportExtEx(ACanvas.Handle, scalex, scaley, nil);
        PaperWidth := GetDeviceCaps(ACanvas.Handle, PHYSICALWIDTH) * 254 div Pixels;
        PaperHeight := GetDeviceCaps(ACanvas.Handle, PHYSICALHEIGHT) * 254 div Pixels;
        if Center then
          SetWindowOrgEx(ACanvas.Handle, LeftMargin - ((PaperWidth - PaperNeedWidth) div 2),
            TopMargin - ((PaperHeight - PaperNeedHeight) div 2), nil);
        SetViewportOrgEx(ACanvas.Handle, - LeftOffset, - TopOffset, nil);
      ACanvas.Font.PixelsPerInch := 254;之后就可以在这个画布上按照每单位对应0.1mm进行绘制了