2

以下のページによると:

http://msdn.microsoft.com/en-us/library/ms646964(VS.85).aspx

最初のグラフィックの下に、「ユーザーが [OK] ボタンをクリックすると、PrintDlg は TRUE を返し、PRINTDLG 構造体はユーザーの選択に関する情報を返します」。

この場合、カスタム印刷ダイアログはほとんど機能していますが、プリンター名、向きなどの情報を抽出しようとしています...私の理解では、プリンター名を取得するには、hDevMode 値を調べる必要があります。 PRINTDLG 構造体からプリンター名を確認します。その情報を抽出できる機能はありますか?

私のコードは次のようになります (pdlg は PRINTDLG 構造体の定義済みインスタンスです):

        bool f = false;
        try
        {
            f = PrintDlg(ref pdlg);
            DEVMODE dm = pdlg.hDevMode;
            int k = 0;
        } catch (Exception ex) 
        {
            // hopefully it doesn't fail
        } 

誰かが知恵の真珠を持っている場合は、ヒントをいただければ幸いです。

4

1 に答える 1

3

以下に、プリンター名とドライバーを抽出する方法を示します。重要なのは、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);
        }
    }
}
于 2009-07-09T01:15:26.873 に答える