zoukankan      html  css  js  c++  java
  • ReportMachine 打印机横向

    Portrait 纵向

    landscape  横向

    RM_reg.pas ;TRMPageSetupForm

    打印机设置RM_PageSetup.dfm

     TRMPageSetting定义在RM_Printer.pas

    TRMPrinterOrientation = (rmpoPortrait, rmpoLandscape);

    TRMPageSetting

    property PageOr: TRMPrinterOrientation read FPageOr write SetPageOr;

    TRMPageSetupForm = class(TForm)

    property PageSetting: TRMPageSetting read FPageSetting;

    TRMPageLayout = class(TPersistent)

    property PageOrientation: TRMPrinterOrientation read FPageOr write FPageOr;

    调用打印机设置窗口

    RM_reg.pas

    procedure TRMPageLayoutProperty.Edit;

    打印方法:

    RM_Class.pas

    procedure TRMReport.PrintReport;

    _DoPrintReport函数中

    lPrinter := ReportPrinter;

    初始值就不对。

    ReportPrinter.PaperWidth;
    ReportPrinter.PaperHeight;

    ReportPrinter.PrintableWidth;
    ReportPrinter.PrintableHeight;

    RMReport1.LoadFromFile('Untitled5.rmf');装载完文件后,RM_Printer.pas里的FRMPrinter变量就变成真实的宽度了从4961变成7016了。也就是说PrintReport无问题了。

    RM_Class.pas

    TRMReport.LoadFromStream

    PrinterName := RMReadString(aStream); 读出原始值。

    Pages.LoadFromStream(FReportVersion, aStream);变成7016了

      >lPage.LoadFromStream(aStream);

    >TRMReportPage.LoadFromStream

    >ChangePaper(FPageSize, PageWidth, PageHeight, FPageBin, FPageOrientation);

    RM_Printer.pas

    procedure TRMCustomPrinter.DeviceContextChanged;

      >FPaperWidth := GetDeviceCaps(FDC, PHYSICALWIDTH); //纸宽 ,单位为打印机象素

    再跟踪

    function TRMCustomPrinter.GetDC: HDC;  FDC有为0 的情况,所以获取值。但是xe8没有为0的情况

     TRMPrinter.SetPrinterInfo函数里,aPageWidth,aPageHeight根据横竖算过了,在SetSettings又算一遍,不是又退回来了嘛!

    procedure TRMPrinter.SetSettings(aPgWidth, aPgHeight: Integer);

    TRMPrinter.SetSettings

    lPDevMode := GlobalLock(lDevMode); 这个lPDevMode 为nil,d7中是正常有值,xe8里为nil,导致后续代码未执行。

    FDevMode := GlobalAlloc(GHND,DocumentProperties(0, PrinterHandle, PChar(lPrinterInfo.Device), lStubDevMode, lStubDevMode, 0)); //一直为0

    D7下

    DocumentProperties(0, PrinterHandle, PChar(lPrinterInfo.Device), lStubDevMode, lStubDevMode, 0);=1012;,C6下也是1012;

    xe8 delphi下,用Longint类型接受返回值是-1,用dword接受返回的是4294967295,这两个值都是错的,用xe8 c++获得是1076,比c6和d7多是因为用了Unicode的原因?

    DocumentProperties()返回最后一个参数设置为 0 时所需的 DEVMODE 缓冲区的字节的数

    function DocumentProperties(hWnd: HWND; hPrinter: THandle; pDeviceName: LPWSTR;const pDevModeOutput: TDeviceMode; var pDevModeInput: TDeviceMode;fMode: DWORD): Longint; stdcall; overload;

    c6定义

     LONG (APIENTRY* pfnDocumentProperties)(HWND hWnd, HANDLE hPrinter, LPTSTR pDeviceName, PDEVMODE pDevModeOutput, PDEVMODE pDevModeInput,DWORD fMode);

    第一步获取nSize不正确,A zero for last param returns the size of buffer needed.最后一个参数为0,后3个都是NULL,不用设定DevMode^参数,就正确了。

    焦点就是如何缓冲区的大缓冲区字节的数

    https://support.microsoft.com/en-us/kb/167345/zh-cn

    https://support.microsoft.com/en-us/kb/140285

    http://blog.csdn.net/hjfjoy/article/details/4250164

    //果然是unicode的差异,导致获得的字节数不一样,以下代码在c6,xec8下都可以执行。结果验证。
    void
    __fastcall TForm35::Button1Click(TObject *Sender) { HANDLE hPrinter; DWORD pDevModeBytes; OpenPrinter(L"Microsoft XPS Document Writer", &hPrinter, NULL); pDevModeBytes = DocumentPropertiesW(0, hPrinter, L"Microsoft XPS Document Writer", NULL, NULL, 0); //1076 pDevModeBytes = DocumentPropertiesA(0, hPrinter, "Microsoft XPS Document Writer", NULL, NULL, 0); //1012 }
    LONG
    WINAPI
    AdvancedDocumentPropertiesA(
    IN HWND hWnd,
    IN HANDLE hPrinter,
    IN LPSTR pDeviceName,
    OUT PDEVMODEA pDevModeOutput,
    IN PDEVMODEA pDevModeInput
    );
    LONG
    WINAPI
    AdvancedDocumentPropertiesW(
    IN HWND hWnd,
    IN HANDLE hPrinter,
    IN LPWSTR pDeviceName,
    OUT PDEVMODEW pDevModeOutput,
    IN PDEVMODEW pDevModeInput
    );

    RM_Printer.pas  1334 Line

     DocumentProperties(0, PrinterHandle, PChar(lPrinterInfo.Device), lStubDevMode, lStubDevMode, 0); 

    >改成下面的就好了。

     DocumentProperties(0, PrinterHandle, PChar(lPrinterInfo.Device), nil, nil, 0);

    这个计算空间,每一种打印机大小都不一样,打印机牌子、型号不一样,空间大小不相同,只能实际计算了。

    最后修改正确,监视lPrinter的值如下,和d7相同了。

    Draw(MasterReport, lPrinter.Canvas, liRect);

  • 相关阅读:
    关于Unity中表面着色器的使用
    关于Unity中顶点片元Shader实例
    php 超时 解决办法 (Maximum execution time of 30 seconds exceeded)这个问题?
    php 汉字转拼音
    jq 获取当前屏幕高度
    php 根据身份证获取出身地址
    根据身份证算出地址
    css 超详细文档
    手机端下拉获取新数据
    基于bootstrap 框架的扩展框架 H-ui
  • 原文地址:https://www.cnblogs.com/cb168/p/4635216.html
Copyright © 2011-2022 走看看