Post by "KevinShan", 02-27-2007, 12:20
-----------------------------------------------------
使用TextRenderer.DrawText在控件上面画文字,在Win2000环境下所画的文字显示不出来。而在WinXP下可以正常显示 (微软的Label控件也是用TextRenderer画的,在两种环境下都可以显示出来)。 不知道是什么问题,在这里寻求大家的帮助。谢谢!
开发环境: .NET2.0 + Vs2005
下面使我测试用的画文字的代码,
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Text;
- using System.Windows.Forms;
- namespace DrawTextDemo
- {
- public class TestControl : Control
- {
- protected override void OnPaint(PaintEventArgs pe)
- {
- // 使用TextRenderer.DrawText在Win2000下显示不处理,XP系统下正常.
- TextRenderer.DrawText(pe.Graphics, this.Text, this.Font, Point.Empty, this.ForeColor);
- // 使用Graphics.DrawString在Win2000下和Xp下面均正常.
- pe.Graphics.DrawString(this.Text, this.Font, SystemBrushes.WindowText, new PointF(0f, 50f));
- base.OnPaint(pe);
- }
- }
- }
复制代码 Reply by "ted", 02-28-2007, 16:51
-----------------------------------------------------
貌视很诡异的问题:
Reflector Lable的代码后发现,其使用了另外一个重载的DrawText函数:
- public static void DrawText (
- IDeviceContext dc,
- string text,
- Font font,
- Rectangle bounds, // 注意到这里传入是Rectangle
- Color foreColor
- )
复制代码 于是更改TestControl的写法如下:
- public class TestControl : Control
- {
- protected override void OnPaint(PaintEventArgs pe)
- {
- // Use TextRenderer.
- TextRenderer.DrawText(pe.Graphics, this.Text, this.Font, new Rectangle(0,0,100,30), this.ForeColor);
- // Use Graphics
- pe.Graphics.DrawString(this.Text, this.Font, SystemBrushes.WindowText, new PointF(0f, 50f));
- base.OnPaint(pe);
- }
- }
复制代码 Text将被画出。
于是再Reflector TextRenderer的public static void DrawText(IDeviceContext dc, string text, Font font, Point pt, Color foreColor){}函数,发现其最终调到的代码是:
- public void DrawText(string text, WindowsFont font, Point pt, Color foreColor, Color backColor, IntTextFormatFlags flags)
- {
- Rectangle bounds = new Rectangle(pt.X, pt.Y, 0x7fffffff, 0x7fffffff);
- this.DrawText(text, font, bounds, foreColor, backColor, flags);
- }
复制代码 其内部创建了一个长宽均为0x7fffffff的矩形来绘画文字。
尝试下面的代码:
- TextRenderer.DrawText(pe.Graphics, this.Text, this.Font, new Rectangle(0,0,0x7fffffff,0x7fffffff), this.ForeColor);
复制代码 没有任何显示。
所以我想原因可能在于在Win2000上实际绘画的API函数不能处理长宽均为0x7fffffff的矩形,而Xp及以后的操作系统均支持。
Reply by "KevinShan", 02-28-2007, 17:01
-----------------------------------------------------
非常感谢!
这应该是微软的一个Bug, 我原来也碰到过类似的问题。如CreateRectRgn的API也只能接受小于27 bit的整数。
问题出在TextRenderer在调用native code的时候传递的Rectangle太大导致在Win2000下面API调用出错,XP以上系统已经解决。
Reply by "Leo", 02-28-2007, 17:33
-----------------------------------------------------
简单的试了一下Code。发现如果我们使用DrawText方法传参数是一个点而不是一个Rectangle就会导致在2000系统下完全不显示。
使用Reflector重新拜读了TextRenderer的代码。发现有这么一段
- public void DrawText(string text, WindowsFont font, Point pt, Color foreColor, Color backColor, IntTextFormatFlags flags)
- {
- Rectangle bounds = new Rectangle(pt.X, pt.Y, 0x7fffffff, 0x7fffffff);
- this.DrawText(text, font, bounds, foreColor, backColor, flags);
- }
复制代码 发现给的Rectangle的长和宽都比较大。不知道是否会导致API调用失败。然后尝试跟了一下API调用结果。发现返回结果非零,说明API调用成功。但是什么也画不出来。
目前这个问题已经解决了。使用TextRenderer的时候传参数给出具体的Rectangle的大小。但是为什么这样还不是很清楚。不知道那位高手能指点一下。 |
|