I have a form which i am painting a custom interface for (I.E Skinning it)
However i have one issue which is:
I am painting the title bar, minimize, maximize and close buttons manually. I paint these on using the graphics object and all looks fine and dandy. However i have one small issue. When someone hovers over say the close button i need to change the image that has been painted in that area. The only way i can see to do this is:
1. create a picture boxe in the location for the close button and change the image depending on the mouse state which could be clunky.
2. repaint the form and paint the correct image in its place. However repainting the entire form for just one button state is a bit heavy and could be very slow. Although it would give me what i want it would not give the user a good experience in the app.
Is there any way of re-painting just a specific area of the form or do i really have to go with a picturebox and change the image depending on the mouse state?
Cheers
Loading
jingePosted Oct 19, 2009, 7:28 AM
Giles PapworthPosted Oct 19, 2009, 9:19 AM
jingePosted Oct 19, 2009, 9:07 AM
Giles PapworthPosted Oct 19, 2009, 9:00 AM
Ah sometimes i wish i didn't embark on these sorts of projects but well, it is the only way to learn.
jingePosted Oct 19, 2009, 8:59 AM
Giles PapworthPosted Oct 19, 2009, 8:54 AM
Thanks for your help again and for the idea's.
jingePosted Oct 19, 2009, 8:50 AM
Giles PapworthPosted Oct 19, 2009, 8:27 AM
Next and last quick question, as this form is designed to be a base object and other forms inherited off it, is there any way of getting the value of the text property from the inherited object?
Cheers
jingePosted Oct 19, 2009, 7:53 AM
Giles PapworthPosted Oct 19, 2009, 7:34 AM
That actually is not a bad idea, i didn't think of that, i can hold all the repainting stuff in the user control, you know that situation where you cannot see the wood for the trees? Yep!
Im going to give that a try and see where it leads me, cheers for that!
Giles PapworthPosted Oct 19, 2009, 7:32 AM
The loadskin() method only gets run if the boolean LoadedSkin is false and obviously if the form is repainted. When the user hovers over where i have painted the close button, the code detects this, sets the loaded skin to false, a boolean to say that the close button has changed and then invalidate the form. The LoadSkin then sees the close button boolean is true, loads the hover image accordingly and then repaints the entire form.
This does work splendidy but repainting is quite heavy, especially if i am doing the entire form. All the images are already loaded into memory so its not as if it has to get them all out of the skin file again.
Giles PapworthPosted Oct 19, 2009, 7:21 AM
It would be usefull to just re-draw the area where the button is without having to re-draw the whole form. With big forms this could be very counter productive.
As per the Glassbutton link posted before, i know this can be done, but looking through the code, it does seem to re-paint the whole control if im not mistaken?
jingePosted Oct 19, 2009, 7:11 AM
Giles PapworthPosted Oct 19, 2009, 7:05 AM
protected override void OnPaint(System.Windows.Forms.PaintEventArgs pe)
{
if (!DesignMode && Storage.LoadedSkin.currentSkin != null)
{
LoadSkin();
Brush t = new TextureBrush(titleBarGraphic);
pe.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(27, 27, 27)), new Rectangle(0, 0, this.Width, this.Height));
pe.Graphics.FillRectangle(new SolidBrush(Storage.LoadedSkin.currentSkin.Form_BackgroundColor), new Rectangle(2, 2, this.Width - 4, this.Height - 4));
try
{
pe.Graphics.FillRectangle(t, new Rectangle(0, 0, this.Width, Storage.LoadedSkin.currentSkin.Form_TitleBarHeight));
}
catch { }
t = null;
try
{
pe.Graphics.DrawImage(closeButton, this.Width - 2 - Storage.LoadedSkin.currentSkin.Form_CloseButtonWidth, 1, Storage.LoadedSkin.currentSkin.Form_CloseButtonWidth, Storage.LoadedSkin.currentSkin.Form_CloseButtonHeight);
closeButtonLocation.X
}
catch { }
try
{
pe.Graphics.DrawImage(maxButton, this.Width - 2 - (Storage.LoadedSkin.currentSkin.Form_CloseButtonWidth + Storage.LoadedSkin.currentSkin.Form_MaximizeButtonWidth) - 1, 1, Storage.LoadedSkin.currentSkin.Form_MaximizeButtonWidth, Storage.LoadedSkin.currentSkin.Form_MaximizeButtonHeight);
}
catch { }
try
{
pe.Graphics.DrawImage(minButton, this.Width - 2 - (Storage.LoadedSkin.currentSkin.Form_CloseButtonWidth + Storage.LoadedSkin.currentSkin.Form_MaximizeButtonWidth + Storage.LoadedSkin.currentSkin.Form_MinimizeButtonWidth) - 1, 1, Storage.LoadedSkin.currentSkin.Form_MinimizeButtonWidth, Storage.LoadedSkin.currentSkin.Form_MinimizeButtonHeight);
}
catch { }
SizeF textSize = pe.Graphics.MeasureString(formText, DisplayFont);
Int32 textWidth = (int)textSize.Width + 2;
StringFormat sFormat = new StringFormat();
sFormat.LineAlignment = StringAlignment.Center;
Rectangle wrapTangle = new Rectangle(0, 0, textWidth, Storage.LoadedSkin.currentSkin.Form_TitleBarHeight);
pe.Graphics.DrawString(formText, DisplayFont, new SolidBrush(Color.White), wrapTangle, sFormat);
}
else
{
pe.Graphics.DrawString("No Skin Loaded", new Font("Arial", 10), Brushes.RoyalBlue, new PointF(30.0F, 50.0F));
}
}
As you can see i am painting all the buttons. The form is set to have no border so i can do the form painting myself.
Kirtan PatelPosted Oct 19, 2009, 6:50 AM
Giles PapworthPosted Oct 19, 2009, 6:43 AM
I am assuming at this point that there is some sort of graphics buffer it draws to and from to ansure that only certain bits are updated.
Kirtan PatelPosted Oct 19, 2009, 6:41 AM
http://www.codeproject.com/KB/buttons/glassbutton.aspx