すらすらプログラマーへのお問い合わせ
すらすらのブログ
アクセス数  累計:000,583,326  昨日:000,000,238  本日:000,000,023
Loading
印刷
.NET プログラミング
プロパティグリッド
印刷
リストボックス
スレッド
リストビュー
インストーラー
やってみよう!

できるVisual Studio 2015 Windows /Android/iOS アプリ対応

独習C# 第3版

VisualBasic2013パーフェクトマスター (Perfect Master SERIES)

プログラミング.NET Framework 第4版 (Microsoft Press)

VisualBasic2013逆引き大全555の極意

猫でもわかるWindowsプログラミング 第4版 (猫でもわかるプログラミング)

VisualC#2013逆引き大全555の極意

プリンタ設定の保存と読込 最終更新:2010/07/22
【Amazon ランキング:DVD - 海外映画】

プリンタの設定情報は印刷が終わって printDocument が破棄されるとデフォルトの状態に戻ってしまいちょっと不便な面があります。
今回は前回作成した印刷ダイアログを拡張してプリンタの設定情報をファイルに保存、読み込みを行って設定情報を永続的に保持するようにしてみます。
プリンタ設定の保存
プリンタ設定は .PrinterSettings.GetHdevmode() で取得できますが、これはグローバルメモリ上のアドレスだけで実際にファイルに書き込むためにデータではありません。そこでこのアドレスから必要なサイズ分データを読み込んでファイルに書き込みます。
プリンタ設定情報のサイズを取得するには前回も使った DocumentPropertys API を使用します。pDevModeOutput、pDevModeInput に IntPtr.Zero を設定すると戻り値に DEVMODE のサイズが設定されます。

[VB]
Dim devSize As Integer = DocumentProperties( _
            
Me.Handle, hPrinter, doc.PrinterSettings.PrinterName, IntPtr.Zero, IntPtr.Zero, 0)

[C#]
int devSize = DocumentProperties(
                
this.Handle, hPrinter, doc.PrinterSettings.PrinterName, IntPtr.Zero, IntPtr.Zero, 0);
印刷ダイアログの作成
印刷用画面は前回と変わりません。

ComboBox:[comboPrinter]
DropDownStyle DropDownList

Button:[buttonProperty]
Button:[buttonOk]
Button:[buttonCancel]

RadioButton:[radioAll]
RadioButton:[radioCurrent]
RadioButton:[radioSome]
RadioButton:[radioSelect]

NumericUpDown:[updownFrom]
NumericUpDown:[updownTo] NumericUpDown:[updownCopy]

ChecBox:[checkCollate]

VB[PrinterForm.vb]
Imports System.Runtime.InteropServices
Imports System.Drawing.Printing
Imports System.io

Public Class PrinterForm

    
' 指定されたプリンタまたはプリントサーバーを識別するハンドルを取得します。
    <DllImport("winspool.drv", EntryPoint:="OpenPrinterW", _
    SetLastError:=
True, CharSet:=CharSet.Unicode, _
    ExactSpelling:=
True, CallingConvention:=CallingConvention.StdCall)> _
    
Private Shared Function OpenPrinter(ByVal pPrinterName As String, _
    
ByRef phPrinter As IntPtr, ByVal pDefault As IntPtr) As Boolean
    End Function

    ' 特定のプリンタオブジェクトをクローズします。
    <DllImport("winspool.Drv", EntryPoint:="ClosePrinter", _
    SetLastError:=
True, CharSet:=CharSet.Unicode, _
    ExactSpelling:=
True, CallingConvention:=CallingConvention.StdCall)> _
    
Private Shared Function ClosePrinter(ByVal hPrinter As IntPtr) As Boolean
    End Function

    ' 特定のプリンタのプリンタ設定プロパティシートを表示します。
    <DllImport("winspool.Drv", EntryPoint:="DocumentPropertiesW", _
    SetLastError:=
True, CharSet:=CharSet.Unicode, _
    ExactSpelling:=
True, CallingConvention:=CallingConvention.StdCall)> _
    
Private Shared Function DocumentProperties(ByVal hWnd As IntPtr, _
                                               
ByVal hPrinter As IntPtr, _
    <MarshalAs(UnmanagedType.LPTStr)> 
ByVal pDeviceName As String, _
    
ByVal pDevModeOutput As IntPtr, ByVal pDevModeInput As IntPtr, _
    
ByVal fMode As IntegerAs Integer
    End Function

    ' fMode 設定値
    Private Const DM_OUT_BUFFER As Integer = &H2
    
Private Const DM_PROMPT As Integer = &H4
    
Private Const DM_IN_PROMPT As Integer = DM_PROMPT
    
Private Const DM_IN_BUFFER As Integer = &H8

    
' メンバ変数
    Private _printDoc As PrintDocument = Nothing

    ' プリンタドキュメントプロパティ
    Public Property Document() As PrintDocument
        
Get
            Return _printDoc
        
End Get
        Set(ByVal value As PrintDocument)
            _printDoc = value
        
End Set
    End Property

    ' プリンタセッティングプロパティ
    Public ReadOnly Property PrinterSettings() As PrinterSettings
        
Get
            Return _printDoc.PrinterSettings
        
End Get
    End Property

    ' フォームロード処理
    Private Sub PrinterForm_Load(ByVal sender As Object, _
                                 
ByVal e As System.EventArgs) _
                                 
Handles Me.Load

        
' 印刷範囲の設定
        Me.radioAll.Checked = True
        Me.updownFrom.Enabled = False
        Me.updownTo.Enabled = False

        ' ページ範囲の設定
        If _printDoc.PrinterSettings.MinimumPage > 0 Then
            Me.updownFrom.Minimum = _printDoc.PrinterSettings.MinimumPage
            
Me.updownTo.Minimum = _printDoc.PrinterSettings.MinimumPage
        
Else
            Me.updownFrom.Minimum = 1
            
Me.updownTo.Minimum = 1
        
End If

        If _printDoc.PrinterSettings.MaximumPage > 0 Then
            Me.updownFrom.Maximum = _printDoc.PrinterSettings.MaximumPage
            
Me.updownTo.Maximum = _printDoc.PrinterSettings.MaximumPage
        
Else
            Me.updownFrom.Maximum = 100
            
Me.updownTo.Maximum = 100
        
End If

        If _printDoc.PrinterSettings.FromPage > 0 Then
            Me.updownFrom.Value = _printDoc.PrinterSettings.FromPage
        
Else
            Me.updownFrom.Value = 1
        
End If

        If _printDoc.PrinterSettings.ToPage > 0 Then
            Me.updownTo.Value = _printDoc.PrinterSettings.ToPage
        
Else
            Me.updownTo.Value = 1
        
End If

        ' 部数の設定
        updownCopy.Minimum = 1

        
If _printDoc.PrinterSettings.MaximumCopies > 1 Then
            updownCopy.Maximum = _printDoc.PrinterSettings.MaximumCopies
        
Else
            updownCopy.Maximum = 100
        
End If

        updownCopy.Value = 1

        
' プリンタ一覧をコンボボックスに設定する
        Me.comboPrinter.Items.Clear()

        
For Each prt As String In PrinterSettings.InstalledPrinters
            
Me.comboPrinter.Items.Add(prt)
        
Next
        Me.comboPrinter.SelectedIndex = 0

    
End Sub

    ' プリンタコンボボックス選択イベント
    Private Sub comboPrinter_SelectedIndexChanged(ByVal sender As System.Object, _
                                                  
ByVal e As System.EventArgs) _
                                                  
Handles comboPrinter.SelectedIndexChanged

        
' プリンタ名
        Dim printerName As String = Me.comboPrinter.Text
        _printDoc.PrinterSettings.PrinterName = printerName

        
' プリンタ情報を設定
        Dim devMode As IntPtr = LoadPrinterSetting(printerName)
        _printDoc.PrinterSettings.SetHdevmode(devMode)
        Marshal.FreeHGlobal(devMode)

    
End Sub

    ' プロパティボタンクリックイベント処理
    Private Sub buttonProperty_Click(ByVal sender As System.Object, _
                                     
ByVal e As System.EventArgs) _
                                     
Handles buttonProperty.Click

        
Dim devModeIn As IntPtr = IntPtr.Zero
        
Dim devModeOut As IntPtr = IntPtr.Zero
        
Dim hPrinter As IntPtr = IntPtr.Zero

        
Try
            Dim printerName As String = _printDoc.PrinterSettings.PrinterName

            
' グローバルメモリオブジェクトをロックします。
            devModeIn = LoadPrinterSetting(printerName)
            
If devModeIn = IntPtr.Zero Then
                devModeIn = Marshal.AllocHGlobal(_printDoc.PrinterSettings.GetHdevmode())
            
End If
            devModeOut = Marshal.AllocHGlobal(_printDoc.PrinterSettings.GetHdevmode())

            
'プリンタのハンドルを取得
            If Not OpenPrinter(printerName, hPrinter, IntPtr.Zero) Then
                Exit Sub
            End If

            ' DEVMODE サイズ取得
            Dim devSize As Integer = DocumentProperties(Me.Handle, hPrinter, printerName, _
                IntPtr.Zero, IntPtr.Zero, 0)

            
' プリンタの設定画面表示
            If DocumentProperties(Me.Handle, hPrinter, printerName, _
                devModeOut, devModeIn, DM_IN_PROMPT 
Or DM_IN_BUFFER Or DM_OUT_BUFFER) = 1 Then

                ' プリンタ情報を設定
                _printDoc.PrinterSettings.SetHdevmode(devModeOut)

                
' プリンタ情報の保存
                Dim setting(devSize - 1) As Byte
                Marshal.Copy(devModeOut, setting, 0, devSize)

                
' 設定ファイル名
                Dim fileName As String = Path.Combine( _
                    Application.StartupPath, printerName & 
".dat")

                
' ファイルオープン
                Using fs As FileStream = New FileStream( _
                    fileName, FileMode.Create, FileAccess.Write)
                    
' 書き込み
                    fs.Write(setting, 0, setting.Length)

                    
' ファイルクローズ
                    fs.Close()
                
End Using

            Else
                Exit Sub
            End If

        Finally
            ' グロバールメモリ開放
            Marshal.FreeHGlobal(devModeIn)
            Marshal.FreeHGlobal(devModeOut)
            ClosePrinter(hPrinter)
        
End Try
    End Sub

    ' ラジオボタンクリックイベント処理
    Private Sub radioButton_Click(ByVal sender As System.Object, _
                                  
ByVal e As System.EventArgs) _
                                  
Handles radioAll.CheckedChanged, _
                                  radioCurrent.CheckedChanged, _
                                  radioSome.CheckedChanged, _
                                  radioSelect.CheckedChanged

        
' ページ指定が選ばれている場合
        If radioSome.Checked Then
            updownFrom.Enabled = True
            updownTo.Enabled = True
        Else
            updownFrom.Enabled = False
            updownTo.Enabled = False
        End If
    End Sub

    ' OKボタンクリックイベント処理
    Private Sub buttonOk_Click(ByVal sender As System.Object, _
                               
ByVal e As System.EventArgs) _
                               
Handles buttonOk.Click

        
' ページ情報を設定
        Select Case True
            Case Me.radioAll.Checked
                _printDoc.PrinterSettings.PrintRange = PrintRange.AllPages

            
Case Me.radioCurrent.Checked
                _printDoc.PrinterSettings.PrintRange = PrintRange.CurrentPage

            
Case Me.radioSome.Checked
                
' 範囲のチェック
                If Me.updownFrom.Value > Me.updownTo.Value Then
                    MessageBox.Show("ページの範囲をFrom < To となるように指定してください", _
                        
Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning)
                    
Exit Sub
                End If
                _printDoc.PrinterSettings.PrintRange = PrintRange.SomePages
                _printDoc.PrinterSettings.FromPage = 
Me.updownFrom.Value
                _printDoc.PrinterSettings.ToPage = 
Me.updownTo.Value

            
Case Me.radioSelect.Checked
                _printDoc.PrinterSettings.PrintRange = PrintRange.Selection

        
End Select

        _printDoc.PrinterSettings.Copies = updownCopy.Value
        _printDoc.PrinterSettings.Collate = checkCollate.Checked

        
Me.DialogResult = Windows.Forms.DialogResult.OK
        
Me.Close()
    
End Sub

    ' キャンセルボタンクリックイベント処理
    Private Sub buttonCancel_Click_1(ByVal sender As System.Object, _
                                     
ByVal e As System.EventArgs) _
                                     
Handles buttonCancel.Click

        
Me.DialogResult = Windows.Forms.DialogResult.Cancel
        
Me.Close()
    
End Sub

    ' プリンタ情報のロード
    Private Function LoadPrinterSetting(ByVal printerName As StringAs IntPtr
        
Dim devMode As IntPtr = IntPtr.Zero

        
' 設定ファイル名
        Dim fileName As String = Path.Combine(Application.StartupPath, printerName & ".dat")

        
'ファイルが存在する場合
        If File.Exists(fileName) Then
            ' ファイルオープン
            Using fs As FileStream = New FileStream(fileName, FileMode.Open, FileAccess.Read)

                
' 読み込み
                Dim setting(fs.Length - 1) As Byte
                fs.Read(setting, 0, fs.Length)

                
' グローバル領域にメモリー確保
                devMode = Marshal.AllocHGlobal(setting.Length)

                
' 設定コピー
                Marshal.Copy(setting, 0, devMode, setting.Length)

                
' ファイルクローズ
                fs.Close()
            
End Using
        End If

        Return devMode

    
End Function

End
 Class
C#[PrinterForm.cs]
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Printing;
using System.Runtime.InteropServices;
using System.IO;

namespace Print_CS
{
    
public partial class PrinterForm : Form
    {

        
// 指定されたプリンタまたはプリントサーバーを識別するハンドルを取得します。
        [DllImport("winspool.drv", EntryPoint = "OpenPrinterW",
        SetLastError = 
true, CharSet = CharSet.Unicode,
        ExactSpelling = 
true, CallingConvention = CallingConvention.StdCall)]
        
private static extern bool OpenPrinter(string pPrinterName,
        
out IntPtr phPrinter, IntPtr pDefault);

        
// 特定のプリンタオブジェクトをクローズします。
        [DllImport("winspool.Drv", EntryPoint = "ClosePrinter",
        SetLastError = 
true, CharSet = CharSet.Unicode,
        ExactSpelling = 
true, CallingConvention = CallingConvention.StdCall)]
        
private static extern bool ClosePrinter(IntPtr hPrinter);

        
// 特定のプリンタのプリンタ設定プロパティシートを表示します。
        [DllImport("winspool.Drv", EntryPoint = "DocumentPropertiesW",
        SetLastError = 
true, CharSet = CharSet.Unicode,
        ExactSpelling = 
true, CallingConvention = CallingConvention.StdCall)]
        
static extern int DocumentProperties(IntPtr hwnd, IntPtr hPrinter,
        [
MarshalAs(UnmanagedType.LPWStr)] string pDeviceName,
        
IntPtr pDevModeOutput, IntPtr pDevModeInput, int fMode);

        
// fMode 設定値
        private const int DM_OUT_BUFFER  = 0x2;
        
private const int DM_PROMPT  = 0x4;
        
private const int DM_IN_PROMPT = DM_PROMPT;
        
private const int DM_IN_BUFFER = 0x8;

        
public PrinterForm()
        {
            InitializeComponent();

            
// ラジオボタンのクリックイベントをひとつにまとめる
            this.radioAll.Click += new EventHandler(radioButton_Click);
            
this.radioCurrent.Click += new EventHandler(radioButton_Click);
            
this.radioSome.Click += new EventHandler(radioButton_Click);
            
this.radioSelect.Click += new EventHandler(radioButton_Click);
        }

        
// メンバ変数
        private PrintDocument _printDoc = null;

        
// プリンタドキュメントプロパティ
        public PrintDocument Document
        {
            
get { return _printDoc; }
            
set { _printDoc = value; }
        }

        
// プリンタセッティングプロパティ
        public PrinterSettings PrinterSettings
        {
            
get { return _printDoc.PrinterSettings; }
        }
        
        
// フォームロード処理
        private void Form2_Load(object sender, EventArgs e)
        {
            
// 印刷範囲の設定
            this.radioAll.Checked = true;
            
this.updownFrom.Enabled = false;
            
this.updownTo.Enabled = false;

            
// ページ範囲の設定
            if (_printDoc.PrinterSettings.MinimumPage > 0)
            {
                
this.updownFrom.Minimum = _printDoc.PrinterSettings.MinimumPage;
                
this.updownTo.Minimum = _printDoc.PrinterSettings.MinimumPage;
            }
            
else
            {
                
this.updownFrom.Minimum = 1;
                
this.updownTo.Minimum = 1;
            }

            
if (_printDoc.PrinterSettings.MaximumPage > 0)
            {
                
this.updownFrom.Maximum = _printDoc.PrinterSettings.MaximumPage;
                
this.updownTo.Maximum = _printDoc.PrinterSettings.MaximumPage;
            }
            
else
            {
                
this.updownFrom.Maximum = 100;
                
this.updownTo.Maximum = 100;
            }

            
if (_printDoc.PrinterSettings.FromPage > 0)
            {
                
this.updownFrom.Value = _printDoc.PrinterSettings.FromPage;
            }
            
else
            {
                
this.updownFrom.Value = 1;
            }

            
if (_printDoc.PrinterSettings.ToPage > 0)
            {
                
this.updownTo.Value = _printDoc.PrinterSettings.ToPage;
            }
            
else
            {
                
this.updownTo.Value = 1;
            }

            
// 部数の設定
            updownCopy.Minimum = 1;

            
if (_printDoc.PrinterSettings.MaximumCopies > 1)
            {
                updownCopy.Maximum = _printDoc.PrinterSettings.MaximumCopies;
            }
            
else
            {
                updownCopy.Maximum = 100;
            }

            
// プリンタ一覧をコンボボックスに設定する
            this.comboPrinter.Items.Clear(); 
            
foreachstring prt in PrinterSettings.InstalledPrinters )
            {
                
this.comboPrinter.Items.Add(prt);
            }
            
this.comboPrinter.SelectedIndex = 0;
        }

        
// プロパティボタンクリックイベント処理
        private void buttonProperty_Click(object sender, EventArgs e)
        {
            
// プリンタ名
            string printerName = this.comboPrinter.Text;

            
// プリンタ名設定
            _printDoc.PrinterSettings.PrinterName = printerName;

            
IntPtr devModeIn = IntPtr.Zero;
            
IntPtr devModeOut = IntPtr.Zero;
            
IntPtr hPrinter = IntPtr.Zero;

            
try{
                
// 設定データのロード
                devModeIn = LoadPrinterSetting(_printDoc);

                
// グローバルメモリオブジェクトをロックします。
                devModeOut = Marshal.AllocHGlobal(_printDoc.PrinterSettings.GetHdevmode());

                
//プリンタのハンドルを取得
                if( !OpenPrinter(printerName, out hPrinter, IntPtr.Zero)){
                    
return;
                }

                
// プリンタの設定画面表示
                if( DocumentProperties(this.Handle, hPrinter, printerName,
                    devModeOut, devModeIn, DM_IN_PROMPT | DM_IN_BUFFER | DM_OUT_BUFFER) == 1){
                    
                    
// OKボタンがクリックされた場合
                    _printDoc.PrinterSettings.SetHdevmode(devModeOut);

                    
// 設定情報の保存
                    SavePrinterSetting(hPrinter, devModeOut, _printDoc);
                }
else{
                    
return;
                }

            }
finally{
                
// グロバールメモリ開放
                Marshal.FreeHGlobal(devModeIn);
                
Marshal.FreeHGlobal(devModeOut);
                ClosePrinter(hPrinter);
            }
        }

        
// ラジオボタンクリックイベント処理
        void radioButton_Click(object sender, EventArgs e)
        {
            
if (radioSome.Checked)
            {
                
this.updownFrom.Enabled = true;
                
this.updownTo.Enabled = true;
            }
            
else
            {
                
this.updownFrom.Enabled = false;
                
this.updownTo.Enabled = false;
            }
        }

        
// OKボタンクリックイベント処理
        private void buttonOk_Click(object sender, EventArgs e)
        {
            
// ページ情報を設定
            if (this.radioAll.Checked)
            {
                _printDoc.PrinterSettings.PrintRange = 
PrintRange.AllPages;
            }
            
else if (radioCurrent.Checked)
            {
                _printDoc.PrinterSettings.PrintRange = 
PrintRange.CurrentPage; 
            }
            
else if (radioSome.Checked)
            {
                
// 範囲のチェック
                if (this.updownFrom.Value > this.updownTo.Value)
                {
                    
MessageBox.Show("ページの範囲をFrom < To となるように指定してください"
                        
this.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
                _printDoc.PrinterSettings.PrintRange = 
PrintRange.SomePages;
                _printDoc.PrinterSettings.FromPage = (
int)this.updownFrom.Value;
                _printDoc.PrinterSettings.ToPage = (
int)this.updownTo.Value;
            }
            
else if (radioSelect.Checked)
            {
                _printDoc.PrinterSettings.PrintRange = 
PrintRange.Selection;
            }

            _printDoc.PrinterSettings.Copies = (
short)this.updownCopy.Value;
            _printDoc.PrinterSettings.Collate = 
this.checkCollate.Checked;

            
this.DialogResult = DialogResult.OK; 
            
this.Close();
        }

        
// キャンセルボタンクリックイベント処理
        private void buttonCancel_Click(object sender, EventArgs e)
        {
            
this.DialogResult = DialogResult.Cancel;
            
this.Close();
        }

        
// プリンタ情報のロード
        IntPtr LoadPrinterSetting(PrintDocument doc)
        {
            
IntPtr devPtr;

            
// 設定ファイル名
            string fileName = Path.Combine(Application.StartupPath,
                doc.PrinterSettings.PrinterName + 
".dat");

            
// ファイルが存在する場合
            if (File.Exists(fileName))
            {
                
usingFileStream fs = new FileStream(
                    fileName, 
FileMode.Open, FileAccess.Read ))
                {
                    
// 読み込み
                    byte[] setting = new byte[fs.Length];
                    fs.Read( setting, 0, (
int)fs.Length);

                    
// グローバル領域にメモリー確保
                    devPtr = Marshal.AllocHGlobal(setting.Length);

                    
// 設定コピー
                    Marshal.Copy(setting, 0, devPtr, setting.Length);

                    
// ファイルクローズ
                    fs.Close(); 
                }
            }
            
else
            {
                devPtr = 
Marshal.AllocHGlobal(doc.PrinterSettings.GetHdevmode());
            }

            
return devPtr;
        }

        
// プリンタ情報の保存
        void SavePrinterSetting(IntPtr hPrinter, IntPtr devMode, PrintDocument doc)
        {
            
// DEVMODE サイズ取得
            int devSize = DocumentProperties(
                
this.Handle, hPrinter, doc.PrinterSettings.PrinterName,
                
IntPtr.Zero, IntPtr.Zero, 0);

            
// DEVMODE をコピー
            byte[] setting = new byte[devSize];
            
Marshal.Copy(devMode, setting, 0, devSize);

            
// 設定ファイル名
            string fileName = Path.Combine(Application.StartupPath,
                doc.PrinterSettings.PrinterName + 
".dat");

            
// ファイルオープン
            usingFileStream fs = new FileStream(
                fileName, 
FileMode.Create,FileAccess.Write ))
            {
                
// 書き込み
                fs.Write(setting, 0, setting.Length);

                
// ファイルクローズ
                fs.Close();
            }
        }
    }
}
※このページで紹介しているサンプルコードについて管理者は動作保障をいたしません※
※サンプルコードを使用する場合は、自己責任でお願いします※

【楽天 ランキング:スマートフォン】




このサイトはフリーソフトのMerge HTMLで作成されています。
このサイトはリンクフリーです。

ページの先頭に戻る Copyright© 2010-2015 Jun.Shiozaki All rights reserved.