列印自定義紙張大小
不過還是要感謝他的提示
今天和小陳搞了一天,他在國外的論壇上看到了一篇文章得到了啟示,最後我們在凌晨3點終於把自定義紙張的程式碼給寫出來了,看來必須用API,微軟的.NET對列印的支援太菜了
現公開我們工作室實現此功能的部分程式碼
using System;
using System.Text;
using System.Runtime.InteropServices;
using System.Security;
using System.ComponentModel;
using System.Drawing.Printing;
namespace MCCustomPrintForm
{
/// <summary>
/// 成都微創工作室(電子科技大學微創工作室)
/// Tell 028-82853098
/// Email
/// 印表機紙張的真正自定義部分程式碼
/// 2006-1-2
/// </summary>
public class MCCustomPrintForm
{
// Make a static class
private MCCustomPrintForm()
{
}
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
internal struct structPrinterDefaults
{
[MarshalAs(UnmanagedType.LPTStr)] public String pDatatype;
public IntPtr pDevMode;
[MarshalAs(UnmanagedType.I4)] public int DesiredAccess;
};
[DllImport("winspool.Drv", EntryPoint="OpenPrinter", SetLastError=true,
CharSet=CharSet.Unicode, ExactSpelling=false,CallingConvention=CallingConvention.StdCall),
SuppressUnmanagedCodeSecurityAttribute()]
internal static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPTStr)]
string printerName,
out IntPtr phPrinter,
ref structPrinterDefaults pd);
[DllImport("winspool.Drv", EntryPoint="ClosePrinter", SetLastError=true,
CharSet=CharSet.Unicode, ExactSpelling=false,
CallingConvention=CallingConvention.StdCall),SuppressUnmanagedCodeSecurityAttribute()]
internal static extern bool ClosePrinter(IntPtr phPrinter);
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
internal struct structSize
{
public Int32 width;
public Int32 height;
}
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
internal struct structRect
{
public Int32 left;
public Int32 top;
public Int32 right;
public Int32 bottom;
}
[StructLayout(LayoutKind.Explicit, CharSet=CharSet.Unicode)]
internal struct FormInfo1
{
[FieldOffset(0), MarshalAs(UnmanagedType.I4)] public uint Flags;
[FieldOffset(4), MarshalAs(UnmanagedType.LPWStr)] public String pName;
[FieldOffset(8)] public structSize Size;
[FieldOffset(16)] public structRect ImageableArea;
};
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi/* changed from CharSet=CharSet.Auto */)]
internal struct structDevMode
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=32)] public String
dmDeviceName;
[MarshalAs(UnmanagedType.U2)] public short dmSpecVersion;
[MarshalAs(UnmanagedType.U2)] public short dmDriverVersion;
[MarshalAs(UnmanagedType.U2)] public short dmSize;
[MarshalAs(UnmanagedType.U2)] public short dmDriverExtra;
[MarshalAs(UnmanagedType.U4)] public int dmFields;
[MarshalAs(UnmanagedType.I2)] public short dmOrientation;
[MarshalAs(UnmanagedType.I2)] public short dmPaperSize;
[MarshalAs(UnmanagedType.I2)] public short dmPaperLength;
[MarshalAs(UnmanagedType.I2)] public short dmPaperWidth;
[MarshalAs(UnmanagedType.I2)] public short dmScale;
[MarshalAs(UnmanagedType.I2)] public short dmCopies;
[MarshalAs(UnmanagedType.I2)] public short dmDefaultSource;
[MarshalAs(UnmanagedType.I2)] public short dmPrintQuality;
[MarshalAs(UnmanagedType.I2)] public short dmColor;
[MarshalAs(UnmanagedType.I2)] public short dmDuplex;
[MarshalAs(UnmanagedType.I2)] public short dmYResolution;
[MarshalAs(UnmanagedType.I2)] public short dmTTOption;
[MarshalAs(UnmanagedType.I2)] public short dmCollate;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=32)] public String dmFormName;
[MarshalAs(UnmanagedType.U2)] public short dmLogPixels;
[MarshalAs(UnmanagedType.U4)] public int dmBitsPerPel;
[MarshalAs(UnmanagedType.U4)] public int dmPelsWidth;
[MarshalAs(UnmanagedType.U4)] public int dmPelsHeight;
[MarshalAs(UnmanagedType.U4)] public int dmNup;
[MarshalAs(UnmanagedType.U4)] public int dmDisplayFrequency;
[MarshalAs(UnmanagedType.U4)] public int dmICMMethod;
[MarshalAs(UnmanagedType.U4)] public int dmICMIntent;
[MarshalAs(UnmanagedType.U4)] public int dmMediaType;
[MarshalAs(UnmanagedType.U4)] public int dmDitherType;
[MarshalAs(UnmanagedType.U4)] public int dmReserved1;
[MarshalAs(UnmanagedType.U4)] public int dmReserved2;
}
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
internal struct PRINTER_INFO_9
{
public IntPtr pDevMode;
}
[DllImport("winspool.Drv", EntryPoint="AddFormW", SetLastError=true,
CharSet=CharSet.Unicode, ExactSpelling=true,
CallingConvention=CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()]
internal static extern bool AddForm(
IntPtr phPrinter,
[MarshalAs(UnmanagedType.I4)] int level,
ref FormInfo1 form);
/* This method is not used
[DllImport("winspool.Drv", EntryPoint="SetForm", SetLastError=true,
CharSet=CharSet.Unicode, ExactSpelling=false,
CallingConvention=CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()]
internal static extern bool SetForm(IntPtr phPrinter, string paperName,
[MarshalAs(UnmanagedType.I4)] int level, ref FormInfo1 form);
*/
[DllImport("winspool.Drv", EntryPoint="DeleteForm", SetLastError=true,
CharSet=CharSet.Unicode, ExactSpelling=false,CallingConvention=CallingConvention.StdCall),
SuppressUnmanagedCodeSecurityAttribute()]
internal static extern bool DeleteForm(
IntPtr phPrinter,
[MarshalAs(UnmanagedType.LPTStr)] string pName);
[DllImport("kernel32.dll", EntryPoint="GetLastError", SetLastError=false,
ExactSpelling=true, CallingConvention=CallingConvention.StdCall),
SuppressUnmanagedCodeSecurityAttribute()]
internal static extern Int32 GetLastError();
[DllImport("GDI32.dll", EntryPoint="CreateDC", SetLastError=true,
CharSet=CharSet.Unicode, ExactSpelling=false,
CallingConvention=CallingConvention.StdCall),
SuppressUnmanagedCodeSecurityAttribute()]
internal static extern IntPtr CreateDC([MarshalAs(UnmanagedType.LPTStr)]
string pDrive,
[MarshalAs(UnmanagedType.LPTStr)] string pName,
[MarshalAs(UnmanagedType.LPTStr)] string pOutput,
ref structDevMode pDevMode);
[DllImport("GDI32.dll", EntryPoint="ResetDC", SetLastError=true,
CharSet=CharSet.Unicode, ExactSpelling=false,
CallingConvention=CallingConvention.StdCall),
SuppressUnmanagedCodeSecurityAttribute()]
internal static extern IntPtr ResetDC(
IntPtr hDC,
ref structDevMode
pDevMode);
[DllImport("GDI32.dll", EntryPoint="DeleteDC", SetLastError=true,
CharSet=CharSet.Unicode, ExactSpelling=false,
CallingConvention=CallingConvention.StdCall),
SuppressUnmanagedCodeSecurityAttribute()]
internal static extern bool DeleteDC(IntPtr hDC);
[DllImport("winspool.Drv", EntryPoint="SetPrinterA", SetLastError=true,
CharSet=CharSet.Auto, ExactSpelling=true,
CallingConvention=CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()]
internal static extern bool SetPrinter(
IntPtr hPrinter,
[MarshalAs(UnmanagedType.I4)] int level,
IntPtr pPrinter,
[MarshalAs(UnmanagedType.I4)] int command);
/*
LONG DocumentProperties(
HWND hWnd, // handle to parent window
HANDLE hPrinter, // handle to printer object
LPTSTR pDeviceName, // device name
PDEVMODE pDevModeOutput, // modified device mode
PDEVMODE pDevModeInput, // original device mode
DWORD fMode // mode options
);
*/
[DllImport("winspool.Drv", EntryPoint="DocumentPropertiesA", SetLastError=true,
ExactSpelling=true, CallingConvention=CallingConvention.StdCall)]
public static extern int DocumentProperties(
IntPtr hwnd,
IntPtr hPrinter,
[MarshalAs(UnmanagedType.LPStr)] string pDeviceName /* changed from String to string */,
IntPtr pDevModeOutput,
IntPtr pDevModeInput,
int fMode
);
[DllImport("winspool.Drv", EntryPoint="GetPrinterA", SetLastError=true,
ExactSpelling=true, CallingConvention=CallingConvention.StdCall)]
public static extern bool GetPrinter(
IntPtr hPrinter,
int dwLevel /* changed type from Int32 */,
IntPtr pPrinter,
int dwBuf /* chagned from Int32*/,
out int dwNeeded /* changed from Int32*/
);
// SendMessageTimeout tools
[Flags] public enum SendMessageTimeoutFlags : uint
{
SMTO_NORMAL = 0x0000,
SMTO_BLOCK = 0x0001,
SMTO_ABORTIFHUNG = 0x0002,
SMTO_NOTIMEOUTIFNOTHUNG = 0x0008
}
const int WM_SETTINGCHANGE = 0x001A;
const int HWND_BROADCAST = 0xffff;
[DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Auto)]
public static extern IntPtr SendMessageTimeout(
IntPtr windowHandle,
uint Msg,
IntPtr wParam,
IntPtr lParam,
SendMessageTimeoutFlags flags,
uint timeout,
out IntPtr result
);
//列印紙張長寬設定
public static void AddMC80MmPaperSizeToDefaultPrinter()
{
AddCustomPaperSizeToDefaultPrinter("MC 80mm * Receipt Length", 80.1f, 4003.9f);
}
public static void AddMC104MmPaperSizeToDefaultPrinter()
{
AddCustomPaperSizeToDefaultPrinter("MC 104mm * Receipt Length", 104.1f, 4003.9f);
}
/// <summary>
/// Adds the printer form to the default printer
/// </summary>
/// <param name="paperName">Name of the printer form</param>
/// <param name="widthMm">Width given in millimeters</param>
/// <param name="heightMm">Height given in millimeters</param>
public static void AddCustomPaperSizeToDefaultPrinter(string paperName, float widthMm, float heightMm)
{
PrintDocument pd = new PrintDocument();
string sPrinterName = pd.PrinterSettings.PrinterName;
AddCustomPaperSize(sPrinterName, paperName, widthMm, heightMm);
}
/// <summary>
/// Add the printer form to a printer
/// </summary>
/// <param name="printerName">The printer name</param>
/// <param name="paperName">Name of the printer form</param>
/// <param name="widthMm">Width given in millimeters</param>
/// <param name="heightMm">Height given in millimeters</param>
public static void AddCustomPaperSize(string printerName, string paperName, float
widthMm, float heightMm)
{
if (PlatformID.Win32NT == Environment.OSVersion.Platform)
{
// The code to add a custom paper size is different for Windows NT then it is
// for previous versions of windows
const int PRINTER_ACCESS_USE = 0x00000008;
const int PRINTER_ACCESS_ADMINISTER = 0x00000004;
const int FORM_PRINTER = 0x00000002;
structPrinterDefaults defaults = new structPrinterDefaults();
defaults.pDatatype = null;
defaults.pDevMode = IntPtr.Zero;
defaults.DesiredAccess = PRINTER_ACCESS_ADMINISTER | PRINTER_ACCESS_USE;
IntPtr hPrinter = IntPtr.Zero;
// Open the printer.
if (OpenPrinter(printerName, out hPrinter, ref defaults))
{
try
{
// delete the form incase it already exists
DeleteForm(hPrinter, paperName);
// create and initialize the FORM_INFO_1 structure
FormInfo1 formInfo = new FormInfo1();
formInfo.Flags = 0;
formInfo.pName = paperName;
// all sizes in 1000ths of millimeters
formInfo.Size.width = (int)(widthMm * 1000.0);
formInfo.Size.height = (int)(heightMm * 1000.0);
formInfo.ImageableArea.left = 0;
formInfo.ImageableArea.right = formInfo.Size.width;
formInfo.ImageableArea.top = 0;
formInfo.ImageableArea.bottom = formInfo.Size.height;
if (!AddForm(hPrinter, 1, ref formInfo))
{
StringBuilder strBuilder = new StringBuilder();
strBuilder.AppendFormat("Failed to add the custom paper size {0} to the printer {1}, System error number: {2}",
paperName, printerName, GetLastError());
throw new ApplicationException(strBuilder.ToString());
}
// INIT
const int DM_OUT_BUFFER = 2;
const int DM_IN_BUFFER = 8;
structDevMode devMode = new structDevMode();
IntPtr hPrinterInfo, hDummy;
PRINTER_INFO_9 printerInfo;
printerInfo.pDevMode = IntPtr.Zero;
int iPrinterInfoSize, iDummyInt;
// GET THE SIZE OF THE DEV_MODE BUFFER
int iDevModeSize = DocumentProperties(IntPtr.Zero, hPrinter, printerName, IntPtr.Zero, IntPtr.Zero, 0);
if(iDevModeSize < 0)
throw new ApplicationException("Cannot get the size of the DEVMODE structure.");
// ALLOCATE THE BUFFER
IntPtr hDevMode = Marshal.AllocCoTaskMem(iDevModeSize + 100);
// GET A POINTER TO THE DEV_MODE BUFFER
int iRet = DocumentProperties(IntPtr.Zero, hPrinter, printerName, hDevMode, IntPtr.Zero, DM_OUT_BUFFER);
if(iRet < 0)
throw new ApplicationException("Cannot get the DEVMODE structure.");
// FILL THE DEV_MODE STRUCTURE
devMode = (structDevMode)Marshal.PtrToStructure(hDevMode, devMode.GetType());
// SET THE FORM NAME FIELDS TO INDICATE THAT THIS FIELD WILL BE MODIFIED
devMode.dmFields = 0x10000; // DM_FORMNAME
// SET THE FORM NAME
devMode.dmFormName = paperName;
// PUT THE DEV_MODE STRUCTURE BACK INTO THE POINTER
Marshal.StructureToPtr(devMode, hDevMode, true);
// MERGE THE NEW CHAGES WITH THE OLD
iRet = DocumentProperties(IntPtr.Zero, hPrinter, printerName,
printerInfo.pDevMode, printerInfo.pDevMode, DM_IN_BUFFER | DM_OUT_BUFFER);
if(iRet < 0)
throw new ApplicationException("Unable to set the orientation setting for this printer.");
// GET THE PRINTER INFO SIZE
GetPrinter(hPrinter, 9, IntPtr.Zero, 0, out iPrinterInfoSize);
if(iPrinterInfoSize == 0)
throw new ApplicationException("GetPrinter failed. Couldn't get the # bytes needed for shared PRINTER_INFO_9 structure");
// ALLOCATE THE BUFFER
hPrinterInfo = Marshal.AllocCoTaskMem(iPrinterInfoSize + 100);
// GET A POINTER TO THE PRINTER INFO BUFFER
bool bSuccess = GetPrinter(hPrinter, 9, hPrinterInfo, iPrinterInfoSize, out iDummyInt);
if(!bSuccess)
throw new ApplicationException("GetPrinter failed. Couldn't get the shared PRINTER_INFO_9 structure");
// FILL THE PRINTER INFO STRUCTURE
printerInfo = (PRINTER_INFO_9)Marshal.PtrToStructure(hPrinterInfo, printerInfo.GetType());
printerInfo.pDevMode = hDevMode;
// GET A POINTER TO THE PRINTER INFO STRUCTURE
Marshal.StructureToPtr(printerInfo, hPrinterInfo, true);
// SET THE PRINTER SETTINGS
bSuccess = SetPrinter(hPrinter, 9, hPrinterInfo, 0);
if(!bSuccess)
throw new Win32Exception(Marshal.GetLastWin32Error(), "SetPrinter() failed. Couldn't set the printer settings");
// Tell all open programs that this change occurred.
SendMessageTimeout(
new IntPtr(HWND_BROADCAST),
WM_SETTINGCHANGE,
IntPtr.Zero,
IntPtr.Zero,
MCCustomPrintForm.SendMessageTimeoutFlags.SMTO_NORMAL,
1000,
out hDummy);
}
finally
{
ClosePrinter(hPrinter);
}
}
else
{
StringBuilder strBuilder = new StringBuilder();
strBuilder.AppendFormat("Failed to open the {0} printer, System error number: {1}",
printerName, GetLastError());
throw new ApplicationException(strBuilder.ToString());
}
}
else
{
structDevMode pDevMode = new structDevMode();
IntPtr hDC = CreateDC(null, printerName, null, ref pDevMode);
if (hDC != IntPtr.Zero)
{
const long DM_PAPERSIZE = 0x00000002L;
const long DM_PAPERLENGTH = 0x00000004L;
const long DM_PAPERWIDTH = 0x00000008L;
pDevMode.dmFields = (int)(DM_PAPERSIZE | DM_PAPERWIDTH | DM_PAPERLENGTH);
pDevMode.dmPaperSize = 256;
pDevMode.dmPaperWidth = (short)(widthMm * 1000.0);
pDevMode.dmPaperLength = (short)(heightMm * 1000.0);
ResetDC(hDC, ref pDevMode);
DeleteDC(hDC);
}
}
}
}
}
相關推薦
列印自定義紙張大小
長江支流說的辦法保留太多了,結果不行,很多類都是他在程式集裡自定義的,原始碼又沒公開 不過還是要感謝他的提示 今天和小陳搞了一天,他在國外的論壇上看到了一篇文章得到了啟示,最後我們在凌晨3點終於把自定義紙張的程式碼給寫出來了,看來必須用API,微軟的.NET對列印的支援
C# 自定義紙張大小列印 PDF
當列印PDF文件的時候,預設情況下紙張大小是A4。但是有些情況下原文件不是A4大小,我們需要保持原來的頁面大小怎麼辦呢?這個時候就需要自定義紙張大小來實現這個功能。本文將介紹如何使用.NET PDF元件Spire.PDF在C#應用程式中自定義紙張大小列印PDF。 在使用以下程式碼前,需要下載
【轉載】Smartforms 設定 自定義紙張列印格式
在sap做一個列印報表,要先設定一個紙張列印格式,下面以工廠中常用來列印的針孔紙為例,在sap設定該紙張的列印格式,以用於報表: 1、執行事務程式碼SPAD;選擇工具欄上的【完全管理】按鈕——>選擇【裝置型別】頁面(在該頁面上有四個按鈕:【裝置型別】、【列印控制】、【格式型別】、【頁格式】
自定義紙張 未驗證
開始 使用 復制 names 字符串 就會 設置 rsize 一個 using System; using System.Collections.Generic; using System.Text; using System.Drawing; using Sy
自定義棋盤大小的N子棋
三子棋程式碼: #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> //對於陣列的長度,最好定義成巨集 //方便程式的擴充套件,改巨集定義則可修改陣列元素個數 #define RO
Webstorm自定義字型大小
webstrom前面文章講到了,前端開發神器,這裡就不多說了。 首先,講一下如何更改工具欄字型大小。File-Settings 看到如圖這個介面,把框起來的地方打鉤,就可以更改字型型別和字型大小
【Android自定義View實戰】之自定義評價打分控制元件RatingBar,可以自定義星星大小和間距
在Android開發中,我們經常會用到對商家或者商品的評價,運用星星進行打分。然而在Android系統中自帶的打分控制元件,RatingBar特別不好用,間距和大小無法改變。所以,我就自定義了一個特別好用的打分控制元件。在專案中可以直接使用,特別簡
VC++ 實現增大可執行檔案的體積 自定義檔案大小
做免殺的同學可能都會吧,增大檔案體積防止雲上傳是個不錯的方法 功能介面: 選擇檔案,是對話方塊支援檔案拖放(詳情見:http://blog.csdn.net/eldn__/article/details/8394060) 為對話方塊新增成員變數:CString m_
Android自定義Dialog大小 自動一螢幕寬度的80%展示
備註:設定大小的程式碼一定放在show方法後面 不然設定不成功 ExitOrderDialog dialog = new ExitOrderDialog(this, messages); dialo
unity3d GUI.Button 自定義字型大小及透明背景
程式碼 public class MyButton: MonoBehaviour { public Texture buttonTexture; // Use this for initialization void Start () {
自定義UIActivityIndicatorView大小
大家知道UIActivityIndicatorView是不能定義frame的,只能設定它的center,建立的UIActivityIndicatorView有三種style,這三種style有預設的大小,不能通過設定frame的方式來修改大小。 最近碰到一個視覺效果,是需
Unity--自定義任意大小截圖功能
最近需要到截圖儲存功能,簡單做個筆記記錄一下。 using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public clas
Android自定義Dialog大小控制
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="ma
NSLog列印自定義物件
我們在開發中,如果直接使用NSLog列印物件,則會列印物件的指標(如下圖) 但我們常常希望列印的是物件的屬性的值,因此我們需要重寫自定義類的description方法(列印日誌時,物件會收到des
Lodop自定義大小不能識別241mm*93mm這種規格的解決辦法 Lodop扁寬橫向241mm*93mm這種怪異的紙張如何設定
本人開發的一套物業收費管理系統,使用Lodop6.221控制元件來列印收據,列印紙是一分三(241mm*93mm)的那種規格,印表機用的是EPSON Q-630K II,之前使用者使用前置進紙、單個列印,一直用得很好。忽然有一天他們提出要求連續列印、後置進紙,卻出現每列印一張收據後要多走一段紙的狀況,經反覆測
如何在sap裡設定自定義列印紙張
5 再點選"裝置型別",進入裝置型別的列表(建立格式與裝置的關係)點選"CNSAPWIN MS Windows driver via SAPLPD"裝置 6 點選"格式"按鈕,進入格式列表,點選"新增"按鈕增加"ZHT01"格式,如下屏 在"列印初始化"輸入下面的控制程式碼# CNSAPWIN SAPscr
javaScript中自定義sort中的比較函數,用於比較字符串長度,數值大小
var cti lin family 字符串長度 tr1 個數 new fun var arr = [‘aa‘, 23, 1.2, ‘bb‘, ‘cc‘]; var len = arr.length; // for (var i = 0; i < len; i++)
修改自定義大小的桌面屏幕分辨率
clas addm nor 終端 model tro virt des tar 在ubuntu14.04虛擬機上修改自定義大小的桌面屏幕分辨率,使用的命令:cvt,xrandr 0、首先查看下當前已經提供的分辨率設置:xrandr -q root@xxx:/home/xx
php自定義函數: 文件大小轉換成智能形式
elseif pos byte light orm files brush 轉換成 else function format_byte($filesize) { if($filesize >= 1073741824) { $filesize
java 圖片的自定義大小
ipa apach logger private idt except clas 取圖 ont java 小功能,進行圖片的自定義大小 package com.project.video.controller; import java.awt.Color; import