Handling backspace in a RichTextBox - again!

Hello,

I'm revisiting a problem I've never solved satisfactorily.  I have a 
multi-line RichTextBox that receives text input from a serial port (not the 
keyboard); that input frequently contains backspace characters.  To handle 
the backspace characters I'm currently calculating the offset of the 
character to be backspaced over from the beginning of the entire text box, 
selecting that character, then replacing it with no character.  The "for" 
loop in the code below calculates the length of everything in the text box.  
While this scheme has worked correctly, it really slows the system down as 
the contents of the text box increases.  It seems that ideally I should be 
able to deal only with the last line in the text box instead of having to 
treat everything in the text box as one big long string, but I haven't 
figured out a way to do this.  Another brutal alternative to recalculating 
the entire length of the text box each time a backspace character is 
encountered would be to manually keep a running count of the total number of 
characters as they are added and subtracted, and this would doubtless speed 
things up significantly.  However, it seems that there still should be a 
better way.

Thanks,
Ray

***** I execute the following code each time a backspace character is 
encountered:

int displayLineCount = display.Lines.Length;
if (displayLineCount > 0)
{
   string lastLine = display.Lines[displayLineCount - 1];
   int lastLineLength = lastLine.Length;
   if (lastLineLength > 0)
   {
      // Get count of all characters from beginning of display up to the 
current line.
      // For purposes of calculating character offset of the last display 
character from
      // the beginning of the display, the length of each line is considered 
to be 1 plus
      // the number of characters on that line.
      int length = 0;
      for (int lineNo = 0; lineNo < displayLineCount - 1; ++lineNo)
         length += display.Lines[lineNo].Length + 1;
      display.Select(length + lastLineLength - 1, 1);
      display.SelectedText = "";
      display.SelectionStart = length + lastLineLength - 1;
   }
}

0
Utf
7/1/2010 7:47:11 PM
dotnet.languages.csharp 1931 articles. 0 followers. Follow

3 Replies
1240 Views

Similar Articles

[PageSpeed] 28

Ray Mitchell wrote:
> Hello,
> 
> I'm revisiting a problem I've never solved satisfactorily.  I have a 
> multi-line RichTextBox that receives text input from a serial port (not the 
> keyboard); that input frequently contains backspace characters.  To handle 
> the backspace characters I'm currently calculating the offset of the 
> character to be backspaced over from the beginning of the entire text box, 
> selecting that character, then replacing it with no character.  The "for" 
> loop in the code below calculates the length of everything in the text box.  
> While this scheme has worked correctly, it really slows the system down as 
> the contents of the text box increases.

Even the code you posted could be improved.  You should not need to 
recalculate the character position of interest from the contents of the 
control, since your own code is the code adding text to it (and so can 
easily keep track of that information).  And you should also only 
retrieve the Lines property value once; the array being returned has to 
be recreated each time you get the property value, and as the amount of 
text increases, that's a lot of data to be copied.

But I think all of that is actually not relevant.  It's not clear to me 
why you're calculating the text position the way you are, even ignoring 
its implicit assumption that the newline is only one character (have you 
checked to make sure that if "\r\n" is used as the newline, the text box 
control converts that to a single character?).  After all, in the end 
you are just trying to delete the last character of the text, right? 
Why not just use the TextLength property to determine the correct 
character offset?

So, assuming the backspace character should always just delete the last 
character in the control, it seems to me that the following should work 
just as well, and be much more efficient:

   int ichDelete = display.TextLength - 1;

   display.Select(ichDelete - 1, 1);
   display.SelectedText = "";
   display.SelectionStart = ichDelete;

(And actually, I haven't tested...it's possible that last line isn't 
required, since the selection has to wind up _somewhere_ after the 
delete and it's likely that the control will just put the text cursor in 
the location where you've just deleted the text).

> It seems that ideally I should be 
> able to deal only with the last line in the text box instead of having to 
> treat everything in the text box as one big long string, but I haven't 
> figured out a way to do this.  Another brutal alternative to recalculating 
> the entire length of the text box each time a backspace character is 
> encountered would be to manually keep a running count of the total number of 
> characters as they are added and subtracted, and this would doubtless speed 
> things up significantly.  However, it seems that there still should be a 
> better way.

See above.

Beyond that, you may recall that a couple of years ago, I pointed you to 
a simple custom control implementation I'd written as a demo but which 
could be modified to suit your needs.  In particular, by writing a 
custom control, you then have direct access to the internal data 
structures, and can provide whatever public API to the control class 
that best fits your usage scenarios.  I think that you can do much 
better with the RichTextBox class than you currently are, but it may 
well be that eventually you find it's just too limited.

If so, you may want to revisit this discussion:
http://groups.google.com/group/microsoft.public.dotnet.languages.csharp/browse_thread/thread/d4c6ff994e2286d7/ae29018b8c504219

Pete
0
Peter
7/1/2010 9:40:56 PM
"Peter Duniho" wrote:

> Ray Mitchell wrote:
> > Hello,
> > 
> > I'm revisiting a problem I've never solved satisfactorily.  I have a 
> > multi-line RichTextBox that receives text input from a serial port (not the 
> > keyboard); that input frequently contains backspace characters.  To handle 
> > the backspace characters I'm currently calculating the offset of the 
> > character to be backspaced over from the beginning of the entire text box, 
> > selecting that character, then replacing it with no character.  The "for" 
> > loop in the code below calculates the length of everything in the text box.  
> > While this scheme has worked correctly, it really slows the system down as 
> > the contents of the text box increases.
> 
> Even the code you posted could be improved.  You should not need to 
> recalculate the character position of interest from the contents of the 
> control, since your own code is the code adding text to it (and so can 
> easily keep track of that information).  And you should also only 
> retrieve the Lines property value once; the array being returned has to 
> be recreated each time you get the property value, and as the amount of 
> text increases, that's a lot of data to be copied.
> 
> But I think all of that is actually not relevant.  It's not clear to me 
> why you're calculating the text position the way you are, even ignoring 
> its implicit assumption that the newline is only one character (have you 
> checked to make sure that if "\r\n" is used as the newline, the text box 
> control converts that to a single character?).  After all, in the end 
> you are just trying to delete the last character of the text, right? 
> Why not just use the TextLength property to determine the correct 
> character offset?
> 
> So, assuming the backspace character should always just delete the last 
> character in the control, it seems to me that the following should work 
> just as well, and be much more efficient:
> 
>    int ichDelete = display.TextLength - 1;
> 
>    display.Select(ichDelete - 1, 1);
>    display.SelectedText = "";
>    display.SelectionStart = ichDelete;
> 

As usual Pete, very helpful answer.  Thanks very much.  The code above 
worked great, except that "ichDelete - 1" should be "ichDelete". 

> (And actually, I haven't tested...it's possible that last line isn't 
> required, since the selection has to wind up _somewhere_ after the 
> delete and it's likely that the control will just put the text cursor in 
> the location where you've just deleted the text).
> 
> > It seems that ideally I should be 
> > able to deal only with the last line in the text box instead of having to 
> > treat everything in the text box as one big long string, but I haven't 
> > figured out a way to do this.  Another brutal alternative to recalculating 
> > the entire length of the text box each time a backspace character is 
> > encountered would be to manually keep a running count of the total number of 
> > characters as they are added and subtracted, and this would doubtless speed 
> > things up significantly.  However, it seems that there still should be a 
> > better way.
> 
> See above.
> 
> Beyond that, you may recall that a couple of years ago, I pointed you to 
> a simple custom control implementation I'd written as a demo but which 
> could be modified to suit your needs.  In particular, by writing a 
> custom control, you then have direct access to the internal data 
> structures, and can provide whatever public API to the control class 
> that best fits your usage scenarios.  I think that you can do much 
> better with the RichTextBox class than you currently are, but it may 
> well be that eventually you find it's just too limited.
> 
> If so, you may want to revisit this discussion:
> http://groups.google.com/group/microsoft.public.dotnet.languages.csharp/browse_thread/thread/d4c6ff994e2286d7/ae29018b8c504219
> 
> Pete
> .
> 
0
Utf
7/2/2010 1:33:31 AM
Ray Mitchell wrote:
> [...]
>>    int ichDelete = display.TextLength - 1;
>>
>>    display.Select(ichDelete - 1, 1);
>>    display.SelectedText = "";
>>    display.SelectionStart = ichDelete;
>>
> 
> As usual Pete, very helpful answer.  Thanks very much.  The code above 
> worked great, except that "ichDelete - 1" should be "ichDelete". 

Quite right.  Sorry about that.  Managed to apply the "one character 
from the end" logic twice.  :)
0
Peter
7/2/2010 1:40:27 AM
Reply:

Similar Artilces:

RichTextBox WordWrap
I cannot get my RTB to wrap properly. I am set for vert scrollbar or both with (fiddled with each) The text does wrap bu not at the end of the actual proper point. Several words ar off screen right. As I resize, the text wrap changes but still leaves several words off the right side. I tried setting right margin with no luck. Must be something else I amd not doing. I tried different fonts: MSSANSERIF, Arial and Lucida Console(preferred). The text is loaded from a .rtf file created in MS WordPad since I do use Bold and Underline in the text. The text has also been through Word 20...

Exchange 2K to 2K3 migration
I'd like to get some advice on the best approach to handle the STM file during an Inter-Org mailbox move. The Exchange migration wizard will handle the the mailbox but how do you handle the content in the STM file? Thanks. You don't need to worry about it. Mailbox data is stored in both the EDB and STM files. Typically, message content from the Internet will be in the STM file. I'd suspect that when you migrate the mailboxes, all data will be converted to native MAPI format (moved to EDB file) and will then be moved to the new mailbox. -- Ben Winzenz Exchange MVP Me...

invalid handle
hi frds i m very new in vc++ and i m founding too much difficulty in this so plz can any one solve this problem .... actully i m inserting a image in list box using this code ........ everything is returning write thing still it is saying invalid handle after ImageList_Add(hList,m_hBmpNew,0); when i m going to dibug it plz help me BOOL Fun() { // Create 256 color image lists HIMAGELIST hList = ImageList_Create(32,32, ILC_COLOR8 , 8, 1); HBITMAP m_hBmpNew = (HBITMAP) LoadImage( AfxGetInstanceHandle(), // handle to instance "c:\\img.bmp", /...

Handle to an ActiveX control
Hi... What if I use GetModuleHandle(L"abc.ocx") in the InitInstance() of the of the App class derived from 'COleControlModule'...of the ActiveX control "abc.ocx" ? Will I get the Handle or it will return NULL....? I have encountered controls, in some of them..handle is found and in others its NULL... Wat is the reason behind this behavior..? Can any one explain? "Abby++" <asthana.abhinav@gmail.com> wrote in message news:1174308443.062622.51500@b75g2000hsg.googlegroups.com... > What if I use GetModuleHandle(L"abc.ocx") in the InitI...

Thunking a 32-bit HANDLE to a 64-bit HANDLE
Currently I am converting a 32-bit WDM driver to a 64-bit KMDF driver that will continue to work with our 32-bit DLL and our customer's 32-bit applications. The sample code for thunking 32-bit items shows the following Buffer->Handle = (HANDLE)Buffer32->Handle; see: http://msdn.microsoft.com/en-us/library/aa489604.aspx Buffer32->Handle is declared as UINT32 Handle The driver compiler issues error number C4312 for this cast. The code that I have adopted (to get it to compile) is: handlerInputs.hEvent = (HANDLE) (ULONG_PTR) p_handlerInputs3...

Daily Bank Sweep
New GP Client that is reconciling for the first time their operating account. We have entered the last reconciled balance and dates as of 12/31/08. Operating account gets swept every night and redeposited the next day. With each sweep interest is calculated. My question is how to handle the last sweep of the month, which is a sweep in transit. We have tried entering as a decrease adjustment (not posting to GL as it should not effect the GL balance). We have also tried entering as an adjustment to see what the effect is. We don't even come close to the bank ending balance. Pl...

Handling blank data points
I have a chart which is has "" in a formula to clear contents when not applicable to show error. This results in the chart treating the cell as 0 and therefore ugly result in data point. All other post responses to this type of question suggest using NA() and conditional formation to hide the error.. Unfortunately when this is used this screws up my SUM() and AVG() formulas.. Any other suggestions? Thanks Jo Hi Jo, I don't know if this is the best way but what I have done under similar circumstances is use the #N/A for the chart series data column and then I use a hel...

Handle Dialog Box From GP using Continuum API
Dear All I am working with VS2005, C#, Developer tool kit, GP 10. I am trying to use Continuum API to handle the response of Dialog Box because I can't do that using Developer tool kit. So I did create a new application "Microsoft Dynamics GP Add-in" C# I have this error: "Specified cast is not valid" I build my solution and I add the DLL in this path: C:\Program Files\Microsoft Dynamics\GP\AddIns Please I need your advise please. And I wrote the below Code using System; using System.Collections.Generic; using System.Text; using Microsoft.Dexterity.Bridge; usi...

HANDLES
Hi All, how can I get info concerning the number of handles opened ? Thanks in advance Paolo You can have some information about the handles used by an application using 'Application Verifier' http://msdn.microsoft.com/en-us/library/aa446904.aspx -- Luca Calligaris (MVP-Windows Embedded) lucaDOTcalligarisATeurotechDOTcom www.eurotech.com "Paolo Cremonese" <cremonese@teledata-i.com> ha scritto nel messaggio news:O6rJxu5FLHA.2276@TK2MSFTNGP06.phx.gbl... > Hi All, > > how can I get info concerning the number of handles opened ?...

Slow in handling mailboxes
Outlook 2000 on Windows 2000, at latest levels. I have nine email services defined. Only four of these are set to be checked by Send/Receive; the others are occasional use and are unchecked in the Options/Mail Service list. Outlook is set to check my mailboxes only when I specifically request, not automatically. This a part of my junk-mail prevention strategy. I use MailWasherPro to interact directly with my ISP mailboxes, before the mail ever gets to Outlook Works great! As I added these occasional services, even through Outlook is set not to check them, I found that Send/Receive slowed do...

Unable to get the window handle ... Windowless ActiveX controls are not supported
Hello, This exception : System.InvalidOperationException was caught Message="Unable to get the window handle for the 'AxMOSServer' control. Windowless ActiveX controls are not supported." Source="System.Windows.Forms" StackTrace: at System.Windows.Forms.AxHost.EnsureWindowPresent() at System.Windows.Forms.AxHost.InPlaceActivate() at System.Windows.Forms.AxHost.TransitionUpTo(Int32 state) at System.Windows.Forms.AxHost.CreateHandle() at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible) ...

Another date handling question variant
Hi, I want to specify time+date and adjust them by timezone, but cannot see how to do this without laborious formulae. I've seen the other time/data tips on this site (v.good thanks), but they don't seem to cover this scenario. what I want to do: Column1: Time, format: dd-mmm-yy [hh]:mm eg: 26-feb-04 03:46 Column2: TZ offset, format: num (0 DP) eg: 5 Column3: Adjusted Time, format: dd-mmm-yy [hh]:mm formula: Col1 + (Col2/24) eg: 26-feb-04 08:46 ie. I want the basic number of TZ offset to increment the original time but that number of hours. Of course, it doesn't work, the e...

55 lb. Wide Handle Kettlebell
Price:$65.00 Image: http://specialdealfinder.info/image.php?id=B000QW57OG Best deal: http://specialdealfinder.info/index.php?id=B000QW57OG I bought a 55lb kettlebell as a Christmas gift (from Pacillo's Fitness) for my husband who does a lot of different kinds of strength and endurance training. This product is fantastic. He's used it at least every other day since he's received it. It's just light enough for a beginner to get their feet wet with a few reps, and heavy enough to be challenging for the more advanced user. Also, the handle is wide enough for both his beefy h...

Limit to GDI Handles and User Handles
Hi, My software is a highly interactive application that uses lots of windows with sub windows (a few hundred windows is not an exception). Not all windows are visible at the same time, but at certain moments the user must be able to quickly switch to another window so I keep the relevant windows invisible and make them visible when needed. Due to the structure of the software, it is not possible to decrease the number of windows. Nevertheless I have succeeded to decrease the used pens, brushes, .... Cleaning up the used menu handles and icon handles is planned for the medium- to long-term. ...

How Would You Handle This?
Hello, all. We have a prototype system that's connected via ethernet to a linux machine that's collecting data on an instrument and sending it to the Windows machine. In addition the Windows machine can send commands via the ethernet link to the linux machine. We're using VS6 and MFC on XP. This is a quick and dirty application I've got running as a tabbed dialog application, i.e. a CPropertySheet-derived class with multiple CPropertyPage. The different pages are intended to handle different tasks, e.g. establishing the connection between the machines, changing and retrievi...

How to get the process handle by a window handle which run in the process.
Thanks! GetWindowThreadProcessId Bill Gates wrote: > Thanks! Thanks:> ...

HOWTO Subclass a .NET UserControl's window handle to an MDI EXE
HOWTO Subclass an AtvieX control's window handle to an MDI EXE Please help, I want to make .NET UserControl launch a VC++/MFC/MDI EXE that in turn is fed the UserControl's windows handle via the STDIN, that EXE then uses to subclass, so that its GUI appears in the UserControl's space. Getting the .NET UserControl's windows handle was easy, it was simply "this.Handle". Using the various .NET means to launch an EXE was easy, and to make the .NET UserControl let the EXE inherit the STDIN handles was easy. And I got the EXE to "see/read" the HANDLE on th...

Handle Error.
A procedure often Number Overflow. So I put this handler in procedure. Private Sub Hint() On Error GoTo Overflow ....... ' Some codes. Exit Sub Overflow: If (Err = 6) Then ......' Handling error. End If End Sub but if other Error happen. it could be a unhandle error. because I not handing all err number. Hi I suggest a Select Case structure on err number, like this: Sub test() Dim i As Long On Error GoTo ErrHandler i = 23232323232323# ^ 2 MsgBox "i=" & i i = 23 / 0 MsgBox "i=" & i Exit Sub ErrHandler: Select Case Err.Number Case 6 ...

Add image from resources to richtextbox
I added an image to the project resources (myImage.bmp) How can i add this image to my richTextBox. Any assistance will be greatly received, Jasmine ...

OWA 2003 Attachment Handling
I am looking for the registry setting to allow certain attachments to be open from within Outlook Web Acccess 2003 and not have to save them to disk. I am running a FE/BE scenario (both Exchnage 2003) and have come across only articles for blocking certain attachments: http://support.microsoft.com/default.aspx?scid=kb;en- us;555001&Product=exch2003 Please let me know if anyone has come across a way to open PDF's from within a browser window with 128bit SSL turned on. By simply clicking the attachment and saying open in a new web browser does not function correctly. I need a w...

Flat Fee Handling Charge per item?
Firstly we are using GP 9.0 with extended pricing. We have a customer that wants us to bill them with a Flat Fee Handling Charge built into the item pricing. We therefore are looking for a way to add $5 to the price of every item we sell them to cover our drop ship handling fees. They cannot accept it as an additional line item. They are much bigger than us and we have to adapt our system to suit theirs. We tried to use the value off option in extended pricing but it would not accept a negative amount (thus adding the $5). We offer 10k+ items and do not want to manage another price s...

error handling
Is it possible to assign a specific key (such as INS) for error handling? I have a combobox that pulls data from a list in sheet2. If the Item is not in the list, I would like the user to be able to press the INS button to call the code to add the item. Thank you in advance Dawna use the Application.OnKey method "Dawna" <Dawna@discussions.microsoft.com> wrote in message news:30937625-50D4-4796-AB94-21EEA34F48EA@microsoft.com... > Is it possible to assign a specific key (such as INS) for error handling? > I > have a combobox that pulls data from a ...

Detecting Alt-Backspace in a KeyDown/OnChar event?
I'm using a CRichEditCtrl and for some reason I can't get to capture that key, Alt-Backspace. (the ALT key doesn't cause either one of those two events be fired... any reason why?) Could someone give me a hint as to how I should go about capturing Alt-Backspace? (I don't want to use an accelerator btw) "Kourosh" <kderakhshan@msn.com> schrieb im Newsbeitrag = news:1144714604.408445.172660@g10g2000cwb.googlegroups.com... > I'm using a CRichEditCtrl and for some reason I can't get to capture > that key, Alt-Backspace. (the ALT key doesn't cause...

How to handle renewal product/ Opportunities
We are having a discussion here about how to handle new and renewal products/ opportunities. One group wants to mark opportunities as either new or renewal and the other wish to mark the product as new or renewal. The marking of opportunities as new or renewal, adding an attribute to the entity, allows us to filter the opportunities reports by this attributes. However other group feels that the attribute on the product better reflect the true product allowing us to mix opportunities with new and renewal products. Is there a best practice for handing this issue? *Side note: Our pr...

databse handling
1.what is the best and the easiest method of handling databse operations(with and without file support 2.How to navigate from one form to another at the click of a button? 1.I guess you can go for Databases without File Support and delcare your source name 2. For moving from one form to another using a button you ned to do the followin 2.1 insert another dialog box and give it a name say" pooja" when asked for a new class name which POPs up Add #include "pooja.h" in all the other .cpp files 2.2 Select a button from the tools controls... 2.3 Add button into the first ...