方法一:调用api
原理:通过c#调用api为打印机添加自定义的纸张类型(本例自定义类型为下图的mySize),然后程序中调用方法
ForcePageSize就OK了
bool ForcePageSize(System.Drawing.Printing.PrintDocument
MyPrintDocument)
{
for (int i = 0; i <
MyPrintDocument.PrinterSettings.PaperSizes.Count; ++i)
{
if(pd.PrinterSettings.PaperSizes[i].PaperName == "mySize")
{
MyPrintDocument.DefaultPageSettings.PaperSize =
MyPrintDocument.PrinterSettings.PaperSizes[i];
MyPrintDocument.Print();
return true;
}
}
return false;

详细源代码见附件
方法二:c#通过调用c++的dll实现纸张自定义,c++实现纸张定义的一段代码,其中pDM->dmPaperLength,
pDM->dmPaperWidth即为自定义纸张的大小
bool Ctest1App::DoPreparePrintDC()
{
CPrintDialog dlgPrint(FALSE);
if(!dlgPrint.GetDefaults() ) return FALSE;
LPDEVMODE pDM=dlgPrint.GetDevMode();
if (pDM==NULL)return FALSE;
pDM->dmOrientation=DMORIENT_PORTRAIT;
pDM->dmPaperSize=DMPAPER_USER;
pDM->dmFields=DM_PAPERSIZE;
pDM->dmPaperLength=1400;
pDM->dmPaperWidth=2200;
pDM->dmFields=-1;
//::GlobalUn1ock(pDM);
m_hDC=dlgPrint.CreatePrinterDC();
if (!m_DC.Attach(m_hDC))return FALSE;
m_DC.m_bPrinting=TRUE;
short cxInch=m_DC.GetDeviceCaps(LOGPIXELSX);
short cyInch=m_DC.GetDeviceCaps(LOGPIXELSY);
/*if(!m_fontPrint.CreateFont(MulDiv(FONTSIZE,-cyInch,
72),
0,0,0,FW_NORMAL,0,0,0,
GB2312_CHARSET,OUT_CHARACTER_PRECIS,CLIP_CHA RACTER_PRECIS,
DEFAULT_QUALITY,DEFAULT_PITCH|FF—DONTCARE,HFONTNAME)
return FALSE;*/
return TRUE;
}
void Ctest1App::DoPrint()
{
if(DoPreparePrintDC()==FALSE) return;
CString str;
str.LoadString(AFX_IDS_APP_TITLE);
DOCINFO di;
//::ZeroMemory(&di,sizeof (DOCINFO));
di.cbSize=sizeof (DOCINFO);
di.lpszDocName=str;
m_DC.StartDoc(&di);
m_DC.StartPage();
m_DC.EndPage();
m_DC.EndDoc();
//m_DC.Select0bject(p0ldFont);
}
然后把c++写的函数编译成dll,用regsvr32.exe注册这个dll,再添加这个dll的引用,就可以用C#调用它了,调用的格式:
using System.Runtime.InteropServices;
[DllImport("XXX.DLL",EntryPoint="GetApiFunction",SetLastError=true)]
public static extern int GetApiFunction(
string strParaA,
StringBuilder strParaB,
int intParaC,
out int intParaD,
bool blnParaE);
C++数据类型和C#的部分对应关系:
C++ 输入输出 C#
==================================
char chr[255] O StringBuilder
KCA_DIR I int
LPCSTR I string
int I int
LPSTR O StringBuilder
int* O out int
DWORD I int
DWORD* O out int
BOOL I bool
Rc_DBMgr I IntPtr
long* O out long
前两种方法都比较烦琐,本来还想研究第三种方法,不过没时间的,感兴趣的可以看下,
m$在c#自定义纸张bug上的最新一点进展http://support.microsoft.com/default.aspx?scid=kb;en-us;282474
[内有附件]