ReportMachine不能打开打印机属性设置的解决方法

ReportMachine不能打开打印设置的解决方法

1、问题现象

在使用ReportMachine作为报表打印时,发现不能调用本机打印机属性设置对话框,如下图:

这里写图片描述

 点击“属性”按钮后无反应,从而不能对打印机属性进行设置。该问题同时也导致不能获取打印机设置信息。

2、问题原因

跟踪代码发现点击“属性”,会调用“PropertiesDlg”函数,RM_Printer.pas文件中,代码如下:
function TRMPrinter.PropertiesDlg: Boolean;
var
    lDevMode: THandle;
    lPDevMode: PDeviceMode;
    lHandle: THandle;
    lResult: Boolean;
begin
    FLock.Acquire;
    try
        GetDevMode(lDevMode);  //调用返回lDevMode一直为0 
        Result := False;
        lResult := FALSE;
        try
            lPDevMode := GlobalLock(lDevMode);//不能分配内存,lPDevMode 为nil.
            if Screen.ActiveForm <> nil then
                lHandle := Screen.ActiveForm.Handle
            else
                lHandle := 0;

            if lPDevMode <> nil  then  //lPDevMode 为nil,不调用打印机属性设置
                lResult := (Winspool.DocumentProperties(lHandle, PrinterHandle, PChar(PrinterInfo.Device),
                    lPDevMode^, lPDevMode^, DM_IN_BUFFER or DM_OUT_BUFFER or DM_IN_PROMPT) > 0);

            if lResult then
            begin
                SetDevMode(lDevMode);
                Result := True;
            end;

            GlobalUnlock(lDevMode);
        finally
            GlobalFree(lDevMode);
        end;
    finally
        FLock.Release;
    end;
end;
进而跟踪GetDevMode,找到RM_Printer.pas文件中GetDocumentProperties函数,代码段如下:
function TRMCustomPrinter.GetDocumentProperties: THandle;
var
    lStubDevMode: TDeviceMode;
    lPrinterInfo: TRMPrinterInfo;
begin
    FLock.Acquire;
    try
        Result := 0;
        if FDevMode = 0 then
        begin
            lPrinterInfo := RMPrinters.PrinterInfo[FPrinterIndex];
            if lPrinterInfo = nil then
                Exit;

            FDevMode := GlobalAlloc(GHND,
                DocumentProperties(0, PrinterHandle, PChar(lPrinterInfo.Device), lStubDevMode, lStubDevMode, 0));
            //这里FDevMode 执行后始终为0,函数反馈也就为0.同时,导致以下IF内代码不会执行,不能获取打印机属性信息。

            if FDevMode <> 0 then
            begin
                FPDevMode := GlobalLock(FDevMode);
                if DocumentProperties(0, PrinterHandle, PChar(lPrinterInfo.Device), FPDevMode^, FPDevMode^, DM_OUT_BUFFER) >= 0 then
                begin
                    FDefaultBin := FPDevMode^.dmDefaultSource;
                end
                else
                    FreeDevMode;
            end;
        end;
        Result := FDevMode;
    finally
        FLock.Release;
    end;
end;

3、解决办法

更改GetDocumentProperties函数中的代码
DocumentProperties(0, PrinterHandle, PChar(lPrinterInfo.Device), lStubDevMode, lStubDevMode, 0)
DocumentProperties(0, PrinterHandle, PChar(lPrinterInfo.Device), nil, nil, 0)
  完整代码如下:
function TRMCustomPrinter.GetDocumentProperties: THandle;
var
//  lStubDevMode: TDeviceMode;
    lPrinterInfo: TRMPrinterInfo;
begin
    FLock.Acquire;
    try
        Result := 0;
        if FDevMode = 0 then
        begin
            lPrinterInfo := RMPrinters.PrinterInfo[FPrinterIndex];
            if lPrinterInfo = nil then
                Exit;

            FDevMode := GlobalAlloc(GHND,
                DocumentProperties(0, PrinterHandle, PWideChar(lPrinterInfo.Device), nil, nil, 0));

            if FDevMode <> 0 then
            begin
                FPDevMode := GlobalLock(FDevMode);
                if DocumentProperties(0, PrinterHandle, PChar(lPrinterInfo.Device), FPDevMode^, FPDevMode^, DM_OUT_BUFFER) >= 0 then
                begin
                    FDefaultBin := FPDevMode^.dmDefaultSource;
                end
                else
                    FreeDevMode;
            end;
        end;
        Result := FDevMode;
    finally
        FLock.Release;
    end;
end;
发布了20 篇原创文章 · 获赞 29 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/tanqth/article/details/71396075