下面显示如何提取打印机名称和驱动程序。关键是在hDevNames上做一个GlobalLock , Marshal.PtrToStructure把它变成CLR版本的struct,然后访问它的内容。完成后记得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);
}
}
}