Multiline RichTextBox flashes as backspacing occurs

G

Guest

Hello,

I've asked about this kind of thing before but I'm still having problems
with it. Below is a stripped down version of my code to do a backspace in a
multiline RichTextBox. I know it still needs some work to make it work for
all cases but my question is more basic so I think you can probably ignore
the minor details (?). My main question concerns why all the text in the box
flashes each time I do a backspace and what can be done to prevent it.
Although I may be mistaken, it appears that during the bacspace algorithm the
caret momentarily jumps to the beginning of the string containing the text
for the entire control, then back to where it belongs. Commercial
applications I've seen don't have this problem so I'm sure I'm doing
something wrong. Any ideas?

Thanks,
Ray

if (ch == '\b')
{
int lineNo = rtfTerminal.Lines.Length - 1;

if (lineNo >= 0)
{
int colNo = rtfTerminal.Lines[lineNo].Length - 1;
if (colNo > 0 && rtfTerminal.Lines[lineNo][colNo] != '\n')
{
string s = rtfTerminal.Lines[lineNo].Substring(0, colNo);
string[] lines = rtfTerminal.Lines;
lines[lineNo] = s;
rtfTerminal.Lines = lines;
rtfTerminal.Select(rtfTerminal.TextLength, 0);
}
}
}
 
P

Peter Duniho

[...]
Although I may be mistaken, it appears that during the bacspace
algorithm the
caret momentarily jumps to the beginning of the string containing the
text
for the entire control, then back to where it belongs.

It does that, and more.

You are replacing the entire text of the control with a whole new group of
text. When this happens, the control has no way to know that the text is
only different by a single character. It acts as though it would when you
replace the text of a control with any new text: it resets the selection
and redraws the entire control. The selection winds up back at the end
because you explicitly put it there.

For what it's worth, the flashing is almost certainly mostly due to
replacing the text, and not to the selection change.
Commercial
applications I've seen don't have this problem so I'm sure I'm doing
something wrong. Any ideas?

Well, a couple of thoughts:

1) I'm not really clear on why you need a "backspace algorithm". The
text box control handles the backspace key just fine.

2) If what you are doing is mapping some other kind of input to the
text box in a way that should emulate the user pushing the backspace even
when they are not, one thing you can do is send the appropriate keys
directly. There are a variety of ways you can try to do this, none of
them great IMHO. The most popular is probably the SendKeys class, but as
near as I can tell, there is no way to guarantee that your own application
will actually get the keys, and it would require that the text box control
has the current focus (which may or may not be true in your case).

If I really wanted to approach it this way, I would create a derived class
from the text box class, and then provide specific methods to simulate the
input you want, creating a Message instance that emulates the keyboard
input you want to emulate, and calling the WndProc method for the control,
passing that Message to it. You'll probably have to simulate the
WM_KEYDOWN and WM_KEYUP messages at a minimum; I'm not sure what else
you'd have to do, but it could be a little tricky to get it just right (or
it might not...like I said, I'm not sure :) )

3) Probably the best way to handle it would be to do it the way that
"commercial applications" most likely do it (I can't speak for any
specific one, since you didn't mention which ones you're talking about).
That is, they don't use the built-in edit controls, and they don't wind up
having to redraw the entire control just because one character changed.
It wouldn't be hard to create your own textbox control, and if you do so
you can provide right in the control whatever mechanism you want for
dealing with backspaces and other types of input not coming directly from
the user's keyboard. You would also be able to in that case make sure
that only the part of the control that actually needed redrawing when some
text was changed was actually redrawn.

Pete
 
G

Guest

Peter Duniho said:
[...]
Although I may be mistaken, it appears that during the bacspace
algorithm the
caret momentarily jumps to the beginning of the string containing the
text
for the entire control, then back to where it belongs.

It does that, and more.

You are replacing the entire text of the control with a whole new group of
text. When this happens, the control has no way to know that the text is
only different by a single character. It acts as though it would when you
replace the text of a control with any new text: it resets the selection
and redraws the entire control. The selection winds up back at the end
because you explicitly put it there.

For what it's worth, the flashing is almost certainly mostly due to
replacing the text, and not to the selection change.
Commercial
applications I've seen don't have this problem so I'm sure I'm doing
something wrong. Any ideas?

Well, a couple of thoughts:

1) I'm not really clear on why you need a "backspace algorithm". The
text box control handles the backspace key just fine.

2) If what you are doing is mapping some other kind of input to the
text box in a way that should emulate the user pushing the backspace even
when they are not, one thing you can do is send the appropriate keys
directly. There are a variety of ways you can try to do this, none of
them great IMHO. The most popular is probably the SendKeys class, but as
near as I can tell, there is no way to guarantee that your own application
will actually get the keys, and it would require that the text box control
has the current focus (which may or may not be true in your case).

If I really wanted to approach it this way, I would create a derived class
from the text box class, and then provide specific methods to simulate the
input you want, creating a Message instance that emulates the keyboard
input you want to emulate, and calling the WndProc method for the control,
passing that Message to it. You'll probably have to simulate the
WM_KEYDOWN and WM_KEYUP messages at a minimum; I'm not sure what else
you'd have to do, but it could be a little tricky to get it just right (or
it might not...like I said, I'm not sure :) )

3) Probably the best way to handle it would be to do it the way that
"commercial applications" most likely do it (I can't speak for any
specific one, since you didn't mention which ones you're talking about).
That is, they don't use the built-in edit controls, and they don't wind up
having to redraw the entire control just because one character changed.
It wouldn't be hard to create your own textbox control, and if you do so
you can provide right in the control whatever mechanism you want for
dealing with backspaces and other types of input not coming directly from
the user's keyboard. You would also be able to in that case make sure
that only the part of the control that actually needed redrawing when some
text was changed was actually redrawn.

Pete

Hi Pete,

Thanks for taking the time for such a detailed reply. Just to give you a
little more information, what I'm writing is very similar to applications
like TereTerm and HyperTerm. These are also the commercial applications I
was referring to regarding the fact that they don't flash as the data comes
in. I these cases, as well as mine, local keystrokes (if not in local echo
mode) don't get put on the screen directly by the control but, rather, get
echoed back into the serial port by the remote device. These incoming
characters must then be put into the control manually. When I try to simply
append an incoming backspace it results in some funky character being
displayed. Thus, I believe I need a backspace algorithm. So, I was
wondering how TereaTerm and HyperTerm and a host of other similar
applications can display continuous data without even a hint of flashing. I
don't think any of them use C# but hopefully that's not the issue anyway.

Thanks again,
Ray
 
P

Peter Duniho

[...] So, I was
wondering how TereaTerm and HyperTerm and a host of other similar
applications can display continuous data without even a hint of
flashing. I
don't think any of them use C# but hopefully that's not the issue anyway.

No, C# is definitely not the issue here. You would have the same issue
regardless of the language you're using.

As I mentioned, I suspect that those applications don't use the built-in
edit controls. It's not hard to write your own text display control, or
even to not bother with the control at all and just handle drawing the
necessary text to the window directly.

As an aside, I realize that .NET makes it seem like you always have to
display things in a control, but in reality lots of Windows applications
have _no_ controls in their windows, and draw everything directly into the
window. In fact, .NET sort of turns the previous convention for Windows
applications upside down. It used to be that controls were special kinds
of windows. In .NET, a Form (which is roughly equivalent to a window) is
a special kind of Control.

Anyway, it occurs to me (finally :) ) that one way to eliminate the
flashing you're seeing is to enable double-buffering for your form. This
will cause all of the updating to happen off-screen, and then the screen
to be updated only after a completely new image has been created, and
without erasing the previous one. This almost always eliminates any
flashing you might see.

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