Изменить настройки принтера функцией DocumentProperties
От: Весельчак У  
Дата: 08.12.10 16:14
Оценка:
Добрый день!

Я пишу программку на C#, задача которой — изменение настроек принтера с помощью функции WinAPI DocumentProperties. Точнее, я хочу изменить приватные настройки драйвера принтера, путем изменения битового содержимого памяти, полученного при считывании настроек.

Вот код, который я использую:


 public enum DevModeOption
 {
  DM_UPDATE = 1,
  DM_COPY = 2,
  DM_PROMPT = 4,
  DM_MODIFY = 8,
  DM_IN_BUFFER = DM_MODIFY,
  DM_IN_PROMPT = DM_PROMPT,
  DM_OUT_BUFFER = DM_COPY,
  DM_OUT_DEFAULT = DM_UPDATE,
 }

  [DllImport("WinSpool.drv", EntryPoint = "DocumentPropertiesA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]  
static extern unsafe int DocumentProperties(IntPtr hWnd, IntPtr hPrinter, [MarshalAs(UnmanagedType.LPStr)] string pDeviceName, 
    IntPtr pDevModeOutput, IntPtr pDevModeInput, int fMode);


    public void SetPrinterData(IntPtr formHandle, string PrinterName, List<DifferByteInfo> differBytes)
    {
      PrinterSettings psSettings = new PrinterSettings();
      psSettings.PrinterName = PrinterName;

      IntPtr ipDevMode = psSettings.GetHdevmode(psSettings.DefaultPageSettings);
      IntPtr pDevMode = GlobalLock(ipDevMode);
      IntPtr ipDevModeData = Marshal.AllocHGlobal(0);
      try
      {
        int nSize = DocumentProperties(formHandle, IntPtr.Zero, psSettings.PrinterName, pDevMode, pDevMode, 0);
        ipDevModeData = Marshal.AllocHGlobal(nSize);
        DocumentProperties(formHandle, IntPtr.Zero, psSettings.PrinterName, ipDevModeData, pDevMode,
                  (int)DevModeOption.DM_OUT_BUFFER);
        DEVMODE d2 = (DEVMODE)Marshal.PtrToStructure(ipDevModeData, typeof(DEVMODE));

        foreach (DifferByteInfo b in differBytes)
        {
          Marshal.WriteByte(ipDevModeData, d2.dmSize + b.index, b.value);  
        }
        
        //DocumentProperties(formHandle, IntPtr.Zero, psSettings.PrinterName, IntPtr.Zero, ipDevModeData,(int)DevModeOption.DM_MODIFY);
        //DocumentProperties(formHandle, IntPtr.Zero, psSettings.PrinterName, ipDevModeData, ipDevModeData,
        //          (int) DevModeOption.DM_IN_BUFFER + (int) DevModeOption.DM_OUT_BUFFER);
        DocumentProperties(formHandle, IntPtr.Zero, psSettings.PrinterName, IntPtr.Zero, ipDevModeData, (int)DevModeOption.DM_IN_BUFFER);

        GlobalUnlock(ipDevMode);
      }
      finally
      {
        GlobalFree(ipDevMode);
        Marshal.FreeHGlobal(ipDevModeData);
      }
    }



К сожалению он не работает. Подскажите, пожалуйста, в чем может быть дело?

С уважением, Николай.
documentproperties печать принтер c# winapi драйвер
Re: Изменить настройки принтера функцией DocumentProperties
От: krushon Россия  
Дата: 06.01.11 01:52
Оценка:
Думаю, решение уже нашлось. Но т.к. я тоже с этим провел почти весь день, и начинал я с Ваших набросок, вот что у меня получилось.
Пришлось всеже использовать SetPrinter. Может кто еще сюда заглянет, подскажет другой метод.
        private uint PRINTER_ALL_ACCESS = 0x00000004 | 0x00000008;
...........
.........
.......
..........

        private unsafe void button2_Click(object sender, EventArgs e)
        {
            PrinterDefaults pd = new PrinterDefaults();
            pd.pDatatype = UIntPtr.Zero;
            pd.pDevMode = UIntPtr.Zero;
            pd.DesiredAccess = PRINTER_ALL_ACCESS;
            PrinterSettings.StringCollection printers = PrinterSettings.InstalledPrinters;
            PrinterSettings ps = new PrinterSettings();
            ps.PrinterName = printers[3];
            IntPtr printerHandle;
            bool result = OpenPrinter(printers[3], out printerHandle,ref pd);

            IntPtr prS;
            int hDEVMODE = DocumentProperties(this.Handle, printerHandle, printers[3], IntPtr.Zero, IntPtr.Zero, 0);

            prS = GlobalAlloc(0, hDEVMODE);
            IntPtr pDEVMODE = GlobalLock(prS);


            int dwRet = DocumentProperties(this.Handle,
             printerHandle,
             printers[3],
             pDEVMODE, 
             IntPtr.Zero, 
             2|4); 
            PrinterSettings nPS;

            if (dwRet < 0)
            {
                GlobalUnlock(pDEVMODE);
                GlobalFree(prS);
                ClosePrinter(printerHandle);
                return;
            }
            else
            {
                nPS = new PrinterSettings();
                nPS.SetHdevmode(pDEVMODE);
            }

            GlobalUnlock(pDEVMODE);
            GlobalFree(prS);

            Byte* b = (Byte*)nPS.GetHdevmode();
            bool r = SetPrinter(printerHandle, 8, b, 0);

            ClosePrinter(printerHandle);
            GlobalFree((IntPtr)b);

        }

    }
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.