- 題名: 用紙サイズの幅と長さを取得したい。
- 日時: 2007/05/17 13:03:40
- ID: 19696
- この記事の返信元:
- (なし)
- この記事への返信:
- [19697] Re[1]: 用紙サイズの幅と長さを取得したい。2007/05/17 14:28:46
- ツリーを表示
■No19696に返信(鈴木 雅夫さんの記事)
ソースを公開する場合は、そのまま実行して試せるぐらいになっていないと難し
いと思います。
ちょっと見てみましたが、定義が抜けている部分がありました。
(DC_PAPERS とか PointST とか)
その辺を補った上で調べてみましたが、DeviceCapabilities3 はそのままでは機
能していないと思われます。
たぶん、pOutput() を IntPtr にして、Marshal.HGlobal で確保したメモリへ設
定してもらったものをループで Marshal.PtrToStructure メソッドを利用してコ
ピーしつつ設定という形になるのかと。
# ちょっとやってみましたが、結構面倒くさいですね(前にも同じようなことやっ
# たことあるけど)。
ぐちゃーっと書いた汚いコードですが、こんな感じになるのかなと。
<StructLayout(LayoutKind.Explicit)> _
Private Structure PointST
<FieldOffset(0)> Private X As Int32
<FieldOffset(4)> Private Y As Int32
End Structure
'プリンタデバイスドライバの能力を取得する(各用紙サイズの番号取得用)
Private Declare Function DeviceCapabilities1 Lib "winspool.drv" Alias "DeviceCapabilitiesA" _
(ByVal pDevice As String, _
ByVal pPortt As String, _
ByVal fwCapability As Short, _
ByVal pOutput() As Short, _
ByVal pDevMode As System.IntPtr) As Integer
'プリンタデバイスドライバの能力を取得する(各用紙サイズの寸法取得用)
Private Declare Function DeviceCapabilities3 Lib "winspool.drv" Alias "DeviceCapabilitiesA" _
(ByVal pDevice As String, _
ByVal pPortt As String, _
ByVal fwCapability As Short, _
ByVal p As IntPtr, _
ByVal pDevMode As System.IntPtr) As Integer
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim strPrinterName As String = "プリンタの名前"
Dim intPaperSizeCount As Integer
Const DC_PAPERS As Integer = 2
Const DC_PAPERSIZE As Integer = 3
' 用紙サイズ数取得(領域確保用)
intPaperSizeCount = DeviceCapabilities1(strPrinterName, "", DC_PAPERS, Nothing, System.IntPtr.Zero)
If intPaperSizeCount = -1 Then
Return
End If
Dim pointStSize As Integer = Marshal.SizeOf(GetType(PointST))
Dim p As IntPtr = IntPtr.Zero
Try
p = Marshal.AllocHGlobal(intPaperSizeCount * pointStSize)
' 用紙サイズ寸法取得
Dim intRet As Integer = DeviceCapabilities3(strPrinterName, "", DC_PAPERSIZE, p, System.IntPtr.Zero)
If intRet = -1 Then
Return
End If
Dim p2 As IntPtr = p
For i As Integer = 0 To intPaperSizeCount - 1
Dim stPoint As PointST
stPoint = DirectCast(Marshal.PtrToStructure(p2, stPoint.GetType()), PointST)
Console.WriteLine("{0} {1}mm {2}mm", i, stPoint.X / 10, stPoint.Y / 10)
p2 = New IntPtr(p2.ToInt32() + pointStSize)
Next
Finally
If p <> IntPtr.Zero Then
Marshal.FreeHGlobal(p)
End If
End Try
End Sub
あんまりテストしてないので、変なところあったらツッコミよろしくお願いします orz
分類:[.NET]
現在、.Net Framework の PrinterSettings.PaperSizes クラスで、指定したプリンタの全ての用紙サイズの幅と長さを取得しておりますが、非常に時間が掛かる(114種の用紙サイズで20秒位)為、 Win32 API で実現しようと考えております。
DeviceCapabilities という関数で
(1)用紙サイズ番号の取得(第三引数に DC_PAPERS を指定)
(2)用紙サイズ名称の取得(第三引数に DC_PAPERNAMES を指定)
(3)用紙サイズの幅と長さの取得(第三引数に DC_PAPERSIZE を指定)
上記(1)、(2)は出来ましたが、(3)が出来ません。
ソースは以下のようになっております。
#Region "Win32 API"
'プリンタデバイスドライバの能力を取得する(各用紙サイズの番号取得用)
Private Declare Function DeviceCapabilities1 Lib "winspool.drv" Alias "DeviceCapabilitiesA" _
(ByVal pDevice As String, _
ByVal pPortt As String, _
ByVal fwCapability As Short, _
ByVal pOutput() As Short, _
ByVal pDevMode As System.IntPtr) As Integer
'プリンタデバイスドライバの能力を取得する(各用紙サイズの名称取得用)
Private Declare Function DeviceCapabilities2 Lib "winspool.drv" Alias "DeviceCapabilitiesA" _
(ByVal pDevice As String, _
ByVal pPortt As String, _
ByVal fwCapability As Short, _
ByVal pOutput As String, _
ByVal pDevMode As System.IntPtr) As Integer
'プリンタデバイスドライバの能力を取得する(各用紙サイズの寸法取得用)
Private Declare Function DeviceCapabilities3 Lib "winspool.drv" Alias "DeviceCapabilitiesA" _
(ByVal pDevice As String, _
ByVal pPortt As String, _
ByVal fwCapability As Short, _
ByVal pOutput() As PointST, _
ByVal pDevMode As System.IntPtr) As Integer
#End Region
'用紙サイズ数取得(領域確保用)
intPaperSizeCount = DeviceCapabilities1(strPrinterName, "", DC_PAPERS, Nothing, System.IntPtr.Zero)
If intPaperSizeCount = -1 Then
Return Nothing
End If
'領域確保
ReDim stPaperSize(intPaperSizeCount - 1) '用紙サイズ構造体配列
ReDim shoPaperSizeNumber(intPaperSizeCount - 1) '用紙サイズ番号
strPaperSizeNameAll = New String(Char.Parse(" "), intPaperSizeCount * 64) '用紙サイズ名称(全用紙サイズ取り出し用)
ReDim stPaperPoint(intPaperSizeCount - 1) 'ポイント構造体配列
'プリンター名称メンバー変数の値をローカル変数へ複写
strPrinterName = m_strPrinterName
'用紙サイズ番号取得
intRet = DeviceCapabilities1(strPrinterName, "", DC_PAPERS, shoPaperSizeNumber, System.IntPtr.Zero)
If intRet = -1 Then
Return Nothing
End If
'プリンター名称メンバー変数の値をローカル変数へ複写
strPrinterName = m_strPrinterName
'用紙サイズ名称取得
intRet = DeviceCapabilities2(strPrinterName, "", DC_PAPERNAMES, strPaperSizeNameAll, System.IntPtr.Zero)
If intRet = -1 Then
Return Nothing
End If
'プリンター名称メンバー変数の値をローカル変数へ複写
strPrinterName = m_strPrinterName
'用紙サイズ寸法取得
intRet = DeviceCapabilities3(strPrinterName, "", DC_PAPERSIZE, stPaperPoint, System.IntPtr.Zero)
If intRet = -1 Then
Return Nothing
End If