Printing BarCodes in Silverlight

19. January 2012 10:32 by Mrojas in Silverlight  //  Tags: , , , ,   //   Comments (0)

Well I tought this was gonna be more difficult, but no. The Silverlight community is great and there are tons of
of  code out there.

So I found a great project in codeplex called obviously http://silverlightbarcode.codeplex.com/

And printing barcode with that library is a peace of cake.

Just do something like this:

 

private void button1_Click(object sender, RoutedEventArgs e)
{
    var p = new PrintDocument();
    p.PrintPage += new EventHandler<PrintPageEventArgs>(p_PrintPage);
    p.Print("NuevoDocument");
}

void p_PrintPage(object sender, PrintPageEventArgs e)
{
    Canvas canvasBarCode = new Canvas();
    canvasBarCode.Width = 200;
    canvasBarCode.Height = 200;
    Me.BarcodeSoftware.Barcode.Barcodes barcode = 
           new Me.BarcodeSoftware.Barcode.Barcodes();
    barcode.BarcodeType =        
                  Me.BarcodeSoftware.Barcode.Barcodes.BarcodeEnum.Code39;
    barcode.Data = "123456";
    barcode.encode();
    string encodedData = barcode.EncodedData;
    //if you want to put the barcode number 
        // add a label to canvas and set text to barcode.HumanText;

    int encodedLength = 0;
    for (int x = 0; x < encodedData.Length; x++)
    {
        if (encodedData[x] == 't')
            encodedLength++;
        else if (encodedData[x] == 'w')
            encodedLength = encodedLength + 3;
    }

    float barWidth = (float)(canvasBarCode.Width / encodedLength);

    if (barWidth < 1) barWidth = 1;
    float thickWidth = barWidth * 3;
    double incrementWidth = 0;

    int swing = 0;
    for (int x = 0; x < encodedData.Length; x++)
    {
        Brush brush;
        if (swing == 0)
            brush = new SolidColorBrush(Colors.Black);
        else
            brush = new SolidColorBrush(Colors.White);

        if (encodedData[x] == 't')
        {
            Rectangle r = new Rectangle();
            r.Fill = brush;
            r.Width = barWidth;
            r.Height = canvasBarCode.Height;
            r.SetValue(Canvas.LeftProperty, incrementWidth);
            r.SetValue(Canvas.TopProperty, 0.0);
            canvasBarCode.Children.Add(r);
            incrementWidth = incrementWidth + ((barWidth));
        }
        else if (encodedData[x] == 'w')
        {
            Rectangle r = new Rectangle();
            r.Fill = brush;
            r.Width = 3 * barWidth;
            r.Height = canvasBarCode.Height;
            r.SetValue(Canvas.LeftProperty, incrementWidth);
            r.SetValue(Canvas.TopProperty, 0.0);
            canvasBarCode.Children.Add(r);
            incrementWidth = incrementWidth + (3 * (barWidth));
        }

        if (swing == 0)
           swing = 1;
        else
           swing = 0;
    }
    e.PageVisual = canvasBarCode;
    e.HasMorePages = false;

}

Printing BarCodes in Silverlight

19. January 2012 10:32 by Mrojas in Silverlight  //  Tags: , , , ,   //   Comments (0)

Well I tought this was gonna be more difficult, but no. The Silverlight community is great and there are tons of
of  code out there.

So I found a great project in codeplex called obviously http://silverlightbarcode.codeplex.com/

And printing barcode with that library is a peace of cake.

Just do something like this:

 

private void button1_Click(object sender, RoutedEventArgs e)
{
    var p = new PrintDocument();
    p.PrintPage += new EventHandler<PrintPageEventArgs>(p_PrintPage);
    p.Print("NuevoDocument");
}

void p_PrintPage(object sender, PrintPageEventArgs e)
{
    Canvas canvasBarCode = new Canvas();
    canvasBarCode.Width = 200;
    canvasBarCode.Height = 200;
    Me.BarcodeSoftware.Barcode.Barcodes barcode = 
           new Me.BarcodeSoftware.Barcode.Barcodes();
    barcode.BarcodeType =        
                  Me.BarcodeSoftware.Barcode.Barcodes.BarcodeEnum.Code39;
    barcode.Data = "123456";
    barcode.encode();
    string encodedData = barcode.EncodedData;
    //if you want to put the barcode number 
        // add a label to canvas and set text to barcode.HumanText;

    int encodedLength = 0;
    for (int x = 0; x < encodedData.Length; x++)
    {
        if (encodedData[x] == 't')
            encodedLength++;
        else if (encodedData[x] == 'w')
            encodedLength = encodedLength + 3;
    }

    float barWidth = (float)(canvasBarCode.Width / encodedLength);

    if (barWidth < 1) barWidth = 1;
    float thickWidth = barWidth * 3;
    double incrementWidth = 0;

    int swing = 0;
    for (int x = 0; x < encodedData.Length; x++)
    {
        Brush brush;
        if (swing == 0)
            brush = new SolidColorBrush(Colors.Black);
        else
            brush = new SolidColorBrush(Colors.White);

        if (encodedData[x] == 't')
        {
            Rectangle r = new Rectangle();
            r.Fill = brush;
            r.Width = barWidth;
            r.Height = canvasBarCode.Height;
            r.SetValue(Canvas.LeftProperty, incrementWidth);
            r.SetValue(Canvas.TopProperty, 0.0);
            canvasBarCode.Children.Add(r);
            incrementWidth = incrementWidth + ((barWidth));
        }
        else if (encodedData[x] == 'w')
        {
            Rectangle r = new Rectangle();
            r.Fill = brush;
            r.Width = 3 * barWidth;
            r.Height = canvasBarCode.Height;
            r.SetValue(Canvas.LeftProperty, incrementWidth);
            r.SetValue(Canvas.TopProperty, 0.0);
            canvasBarCode.Children.Add(r);
            incrementWidth = incrementWidth + (3 * (barWidth));
        }

        if (swing == 0)
           swing = 1;
        else
           swing = 0;
    }
    e.PageVisual = canvasBarCode;
    e.HasMorePages = false;

}

Printing BarCodes in Silverlight

19. January 2012 10:32 by Mrojas in   //  Tags: , , , ,   //   Comments (0)

Well I tought this was gonna be more difficult, but no. The Silverlight community is great and there are tons of
of  code out there.

So I found a great project in codeplex called obviously http://silverlightbarcode.codeplex.com/

And printing barcode with that library is a peace of cake.

Just do something like this:

 

private void button1_Click(object sender, RoutedEventArgs e)
{
    var p = new PrintDocument();
    p.PrintPage += new EventHandler<PrintPageEventArgs>(p_PrintPage);
    p.Print("NuevoDocument");
}

void p_PrintPage(object sender, PrintPageEventArgs e)
{
    Canvas canvasBarCode = new Canvas();
    canvasBarCode.Width = 200;
    canvasBarCode.Height = 200;
    Me.BarcodeSoftware.Barcode.Barcodes barcode = 
           new Me.BarcodeSoftware.Barcode.Barcodes();
    barcode.BarcodeType =        
                  Me.BarcodeSoftware.Barcode.Barcodes.BarcodeEnum.Code39;
    barcode.Data = "123456";
    barcode.encode();
    string encodedData = barcode.EncodedData;
    //if you want to put the barcode number 
        // add a label to canvas and set text to barcode.HumanText;

    int encodedLength = 0;
    for (int x = 0; x < encodedData.Length; x++)
    {
        if (encodedData[x] == 't')
            encodedLength++;
        else if (encodedData[x] == 'w')
            encodedLength = encodedLength + 3;
    }

    float barWidth = (float)(canvasBarCode.Width / encodedLength);

    if (barWidth < 1) barWidth = 1;
    float thickWidth = barWidth * 3;
    double incrementWidth = 0;

    int swing = 0;
    for (int x = 0; x < encodedData.Length; x++)
    {
        Brush brush;
        if (swing == 0)
            brush = new SolidColorBrush(Colors.Black);
        else
            brush = new SolidColorBrush(Colors.White);

        if (encodedData[x] == 't')
        {
            Rectangle r = new Rectangle();
            r.Fill = brush;
            r.Width = barWidth;
            r.Height = canvasBarCode.Height;
            r.SetValue(Canvas.LeftProperty, incrementWidth);
            r.SetValue(Canvas.TopProperty, 0.0);
            canvasBarCode.Children.Add(r);
            incrementWidth = incrementWidth + ((barWidth));
        }
        else if (encodedData[x] == 'w')
        {
            Rectangle r = new Rectangle();
            r.Fill = brush;
            r.Width = 3 * barWidth;
            r.Height = canvasBarCode.Height;
            r.SetValue(Canvas.LeftProperty, incrementWidth);
            r.SetValue(Canvas.TopProperty, 0.0);
            canvasBarCode.Children.Add(r);
            incrementWidth = incrementWidth + (3 * (barWidth));
        }

        if (swing == 0)
           swing = 1;
        else
           swing = 0;
    }
    e.PageVisual = canvasBarCode;
    e.HasMorePages = false;

}

Setting the Default Printer in .NET

 
The following C# code shows how to use WMI to query printers information, set and get default printer.
public bool SetDefaultPrinter()
{
    System.Management.ManagementObjectSearcher search = 
default(System.Management.ManagementObjectSearcher); System.Management.ManagementObjectCollection results =
default(System.Management.ManagementObjectCollection); System.Management.ManagementObject printer =
default(System.Management.ManagementObject); search =
new System.Management.ManagementObjectSearcher("select * from win32_printer"); results = search.Get(); //Get Default Printer System.Management.ManagementObject defaultPrinter = null; foreach (System.Management.ManagementObject foundPrinter in results) { System.Management.PropertyDataCollection
propertyDataCollection = foundPrinter.Properties; if ((bool)foundPrinter["Default"]) // DEFAULT PRINTER { System.Diagnostics.Debug.WriteLine(foundPrinter["Name"]); System.Diagnostics.Debug.WriteLine(foundPrinter["Location"]); } } //Sets new default Printer foreach (System.Management.ManagementObject foundPrinter in results) { System.Diagnostics.Debug.Print(foundPrinter["Name"].ToString()); if (foundPrinter["Name"].Equals("PDFCreator")) { System.Management.ManagementBaseObject outParams =
foundPrinter.InvokeMethod("SetDefaultPrinter", null, null); if (outParams == null) System.Diagnostics.Debug.WriteLine("Unable to set default printer"); Int32 retVal = (int)(uint)outParams.Properties["ReturnValue"].Value; if (retVal == 0) return true; else return false; } } return false; }

Printing RichTextBox contents in C#

10. July 2009 05:54 by Mrojas in General  //  Tags: , , , ,   //   Comments (0)

This post discusses and provides the implementation of a helper class to add support
for printing the formatted contents of a richtextbox control.

The print model in .NET is a little different than one used in VB6.

For example see: http://support.microsoft.com/kb/146022

Public Sub PrintRTF(RTF As RichTextBox, LeftMarginWidth As Long, _
   TopMarginHeight, RightMarginWidth, BottomMarginHeight)
   Dim LeftOffset As Long, TopOffset As Long
   Dim LeftMargin As Long, TopMargin As Long
   Dim RightMargin As Long, BottomMargin As Long
   Dim fr As FormatRange
   Dim rcDrawTo As Rect
   Dim rcPage As Rect
   Dim TextLength As Long
   Dim NextCharPosition As Long
   Dim r As Long

   ' Start a print job to get a valid Printer.hDC
   Printer.Print Space(1)
   Printer.ScaleMode = vbTwips

   ' Get the offsett to the printable area on the page in twips
   LeftOffset = Printer.ScaleX(GetDeviceCaps(Printer.hdc, _
      PHYSICALOFFSETX), vbPixels, vbTwips)
   TopOffset = Printer.ScaleY(GetDeviceCaps(Printer.hdc, _
      PHYSICALOFFSETY), vbPixels, vbTwips)

   ' Calculate the Left, Top, Right, and Bottom margins
   LeftMargin = LeftMarginWidth - LeftOffset
   TopMargin = TopMarginHeight - TopOffset
   RightMargin = (Printer.Width - RightMarginWidth) - LeftOffset
   BottomMargin = (Printer.Height - BottomMarginHeight) - TopOffset

   ' Set printable area rect
   rcPage.Left = 0
   rcPage.Top = 0
   rcPage.Right = Printer.ScaleWidth
   rcPage.Bottom = Printer.ScaleHeight

   ' Set rect in which to print (relative to printable area)
   rcDrawTo.Left = LeftMargin
   rcDrawTo.Top = TopMargin
   rcDrawTo.Right = RightMargin
   rcDrawTo.Bottom = BottomMargin

   ' Set up the print instructions
   fr.hdc = Printer.hdc   ' Use the same DC for measuring and rendering
   fr.hdcTarget = Printer.hdc  ' Point at printer hDC
   fr.rc = rcDrawTo            ' Indicate the area on page to draw to
   fr.rcPage = rcPage          ' Indicate entire size of page
   fr.chrg.cpMin = 0           ' Indicate start of text through
   fr.chrg.cpMax = -1          ' end of the text

   ' Get length of text in RTF
   TextLength = Len(RTF.Text)

   ' Loop printing each page until done
   Do
      ' Print the page by sending EM_FORMATRANGE message
      NextCharPosition = SendMessage(RTF.hWnd, EM_FORMATRANGE, True, fr)
      If NextCharPosition >= TextLength Then Exit Do  'If done then exit
      fr.chrg.cpMin = NextCharPosition ' Starting position for next page
      Printer.NewPage                  ' Move on to next page
      Printer.Print Space(1) ' Re-initialize hDC
      fr.hdc = Printer.hdc
      fr.hdcTarget = Printer.hdc
   Loop

   ' Commit the print job
   Printer.EndDoc

   ' Allow the RTF to free up memory
   r = SendMessage(RTF.hWnd, EM_FORMATRANGE, False, ByVal CLng(0))
End Sub

The VBCompanion provides excellent helpers that provide a lot fo the VB6 Printer object functionality, so you dont have to change any of your actual code, but in some cases, you might just want to remove that code, specially for very specific things like printing a RichTextBox.

So here I’m providing a .NET simplified helper that allows you to print the contents of a RichTextBox control. This helper is just based on the code published by Martin Muller in http://msdn.microsoft.com/en-us/library/ms996492.aspx. It provides an extension method for VS 2008 user so all you have to do is call RichTextBox.Print.

The implementation is simple. The RichTextBoxPrintHelper creates or receives an instance of a PrintDocument object, and event handlers are added to it for the BeginPrint, PrintPage and EndPrint events.

    private int m_nFirstCharOnPage;

    private void printDocument_BeginPrint(object sender, System.Drawing.Printing.PrintEventArgs e)
    {
        // Start at the beginning of the text
        m_nFirstCharOnPage = 0;
    }

    private void printDocument_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
    {
        // To print the boundaries of the current page margins
        // uncomment the next line:
        //e.Graphics.DrawRectangle(System.Drawing.Pens.Blue, e.MarginBounds);

        // make the RichTextBoxEx calculate and render as much text as will
        // fit on the page and remember the last character printed for the
        // beginning of the next page
        m_nFirstCharOnPage = FormatRange(false,
            e,
            m_nFirstCharOnPage,
            control.TextLength);

        // check if there are more pages to print
        if (m_nFirstCharOnPage < control.TextLength)
            e.HasMorePages = true;
        else
            e.HasMorePages = false;
    }

    private void printDocument_EndPrint(object sender, System.Drawing.Printing.PrintEventArgs e)
    {
        // Clean up cached information
        FormatRangeDone();
    }
The FormatRange method is called. This method will use the fill out some structures 
with page information and use the RichTextBox handle to send messages that will render
the control contents to the Printer’s HDC.
 
 /// <summary>
    /// Calculate or render the contents of our RichTextBox for printing
    /// </summary>
    /// <param name="measureOnly">If true, only the calculation is performed,
    /// otherwise the text is rendered as well</param>
    /// <param name="e">The PrintPageEventArgs object from the
    /// PrintPage event</param>
    /// <param name="charFrom">Index of first character to be printed</param>
    /// <param name="charTo">Index of last character to be printed</param>
    /// <returns>(Index of last character that fitted on the
    /// page) + 1</returns>
    public int FormatRange(bool measureOnly, PrintPageEventArgs e,
        int charFrom, int charTo)
    {
        // Specify which characters to print
        STRUCT_CHARRANGE cr;
        cr.cpMin = charFrom;
        cr.cpMax = charTo;

        // Specify the area inside page margins
        STRUCT_RECT rc;
        rc.top = HundredthInchToTwips(e.MarginBounds.Top);
        rc.bottom = HundredthInchToTwips(e.MarginBounds.Bottom);
        rc.left = HundredthInchToTwips(e.MarginBounds.Left);
        rc.right = HundredthInchToTwips(e.MarginBounds.Right);

        // Specify the page area
        STRUCT_RECT rcPage;
        rcPage.top = HundredthInchToTwips(e.PageBounds.Top);
        rcPage.bottom = HundredthInchToTwips(e.PageBounds.Bottom);
        rcPage.left = HundredthInchToTwips(e.PageBounds.Left);
        rcPage.right = HundredthInchToTwips(e.PageBounds.Right);

        // Get device context of output device
        IntPtr hdc = e.Graphics.GetHdc();

        // Fill in the FORMATRANGE struct
        STRUCT_FORMATRANGE fr;
        fr.chrg = cr;
        fr.hdc = hdc;
        fr.hdcTarget = hdc;
        fr.rc = rc;
        fr.rcPage = rcPage;

        // Non-Zero wParam means render, Zero means measure
        Int32 wParam = (measureOnly ? 0 : 1);

        // Allocate memory for the FORMATRANGE struct and
        // copy the contents of our struct to this memory
        IntPtr lParam = Marshal.AllocCoTaskMem(Marshal.SizeOf(fr));
        Marshal.StructureToPtr(fr, lParam, false);

        // Send the actual Win32 message
        int res = SendMessage(control.Handle, EM_FORMATRANGE, wParam, lParam);

        // Free allocated memory
        Marshal.FreeCoTaskMem(lParam);

        // and release the device context
        e.Graphics.ReleaseHdc(hdc);

        return res;
    }
 

Using the RichTextBox is even more simple. You add a richtextbox to a form and call the Print method:

image

        private void printToolStripMenuItem_Click(object sender, EventArgs e)
        {
            richTextBox1.Print();
        }

I’m attaching the source code for the helper an this sample application so you can use this.

DOWNLOAD SOURCE CODE

IE7 Print shrink to fit problem

29. September 2007 17:22 by Mrojas in General  //  Tags: , , ,   //   Comments (0)
IE7 has an interesting bug...
Someone decided to change the printing default
to "Shrink to Fit".This is supposed to be good
because it will make printing of web pages better
but it affects several applications develop for
IE, for example if you are using the Web Access
to your Exchange server, or if you have an application
that prints on a page that is not a letter size page


Well a guy from a forum found an excellent solution.

The only problem is that he refers a hot fix,
but if you have problems with that hotfix, then
do the following:

1. Go to windowsupdate.microsoft.com

2. Make sure you have the following updates:

** Security Update for Internet Explorer 7 for Windows XP (KB938127)
** Cumulative Security Update for Internet Explorer 7 for Windows XP (KB937143)

And then run the following in the command prompt:
reg add "HKLM\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_STF_Scale_Min" /v iexplore.exe /t REG_DWORD /d 100 /f