Wednesday, February 18, 2009

Printing in C# (2)

Printing in C#, an Introduction Which Works


Printing, previewing, and setting up pages is not simple. Here's an attempt at getting a
novice started. It's my second attempt (and I hope my last); the first attempt is also shown on this blog.


Starting out with a new Project (named PrintTest2 here), in the Form editor, we drag from the toolbar the buttons and Printing components we need.

The final form at the end of the insertion process has three buttons, and four non-Form related items (they are below the form). As usual, their names, the identifiers used to address them, can be changed.


I'm assuming that the reader will also borrow code as necessary. The only thing different here is that instead of having a fixed text file for viewing or printing, I've put in an OpenFile dialog which is off topic). Of course, I could have put in two, one for printing and one for previewing, but the reader can easily do this if s/he wishes, which shows (4 components added from the toolbox.

The code has been copied from MSDN (I think there's automatically permission given to this kind of non-profit quoting) in large measure. Here's the full code:


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Printing;
using System.IO;


namespace PrintTest2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{

}

private void pageSetupButton_Click(object sender, EventArgs e)
//This method displays a PageSetupDialog object. If the
// user clicks OK in the dialog, selected results of
// the dialog are displayed in ListBox1.
{

// Initialize the dialog's PrinterSettings property to hold user
// defined printer settings.
PageSetupDialog1.PageSettings =
new System.Drawing.Printing.PageSettings();

// Initialize dialog's PrinterSettings property to hold user
// set printer settings.
PageSetupDialog1.PrinterSettings =
new System.Drawing.Printing.PrinterSettings();

//Do not show the network in the printer dialog.
PageSetupDialog1.ShowNetwork = false;

//Show the dialog storing the result.
DialogResult result = PageSetupDialog1.ShowDialog();

// If the result is OK, display selected settings in
// ListBox1. These values can be used when printing the
// document.
if (result == DialogResult.OK)
{
object[] results = new object[]{
PageSetupDialog1.PageSettings.Margins,
PageSetupDialog1.PageSettings.PaperSize,
PageSetupDialog1.PageSettings.Landscape,
PageSetupDialog1.PrinterSettings.PrinterName,
PageSetupDialog1.PrinterSettings.PrintRange};
//listBox1.Items.AddRange(results);//changed case (l)istBox1
}
}


// The Click event is raised when the user clicks the Print button.
private void printButton_Click_1(object sender, EventArgs e)
{
OpenFileDialog dialog = new OpenFileDialog();
dialog.Filter = "txt files (*.txt)*.txtAll files (*.*)*.*";
dialog.InitialDirectory = "C:\\";
dialog.Title = "Choose a file to print";
if (dialog.ShowDialog() == DialogResult.OK)
{

PrintDocument pd = new PrintDocument();
PrintDialog dlgSettings = new PrintDialog();

dlgSettings.Document = pd;
pd.DocumentName = dialog.FileName;
if (dlgSettings.ShowDialog() == DialogResult.OK)

{
try
{
streamToPrint = new StreamReader
(dialog.FileName);
try
{
printFont = new Font("Arial", 10);

pd.PrintPage += new PrintPageEventHandler
(this.pd_PrintPage);
pd.Print();
}
finally
{
streamToPrint.Close();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
}

// The PrintPage event is raised for each page to be printed.
private void pd_PrintPage(object sender, PrintPageEventArgs ev)
{
float linesPerPage = 0;
float yPos = 0;
int count = 0;
float leftMargin = ev.MarginBounds.Left;
float topMargin = ev.MarginBounds.Top;
string line = null;

// Calculate the number of lines per page.
linesPerPage = ev.MarginBounds.Height /
printFont.GetHeight(ev.Graphics);

// Print each line of the file.
while (count < line =" streamToPrint.ReadLine())" ypos =" topMargin" hasmorepages =" true;" hasmorepages =" false;" document =" printDocument1;" printpreviewdialog1 =" new" printdocument1 =" new" printpreviewdialog1 =" new" clientsize =" new" location =" new" name = "PrintPreviewDialog2" minimumsize =" new" useantialias =" true;" charactersonpage =" 0;" linesperpage =" 0;" stringtoprint =" stringToPrint.Substring(charactersOnPage);" hasmorepages =" (stringToPrint.Length"> 0);

// If there are no more pages, reset the string to be printed.
if (!e.HasMorePages)
stringToPrint = documentContents;
}

private void ReadDocument()//used in preview
{
string docName = "isorecorder.log";
string docPath = @"c:\";
printDocument1.DocumentName = docName;
using (FileStream stream = new FileStream(docPath + docName, FileMode.Open))
using (StreamReader reader = new StreamReader(stream))
{
documentContents = reader.ReadToEnd();
}
stringToPrint = documentContents;
}


private Font printFont;
private StreamReader streamToPrint;
// the following is from http://msdn.microsoft.com/en-us/library/ms404294(printer).aspx

// Declare a string to hold the entire document contents.
private string documentContents;

// Declare a variable to hold the portion of the document that
// is not printed.
private string stringToPrint;
}
}

Here is the InitializeComponent() code generated during the dragging operations:


namespace PrintTest2
{
partial class Form1
{
///


/// Required designer variable.
///

private System.ComponentModel.IContainer components = null;
///
/// Clean up any resources being used.
///

/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///

private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
this.printButton = new System.Windows.Forms.Button();
this.printDocument1 = new System.Drawing.Printing.PrintDocument();
this.printDialog1 = new System.Windows.Forms.PrintDialog();
this.PageSetupDialog1 = new System.Windows.Forms.PageSetupDialog();
this.previewButton = new System.Windows.Forms.Button();
this.pageSetupButton = new System.Windows.Forms.Button();
this.printPreviewDialog1 = new System.Windows.Forms.PrintPreviewDialog();
this.SuspendLayout();
//
// printButton
//
this.printButton.Location = new System.Drawing.Point(12, 12);
this.printButton.Name = "printButton";
this.printButton.Size = new System.Drawing.Size(125, 23);
this.printButton.TabIndex = 0;
this.printButton.Text = "Press to Print";
this.printButton.UseVisualStyleBackColor = true;
this.printButton.Click += new System.EventHandler(this.printButton_Click_1);
//
// printDocument1
//
this.printDocument1.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(this.printDocument1_PrintPage);
//
// printDialog1
//
this.printDialog1.UseEXDialog = true;
//
// previewButton
//
this.previewButton.Location = new System.Drawing.Point(162, 12);
this.previewButton.Name = "previewButton";
this.previewButton.Size = new System.Drawing.Size(125, 23);
this.previewButton.TabIndex = 2;
this.previewButton.Text = "Press to Preview";
this.previewButton.UseVisualStyleBackColor = true;
this.previewButton.Click += new System.EventHandler(this.previewButton_Click);
//
// pageSetupButton
//
this.pageSetupButton.Location = new System.Drawing.Point(302, 12);
this.pageSetupButton.Name = "pageSetupButton";
this.pageSetupButton.Size = new System.Drawing.Size(125, 23);
this.pageSetupButton.TabIndex = 3;
this.pageSetupButton.Text = "Press to SetUp Page";
this.pageSetupButton.UseVisualStyleBackColor = true;
this.pageSetupButton.Click += new System.EventHandler(this.pageSetupButton_Click);
//
// printPreviewDialog1
//
this.printPreviewDialog1.AutoScrollMargin = new System.Drawing.Size(0, 0);
this.printPreviewDialog1.AutoScrollMinSize = new System.Drawing.Size(0, 0);
this.printPreviewDialog1.ClientSize = new System.Drawing.Size(400, 300);
this.printPreviewDialog1.Enabled = true;
this.printPreviewDialog1.Icon = ((System.Drawing.Icon)(resources.GetObject("printPreviewDialog1.Icon")));
this.printPreviewDialog1.Name = "PrintPreviewDialog1";
this.printPreviewDialog1.Visible = false;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(438, 59);
this.Controls.Add(this.pageSetupButton);
this.Controls.Add(this.previewButton);
this.Controls.Add(this.printButton);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Button printButton;
private System.Windows.Forms.PrintDialog printDialog1;
private System.Windows.Forms.PageSetupDialog PageSetupDialog1;
private System.Windows.Forms.Button previewButton;
private System.Windows.Forms.Button pageSetupButton;
public string documentsContents;
}
}

I find all of this incomprehensible in the sense that dragging the printing parts to the form was treated so differently, and non-intuitively, from dragging buttons, labels, etc..Debugging it was just plain terrible. But it works, and as of II/2009, please accept it as useful.

Monday, February 2, 2009

Editing with Equations

Equations in Google Docs





This manuscript does not appear properly in FireFox, and I use IE always to see the pictures and equations properly.



We open sitmo in IE (firefox doesn't show sitmo properly for some unknown reason)eq=-\frac{\hbar}{2 \pi}\nabla^2 \psi +V\psi=E\psi


and type the latex as needed. Then, right click on the image and copy it, return to docs, and paste it. Wow! NOT REALLY.

This won't print. You need to save the image out of sitmo on your desktop, and then use

Insert->Picture in docs and find the image and upload it. We obtain the

pasted image (here):



Here's what the sitmo screen looked like ( I put the border on):


showing the Latex I typed (in red), the Schroedinger Equation as formatted, so all that's missing is the right click on the formatted equation and the accompanying paste into my Google Docs. Of course, you have to ignore the physics error!





How about directly inserting Latex (via codecogs rather than sitmo) using Edit->Edit HTML: using an online codecogs editor and the code shown in this footnote<a href="http://www.codecogs.com/eqnedit.php?latex=-%5Cfrac%7B%5Chbar%7D%7B2 \pi}\nabla^2 \psi +V\psi=E\psi"><img src="http://latex.codecogs.com/gif.latex?-%5Cfrac%7B%5Chbar%7D%7B2&space;%5Cpi%7D%5Cnabla%5E2&space;%5Cpsi&space;+V%5Cpsi=E%5Cpsi" title="-\frac{\hbar}{2 \pi}\nabla^2 \psi +V\psi=E\psi" border="1"/></a>. This one prints badly also, since there are extraneous spaces which IE can't handle. In the footnote, you will see the offending spaces explicitly.



Here is the final rendering, absent spaces (better physics but doesn't show on FireFox!, only IE):




which should be OK (in IE, on screen and printed).

Here's a screen dump of codecogs.com:


The disadvantage of this scheme is that if one downloads the manuscript (say in Word form) the link will be inactivated! Thus one is umbilically bound to Google Docs (not necessarily a bad thing).

I would be remiss if I didn't note that material such as this exists on the WWW.