|
<br />
protected override void WndProc(ref Message m)<br />
{<br />
if (this.DropDownStyle == ComboBoxStyle.Simple)<br />
{<br />
base.WndProc(ref m);<br />
return;<br />
}<br />
<br />
IntPtr hDC = IntPtr.Zero;<br />
Graphics gdc = this.CreateGraphics();<br />
switch (m.Msg)<br />
{<br />
case WM_NC_PAINT:<br />
base.WndProc(ref m);<br />
PaintFlatControlBorder(this, gdc);<br />
gdc.Dispose();<br />
break;<br />
case WM_PAINT:<br />
base.WndProc(ref m);<br />
Pen p = new Pen((this.Enabled ? BackColor : SystemColors.Control), 2);<br />
gdc.DrawRectangle(p, new Rectangle(2, 2, this.Width - 3, this.Height - 3));<br />
PaintFlatDropDown(this, gdc);<br />
PaintFlatControlBorder(this, gdc);<br />
gdc.Dispose();<br />
break;<br />
default:<br />
base.WndProc(ref m);<br />
break;<br />
}<br />
}<br />
I just hate .NET + win32 :>...
|
|
|
|
|
Hi,
There is a slight difference between Graphics.CreateGraphics and Win32 Graphics.FromHdc using the Win32 device context. CreateGraphics give you the DC for the client area only, whereby FromHdc gives you the entire window area including non-client area. We need this to paint our border around the bound of the control. WM_NC_PAINT (Non Client area paint) is the windows event message sent specifically for paintint the non client area.
Hope the explaination above helps.
Fadrian
|
|
|
|
|
|
How to make birthday reminders in C# 2003
Thimani
|
|
|
|
|
By your code,I tried to make standard TextBox appear flat,but i couldn't handle the ScrollBars property very well,especially when ScrollBars property set
System.Windows.Forms.ScrollBars.Vertical(I want to make the TextBox Border Color can looks other color,include the ScrollBars,not standard style),It always has some problem.My english is poor,I hope that you can understand,thank you very much.
-- modified at 23:13 Thursday 13th April, 2006
Follow is Mainly code
private void DrawScrollButton(System.Drawing.Graphics g)
{
if ( ScrollBars == System.Windows.Forms.ScrollBars.Vertical )
{
Int16 btnHeight = (Int16)Math.Min(Math.Ceiling((this.Height - 4) / 2.0),MaxScrollButtonHeight);
Int32 left = this.Width - this.ScrollButtonWidth -3;
Int32 downButtonTop = this.Height - btnHeight - 3;
System.Drawing.Rectangle upBtn = new Rectangle(left,3,ScrollButtonWidth,btnHeight);
ControlPaint.DrawScrollButton(g,upBtn,ScrollButton.Up,ButtonState.Flat);
System.Drawing.Rectangle downBtn = new Rectangle(left,downButtonTop,ScrollButtonWidth,btnHeight);
ControlPaint.DrawScrollButton(g,downBtn,ScrollButton.Down,ButtonState.Flat);
// if ( ( downButtonTop - 1) > (btnHeight + 4) )
// {
// g.FillRectangle(new SolidBrush(Focused ? Color.Transparent : _ScrollBarColor),new Rectangle(left,btnHeight + 4,ScrollButtonWidth,downButtonTop - btnHeight -5));
// }
if ( this.ReadOnly == true || this.Enabled == false )
{
// DrawLine(g,left,3,left,downButtonTop,_DisableColor);
DrawRectangle(g,upBtn,_DisableColor);
DrawRectangle(g,downBtn,_DisableColor);
return;
}
if ( this.Focused )
{
// DrawLine(g,left,3,left,downButtonTop,_HightlightColor);
DrawRectangle(g,upBtn,_HightlightColor);
DrawRectangle(g,downBtn,_HightlightColor);
}
else
{
// DrawLine(g,left,3,left,downButtonTop,_NormalColor);
DrawRectangle(g,upBtn,_NormalColor);
DrawRectangle(g,downBtn,_NormalColor);
}
}
}
|
|
|
|
|
Hi,
Completely redrawing over the scrollbar is not easy and it requires you to do a lot more then the above.
To get a flat text box, you can simply do:
- Create a textbox and set the border to FixedSingle
- The standard border is quite awful, so you can use similar method to above to draw the border of your prefered colour or style
I haven't tried to paint over scrollbar before, but I believe you will need to trap the scroll event as well
Fadrian
|
|
|
|
|
I can't seem to get this working in vs2005, even though in vs2003 it all works fine. Its reporting the following error:
A call to PInvoke function 'ELSA 1.1!ELSA.FlatComboBox::SendMessage' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.
relating to line 108:
switch (m.Msg)<br />
{<br />
case WM_NC_PAINT: <br />
hDC = GetWindowDC(this.Handle);<br />
gdc = Graphics.FromHdc(hDC);<br />
SendMessage(this.Handle, WM_ERASEBKGND, hDC, 0);
SendPrintClientMsg();
PaintFlatControlBorder(this, gdc);<br />
m.Result = (IntPtr) 1;
ReleaseDC(m.HWnd, hDC);<br />
gdc.Dispose(); <br />
<br />
break;<br />
At the moment I am struggling to fix it. Any ideas?
|
|
|
|
|
Hi,
I tested and it actually works fine. I start to suspect it is either the installed framework is corrupted or perhaps you have a later operating system then what I'm running?
Also, if you are using VS2005, wouldn't it be just as easy to just use the standard combobox provided - which is now have the proper flat mode?
Fadrian
|
|
|
|
|
If it works fine for you then I am baffled. It works fine in 2003 but in 2005 it comes up with the above error. I am using Windows XP, and haven't encountered any other problems which could be related to corrupt framework.
The reason that I was hoping your combobox would work was that I have been using the flatmode provided by vs2005, but it has no support for a black border. What I am finding frustrating is that if you set textboxes to border style none they immediately shrink and only just fit around the text. Meanwhile comboboxes set to flatstyle still remain fat with plenty of padding inside. The solution to this is set textboxes to borderstyle fixedsingle, which remain fat - approx in proportion to comboboxes, but then there is a black border around all the textboxes that I cannot work out how to put around the comboboxes.
I was hoping your combobox would work as it has the black border! and looks neater. Any help would be hugely appreciated.
|
|
|
|
|
I initially tested on Beta 2, just because the PC on hand only had that and it was fine. Getting your reply I loaded the full vs2005 and get the same error! sorry for the confusion.
I got the fix for it.
Change the declaration to
[DllImport("user32.dll", EntryPoint="SendMessageA")]
public static extern int SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);
and in the code where you use the DC, you will have to do .ToInt32()
SendMessage(this.Handle, WM_ERASEBKGND, hDC.ToInt32(), 0);
and that will fix it.
Seem like .NET 2.0 is very strict with the pinvoke signature. In WINAPI, SendMessage does use DWORD for the param which should really be mapping to int32, but in .NET 1.1 if you do so, it give you another set of issues to workaround with.
Fadrian
|
|
|
|
|
Hi
Thnx it works 4 me as well in VS2005 thnx
|
|
|
|
|
Like many who use The Code Project we've spent countless hours building custom controls to meet our needs. Unfortunately, it's hard to justify spending thousands of hours on a custom control unless you intend to market them.
We've just released a beta of List Controls for .NET WinForms which includes the most advanced list box and combo box controls ever built for any platform.
Sounds too good to be true? Please, confirm this statement for yourself. A beta of List Controls is available for download from our website, including a comprehensive demo and tutorial.
http://www.it-partners.com/products/list_controls_win_forms/list_controls.asp[^]
Many features, too many to list here!
Brett Werner
it-partners.com
|
|
|
|
|
I want to use color in combo box and arow and background color of combo box.
plz help me how can i change it through CSS classes.
Ajay
Advance Scripter
|
|
|
|
|
Hi Ajay,
Unfortunately to my knowledge, you can only use css style with web control and not winform control. I would think to implement support for css will involve a lot of work.
I dont use css much and I would welcome pointers from others.
Fadrian
|
|
|
|
|
Hi,
I've slightly changed your control for my purpose and add colored border
onto it, problem is however with inner listbox. I think I will propably have to subclass it and redirect WM_NCPAINT to fake WndProc function, when I'll draw border of listbox in appropriate color. Do you plan to add this behaviour to your control? If you have it already, please let me know, I would like to save some time in writing it.
Thanks
Martin
martinhoge@seznam.cz
|
|
|
|
|
Martin,
I haven't done anything on that area yet. If you have done something it will be nice if you can share your work here.
Thanks,
Fadrian
|
|
|
|
|
There is a problem when i change RightToLeft property to Yes
|
|
|
|
|
Booky,
Thanks for pointing that out. It is something that I haven't looked at before
Well, I did a quick hack just then and it works for me. Below is the snipplet of the code that will do the job. Replace the original PaintFlatDropDown function with the revised code below.
private static bool DrawRightToLeft(Control ctrl)
{
if (ctrl.RightToLeft == RightToLeft.Yes ||
(ctrl.RightToLeft == RightToLeft.Inherit && ctrl.Parent.RightToLeft == RightToLeft.Yes))
{
return true;
}
return false;
}
public static void PaintFlatDropDown(Control ctrl, Graphics g)
{
Rectangle rect = new Rectangle(ctrl.Width-DropDownButtonWidth, 0, DropDownButtonWidth, ctrl.Height);
if (DrawRightToLeft(ctrl))
rect = new Rectangle(1, 0, DropDownButtonWidth, ctrl.Height);
ControlPaint.DrawComboButton(g, rect, ButtonState.Flat);
}
Hope that help.
Fadrian
|
|
|
|
|
flickering !!
If there are so much combobox in the same form, flickering is increaseing. Because Windows drawing the normal combobox before our painting.
Serdar YILMAZ
Senior Developer
|
|
|
|
|
Adding following code will not make flickering any more!!
protected override void OnPaint(PaintEventArgs e)
{
// base.OnPaint (e);
}
switch (m.Msg)
{
...
case WM_ERASEBKGND:
//indicate msg has been processed
m.Result = (IntPtr) 1;
break;
...
Thanks,
ChangYoung
jucyblue@gmail.com
jucyblue@gmail.com
|
|
|
|
|
Has no change ...
Serdar YILMAZ
Senior Developer
|
|
|
|
|
Thanks for the post and suggestion. I really don't have much idea on how to fix that, as my control is drawing on top of existing control to leverage all the existing functionality. If someone has a solution to this I will be please to know.
Fadrian
|
|
|
|
|
I changed Draw Mode of this control.
Now, there are NO flicker.
And I added ImageList properties.
public syComboBox()
{
...
...
base.SetStyle(ControlStyles.ResizeRedraw, true);
this.DrawMode = DrawMode.OwnerDrawVariable;
}
...
...
protected virtual void Draw(bool fillContent)
{
Graphics graphics1 = Graphics.FromHwnd(base.Handle);
// Drawing Border
... drawing border procedures
... if (this.isMouseOver | this.Focused) then draw HOT else draw NORMAL
// Drawing Button
ButtonState bs = (DroppedDown) ? ButtonState.Pushed : ButtonState.Normal;
... drawing combobox button procedures
if (fillContent)
{
Rectangle rectangle1 = (1, 1, this.Width-SystemInformation.HorizontalScrollBarArrowWidth-2, this.Height-2);
Color color1 = this.BackColor;
if (!base.Enabled)
{
color1 = SystemColors.Control;
}
SolidBrush brush1 = new SolidBrush(color1);
graphics1.FillRectangle(brush1, 1, 1, rectangle1.Width, 2); // top
graphics1.FillRectangle(brush1, 1, rectangle1.Bottom - 2, rectangle1.Width, 2); // bottom
graphics1.FillRectangle(brush1, 1, 1, 2, rectangle1.Height); // left
graphics1.FillRectangle(brush1, rectangle1.Right - 2, 1, 2, rectangle1.Height); // right
}
}
...
protected override void OnMouseLeave(EventArgs e)
{
base.OnMouseLeave(e);
this.isMouseOver = false;
this.Draw(false);
}
protected override void OnMouseEnter(EventArgs e)
{
base.OnMouseEnter(e);
this.isMouseOver = true;
this.Draw(false);
}
protected override void OnLostFocus(System.EventArgs e)
{
base.OnLostFocus(e);
this.Draw(false);
}
protected override void OnGotFocus(System.EventArgs e)
{
base.OnLostFocus(e);
this.Draw(false);
}
protected override void WndProc(ref Message msg)
{
if (msg.Msg == 15)
{
base.DefWndProc(ref msg);
this.Draw(true);
}
else
{
base.WndProc(ref msg);
}
}
-----------------
Serdar YILMAZ
Senior Developer
|
|
|
|
|
please, can you post the modified source ?
|
|
|
|
|
Great control, small, simple, and yet does all it's supposed to do. Well, most of it anyway, that's where I want to ask you some questions.
1.First is that I implemented a mouseenter/mouseleave event to highlight the border with different color depending on whether the mouse is hovering above the control or not. However if I repeatedly move my mouse in and out of control at least three-four times a second I notice a lot of flickering at the drop down button. My guess is that when you do a WM_PAINT event you let the default wndproc to take over and then paint the custom border and dropdown button which causes the flickering. Is there any way to redraw this manually without base class? I tried it, but I'm very new at this whole GDI and window messages thing, so, not surprisingly I failed.
2.This is also related to mouseenter/mouseleave thing. You said that your combobox did not work with simple style. What did you mean by that, what exactly did not work? Because for some reason, and I don't know why I have problems when the style is set to dropdown instead of dropdownlist. The issue I have is that when I set the style to dropdown, sometimes, when I move the mouse quickly in or out of the control mouseenter/mouseleave events do not fire. So the border of the control does not change, it's really annoying. I tried catching wm_mouseleave message in the wndproc, but it seems it never gets sent. Any idea what's causing it?
I also posted a question about your datetimepicker control. Can you take a look at it too?
Thanks.
|
|
|
|
|