Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Решение проблемы с печатью в Windows 10 при использовании Delphi 7 и QuickReport 5.02.2

Delphi , Компоненты и Классы , TQuickReport

Если вы столкнулись с проблемой печати в Windows 10 при использовании Delphi 7 и QuickReport 5.02.2, то данная статья поможет вам найти решение этой проблемы.

Оригинальный вопрос:

Delphi 7 / QuickReport 5.02.2

Мы использовали подобный код в течение нескольких лет, ноRecently, we've encountered an issue now that we're migrating workstations to Windows 10. Previously, we were using Windows 7 and all was fine. Maybe there's something I'm missing or doing wrong?

Here's a simple test project I put together to test this. When the report is within a DLL every call to "Printer.GetPrinter" fails in Windows 10. Though, if the report is on a form within the main application it works fine.

Below is the code, and a zipped up folder for anyone that's interested. There is the dependency on QuickReport though, which can't be helped. Thanks for looking.

https://1drv.ms/u/s!AsbtokV75aocsXM6MQZcrvwpHKcg

ДLL проект.

library test_dll;

uses SysUtils, Classes, Forms, report in 'report.pas' {report_test};

{$R *.res}

function Report_Print(PrinterName: WideString): Integer; export; var Receipt: Treport_test; begin try Receipt := Treport_test.Create(nil); try Receipt.Print(PrinterName); Receipt.Close; finally Receipt.Free; end; except Application.HandleException(Application.Mainform); end; Result := 1; end;

exports Report_Print; begin

end.

Единица отчета.

unit report;

interface

uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, QRCtrls, QuickRpt, ExtCtrls, Printers, QRpCtrls, QRPrntr;

type Treport_test = class(TForm) QuickRep1: TQuickRep; DetailBand1: TQRBand; TitleBand1: TQRBand; QRLabel1: TQRLabel; SummaryBand1: TQRBand; QRLabel2: TQRLabel; QRLabel3: TQRLabel; private { Private declarations } public { Public declarations } procedure Print(const PrinterName: string); end;

var report_test: Treport_test;

procedure SetupPrinter(QuickRep: TQuickRep; const PrinterName: string); function SelectPrinter(QuickRep: TQuickRep; const PrinterName: string): boolean;

implementation

var DLL_QRPrinter: TQRPrinter;

{$R *.dfm}

function SelectPrinter(QuickRep: TQuickRep; const PrinterName: string): boolean; var i: integer; compareLength: integer; windowsPrinterName: string; selectedPrinter: Integer; defaultPrinterAvailable: Boolean; begin defaultPrinterAvailable := True; try // an exception will occur if there is no default printer i := Printer.printerIndex; if i > 0 then ; // this line is here so Delphi does not generate a hint except defaultPrinterAvailable := False; end;

compareLength := Length(PrinterName); if (not Assigned(QuickRep.QRPrinter)) then begin QuickRep.QRPrinter := DLL_QRPrinter; end; // Look for the printer. selectedPrinter := -1;

// Attempt #1: first try to find an exact match for i := 0 to QuickRep.QRPrinter.Printers.Count - 1 do begin windowsPrinterName := Copy(QuickRep.QRPrinter.Printers.Strings[i], 1, compareLength); if (UpperCase(windowsPrinterName) = UpperCase(PrinterName)) then begin selectedPrinter := i; Break; end; end;

// Attempt #2: if no exact matches, look for the closest if (selectedPrinter < 0) then for i := 0 to QuickRep.QRPrinter.Printers.Count - 1 do begin windowsPrinterName := Copy(QuickRep.QRPrinter.Printers.Strings[i], 1, compareLength); if (Pos(UpperCase(PrinterName), UpperCase(QuickRep.QRPrinter.Printers.Strings[i])) > 0) then begin selectedPrinter := i; Break; end; end;

// Attempt #3: if no exact matches, and nothing close, use default printer if (selectedPrinter < 0) and (defaultPrinterAvailable) then selectedPrinter := QuickRep.Printer.printerIndex;

Result := False; if (selectedPrinter > -1) then begin QuickRep.PrinterSettings.PrinterIndex := selectedPrinter; Result := True; end; end;

procedure SetupPrinter(QuickRep: TQuickRep; const PrinterName: string); begin //check if we have the default printer instead of the selected printer SelectPrinter(QuickRep, PrinterName);

QuickRep.Page.Units := Inches; QuickRep.Page.Length := 11; end;

procedure Treport_test.Print(const PrinterName: string); begin SetupPrinter(QuickRep1, PrinterName); QuickRep1.Print; end;

initialization DLL_QRPrinter := TQRPrinter.Create(nil);

finalization DLL_QRPrinter.Free; DLL_QRPrinter := nil; end.

Тестовое приложение.

program Project1;

uses Forms, Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

begin Application.Initialize; Application.CreateForm(TForm1, Form1); Application.Run; end.

Главная форма.

unit Unit1;

interface

uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, QRPrntr, Dialogs, StdCtrls, QuickRpt, QRCtrls, ExtCtrls, Printers, QRPCtrls;

type TForm1 = class(TForm) Button1: TButton;

procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end;

type TPrintReport = function(PrinterName: WideString): Integer;

var Form1: TForm1;

procedure PrintReport(const PrinterName: string);

implementation

var DLLHandle: THandle = 0; POS: TPrintReport = nil;

{$R *.dfm}

procedure PrintReport(const PrinterName: string); begin try POS(PrinterName); except on e: Exception do ShowMessage(e.Message); end; end;

procedure LoadDLL; var DLLName: string; DLLRoutine: PChar; begin DLLName := 'test_dll.dll'; DLLRoutine := 'Report_Print'; if not (FileExists(DLLName)) then raise Exception.CreateFmt('The DLL "%s" is missing. Build the DLL project and try again.', [DLLName]);

Application.ProcessMessages; DLLHandle := LoadLibrary(PChar(DLLName)); Application.ProcessMessages;

if (DLLHandle = 0) then raise Exception.CreateFmt('Error: %s, while attempting to load DLL %s.', [IntToStr(GetLastError), DLLName]);

POS := GetProcAddress(DLLHandle, DLLRoutine); if (@POS = nil) then raise Exception.CreateFmt('Error: %s, while attempting get address to %s in DLL %s.', [IntToStr(GetLastError), DLLRoutine, DLLName]); end;

procedure TForm1.Button1Click(Sender: TObject); begin LoadDLL; ShowMessage('dll loaded'); PrintReport('MyPrinter'); FreeLibrary(DLLHandle); end;

end.

Вырезка из QuickReport

procedure TPrinterSettings.ApplySettings; var Cancel : boolean; begin FPrinter.GetPrinter(FDevice, FDriver, FPort, DeviceMode); DevMode := GlobalLock(DeviceMode); begin SetField(dm_paperlength); ...

DeviceMode is 0, so SetField throws an access violation. See below.

Access violation at address 036BFBA7 in module 'test_dll.dll'. Write of address 00000028.

Возможное решение:

Если вы используете Delphi 7 и QuickReport 5.02.2, и у вас возникла проблема с печатью в Windows 10, то вы можете попробовать следующее решение:

  1. Откройте файл report.pas в редакторе кода.
  2. Найдите процедуру TPrinterSettings.ApplySettings и удалите следующие две строки кода: FPrinter.GetPrinter(FDevice, FDriver, FPort, DeviceMode); DevMode := GlobalLock(DeviceMode);
  3. Сохраните файл и перекомпилируйте проект.

Если это не поможет, то вы можете попробовать другой подход:

Альтернативное решение:

Если предыдущее решение не помогло, то вы можете попробовать следующее альтернативное решение:

  1. Добавьте следующие единицы в начало своего проекта: uses ComObj, ActiveX, StdVcl;
  2. Добавьте следующий код в начало процедуры TForm1.Button1Click: if Printer.Printers.Count > 0 then begin FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator'); FWMIService := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', ''); FWbemObject := FWMIService.Get(Format('Win32_Printer.DeviceID="%s"', [Printer.Printers.Strings[0]])); if not VarIsClear(FWbemObject) then FWbemObject.SetDefaultPrinter(); end;
  3. Сохраните файл и перекомпилируйте проект.

Надеюсь, что одно из этих решений поможет вам решить проблему с печатью в Windows 10 при использовании Delphi 7 и QuickReport 5.02.2.

Создано по материалам из источника по ссылке.

Проблема печати в Windows 10 при использовании Delphi 7 и QuickReport 5.02.2


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: TQuickReport ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-01-28 07:16:31/0.0023119449615479/0