我一直致力于创建自定义RichTextBox
控件,以便为文本区域添加一些额外的图形。根据我一直在阅读的内容,此控件默认情况下不会公开其Paint事件。
我按照MSDN上的建议(Painting on a RichTextBox Control )重新公开了Paint事件,并创建了一个由OnPaint
消息触发的WM_PAINT
事件处理程序。
在OnPaint
方法中,我试图从Win32 API调用BeginPaint()
来绘制一些形状,但没有绘制任何形状。当我检查rcPaint
结构内的PAINTSTRUCT
字段时,它总是为空(所有值都为0)。所以我的问题是,为什么更新区域总是空的?我一定错过了什么。
相关代码:
public partial class RichTextBoxEnhanced : RichTextBox
{
private PAINTSTRUCT ps;
new public void OnPaint(PaintEventArgs e)
{
var hdc = BeginPaint(this.Handle, out ps);
FillRect(hdc, ref ps.rcPaint, CreateSolidBrush(100));
Rectangle(hdc, 1000, 2000, 1000, 2000);
EndPaint(this.Handle, ref ps);
Paint?.Invoke(this, e);
}
[DllImport("user32.dll")]
static extern IntPtr BeginPaint(IntPtr hwnd, out PAINTSTRUCT lpPaint);
[DllImport("user32.dll")]
static extern bool EndPaint(IntPtr hWnd, [In] ref PAINTSTRUCT lpPaint);
[DllImport("gdi32.dll")]
static extern IntPtr CreateSolidBrush(uint crColor);
}
答案 0 :(得分:1)
您必须浏览WndProc
并允许控件执行默认绘制。您可以使用Graphics
对象进行绘画。例如:
public partial class MyRichEdit : RichTextBox
{
public MyRichEdit()
{
InitializeComponent();
}
protected override void WndProc(ref Message msg)
{
switch (msg.Msg)
{
case 15://WM_PAINT
base.WndProc(ref msg);
Graphics g = Graphics.FromHwnd(Handle);
Pen pen = new Pen(Color.Red);
g.DrawRectangle(pen, 0, 0, 10, 10);
return;
}
base.WndProc(ref msg);
}
}
答案 1 :(得分:0)
我发现了这个问题。 @andlabs评论让我看看我被覆盖的WndProc
方法。我的绘画方法是在base.WndProc(ref msg)
之后调用的,它显然执行BeginPaint
。移动我上面的OnPaint()
方法可以解决问题。
错误的代码:
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case WM_PAINT:
mBaseControl.Invalidate();
base.WndProc(ref m);
OnPaint();
break;
default:
base.WndProc(ref m);
break;
}
}
正确的代码:
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case WM_PAINT:
mBaseControl.Invalidate();
OnPaint();
base.WndProc(ref m);
break;
default:
base.WndProc(ref m);
break;
}
}