tags:

views:

253

answers:

1

I'm using Visual Studio 2010 to create a Word Template. I created a Ribbon with to buttons: print in color, print in B&W. I use the Document.printout() function to print the document.

How can I set the printer to Grayscale printing from code?

I don't want to use the printDialog.

I tried to use this:
PrinterSettings settings = new PrinterSettings();
settings.DefaultPageSettings.Color = false;

But this doesn't work in combination with Word

A: 

I Found a solution with the DEVMODE and some pInvokes;

Devmode: (http://msdn.microsoft.com/en-us/library/aa927408.aspx) This structure contains information about a printer environment and device initialization.

It contains a field: dmColor (short) setting this to 1 means grayscale/monoschrome, settings this to 2 means color. Changing this settings effects the printer directly and overrides user settings.

[DllImport("winspool.drv", CharSet = CharSet.Ansi, SetLastError = true)]
private static extern bool SetPrinter(IntPtr hPrinter, int Level, IntPtr pPrinter, int command);

I used this example to create my code

public bool setPrinterToGrayScale(string printerName) 
{
  short monochroom = 1;
  dm = this.GetPrinterSettings(printerName);
  dm.dmColor = monochroom;

  Marshal.StructureToPtr(dm, yDevModeData, true);
  pinfo.pDevMode = yDevModeData;
  pinfo.pSecurityDescriptor = IntPtr.Zero;

  Marshal.StructureToPtr(pinfo, ptrPrinterInfo, true);
  lastError = Marshal.GetLastWin32Error();

  nRet = Convert.ToInt16(SetPrinter(hPrinter, 2, ptrPrinterInfo, 0));
  if (nRet == 0)
  {
    //Unable to set shared printer settings.

    lastError = Marshal.GetLastWin32Error();
    //string myErrMsg = GetErrorMessage(lastError);

    throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());

   }
   if (hPrinter != IntPtr.Zero)
      ClosePrinter(hPrinter);
    return Convert.ToBoolean(nRet);
}

PrinterName can be retrieved via:
System.Drawing.Printing.PrinterSettings.InstalledPrinters

wasigh