Six_Rabbit 2024-11-13 13:49 采纳率: 0%
浏览 11
已结题

C# 使用DEVMOD设置打印机首选项

使用DEVMOD修改打印机对应设置无法成功设置;
使用GPT或其他人工智能检索整理回答都不会采纳

/// <summary>
/// 设置打印机
/// </summary>
public void SettingPrint(PrinterSet printerSet)
{
    //dm = (DEVMODE)Marshal.PtrToStructure(devModeIntptr, typeof(DEVMODE));

    int ResultCode, n = 0;

    // 空默认不使用
    IntPtr temp = new IntPtr();

    // 获取lpDevModeDmW的大小
    DevModeSize = FunctionClass.DocumentProperties(0, printerSlef, printName, IntPtr.Zero, ref temp, 0);
    if (DevModeSize == 0)
    {
        // TODO 抛出错误
        return;
    }
    IntPtr hDevMode = GCFunction.GlobalAlloc(DevModeCode.GHND, DevModeSize);
    devModeIntptr = GCFunction.GlobalLock(hDevMode);
    //devModeIntptr = Marshal.AllocHGlobal(DevModeSize);

    // 再次访问获取实际数据
    ResultCode = FunctionClass.DocumentProperties(0, printerSlef, printName, devModeIntptr, ref temp, DevModeCode.DM_OUT_BUFFER);
    if (ResultCode < 0)
    {
        // TODO 抛出错误
        return;
    }

    GCFunction.Mem2DevCopy(out dm, devModeIntptr, DevModeSize);

    // 填写自定义配置
    dm.ExDevMode[DevModeCode.ExDevTop + DevModeCode.ExCut2inch] = printerSet.Cut2inch;

    // 将打包好的发送回打印机并且设置
    //Marshal.StructureToPtr(dm, devModeIntptr, true);
    GCFunction.Mem2DevCopy(devModeIntptr,ref dm,DevModeSize);
    GetDevMode();
    pd.PrinterSettings.SetHdevmode(devModeIntptr);
}

每次Mem2DevCopy或者StructureToPtr之后,再次获取驱动设置,打印机的值未能生效

  • 写回答

24条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-11-13 13:54
    关注

    参考免费微信小程序:皆我百晓生作答,经由专家-赤兔整理回复,如问题解决,望采纳;如仍有疑问,可评论回复,或私信深度沟通。

    在您的代码中,您尝试将内存中的设备模式结构体复制到新的设备模式指针上,并且随后调用了GetDevMode()函数来更新打印设置。但是,我发现了一个小问题:当您尝试将设备模式结构体复制到新指针时,没有正确地释放原始内存。

    为了解决这个问题,您可以先创建一个临时变量,用于存储复制后的设备模式结构体,然后再将其赋值给新的设备模式指针。这样可以确保原始内存被正确地释放,从而避免了内存泄漏的问题。

    以下是修复后的代码示例:

    /// <summary>
    /// 设置打印机
    /// </summary>
    public void SettingPrint(PrinterSet printerSet)
    {
        // 先创建一个临时变量,用于存储复制后的设备模式结构体
        DEVMODE tempDevMode = new DEVMODE();
    
        // 获取lpDevModeDmW的大小
        DevModeSize = FunctionClass.DocumentProperties(0, printerSlef, printName, IntPtr.Zero, ref tempDevMode, 0);
        if (DevModeSize == 0)
        {
            // TODO 抛出错误
            return;
        }
    
        // 尝试复制设备模式结构体到临时变量
        Marshal.Copy(devModeIntptr, tempDevMode, 0, DevModeSize);
        
        // 将临时变量的值赋值给新的设备模式指针
        IntPtr hDevMode = GCFunction.GlobalAlloc(DevModeCode.GHND, DevModeSize);
        devModeIntptr = GCFunction.GlobalLock(hDevMode);
        Marshal.StructureToPtr(tempDevMode, devModeIntptr, false);
        GCFunction.MemFree(tempDevMode); // 此处释放原始内存
        
        // 再次访问获取实际数据
        int ResultCode = FunctionClass.DocumentProperties(0, printerSlef, printName, devModeIntptr, ref tempDevMode, DevModeCode.DM_OUT_BUFFER);
        if (ResultCode < 0)
        {
            // TODO 抛出错误
            return;
        }
    
        // ... 其他代码 ...
    }
    

    这段代码首先创建了一个临时的设备模式结构体(tempDevMode),然后通过Marshal.Copy方法复制了设备模式结构体的值到这个临时结构体中。接下来,它将临时结构体的值复制到了新的设备模式指针上,并释放了原始的内存。最后,它再次调用了DocumentProperties函数来获取打印设置的实际值,并进行相应的更新。

    请注意,我在代码中添加了一些注释,以便更好地理解每个步骤的作用。如果您有任何疑问,请随时提问。

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 11月15日
  • 修改了问题 11月14日
  • 修改了问题 11月14日
  • 创建了问题 11月13日

悬赏问题

  • ¥15 centos7中sudo命令无法使用
  • ¥15 灰狼算法和蚁群算法如何结合
  • ¥15 这是一个利用ESP32自带按键和LED控制的录像代码,编译过程出现问题,请解决并且指出错误,指导如何处理 ,协助完成代码并上传代码
  • ¥20 stm32f103,hal库 hal_usart_receive函数接收不到数据。
  • ¥20 求结果和代码,sas利用OPTEX程序和D-efficiency生成正交集
  • ¥50 求fpga交通信号灯设计Verilog代码
  • ¥50 adb连接不到手机是怎么回事?
  • ¥20 抓取数据时发生错误: get_mooncake_data() missing 1 required positional argument: 'driver'的问题,怎么改出正确的爬虫代码?
  • ¥15 vs2022无法联网
  • ¥15 TCP的客户端和服务器的互联