RE: Overriding RichTextBox OnPaint() Problems

  • Thread starter Thread starter Guest
  • Start date Start date
In VB, I have done a simliar thing..

Firstly override the WndProc as you stated.. handle message &HF (WM_PAINT)
and &H85 (WM_NCPAINT i think ) .. code below..

However you will find that the graphics that you can get from CreateGraphics
for the textbox or richtextbox does not include the border region..

You will need to define two external functions to get the correct graphics
region.. also shown below...

I have typed the stuff below from memory, but I think that's about right, it
should get you started in the right direction anyway..

HTH

Rigga

<CODE>

Protected Overrides Sub WndProc(ByRef m As Message)

MyBase.WndProc(m)

Select Case m.Msg
Case &H85
DrawTextBoxBorder()
Case &HF
DrawTextBoxBorder()
End Select

End Sub


Private Sub DrawTextBoxBorder()

Dim hdc As IntPtr
hdc = GetWindowDC(Handle)

Dim drawRect As Rectangle = New Rectangle(0, 0, Width, Height)
Dim g As Graphics = Graphics.FromHdc(hdc)

g.DrawRectangle(New Pen(Color.black, 3), drawRect.Left,
drawRect.Top, drawRect.Width - 2, drawRect.Height - 2)

ReleaseDC(Handle, hdc)

End Sub


Public Declare Ansi Function GetWindowDC Lib "User32.dll" (ByVal hwnd As
IntPtr) As IntPtr
Public Declare Ansi Function ReleaseDC Lib "User32.dll" (ByVal hWnd As
IntPtr, ByVal hDC As IntPtr) As Integer

<END CODE>
 
thanks for your reply

that is exactly what i did. it works fine for painting the border. however, now i have a problem with the border flickering as it is painted when you type inside the text box. i don't think double buffering or anything like that would help since i am painting on top after the control is drawn. anyone know a way around that

----- Rigga wrote: ----

In VB, I have done a simliar thing.

Firstly override the WndProc as you stated.. handle message &HF (WM_PAINT
and &H85 (WM_NCPAINT i think ) .. code below.

However you will find that the graphics that you can get from CreateGraphic
for the textbox or richtextbox does not include the border region.

You will need to define two external functions to get the correct graphic
region.. also shown below..

I have typed the stuff below from memory, but I think that's about right, i
should get you started in the right direction anyway.

HT

Rigg

<CODE

Protected Overrides Sub WndProc(ByRef m As Message

MyBase.WndProc(m

Select Case m.Ms
Case &H8
DrawTextBoxBorder(
Case &H
DrawTextBoxBorder(
End Selec

End Su


Private Sub DrawTextBoxBorder(

Dim hdc As IntPt
hdc = GetWindowDC(Handle

Dim drawRect As Rectangle = New Rectangle(0, 0, Width, Height
Dim g As Graphics = Graphics.FromHdc(hdc

g.DrawRectangle(New Pen(Color.black, 3), drawRect.Left
drawRect.Top, drawRect.Width - 2, drawRect.Height - 2

ReleaseDC(Handle, hdc

End Su


Public Declare Ansi Function GetWindowDC Lib "User32.dll" (ByVal hwnd A
IntPtr) As IntPt
Public Declare Ansi Function ReleaseDC Lib "User32.dll" (ByVal hWnd A
IntPtr, ByVal hDC As IntPtr) As Intege

<END CODE
 
Try not to call the base.WndProc() when the message is WM_NCPAINT. This will prevent the system from drawing the non-client area which is the border... Not sure if it will work though..
 
that doen's work either. i think i finally found a solution though. the problem was that i really needed to paint on the form itself, not on the control. when i paint on the control it causes flicker and when i use scrolling it paints the border all over the control. here is the code , if anyone is interested, that paints on the parent form and seems to solve all the problems

<code
using System
using System.Collections
using System.ComponentModel
using System.Drawing
using System.Data
using System.Windows.Forms
using System.Runtime.InteropServices

namespace FlatRT

/// <summary
/// Summary description for FlatRTB
/// </summary
public class FlatRTB : System.Windows.Forms.RichTextBo


[DllImport("user32")
private static extern IntPtr GetDC
IntPtr hWnd)

[DllImport("user32")
private static extern int ReleaseDC
IntPtr hWnd,
IntPtr hdc)


private const int WM_PAINT = 0xF
private const int WM_NCPAINT = 0x85

public FlatRTB(

this.SetStyle (ControlStyles.DoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);


/// <summary
/// Calls the base WndProc for the control an
/// responds to events allowing the control to b
/// drawn with a flat style
/// </summary
/// <param name="m">WndProc Message.</param

protected override void WndProc(ref Message m

// Call the base Window Procedure
base.WndProc(ref m)

// Process messages for overpainting
switch (m.Msg

case WM_PAINT
paintBorder()
break
case WM_NCPAINT
break



private void paintBorder(

Rectangle rcItem
IntPtr hDC = IntPtr.Zero

rcItem = new Rectangle(this.Left - 1, this.Top - 1, this.Width + 1, this.Height + 1)

hDC = GetDC(this.Parent.Handle)
Graphics gfx = Graphics.FromHdc(hDC)

Pen pen = new Pen(Color.Black,1)
gfx.DrawRectangle(pen, rcItem)

pen.Dispose()
gfx.Dispose()
ReleaseDC(this.Handle, hDC)






----- Iulian Ionescu wrote: ----
Try not to call the base.WndProc() when the message is WM_NCPAINT. This will prevent the system from drawing the non-client area which is the border... Not sure if it will work though..
 
i forgot to add that you also need to set the BorderStyle property of the instance of the FlatRTB conrol on your form to "None" so that the painted border is the only one seen.
 
Back
Top