今年初めてのエントリになります。 共同化が忙しくてブログどころではなくなってしまいまして(汗)
///////////////////////////////////////////////////////////////////////////////////////////
さて事務共同化の話しで、自分作成のアプリを配ったところ次の問題が発生しました。
予想はうすうすしていたのですが。
使うプリンタの環境が各校かなり違うのですよ。
自分のアプリは「インクジェット」を使うことを前提に考えていたのですが、ページプリンタ・ジェルジェットプリンタなど、種類もメーカーもまちまちです。
むろんプリンタによって違う最小余白はAPI関数を使って取得してますので、「ちがうプリンタを使ったら印刷位置が全く異なってしまった」という現象は極力回避しています。
ところが。。。
エクセルやワードなんかでは、印刷時に「通常使うプリンタの設定」が出てきますが途中で変更することはもちろん出来ますね。
エクセルやワードが終了するまでそのアプリケーション内だけで設定が保持され、アプリが終了したらその設定は開放されるわけです。
みなさんはこれが普通に出来ることだと思われていることでしょう。
が、
残念なことにVisualBasic6.0(以下VB6)はプリンタの扱いがとても苦手と来ています。
最新のVisualBasic NET(以下VB.NET)系ならそのあたりはだいぶ改善されていると聞きます。
「んじゃおまえさんが使っているVB6をVB.NETにバージョンアップさせりゃいいじゃん」とお思いでしょう。
ところがそう簡単ではないのです。
バージョンアップ、ではないのです。
VB6とVB.NETは「別物」なのです。 単に同じように先頭にVisualBasicという文字が付いているだけ。
エクセルで言うと、2003と2007の違いなんて言うもんじゃありません。 全くの別物なのですから。
VB.NETをやってもいいんでしょうが、VB6に慣れきった私が新たな言語を覚えて新たに作り直すなんて、考えただけでぞっとします。
話しが長くなってしまいました。
自分の使っているVB6はプリンタの扱いが下手、という弱点を抱えています。
どうせならプリンタの扱いを進化させたVB6.5でも出してくれれば良かったのに、と思うことしきり。
なんでもVB.NETはVB6に比べて細かい設定が可能になった分、開発時間が数倍にふくれあがったという話しを聞きます。
それだけ細かい言語なんですね。
無論VB6もプリンタの設定は出来ます。
が、印刷精度に関しては数段階。 印刷トレーの設定もやってみないとエラーが発生するかどうか分からない。
とりあえず用紙サイズと用紙方向は設定できる。
ただし封筒なんかだと出来ない場合もあったり(汗)
要するに細かい設定が出来ないんですよ。 困ったことに。
VB6でプログラミングする人たちはほとんどみなさんプリンタの扱いで困っているようです。
古い言語だからいまさらマイクロソフトがサポートするわけはないので尚更困っちゃいます。
無論プリンタのダイアログを表示することは可能です。
が、あろうことかこれを使うと「通常使うプリンタ」の設定が変わっちゃうのです。
エクセルのように、印刷時に設定を自由に変えて、アプリ終了時と同時に設定が開放されるという振る舞いが出来ないのです。
つまり「アプリ終了時と同時に設定が開放される」の部分がダメなんですな。
当然他のアプリにも影響を(プリンタの部分で)与えるわけです。
他の人が使っている手としまして、プリンタの元々の設定をプログラム上で記憶させておき、アプリの終了時に元に戻す、ということをします。
これもVB6本来の持っている機能を使うのではなく、API関数というちょっとやっかいなものを使用して初めて使用可能になります。
1.プリンタ情報は「winspool.drv」というファイルに書き込まれており、これを最初に「使う」と宣言します。 なんでもC言語の関数とかで、そのままではVB6では使えず、宣言することで初めて使用可能になります。
2.使用可能になったらプリンタに対するアクセス権を宣言します。
3.次にプリンタのハンドルを取得します。
4.次に構造体のレベルを指定します。 おいらにもよく分かりません(汗)が、手続きなので順序よく行っていきます。
5.次に、バッファの必要サイズを取得します。
6.次に「ようやく」プリンタの詳細情報を取得します。 ふぅ
7.ここで終わりではなく、取得した情報を先ほど指定した構造体に移動させます。
8.次に「なんとかかんとか」プリンタのデバイス情報を取得できます。
取得するまでになんと8段階の手続きが必要なのです。
コードで書くと次のようになります(別に理解しなくていいよ)
Dim bytPrinterInfo2Buffer() As Byte
' On Error GoTo ErrTrap
' プリンタアクセス権を指定
With udtPrinterDefaults
.DesiredAccess = PRINTER_ALL_ACCESS
End With
' プリンタのオブジェクトハンドルを取得
lngResult = OpenPrinter(strPrinterDeviceName, lngPrinterHandle, udtPrinterDefaults)
' 構造体のレベルを指定
lngPrinterInfo2Level = 2
' バッファに必要なサイズを取得
lngResult = GetPrinter(lngPrinterHandle, lngPrinterInfo2Level, ByVal vbNullString, 0, lngPrinterInfo2Needed)
' バッファを確保
On Error Resume Next
ReDim ytPrinterInfo2Buffer(lngPrinterInfo2Needed - 1)
If Err Then ReDim ytPrinterInfo2Buffer(6000)
On Error GoTo 0
' 詳細なプリンタ情報を取得
lngResult = GetPrinter(lngPrinterHandle, lngPrinterInfo2Level, ytPrinterInfo2Buffer(0), lngPrinterInfo2Needed, lngPrinterInfo2Needed)
' 取得した詳細なプリンタ情報を構造体へ移動
MoveMemory udtPrinterInfo2, ytPrinterInfo2Buffer(0), Len(udtPrinterInfo2)
' 取得した詳細なプリンタデバイス情報を構造体へ移動
MoveMemory udtDevMode, ByVal udtPrinterInfo2.pDevMode, Len(udtDevMode)
On Error Resume Next
With udtDevMode ' 詳細なプリンタデバイス情報を設定
' lngDevMode(0) = .dmSpecVersion
' lngDevMode(0) = .dmDriverVersion
' lngDevMode(0) = .dmSize
' lngDevMode(0) = .dmDriverExtra
' lngDevMode(0) = .dmFields
lngDevMode(0) = .dmOrientation
lngDevMode(1) = .dmPaperSize
lngDevMode(2) = .dmPaperLength
lngDevMode(3) = .dmPaperWidth
lngDevMode(4) = .dmScale
lngDevMode(5) = .dmCopies
' lngDevMode(0) = .dmDefaultSource
lngDevMode(6) = .dmPrintQuality
lngDevMode(7) = .dmColor
lngDevMode(8) = .dmDuplex
lngDevMode(9) = .dmYResolution
lngDevMode(10) = .dmTTOption
lngDevMode(11) = .dmCollate
' lngDevMode(0) = .dmFormName(CCHFORMNAME - 1)
lngDevMode(12) = .dmLogPixels
lngDevMode(13) = .dmBitsPerPel
lngDevMode(14) = .dmPelsWidth
lngDevMode(15) = .dmPelsHeight
lngDevMode(16) = .dmDisplayFlags
lngDevMode(17) = .dmDisplayFrequency
End With
' ' 構造体を取得した詳細なプリンタデバイス情報へ移動
' MoveMemory ByVal udtPrinterInfo2.pDevMode, udtDevMode, Len(udtDevMode)
' '詳細なプリンタ情報を書き戻し
' lngResult = SetPrinter(lngPrinterHandle, lngPrinterInfo2Level, udtPrinterInfo2, 0)
On Error GoTo ErrTrap
' プリンタオブジェクトをクローズ
lngResult = ClosePrinter(lngPrinterHandle)
ところがなんとも困ったことにVistaでは動きません。
Win2000やXPでは可能な5番のバッファの必要サイズ取得が出来ないのです。
2000だと「サイズは3000だの4000だの」と値を返してきますが、Vistaはなぜか0かEmptyしか返してきません。
もちろんそのまま続行すると間違いなくフリーズします。
最初、アクセス権が制限されているPCだから起きるのかとも思いましたが管理者権限のあるVistaでも同様の現象が起きました。
悩んだ挙げ句、なんともしょうがないので「かんたん設定」と「自分で設定」を選択できるようにし、「自分で設定」を行った場合は「手動で戻してね」、と言うことにしました。
っつーか、今のおいらにはその程度の技術しかありません。
ネットでFLASHで作成した画面を簡単に印刷できるのを見る度に、「VB6に実装できたらどんなにいいか」と思うこの頃なのであります。
。。。年始め(1ヶ月も過ぎているのに)から訳分からない独り言ですみません(汗)
出張で京都・静岡に行った記事も書きたいなぁと思いますが、いかんせん時間がなくてとても困ってます。
誰か代わりませんか? 拠点校(笑)