请勿使用AIGC类型回答,鄙人会用AI;AIGC类型回答一律不采纳;不要™用AIGC回答
这个问题已近困扰了我快一个月,每次都是爬虫回答我的问题,搞得我有些愤怒,不要使用ChatGPT回答我的问题,我会用CharGPT;
问题简述:我是用GlobalAlloc()和GlobalLock()进行内存操作之后,在Intptr传入SetHdevmode()之后导致DEVMODE参数与外部的DEVMODE结构体值不同;
目前已经解决,发现SetHdevmode()没有办法有效的修改额外参数的值,打算使用C++写dll提供C#调用
代码如下:
[StructLayout(LayoutKind.Sequential)]
public struct DEVMODE
{
const int CCHDEVICENAME = (32 * 2);
const int CCHFORMNAME = (32 * 2);
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCHDEVICENAME)]
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 = CCHFORMNAME)]
public string dmFormName;
public short dmUnusedPadding;
public short dmBitsPerPel;
public int dmPelsWidth;
public int dmPelsHeight;
public int dmDisplayFlags;
public int dmDisplayFrequency;
public int dmICMMethod;
public int dmICMIntent;
public int dmMediaType;
public int dmDitherType;
public int dmICCManufacturer;
public int dmICCModel;
public int dmPanningWidth;
public int dmPanningHeight;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1024)]
public int[] ExDevMode;
}
/// <summary>
/// 读取初始配置
/// </summary>
private void GetDevMode()
{
IntPtr printerSlef = IntPtr.Zero;
int n = 0;
// 空默认不使用
IntPtr temp = new IntPtr();
try
{
if (!FunctionClass.OpenPrinter(printName, out printerSlef, 0))
{
throw new Exception("Cannot open printer");
}
// 正式获取结构体
GetDevModPtr(out devModePtr, printerSlef);
GetDevMode(devModePtr, out dm, printerSlef);
// 获取额外配置项的起始位
while (true)
{
if (dm.ExDevMode[n] == DevModeCode.EX_DEV_SIGN)
{
DevModeCode.ExDevTop = n - 1;
break;
}
if (n >= DevModeCode.EX_DEV_SIZE)
{
break;
}
n++;
}
}
finally
{
FunctionClass.ClosePrinter(printerSlef);
}
}
/// <summary>
/// 设置打印机
/// </summary>
public void SettingPrint(PrinterSet printerSet)
{
try
{
dm = Marshal.PtrToStructure<DEVMODE>(devModePtr);
// 修改内容
dm.ExDevMode[DevModeCode.ExDevTop + DevModeCode.ExCut2inch] = printerSet.Cut2inch;
// 将修改之后dm同步内存
Marshal.StructureToPtr(dm, devModePtr, true);
pd.PrinterSettings.SetHdevmode(devModePtr);
}
finally
{
GCFunction.GlobalFree(devModePtr);
}
}
/// <summary>
/// 手动获取DEVMOD指针
/// </summary>
/// <param name="devModePtr"> 等待分配的指针 </param>
/// <exception cref="Exception"></exception>
public void GetDevModPtr(out IntPtr devModePtr,IntPtr printerSlef)
{
// 空默认不使用
IntPtr tempNull = new IntPtr(), hDevMode;
int devSize;
devSize = FunctionClass.DocumentProperties(IntPtr.Zero, printerSlef, printName, tempNull, ref tempNull, 0);
// 是否获取成功
if (devSize <= 0)
{
throw new Exception("Cannot get DevMode Intptr");
}
// 分配内存大小
hDevMode = GCFunction.GlobalAlloc(DevModeCode.GHND, devSize);
devModePtr = GCFunction.GlobalLock(hDevMode);
}
/// <summary>
/// 手动获取DevMod内容
/// </summary>
/// <param name="devModePtr"> 已被分配内存的指针 </param>
/// <param name="dm"> 回传结构体 </param>
/// <exception cref="Exception"></exception>
public void GetDevMode(IntPtr devModePtr, out DEVMODE dm, IntPtr printerSlef)
{
IntPtr tempNull = IntPtr.Zero;
int resultCode;
// 再次访问获取实际数据
resultCode = FunctionClass.DocumentProperties(0, printerSlef, printName, devModePtr, ref tempNull, DevModeCode.DM_OUT_BUFFER);
if (resultCode < 0)
{
GCFunction.GlobalFree(devModePtr);
throw new Exception("Cannot get DevMode"); ;
}
dm = Marshal.PtrToStructure<DEVMODE>(devModePtr);
}