Delphiで印刷のプログラムを書いていて、動作確認のため実行(F9)する際、次の警告メッセージが表示されることに気がついた。
[dcc32 警告] UnitXXX.pas(1858): W1000 シンボル ‘GetPrinter’ を使用することは推奨されていません
以前は「印刷して終了」というパターンでプログラムを作成することが多かったが、いつの間にか、紙への印刷ではなく、「ファイルへデータを出力して終わり」というパターンが普通になった。だから、印刷を実行するプログラムはこの数年間書いた記憶がない。
(印刷関連のプログラムも進化してたんだ・・・)
では、GetPrinterのかわりに何を使えばいいのか、現在、推奨されている方法を調べたが、GetPrinterにかわって推奨されている「はず」の手続き名がわからない。
さんざん悩んだ末、ようやくGetPrinterの引数の型の問題であることに気づく。もしかしたら、同じ問題で悩んでいる人がいるかもしれない・・・。ふと、そんな気がして。
【もくじ】
1.推奨されている「はず」の手続き名は?
2.GetPrinterが2つある・・・
3.まとめ
4.お願いとお断り
1.推奨されている「はず」の手続き名は?
「Delphi シンボル’GetPrinter’を使用することは推奨されていません」をキーワードに検索してみても、現在推奨されているはずの手続き名を知る手がかりになりそうな情報が表示されない。
この段階で、なんとなく前途に暗雲が漂うのを感じ、気分が重くなる。
(この警告の意味は「互換性のために残されている機能を使っている」ってことだと以前どこかで読んだ気がする。推奨されないってことはそれに代わる方法が必ずあるはずなんだけど・・・)
どうしても代替方法を見つけたい気持ちはもちろんある。その反面・・・
(推奨されないだけで、まだ使えるから、とりあえず、このままでいいかぁ・・・)
そう思ってしまうのも、また本当。
Copilotさんに訊ねても、納得できる回答は得られない。
(なんでかな?)
ただ時間だけが静かに流れて行く・・・
2.GetPrinterが2つある・・・
問題解決の手掛かりは思わぬところにあった。それがコレ!
![](https://coding-tips-memoranda.com/wp-content/uploads/2024/03/screenshot.1-4.jpg)
検索しても代替手段の情報が出てこない。ならば(直接入力で)片っ端から探せばいいと考え、既存のGetPrinter手続きをコメントアウトして改行。Printer.getと入力してみると、あろうことか、GetPrinterが2つ表示される。
よく見ると引数の型がPCharとstringで異なっている。
(コレかー!)
おそらく、上の引数がPChar型なのが「推奨されないGetPrinter手続き」で、下の引数がstring型なのが(誰も教えてくれなかったけど、おそらく)「推奨されるGetPrinter手続き」なんだろー。
そんなことを思いながら、変数の宣言に戻って、次のように引数の型を変更。
var
//プリンタ設定
//Device: array [0..127] of Char;
//Driver: array [0..127] of Char;
//Port: array [0..127] of Char;
Device: string;
Driver: string;
Port: string;
DeviceMode: THandle;
pDevMode: ^TDevMode;
追記(20240821)
データをPDFファイルに出力するプログラムを書いていて、また、同じ警告に遭遇。(前にもあったなー)と思いながら検索すると自分の書いた過去記事がヒット。まさか、自分に救われるとは・・・記事を書いた時には思ってもみませんでした。
このブログは備忘録と言うことで、補足的に全体の状況をメモ。
警告が表示される状況とその対応方法のまとめです。
![](https://coding-tips-memoranda.com/wp-content/uploads/2024/03/screenshot.4-4.jpg)
【表示された警告】
![](https://coding-tips-memoranda.com/wp-content/uploads/2024/03/screenshot.5-3.jpg)
【警告を消す方法】
![](https://coding-tips-memoranda.com/wp-content/uploads/2024/03/screenshot.6-3.jpg)
上と同じなんだけど、こちらでは変数をまとめて1行で宣言。
procedure TForm1.Button1Click(Sender: TObject);
var
//DeviceName, DriverName, PortName: array[0..MAX_PATH - 1] of Char;
DeviceName, DriverName, PortName: string;
DeviceMode: THandle;
begin
Printer.GetPrinter(DeviceName, DriverName, PortName, DeviceMode);
end;
これで実行(F9)すると・・・
![](https://coding-tips-memoranda.com/wp-content/uploads/2024/03/screenshot.7-2.jpg)
追記(20240821)ここまで
「プロジェクト」⇨「XXXの構文チェック」を実行し、警告のメッセージが消えたことを確認。同時に何か既視感のようなものが・・・
(そう言えば下にSetPrinter手続きもあったはず・・・)
そう思って、そちらを確認すると・・・やはり、
![](https://coding-tips-memoranda.com/wp-content/uploads/2024/03/screenshot.3-3.jpg)
2つあるのはいっしょでも、よく見ると違いはあって、GetPrinter手続きの方は引数の前にvarキーワードがついてる「参照渡し」だが、SetPrinter手続きの方はそれがない「値渡し」になってる・・・
それに、変数の型を次のように宣言してあっても・・・
var
//プリンタ設定
Device: array [0..127] of Char;
Driver: array [0..127] of Char;
Port: array [0..127] of Char;
![](https://coding-tips-memoranda.com/wp-content/uploads/2024/03/screenshot.2-4.jpg)
(なんでかなー?)
MessageBox関数の引数でも同じことを感じたことがあったような・・・。PChar型の変数をstring型の変数に代入する際には、Delphiの場合、自動的に変換されるって理解であってるのかな?
摩訶不思議。
3.まとめ
GetPrinter手続き、SetPrinter手続きは同名の手続きがそれぞれ2つずつ存在し、引数の型がPChar/stringという違いがある。
引数の型がPChar型のGetPrinter手続きを使うと「シンボル ‘GetPrinter’ を使用することは推奨されていません」という警告のメッセージが表示される。
警告のメッセージを消すには、引数の型がstring型のGetPrinter手続きを使用する。
(これでいいのかなー?)
4.お願いとお断り
このサイトの内容を利用される場合は、自己責任でお願いします。ここに記載した内容を利用した結果、利用者および第三者に損害が発生したとしても、このサイトの管理者は一切責任を負えません。予め、ご了承ください。