C# 在C中读取打印机设备上下文#
我能够显示屏幕设备并将其保存到DIB位图,我希望在打印机设备上下文中也能这样做。我可以得到一个非空位图,但它总是纯黑色 下面是允许我处理屏幕设备上下文的代码C# 在C中读取打印机设备上下文#,c#,winapi,printing,bitmap,gdi,C#,Winapi,Printing,Bitmap,Gdi,我能够显示屏幕设备并将其保存到DIB位图,我希望在打印机设备上下文中也能这样做。我可以得到一个非空位图,但它总是纯黑色 下面是允许我处理屏幕设备上下文的代码 //In size variable we shall keep the size of the window. SIZE size; //Win32 API functions are imported in classes //PlatformInvokeGDI32
//In size variable we shall keep the size of the window.
SIZE size;
//Win32 API functions are imported in classes
//PlatformInvokeGDI32
//PlatformInvokeUSER32
//Get handle of calc.exe window.
IntPtr hwnd = PlatformInvokeUSER32.FindWindow("SciCalc", "Calculator");
//Get window dimensions
PlatformInvokeUSER32.RECT rect;
PlatformInvokeUSER32.GetWindowRect(hwnd, out rect);
size.cx = rect._Right - rect._Left;
size.cy = rect._Bottom - rect._Top;
//Get the device context of Calculator.
IntPtr hDC = PlatformInvokeUSER32.GetDC(hwnd);
//Draw on the Calculator surface.
Graphics CalculatorGraphics = Graphics.FromHdc(hDC);
Color colorRed = Color.FromName("Red");
Pen penRed = new Pen(colorRed);
CalculatorGraphics.DrawEllipse(penRed, 50, 50, 50, 50);
CalculatorGraphics.Save();
//Here we make a compatible device context in memory for screen device context.
IntPtr hMemDC = PlatformInvokeGDI32.CreateCompatibleDC(hDC);
//Create a compatible bitmap of window size and using screen device context.
m_HBitmap = PlatformInvokeGDI32.CreateCompatibleBitmap(hDC, size.cx, size.cy);
//As m_HBitmap is IntPtr we can not check it against null. For this purspose IntPtr.Zero is used.
if (m_HBitmap != IntPtr.Zero)
{
//Here we select the compatible bitmap in memeory device context and keeps the refrence to Old bitmap.
IntPtr hOld = (IntPtr)PlatformInvokeGDI32.SelectObject(hMemDC, m_HBitmap);
//We copy the Bitmap to the memory device context.
PlatformInvokeGDI32.BitBlt(hMemDC, 0, 0, size.cx, size.cy, hDC, 0, 0, PlatformInvokeGDI32.SRCCOPY);
//We select the old bitmap back to the memory device context.
PlatformInvokeGDI32.SelectObject(hMemDC, hOld);
//We delete the memory device context.
PlatformInvokeGDI32.DeleteDC(hMemDC);
//We release the screen device context.
PlatformInvokeUSER32.ReleaseDC(hwnd, hDC);
//Image is created by Image bitmap handle and returned.
return System.Drawing.Image.FromHbitmap(m_HBitmap);
}
//If m_HBitmap is null retunrn null.
return null;
以下是获取打印机设备上下文的方法:
//In size variable we shall keep the size of the window.
SIZE size;
size.cx = 1000;
size.cy = 1000;
//Get Printer Handle
IntPtr PrinterHandle;
PlatformInvokeGDI32.PRINTER_DEFAULTSW defaults = new PlatformInvokeGDI32.PRINTER_DEFAULTSW();
PlatformInvokeGDI32.OpenPrinterW("Bullzip PDF Printer", out PrinterHandle, defaults);
//Get Printer Device context
IntPtr PrinterHDC = PlatformInvokeGDI32.CreateDCW("", "Bullzip PDF Printer", "", IntPtr.Zero);
//Initialize DocInfo structure.
PlatformInvokeGDI32.DOCINFOW docInfo = new PlatformInvokeGDI32.DOCINFOW();
//Start printing.
PlatformInvokeGDI32.StartDocW(PrinterHDC, ref docInfo);
PlatformInvokeGDI32.StartPage(PrinterHDC);
Graphics graphics = Graphics.FromHdc(PrinterHDC, PrinterHandle);
Color theColor = Color.FromName("Red");
Pen pen = new Pen(theColor);
graphics.DrawRectangle(pen, 50, 50, 50, 50);
graphics.DrawEllipse(pen, 50, 50, 50, 50);
graphics.Save();
//Here we make a compatible device context in memory for screen device context.
IntPtr hMemDC = PlatformInvokeGDI32.CreateCompatibleDC(PrinterHDC);
//Create a compatible bitmap of window size and using screen device context.
m_HBitmap = PlatformInvokeGDI32.CreateCompatibleBitmap(PrinterHDC, size.cx, size.cy);
//As m_HBitmap is IntPtr we can not check it against null. For this purspose IntPtr.Zero is used.
if (m_HBitmap != IntPtr.Zero)
{
//Here we select the compatible bitmap in memeory device context and keeps the refrence to Old bitmap.
IntPtr hOld = (IntPtr)PlatformInvokeGDI32.SelectObject(hMemDC, m_HBitmap);
//We copy the Bitmap to the memory device context.
PlatformInvokeGDI32.BitBlt(hMemDC, 0, 0, size.cx, size.cy, PrinterHDC, 0, 0, PlatformInvokeGDI32.SRCCOPY);
//We select the old bitmap back to the memory device context.
PlatformInvokeGDI32.SelectObject(hMemDC, hOld);
//We delete the memory device context.
PlatformInvokeGDI32.DeleteDC(hMemDC);
//We release the screen device context.
//PlatformInvokeUSER32.ReleaseDC(hwnd, PrinterHDC);
//Image is created by Image bitmap handle and returned.
PlatformInvokeGDI32.EndPage(PrinterHDC);
PlatformInvokeGDI32.EndDoc(PrinterHDC);
PlatformInvokeGDI32.ClosePrinter(PrinterHandle);
pen.Dispose();
graphics.Dispose();
return System.Drawing.Image.FromHbitmap(m_HBitmap);
}
//If m_HBitmap is null retunrn null.
return null;
如何在打印机设备上下文上绘图?
如何将打印机设备上下文保存到DIB
谢谢,
Jacob打印机设备上下文是只写的 例如,假设您正在打印到PostScript打印机。创建打印机设备上下文并在其上绘制一些文本。打印机设备驱动程序不会呈现包含文本的位图。相反,它创建一系列PostScript命令来绘制文本,并将命令发送到打印机。换句话说,没有要复制的位图
你想实现什么?这是一件非常不寻常的事情。一个名为“Bullzip PDF printer”的假打印机驱动程序无疑不支持它。工作原理类似于光栅设备,而不是位图设备。我现在在其他物理和软件打印机上尝试了相同的代码,得到了相同的结果:图形打印成功,但DC没有像我希望的那样转换为位图。打印机:HP LaserJet 4100系列PCL、Apple Color LaserWriter 12/600、Bullzip PDF打印机、DOXPrinter801和LaserWriter Personal NT v51.8。打印机Ricoh Aficio MP C4000 PCL6在PlatformInvokeGDI32.StartPage(PrinterHDC)上给出了一个AccessViolationException;。我以编程方式将大量文档打印到TIFF。有时,文档是基于HTML的电子邮件,包含的表格太宽,无法在页面上打印,这意味着某些内容没有打印出来。我希望保存一个位图,然后确定该区域以外是否有任何非白色像素可以打印到页面上。能否将电子邮件加载到HTML渲染器中,并询问其文档宽度?电子邮件存储在Outlook PST中。提交电子邮件进行打印的应用程序是一个名为DiscoveryCracker的现成应用程序,它将电子邮件提交到Outlook 2007进行打印。我不知道在这个过程中,我可以将文档发送到HTML渲染器的哪个位置。我之所以想使用设备上下文,是因为我可以将DLL注入DiscoveryCracker或Outlook and hook StartPage,后者使用hDC。我不是Outlook专家,但似乎可以编写一个宏在加载消息时运行。然而,如果只打印正在打开的消息的一个子集,这将没有多大用处。与Excel不同,打印文档时似乎不可能运行宏。或者,如果要挂接GDI,可以挂接文本和线条绘制函数并检查它们的边界。尽管如果需要考虑映射模式,这可能会变得复杂。或者可能有一种更干净的方式连接到打印管道中。获取ExtTextOut和其他文本方法的坐标是我想到的另一种方式。我同意必须考虑映射模式会使事情变得具有挑战性。如果有一种更干净的方法连接到打印管道,我还没有找到。你有什么想法吗?宏观的想法不是我想到的。我会考虑一下。