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 = "继续";
}
}
经测试,这种方法完全能满足我们打印任务的控制要求.
※※※※※※※※※※※※※※--我的程序人生--※※※※※※※※※※※※※※