Antialiasing the text in Windows Forms Controls

R

RSH

I have been experimenting with overriding the Paint event on Win Form
controls...more specifically trying to force the text to render as
Antialiased text. I have not been successful in any of the methods Ive
tried...is there a trick? Any information or examples would be greatly
appreciated.

Thanks!
Ron
 
N

Nicholas Paldino [.NET/C# MVP]

Ron,

What is the call to DrawString that you are making? Are you setting the
TextRenderingHint property on the Graphics instance you are using to draw to
the form?
 
R

RSH

Nicholas,

Here is what I have pieced together so far. My problem is that I see both
the text that was set in the label1.Text property, as well as my formatted
text. I cant figure out how to get rid of the previous text as setting the
label1.Text property = ""; erases all text.

private void SmoothingFonts_Paint(object sender,
System.Windows.Forms.PaintEventArgs e)

{

Label lbl = (Label)sender;

Font TextFont = new Font("Arial", 12, FontStyle.Regular);

e.Graphics.TextRenderingHint = TextRenderingHint.AntiAlias;

int height = lbl.Size.Height + 20;

int width = lbl.Size.Width + 500;

Size size = new Size(width, height);

Rectangle rect = new Rectangle(lbl.Location, size);

e.Graphics.DrawString(lbl.Text, TextFont, Brushes.White,
lbl.ClientRectangle);

}





Nicholas Paldino said:
Ron,

What is the call to DrawString that you are making? Are you setting
the TextRenderingHint property on the Graphics instance you are using to
draw to the form?


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

RSH said:
I have been experimenting with overriding the Paint event on Win Form
controls...more specifically trying to force the text to render as
Antialiased text. I have not been successful in any of the methods Ive
tried...is there a trick? Any information or examples would be greatly
appreciated.

Thanks!
Ron
 
P

Peter Duniho

Nicholas,

Here is what I have pieced together so far. My problem is that I see
both
the text that was set in the label1.Text property, as well as my
formatted
text. I cant figure out how to get rid of the previous text as setting
the
label1.Text property = ""; erases all text.

To be perfectly honest, I'm not convinced there's going to be a good way
of doing what you want, using the Label control.

The main problem you're running into is that when you handle the Paint
event, you don't change any of the original paint behavior. You can only
add to it. Thus the duplicated text.

You _could_ work around this by creating a Label-derived class, overriding
the OnPaint() method, and _not_ calling the base OnPaint() method. But at
that point, you're basically handling all of the rendering duties
yourself. This assumes that overriding OnPaint() would actually stop the
base class from drawing the text, which I'm not even all that sure about..
Most of the .NET controls are wrappers around existing Windows unmanaged
controls, and they often don't have any connection between the public .NET
API and their underlying workings. Suppressing the base class's rendering
might be more involved than just overriding OnPaint() in a derived class..

In any case, you'd probably find it just as straightforward to create your
own custom Label-like class, derived straight from Control, rather than
trying to override the existing Label class. On the bright side, of all
the .NET Forms controls, Label is one of the simplest and so should be one
of the easiest to replicate yourself. :)

One thing that you _might_ want to try is writing a custom Label-derived
class and just overriding the graphical settings when the painting is
done. Per my comment above, this may or may not be possible from the
OnPaint() method, assuming it's possible at all. If it is, it should be
as simple as setting the anti-aliasing in the PaintEventArgs.Graphics
instance and then calling base.OnPaint().

If it's not that simple, the next thing to try would be to override the
WndProc() method, check the message ID and handle WM_PAINT. There, you'd
get the HDC from the message data (in the lParam, if I recall correctly),
set the graphical settings using unmanaged code on the HDC, and then call
the base WndProc() method to allow the control to do the actual drawing.

All of the above is speculative, and frankly I wouldn't bother if you can
actually just write a custom label class that will do what you want. If
you think you are going to need this sort of technique with _other_ kinds
of control classes, then it might actually make sense to go to the work
above. It's not necessarily going to be easy, but once you've figured it
out, it should work with most of the .NET Forms control classes.

If you do get it to work, don't forget to post your solution back here. :)

Pete
 
R

RSH

Peter,

Thank you for the great information you provided!

I did manage to get the label working by overriding the Label class, that
worked perfectly! Then as you suggested I went to the textbox control.
MUCH different! But I did subclass a custom control and accessed the paint
event through unmanaged code. Im still working through that, but it seems
like it will work.

I will post the solution when I actually get everything working.

thanks!
Ron


Nicholas,

Here is what I have pieced together so far. My problem is that I see
both
the text that was set in the label1.Text property, as well as my
formatted
text. I cant figure out how to get rid of the previous text as setting
the
label1.Text property = ""; erases all text.

To be perfectly honest, I'm not convinced there's going to be a good way
of doing what you want, using the Label control.

The main problem you're running into is that when you handle the Paint
event, you don't change any of the original paint behavior. You can only
add to it. Thus the duplicated text.

You _could_ work around this by creating a Label-derived class, overriding
the OnPaint() method, and _not_ calling the base OnPaint() method. But at
that point, you're basically handling all of the rendering duties
yourself. This assumes that overriding OnPaint() would actually stop the
base class from drawing the text, which I'm not even all that sure about.
Most of the .NET controls are wrappers around existing Windows unmanaged
controls, and they often don't have any connection between the public .NET
API and their underlying workings. Suppressing the base class's rendering
might be more involved than just overriding OnPaint() in a derived class.

In any case, you'd probably find it just as straightforward to create your
own custom Label-like class, derived straight from Control, rather than
trying to override the existing Label class. On the bright side, of all
the .NET Forms controls, Label is one of the simplest and so should be one
of the easiest to replicate yourself. :)

One thing that you _might_ want to try is writing a custom Label-derived
class and just overriding the graphical settings when the painting is
done. Per my comment above, this may or may not be possible from the
OnPaint() method, assuming it's possible at all. If it is, it should be
as simple as setting the anti-aliasing in the PaintEventArgs.Graphics
instance and then calling base.OnPaint().

If it's not that simple, the next thing to try would be to override the
WndProc() method, check the message ID and handle WM_PAINT. There, you'd
get the HDC from the message data (in the lParam, if I recall correctly),
set the graphical settings using unmanaged code on the HDC, and then call
the base WndProc() method to allow the control to do the actual drawing.

All of the above is speculative, and frankly I wouldn't bother if you can
actually just write a custom label class that will do what you want. If
you think you are going to need this sort of technique with _other_ kinds
of control classes, then it might actually make sense to go to the work
above. It's not necessarily going to be easy, but once you've figured it
out, it should work with most of the .NET Forms control classes.

If you do get it to work, don't forget to post your solution back here. :)

Pete
 
P

Peter Duniho

Thank you for the great information you provided!

You're welcome.
I did manage to get the label working by overriding the Label class, that
worked perfectly!

Really? I'm pleasantly surprised. :)
Then as you suggested I went to the textbox control.
MUCH different! But I did subclass a custom control and accessed the
paint
event through unmanaged code. Im still working through that, but it
seems
like it will work.

I will post the solution when I actually get everything working.

Excellent. I look forward to see what an actual solution looks like, as
opposed to my own speculation. :)

Pete
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top