Đồ hoạ, đa phương tiện ( Mutilmedia) và In ấn Đồ họa phần 5

Chia sẻ: Nghia Bui Tuan | Ngày: | Loại File: PDF | Số trang:13

0
46
lượt xem
21
download

Đồ hoạ, đa phương tiện ( Mutilmedia) và In ấn Đồ họa phần 5

Mô tả tài liệu
  Download Vui lòng tải xuống để xem tài liệu đầy đủ

Bạn cần in text hoặc hình. Thụ lý sự kiện PrintDocument.PrintPage, và sử dụng các phương thức DrawString và DrawImage của lớp Graphics để in dữ liệu ra trang. .NET sử dụng mô hình in dựa-trên-sự-kiện bất đồng bộ (asynchronous event-based printing model)

Chủ đề:
Lưu

Nội dung Text: Đồ hoạ, đa phương tiện ( Mutilmedia) và In ấn Đồ họa phần 5

  1. 1.1 In văn bản đơn giản Bạn cần in text hoặc hình. Thụ lý sự kiện PrintDocument.PrintPage, và sử dụng các phương thức DrawString và DrawImage của lớp Graphics để in dữ liệu ra trang. .NET sử dụng mô hình in dựa-trên-sự-kiện bất đồng bộ (asynchronous event-based printing model). Để in một văn bản, bạn cần tạo một đối tượng System.Drawing.Printing.PrintDocument, cấu hình các thuộc tính của nó, và rồi gọi phương thức Print để thực hiện tác vụ in. Bộ thực thi sẽ phát sinh các sự kiện BeginPrint, PrintPage, và EndPrint của lớp PrintDocument trên một tiểu trình mới. Bạn thụ lý các sự kiện này và sử dụng đối tượng System.Drawing.Graphics để xuất dữ liệu ra trang. Hình và text được ghi ra trang theo cùng cách như bạn vẽ lên cửa sổ bằng GDI+. Tuy nhiên, bạn có thể cần phải theo vết vị trí của bạn trên trang, vì mọi phương thức của lớp Graphics đều yêu cầu tọa độ chỉ định nơi cần vẽ. Các thiết lập cho máy in được cấu hình thông qua các thuộc tính PrintDocument.PrinterSettings và PrintDocument.DefaultPageSettings. Thuộc tính PrinterSettings trả về một đối tượng PrinterSettings (đã được mô tả trong mục 8.12) cho biết máy in sẽ được sử dụng. Thuộc tính DefaultPageSettings cung cấp đối tượng PageSettings cho biết độ phân giải (resolution), lề (margin), hướng trang (orientation)... Bạn có thể cấu hình các thuộc tính này trong mã lệnh, hoặc bạn có thể sử dụng lớp System.Windows.Forms.PrintDialog để người dùng thực hiện các thay đổi thông qua hộp thoại in chuẩn của Windows (xem hình 8.9). Trong hộp thoại in, người dùng có thể chọn một máy in và chọn số lượng bản in (number of copies). Người dùng cũng có thể nhắp vào nút Properties để cấu hình các thiết lập nâng cao như cách bố trí trang (layout) và độ phân giải máy in (resolution). Cuối cùng, người dùng có thể chấp thuận hoặc hủy bỏ thao tác in bằng cách nhắp OK hoặc Cancel. The image part with relationship ID rId5 was not found in the file.
  2. Hình 8.9 Hộp thoại Print Trước khi sử dụng lớp PrintDialog, bạn phải gắn nó vào đối tượng PrintDocument bằng cách thiết lập thuộc tính PrintDialog.Document. Theo đó, bất kỳ sự thay đổi nào do người dùng thực hiện trong hộp thoại in sẽ tự động được áp dụng vào đối tượng PrintDocument. Ví dụ dưới đây là một form chỉ chứa một nút lệnh. Khi người dùng nhắp vào nút này, ứng dụng sẽ tạo một đối tượng PrintDocument mới, cho phép người dùng cấu hình các thiết lập in, và rồi bắt đầu thao tác in bất đồng bộ. Phương thức thụ lý sự kiện đáp ứng cho sự kiện PrintPage sẽ ghi ra nhiều dòng text và một bức hình. using System; using System.Windows.Forms; using System.Drawing; using System.Drawing.Printing; public class SimplePrint : System.Windows.Forms.Form { private System.Windows.Forms.Button cmdPrint; // (Bỏ qua phần mã designer.) private void cmdPrint_Click(object sender, System.EventArgs e) { // Tạo một văn bản và gắn vào phương thức thụ lý sự kiện. PrintDocument doc = new PrintDocument(); doc.PrintPage += new PrintPageEventHandler(this.Doc_PrintPage); // Cho phép người dùng chọn một máy in // và chỉ định các thiết lập khác. PrintDialog dlgSettings = new PrintDialog(); dlgSettings.Document = doc; // Nếu người dùng nhắp OK thì in văn bản. if (dlgSettings.ShowDialog() == DialogResult.OK) { // Phương thức này trả về tức thì, trước khi tác vụ in // bắt đầu. Sự kiện PrintPage sẽ phát sinh bất đồng bộ. doc.Print(); }
  3. } private void Doc_PrintPage(object sender, PrintPageEventArgs e) { // Định nghĩa font. Font font = new Font("Tahoma", 30); // Xác định vị trí trên trang. // Trong trường hợp này, chúng ta đọc các thiết lập lề // (mặc dù không có gì ngăn chúng ta vượt qua biên lề). float x = e.MarginBounds.Left; float y = e.MarginBounds.Top; // Xác định chiều cao của một dòng (dựa trên font được sử dụng). float lineHeight = font.GetHeight(e.Graphics); // In năm dòng text. for (int i=0; i < 5; i++) { // Vẽ text với bút vẽ đen, sử dụng font và // tọa độ mà chúng ta đã xác định. e.Graphics.DrawString("Thập Diện Mai Phục " + i.ToString(), font, Brushes.Black, x, y); // Dịch xuống một dòng. y += lineHeight; } y += lineHeight; // Vẽ hình. e.Graphics.DrawImage(Image.FromFile(Application.StartupPath + "\\test.bmp"), x, y); } } Ví dụ này có một hạn chế là nó chỉ in một trang đơn. Để in các văn bản phức tạp và nhiều trang hơn, bạn cần phải tạo một lớp chuyên biệt để đóng gói các thông tin về văn bản, trang hiện hành... Kỹ thuật này sẽ được trình bày trong mục 8.14.
  4. The image part with relationship ID rId6 was not found in the file. Hình 8-10 Văn bản đã được in (sử dụng máy in Adobe PDF) 1.2 In văn bản có nhiều trang Bạn cần in các văn bản phức tạp gồm nhiều trang và in nhiều văn bản khác nhau cùng một lúc. Đặt thông tin muốn in vào một lớp tùy biến dẫn xuất từ PrintDocument, và thiết lập thuộc tính PrintPageEventArgs.HasMorePages là true trong khi vẫn còn trang để in. Sự kiện PrintDocument.PrintPage cho phép bạn chỉ in một trang đơn. Nếu muốn in nhiều trang hơn, bạn cần thiết lập thuộc tính PrintPageEventArgs.HasMorePages là true trong phương thức thụ lý sự kiện PrintPage. Trong khi HasMorePages là true, lớp PrintDocument vẫn tiếp tục phát sinh các sự kiện PrintPage (một sự kiện cho một trang). Tuy nhiên, bạn cần biết là đang in đến trang thứ mấy, dữ liệu gì sẽ được in trên mỗi trang... Để thực hiện điều này, cách hay nhất là tạo một lớp tùy biến. Lớp TextDocument dưới đây thừa kế từ PrintDocument và thêm ba thuộc tính: Text lưu trữ một mảng các dòng text, PageNumber cho biết trang vừa được in, và Offset cho biết dòng vừa được in (trong mảng Text). public class TextDocument : PrintDocument { private string[] text; private int pageNumber; private int offset; public string[] Text {
  5. get {return text;} set {text = value;} } public int PageNumber { get {return pageNumber;} set {pageNumber = value;} } public int Offset { get {return offset;} set {offset = value;} } public TextDocument(string[] text) { this.Text = text; } } Tùy thuộc vào kiểu tài liệu muốn in, bạn có thể chỉnh sửa lớp này. Ví dụ, bạn có thể lưu trữ một mảng gồm các dữ liệu hình, một vài nội dung sẽ được sử dụng làm header hoặc footer trên mỗi trang, thông tin về font, hoặc tên của file mà bạn muốn đọc thông tin từ nó. Gói các thông tin này vào một lớp đơn sẽ khiến cho việc in nhiều văn bản cùng một lúc dễ dàng hơn. Phần mã khởi đầu cũng giống như mục 8.13, chỉ khác là bây giờ tạo đối tượng TextDocument (thay vì tạo đối tượng PrintDocument). Phương thức thụ lý sự kiện PrintPage giữ vết của dòng hiện hành và kiểm tra có còn chỗ trống trên trang hay không trước khi thực hiện in dòng kế tiếp. Nếu cần trang mới, thuộc tính HasMorePages được thiết lập là true và sự kiện PrintPage phát sinh lần nữa cho trang kế tiếp. Nếu không, thao tác in xem như hoàn tất. Phần mã đầy đủ cho form được trình bày dưới đây: using System; using System.Windows.Forms; using System.Drawing; using System.Drawing.Printing; public class MultiPagePrint : System.Windows.Forms.Form { private System.Windows.Forms.Button cmdPrint;
  6. // (Bỏ qua phần mã designer.) private void cmdPrint_Click(object sender, System.EventArgs e) { // Tạo văn bản gồm 100 dòng. string[] printText = new string[100]; for (int i=0; i < 100; i++) { printText[i] = i.ToString(); printText[i] += ": Thập Diện Mai Phục (House of Flying Daggers)"; } PrintDocument doc = new TextDocument(printText); doc.PrintPage += new PrintPageEventHandler(this.Doc_PrintPage); PrintDialog dlgSettings = new PrintDialog(); dlgSettings.Document = doc; // Nếu người dùng nhắp OK thì in văn bản. if (dlgSettings.ShowDialog() == DialogResult.OK) { doc.Print(); } } private void Doc_PrintPage(object sender, PrintPageEventArgs e) { // Thu lấy văn bản đã gửi sự kiện này. TextDocument doc = (TextDocument)sender; // Định nghĩa font và xác định chiều cao. Font font = new Font("Tahoma", 10); float lineHeight = font.GetHeight(e.Graphics); // Tạo các biến lưu giữ vị trí trên trang. float x = e.MarginBounds.Left; float y = e.MarginBounds.Top;
  7. // Tăng biến đếm cho trang (cho biết số trang đã được in). doc.PageNumber += 1; // In tất cả thông tin vừa khít trên trang. // Vòng lặp này kết thúc khi dòng kế tiếp vượt quá biên lề, // hoặc không còn dòng nào để in. while ((y + lineHeight) < e.MarginBounds.Bottom && doc.Offset
  8. Thông thường, bạn sẽ cần phá một khối text lớn thành các dòng riêng biệt để có thể in lên trang từng dòng một. .NET Framework có thể thực hiện công việc này một cách tự động bằng một phiên bản của phương thức Graphics.DrawString (nhận vào một hình chữ nhật biên). Bạn cần chỉ định hình chữ nhật mô tả nơi bạn muốn text sẽ hiển thị. Theo đó, text sẽ được wrap một cách tự động cho vừa khít bên trong đường biên này. Đoạn mã dưới đây thực hiện cách tiếp cận này: using System; using System.Windows.Forms; using System.Drawing; using System.Drawing.Printing; public class WrappedPrint : System.Windows.Forms.Form { private System.Windows.Forms.Button cmdPrint; // (Bỏ qua phần mã designer.) private void cmdPrint_Click(object sender, System.EventArgs e) { // Tạo một văn bản và gắn nó vào phương thức thụ lý sự kiện. string text = "Windows Server 2003 builds on the core strengths " + "of the Windows family of operating systems--security, " + "manageability, reliability, availability, and scalability. " + "Windows Server 2003 provides an application environment to " + "build, deploy, manage, and run XML Web services. " + "Additionally, advances in Windows Server 2003 provide many " + "benefits for developing applications."; PrintDocument doc = new ParagraphDocument(text); doc.PrintPage += new PrintPageEventHandler(this.Doc_PrintPage); // Cho phép người dùng chọn một máy in // và chỉ định các thiết lập khác. PrintDialog dlgSettings = new PrintDialog(); dlgSettings.Document = doc; // Nếu người dùng nhắp OK thì in văn bản. if (dlgSettings.ShowDialog() == DialogResult.OK) { doc.Print();
  9. } } private void Doc_PrintPage(object sender, PrintPageEventArgs e) { // Thu lấy văn bản đã gửi sự kiện này. ParagraphDocument doc = (ParagraphDocument)sender; // Định nghĩa font và text. Font font = new Font("Arial", 15); e.Graphics.DrawString(doc.Text, font, Brushes.Black, e.MarginBounds, StringFormat.GenericDefault); } } public class ParagraphDocument : PrintDocument { private string text; public string Text { get {return text;} set {text = value;} } public ParagraphDocument(string text) { this.Text = text; } } The image part with relationship ID rId7 was not found in the file. Hình 8.11 Văn bản đã được in (sử dụng máy in Adobe PDF)
  10. 1.4 Hiển thị print-preview Bạn cần sử dụng print-preview để biết được văn bản khi được in ra sẽ trông như thế nào. Sử dụng PrintPreviewDialog hoặc PrintPreviewControl (cả hai đều thuộc không gian tên System.Windows.Forms). .NET cung cấp hai điều kiểm có thể nhận vào một đối tượng PrintDocument, chạy đoạn mã thực hiện thao tác in, và sử dụng nó để tạo print-preview trên màn hình. Hai điều kiểm này là: • PrintPreviewDialog—hiển thị print-preview trong một cửa sổ độc lập. • PrintPreviewControl—hiển thị print-preview trong một form tùy biến. Để sử dụng cửa sổ print-preview độc lập, bạn cần tạo đối tượng PrintPrevewDialog, ấn định văn bản, và gọi phương thức PrintPreviewDialog.Show. PrintPreviewDialog dlgPreview = new PrintPreviewDialog(); dlgPreview.Document = doc; dlgPreview.Show(); Cửa sổ print-preview (xem hình 8.12) cung cấp tất cả các điều khiển cần thiết để di chuyển từ trang này sang trang khác, thu phóng trang... Cửa sổ này cũng cung cấp nút Print cho phép người dùng gửi trực tiếp văn bản đến máy in. Bạn có thể biến đổi cửa sổ này bằng cách chỉnh sửa các thuộc tính của PrintPrevewDialog. Bạn cũng có thể thêm PrintPreviewControl vào bất kỳ form nào để hiển thị print-preview kế bên các thông tin khác. Trong trường hợp này, bạn không cần gọi phương thức Show. Ngay khi bạn thiết lập thuộc tính PrintPreviewControl.Document thì preview được tạo ra. Để xóa preview, cần thiết lập thuộc tính Document là null, và để làm tươi preview, cần gán lại thuộc tính Document. PrintPreviewControl chỉ hiển thị các trang preview, không có thêm điều khiển nào khác. Tuy nhiên, bạn có thể thêm các điều kiểm để thực hiện thu phóng trang, lát nhiều trang... Bạn chỉ cần điều chỉnh các thuộc tính của PrintPreviewControl cho phù hợp. Ví dụ, xét form được trình bày trong hình 8.13. Nó sáp nhập một PrintPreviewControl và cho phép người dùng chọn thiết lập cho zoom (thu phóng trang).
  11. The image part with relationship ID rId8 was not found in the file. Hình 8.12 Sử dụng PrintPreviewDialog để hiển thị print-preview trong một cửa sổ độc lập The image part with relationship ID rId9 was not found in the file. Hình 8.13 Sử dụng PrintPreviewControl để hiển thị print-preview trong một cửa sổ tùy biến Dưới đây là phần mã cho form: using System; using System.Windows.Forms; using System.Drawing; using System.Drawing.Printing; public class PrintPreview : System.Windows.Forms.Form { private System.Windows.Forms.PrintPreviewControl printPreviewControl;
  12. private System.Windows.Forms.Button cmdPreview; private System.Windows.Forms.ListBox lstZoom; private System.Windows.Forms.Label label1; // (Bỏ qua phần mã designer.) private PrintDocument doc; // (Bỏ qua phần mã cho phương thức thụ lý sự kiện // PrintDocument.PrintPage - Xem mục 8.14) private void PrintPreview_Load(object sender, System.EventArgs e) { // Thiết lập các zoom được phép. for (int i=1; i
  13. // Hiển thị cả hai trang, trang này ở trên trang kia. printPreviewControl.Rows = 2; // Gắn lại PrintDocument để làm tươi preview. printPreviewControl.Document = doc; } } // (Bỏ qua phần mã cho lớp TextDocument - Xem mục 8.14) 1.5 Quản lý tác vụ in Bạn cần tạm dừng hoặc phục hồi một tác vụ in hoặc một hàng đợi in. Sử dụng Windows Management Instrumentation. Bạn có thể lấy thông tin từ hàng đợi in bằng một truy vấn với lớp Win32_PrintJob, và bạn có thể sử dụng các phương thức Pause và Resume của các lớp Win32_PrintJob và Win32_Printer để quản lý hàng đợi. Windows Management Instrumentation (WMI) cho phép bạn lấy một lượng lớn các thông tin hệ thống bằng một cú pháp giống truy vấn. Một trong các công việc mà bạn có thể thực hiện với WMI là lấy danh sách các tác vụ in đang chờ, cùng với thông tin về mỗi tác vụ. Bạn cũng có thể thực hiện các thao tác như in và phục hồi một tác vụ hoặc tất cả các tác vụ cho một máy in. Để sử dụng WMI, bạn cần thêm một tham chiếu đến System.Management.dll. Ứng dụng dưới đây thực hiện một truy vấn WMI để lấy danh sách tất cả các tác vụ in đang chờ trên máy tính và hiển thị ID cho mỗi tác vụ trong một ListBox. Khi người dùng chọn một item, một truy vấn đầy đủ hơn sẽ được thực hiện, và các chi tiết về tác vụ in này được hiển thị trong một TextBox. Cuối cùng, người dùng có thể nhắp nút Pause và Resume sau khi chọn một tác vụ để thay đổi trạng thái của nó.
Đồng bộ tài khoản