喫茶XRAYトップページ

[スレッド全体
]

[9521] プリンタドライバの情報をDEVMODE構造体から取得返信 削除
2016/1/8 (金) 15:38:29 taki
マスター お世話になります。
サンプルプログラム集
「011_プリンタドライバの情報をDEVMODE構造体から取得」での質問です。

やりたい事はPrinterSetupDialogを表示して「用紙サイズ」(種類)を変更したり
「印刷の向き」を変更することで変更された用紙の大きさ(縦・横の長さ)を
得て印刷データの行数を決めたいのです。

dmOrientation,dmPaperSize,dmPaperLength,dmPaperWidthの情報がそれらに
該当するのですが、
サンプルに同梱されている「DEVMODE_Structure.exe」で試したところ

A4縦 → portrait,A4,2970,2100(初期値)
A4横 → landscape,A4,2970,2100
再度 A4横 → landscape,A4,2970,2100
A4縦 → portrait,A4,2970,2100
となります。縦と横の長さが入れ替わるかなと予想したのですが、
そうではないようです。

次に用紙のサイズ(種類)を変更したところ
B5縦 → portrait,B5,2970,2100 (A4用紙の長さが残る?)
再度 B5縦 → portrait,B5,2570,1820 (B5に直った)
となりました。

A4縦 → portrait,A4,2570,1820 (B5用紙の長さが残る?)
再度 A4縦 → portrait,A4,2970,2100 (A4に直った)

どうやらdmPaperLength,dmPaperWidthの情報は直ちには反映されない
ようなのですが、これは仕様?なのでしょうか。
それとも私のPCもしくはプリンタードライバーだけの現象なのでしょうか。

環境 Windows7 Pro,Delphi XE4 Starter,Canon MG5430


[9534] Re:プリンタドライバの情報をDEVMODE構造体から取得返信 削除
2016/1/11 (月) 09:29:48 Mr.XRAY
> やりたい事はPrinterSetupDialogを表示して「用紙サイズ」(種類)を変更したり
> 「印刷の向き」を変更することで変更された用紙の大きさ(縦・横の長さ)を
> 得て印刷データの行数を決めたいのです。


今読み直してみたんですが,
実は [011] のサンプルは,DEVMODE 構造体から取得可能な値をリストするものです.

dmPaperLength, dmPaperWidth はユーザ定義サイズの値です.
dmPaperLength は,縦向きの時の用紙の長さ,
dmPaperWidth は,縦向きの時の用紙の幅です.

で,印刷の時の用紙のサイズの取得は,

[012_プリンタの解像度と用紙サイズ等の取得]
http://mrxray.on.coocan.jp/Delphi/plSamples/012_PrintResolution.htm

を参考にしてくださいませ.
意味が違っていたらゴメンなさいです.


[9535] Re2:プリンタドライバの情報をDEVMODE構造体から取得返信 削除
2016/1/11 (月) 19:19:50 taki
▼ Mr.XRAYさん
 
> 今読み直してみたんですが,
> 実は [011] のサンプルは,DEVMODE 構造体から取得可能な値をリストするものです.
>


> で,印刷の時の用紙のサイズの取得は,
>
> [012_プリンタの解像度と用紙サイズ等の取得]
> http://mrxray.on.coocan.jp/Delphi/plSamples/012_PrintResolution.htm
>
> を参考にしてくださいませ.
> 意味が違っていたらゴメンなさいです.


マスター 誠にすみません。
マスターのご指摘のように
GetDeviceCaps(Printer.Handle, PHYSICALHEIGHT);で
常に正しい情報を得ることができました。

それと、私がしくじった原因も報告します。

以下のコードで試しました。

uses Printers;

procedure TForm1.GetNagasa;
var
  TempInt,YDPI: Integer;
  TempDouble  : Double;
begin
  YDPI  := GetDeviceCaps(Printer.Handle, LOGPIXELSY);
  TempInt    := GetDeviceCaps(Printer.Handle, PHYSICALHEIGHT);
  TempDouble := TempInt * 25.4 / YDPI;
  label2.Caption := Format('%8.1f [mm]', [TempDouble]);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
//  Printer.PrinterIndex := -1;  // ←間違った使い方1
  if PrinterSetupDialog1.Execute then begin
  // OKで閉じるまでに用紙の種類を変更する
    GetNagasa;
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
//  Printer.PrinterIndex := -1;  // ←間違った使い方2
  GetNagasa;
end;

確実にデフォルトのプリンターを使おうとしてPrinterIndex := -1;を
コーディングしたのが間違いでした。

色々試した結果、PrinterIndex := -1;とすると、デフォルトの
プリンターが選ばれるだけでなく、デフォルトの状態も設定されるようです。
つまり私の環境の場合、
プリンター名 「Canon MG5400 series Printer」
用紙サイズ 「A4」
印刷の向き 「縦」
に戻ってしまうようです。

それぞれの間違った使い方のコードが有効な状態で試すと
Button1をClickすると、PrinterSetupDialogを開くたびにA4・縦になる。
しかし、用紙の縦の長さは変化する。(変更した正しい長さになる。)
Button2をClickすると、常にA4用紙の縦の長さ297mmに戻ってしまう。

それぞれのコードをコメントアウトすると
Button1をClickすると、PrinterSetupDialogは以前の状態が保持されている。
変更した用紙の紙の長さも正常に表示される。
Button2をClickしても、用紙の紙の長さは変わらない。

出入り禁止にはしないでください。m(__)m


[9536] Re3:プリンタドライバの情報をDEVMODE構造体から取得返信 削除
2016/1/11 (月) 20:50:28 Mr.XRAY
▼ takiさん

> 色々試した結果、PrinterIndex := -1;とすると、デフォルトの
> プリンターが選ばれるだけでなく、デフォルトの状態も設定されるようです。


今後使用する状況があるかどうか分かりせんが,以下のようになっています.
これは,実は,問題になることがあるんです.
今回のこととは直接関係ありませんが,プリンタ関係を扱う場合の参考として.

  //現在のプリンタを指定したプリンタにする
  //-1 を代入した場合は,-1 になるのではなく,デフォルトのプリンタの番号
  //が代入される
  Printer.PrinterIndex := プリンタ番号(整数値);

  //ここで取得するADeviceModeには,変更前のプリンタの情報が格納されている
  //その他の値は現在(変更後)のプリンタの情報となっている
  Printer.GetPrinter(ADevice, ADriver, APort, ADeviceMode);
  //ADeviceMode初期化
  Printer.SetPrinter(ADevice, ADriver, APort, 0);
  //ADeviceModeが新しいプリンタドライバの値(デフォルトのプロパティ値)となる
  Printer.GetPrinter(ADevice, ADriver, APort, ADeviceMode);

プリンタを変更して,DEVMODE 構造体で設定する場合は,上のコードの後に書きます.
上の 3 行を実行しないと,正常に設定されないことがあります.
(昔は,この手の質問がいっぱいあったんですよね --- 遠い目)
 

> 出入り禁止にはしないでください。m(__)m

え ? 何か悪いことしました ??


[9537] Re4:プリンタドライバの情報をDEVMODE構造体から取得返信 削除
2016/1/12 (火) 10:56:59 taki
▼ Mr.XRAYさん
 
> (昔は,この手の質問がいっぱいあったんですよね --- 遠い目)

マスター もう少しお付き合いください。

プリンタ関係のサンプルプログラムの記事を読み直してみて、分かったことも
多くあるのですが、色々と混乱して分からなくなってしまいました。

具体的な例にしての質問です。

パソコンに2台のプリンタが接続されています。
インクジェットと連続帳票専用プリンタです。

「通常使うプリンタ」(デフォルトのプリンタ) は、OSに登録(定義)されている
プリンタで、色々なアプリ(メモ帳、Word、Execl等)で印刷する時に自動で
選択されているプリンタですね。
インクジェットプリンタでプリンタ番号を2としてください。
プロパティはA4用紙・縦です。

連続帳票印刷アプリは連続帳票専用のプリンタを使います。
専用プリンタのプリンタ番号を3としてください。プロパティは連続用紙(かな?)
連続帳票印刷アプリを起動直後は、OSの「通常使うプリンタ」のままではダメ
(無駄紙大量発生)なので、帳票印刷する前に使用するプリンタの変更が
必要になります。

そのプリンタの変更を人間ができる場合は、「PrinterSetupDialog」でプリンタを
連続帳票専用プリンタに変更すれば、プロパティも連続用紙に変わってくれる?
(多分)ので、後は印刷すれば良い事になります。

でも、通常は「無駄紙大量発生」を防ぐため、使用するプリンタの変更をアプリの
コードで行いますよね。

そのコードが

Printer.PrinterIndex := 3;
// または
//Printer.PrinterIndex := Printer.Printers.indexof('OKI XXXX');
// OKI XXXX は帳票プリンタの名前(仮称)

Printer.GetPrinter(ADevice, ADriver, APort, ADeviceMode);
Printer.SetPrinter(ADevice, ADriver, APort, 0);
Printer.GetPrinter(ADevice, ADriver, APort, ADeviceMode);
// これで連続帳票専用プリンタ(仮称 OKI XXXX)に変更できたのでしょうか?
この時に、プロパティも連続用紙に変わっているのでしょうか?

無事に連続帳票の印刷が済んでアプリを終了したら、「通常使うプリンタ」は
インクジェットに戻っているのでしょうか?(上記コードはアプリ内だけ有効?)

自分で試せばいいのですが、プリンタが1台しかないもので…。


[9541] お付き合い返信 削除
2016/1/12 (火) 12:28:06 Mr.XRAY
> マスター もう少しお付き合いください。

これは結婚を前提にしてのことでしょうか ? なんてね.
ほら,昔,付き合っている女性に言われたことないですか ?
「私は貴方のなんなの ?」

で,彼女にこんなことを書いたメモを渡したでしょう ?

以下の希望するどれかに○を付けてください.
  1. 単なる女友達
  2. 女友達以上,恋人未満
  3. 婚約者
  4. 妻
  5. 今から別れる彼女


[9542] Re:お付き合い返信 削除
2016/1/12 (火) 14:13:44 taki
▼ Mr.XRAYさん
> > マスター もう少しお付き合いください。
>
> これは結婚を前提にしてのことでしょうか ? なんてね.
> ほら,昔,付き合っている女性に言われたことないですか ?
> 「私は貴方のなんなの ?」
>
> で,彼女にこんなことを書いたメモを渡したでしょう ?
>
> 以下の希望するどれかに○を付けてください.
>   1. 単なる女友達
>   2. 女友達以上,恋人未満
>   3. 婚約者
>   4. 妻
>   5. 今から別れる彼女


残念ながら、おじさんはそんなことを言われたことがありません。

マスターはモテモテだったんでしょうね。


[9544] Re2:お付き合い返信 削除
2016/1/12 (火) 15:56:45 Mr.XRAY
▼ takiさん

> マスターはモテモテだったんでしょうね。

んなわけありません !

で,このメモの話は本当らしいです.実際の内容は記憶です.
違っていると思います.
山岳会の同期の友人で,そういう方がいたそうです.
で,5. に○を付けられて,あわてて追いかけたそうです.

結果的に,その女性と結婚したそうです.めでたし,めでたし.


[▼次のスレッド]
INCM/CMT
Cyclamen v3.82