以下に、プリンター名とドライバーを抽出する方法を示します。重要なのは、hDevNamesで GlobalLock を実行し、Marshal.PtrToStructureをstructの CLR バージョンに入れ、そのコンテンツにアクセスすることです。完了したら GlobalUnlockを忘れないでください。
プリンターのメトリックとセットアップに関する情報を取得する hDevMode で同様のことを行うことができます。ここでDEVMODE構造体の C# 宣言を見つけることができます。
using System;
using System.Runtime.InteropServices;
namespace ConsoleApplication3 {
class Program {
// Win32 struct declarations
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 1)]
[System.Runtime.InteropServices.ComVisible(false)]
internal class PRINTDLG {
public Int32 lStructSize;
public IntPtr hwndOwner;
public IntPtr hDevMode;
public IntPtr hDevNames;
public IntPtr hDC = IntPtr.Zero;
public Int32 Flags;
public Int16 FromPage = 0;
public Int16 ToPage = 0;
public Int16 MinPage = 0;
public Int16 MaxPage = 0;
public Int16 Copies = 0;
public IntPtr hInstance = IntPtr.Zero;
public IntPtr lCustData = IntPtr.Zero;
public IntPtr lpfnPrintHook;
public IntPtr lpfnSetupHook = IntPtr.Zero;
public IntPtr lpPrintTemplateName = IntPtr.Zero;
public IntPtr lpSetupTemplateName = IntPtr.Zero;
public IntPtr hPrintTemplate = IntPtr.Zero;
public IntPtr hSetupTemplate = IntPtr.Zero;
}
[StructLayout(LayoutKind.Sequential)]
public class DEVNAMES {
public short wDriverOffset;
public short wDeviceOffset;
public short wOutputOffset;
public short wDefault;
}
// import PrintDlg, GlobalLock and GlobalUnlock
[DllImport("comdlg32.dll", CharSet = CharSet.Auto)]
private static extern bool PrintDlg([In, Out] PRINTDLG lppd);
[DllImport("kernel32.dll")]
private static extern IntPtr GlobalLock(IntPtr hMem);
[DllImport("kernel32.dll")]
private static extern bool GlobalUnlock(IntPtr hMem);
static void Main(string[] args) {
// show the printer dialog box
PRINTDLG pd = new PRINTDLG();
pd.lStructSize = Marshal.SizeOf(pd);
PrintDlg(pd);
// here's the meat -- extract the printer information
// out of pd.hDevNames...
DEVNAMES devNames = new DEVNAMES();
// lock hDevNames into memory and get a pointer to it
IntPtr pDevNames = GlobalLock(pd.hDevNames);
// marshal into a DEVNAME struct
Marshal.PtrToStructure(pDevNames, devNames);
// pull out the device and driver strings; hopefully not much of
// that in DEVMODE
string sDevice = Marshal.PtrToStringUni((IntPtr) (
pDevNames.ToInt32() +
devNames.wDeviceOffset * Marshal.SystemDefaultCharSize));
string sDriver = Marshal.PtrToStringUni((IntPtr) (
pDevNames.ToInt32() +
devNames.wDriverOffset * Marshal.SystemDefaultCharSize));
string sOutput = Marshal.PtrToStringUni((IntPtr) (
pDevNames.ToInt32() +
devNames.wOutputOffset * Marshal.SystemDefaultCharSize));
// done -- release the global memory handle
GlobalUnlock(pd.hDevNames);
}
}
}