C#中,通常涉及到列印,我們一般都會用到PrintDocument類,用該類來實現列印真是又方便又強大.程式員可以非常輕鬆的控制列印內容.然而PrintDocument類提供了列印"取消"功能,卻沒有為我們提供列印的"暫停"與"繼續".這對與想在列印過程中實現對列印任務的控制的初學者來說,製造了不少麻煩.
其實,實現列印任務的"暫停"與"繼續".我們可以藉助於API函數"SetJob"來實現.這個函數可以對一個列印工作的狀態進行控制,它在VB中的聲明如下:
Declare Function SetJob Lib "winspool.drv" Alias "SetJobA" (ByVal hPrinter As Long, ByVal JobId As Long, ByVal Level As Long, pJob As Byte, ByVal Command As Long) As Long
傳回值及相關參數說明請參考有關資料,這本不想過多的闡述.因為本文想著重講的是在C#中如何簡單有效控制列印任務.
由列印任務的暫停與繼續我們可能很自然的想到了C#中線程的暫停與繼續.而如果把列印任務運行在某個線程上,然後控制該線程的暫停與繼續,不就可以實現對列印任務的控制了嗎?
想到這裡,那我們就動手測試一下吧:
列印暫停時的介面:
以下為關鍵代碼:
Thread th;
private int pageCounter;
public delegate void invoke();
private void button1_Click(object sender, System.EventArgs e)
{
pageCounter = 0;
//開始一個新的線程來完成列印任務:
th = new Thread( new ThreadStart( printDocumentWithAHardJob.Print));
th.Start();
//列印開始以後,原"列印"按鈕不可用,後"暫停"變得可用.
button1.Enabled = false;
button3.Enabled = true;
}
//這是實現列印內容的關鍵方法.每列印一頁,都會執行一次該方法.注意啦,該方法已經運行在新建立的th線程上了.
private void printDocumentWithAHardJob_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
//每頁列印前小停一會,以便我們觀察列印過程,實際列印中可以不要這一句
System.Threading.Thread.Sleep(Convert.ToInt32(numericUpDownDelay.Value));
//以下幾句在頁面上畫一個圖形,做為列印輸入的頁面內容
e.Graphics.DrawRectangle(Pens.Black, e.MarginBounds);
e.Graphics.DrawLine(Pens.Black, e.MarginBounds.X, e.MarginBounds.Y, e.MarginBounds.X + e.MarginBounds.Width, e.MarginBounds.Y + e.MarginBounds.Height);
e.Graphics.DrawLine(Pens.Black, e.MarginBounds.X + e.MarginBounds.Width, e.MarginBounds.Y, e.MarginBounds.X, e.MarginBounds.Y + e.MarginBounds.Height);
pageCounter++;
//檢查是否列印完成
if (pageCounter == numericUpDownPages.Value)
{
e.HasMorePages = false;
//以下為調用委託方法來完成對主線程上幾個按鈕可用性的設定(線程間的操作,不可以直接存取非當前線程上建立的控制項)
invoke InvokeMothed=new invoke(SetButton);
this.Invoke(InvokeMothed);
}
else
e.HasMorePages = true;
}
//委託方法
private void SetButton()
{
button1.Enabled = true;
button3.Enabled = false;
}
//根據th線程的狀態來控制列印任務(即th線程)的掛起與恢複
private void button3_Click(object sender, EventArgs e)
{
if (th.ThreadState == ThreadState.Suspended)
{
th.Resume();
button3.Text = "暫停";
}
else if(th.IsAlive)
{
th.Suspend();
button3.Text = "繼續";
}
}
經測試,這種方法完全能滿足我們列印任務的控制要求.
測試源碼:http://files.cnblogs.com/luckeryin/PrintTest.rar