110,571
社区成员
发帖
与我相关
我的任务
分享
BOOL CMyView::OnPreparePrinting(CPrintInfo* pInfo)
{
PRINTDLG rPD;
BOOL fRet= AfxGetApp()->GetPrinterDeviceDefaults( &rPD );
LPDEVMODE pDM= (LPDEVMODE)::GlobalLock( rPD.hDevMode );
PBYTE pbDriverData= (PBYTE)(((BYTE *)pDM)+(pDM->dmSize));// right after the end
pbDriverData[24]= 2; // set to 4-up (1=2-up, 3=6-up, etc.)
::GlobalUnlock( rPD.hDevMode );
// default handling (as added by the ClassWizard)
return( DoPreparePrinting(pInfo) );
}
var dialog = new PrintDialog();
var hDevMode = dialog.PrinterSettings.GetHdevmode();
var p = GlobalLock(hDevMode);
var devmode = (DEVMODE)Marshal.PtrToStructure(p, typeof(DEVMODE));
Console.WriteLine("Device Name: {0}\ndmSize: {1}\ndmDriverExtra: {2}",
devmode.dmDeviceName, devmode.dmSize, devmode.dmDriverExtra);
int len = devmode.dmDriverExtra;
var buf = new byte[len];
Marshal.Copy(p+devmode.dmSize, buf, 0, len);
GlobalUnlock(hDevMode);
dialog.ShowDialog();
var hDevMode1 = dialog.PrinterSettings.GetHdevmode();
var p1 = GlobalLock(hDevMode1);
var buf2 = new byte[len];
Marshal.Copy(p1+devmode.dmSize, buf2, 0, len);
GlobalUnlock(hDevMode1);
var changed = buf.Select((a, i) => new {i, a, b = buf2[i]}).Where(x => x.a != x.b);
Console.WriteLine("changed bytes: {0}", changed.Count());
foreach (var x in changed)
{
Console.WriteLine("offset {0}: {1} -> {2}", x.i, x.a, x.b);
}
弹出打印框后,改一下“每张纸打印页数这个参数”,看看devmode的前后变化。
const int CCHDEVICENAME = 32;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct DEVMODE
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCHDEVICENAME)]
public string dmDeviceName;
public short dmSpecVersion;
public short dmDriverVersion;
public short dmSize;
public short dmDriverExtra;
// 其余字段不用省略
}
[DllImport("kernel32.dll")]
public static extern IntPtr GlobalLock(IntPtr handle);
[DllImport("kernel32.dll")]
public static extern IntPtr GlobalUnlock(IntPtr handle);
void Print()
{
var dialog = new PrintDialog();
var hDevMode = dialog.PrinterSettings.GetHdevmode();
var p = GlobalLock(hDevMode);
var devmode = (DEVMODE)Marshal.PtrToStructure(p, typeof(DEVMODE));
p = p + devmode.dmSize + 24;
Marshal.WriteByte(p, 3);
GlobalUnlock(hDevMode);
dialog.PrinterSettings.SetHdevmode(hDevMode);
Marshal.FreeHGlobal(hDevMode);
var result = dialog.ShowDialog();
。。。
}