gpt4 book ai didi

c# - PrinterSettings.GetHdevmode() 有错误吗?

转载 作者:太空狗 更新时间:2023-10-29 19:46:20 29 4
gpt4 key购买 nike

我希望能够在不打开打印机属性窗口的情况下更改打印机属性...

使用 DocumentProperties(从 winspool.drv 导入)函数到目前为止失败了,因为虽然很容易抑制对话框的显示,但 PrinterSettings.GetHdevmode() 返回的值似乎没有反射(reflect) PrinterSettings正在调用它,而是返回 OK 的先前打印机属性的值。例如,这给了我上次调用属性时的先前(错误)值,而不是它应该从 PrinterSettings 对象获得的值:

IntPtr hdevmode = PrinterSettings.GetHdevmode(PrinterSettings.DefaultPageSettings);
PrinterSettings.SetHdevmode(hdevmode);
PrinterSettings.DefaultPageSettings.SetHdevmode(hdevmode);

那么 GetHdevmode 是否有错误或者这是它应该做的?是否有 C# 解决此问题或者是否有人甚至有任何关于它的信息?我什至很难找到有关该主题的信息。

提前感谢您的任何见解。

编辑:我不想让这个问题过于个人化,但希望拥有本案例中的所有信息可以提供一个对其他人也有用的解决方案的答案。

这是我为解决此问题而编写的 C++ DLL。它目前不工作 - 它改变了其他内存,如副本,并且没有成功改变“底层”纸张大小。我以为我需要做的就是指定输出缓冲区标志以进行更改?

extern "C" __declspec(dllexport) DEVMODE* __stdcall GetRealHDevMode(int width, int height, char *printerName, DEVMODE* inDevMode)
{
//declare handles and variables
HANDLE printerHandle;
LPHANDLE printerHandlePointer(&printerHandle);

//get printer handle pointer
OpenPrinter((LPWSTR)printerName, printerHandlePointer, NULL);

//Get size needed for public and private devmode data and declare devmode structure
size_t devmodeSize = DocumentProperties(NULL, printerHandle, (LPWSTR)printerName, NULL, NULL, 0);
DEVMODE* devmode = reinterpret_cast<DEVMODE*>(new char[devmodeSize + sizeof(DEVMODE) + sizeof(inDevMode->dmDriverExtra)]);

//lock memory
GlobalLock(devmode);

//fill the out buffer
DocumentProperties(NULL, printerHandle, (LPWSTR)printerName, devmode, NULL, DM_OUT_BUFFER);

//change the values as required
devmode->dmPaperWidth = width;
devmode->dmPaperLength = height;
devmode->dmPaperSize = DMPAPER_USER;

devmode->dmFields &= ~DM_PAPERSIZE;
devmode->dmFields &= ~DM_PAPERLENGTH;
devmode->dmFields &= ~DM_PAPERWIDTH;
devmode->dmFields |= (DM_PAPERSIZE | DM_PAPERLENGTH | DM_PAPERWIDTH);

//input flag on now to put the changes back in
DocumentProperties(NULL, printerHandle, (LPWSTR)printerName, devmode, devmode, DM_IN_BUFFER | DM_OUT_BUFFER);

//unlock memory
GlobalUnlock(devmode);

//return the devmode that was used to alter the settings
return devmode;
}

我认为 C++ 代码足以更改设置,所以我在 C# 中所做的就是:

public PrinterSettings ChangePrinterProperties(PrinterSettings inPrinterSettings)
{
IntPtr TemphDevMode = inPrinterSettings.GetHdevmode(inPrinterSettings.DefaultPageSettings);
IntPtr hDevMode = GetRealHDevMode((int)(inPrinterSettings.DefaultPageSettings.PaperSize.Width * 2.54F),
(int)(inPrinterSettings.DefaultPageSettings.PaperSize.Height * 2.54F),
inPrinterSettings.PrinterName, TemphDevMode);
GlobalFree(hDevMode);
return inPrinterSettings;
}

更新:使用 dmPaperSize 和 dmFields 稍微改变了顺序。改进的结果;还没有到那一步。

更新 2:好的,我发现一个微软页面说文档有误。 MSDN 说要指定宽度和高度时将 dmPaperSize 设置为 0,而 Microsoft 支持更正说将其设置为 DMPAPER_USER。 http://support.microsoft.com/kb/108924

最佳答案

在 DEVMODE 中指定纸张尺寸的方式有 2 个问题:

(1) 如果指定 DM_PAPERWIDTH 或 DM_PAPERLENGTH 或两者,则不得同时设置 DM_PAPERSIZE 位。这取决于打印机驱动程序,但许多驱动程序会忽略上面代码中的 DM_PAPERLENGTH/WIDTH。

(2) 许多驱动程序根本不支持 DM_PAPERLENGTH/WIDTH。使用此类驱动程序,您根本无法像上面那样设置纸张尺寸。您只能选择预定义的 dmPaperSizes 之一。

您可以使用 DeviceCapabilities(DC_FIELDS) 来确定您的驱动程序是否支持 DM_PAPERLENGTH/WIDTH。

您可以使用 DeviceCapabilities(DC_PAPERS) 来枚举允许的 dmPaperSizes。

关于c# - PrinterSettings.GetHdevmode() 有错误吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2436619/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com