DocumentProperties API

B

bluf2000

Hello csharp professionlals.
I have a problem: my application has to handle with DocumentProperties
API. The application is coded in C#.
It works fine, the DocumentProperties appears, after that the devmode
Structure seems corectly updated, but at last DocumentProperties call
(when it should update the setings), the DEVMODE structure has the
settings from the initial call (seems that DocumentProperties discards
the changes).
Please, if u could tell me what's wrong...
I will post the code too.
this is the class that handles the function ShowDocProps that should
change the document properties:


using System;
using System.Runtime.InteropServices;
using System.Drawing.Printing;
namespace Drag_drop
{
/// <summary>
/// Summary description for CPrinter.
/// </summary>
///
unsafe struct PRINTER_DEFAULTS
{
public void * pDatatype; // LPTSTR
public void * pDevMode; // LPDEVMODE
public uint DesiredAccess; // ACCESS_MASK
};




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,
}


public class CPrinter
{
PrintDocument pdoc = new PrintDocument();

#region DEVMODE
private const short CCDEVICENAME = 32;
private const short CCFORMNAME = 32;

[StructLayout(LayoutKind.Sequential)]
public struct DEVMODE
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCDEVICENAME)]
public string dmDeviceName;

public short dmSpecVersion;
public short dmDriverVersion;
public short dmSize;
public short dmDriverExtra;
public int dmFields;
public short dmOrientation;
public short dmPaperSize;
public short dmPaperLength;
public short dmPaperWidth;
public short dmScale;
public short dmCopies;
public short dmDefaultSource;
public short dmPrintQuality;
public short dmColor;
public short dmDuplex;
public short dmYResolution;
public short dmTTOption;
public short dmCollate;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCFORMNAME)]
public string dmFormName;

public short dmUnusedPadding;
public short dmBitsPerPel;
public int dmPelsWidth;
public int dmPelsHeight;
public int dmDisplayFlags;
public int dmDisplayFrequency;
}
#endregion


#region dllimport

[DllImport("kernel32.dll")]
private static extern IntPtr GlobalLock(IntPtr hMem);
[DllImport("kernel32.dll")]
private static extern bool GlobalUnlock(IntPtr hMem);
[DllImport("kernel32.dll")]
private static extern UIntPtr GlobalSize(IntPtr hMem);

[DllImport("winspool.Drv", EntryPoint="GetPrinterA",
SetLastError=true, CharSet=CharSet.Ansi,ExactSpelling=true,
CallingConvention=CallingConvention.StdCall)]
public static extern bool GetPrinter(int hPrinter, Int32 dwLevel,
IntPtr pPrinter, Int32 dwBuf, out Int32 dwNeeded);

[DllImport("kernel32", SetLastError=true)]
static extern int GetLastError();

[DllImport("WinSpool.drv", SetLastError=true)]
static extern unsafe bool OpenPrinter
(string pPrinterName, int * phPrinter, void * pDefault);

[DllImport("WinSpool.drv", SetLastError=true)]
static extern bool ClosePrinter(int hPrinter);

[DllImport("WinSpool.drv",SetLastError=true)]
static extern unsafe bool SetPrinter
(int hPrinter, uint Level, void * pPrinter, uint Command);
[DllImport("WinSpool.drv",SetLastError=true)]
static extern unsafe bool PrinterProperties
(IntPtr hWnd, int hPrinter);
[DllImport("WinSpool.drv",SetLastError=true)]
static extern unsafe int DocumentProperties
(IntPtr hWnd, int hPrinter, string pDeviceName,
IntPtr pDevModeOutput, IntPtr pDevModeInput,
int fMode );

#endregion

#region ForUnsafeTypes
const int STANDARD_RIGHTS_REQUIRED = 0xF0000;
const uint PRINTER_ACCESS_USE = 0x00000008;
const uint PRINTER_ACCESS_ADMINISTER = 0x00000004;
const uint PRINTER_STATUS_OFFLINE = 0x00000080;
const uint PRINTER_CONTROL_PAUSE = 1;
const uint PRINTER_CONTROL_RESUME = 2;
const uint PRINTER_CONTROL_PURGE = 3;
const uint PRINTER_CONTROL_SET_STATUS = 4;

#endregion

private Form1 owner;
public CPrinter( Form1 frm )
{
this.owner = frm;
//
// TODO: Add constructor logic here
//
}
public static unsafe int CSOpenPrinter(string printerName)
{
bool bResult;


int hPrinter2;
PRINTER_DEFAULTS pd;

pd.pDatatype = null;
pd.pDevMode = null;
pd.DesiredAccess = PRINTER_ACCESS_USE;

bResult = OpenPrinter(printerName, &hPrinter2, &pd);
if (!bResult)
{
throw new ApplicationException("Cannot open printer '" +
printerName + "' " +
Marshal.GetLastWin32Error());
}
return hPrinter2;
}
// Close the printer.
static void CSClosePrinter(int hPrinter)
{
if (!ClosePrinter(hPrinter))
{
throw new ApplicationException("Cannot close printer " +
Marshal.GetLastWin32Error());
}
}


public unsafe void ShowDocProps(string PrinterName)
{
DEVMODE dm = new DEVMODE();


Int32 level = 2;
Int32 Needed = 0;

IntPtr pPrinter = new IntPtr(0);
PRINTER_INFO_2 pi = new PRINTER_INFO_2();

PRINTER_DEFAULTS pd;
IntPtr iOldDev = pdoc.PrinterSettings.GetHdevmode();
pd.pDatatype = null;
pd.pDevMode = null;
pd.DesiredAccess = STANDARD_RIGHTS_REQUIRED;

iOldDev = pdoc.PrinterSettings.GetHdevmode();

int hPrinter;
PRINTER_INFO_2 pLocal = new PRINTER_INFO_2();
if( OpenPrinter( PrinterName, &hPrinter, &pd ) )
{
// Get printer level page size needed - first call
if (GetPrinter(hPrinter, level, pPrinter, 0, out Needed) == false)
{
IntPtr pBytes = Marshal.AllocCoTaskMem(Needed); // Alloc
GetPrinter(hPrinter, level, pBytes, Needed, out Needed);
Marshal.PtrToStructure(pBytes, pi);
IntPtr iDevModeNew = GlobalLock(iOldDev);
int xSet = 0;

int x = DocumentProperties(owner.Handle, hPrinter, PrinterName,
iDevModeNew, iDevModeNew, (int)DevModeOption.DM_OUT_BUFFER
|(int)DevModeOption.DM_PROMPT);
DEVMODE d2 = (DEVMODE) Marshal.PtrToStructure(iDevModeNew,
typeof(DEVMODE));
if (x != 0)
{
//iDevModeNew = IntPtr.Zero;
Marshal.StructureToPtr(d2, iDevModeNew, true);
d2 = (DEVMODE) Marshal.PtrToStructure(iDevModeNew, typeof(DEVMODE));
pdoc.PrinterSettings.SetHdevmode(iDevModeNew);
x = DocumentProperties(IntPtr.Zero, hPrinter, PrinterName,
iDevModeNew, iDevModeNew, (int)DevModeOption.DM_IN_BUFFER |
(int)DevModeOption.DM_OUT_BUFFER);
//it seems that the changes are discarded
d2 = (DEVMODE) Marshal.PtrToStructure(iDevModeNew, typeof(DEVMODE));

}


GlobalUnlock(iOldDev);
CSClosePrinter(hPrinter);

// Marshal.FreeCoTaskMem(iOldDev);
}
}

}

}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top