C# 自定义 PrintDialog PInvoke DevMode 问题

发布于 2024-07-26 06:27:35 字数 746 浏览 1 评论 0原文

根据以下页面:

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

在第一个图形下方,“如果用户单击“确定”按钮,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
        } 

如果有人有任何智慧的珍珠,我肯定会感激任何提示。

According to the following page:

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

underneath the first graphic, "If the user clicks the OK button, PrintDlg returns TRUE and the PRINTDLG structure to return informmation about the user's selection".

In this case, my custom print dialog is nearly working, but I'm trying to extract the information about printer name, orientation, etc... My understanding is that in order to retrieve the printer name, I need to examine the hDevMode value from the PRINTDLG structure to see the printer name. Is there a function that will allow me to extract that info?

My code is like (where pdlg is my defined instance of the PRINTDLG structure):

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

If someone has any pearlsof wisdom out there, I would sure appreciate any tips.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

话少情深 2024-08-02 06:27:35

下面显示如何提取打印机名称和驱动程序。 关键是对 hDevNames 执行 GlobalLockMarshal.PtrToStructure 将其转换为 CLR 版本的struct,然后访问其内容。 完成后请记住全局解锁

您可以使用 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);
        }
    }
}

The following shows how to extract the printer name and driver. The key is to do a GlobalLock on hDevNames, Marshal.PtrToStructure it into the CLR version of the struct, and then access its content. Remember to GlobalUnlock when done.

You could do something similar with hDevMode, which will get you information about the printer metrics and setup. You can find a C# declaration of the DEVMODE struct here.

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);
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文