首页 > 解决方案 > 如何在 C# 中确定 DM_OUT_BUFFER 的值

问题描述

我正在用 C# 打印文本框的输出。为此,我使用原始打印。但是,在发送要打印的文本之前,使用WritePrinter

[DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, Int32 dwCount, out Int32 dwWritten);

我想将设备结构修改为横向模式。

我可以执行第一个DocumentProperties调用,因为它返回将由pDevMode.

IntPtr pDevMode;
.
.
.
int dwNeeded = DocumentProperties(GetForegroundWindow(),
    hPrinter,       /* Handle to our printer. */
    szPrinterName,        /* Name of the printer. */
    IntPtr.Zero,           /* Asking for size, so */
    IntPtr.Zero,           /* these are not used. */
    0);             /* Zero returns buffer size. */

pDevMode = new IntPtr(dwNeeded);

但是,对DocumentProperties的第二次调用既需要一个指向设备信息块的指针,也需要一个常量DM_OUT_BUFFER来告诉函数将设备信息写入设备信息块,由pDevMode.

如何DM_OUT_BUFFER从 C# 访问值?我已经阅读了很多文章,但没有遇到任何可以说明这一点的文章。

WinAPI下面列出了大部分完整的原始打印函数,不包括不能从 C# 直接访问的函数所需的 DLL 。

这个例子工作正常,除了它发送文档纵向模式,即使打印机默认为横向模式。

   static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);

    // SendBytesToPrinter()
    // When the function is given a printer name and an unmanaged array
    // of bytes, the function sends those bytes to the print queue.
    // Returns true on success, false on failure.
    public static bool SendBytesToPrinter(string szPrinterName, IntPtr pBytes, Int32 dwCount)
    {
        Int32 dwError = 0, dwWritten = 0;
        IntPtr hPrinter = new IntPtr(0);
        DOCINFOA di = new DOCINFOA();
        IntPtr pDevMode;
        bool bSuccess = false; // Assume failure unless you specifically succeed.

        di.pDocName = "My C#.NET RAW Document";
        di.pDataType = "RAW";

        // Open the printer.
        if (OpenPrinter(szPrinterName.Normalize(), out hPrinter, IntPtr.Zero))
        {
            if (StartDocPrinter(hPrinter, 1, di))
            {
                // Start a page.
                if (StartPagePrinter(hPrinter))
                {
                    // Write your bytes.
                    bSuccess = WritePrinter(hPrinter, pBytes, dwCount, out dwWritten);
                    EndPagePrinter(hPrinter);
                }
                EndDocPrinter(hPrinter);
            }
            ClosePrinter(hPrinter);
        }
        // If you did not succeed, GetLastError may give more information
        // about why not.
        if (bSuccess == false)
        {
            dwError = Marshal.GetLastWin32Error();
        }
        return bSuccess;
    }

标签: c#winapilandscapeportraitprint-spooler-api

解决方案


该常量在 windows api 中定义,您可以使用 pinvoke.net 中的以下 pinvoke 定义:https ://www.pinvoke.net/default.aspx/Enums.fModes

[Flags]
internal enum fModes
{
   /// <summary>
   /// When used, the DocumentProperties function returns the number
   /// of bytes required by the printer driver's DEVMODE data structure.
   /// </summary>
   DM_SIZEOF = 0,

   /// <summary>
   /// <see cref="DM_OUT_DEFAULT"/>
   /// </summary>
   DM_UPDATE = 1,

   /// <summary>
   /// <see cref="DM_OUT_BUFFER"/>
   /// </summary>
   DM_COPY = 2,

   /// <summary>
   /// <see cref="DM_IN_PROMPT"/>
   /// </summary>
   DM_PROMPT = 4,

   /// <summary>
   /// <see cref="DM_IN_BUFFER"/>
   /// </summary>
   DM_MODIFY = 8,

   /// <summary>
   /// No description available.
   /// </summary>
   DM_OUT_DEFAULT = DM_UPDATE,

   /// <summary>
   /// Output value. The function writes the printer driver's current print settings,
   /// including private data, to the DEVMODE data structure specified by the 
   /// pDevModeOutput parameter. The caller must allocate a buffer sufficiently large
   /// to contain the information. 
   /// If the bit DM_OUT_BUFFER sets is clear, the pDevModeOutput parameter can be NULL.
   /// This value is also defined as <see cref="DM_COPY"/>.
   /// </summary>
   DM_OUT_BUFFER = DM_COPY,

   /// <summary>
   /// Input value. The function presents the printer driver's Print Setup property
   /// sheet and then changes the settings in the printer's DEVMODE data structure
   /// to those values specified by the user. 
   /// This value is also defined as <see cref="DM_PROMPT"/>.
   /// </summary>
   DM_IN_PROMPT = DM_PROMPT,

   /// <summary>
   /// Input value. Before prompting, copying, or updating, the function merges 
   /// the printer driver's current print settings with the settings in the DEVMODE
   /// structure specified by the pDevModeInput parameter. 
   /// The function updates the structure only for those members specified by the
   /// DEVMODE structure's dmFields member. 
   /// This value is also defined as <see cref="DM_MODIFY"/>. 
   /// In cases of conflict during the merge, the settings in the DEVMODE structure 
   /// specified by pDevModeInput override the printer driver's current print settings.
   /// </summary>
   DM_IN_BUFFER = DM_MODIFY,
}

推荐阅读