George Shepherd's Windows Forms FAQ
Questions and answers in this FAQ have been collected from newsgroup posts, various mailing lists and the employees of Syncfusion.

39. GDI+ Brushes

WinForms FAQ Home
   39.1 How do I use hatched and gradient brush types?
   39.2 How to set the rendering origin for hatch brushes?
   39.3 How to create my own hatch styles for brushes?



39.1 How do I use hatched and gradient brush types?


You can do this by starting a new thread and executing Application.Run for the status dialog form when the background thread starts running. To communicate changes in percentage use BeginInvoke to executes a specific delegate asynchronously on the thread that the form was created on.

Download the ProgressThread progressthread.zip sample for a complete implementation of a BackgroundThreadStatusDialog class that shows a status dialog in a separate thread.

In order to use BackgroundThreadStatusDialog from your code you have to update the Progress inside your loop and check the IsCanceled state to detect if the user pressed the Cancel button.


          private void button1_Click(object sender, System.EventArgs e)
          {
               BackgroundThreadStatusDialog statusDialog = new BackgroundThreadStatusDialog();
               try
               {
                    for (int n = 0; n < 1000; n++)
                    {
                         statusDialog.Percent = n/10;
                         int ticks = System.Environment.TickCount;
                         while (System.Environment.TickCount - ticks < 10)
                              ;
                         if (statusDialog.IsCanceled)
                              return;
                    }
                    statusDialog.Close();
                    MessageBox.Show(statusDialog.IsCanceled ? "Canceled" : "Success");
               }
               finally
               {
                    statusDialog.Close();
               }
          }



39.2 How to set the rendering origin for hatch brushes?


The Graphics.RenderingOrigin property lets you specify a Point structure that represents the dither origin for 8-bits-per-pixel and 16-bits-per-pixel dithering and is also used to set the origin for hatch brushes.

The following example shows how to use RenderingOrigin:


namespace Scrollable1
{
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

///
/// Summary description for ScrollableControl1.
///
public class ScrollableControl1 : System.Windows.Forms.ScrollableControl
{
private void InitializeComponent ()
{
}

public ScrollableControl1()
{
InitializeComponent ();

this.AutoScrollMinSize = new Size(500, 500);
}

protected override void OnPaint(PaintEventArgs pe)
{
     pe.Graphics.RenderingOrigin = AutoScrollPosition;
HatchBrush br = new HatchBrush(HatchStyle.ForwardDiagonal, Color.Blue, Color.White);
pe.Graphics.FillRectangle(br, ClientRectangle /*or pe.ClipRectangle*/);
br.Dispose();
}
}
}




39.3 How to create my own hatch styles for brushes?


GDI+ features a TextureBrush that lets you draw repeating patterns. You can specify any bitmap to be drawn repeatedly. In this example we create bitmaps using code and attach them to a TextureBrush.


          static object[] patternSpecs = new object[]
          {
               new short[] { 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 }, // horizontal
               new short[] { 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc }, // vertical
               new short[] { 0x77, 0xbb, 0xdd, 0xee, 0x77, 0xbb, 0xdd, 0xee }, // \\\ Down
               new short[] { 0xee, 0xdd, 0xbb, 0x77, 0xee, 0xdd, 0xbb, 0x77 }, // /// Up
               new short[] { 0xee, 0x00, 0xee, 0xee, 0xee, 0x00, 0xee, 0xee }, // +++
          }

          public static Bitmap CreateBitmapFromPattern(int pattern)
          {
               Bitmap patternBitmap;
               IntPtr hBitmap = NativeMethods.CreateBitmap(8, 8, 1, 1, (short[]) patternSpecs[pattern]);
               if (hBitmap != IntPtr.Zero)
                    patternBitmap = Image.FromHbitmap(hBitmap);
               NativeMethods.DeleteObject(hBitmap);
               return patternBitmap;
          }

          public static void FillRectangle(Graphics g, Rectangle r, int pattern, Color foreColor, Color backColor)
          {
               Bitmap bm = CreateBitmapFromPattern(pattern);
               FillRectangle(g, r, bm, foreColor, backColor);
          }
          public static void FillRectangle(Graphics g, Rectangle r, Bitmap bm, Color foreColor, Color backColor)
          {
               if (bm != null)
               {
                    Size size = bm.PhysicalDimension.ToSize();
                    TextureBrush br = new TextureBrush(bm, new Rectangle(new Point(0, 0), size), ia);
                    br.WrapMode = WrapMode.Tile;

                    g.FillRectangle(br, r);
                    br.Dispose();
               }
          }

     public class NativeMethods
     {
          [DllImport("gdi32", CharSet=CharSet.Auto, ExactSpelling=true)]
          extern public static IntPtr CreateBitmap(int nWidth, int nHeight, int nPlanes, int nBitsPerPixel,
               [MarshalAs(UnmanagedType.LPArray)] short[] lpvBits);

          [DllImport("gdi32")]
          extern public static bool DeleteObject(IntPtr hObject) ;

     }     


© 2001-2010 Copyright Syncfusion Inc. All rights reserved.  |  Privacy Policy  |  Contact  |  Sitemap