プリンタのプロパティだけを表示 (2)

あれ、なんか[id:machi_pon:20061004]にMSDNフォーラムからリンクされてました。
で、「DocumentProperties()」とかで検索してここに来る人もいるみたいなので、もう少し実験してみました(・∀・)


プリンタ設定の変更で、システム設定も変更されるようにしてみようと思ったんですが…。


とりあえず、やってみたソース。

[DllImport("winspool.drv",SetLastError=true)] 
private static extern bool OpenPrinter(string pPrinterName, out IntPtr phPrinter, IntPtr pDefault);

[DllImport("winspool.drv", SetLastError=true)]
private static extern int ClosePrinter(IntPtr hPrinter);  

[DllImport("winspool.drv", EntryPoint="GetPrinter", SetLastError=true, CallingConvention=CallingConvention.StdCall)]
private static extern bool GetPrinter(IntPtr hPrinter, uint dwLevel, IntPtr pPrinter, uint dwBuf, out uint dwNeeded);

[DllImport("winspool.drv", EntryPoint="SetPrinter", SetLastError=true, CallingConvention=CallingConvention.StdCall)]
private static extern bool SetPrinter(IntPtr hPrinter, uint dwLevel, IntPtr pPrinter, uint Command);

[DllImport("winspool.drv", EntryPoint="DocumentPropertiesW", SetLastError=true, ExactSpelling=true, CallingConvention=CallingConvention.StdCall)]
private static extern int DocumentProperties(IntPtr hwnd, IntPtr hPrinter, [MarshalAs(UnmanagedType.LPWStr)] string pDeviceName, IntPtr pDevModeOutput, IntPtr pDevModeInput, int fMode);
[StructLayout(LayoutKind.Sequential)]
private struct PRINTER_INFO_2
{
    [MarshalAs(UnmanagedType.LPStr)] public string pServerName; 
    [MarshalAs(UnmanagedType.LPStr)] public string pPrinterName; 
    [MarshalAs(UnmanagedType.LPStr)] public string pShareName; 
    [MarshalAs(UnmanagedType.LPStr)] public string pPortName; 
    [MarshalAs(UnmanagedType.LPStr)] public string pDriverName; 
    [MarshalAs(UnmanagedType.LPStr)] public string pComment; 
    [MarshalAs(UnmanagedType.LPStr)] public string pLocation; 
    public IntPtr pDevMode; 
    [MarshalAs(UnmanagedType.LPStr)] public string pSepFile; 
    [MarshalAs(UnmanagedType.LPStr)] public string pPrintProcessor; 
    [MarshalAs(UnmanagedType.LPStr)] public string pDatatype; 
    [MarshalAs(UnmanagedType.LPStr)] public string pParameters; 
    public IntPtr pSecurityDescriptor; 
    public Int32 Attributes; 
    public Int32 Priority; 
    public Int32 DefaultPriority; 
    public Int32 StartTime; 
    public Int32 UntilTime; 
    public Int32 Status; 
    public Int32 cJobs; 
    public Int32 AveragePPM; 
}
public static bool ShowProperties(IntPtr hwnd, string printer)
{
    IntPtr hPrt = IntPtr.Zero;

    if ( OpenPrinter( printer, out hPrt, IntPtr.Zero ) == false )
    {
       return( false );
    }
    if ( hPrt == IntPtr.Zero )
    {
        return( false );
    }

    uint need;
    GetPrinter( hPrt, 2, IntPtr.Zero, 0, out need );
    if ( need == 0 )
    {
        return( false );
    }

    IntPtr pPrinterInfo = IntPtr.Zero;
    try
    {
        pPrinterInfo = Marshal.AllocHGlobal( (int)need );

        if ( GetPrinter( hPrt, 2, pPrinterInfo, need, out need ) == false )
        {
            return( false );
        }

        PRINTER_INFO_2 pinfo = (PRINTER_INFO_2)Marshal.PtrToStructure( pPrinterInfo, typeof(PRINTER_INFO_2) );

        int ret = DocumentProperties( hwnd, hPrt, printer, pinfo.pDevMode, pinfo.pDevMode, 14 );
        if ( ret == 1 )
        {
            Marshal.StructureToPtr( pinfo, pPrinterInfo, true );

            SetPrinter( hPrt, 2, pPrinterInfo, 0 );
        }
    }
    finally
    {
        if ( pPrinterInfo != IntPtr.Zero )
        {
            Marshal.FreeHGlobal( pPrinterInfo );
        }
    }

    return( true );
}

なんかね、これでやってみたんだけどSetPrinter()でfalseが返って来ちゃう(´・ω・`)
でも、プリンタによっては変更が反映されていることもあったりして(設定が反映されないものもある…)。
Marshal.GetLastWin32Error()してみると6、(ERROR_INVALID_HANDLE)が返ってくるんですが、さて。


ちなみに参考にした情報はこのへんです。
http://support.microsoft.com/default.aspx?scid=kb;ja;140285


なんか間違いに気がついた人は教えてくださいな(´ω`)