I have made a custom control that draws a rectangle when the mouse is down, and does nothing when the mouse is up.
I set/reset a flag in MouseDown/Mouse up and use this to do the drawing in the OnPaint .
The recangle draws correct when i press the mouse, but when i release the mouse the background is not restored
What should i do in the Onpaint to make sure the background (the form) is restored correctly ?
This problem already keeps me busy for 2 days ...
Johan
copy this code in a new win c# app
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Drawing.Imaging;
using System.Reflection;
namespace WindowsApplication2
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
private Hotspot spot ;
public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.BackColor = System.Drawing.SystemColors.Desktop;
this.ClientSize = new System.Drawing.Size(152, 141);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void Form1_Load(object sender, System.EventArgs e)
{
spot=new Hotspot() ;
spot.Size=new Size(50,50);
spot.Location=new Point(40,40);
spot.BringToFront();
spot.Visible=true;
this.Controls.Add(spot);
}
}
public class Hotspot : Control
{
//private Image image;
private bool bPushed;
private Bitmap m_bmpOffscreen;
Brush GrayBrush;
public Hotspot()
{
bPushed = false;
//default minimal size
this.Size = new Size(21, 21);
GrayBrush=new SolidBrush(Color.Gray);
}
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e )
{
Graphics gxOff; //Offscreen graphics
if (m_bmpOffscreen == null) //Bitmap for doublebuffering
{
m_bmpOffscreen = new Bitmap(ClientSize.Width, ClientSize.Height);
}
gxOff = Graphics.FromImage(m_bmpOffscreen);
gxOff.Clear(Color.Empty);
if (bPushed)
{
gxOff.FillRectangle(GrayBrush,5,5,ClientSize.Width-10, ClientSize.Height-10);
e.Graphics.DrawImage(m_bmpOffscreen, 0, 0);
}
base.OnPaint(e);
}
protected override void OnPaintBackground(System.Windows.Forms.PaintEventA rgs e )
{
}
protected override void OnMouseDown ( System.Windows.Forms.MouseEventArgs e )
{
bPushed = true;
Invalidate();
}
protected override void OnMouseUp ( System.Windows.Forms.MouseEventArgs e )
{
bPushed = false;
Invalidate();
}
}
} 11 6045
Are you calling the base class paint in your onpaint override?
Are you calling Invalidate() on mouse up?
Did you override background paint - I've seen too many suggestions saying to do this and I don't think for most situations it makes sense.
--
Justin Weinberg
Designing a PrintDocument? Drawing to forms?
Check out GDI+ Architect at www.mrgsoft.com
"Sagaert Johan" <RE*******************@hotmail.com> wrote in message news:uK**************@TK2MSFTNGP12.phx.gbl...
I have made a custom control that draws a rectangle when the mouse is down, and does nothing when the mouse is up.
I set/reset a flag in MouseDown/Mouse up and use this to do the drawing in the OnPaint .
The recangle draws correct when i press the mouse, but when i release the mouse the background is not restored
What should i do in the Onpaint to make sure the background (the form) is restored correctly ?
This problem already keeps me busy for 2 days ...
Johan
copy this code in a new win c# app
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Drawing.Imaging;
using System.Reflection;
namespace WindowsApplication2
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
private Hotspot spot ;
public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.BackColor = System.Drawing.SystemColors.Desktop;
this.ClientSize = new System.Drawing.Size(152, 141);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void Form1_Load(object sender, System.EventArgs e)
{
spot=new Hotspot() ;
spot.Size=new Size(50,50);
spot.Location=new Point(40,40);
spot.BringToFront();
spot.Visible=true;
this.Controls.Add(spot);
}
}
public class Hotspot : Control
{
//private Image image;
private bool bPushed;
private Bitmap m_bmpOffscreen;
Brush GrayBrush;
public Hotspot()
{
bPushed = false;
//default minimal size
this.Size = new Size(21, 21);
GrayBrush=new SolidBrush(Color.Gray);
}
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e )
{
Graphics gxOff; //Offscreen graphics
if (m_bmpOffscreen == null) //Bitmap for doublebuffering
{
m_bmpOffscreen = new Bitmap(ClientSize.Width, ClientSize.Height);
}
gxOff = Graphics.FromImage(m_bmpOffscreen);
gxOff.Clear(Color.Empty);
if (bPushed)
{
gxOff.FillRectangle(GrayBrush,5,5,ClientSize.Width-10, ClientSize.Height-10);
e.Graphics.DrawImage(m_bmpOffscreen, 0, 0);
}
base.OnPaint(e);
}
protected override void OnPaintBackground(System.Windows.Forms.PaintEventA rgs e )
{
}
protected override void OnMouseDown ( System.Windows.Forms.MouseEventArgs e )
{
bPushed = true;
Invalidate();
}
protected override void OnMouseUp ( System.Windows.Forms.MouseEventArgs e )
{
bPushed = false;
Invalidate();
}
}
}
there are multiple things wrong in general with your hotspot control
(but they are things you'll learn as you do more with them). However
the two that are causing all your problems is a very small logic error
and a color error.
First, you are clearing your control's surface with the color Empty,
which in fact is no color at all (hence its not clearing anything for
you) and whatever was there before the control took a seat, is still
there after including anything you subsequently draw.
The second is that you seem to have accidently put your drawing to
surface inside your 'bPushed' if statement. This is a subtle but
important error. Since you are drawing to your offscreen bitmap, you
ALWAYS need to draw the bitmap regardless of whether you are doing it
for your pressed or nonpressed state.
Therefore, your draw loop should look as follows,
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e
)
{
Graphics gxOff; //Offscreen graphics
if (m_bmpOffscreen == null) //Bitmap for doublebuffering
m_bmpOffscreen = new Bitmap(ClientSize.Width,
ClientSize.Height);
gxOff = Graphics.FromImage(m_bmpOffscreen);
gxOff.Clear(Color.White); // or whatever color you would
like
if (bPushed)
gxOff.FillRectangle(GrayBrush,5,5,ClientSize.Width-10,
ClientSize.Height-10);
e.Graphics.DrawImage(m_bmpOffscreen, 0, 0);
gxOff.Dispose();
base.OnPaint(e);
}
that will fix your problem.
Allen Anderson http://www.glacialcomponents.com
On Thu, 9 Oct 2003 19:52:23 +0200, "Sagaert Johan"
<RE*******************@hotmail.com> wrote: I have made a custom control that draws a rectangle when the mouse is down, and does nothing when the mouse is up. I set/reset a flag in MouseDown/Mouse up and use this to do the drawing in the OnPaint .
The recangle draws correct when i press the mouse, but when i release the mouse the background is not restored
What should i do in the Onpaint to make sure the background (the form) is restored correctly ?
This problem already keeps me busy for 2 days ...
Johan copy this code in a new win c# app
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Drawing.Imaging;
using System.Reflection; namespace WindowsApplication2
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
private Hotspot spot ;
public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.BackColor = System.Drawing.SystemColors.Desktop;
this.ClientSize = new System.Drawing.Size(152, 141);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void Form1_Load(object sender, System.EventArgs e)
{
spot=new Hotspot() ;
spot.Size=new Size(50,50);
spot.Location=new Point(40,40);
spot.BringToFront();
spot.Visible=true;
this.Controls.Add(spot);
} }
public class Hotspot : Control
{
//private Image image;
private bool bPushed;
private Bitmap m_bmpOffscreen;
Brush GrayBrush;
public Hotspot()
{
bPushed = false;
//default minimal size
this.Size = new Size(21, 21);
GrayBrush=new SolidBrush(Color.Gray);
}
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e )
{
Graphics gxOff; //Offscreen graphics
if (m_bmpOffscreen == null) //Bitmap for doublebuffering
{
m_bmpOffscreen = new Bitmap(ClientSize.Width, ClientSize.Height);
}
gxOff = Graphics.FromImage(m_bmpOffscreen);
gxOff.Clear(Color.Empty);
if (bPushed)
{
gxOff.FillRectangle(GrayBrush,5,5,ClientSize.Widt h-10, ClientSize.Height-10);
e.Graphics.DrawImage(m_bmpOffscreen, 0, 0);
}
base.OnPaint(e);
}
protected override void OnPaintBackground(System.Windows.Forms.PaintEventA rgs e )
{
}
protected override void OnMouseDown ( System.Windows.Forms.MouseEventArgs e )
{
bPushed = true;
Invalidate();
}
protected override void OnMouseUp ( System.Windows.Forms.MouseEventArgs e )
{
bPushed = false;
Invalidate();
}
}
}
Hi Johan,
1. Dont use Color.Empty for clearing the bitmap. This won't clear anything.
You should use color instead.
something like:
gxOff.Clear(this.BackColor);
2. Move
e.Graphics.DrawImage(m_bmpOffscreen, 0, 0);
out of the if(bPushed) block. You paint the control only if the button is
down. And you don't paint (clear ) anything if the button is up.
Beside I have one suggestion. If you want to paint the whole clent rectangle
by yourself consider setting control styles:
this.SetStyle(ControlStyles.DoubleBuffer | ControlStyles.UserPaint |
ControlStyles.AllPaintingInWmPaint, true);
Even if you have your own offscreen bitmap you should set
ControlStyles.DoubleBuffer style in order to avoid flickering.
HTH
B\rgds
100
Thanks for the reply ,
it did'nt solve my problem ,if i don't push the control, i would like
nothing else to see then my form.(my control must appear invisible to the
user whet it's NOT pushed, it should only be draw a when it's pushed)
"Allen Anderson" <al***@sparkysystems.com> wrote in message
news:c1********************************@4ax.com... there are multiple things wrong in general with your hotspot control (but they are things you'll learn as you do more with them). However the two that are causing all your problems is a very small logic error and a color error.
First, you are clearing your control's surface with the color Empty, which in fact is no color at all (hence its not clearing anything for you) and whatever was there before the control took a seat, is still there after including anything you subsequently draw.
The second is that you seem to have accidently put your drawing to surface inside your 'bPushed' if statement. This is a subtle but important error. Since you are drawing to your offscreen bitmap, you ALWAYS need to draw the bitmap regardless of whether you are doing it for your pressed or nonpressed state.
Therefore, your draw loop should look as follows,
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e ) { Graphics gxOff; //Offscreen graphics
if (m_bmpOffscreen == null) //Bitmap for doublebuffering m_bmpOffscreen = new Bitmap(ClientSize.Width, ClientSize.Height);
gxOff = Graphics.FromImage(m_bmpOffscreen); gxOff.Clear(Color.White); // or whatever color you would like
if (bPushed) gxOff.FillRectangle(GrayBrush,5,5,ClientSize.Width-10, ClientSize.Height-10);
e.Graphics.DrawImage(m_bmpOffscreen, 0, 0); gxOff.Dispose();
base.OnPaint(e); }
that will fix your problem.
Allen Anderson http://www.glacialcomponents.com
On Thu, 9 Oct 2003 19:52:23 +0200, "Sagaert Johan" <RE*******************@hotmail.com> wrote:
I have made a custom control that draws a rectangle when the mouse is
down, and does nothing when the mouse is up.I set/reset a flag in MouseDown/Mouse up and use this to do the drawing
in the OnPaint . The recangle draws correct when i press the mouse, but when i release the
mouse the background is not restored What should i do in the Onpaint to make sure the background (the form) is
restored correctly ? This problem already keeps me busy for 2 days ...
Johan copy this code in a new win c# app
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Drawing.Imaging;
using System.Reflection; namespace WindowsApplication2
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
private Hotspot spot ;
public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.BackColor = System.Drawing.SystemColors.Desktop;
this.ClientSize = new System.Drawing.Size(152, 141);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void Form1_Load(object sender, System.EventArgs e)
{
spot=new Hotspot() ;
spot.Size=new Size(50,50);
spot.Location=new Point(40,40);
spot.BringToFront();
spot.Visible=true;
this.Controls.Add(spot);
} }
public class Hotspot : Control
{
//private Image image;
private bool bPushed;
private Bitmap m_bmpOffscreen;
Brush GrayBrush;
public Hotspot()
{
bPushed = false;
//default minimal size
this.Size = new Size(21, 21);
GrayBrush=new SolidBrush(Color.Gray);
}
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e )
{
Graphics gxOff; //Offscreen graphics
if (m_bmpOffscreen == null) //Bitmap for doublebuffering
{
m_bmpOffscreen = new Bitmap(ClientSize.Width, ClientSize.Height);
}
gxOff = Graphics.FromImage(m_bmpOffscreen);
gxOff.Clear(Color.Empty);
if (bPushed)
{
gxOff.FillRectangle(GrayBrush,5,5,ClientSize.Widt h-10,
ClientSize.Height-10); e.Graphics.DrawImage(m_bmpOffscreen, 0, 0);
}
base.OnPaint(e);
}
protected override void
OnPaintBackground(System.Windows.Forms.PaintEventA rgs e ) {
}
protected override void OnMouseDown ( System.Windows.Forms.MouseEventArgs
e ) {
bPushed = true;
Invalidate();
}
protected override void OnMouseUp ( System.Windows.Forms.MouseEventArgs
e ) {
bPushed = false;
Invalidate();
}
}
}
Yes, see and try my source in the first post
"Justin Weinberg" <jweinberg@_spamkill_mrgsoft.com> wrote in message news:ed**************@tk2msftngp13.phx.gbl...
Are you calling the base class paint in your onpaint override?
Are you calling Invalidate() on mouse up?
Did you override background paint - I've seen too many suggestions saying to do this and I don't think for most situations it makes sense.
--
Justin Weinberg
Designing a PrintDocument? Drawing to forms?
Check out GDI+ Architect at www.mrgsoft.com
"Sagaert Johan" <RE*******************@hotmail.com> wrote in message news:uK**************@TK2MSFTNGP12.phx.gbl...
I have made a custom control that draws a rectangle when the mouse is down, and does nothing when the mouse is up.
I set/reset a flag in MouseDown/Mouse up and use this to do the drawing in the OnPaint .
The recangle draws correct when i press the mouse, but when i release the mouse the background is not restored
What should i do in the Onpaint to make sure the background (the form) is restored correctly ?
This problem already keeps me busy for 2 days ...
Johan
copy this code in a new win c# app
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Drawing.Imaging;
using System.Reflection;
namespace WindowsApplication2
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
private Hotspot spot ;
public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.BackColor = System.Drawing.SystemColors.Desktop;
this.ClientSize = new System.Drawing.Size(152, 141);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void Form1_Load(object sender, System.EventArgs e)
{
spot=new Hotspot() ;
spot.Size=new Size(50,50);
spot.Location=new Point(40,40);
spot.BringToFront();
spot.Visible=true;
this.Controls.Add(spot);
}
}
public class Hotspot : Control
{
//private Image image;
private bool bPushed;
private Bitmap m_bmpOffscreen;
Brush GrayBrush;
public Hotspot()
{
bPushed = false;
//default minimal size
this.Size = new Size(21, 21);
GrayBrush=new SolidBrush(Color.Gray);
}
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e )
{
Graphics gxOff; //Offscreen graphics
if (m_bmpOffscreen == null) //Bitmap for doublebuffering
{
m_bmpOffscreen = new Bitmap(ClientSize.Width, ClientSize.Height);
}
gxOff = Graphics.FromImage(m_bmpOffscreen);
gxOff.Clear(Color.Empty);
if (bPushed)
{
gxOff.FillRectangle(GrayBrush,5,5,ClientSize.Width-10, ClientSize.Height-10);
e.Graphics.DrawImage(m_bmpOffscreen, 0, 0);
}
base.OnPaint(e);
}
protected override void OnPaintBackground(System.Windows.Forms.PaintEventA rgs e )
{
}
protected override void OnMouseDown ( System.Windows.Forms.MouseEventArgs e )
{
bPushed = true;
Invalidate();
}
protected override void OnMouseUp ( System.Windows.Forms.MouseEventArgs e )
{
bPushed = false;
Invalidate();
}
}
}
"100" <10*@100.com> wrote in message
news:Ot*************@TK2MSFTNGP12.phx.gbl... Hi Johan,
1. Dont use Color.Empty for clearing the bitmap. This won't clear
anything. You should use color instead.
something like: gxOff.Clear(this.BackColor);
2. Move e.Graphics.DrawImage(m_bmpOffscreen, 0, 0); out of the if(bPushed) block. You paint the control only if the button is down. And you don't paint (clear ) anything if the button is up.
Thats just my problem,i don't want anything to be painted when i don't
press my control,
the only thing i want to see is the form , or the image i draw on the form .
In my form i draw a background image in the forms paint event, and the i
would like to use
my control to create hotspots almost identical as they create hotspots on
images of html pages.
I don't understand why part of the form the is'nt painted correctly if my
control does'nt do any painting by itself.Even if i call the forms
invalidate, the form paint routine seems to skip the area where my control
is.
Johan
Beside I have one suggestion. If you want to paint the whole clent
rectangle by yourself consider setting control styles:
this.SetStyle(ControlStyles.DoubleBuffer | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);
Even if you have your own offscreen bitmap you should set ControlStyles.DoubleBuffer style in order to avoid flickering.
HTH B\rgds 100
Hi Johan,
Now I see what your issue is. Ok, the problem is that when a control is
created the framework by default sets WS_CLIPCHILDREN windows style to the
underlaying window. This style cause any part of of the client area covered
by a child control to be excluded of the invalid region. As a result all
drawing in those areas are clipped.
What you can do is to reset this style. I don't know if it is good idea to
use such platform dependant features, but this solves your problem. So what
you can do is:
1. Add the following property to your main form:
protected override CreateParams CreateParams
{
get
{
CreateParams createParams = base.CreateParams;
createParams.Style &= ~0x02000000; //reset WS_CLIPCHILDREN
return createParams;
}
}
2. Now you have to restore the main form's clent area when the mouse button
is released. You can't simply ignore OnPaint event in the child control.
This will not repaint the main form. You have to do something to fire Paint
event in the parent form. There is my suggestion for the child control's
Paint event implementation:
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e )
{
base.OnPaint(e); //If you needed it it's better to call it before your
painting
if (bPushed)
{
Graphics gxOff; //Offscreen graphics
if (m_bmpOffscreen == null) //Bitmap for doublebuffering
{
m_bmpOffscreen = new Bitmap(ClientSize.Width, ClientSize.Height,
e.Graphics); //I believe is better to use this constructor
}
gxOff = Graphics.FromImage(m_bmpOffscreen);
//gxOff.Clear(Color.Empty); - I believe it is not necessary sice it
doesnt do anything
gxOff.FillRectangle(GrayBrush,5,5,ClientSize.Width-10,
ClientSize.Height-10);
e.Graphics.DrawImage(m_bmpOffscreen, 0, 0);
}
else
{
Parent.Invalidate(this.Bounds, false); //Fires parent's paint event
}
}
HTH
B\rgds
100
"Sagaert Johan" <RE*******************@hotmail.com> wrote in message
news:un**************@TK2MSFTNGP09.phx.gbl...
"100" <10*@100.com> wrote in message news:Ot*************@TK2MSFTNGP12.phx.gbl... Hi Johan,
1. Dont use Color.Empty for clearing the bitmap. This won't clear anything. You should use color instead.
something like: gxOff.Clear(this.BackColor);
2. Move e.Graphics.DrawImage(m_bmpOffscreen, 0, 0); out of the if(bPushed) block. You paint the control only if the button
is down. And you don't paint (clear ) anything if the button is up.
Thats just my problem,i don't want anything to be painted when i don't press my control, the only thing i want to see is the form , or the image i draw on the form
.. In my form i draw a background image in the forms paint event, and the i would like to use
my control to create hotspots almost identical as they create hotspots on images of html pages.
I don't understand why part of the form the is'nt painted correctly if my control does'nt do any painting by itself.Even if i call the forms invalidate, the form paint routine seems to skip the area where my control is.
Johan
Beside I have one suggestion. If you want to paint the whole clent rectangle by yourself consider setting control styles:
this.SetStyle(ControlStyles.DoubleBuffer | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);
Even if you have your own offscreen bitmap you should set ControlStyles.DoubleBuffer style in order to avoid flickering.
HTH B\rgds 100
A little correction. It seems like calling invalidate with
invalidateChildren=false is not enough to stop Paint event for the child
control. As a result Parent.Invalidate is called over and over again (like
infinite loop of messages).
More logic has to be put in childe's control Paint event.
The idea I came up with is to use a flag in the child's control class
public class Hotspot : Control
{
private bool mStopPaint = false;
//..... other members
protected override void OnPaint(System.Windows.Forms.PaintEventArgs
e )
{
if(mStopPaint) return;
base.OnPaint(e); //If you needed it it's better to call it before
your painting
if (bPushed)
{
//..... not changed
}
else
{
mStopPaint = true;
Parent.Invalidate(this.Bounds, false); //Fires parent's
paint event
Parent.Update(); //This want return until the parent is not
repainted. We need that in order to mStopPaint flag to work
mStopPaint = false;
}
}
//.....The rest of the class
}
HTH
B\rgds
100
"100" <10*@100.com> wrote in message
news:en**************@TK2MSFTNGP10.phx.gbl... Hi Johan,
Now I see what your issue is. Ok, the problem is that when a control is created the framework by default sets WS_CLIPCHILDREN windows style to the underlaying window. This style cause any part of of the client area
covered by a child control to be excluded of the invalid region. As a result all drawing in those areas are clipped. What you can do is to reset this style. I don't know if it is good idea to use such platform dependant features, but this solves your problem. So
what you can do is:
1. Add the following property to your main form: protected override CreateParams CreateParams { get { CreateParams createParams = base.CreateParams; createParams.Style &= ~0x02000000; //reset WS_CLIPCHILDREN return createParams; } }
2. Now you have to restore the main form's clent area when the mouse
button is released. You can't simply ignore OnPaint event in the child control. This will not repaint the main form. You have to do something to fire
Paint event in the parent form. There is my suggestion for the child control's Paint event implementation:
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e ) { base.OnPaint(e); //If you needed it it's better to call it before
your painting if (bPushed) {
Graphics gxOff; //Offscreen graphics if (m_bmpOffscreen == null) //Bitmap for doublebuffering { m_bmpOffscreen = new Bitmap(ClientSize.Width,
ClientSize.Height, e.Graphics); //I believe is better to use this constructor } gxOff = Graphics.FromImage(m_bmpOffscreen); //gxOff.Clear(Color.Empty); - I believe it is not necessary sice
it doesnt do anything gxOff.FillRectangle(GrayBrush,5,5,ClientSize.Width-10, ClientSize.Height-10); e.Graphics.DrawImage(m_bmpOffscreen, 0, 0); } else { Parent.Invalidate(this.Bounds, false); //Fires parent's paint
event } }
HTH B\rgds 100
"Sagaert Johan" <RE*******************@hotmail.com> wrote in message news:un**************@TK2MSFTNGP09.phx.gbl...
"100" <10*@100.com> wrote in message news:Ot*************@TK2MSFTNGP12.phx.gbl... Hi Johan,
1. Dont use Color.Empty for clearing the bitmap. This won't clear anything. You should use color instead.
something like: gxOff.Clear(this.BackColor);
2. Move e.Graphics.DrawImage(m_bmpOffscreen, 0, 0); out of the if(bPushed) block. You paint the control only if the button is down. And you don't paint (clear ) anything if the button is up.
Thats just my problem,i don't want anything to be painted when i don't press my control, the only thing i want to see is the form , or the image i draw on the
form . In my form i draw a background image in the forms paint event, and the i would like to use
my control to create hotspots almost identical as they create hotspots
on images of html pages.
I don't understand why part of the form the is'nt painted correctly if
my control does'nt do any painting by itself.Even if i call the forms invalidate, the form paint routine seems to skip the area where my
control is.
Johan
Beside I have one suggestion. If you want to paint the whole clent rectangle by yourself consider setting control styles:
this.SetStyle(ControlStyles.DoubleBuffer | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);
Even if you have your own offscreen bitmap you should set ControlStyles.DoubleBuffer style in order to avoid flickering.
HTH B\rgds 100
Hi
Thanks for your reply , now it works just as i would like !!!!!!!!!!!
I have put the Parent.Invalidate in the controls MouseUp event ,this seems
to be enough.
Now my next problem is how to solve this issue in the Compact framework
,since CF does not have the CreateParams method...
Best regards Johan http://www.qsl.net/on5di/
"100" <10*@100.com> wrote in message
news:OX****************@TK2MSFTNGP09.phx.gbl... A little correction. It seems like calling invalidate with invalidateChildren=false is not enough to stop Paint event for the child control. As a result Parent.Invalidate is called over and over again (like infinite loop of messages). More logic has to be put in childe's control Paint event.
The idea I came up with is to use a flag in the child's control class
public class Hotspot : Control
{ private bool mStopPaint = false; //..... other members
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e ) { if(mStopPaint) return; base.OnPaint(e); //If you needed it it's better to call it
before your painting
if (bPushed) { //..... not changed } else { mStopPaint = true; Parent.Invalidate(this.Bounds, false); //Fires parent's paint event Parent.Update(); //This want return until the parent is
not repainted. We need that in order to mStopPaint flag to work mStopPaint = false; }
} //.....The rest of the class }
HTH B\rgds 100
"100" <10*@100.com> wrote in message news:en**************@TK2MSFTNGP10.phx.gbl... Hi Johan,
Now I see what your issue is. Ok, the problem is that when a control is created the framework by default sets WS_CLIPCHILDREN windows style to
the underlaying window. This style cause any part of of the client area covered by a child control to be excluded of the invalid region. As a result all drawing in those areas are clipped. What you can do is to reset this style. I don't know if it is good idea
to use such platform dependant features, but this solves your problem. So what you can do is:
1. Add the following property to your main form: protected override CreateParams CreateParams { get { CreateParams createParams = base.CreateParams; createParams.Style &= ~0x02000000; //reset WS_CLIPCHILDREN return createParams; } }
2. Now you have to restore the main form's clent area when the mouse button is released. You can't simply ignore OnPaint event in the child control. This will not repaint the main form. You have to do something to fire Paint event in the parent form. There is my suggestion for the child control's Paint event implementation:
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e ) { base.OnPaint(e); //If you needed it it's better to call it before your painting if (bPushed) {
Graphics gxOff; //Offscreen graphics if (m_bmpOffscreen == null) //Bitmap for doublebuffering { m_bmpOffscreen = new Bitmap(ClientSize.Width, ClientSize.Height, e.Graphics); //I believe is better to use this constructor } gxOff = Graphics.FromImage(m_bmpOffscreen); //gxOff.Clear(Color.Empty); - I believe it is not necessary sice it doesnt do anything gxOff.FillRectangle(GrayBrush,5,5,ClientSize.Width-10, ClientSize.Height-10); e.Graphics.DrawImage(m_bmpOffscreen, 0, 0); } else { Parent.Invalidate(this.Bounds, false); //Fires parent's paint event } }
HTH B\rgds 100
"Sagaert Johan" <RE*******************@hotmail.com> wrote in message news:un**************@TK2MSFTNGP09.phx.gbl...
"100" <10*@100.com> wrote in message news:Ot*************@TK2MSFTNGP12.phx.gbl... > Hi Johan, > > 1. Dont use Color.Empty for clearing the bitmap. This won't clear anything. > You should use color instead. > > something like: > gxOff.Clear(this.BackColor); > > 2. Move > e.Graphics.DrawImage(m_bmpOffscreen, 0, 0); > out of the if(bPushed) block. You paint the control only if the
button is > down. And you don't paint (clear ) anything if the button is up.
Thats just my problem,i don't want anything to be painted when i
don't press my control, the only thing i want to see is the form , or the image i draw on the
form . In my form i draw a background image in the forms paint event, and the
i would like to use
my control to create hotspots almost identical as they create hotspots
on images of html pages.
I don't understand why part of the form the is'nt painted correctly if my control does'nt do any painting by itself.Even if i call the forms invalidate, the form paint routine seems to skip the area where my control is.
Johan
> Beside I have one suggestion. If you want to paint the whole clent rectangle > by yourself consider setting control styles: > > this.SetStyle(ControlStyles.DoubleBuffer | ControlStyles.UserPaint
| > ControlStyles.AllPaintingInWmPaint, true); > > Even if you have your own offscreen bitmap you should set > ControlStyles.DoubleBuffer style in order to avoid flickering. > > HTH > B\rgds > 100 > >
Hi Joahn,
I didn't know that you are going to use it with CF. In CF there is no
underlaying native control so there is not Handle, CreateParameters, etc
properties and methods to manimpulating the underlaying window. That's why I
told you this is platform dependent and it's not good idea to use it.
Now I'm posting you the whole source of my next suggestion, which I believe
will work for CF. You can find my comments inline.
The new things are:
1. New event in the Hotspot control class + event handler in the form class
(PaintParent).
The full version of the framework has method InvokePaint that can be
used instead. CF doesn's suported it, though, so I added this event.
2. New method in the Hotspot control class (PaintBackground)
HTH
B\rgds
100
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Drawing.Imaging;
using System.Reflection;
namespace WindowsApplication2
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
private Hotspot spot ;
public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//The following is not supported by CF so don't set it. It will make the
things better for not CF, though.
//Set this to remove flickering.
//SetStyle(ControlStyles.AllPaintingInWmPaint |
ControlStyles.DoubleBuffer | ControlStyles.UserPaint, true);
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.BackColor = System.Drawing.SystemColors.Info;
this.ClientSize = new System.Drawing.Size(304, 213);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void Form1_Load(object sender, System.EventArgs e)
{
spot=new Hotspot() ;
spot.Size=new Size(50,50);
spot.Location=new Point(40,40);
spot.BringToFront();
spot.Visible=true;
spot.PaintParent += new PaintEventHandler(spot_PaintParent);
this.Controls.Add(spot);
}
protected override void OnPaint(PaintEventArgs e)
{
//Draw some stuff here
base.OnPaint (e);
e.Graphics.DrawLine(Pens.Red, 0, 0, this.ClientSize.Width,
this.ClientSize.Height);
e.Graphics.DrawLine(Pens.Red, this.ClientSize.Width, 0, 0,
this.ClientSize.Height);
}
private void spot_PaintParent(object sender, PaintEventArgs e)
{
//CF dosen't support background painting
//OnPaintBackground(e);
//Use the same event handler as for Pint event
OnPaint(e);
}
}
public class Hotspot : Control
{
//Requesting parent form to draw iteself on the control's surface
public PaintEventHandler PaintParent;
private bool bPushed;
private Bitmap m_bmpOffscreen;
Brush GrayBrush;
public Hotspot()
{
bPushed = false;
//default minimal size
this.Size = new Size(21, 21);
GrayBrush=new SolidBrush(Color.Gray);
//The following is not supported by CF so don't set it. It will make the
things better for not CF, though.
//Set this to remove flickering.
//SetStyle(ControlStyles.AllPaintingInWmPaint |
ControlStyles.DoubleBuffer | ControlStyles.UserPaint, true);
}
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e )
{
base.OnPaint(e); //If you needed it it's better to call it before your
painting
PaintBackground(e);
if (bPushed)
{
e.Graphics.FillRectangle(GrayBrush,5,5,ClientSize. Width-10,
ClientSize.Height-10);
}
}
private void PaintBackground(PaintEventArgs e)
{
Graphics gxOff; //Offscreen graphics
//Beacause the form is resizable the bitmap has to be recreated everytime
the form changes its size.
if (m_bmpOffscreen == null) //Bitmap for doublebuffering
{
//CF doesn't support transforamtions so we need to create bit map for
the whole parent client.
m_bmpOffscreen = new Bitmap(this.Parent.ClientSize.Width,
this.Parent.ClientSize.Height); //I believe is better to use this
constructor
}
gxOff = Graphics.FromImage(m_bmpOffscreen);
//Setting the clip region may increase the perforamnce
gxOff.Clip = new Region(this.Bounds);
PaintEventArgs pea = new PaintEventArgs(gxOff, this.Bounds);
//Raises OnPaintParent event
OnPaintParent(pea);
gxOff.Dispose();
e.Graphics.DrawImage(m_bmpOffscreen, 0, 0, this.Bounds,
GraphicsUnit.Pixel);
}
//Raises PaintParent event.
protected virtual void OnPaintParent(PaintEventArgs e)
{
if(PaintParent != null)
{
PaintParent(this, e);
}
}
protected override void OnMouseDown ( System.Windows.Forms.MouseEventArgs
e )
{
bPushed = true;
Invalidate();
}
protected override void OnMouseUp ( System.Windows.Forms.MouseEventArgs
e )
{
bPushed = false;
Invalidate();
}
}
}
Hi Johan,
I'm just curious. Is the problem solved.
B\rgds
100
"Sagaert Johan" <ys*********@hotmail.com> wrote in message
news:3f***********************@reader1.news.skynet .be... Hi Thanks for your reply , now it works just as i would like !!!!!!!!!!!
I have put the Parent.Invalidate in the controls MouseUp event ,this seems to be enough.
Now my next problem is how to solve this issue in the Compact framework ,since CF does not have the CreateParams method...
Best regards Johan http://www.qsl.net/on5di/
"100" <10*@100.com> wrote in message news:OX****************@TK2MSFTNGP09.phx.gbl... A little correction. It seems like calling invalidate with invalidateChildren=false is not enough to stop Paint event for the child control. As a result Parent.Invalidate is called over and over again
(like infinite loop of messages). More logic has to be put in childe's control Paint event.
The idea I came up with is to use a flag in the child's control class
public class Hotspot : Control
{ private bool mStopPaint = false; //..... other members
protected override void
OnPaint(System.Windows.Forms.PaintEventArgs e ) { if(mStopPaint) return; base.OnPaint(e); //If you needed it it's better to call it before your painting
if (bPushed) { //..... not changed } else { mStopPaint = true; Parent.Invalidate(this.Bounds, false); //Fires parent's paint event Parent.Update(); //This want return until the parent is not repainted. We need that in order to mStopPaint flag to work mStopPaint = false; }
} //.....The rest of the class }
HTH B\rgds 100
"100" <10*@100.com> wrote in message news:en**************@TK2MSFTNGP10.phx.gbl... Hi Johan,
Now I see what your issue is. Ok, the problem is that when a control
is created the framework by default sets WS_CLIPCHILDREN windows style to the underlaying window. This style cause any part of of the client area covered by a child control to be excluded of the invalid region. As a result
all drawing in those areas are clipped. What you can do is to reset this style. I don't know if it is good
idea to use such platform dependant features, but this solves your problem. So what you can do is:
1. Add the following property to your main form: protected override CreateParams CreateParams { get { CreateParams createParams = base.CreateParams; createParams.Style &= ~0x02000000; //reset WS_CLIPCHILDREN return createParams; } }
2. Now you have to restore the main form's clent area when the mouse button is released. You can't simply ignore OnPaint event in the child
control. This will not repaint the main form. You have to do something to fire Paint event in the parent form. There is my suggestion for the child
control's Paint event implementation:
protected override void OnPaint(System.Windows.Forms.PaintEventArgs
e ) { base.OnPaint(e); //If you needed it it's better to call it before your painting if (bPushed) {
Graphics gxOff; //Offscreen graphics if (m_bmpOffscreen == null) //Bitmap for doublebuffering { m_bmpOffscreen = new Bitmap(ClientSize.Width, ClientSize.Height, e.Graphics); //I believe is better to use this constructor } gxOff = Graphics.FromImage(m_bmpOffscreen); //gxOff.Clear(Color.Empty); - I believe it is not necessary
sice it doesnt do anything gxOff.FillRectangle(GrayBrush,5,5,ClientSize.Width-10, ClientSize.Height-10); e.Graphics.DrawImage(m_bmpOffscreen, 0, 0); } else { Parent.Invalidate(this.Bounds, false); //Fires parent's paint event } }
HTH B\rgds 100
"Sagaert Johan" <RE*******************@hotmail.com> wrote in message news:un**************@TK2MSFTNGP09.phx.gbl... > > > "100" <10*@100.com> wrote in message > news:Ot*************@TK2MSFTNGP12.phx.gbl... > > Hi Johan, > > > > 1. Dont use Color.Empty for clearing the bitmap. This won't clear > anything. > > You should use color instead. > > > > something like: > > gxOff.Clear(this.BackColor); > > > > 2. Move > > e.Graphics.DrawImage(m_bmpOffscreen, 0, 0); > > out of the if(bPushed) block. You paint the control only if the button is > > down. And you don't paint (clear ) anything if the button is up. > > > Thats just my problem,i don't want anything to be painted when i don't > press my control, > the only thing i want to see is the form , or the image i draw on
the form . > > In my form i draw a background image in the forms paint event, and
the i > would like to use > > my control to create hotspots almost identical as they create
hotspots on > images of html pages. > > I don't understand why part of the form the is'nt painted correctly
if my > control does'nt do any painting by itself.Even if i call the forms > invalidate, the form paint routine seems to skip the area where my control > is. > > Johan > > > > > > Beside I have one suggestion. If you want to paint the whole clent > rectangle > > by yourself consider setting control styles: > > > > this.SetStyle(ControlStyles.DoubleBuffer |
ControlStyles.UserPaint | > > ControlStyles.AllPaintingInWmPaint, true); > > > > Even if you have your own offscreen bitmap you should set > > ControlStyles.DoubleBuffer style in order to avoid flickering. > > > > HTH > > B\rgds > > 100 > > > > > >
This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: DraguVaso |
last post by:
Hi,
I want to override the MyBase.OnPaint(ByVal pe As
System.Windows.Forms.PaintEventArgs) of the DataGrid, to have some custom
property's designed (other column headers etc).
The problem is...
|
by: DraguVaso |
last post by:
Hi,
I have my custom Inherited DataGrid. I override the OnPaint-event to speed
up things and avoid flikkering using Double Buffering. To draw the normal
things of the DataGrid I have to call the...
|
by: Ron Vecchi |
last post by:
I have a custyom control that has a property which wraps a collection. When
I add controls to the collection the OnPaint method of these newly added
controls never get fired.
But if I take the...
|
by: Dave |
last post by:
Hi all,
I'm creating a control derived from System.Windows.Forms.Control
I override the OnPaint() function
The control takes place on a form with a background image.
Because I've some problems...
|
by: |
last post by:
Please, help.
I created my contol, ButtonX, which subclasses System.Forms.Windows.Button
class. I am doing my own paiting, by overriding OnPaint and
OnPaintBackground (without calling base...
|
by: BB |
last post by:
Hello all,
I am trying to override OnPaint in a custom textbox
control (so I can drawstring a caption, etc.). In the
code below, I get the "painting the form" message as
expected, but not the...
|
by: Kenneth Siewers Møller |
last post by:
Hi there
I have a custom label control (GradientLabel) which enherits from Label and
basically just paints the background of a label in a gradient.
In my code I have the following for the...
|
by: ian_jacobsen |
last post by:
I have a control that is derived from the standard ComboBox. I have an
override for the OnPaint method that paints a border, drop down arrow
button, background, and foreground. The only problem...
|
by: Tom P. |
last post by:
I'm trying to make one of our perennial favorites - The Syntax Color
Editor. (Mostly as a learning exercise). I'm wondering if there is a
way to capture the Paint event of a textbox so I can...
|
by: Kemmylinns12 |
last post by:
Blockchain technology has emerged as a transformative force in the business world, offering unprecedented opportunities for innovation and efficiency. While initially associated with cryptocurrencies...
|
by: Naresh1 |
last post by:
What is WebLogic Admin Training?
WebLogic Admin Training is a specialized program designed to equip individuals with the skills and knowledge required to effectively administer and manage Oracle...
|
by: antdb |
last post by:
Ⅰ. Advantage of AntDB: hyper-convergence + streaming processing engine
In the overall architecture, a new "hyper-convergence" concept was proposed, which integrated multiple engines and...
|
by: Arjunsri |
last post by:
I have a Redshift database that I need to use as an import data source. I have configured the DSN connection using the server, port, database, and credentials and received a successful connection...
|
by: WisdomUfot |
last post by:
It's an interesting question you've got about how Gmail hides the HTTP referrer when a link in an email is clicked. While I don't have the specific technical details, Gmail likely implements measures...
|
by: Ricardo de Mila |
last post by:
Dear people, good afternoon...
I have a form in msAccess with lots of controls and a specific routine must be triggered if the mouse_down event happens in any control.
Than I need to discover what...
|
by: Johno34 |
last post by:
I have this click event on my form. It speaks to a Datasheet Subform
Private Sub Command260_Click()
Dim r As DAO.Recordset
Set r = Form_frmABCD.Form.RecordsetClone
r.MoveFirst
Do
If...
|
by: ezappsrUS |
last post by:
Hi,
I wonder if someone knows where I am going wrong below. I have a continuous form and two labels where only one would be visible depending on the checkbox being checked or not. Below is the...
|
by: jack2019x |
last post by:
hello, Is there code or static lib for hook swapchain present?
I wanna hook dxgi swapchain present for dx11 and dx9.
| |