VB2010EXでドットプリンター への返答

投稿で使用できる特殊コードの説明。(別タブで開きます。)
本名は入力しないようにしましょう。
投稿した後で削除するときに使うパスワードです。返答があった後は削除できません。
返答する人が目安にします。相手が小学生か社会人かで返答の仕方も変わります。
最初の投稿が質問の場合、質問者が解決時にチェックしてください。(以降も追加書き込み・返信は可能です。)
※「過去ログ」について書くときはその過去ログのURLも書いてください。

以下の返答は逆順(新しい順)に並んでいます。

投稿者 魔界の仮面弁士  (社会人) 投稿日時 2015/11/18 14:22:40
> の部分をJISの文字列に適応させる機能はないらしいと云う結論に達しました。

文字列データから JIS バイナリを生成する部分については
 System.Text.Encoding.GetEncoding(codePageID).GetBytes(文字列)
が使えると思います。 指定する codePageID としては
 50220 … 日本語 JIS(1バイトカタカナ未定義)
 50221 … 日本語 JIS(1バイトカタカナ許可)
 50222 … 日本語 JIS(シフトイン/シフトアウトにて1バイトカタカナ利用可)
などでしょうか。ESC/P コマンドが必要な場合は、適宜挿入するとして。


ただし、700JX3 が相手ならラスタ出力も可能ですから、
無理に API としてラインプリンタとして扱わずとも、
通常のページプリンタと同様、PrintDocument クラスなり
Visual Studio Report なりで出力すれば十分なことが多いですね。

用紙サイズの「高さ」を、出力したい用紙の長さに合わせ、
用紙サイズの「幅」を、出力したい用紙の幅以上に設定し、
上下余白を 0mm にセットして対応していました。
投稿者 hori  (社会人) 投稿日時 2015/11/18 13:04:55
kikuさま。daiveさま。ありがとうございます。

いろいろ試してみましたが、僕としましては、VB2010EXには

pBytes = Marshal.StringToCoTaskMemAnsi(szString)

の部分をJISの文字列に適応させる機能はないらしいと云う結論に達しました。
これで解決と云うのはちょっと口惜しい気はしますけれどね。


まぁ、縦1インチで6行、と云うような古い様式に拘ったのが間違いで
最初から素直にページプリンターとして認識しておけばよかったかなと思います。

とは言え、APIの知識など結構勉強にはなりました。
また、何かの節にはよろしくお願いいたします。
投稿者 daive  (社会人) 投稿日時 2015/11/17 18:54:40
参考サイト例
PC-PR201系制御コード
http://software.aufheben.info/ooholdpc/pcpr201.html

日本語シリアルプリンタ言語201PLのリファレンスマニュアル
http://webcache.googleusercontent.com/search?q=cache:XOWs9hMEZOoJ:jpn.nec.com/printer/dot/old/prd201hx/index.html+&cd=5&hl=ja&ct=clnk&gl=jp&lr=lang_ja
のような、(たまたま、PL系ですが、本来のPC-PR201系のリファレンスマニュアルが必要)
該当プリンタ系統のリファレンスマニュアル

などが無いと、
英文字圏のプリンタとは、違って、
日本語プリンタの操作は、厳しいかも。

Windowsのドライバを経由すると、どうしてもWindows Printing Systemの横やりが入るので、
パラレルであれば、パラレルシリアル変換アダプタや、パラレルUSBアダプタを介在させて、
PC-PR201のプリンタネイティブのコマンドを使った方が、楽かもしれません。
⇒プリンタの制御コードを弄るソフトを、1から書くという場合です。

英語圏のプリンタは、
古くは、デイジー、ベルト、チェーン他、固定文字のプリンタでした。
ドットインパクトも、当初はANKサポートだけでしたが、
16ドット位から、漢字サポートが始まり、
DOS時代の売れ線プリンタが
PC-PR201系ドットマトリックスプリンタでした。
投稿者 kiku  (社会人) 投稿日時 2015/11/17 18:44:28

エラーが出てれば対処方法も検討のしようがあると
思うのですがエラー出てないと困りますね。

すべての命令で下記してみたらどうでしょう?
dwError = Marshal.GetLastWin32Error()

どっかでエラーになってるかも。
投稿者 hori  (社会人) 投稿日時 2015/11/17 17:44:18
kikuさま。ご心配いただきありがとうございます。心強いです。

テストページは印刷できます。

「Windows からの PR201系プリンタ直接制御」のサイトを読んでいますと
NECのプリンターには文字データを[JIS]で送らねばならないようです。

[szString]を、たぶん元はユニコードだと思うのでバイトデータに変換し
それをさらにJISに変換してやってみましたが駄目でした。

なので、下記の「Ansi」の部分が引っ掛かっているのではないかと思って

pBytes = Marshal.StringToCoTaskMemAnsi(szString)

対処方法を探しているのですが今のところ行き当たりません。

まぁ、仕事ではないのでどっちでもいいんですが
友人に『簡単なことさ』と大見栄を切ったのでちょっとねぇ・・・・・・
投稿者 kiku  (社会人) 投稿日時 2015/11/17 16:09:07
>Button2 をクリックするとメッセージボックスに「000」が表示される状態です。

あら、本当に正常系で実行されているみたいですね。

サンプルが悪く、エラーをきちんと取得できていないのか?
それとも
ドライバーまでは正常にデータが送れているのか?
という切り分けが必要に思います。

プリンタドライバのプロパティから
テストページの印刷はできますか?


>Dim b(128) As Byte のデータを
>WritePrinter の2つ目のパラメーターの
> IntPtr型に変換する方法を探しているところですが
> ご存知でしたらご教示ください。

ごめんなさい。
ここわからないです。

下記ではだめなんでしょうか?
Dim pBytes As IntPtr
Dim dwCount As Int32
dwCount = szString.Length()
pBytes = Marshal.StringToCoTaskMemAnsi(szString)
投稿者 hori  (社会人) 投稿日時 2015/11/17 15:10:31
MSのサンプルの「SendBytesToPrinter」の部分を

    Public Shared Function SendBytesToPrinter(ByVal szPrinterName As String, ByVal pBytes As IntPtr, ByVal dwCount As Int32) As Boolean
        Dim hPrinter As IntPtr      ' The printer handle.
        Dim dwError As Int32        ' Last error - in case there was trouble.
        Dim di As DOCINFOW          ' Describes your document (name, port, data type).
        Dim dwWritten As Int32      ' The number of bytes written by WritePrinter().
        Dim bSuccess As Boolean     ' Your success code.

        ' Set up the DOCINFO structure.
        With di
            .pDocName = "My Visual Basic .NET RAW Document"
            .pDataType = "RAW"
        End With
        ' Assume failure unless you specifically succeed.
        bSuccess = False
        If OpenPrinter(szPrinterName, hPrinter, 0) Then
            If StartDocPrinter(hPrinter, 1, di) Then
                If StartPagePrinter(hPrinter) Then
                    ' Write your printer-specific bytes to the printer.
                    bSuccess = WritePrinter(hPrinter, pBytes, dwCount, dwWritten)
                    EndPagePrinter(hPrinter)
                End If
                EndDocPrinter(hPrinter)
            End If
            ClosePrinter(hPrinter)
        End If
        ' If you did not succeed, GetLastError may give more information
        ' about why not.
        If bSuccess = False Then
            dwError = Marshal.GetLastWin32Error()
        Else
            Msgbox("000")
        End If
        Return bSuccess
    End Function ' SendBytesToPrinter()


にして Button2 をクリックするとメッセージボックスに「000」が表示される状態です。


http://www.ne.jp/asahi/fukano/yoshio/lprintbs.html

を見つけ、同じNECのプリンターなので
これを参考にできるのではないかと思い今やっているところです。
基本を勉強しながらなので難しいですねぇ。

Dim b(128) As Byte のデータを
WritePrinter の2つ目のパラメーターの
 IntPtr型に変換する方法を探しているところですが
ご存知でしたらご教示ください。

 


投稿者 kiku  (社会人) 投稿日時 2015/11/17 09:55:06
>プログラム的には最後まで行くようになりましたが
>プリンターが反応しない状態です。

この情報だけですと、回答が得られないと思いますので
もう少し具体的な質問ができるようになるために
情報を集める必要があると思います。

「最後まで行く」というコメントがありますが、
デバッカでステップ実行をした結果、
途中でエラーや、分岐もせずに
最後まで行ったということでしょうか?

もし、途中でエラーが出ている場合には
その情報を提示する必要がありますし、
途中で分岐などする場合には、
この命令で0が返るはずが、1が返って分岐するなどの
情報を提示してはいかがでしょうか?

投稿者 hori  (社会人) 投稿日時 2015/11/16 17:39:16
kikuさま。

プリンターは、NECの マルチインパクト700JX3 で
プリンターサーバー内蔵タイプでLANで接続しています。
PCのOSは、win7アルチメイトで
NETのバージョンと云うのはframework4.5という事ですかねぇ。
ドライバーはNECのサイトからダウンロードしましたが
詳細までは承知していません。

http://hanatyan.sakura.ne.jp/patio/read.cgi?no=155

に行き当たって、そのようにやってみましたら
前出のエラーはクリアして
プログラム的には最後まで行くようになりましたが
プリンターが反応しない状態です。
投稿者 kiku  (社会人) 投稿日時 2015/11/16 11:25:43
小生は、知識がないため、今回の問題に対する直接的な解答はできませんが、
まずは、動作環境を明示した方が、回答がつきやすくなるのではないかと思いました。
思いつく限りには下記になります。

・ドットプリンタのメーカ名と型番
・ドットプリンタとPC間の接続方法(ハード的に)
・PCのOSの種類
・.NETのバージョンの指定があれば明記
・現在、ドットプリンタを利用できるようにするために
 PCへプリンタドライバなどを導入しているのであるならばそれを明記。
投稿者 hori  (社会人) 投稿日時 2015/11/16 10:30:51
先日、現在、月に1~2枚手書きで書いている宅配便の送り状に使えるかなと思って、
友人から不要になったドットインパクトプリンターをもらったのですが、
VB2010EXで行単位の印刷をする方法がわかりません。調べたところ

https://support.microsoft.com/en-us/kb/322090

に行き当たり、記載のコードをそのまま試してみたら、

OpenPrinter のところで

「PInvokeStackImbalance」 と云うエラーになります。

どうも、パラメーターの型が違うと云う事らしいのですが

https://msdn.microsoft.com/ja-jp/library/cc410486.aspx

を見ても何が正解の『型』なのかわかりません。

このエラーを回避する方法をご存知の方居られましたらご教示願えませんでしょうか。
よろしくお願いいたします。