こんにちは
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へ複写する。
力技っぽい結果となりましたが、いろいろ勉強になりました。
ありがとうございました。
| ツイート | 
        
         |