DOBON.NET DOBON.NETプログラミング掲示板過去ログ

PaperSizeのKindがCustumなのにPaperSizeを変更できない

環境/言語:[C#]
分類:[.NET]

いつもお世話になってます、大西です。
プリンタ関係の質問です。

プリンタの用紙に"ユーザー定義サイズ"などのPaperSizeのKindがCustumのものが選択されている場合に、下記のようにPaperSizeの大きさを設定しようとしても、
"PaperSizeのKindがCustumでない限り、PaperSizeを変更できません。"というエラーになってしまいます。

PaperSizeのKindがCustumなのにどうして設定できないのでしょうか?
何かご存知の方がいらっしゃれば教えてください。
よろしくお願いします。

PrintDocument prnDoc = new PrintDocument();
prnDoc.PrinterSettings.PrinterName ="PrinterName";
prnDoc.DefaultPageSettings.PaperSize.Height = 100;
prnDoc.DefaultPageSettings.PaperSize.Width = 200;
> PaperSizeのKindがCustumなのにどうして設定できないのでしょうか?
その時の定数値は 256 の Custum ですか? 
ユーザ定義サイズは 定数が 256 のものしか使えなかったかと
VB.NET で Win32 API関数を使って、ユーザ定義サイズは 定数が 256 の用紙で
自由な寸法を設定しております。
(但し、VB6.0 でも設定できないプリンターは無理かと)
これえらーメッセージがわかりにくいだけ。

System.Drawing.Printing.PrinterSettings ps = new System.Drawing.Printing.PrinterSettings();
ps.DefaultPageSettings.PaperSize = new System.Drawing.Printing.PaperSize("name", 1,3);


これが正解
>花ちゃんさん
返信ありがとうございます。

>>PaperSizeのKindがCustumなのにどうして設定できないのでしょうか?
> その時の定数値は 256 の Custum ですか? 
> ユーザ定義サイズは 定数が 256 のものしか使えなかったかと

はい、いちおう256のものだけ設定するようにしています。

> VB.NET で Win32 API関数を使って、ユーザ定義サイズは 定数が 256 の用紙で
> 自由な寸法を設定しております。
> (但し、VB6.0 でも設定できないプリンターは無理かと)

いちおうVB6.0で試したところ普通に設定できたので、プリンタのほうは大丈夫そうです。
VB.NET で Win32 API関数を使って、ユーザ定義サイズを設定する方法をよろしければ教えていただけませんか?
>中博俊さん
返信ありがとうございます。

教えていただいた方法で試してみたところ、エラーは出なくなりました。
しかしドライバとの相性が悪いのか、何かまだ間違っているのか印刷結果にサイズが反映されません。
同じやり方でPrintPreviewDialogに命令を送ってやると設定されたサイズでプレビューされるので、やり方としては正しいのだと思うのですが・・・。

教えていただいた方法でもう少しいろいろと調べてみます。
> しかしドライバとの相性が悪いのか、何かまだ間違っているのか印刷結果にサイズが反映されません。

System.Drawing.Printing.PrinterSettings.DefaultPageSettings.PaperSize ではなく
System.Drawing.Printing.PrintDocument.DefaultPageSettings.PaperSize に設定すれば大丈夫だと思います。

(VBだとこんなかんじ)
Dim prnDoc As New System.Drawing.Printing.PrintDocument
prnDoc.DefaultPageSettings.PaperSize = New System.Drawing.Printing.PaperSize("name", 1, 3)
> VB.NET で Win32 API関数を使って、ユーザ定義サイズを設定する方法をよろしければ教えていただけませんか?
>

.NETできるのであれば、もう必要ないかもしれませんが、こんなかんじです。

---------------------------------------
Imports System.Runtime.InteropServices
Imports System.ComponentModel
---------------------------------------
Private Declare Auto Function OpenPrinter Lib "winspool.drv" ( _
<MarshalAs(UnmanagedType.LPTStr)> ByVal pPrinterName As String, _
ByRef phPrinter As IntPtr, _
ByVal pDefault As IntPtr) As Int32

Private Declare Auto Function ClosePrinter Lib "winspool.drv" (ByVal hPrinter As IntPtr) As Int32

Private Declare Auto Function AddForm Lib "winspool.drv" ( _
ByVal hPrinter As IntPtr, _
ByVal Level As Integer, _
ByVal pForm As IntPtr) As Integer

Private Declare Auto Function DeleteForm Lib "winspool.drv" (ByVal hPrinter As IntPtr, _
<MarshalAs(UnmanagedType.LPTStr)> ByVal pName As String) As Integer

'FORM_INFO_1 (用紙情報を定義する構造体)
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
Public Structure FORM_INFO_1
<MarshalAs(UnmanagedType.I4)> Public Flags As Int32
<MarshalAs(UnmanagedType.LPTStr)> Public pName As String
Public Size As SIZEL
Public ImageableArea As RECTL
End Structure

'幅と高さを定義する構造体の宣言
<StructLayout(LayoutKind.Sequential)> _
Public Structure SIZEL
Public cx As Int32
Public cy As Int32
End Structure

'矩形を定義する構造体の宣言
<StructLayout(LayoutKind.Sequential)> _
Public Structure RECTL
Public left As Int32
Public top As Int32
Public right As Int32
Public bottom As Int32
End Structure

' ユーザー定義の用紙を示す定数の宣言
Public Const FORM_USER = &H0&

---------------------------------------

ユーザー定義サイズ用紙設定
Public Sub AddPaperForm()
Dim ret As Integer
Dim hPrinter As IntPtr
Dim FormInfo1Level As Integer = 1
Dim FormInfo1 As FORM_INFO_1
Dim prtFormInfo1 As IntPtr
Dim lastError As Integer

Try
' プリンタのハンドルを取得
ret = OpenPrinter(PrinterName, hPrinter, IntPtr.Zero)
If ret = 0 Or hPrinter.Equals(IntPtr.Zero) Then
Return 0
End If
With FormInfo1
' 特性にユーザー定義を指定
.Flags = FORM_USER
' 用紙名を指定
.pName = "請求書"
' 幅と高さを指定
.Size.cx = 229000
.Size.cy = 241000
' 印刷範囲を指定
.ImageableArea.left = 10000
.ImageableArea.top = 10000
.ImageableArea.right = 229000 - 10000
.ImageableArea.bottom = 241000 - 10000
End With

prtFormInfo1 = Marshal.AllocHGlobal(Marshal.SizeOf(GetType(FORM_INFO_1)))

Marshal.StructureToPtr(FormInfo1, prtFormInfo1, True)

' 用紙情報を追加
ret = AddForm(hPrinter, FormInfo1Level, prtFormInfo1)

'Dim Struct1 As FORM_INFO_1
'Struct1 = CType(Marshal.PtrToStructure(prtFormInfo1, GetType(FORM_INFO_1)), FORM_INFO_1)

If ret <= 0 Then
Throw New Win32Exception(Marshal.GetLastWin32Error())
End If

Catch ex As Exception
MessageBox.Show(ex.Message, "エラー")

Finally
If Not hPrinter.Equals(IntPtr.Zero) Then
ClosePrinter(hPrinter)
End If
Marshal.FreeHGlobal(prtFormInfo1)
End Try
End Sub

---------------------------------------

'ユーザー定義サイズ用紙削除
Public Sub DeletePaperForm()
Dim ret As Integer
Dim hPrinter As IntPtr

Try
' プリンタのハンドルを取得
ret = OpenPrinter(PrinterName, hPrinter, IntPtr.Zero)
If ret = 0 Or hPrinter.Equals(IntPtr.Zero) Then
Return 0
End If

ret = DeleteForm(hPrinter, "請求書")

If ret <= 0 Then
Throw New Win32Exception(Marshal.GetLastWin32Error())
End If

Catch ex As Exception
MessageBox.Show(ex.Message, "エラー")
Finally
If Not hPrinter.Equals(IntPtr.Zero) Then
ClosePrinter(hPrinter)
End If
Marshal.FreeHGlobal(prtFormName)
End Try
End Sub
どうも返信ありがとうございます。
早速以下のように試してみたのですがやはり今までと同様にうまくいきませんでした。
何か自分が勘違いしているのでしょうか?

PrintDocument prnDoc = new PrintDocument();
prnDoc.PrinterSettings.PrinterName =classPageSetting.PrinterName;
prnDoc.DefaultPageSettings.PaperSize = new PaperSize("123",10,20);
prnDoc.PrintController = new StandardPrintController();
prnDoc.PrintPage += new PrintPageEventHandler(prnDoc_PrintPage); //印刷イベントを割付け
prnDoc.Print(); //印刷
この方法ですると用紙は切り替わらずにデフォルトで選択されている用紙でそのまま印字されてしまいます。
そこでまず"ユーザー定義サイズ"に設定してからこの処理を行わないといけないのかな?と思い以下のようにしてみました。

PrintDocument prnDoc = new PrintDocument();
prnDoc.PrinterSettings.PrinterName =classPageSetting.PrinterName;
foreach(PaperSize ps in prnDoc.PrinterSettings.PaperSizes)
{
 if (ps.PaperName == "ユーザー定義サイズ")
  {
   prnDoc.DefaultPageSettings.PaperSize = ps;
   break;
  }
}
prnDoc.DefaultPageSettings.PaperSize = new PaperSize("123",10,20);
prnDoc.PrintController = new StandardPrintController();
prnDoc.PrintPage += new PrintPageEventHandler(prnDoc_PrintPage); //印刷イベントを割付け
prnDoc.Print(); //印刷
こうすると用紙は"ユーザー定義サイズ"に変わっているようで、"ユーザー定義サイズ"にデフォルトで設定されているサイズでは印刷できるのですが、こちらの指定したサイズにはなりませんでした。

何かおかしな点、気づいた点などがあれば教えてください。
よろしくお願いします。
ほんとにどうもありがとうございます。

とりあえずドットネットでもう少しいろいろとやってみて、
どうしても無理ならこちらをC#に移植して試してみます。

DOBON.NET | プログラミング道 | プログラミング掲示板