Printers, don't setup printer list while printer object is being destroyed, fix issue #26489

git-svn-id: trunk@46235 -
This commit is contained in:
jesus 2014-09-14 17:41:24 +00:00
parent cac409bb01
commit 679d20a26e
9 changed files with 98 additions and 66 deletions

View File

@ -282,7 +282,7 @@ begin
//DebugLn('Default ' + FDefaultPrinter); //DebugLn('Default ' + FDefaultPrinter);
end; end;
destructor TCarbonPrinter.Destroy; procedure TCarbonPrinter.DoDestroy;
begin begin
FPrinterContext.Free; FPrinterContext.Free;
@ -290,7 +290,7 @@ begin
if FPageFormat <> nil then PMRelease(PMObject(FPageFormat)); if FPageFormat <> nil then PMRelease(PMObject(FPageFormat));
if FPrintSession <> nil then PMRelease(PMObject(FPrintSession)); if FPrintSession <> nil then PMRelease(PMObject(FPrintSession));
inherited Destroy; inherited DoDestroy;
end; end;
function TCarbonPrinter.Write(const Buffer; Count: Integer; function TCarbonPrinter.Write(const Buffer; Count: Integer;

View File

@ -77,12 +77,12 @@ type
function GetCanPrint: Boolean;override; function GetCanPrint: Boolean;override;
function GetCanRenderCopies : Boolean;override; function GetCanRenderCopies : Boolean;override;
procedure RawModeChanging; override; procedure RawModeChanging; override;
procedure DoDestroy; override;
public public
procedure Validate; procedure Validate;
procedure UpdatePrinter; procedure UpdatePrinter;
public public
constructor Create; override; constructor Create; override;
destructor Destroy; override;
function Write(const {%H-}Buffer; {%H-}Count:Integer; var {%H-}Written: Integer): Boolean; override; function Write(const {%H-}Buffer; {%H-}Count:Integer; var {%H-}Written: Integer): Boolean; override;
// Warning not portable functions here // Warning not portable functions here
property CurrentPrinterName: String read GetCurrentPrinterName; property CurrentPrinterName: String read GetCurrentPrinterName;

View File

@ -147,11 +147,11 @@ begin
CreatePrintSettings; CreatePrintSettings;
end; end;
destructor TQtPrinters.Destroy; procedure TQtPrinters.DoDestroy;
begin begin
FPagesEnum.Free; FPagesEnum.Free;
QtDefaultPrinter.endDoc; QtDefaultPrinter.endDoc;
inherited Destroy; inherited DoDestroy;
end; end;
function TQtPrinters.Write(const Buffer; Count: Integer; function TQtPrinters.Write(const Buffer; Count: Integer;

View File

@ -51,12 +51,12 @@ type
function GetCanPrint: Boolean;override; function GetCanPrint: Boolean;override;
function GetCanRenderCopies : Boolean;override; function GetCanRenderCopies : Boolean;override;
procedure RawModeChanging; override; procedure RawModeChanging; override;
procedure DoDestroy; override;
public public
procedure Validate; procedure Validate;
function GetPaperSize(Const Str: String): QPrinterPageSize; function GetPaperSize(Const Str: String): QPrinterPageSize;
public public
constructor Create; override; constructor Create; override;
destructor Destroy; override;
function Write(const {%H-}Buffer; {%H-}Count:Integer; var {%H-}Written: Integer): Boolean; override; function Write(const {%H-}Buffer; {%H-}Count:Integer; var {%H-}Written: Integer): Boolean; override;
property ColorMode: QPrinterColorMode read GetColorMode write SetColorMode; property ColorMode: QPrinterColorMode read GetColorMode write SetColorMode;

View File

@ -122,7 +122,7 @@ begin
FCupsPapersCount := -1; FCupsPapersCount := -1;
end; end;
destructor TCUPSPrinter.Destroy; procedure TCUPSPrinter.DoDestroy;
begin begin
if assigned(fRawModeStream) then if assigned(fRawModeStream) then
fRawModeStream.Free; fRawModeStream.Free;
@ -132,7 +132,7 @@ begin
if Assigned(fcupsHttp) then if Assigned(fcupsHttp) then
httpClose(fcupsHttp); httpClose(fcupsHttp);
inherited destroy; inherited DoDestroy;
end; end;
procedure TCUPSPrinter.FreeOptions; procedure TCUPSPrinter.FreeOptions;

View File

@ -158,9 +158,9 @@ type
function GetResolutionOption: string; function GetResolutionOption: string;
function IsOptionValueValid(AKeyword,AValue: pchar): boolean; function IsOptionValueValid(AKeyword,AValue: pchar): boolean;
function PPDOptionChoiceFrom(OptionStr, aKeyOrValue: string; IsKey:boolean): pppd_choice_t; function PPDOptionChoiceFrom(OptionStr, aKeyOrValue: string; IsKey:boolean): pppd_choice_t;
procedure DoDestroy; override;
public public
constructor Create; override; constructor Create; override;
destructor Destroy; override;
function Write(const Buffer; Count:Integer; var Written: Integer): Boolean; override; function Write(const Buffer; Count:Integer; var Written: Integer): Boolean; override;
{------------------------------------------------- {-------------------------------------------------

View File

@ -47,10 +47,8 @@ begin
fPrinterHandle := 0; //None fPrinterHandle := 0; //None
end; end;
destructor TWinPrinter.Destroy; procedure TWinPrinter.DoDestroy;
begin begin
fDestroying := true;
ClearDC; ClearDC;
DoResetPrintersList; DoResetPrintersList;
@ -58,7 +56,7 @@ begin
if fPrinterHandle <> 0 then if fPrinterHandle <> 0 then
ClosePrinter(fPrinterHandle); ClosePrinter(fPrinterHandle);
inherited Destroy; inherited DoDestroy;
end; end;
function TWinPrinter.Write(const Buffer; Count: Integer; function TWinPrinter.Write(const Buffer; Count: Integer;
@ -97,7 +95,7 @@ end;
procedure TWinPrinter.PrinterSelected; procedure TWinPrinter.PrinterSelected;
begin begin
if not fDestroying and (PrinterIndex >= 0) and not RawMode then if ([pfDestroying, pfRawMode]*PrinterFlags=[]) and (PrinterIndex>=0) then
SetDC; SetDC;
end; end;
@ -888,7 +886,7 @@ begin
if FPrinterHandle <> 0 then if FPrinterHandle <> 0 then
ClosePrinter(FPrinterHandle); ClosePrinter(FPrinterHandle);
if fDestroying then if pfDestroying in PrinterFlags then
result := i result := i
else begin else begin
PDev := TPrinterDevice(Printers.Objects[i]); PDev := TPrinterDevice(Printers.Objects[i]);

View File

@ -36,7 +36,6 @@ Type
fLastHandleType : THandleType; fLastHandleType : THandleType;
fDC : HDC; fDC : HDC;
fPrinterHandle : THandle; fPrinterHandle : THandle;
fDestroying : boolean;
procedure SetIC; procedure SetIC;
procedure SetDC; procedure SetDC;
procedure ClearDC; procedure ClearDC;
@ -82,9 +81,9 @@ Type
procedure SetHandlePrinter(aValue : HDC); procedure SetHandlePrinter(aValue : HDC);
procedure RawModeChanging; override; procedure RawModeChanging; override;
procedure PrinterSelected; override; procedure PrinterSelected; override;
procedure DoDestroy; override;
public public
constructor Create; override; constructor Create; override;
destructor Destroy; override;
function Write(const Buffer; Count:Integer; var Written: Integer): Boolean; override; function Write(const Buffer; Count:Integer; var Written: Integer): Boolean; override;

View File

@ -174,6 +174,15 @@ type
property PaperRectOf[aName : string] : TPaperRect read PaperRectOfName; property PaperRectOf[aName : string] : TPaperRect read PaperRectOfName;
end; end;
TPrinterFlags = set of
(
pfPrinting, //Printing
pfAborted, //Abort process
pfDestroying, //Printer object is being destroyed
pfPrintersValid, //fPrinters list is valid
pfRawMode //Printer is in raw mode
);
{ TPrinter } { TPrinter }
TPrinter = class(TObject) TPrinter = class(TObject)
@ -183,17 +192,15 @@ type
fFonts : TStrings; //Accepted font by printer fFonts : TStrings; //Accepted font by printer
fPageNumber : Integer; //Current page number fPageNumber : Integer; //Current page number
fPrinters : TStrings; //Printers names list fPrinters : TStrings; //Printers names list
fPrintersValid: Boolean;
fPrinterIndex: Integer; //selected printer index fPrinterIndex: Integer; //selected printer index
fTitle : string; //Title of current document fTitle : string; //Title of current document
fPrinting : Boolean; //Printing
fAborted : Boolean; //Abort process
//fCapabilities: TPrinterCapabilities; //fCapabilities: TPrinterCapabilities;
fPaperSize : TPaperSize; fPaperSize : TPaperSize;
fRawMode : Boolean;
fCanvasClass : TPrinterCanvasRef; fCanvasClass : TPrinterCanvasRef;
fBins : TStrings; fBins : TStrings;
fFlags : TPrinterFlags;
function GetAborted: Boolean;
function GetCanvas: TCanvas; function GetCanvas: TCanvas;
procedure CheckPrinting(Value: Boolean); procedure CheckPrinting(Value: Boolean);
function GetCanvasClass: TPrinterCanvasRef; function GetCanvasClass: TPrinterCanvasRef;
@ -208,6 +215,8 @@ type
function GetPrinterIndex: integer; function GetPrinterIndex: integer;
function GetPrinterName: string; function GetPrinterName: string;
function GetPrinters: TStrings; function GetPrinters: TStrings;
function GetPrinting: Boolean;
function GetRawMode: boolean;
procedure SetCanvasClass(const AValue: TPrinterCanvasRef); procedure SetCanvasClass(const AValue: TPrinterCanvasRef);
procedure SetCopies(AValue: Integer); procedure SetCopies(AValue: Integer);
procedure SetOrientation(const AValue: TPrinterOrientation); procedure SetOrientation(const AValue: TPrinterOrientation);
@ -242,6 +251,8 @@ type
procedure DoSetBinName(aName: string); virtual; procedure DoSetBinName(aName: string); virtual;
function DoGetPaperRect(aName : string; Var aPaperRc : TPaperRect) : Integer; virtual; function DoGetPaperRect(aName : string; Var aPaperRc : TPaperRect) : Integer; virtual;
function DoGetPrinterState: TPrinterState; virtual; function DoGetPrinterState: TPrinterState; virtual;
procedure DoDestroy; virtual;
function GetPrinterType : TPrinterType; virtual; function GetPrinterType : TPrinterType; virtual;
function GetCanPrint : Boolean; virtual; function GetCanPrint : Boolean; virtual;
function GetCanRenderCopies : Boolean; virtual; function GetCanRenderCopies : Boolean; virtual;
@ -252,6 +263,8 @@ type
procedure RawModeChanging; virtual; procedure RawModeChanging; virtual;
procedure PrinterSelected; virtual; procedure PrinterSelected; virtual;
function DoGetDefaultCanvasClass: TPrinterCanvasRef; virtual; function DoGetDefaultCanvasClass: TPrinterCanvasRef; virtual;
property PrinterFlags: TPrinterFlags read fFlags write fFlags;
public public
constructor Create; virtual; constructor Create; virtual;
destructor Destroy; override; destructor Destroy; override;
@ -279,15 +292,15 @@ type
property PageHeight: Integer read GetPageHeight; property PageHeight: Integer read GetPageHeight;
property PageWidth: Integer read GetPageWidth; property PageWidth: Integer read GetPageWidth;
property PageNumber : Integer read fPageNumber; property PageNumber : Integer read fPageNumber;
property Aborted: Boolean read fAborted; property Aborted: Boolean read GetAborted;
property Printing: Boolean read FPrinting; property Printing: Boolean read GetPrinting;
property Title: string read fTitle write fTitle; property Title: string read fTitle write fTitle;
property PrinterType : TPrinterType read GetPrinterType; property PrinterType : TPrinterType read GetPrinterType;
property CanPrint : Boolean read GetCanPrint; property CanPrint : Boolean read GetCanPrint;
property CanRenderCopies : Boolean read GetCanRenderCopies; property CanRenderCopies : Boolean read GetCanRenderCopies;
property XDPI : Integer read GetXDPI; property XDPI : Integer read GetXDPI;
property YDPI : Integer read GetYDPI; property YDPI : Integer read GetYDPI;
property RawMode: boolean read FRawMode write SetRawMode; property RawMode: boolean read GetRawMode write SetRawMode;
property DefaultBinName: string read GetDefaultBinName; property DefaultBinName: string read GetDefaultBinName;
property BinName: string read GetBinName write SetBinName; property BinName: string read GetBinName write SetBinName;
property SupportedBins: TStrings read GetBins; property SupportedBins: TStrings read GetBins;
@ -317,31 +330,8 @@ end;
destructor TPrinter.Destroy; destructor TPrinter.Destroy;
begin begin
if Printing then Include(fFlags, pfDestroying);
Abort; DoDestroy;
fBins.free;
if Assigned(fCanvas) then
fCanvas.Free;
if Assigned(fPaperSize) then
fPaperSize.Free;
if Assigned(fPrinters) then
begin
DoResetPrintersList;
FreeAndNil(fPrinters);
end;
if Assigned(fFonts) then
begin
DoResetFontsList;
FreeAndNil(fFonts);
end;
inherited Destroy; inherited Destroy;
end; end;
@ -353,7 +343,7 @@ begin
DoAbort; DoAbort;
fAborted:=True; Include(fFlags, pfAborted);
EndDoc; EndDoc;
end; end;
@ -365,12 +355,12 @@ begin
//If not selected printer, set default printer //If not selected printer, set default printer
SelectCurrentPrinterOrDefault; SelectCurrentPrinterOrDefault;
fPrinting := True; Include(fFlags, pfPrinting);
fAborted := False; Exclude(fFlags, pfAborted);
fPageNumber := 1; fPageNumber := 1;
if not FRawMode then begin if not RawMode then begin
Canvas.Refresh; Canvas.Refresh;
TPrinterCanvas(Canvas).BeginDoc; TPrinterCanvas(Canvas).BeginDoc;
end; end;
@ -378,7 +368,7 @@ begin
DoBeginDoc; DoBeginDoc;
// Set font resolution // Set font resolution
if not FRawMode then if not RawMode then
Canvas.Font.PixelsPerInch := YDPI; Canvas.Font.PixelsPerInch := YDPI;
end; end;
@ -388,13 +378,13 @@ begin
//Check if Printer print otherwise, exception //Check if Printer print otherwise, exception
CheckPrinting(True); CheckPrinting(True);
if not FRawMode then if not RawMode then
TPrinterCanvas(Canvas).EndDoc; TPrinterCanvas(Canvas).EndDoc;
DoEndDoc(fAborted); DoEndDoc(pfAborted in fFlags);
fPrinting := False; Exclude(fFlags, pfPrinting);
fAborted := False; Exclude(fFlags, pfAborted);
fPageNumber := 0; fPageNumber := 0;
end; end;
@ -511,6 +501,11 @@ begin
Result:=fCanvas; Result:=fCanvas;
end; end;
function TPrinter.GetAborted: Boolean;
begin
Result := (pfAborted in fFlags);
end;
//Raise error if Printer.Printing is not Value //Raise error if Printer.Printing is not Value
procedure TPrinter.CheckPrinting(Value: Boolean); procedure TPrinter.CheckPrinting(Value: Boolean);
begin begin
@ -525,7 +520,7 @@ end;
function TPrinter.GetCanvasClass: TPrinterCanvasRef; function TPrinter.GetCanvasClass: TPrinterCanvasRef;
begin begin
if FRawMode then if RawMode then
result := nil result := nil
else else
if FCanvasClass=nil then if FCanvasClass=nil then
@ -536,7 +531,7 @@ end;
procedure TPrinter.CheckRawMode(const Value: boolean; Msg: string); procedure TPrinter.CheckRawMode(const Value: boolean; Msg: string);
begin begin
if FRawMode<>Value then if RawMode<>Value then
begin begin
if msg='' then if msg='' then
if Value then if Value then
@ -648,8 +643,8 @@ begin
Result:=fPrinters; Result:=fPrinters;
//Only 1 initialization //Only 1 initialization
if not fPrintersValid then begin if [pfPrintersValid, pfDestroying]*fFlags = [] then begin
fPrintersValid:=true; Include(fFlags, pfPrintersValid);
DoEnumPrinters(fPrinters); DoEnumPrinters(fPrinters);
if FPrinters.Count>0 then if FPrinters.Count>0 then
SelectCurrentPrinterOrDefault; SelectCurrentPrinterOrDefault;
@ -657,6 +652,16 @@ begin
end; end;
end; end;
function TPrinter.GetPrinting: Boolean;
begin
result := (pfPrinting in fFlags);
end;
function TPrinter.GetRawMode: boolean;
begin
result := (pfRawMode in fFlags);
end;
procedure TPrinter.SetCanvasClass(const AValue: TPrinterCanvasRef); procedure TPrinter.SetCanvasClass(const AValue: TPrinterCanvasRef);
begin begin
FCanvasClass := AValue; FCanvasClass := AValue;
@ -725,10 +730,13 @@ end;
procedure TPrinter.SetRawMode(const AValue: boolean); procedure TPrinter.SetRawMode(const AValue: boolean);
begin begin
if AValue<>FRawMode then begin if AValue<>RawMode then begin
CheckPrinting(False); CheckPrinting(False);
RawModeChanging; RawModeChanging;
FRawMode := AValue; if AValue then
Include(fFlags, pfRawMode)
else
Exclude(fFlags, pfRawMode);
end; end;
end; end;
@ -768,7 +776,7 @@ end;
procedure TPrinter.DoResetPrintersList; procedure TPrinter.DoResetPrintersList;
begin begin
//Override this method //Override this method
fPrintersValid:=false; Exclude(fFlags, pfPrintersValid);
end; end;
procedure TPrinter.DoResetFontsList; procedure TPrinter.DoResetFontsList;
@ -899,6 +907,33 @@ begin
Result:=psNoDefine; Result:=psNoDefine;
end; end;
procedure TPrinter.DoDestroy;
begin
if Printing then
Abort;
fBins.free;
if Assigned(fCanvas) then
fCanvas.Free;
if Assigned(fPaperSize) then
fPaperSize.Free;
if Assigned(fPrinters) then
begin
DoResetPrintersList;
FreeAndNil(fPrinters);
end;
if Assigned(fFonts) then
begin
DoResetFontsList;
FreeAndNil(fFonts);
end;
end;
//Return the type of selected printer //Return the type of selected printer
function TPrinter.GetPrinterType: TPrinterType; function TPrinter.GetPrinterType: TPrinterType;
begin begin