C#  •  Retrieve the Margins With P/Invoke

Listing 3. The .NET Framework doesn't provide a way to retrieve the hard margins of a printer, so you need to use P/Invoke and call the Win32 GetDeviceCaps function. The method in this class takes a device handle (hDc), then populates the class members with the information you need.

[DllImport("gdi32.dll")]
private static extern Int16 GetDeviceCaps([In] 
   [MarshalAs 
   (UnmanagedType.U4)] int hDc, [In] [MarshalAs 
   (UnmanagedType.U2)] Int16 funct);
private float _leftMargin = 0;
private float _topMargin = 0;
private float _rightMargin = 0;
private float _bottomMargin = 0;
const short HORZSIZE      = 4;
const short VERTSIZE      = 6;
const short HORZRES       = 8;
const short VERTRES       = 10;
const short PHYSICALOFFSETX = 112;
const short PHYSICALOFFSETY = 113;
public marginInfo(int deviceHandle) {
   float offx = Convert.ToSingle(
      GetDeviceCaps(deviceHandle, 
      PHYSICALOFFSETX));
   float offy = Convert.ToSingle(
      GetDeviceCaps(deviceHandle, 
      PHYSICALOFFSETY));
   float resx = Convert.ToSingle(
      GetDeviceCaps(deviceHandle, HORZRES));
   float resy = Convert.ToSingle(
      GetDeviceCaps(deviceHandle, VERTRES));
   float hsz = Convert.ToSingle(
      GetDeviceCaps(deviceHandle, HORZSIZE))/25.4f;
   float vsz = Convert.ToSingle(
      GetDeviceCaps(deviceHandle,VERTSIZE))/25.4f;
   float ppix = resx/hsz;
   float ppiy = resy/vsz;
   _leftMargin  = (offx/ppix) * 100.0f;
   _topMargin   = (offy/ppix) * 100.0f;
   _bottomMargin  = _topMargin + (vsz * 100.0f);
   _rightMargin  = _leftMargin + (hsz * 100.0f);
}