Discussion:
USBプリンタに特別なコーディングが必要ですか。
(too old to reply)
unknown
2008-03-19 04:14:00 UTC
Permalink
USBプリンタの印刷で困っています。
印刷の最初の段階でエラーになるということです。
知人にテストの為、自作プログラムを送ってテストしてもらったのですが、
印刷がうまく行きません。
私が使っているのはセントロニクス規格のパラレル接続ですが、
知人はUSB接続のCANONのPIXSUSです。
私は同じCANONのBJC400JとEPSON PM760Cで何れも
セントロニクスで接続しています。
USB対策で何かコーディングが必要なのでしょうか。
下記にその抜粋を記述します。
よろしくお願い致します。

VisualC++6
セントロではうまく動作するプログラム
BOOL PrintOnePage(HWND hWnd,int prn_type,int page_size)
{
static DOCINFO di = { sizeof (DOCINFO),TEXT("印刷中です。しばらくお待ち下さい") };
BOOL bSuccess = TRUE;
HDC hdcPrn;
int xPage,yPage;

if(check_prn_sw() == 0){ return(0); } // 印刷しない
if(NULL == (hdcPrn = GetPrnDC())){ return FALSE; }
if(page_size == 0){ page_size = 1; }
xPage = GetDeviceCaps(hdcPrn,HORZRES); // 現在設定されている印刷横サイズ 現在A4の設定の前提
yPage = GetDeviceCaps(hdcPrn,VERTRES); // 現在設定されている印刷縦サイズ
xPage /= page_size;
yPage /= page_size;

if( StartDoc (hdcPrn,&di) > 0) // 印刷ジョブを開始
{
if(StartPage(hdcPrn) > 0)
{
switch(prn_type)
{
case 2: // 入場1枚
prn_parkin_a6(hdcPrn,xPage,yPage);
break;
/**** 省略 ****/ 
}
if(EndPage(hdcPrn) > 0){ EndDoc(hdcPrn); } // 印刷ジョブを終了
else{ bSuccess = FALSE; }
}
}
else
{
bSuccess = FALSE;
}

DeleteDC(hdcPrn);
return bSuccess;
}

/*** prn_parkin_a6(hdcPrn,xPage,yPage)の各行の印刷は下記関数で *****/

int prn_textex(HDC hdcPrn,int typesw,int futosa,int mojisize,int x,int
y,char *moji)
{
int nHeight,len;
static HFONT hFont;
static HGDIOBJ oldhFont;
char shotaimoji[51];
COLORREF oldcr;

cls_str(shotaimoji,51);
switch(typesw) // 書体選択
{
case 1: // MS明朝
sprintf(shotaimoji,"%s %s","MS","明朝");
break;
case 2: // MSP明朝
sprintf(shotaimoji,"%s %s","MS","P明朝");
break;
case 3: // MSゴチック
sprintf(shotaimoji,"%s %s","MS","ゴチック");
break;
case 4: // MSPゴチック
sprintf(shotaimoji,"%s %s","MS","Pゴチック");
break;
default: // システム指定の書体
break;
}
nHeight = -MulDiv(mojisize,GetDeviceCaps(hdcPrn,LOGPIXELSY),72);
hFont =
CreateFont(nHeight,0,0,0,futosa,0,0,0,SHIFTJIS_CHARSET,OUT_TT_ONLY_PRECIS,
CLIP_TT_ALWAYS,PROOF_QUALITY,FIXED_PITCH |
FF_DONTCARE,shotaimoji);

oldhFont = SelectObject(hdcPrn,hFont);
oldcr = SetTextColor(hdcPrn,XBLACK);
len = lstrlen(moji);
TextOut(hdcPrn,x,y,moji,len);
SetTextColor(hdcPrn,oldcr);
SelectObject(hdcPrn,oldhFont);
DeleteObject(hFont);
return(len);
}
UETA, Shin-ichi
2008-03-31 05:27:20 UTC
Permalink
こんにちは、植田です。
Post by unknown
印刷の最初の段階でエラーになるということです。
ソースコード上では、具体的にはどの辺りで失敗しているのでしょうか?
GetLastError()が示す値も含めて、もう少し詳しい情報がないと判断が
難しいかと。
Post by unknown
私が使っているのはセントロニクス規格のパラレル接続ですが、
知人はUSB接続のCANONのPIXSUSです。
私は同じCANONのBJC400JとEPSON PM760Cで何れも
セントロニクスで接続しています。
ドライバ絡みの問題なのかもしれませんが、ドライバが悪いというわけ
ではなく、アプリケーション側での対処が不十分というケースも考えられ
ます。
たとえば、ある特定の解像度を前提にしているとか、プリンタで対応
できない条件になっているとか、etc.

ところで、知人の方のプリンタは、ほかのアプリケーションからの印刷は
うまくいっているのでしょうか?
Post by unknown
USB対策で何かコーディングが必要なのでしょうか。
よほどデバイスに依存する書き方をしないかぎりはインターフェイスの
違いくらいでこけることはない気がしますけど、とにかく、どのAPI呼び
出しで失敗しているのかを突き止めないことには何とも言えませんね。

たとえば、気になるところと言えば ――

prn_type, page_size
そもそも引数は期待する値が渡されているのだろうか?
check_prn_sw()
もしかしてこの時点ですでに「印刷しない」になってたりして?
GetPrnDC()
この関数(メソッド?)の実装はどうやってプリンタDCを得ているのか?
DOCINFO
cbSizeとlpszDocName以外は設定していないけどそれでいいのか?
MSゴチック/MSPゴチック
フォント名が違うような...? 正しくは "MS ゴシック", "MS Pゴシック"
--
植田システム設計事務所
Ueta System Design Studio
http://www.usdesign.jp/
植田真一
mailto:***@usdesign.jp
unknown
2008-04-01 10:18:03 UTC
Permalink
上田です。

植田さん、年度替わりの忙しい時にお手を煩わせて申し訳けありません。
結局、先の知人はプリンタに別のパラレルのコネクタがあったとかで、
パラレル用のプリンタコードを調達してもらったら、印刷は問題なくうまくいったとのことでした。
 この結果を考えると、どうも以下の関数がうまく働いていないのではないかと推測しました。
問題はEnumPrinters (... )関数にあると考えています。
プリンタはローカルプリンタを想定していますが、USBプリンタでは(正確にはUSB接続タイプ
のプリンタでは情報が読めないのではと推測しています。
つまりプリンタ名が取れていないので当然CreateDC(... )は失敗すると。
パラレルでは、プリンタ名(私の場合はBJC400)が読めますから。
check_prn_sw()は条件設定でプリンタ接続/未接続の情報を見て
印刷をするかしないかを決めているだけです。
EnumPrinters関数に代わるプリンタ名を探し出す関数(但し、プリンタハンドルは不明な状態で)が
あれば良いのですが。あれば助かります。


HDC GetPrnDC(void)
{
DWORD dwNeeded,dwReturned;
HDC hdc;
PRINTER_INFO_4 *pinfo4;
PRINTER_INFO_5 *pinfo5;

if (GetVersion() & 0x80000000) // Windows 98
{
EnumPrinters
(PRINTER_ENUM_DEFAULT,NULL,5,NULL,0,&dwNeeded,&dwReturned); // <<< この関数が問題かと
pinfo5 = malloc(dwNeeded);
EnumPrinters
(PRINTER_ENUM_DEFAULT,NULL,5,(PBYTE)pinfo5,dwNeeded,&dwNeeded,&dwReturned); // <<< この関数が問題かと
hdc = CreateDC(NULL,pinfo5->pPrinterName,NULL,NULL);
free(pinfo5);
}
else // Windows NT
{
EnumPrinters
(PRINTER_ENUM_LOCAL,NULL,4,NULL,0,&dwNeeded,&dwReturned); // <<< この関数が問題かと
pinfo4 = malloc(dwNeeded);
EnumPrinters
(PRINTER_ENUM_LOCAL,NULL,4,(PBYTE)pinfo4,dwNeeded,&dwNeeded,&dwReturned); // <<< この関数が問題かと
hdc = CreateDC(NULL,pinfo4->pPrinterName,NULL,NULL);
free(pinfo4);
}
return hdc;
}
UETA, Shin-ichi
2008-04-02 04:58:41 UTC
Permalink
どうも、植田です。
Post by unknown
問題はEnumPrinters (... )関数にあると考えています。
添付のソースコードをコピーして当方の環境で試してみたところ、
USBプリンタも列挙されていました。プリンタDCの生成も問題なし。
ちなみに、Office 2003の仮想プリンタも含めて、存在するプリンタは
すべて列挙されていました。

当方の環境:WinXPSP2+Brother製USB複合機能プリンタ

Win9x系だとどうなんだろう...。すぐに試せる環境がないので未確認です。
Post by unknown
EnumPrinters関数に代わるプリンタ名を探し出す関数(但し、プリンタハンドルは不明な状態で)が
あれば良いのですが。あれば助かります。
どうでしょうね。心当たりはありませんが、あるとすればレジストリを
検索することになるのかな?
--
植田システム設計事務所
Ueta System Design Studio
http://www.usdesign.jp/
植田真一
mailto:***@usdesign.jp
unknown
2008-04-04 03:29:00 UTC
Permalink
上田です。
ありがとうございました。
Post by UETA, Shin-ichi
添付のソースコードをコピーして当方の環境で試してみたところ、
USBプリンタも列挙されていました。プリンタDCの生成も問題なし。
ちなみに、Office 2003の仮想プリンタも含めて、存在するプリンタは
すべて列挙されていました。
当方の環境:WinXPSP2+Brother製USB複合機能プリンタ
Win9x系だとどうなんだろう...。すぐに試せる環境がないので未確認です。
驚きです。
実は、知人は二人で二人共エラーと言ってきました。
二人ともパソコンについてはある程度なれているので
初心者が間違えるようなことはしていないと思いました。
但し、プログラムに関する知識はないので、あまり突っ込んだ
質問もできず、弱りました。
ここは実際にUSBプリンタを手に入れて自身でテストすることしか
確かめようはないようです。
UETA, Shin-ichi
2008-04-02 05:00:45 UTC
Permalink
どうも、植田です。
Post by unknown
問題はEnumPrinters (... )関数にあると考えています。
添付のソースコードをコピーして当方の環境で試してみたところ、
USBプリンタも列挙されていました。プリンタDCの生成も問題なし。
ちなみに、Office 2003の仮想プリンタも含めて、存在するプリンタは
すべて列挙されていました。

当方の環境:WinXPSP2+Brother製USB複合機能プリンタ

Win9x系だとどうなんだろう...。すぐに試せる環境がないので未確認です。
Post by unknown
EnumPrinters関数に代わるプリンタ名を探し出す関数(但し、プリンタハンドルは不明な状態で)が
あれば良いのですが。あれば助かります。
どうでしょうね。心当たりはありませんが、あるとすればレジストリを
検索することになるのかな?
--
植田システム設計事務所
Ueta System Design Studio
http://www.usdesign.jp/
植田真一
mailto:***@usdesign.jp
UETA, Shin-ichi
2008-04-02 05:49:51 UTC
Permalink
どうも、植田です。
Post by UETA, Shin-ichi
Post by unknown
EnumPrinters関数に代わるプリンタ名を探し出す関数(但し、プリンタハンドルは不明な状態で)が
あれば良いのですが。あれば助かります。
どうでしょうね。心当たりはありませんが、あるとすればレジストリを
検索することになるのかな?
デフォルトプリンタ限定であれば、次のようなコードはいかがでしょうか。

PRINTDLG pd = {sizeof(PRINTDLG)};
pd.Flags = PD_RETURNDEFAULT | PD_RETURNDC;
PrintDlg(&pd);

DeleteDC(pd.hDC);
GlobalFree(pd.hDevMode);
GlobalFree(pd.hDevNames);

もちろん、[印刷]ダイアログボックスをちゃんと表示して、ユーザーに
プリンタの選択を委ねてもよろしいかと思います。
--
植田システム設計事務所
Ueta System Design Studio
http://www.usdesign.jp/
植田真一
mailto:***@usdesign.jp
unknown
2008-04-04 03:32:00 UTC
Permalink
上田です。
Post by UETA, Shin-ichi
PRINTDLG pd = {sizeof(PRINTDLG)};
pd.Flags = PD_RETURNDEFAULT | PD_RETURNDC;
PrintDlg(&pd);

DeleteDC(pd.hDC);
GlobalFree(pd.hDevMode);
GlobalFree(pd.hDevNames);
もちろん、[印刷]ダイアログボックスをちゃんと表示して、ユーザーに
プリンタの選択を委ねてもよろしいかと思います。
試してみます。ありがとうございました。

Continue reading on narkive:
Loading...