こんにちは
TPrinterのBeginDoc関数のDocInfoなのですが、
ここにlpszOutputを指定したく次のように修正したPrinters.pasを
アプリのソースフォルダに保存しました。
procedure TPrinter.BeginDocEx(APath: String);
with DocInfo do
begin
cbSize := SizeOf(DocInfo);
lpszDocName := PChar(Title);
lpszOutput := PChar(APath); // ここはオリジナルソースには無い
end;
この状態でコンパイルすると「Formsは異なるバージョンによりコンパイルされています」
というコンパイルエラーが発生します。
これは他のコンポーネントがPrinters.pasを参照している為に発生するのでしょうか?
この場合、Program Files\Borland\Delphi5\Lib 内のdcuを全削除して再構築すればよいのでしょうか?
dcuの削除は不安なので試していません。
できることならPrinters.pasを直接修正するような事は避けたいので
他にDocInfo.lpszOutputをセットする方法があるなら教えていただけないでしょうか?
よろしくお願いいたします。
こんにちは,
>できることならPrinters.pasを直接修正するような事は避けたいので
これは,一般論ですが,Delphi では,あるクラスに機能を追加したり,変更するには,
そのクラスを継承したクラス (コンポーネント) を作成します.
そのために,「継承」という概念があるとも言えます.
TMyMemo = class(TMemo)
end;
というのは,TMemo というクラスを継承したクラスです.
Delphi では,慣習的に,クラス名の先頭には T を付けているようです.
同じ名前のクラス名は,原則的に,同時使用はできません.
また,レコード型 (構造体) も同じです.
既にあるレコード型に,勝手にメンバーを追加することはできません.
(比較的新しい Delphi では,少し意味は違いますが,方法があります)
解決策ということではありませんが,参考になれば.
>既にあるレコード型に,勝手にメンバーを追加することはできません.
そのレコード型を,別のクラス,プログラム等で使用していたとすると,
問題が発生する可能性があります.
Printers.pas の名前を変えてしまえ
>LPrinters.pas の名前を変えてしまえ
おおっ !! グッドアイディア !
Mr.XRAYさん、KHE00221さん、ありがとうございます。
実は、当初はPrintersEx.pasとして作成していました。
その状態で印刷処理自体は正常に動いていましたが
TPrinterDialogもPrinters.pasを参照しているようで
プリンタ設定が正しく行えませんでした。
TPrinterから継承してTPrinterExを作成
TPrinterEx=class(TPrinter)
procedure BeginDocEx(APath: String);
end;
自分でTPrinterExのインスタンスを作成し、SetPrinter関数(Printers.pas)により、
ユニットで保持するインスタンスの差し替え。
SetPrinterの結果は、Create済みのTPrinterインスタンスが返ってくるので
nil でなければFreeする。
あとは、TPrinterEx(Printer)のようにキャストするだけで使える・・・
と、思ったりしますが、いかがなものでしょう?
var
SavePrinter: TPrinter;
begin
SavePrinter := Vcl.Printers.SetPrinter(TPrinter(PrintersEx.Printer));
PrintersEx.Printer.Copies := 20; //確認用
if PrintDialog1.Execute = True then
begin
end;
Vcl.Printers.SetPrinter(SavePrinter);
Freeにすると終了後にプロセス残って RunTimeError が起こる
Win7 XE2 だけど
おかぽんさん、KHE00221さん
教えていただいた方法で試してみます。
ありがとうございました。
こんにちは
KHE00221 さんに教えていただいたコードでテストを進めていたのですが
思うように動作しないので再度質問させてください。
プリンタダイアログで変更した内容がPrinters.Printerには反映されるのですが
PrintersEx.Printerから参照するとに反映されていない状態になります。
具体的には、ダイアログでCopiesを10に変更して
PrintersEx.Printer.Copiesを確認すると20のままで
Printers.Printer.Copiesを確認すると10になっていました。
Setprinterが正しく行えていないのかと思いPrintersEx.Printerと
Printers.Printerのアドレスを確認しましたが同じものを指していました。
PrintersEx.pasはPrinters.pasをリネームし、usesにPrintersを追加して
TPrinterEx = class(TPrinter)
としています。TPrinterExの作成方法が問題なのでしょうか?
よろしくお願いいたします。
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, PrintersEx, Printers, Vcl.StdCtrls, Vcl.Dialogs;
procedure TForm1.Button1Click(Sender: TObject);
var
SavePrinter: TPrinter;
begin
SavePrinter := Vcl.Printers.SetPrinter(TPrinter(PrintersEx.Printer));
PrintersEx.Printer.Copies := 20; //確認用
if PrintDialog1.Execute = True then
begin
end;
Memo1.Lines.Add(IntToStr(Printer.Copies)); //変更した数になる
Memo1.Lines.Add(IntToStr(PrintersEx.Printer.Copies)); //変更した数になる
Vcl.Printers.SetPrinter(SavePrinter);
Memo1.Lines.Add(IntToStr(Printer.Copies)); //1のまま
Memo1.Lines.Add(IntToStr(PrintersEx.Printer.Copies)); //変更した数になる
end;
KHE00221 さん、ありがとうございます。
プリンタダイアログでCopiesを10に変更した結果
--------------
10
20
1
20
--------------
となり、PrintersEx.Printerには反映されません。
ソースもコピペさせていただいたので全く同じはずなのですが・・・
異なる可能性があるのは、PrintersEx.pasでしょうか。
DelphiはDelphi5を使用しています。
他にDelphi7とDelphi2007がありますので、Delphi2007でテストしてみます。
var
SavePrinter: Printers.TPrinter;
begin
SavePrinter := Printers.SetPrinter(Printers.TPrinter(PrintersEx.Printer));
PrintersEx.Printer.Copies := 20; //確認用
if Pointer(Printers.Printer) = Pointer(PrintersEx.Printer) then Memo1.Lines.Add('同じ1');
if PrintDialog1.Execute = True then
begin
end;
if Pointer(Printers.Printer) = Pointer(PrintersEx.Printer) then Memo1.Lines.Add('同じ2');
Memo1.Lines.Add(IntToStr(Printers.Printer.Copies)); //変更した数になる
Memo1.Lines.Add(IntToStr(PrintersEx.Printer.Copies)); //変更した数になる
Printers.SetPrinter(SavePrinter);
Memo1.Lines.Add(IntToStr(Printers.Printer.Copies)); //1のまま
Memo1.Lines.Add(IntToStr(PrintersEx.Printer.Copies)); //変更した数になる
同じ1
同じ2
表示される?
>表示される?
はい、表示されます。
プリンタダイアログでCopiesを10に変更した結果
---------------
同じ1
同じ2
10
20
1
20
---------------
アドレスが異なっていればわかるのですが、
同じアドレスなのに値が異なるという状態です。
環境はVistaにDelphi2007です。
関係ないとは思いますが、Delphi20xxとXExでは動作が違う可能性も?
XE3体験版をインストールしてテストしてみます。
報告が遅くなり申し訳ありません。
XE3体験版をインストールしてみましたが、
DCUしか付属しておらずテストすることができませんでした。
その後、いろいろ試してみましたがうまくいかず
最終的には次のような処理となりました。
BeginDocExが必要な場合のみPrintersExを使用し、
その際にPrinters.Printerの内容をPrintersEx.Printerへ複写する。
力技っぽい結果となりましたが、いろいろ勉強になりました。
ありがとうございました。
ツイート | ![]() |