2008年9月 3日

[openoffice:11306] Re: Q: Impress 複数部数の印刷

小笠原さん

ありがとうございます。

Naruhiko Ogasawara wrote:
> ええ、もうネタばらししてしまいますが、ワタクシ某OA機器メーカでプリンタド
> ライバの開発を行う部署に属しております(ちなみに FX さんではありませ
> ん)。


心強いです。

>> ・現在 2008 年においては、プリンタドライバが部数分のデータを生成するという
>>  役割分担を行うのが当たり前になっているのではないかなぁと捉えています。
>
> ええと、これが可能かどうか、プリンタドライバからアプリに通知する手段が
> dmFields の DM_COLLATE フラグです。
>
> このフラグが立っている場合、ドライバ or プリンタは collation (部単位印
> 刷)の機能を持っているので、dmCopies に部数をセットし、dmCollate を
> DMCOLLATE_TRUE にする、というのがアプリの正しい実装です。
>
> このフラグが寝ている場合は、当該のドライバ/プリンタは部単位印刷をサポー
> トしていないので、現在の実装、すなわち
>
>>  OpenOffice.org が自前で頑張って部数分のデータを生成する
>>  ような現行の機能
>
> で動かなければなりません。

少しお教えいただけませんでしょうか。

DeviceCapabilitiesW, DeviceCapabilitiesA, GetDeviceCaps あたりの使い方は
どのようにすればよいのでしょうか。

OpenOffice.org の現在のソースコードのどこらへんに、改善の余地がありそうで
しょうか。


DC_COPIES や DC_COLLATE の値を取得するようなコードは
vcl/win/source/gdi/salprn.cxx にはあるのですが、

・印刷関連の Windows 向けのコード
 vcl/win/source/gdi/salprn.cxx
http://gsl.openoffice.org/source/browse/gsl/vcl/win/source/gdi/

そして Windows 固有の DeviceCapabilities() を呼び出す関数、を呼び出す
関数 GetCapabilities() を呼び出す、プラットホーム非依存な大元のコードは

・印刷関連のプラットホーム非依存なコード
 vcl/source/gdi/print.cxx
http://gsl.openoffice.org/source/browse/gsl/vcl/source/gdi/

の BOOL Printer::StartJob( const XubString& rJobName ) にあります。

ところが、実際の動作を見ていると、DeviceCapabilities() を呼ぶよりも前に、
そのメソッドの前半部分の IsQueuePrinter() の戻り値が必ず?かどうかはよく
わかりませんが、真になっているようでして、

if ( IsQueuePrinter() )
{
if ( ((ImplQPrinter*)this)->IsUserCopy() )
{
nCopies = 1;
bCollateCopy = FALSE;
}
}
else
{
if ( nCopies > 1 )
{
ULONG nDevCopy;

if ( bCollateCopy )
nDevCopy = GetCapabilities( PRINTER_CAPABILITIES_COLLATECOPIES );
else
nDevCopy = GetCapabilities( PRINTER_CAPABILITIES_COPIES );

結果的に、プリンタ側の能力を調べることもなく、OpenOffice.org が自分で頑張って
部数分ループするんだと判断してしまうようなのです。
上記の nCopies = 1 は、後に dmCopies に代入される値のようです。

>> ・そのご意見の状況につきましては、上述いたしました方法で回避できるのではないかと
>>  私は考えております。そもそも、設定項目が無ければ、どっかにあるだろうと。
>>  あっ、〔詳細設定〕というボタンがある。押してみよう!。あった、あったと。
>
> これは私の業務上の経験なのですが、ユーザに甘えすぎというか期待しすぎで
> す。
> アプリに設定が見当たらなければ「ない」と思う、わざわざ探さない、そしてそ
> のアプリを「使い物にならねー」といって放棄する、というのがごくごく普通な
> ユーザだと思われます。

なるほど。


> アプリケーション側が DEVMODE を通じてドライバに正しい指示を出してきた場
> 合、ドライバ側はそれを反映してダイアログに表示しなければなりません。
> つまり同じ設定項目が存在するならば、アプリで設定しようがドライバで設定し
> ようが同じ結果になることをプリンタドライバは (そしてアプリの側も) 期待さ
> れています。


ということは、ユーザーインターフェースについては、

・OpenOffice.org 側のダイアログの処理では、〔プロパティ〕ボタンが押されると、
 そのハンドラ内にて、まず、現在の「部数」および「部単位で印刷」の設定値を
 DEVMODE.dmCopies および DEVMODE.dmCollate に設定してプリンタドライバ側へ
 通知し、その後、プリンタドライバ側の「プロパティ」ダイアログを表示するよう
 に指示する。

・OpenOffice.org 側のダイアログの処理では、プリンタドライバ側の「プロパティ」
 ダイアログが閉じられるなどして、自身にフォーカスが来たよというイベントなど
 によって通知を受けると、DEVMODE.dmCopies および DEVMODE.dmCollate の現在の
 設定値を取得し、自身の「部数」および「部単位で印刷」の設定に反映する。

というようなつくりにするというのが、よいでしょうか。

というか、もしかして、それが当たり前の作りでしょうか。


> したがって今回の件については、OOo のロジックを、
>
> if (DEVMODE.dmFiels & DM_COLLATE) {
> DEVMODE.dmCollate = 《OOo の部単位印刷指定が On》?
> DMCOLLATE_TRUE : DMCOLLATE_FALSE;
> DEVMODE.dmCopies = 《OOo の部数指定》;
> } else {
> DEVMODE.dmCollate = DMCOLLATE_FALSE;
> DEVMODE.dmCopies = 1;
> ... (今までの処理)
> }
>
> とすべき、というのが私の考えです。

さらに DeviceCapabilities() をどのように組み入れればよいでしょうか。
それとも、DeviceCapabilities() の呼び出しは不要でしょうか。
そもそも、DeviceCapabilities() の 「DC_COPIES デバイスが印刷できる部数が返ります。」
で返される値は、どのような値が返されるのでしょうか。

DeviceCapabilities
http://msdn.microsoft.com/ja-jp/library/cc428443.aspx

さらに、DeviceCapabilities() は、プリンタ固有で DEVMODE の設定値に
係わり無く、一定の値が返されるものでしょうか。それとも、例えば、
100部印刷可能と返されたのに、DEVMODE.dmDuplex を立てて両面印刷を
指定した後 、DeviceCapabilities() をもう一度呼ぶと、今度は 50部印刷
可能と返されるようなものなのでしょうか。

Tora

【MLコミュホームページ http://www.freeml.com/openoffice

--[PR]------------------------------------------------------------------
■□ 「ウコンの力」でおなじみのハウス食品が自信を持ってお届け!! □■
□■      『ハウスの天然効果(R)活性ウコン』         ■□
 
  ※通常価格2,000円(約30日分)⇒今なら半額の1,000円(税込・送料込)
http://ad.freeml.com/cgi-bin/sa.cgi?id=c1AcM
------------------------------------------------------------------[PR]--
■GMO INTERNET GROUP■ GMO INTERNET www.gmo.jp


投稿者 xml-rpc : 2008年9月 3日 02:39
役に立ちました?:
過去のフィードバック 平均:(0) 総合:(0) 投票回数:(0)
本記事へのTrackback: http://hoop.euqset.org/blog/mt-tb2006.cgi/76947
トラックバック
コメント
コメントする




画像の中に見える文字を入力してください。