Hey Jack,
As always, thanks for your help. I figured it out. It involves accessing the Win32 API, my first experience with unmanaged code from .NET. I'll list the code at the end of this post. Sorry it's in C# but it will be good conversion practice for you if you need the routine.

The general idea is that the method (GetDeviceCaps) in the dll (gid32.dll) that gets the unprintable margin values from a printer can be called using the IneropServices assembly. You have to define constants so the GetDeviceCaps method knows what values to return. After prototyping the Win32 API method you can call it from your managed .NET code. The biggest stumbling block for me was figuring out that the graphics object would return the handle to the device context so I could pass that to the method. I just kind of stumbled around in the code and intellisense until I figured that out. The return value is in printer units so it must be divided by the printer resolution to know the value of the unprintable margin.
Take care and thanks again.
Here's the code:
// Reference InteropServices;
using System.Runtime.InteropServices;
// define constants for the physical offset values
private const int PHYSICALOFFSETX = 112;
private const int PHYSICALOFFSETY = 113;
// Define DLL and prototype the Win32 API method
[DllImport("gdi32"

]
public static extern int GetDeviceCaps(IntPtr hdc, int cap);
// get the device context handle from the graphic object that is being printed
// call GetDeviceCaps to return the offsets
// release the handle to the device context
int unprintableleft, unprintabletop;
IntPtr hdc;
hdc = e.Graphics.GetHdc();
unprintableleft = GetDeviceCaps(hdc,PHYSICALOFFSETX);
unprintabletop = GetDeviceCaps(hdc,PHYSICALOFFSETY);
e.Graphics.ReleaseHdc(hdc);
MessageBox.Show("Unprintable: " + unprintableleft + " " + unprintabletop);