中國最大的web開發(fā)資源網(wǎng)站及技術(shù)社區(qū),
前篇說了.net環(huán)境下有關(guān)打印頁面設(shè)置、打印機設(shè)置、打印預(yù)覽對話框的實現(xiàn),現(xiàn)在到了我們應(yīng)用它們的時候了。
我們需要做下面的一些事情:
1、將上篇中寫的程序輸出類型改為類庫并編譯成printerpagesetting.dll;
2、建立c#或vb.net項目,并在項目的引用處添加引用,在彈出的對話框的.net標(biāo)簽中瀏覽并選擇printerpagesetting.dll;
3、在默認窗口form1上增加一個textbox文本框控件,默認名textbox1(實際項目中建議采用命名及編碼規(guī)范,如frmtestprint,txtprint)
4、從工具箱中拖一個mainmenu到窗口form1,創(chuàng)建mainmenu1菜單對象,建立主菜單menufile
5、單擊menufile,在其下方輸入處分別建立menufilepagesetup、menufileprintpreview、menufileprint菜單。我想大家明白這幾個菜單的意義了,這是命名規(guī)范最基本的。
準(zhǔn)備工作做完了,看看我們怎么使用printerpagesetting輕松完成打印頁面設(shè)置、打印機設(shè)置、打印預(yù)覽對話框。
第一步:在窗口類中申明并實例化printerpagesetting,當(dāng)然實例化對象可以放在構(gòu)造函數(shù)中。
c#:
private goldprinter.printerpagesetting printerpagesetting = new goldprinter.printerpagesetting();
vb.net:
private printerpagesetting as new goldprinter.printerpagesetting
第二步:寫一個實現(xiàn)打印的具體過程
c#:
private void printdocument_printpage_handler(object o,system.drawing.printing.printpageeventargs e)
{
system.drawing.graphics g = e.graphics;
if (draw(g))
{
e.hasmorepages = true; //要分頁打印
}
else
{
e.hasmorepages = false; //打印結(jié)束
}
}
vb.net:
private sub printdocument_printpage(byval sender as object, byval e as system.drawing.printing.printpageeventargs)
dim g as system.drawing.graphics = e.graphics
if me.draw(g) then
e.hasmorepages = true '要分頁打印
else
e.hasmorepages = false '打印結(jié)束
end if
end sub
大家可以看到我們是怎么使程序在打印時自動分頁的,就是設(shè)置hasmorepages屬性為真就可以了。為了清晰可見,我將真正打印的具體過程獨立出來用draw()實現(xiàn)。
在第二步中我們實現(xiàn)打印的具體過程,在printerpagesetting類中,我們并不知道打印的具體實現(xiàn),就設(shè)計了printpage委托,讓調(diào)用者自己實現(xiàn),然后告訴printerpagesetting是用哪一個方法實現(xiàn),也就是第三步了。
第三步:打印委托
在窗口空白處雙擊,在form1_load事件中輸入相關(guān)語句。當(dāng)然也可以放在構(gòu)造函數(shù)中,這里為了描述的方便。
c#:
private void form1_load(object sender, system.eventargs e)
{
this.printerpagesetting.printpage += new goldprinter.printpagedelegate(printdocument_printpage_handler);
}
如果你不知上一句是什么意思,就用這一句吧:
this.printerpagesetting.printpagevalue = new goldprinter.printpagedelegate(printdocument_printpage_handler);
意思就是告訴printerpagesetting打印的具體實現(xiàn)過程是printdocument_printpage_handler(第二步)
vb.net:
private sub form1_load(byval sender as system.object, byval e as system.eventargs) handles mybase.load
me.printerpagesetting.printpagevalue = new goldprinter.printpagedelegate(addressof printdocument_printpage)
end sub
大家還可以一試啊,
private withevents printdocument as system.drawing.printing.printdocument '第一步:在申明窗口級變量
me.printdocument = me.printerpagesetting.printdocument '第二步:在此將兩個量聯(lián)系起來
將printdocument_printpage(...)加上 handles printdocument.printpage
第四步:顯示頁面設(shè)置/打印機設(shè)置/打印預(yù)覽對話框
分別在幾個菜單上單擊,具體代碼如下:
c#:
private void menufilepagesetup_click(object sender, system.eventargs e)
{
this.printerpagesetting.showpagesetupdialog(); //顯示頁面設(shè)置對話框
}
private void menufileprintpreview_click(object sender, system.eventargs e)
{
this.printerpagesetting.showprintpreviewdialog(); //顯示打印預(yù)覽對話框
}
private void menufileprint_click(object sender, system.eventargs e)
{
this.printerpagesetting.showprintsetupdialog(); //顯示打印預(yù)覽對話框
}
vb.net:
private sub menufilepagesetup_click(byval sender as system.object, byval e as system.eventargs) handles menufilepagesetup.click
me.printerpagesetting.showpagesetupdialog()
end sub
private sub menufileprintpreview_click(byval sender as system.object, byval e as system.eventargs) handles menufileprintpreview.click
me.printerpagesetting.showprintpreviewdialog()
end sub
private sub menufileprint_click(byval sender as system.object, byval e as system.eventargs) handles menufileprint.click
me.printerpagesetting.showprintsetupdialog()
end sub
哈哈,到現(xiàn)在為此,我們做的工作基本完成了,不過不要忘了draw()噢。
c#:
private bool draw(system.drawing.graphics g)
{
g.drawstring("hello world!",new font("宋體",15),brushes.black,new pointf(0,0));
return false;
}
vb.net:
private function draw(byval g as system.drawing.graphics) as boolean
g.drawstring("hello world!", new font("宋體", 15), brushes.black, new pointf(0, 0))
return false
end function
大家可不要笑這個draw()太簡單喲!運行看看,嘿,程序確實能夠完成打印頁面設(shè)置、打印機設(shè)置、打印預(yù)覽對話框的功能,還能設(shè)置橫向縱向打印,改變紙張大小等設(shè)置呢。
擴展:
當(dāng)然,既然printdocument_printpage_handler()與printdocument_printpage()組織的清晰且能夠分頁,那我就不讓大家遺憾了。
我現(xiàn)在分別用vb.net和c#實現(xiàn)一個能夠分頁打印的例子,而且上面的工作不白做,僅僅改一下draw()就可以了。
vb.net:
private function draw(byval g as system.drawing.graphics) as boolean
return drawtext(g, me.printerpagesetting.printdocument, me.textbox1.text)
end function
'這段代碼改編自msdn
private function drawtext(byval g as system.drawing.graphics, byval pdoc as system.drawing.printing.printdocument, byval text as string) as boolean
g.drawstring("hello world!", new font("宋體", 15), brushes.black, new pointf(0, 0))
return false
static intcurrentchar as int32
dim font as new font("宋體", 10)
dim intprintareaheight, intprintareawidth as int32
with pdoc.defaultpagesettings
intprintareaheight = .papersize.height - .margins.top - .margins.bottom
intprintareawidth = .papersize.width - .margins.left - .margins.right
end with
' 橫向打印,寬與高交換
if pdoc.defaultpagesettings.landscape then
me.swap(intprintareawidth, intprintareaheight)
end if
'定義打印區(qū)域
dim rectprintingarea as new rectanglef(pdoc.defaultpagesettings.margins.left, pdoc.defaultpagesettings.margins.top, intprintareawidth, intprintareaheight)
dim fmt as new stringformat(stringformatflags.linelimit)
dim intlinesfilled, intcharsfitted as int32
g.measurestring(mid(text, intcurrentchar + 1), font, _
new sizef(intprintareawidth, intprintareaheight), fmt, _
intcharsfitted, intlinesfilled)
g.drawstring(mid(text, intcurrentchar + 1), font, _
brushes.black, rectprintingarea, fmt)
intcurrentchar += intcharsfitted
if intcurrentchar < text.length then
return true
else
intcurrentchar = 0
return false
end if
end function
'兩個數(shù)的值互換
private sub swap(byref i as int32, byref j as int32)
dim tmp as int32 = i
i = j
j = tmp
end sub
vb.net實現(xiàn)了,那我就換一個面向?qū)ο蟮膶崿F(xiàn)方法吧。
c#:
在c#項目上右鍵選擇添加/添加類,命名為drawtext.cs,這里列出全部內(nèi)容:
///
/// 在繪圖表面區(qū)域內(nèi)繪制文本
///
public class drawtext
{
private graphics _graphics;
private rectanglef _rectanglef;
private string _text;
private font _font;
private brush _brush;
private stringformat _stringformat;
private int _startchar;
private int _linesfilled;
private int _charsfitted;
#region 字段屬性
public graphics graphics
{
get
{
return _graphics;
}
set
{
_graphics = value;
}
}
public rectanglef rectanglef
{
get
{
return _rectanglef;
}
set
{
_rectanglef = value;
}
}
public string text
{
get
{
return _text;
}
set
{
_text = value;
}
}
public font font
{
get
{
return _font;
}
set
{
if (value != null)
{
_font = value;
}
}
}
public brush brush
{
get
{
return _brush;
}
set
{
if (value != null)
{
_brush = value;
}
}
}
public stringformat stringformat
{
get
{
return _stringformat;
}
set
{
_stringformat = value;
}
}
public int startchar
{
get
{
return _startchar;
}
set
{
_startchar = value;
if (_startchar < 0)
{
_startchar = 0;
}
}
}
public int charsfitted
{
get
{
return _charsfitted;
}
}
public int linesfilled
{
get
{
return _linesfilled;
}
}
#endregion
public drawtext()
{
_text = "";
_font = new font("宋體",10);
_rectanglef = new rectanglef(0,0,0,_font.height);
_brush = brushes.black;
_startchar = 0;
_linesfilled = 0;
_charsfitted = 0;
_stringformat = new stringformat(stringformatflags.linelimit);
}
public drawtext(string text):this()
{
_text = text;
}
public void draw()
{
if (_graphics != null)
{
int intlinesfilled, intcharsfitted;
_graphics.measurestring(_text.substring(_startchar),_font,new sizef(_rectanglef.width, _rectanglef.height),_stringformat,out intcharsfitted,out intlinesfilled);
_graphics.drawstring(_text.substring(_startchar),_font,_brush,_rectanglef,_stringformat);
this._linesfilled = intlinesfilled;
this._charsfitted = intcharsfitted;
}
}
然后將原來的draw()用下面的語句替換掉:
private static int intcurrentcharindex;
private bool draw(system.drawing.graphics g)
{
float width,height;
width = this.printerpagesetting.printdocument.defaultpagesettings.papersize.width - this.printerpagesetting.printdocument.defaultpagesettings.margins.left - this.printerpagesetting.printdocument.defaultpagesettings.margins.right;
height = this.printerpagesetting.printdocument.defaultpagesettings.papersize.height -this.printerpagesetting.printdocument.defaultpagesettings.margins.top - this.printerpagesetting.printdocument.defaultpagesettings.margins.bottom;
//橫向打印,寬與高交換
if (this.printerpagesetting.printdocument.defaultpagesettings.landscape)
{
swap(ref width,ref height);
}
rectanglef recprintarea = new rectanglef(this.printerpagesetting.printdocument.defaultpagesettings.margins.left,this.printerpagesetting.printdocument.defaultpagesettings.margins.top,width,height);
drawtext drawtext = new drawtext(this.textbox1.text);
drawtext.graphics = g;
drawtext.rectanglef = recprintarea;
drawtext.startchar = intcurrentcharindex;
drawtext.draw();
intcurrentcharindex += drawtext.charsfitted;
if (intcurrentcharindex < this.textbox1.text.length)
{
return true;
}
else
{
intcurrentcharindex = 0;
return false;
}
}
//兩個數(shù)的值互換
private void swap(ref float i,ref float j)
{
float tmp = i;
i = j;
j = tmp;
}
在vb.net和c#的實現(xiàn)中,都分別寫了一個互換兩個數(shù)的值swap()函數(shù),供頁面橫向打印時調(diào)用,這里不再敖述。
還需要補充說明的是在上篇:
開源:.net環(huán)境下有關(guān)打印頁面設(shè)置、打印機設(shè)置、打印預(yù)覽對話框的實現(xiàn)
http://blog.csdn.net/flygoldfish/archive/2004/08/17/77208.aspx
中,我又稍有改動,列表如下:
1、iprinterpagesetting.cs中將printpage改為printpagevalue,增加event printpagedelegate printpage;
2、webprinterpagesetting.cs中將printpage改為printpagevalue,增加public event goldprinter.printpagedelegate printpage;
3、winprinterpagesetting.cs中printpage改為printpagevalue,增加
public event printpagedelegate printpage
{
add
{
_printdocument.printpage += new system.drawing.printing.printpageeventhandler(value);
_printpagevalue = value;
}
remove
{
_printdocument.printpage -= new system.drawing.printing.printpageeventhandler(value);
_printpagevalue = null;
}
}
4、printerpagesetting.cs中printpage改為printpagevalue,增加
public event printpagedelegate printpage
{
add
{
_printerpagesetting.printpage += new printpagedelegate(value);
}
remove
{
_printerpagesetting.printpage -= new printpagedelegate(value);
}
}
5、printerpagesetting.cs中將printerpagesetting的有參構(gòu)造函數(shù)public printerpagesetting(printdocument printdocument)
的_printerpagesetting.printdocument = printdocument;加一個判斷,即
if (printdocument != null)
{
_printerpagesetting.printdocument = printdocument;
}
這樣,系統(tǒng)會提供一個默認的printdocument對象。