?
Solved

Rich Text Box flickers whenever I do *anything*!

Posted on 2003-03-24
13
Medium Priority
?
455 Views
Last Modified: 2013-12-25
I am trying to do processing of the text in a rich text box.  When I do, it flickers..  I tried
copying the entire rich text to a duplicate one, showing the new box, hiding the old and doing the processing in the background, then restoring the new one.  That doesn't work.  Even if the task is simple like:

    (save old selStart and selLength)

    rtb.SelStart = 0
    rtb.SelLength = Len(rtb.Text)
   
    '//This next line causes flickering!!!
    rtb.SelBold = True
    (restore selStart and selLength)

The screen still flickers.  Is there any way to avoid this?  thanks!!
0
Comment
Question by:rkitti4
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 3
  • 2
  • +1
13 Comments
 

Author Comment

by:rkitti4
ID: 8197371
Is anyone out there??  I'll up the points
0
 
LVL 11

Expert Comment

by:supunr
ID: 8198913
how about...

rtb.visible = false
  rtb.SelStart = 0
   rtb.SelLength = Len(rtb.Text)
   
   '//This next line causes flickering!!!
   rtb.SelBold = True
   (restore selStart and selLength)
rtb.visible = true

0
 
LVL 11

Expert Comment

by:supunr
ID: 8198965
make sure you have the latest version of Richtextbox control available.  The version in my is 6.0.88.4 (SP4), which is the "C:\WinNT\System32\Richtx32.OCX"

I tried your code without any modifications, and it does not flicker.  I am not sure whether that is because I got a faster computer (2.2GHz + 128MB Video).  but try using the lastest richtext control.  (download and update Visual Studio SP5).

Good Luck!
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 9

Expert Comment

by:GivenRandy
ID: 8199693
To add a string to a RichTextBox with very little flicker, use:

---
With RichTextBox1
    .SelStart = Len(.Text)
    .SelText = "SomeNewString"
End With
---

The following shows a typical use of this approach:

---
Private Sub Command1_Click()
    AddText RichTextBox1, "Some new text" & vbCrLf
End Sub

Private Sub AddText(RTB As RichTextBox, NewText As String)
    With RTB
        .SelStart = Len(.Text)
        .SelText = NewText
    End With
End Sub
---
0
 

Author Comment

by:rkitti4
ID: 8202972
Hello again - I checked the version of the rtb control, and it is C:\WinNT\System32\Richtx32.OCX. I tried changing the visible property, and the screen still flickers...  
Then tried using the with block, but did not see any improvement.

The code is in the SelChange event, so I set a flag to bypass the event when changing .SelStart..  Could this cause problems since SelChange is called again and again?  I could not find another way to disable SelChange other than setting the flag.

I have a P3, 733MHz (not sure how much video ram (?) ), and  do not see flickering in other applications.  Maybe there is a way to stop repainting while changing rtb text??  This way the user will not see the cursor move around.  Or is there a way to take a snapshot of what's shown in the rtb and put it in a picture box while formatting?
thanks for your help!! :)
0
 
LVL 9

Expert Comment

by:GivenRandy
ID: 8203103
But where do you do the SelText:

rtb.SelText = "SomeNewString"

If you are adding it a bit at a time, you very well may see flickering. It may be better to add it to a temporary string (say, S) and then do:

S = "First sentence." ' first part of S
S = S & " Second sentence." ' add something to S
S = S & " Third and final sentence." ' add more to S

rtb.SelStart = 0
rtb.SelLength = Len(S)
rtb.SelBold = True
rtb.SelText = S
0
 

Author Comment

by:rkitti4
ID: 8203332
SelText is done multiple times in SelChange event procedure.

What I'm trying to do is write an editor (like the VB editor)..  So every time there is a change in cursor position, the code checks to see if the user moved to a new line.  If they did, the old line is checked for keywords - All keywords are replaced with the word in a keywords collection (for proper case) and turned blue.  If the user edited the current line, all formatting is removed (words are turned black).

I guess what I'm wondering is if there is some way to do the processing so that the user does not see any flickering.

Here is the code I have so far in SelChange.  I wrote a Get_Line_From_Char procedure instead of using the built in one because for some reason it doesn't work when the line length gets to be around 100 characters or so (?)  I don't know why.

Private Sub rtb_SelChange()

    '//bypass event procedure while processing or if user is selecting something
    If blnBYPASS Or rtb.SelLength <> 0 Then Exit Sub

    Dim lngNewLine As Long
    Dim lngNewTotal As Long
    Dim lngStart As Long
    Dim lngEnd As Long
    Dim strNewLine As String
    Dim tmpStart As Long
    Dim tmpLen As Long
   
    blnBYPASS = True

    tmpStart = rtb.SelStart
    tmpLen = rtb.SelLength

    lngNewLine = Get_Line_From_Char(rtb.SelStart)

    '//Get start of line
    rtb.UpTo vbCrLf
    lngEnd = rtb.SelStart

    '//Get end of line
    rtb.UpTo vbCrLf, False
    lngStart = rtb.SelStart

    '//Get line
    rtb.SelLength = lngEnd - lngStart
    strNewLine = rtb.SelText
   
    '//Get total # of lines
    lngNewTotal = Total_Lines

    '//If line changed, check old line for keywords
    If lngNewLine <> glngOldLine And lngNewTotal >= glngOldTotal Then
        Check_Block_For_Keywords Start_Of_Line(glngOldLine), End_Of_Line(glngOldLine), strKeywordCOLOR, strTextCOLOR
    '//Check if line string matches old string (binary compare)
    ElseIf StrComp(gstrOldLine, strNewLine, vbBinaryCompare) <> 0 Then
        Format_Block lngStart, lngEnd, strTextCOLOR
    End If

    '//update
    glngOldLine = lngNewLine
    glngOldTotal = lngNewTotal
    gstrOldLine = strNewLine

'    restore_rtb
    rtb.SelStart = tmpStart
    rtb.SelLength = tmpLen
    blnBYPASS = False

End Sub
0
 

Author Comment

by:rkitti4
ID: 8203382
Oh, and here is how SelText is done..

Private Sub Check_Block_For_Keywords(lngStart As Long, lngEnd As Long, KEYColor As String, TEXTColor As String)
    Dim strWord As String
    Dim objWord As Object
   
    '//Put cursor at beginning of BLOCK
    rtb.SelStart = lngStart
   
    '//Adjust cursor to position of next non-delimiting character
    rtb.UpTo strDelim, , True

    Do Until rtb.SelStart >= lngEnd
        rtb.Span strDelim, , True
       
        strWord = rtb.SelText
       
        '//Check to see if this is keyword
        For Each objWord In KeyWords
            If objWord.strWord = strWord Then
                rtb.SelColor = KEYColor
                rtb.SelText = objWord.strWord
                Exit For
            Else
                rtb.SelColor = TEXTColor
            End If
        Next

        '//Adjust cursor to position of next non-delimiting character
        rtb.SelStart = rtb.SelStart + rtb.SelLength
        rtb.UpTo strDelim, , True
    Loop

End Sub


0
 
LVL 9

Expert Comment

by:GivenRandy
ID: 8203769
You might want to look into this control:

http://www.vbaccelerator.com/codelib/richedit/richedit.htm
0
 
LVL 1

Accepted Solution

by:
Gahawn earned 2000 total points
ID: 8204847
You should be able to do this fairly easily but it requires use of the Windows API. It's not very difficult though. Here's how...

First, declare the API function in your project. I usually declare API functions as public in a .bas module. The declaration you need is:

Public Declare Function LockWindowUpdate lib "user32" (ByVal hWndLock as Long) as Long

Then, before doing your updates, call the LockWindowUpdate function using the hwnd property of the control like this:

returnValue = LockWindowUpdate(rtb.hwnd)

'Do stuff here
'Then unlock the window again like this:

returnValue = LockWindowUpdate(&0)

See if that does the trick!
0
 

Author Comment

by:rkitti4
ID: 8206386
GivenRandy - Thanks for the link-  I downloaded vbalEdit.ocx, but am getting more problems!  run-time error '429' - ActiveX component cannot create object.  I'll look into this a little more and use it if there are no other work arounds.  

Ideally though, it would be nice to use built-in VB controls rather than 3rd party if there was only a way to turn off repainting while doing the formatting or - change the highlight and cursor color to the match backcolor of the rtb.   This would be the simplest solution, and plus I would be able to use code I already have written.  If anyone knows how to do this, please let me know!

(and in case anyone else is looking, here's a link to another editor control..
http://www.visualbasicforum.com/t53502.html)

0
 

Author Comment

by:rkitti4
ID: 8206429
Hi Gahawn  - thanks for your response  :)
that is exactly the path I would like to go down!
I tried using the LockWindowUpdate (per your suggestion), but it seems to not suppress built in refresh of rtb control SelStart and SelLength.  I also did check to make sure the function did not return 0 (it returned 1).

then I tried using WM_SETREDRAW ...

'//declare in public *.bas module...
Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Public Const WM_SETREDRAW = &HB

'//then in form module (or wherever) ...
Private Sub rtb_SelChange()
    SendMessage rtb.hwnd, WM_SETREDRAW, 0, 0
    '//Do some stuff
    SendMessage rtb.hwnd, WM_SETREDRAW, 1, 0
    rtb.Refresh
End Sub

there is less flicker because refresh is done only once per SelChange, but it is still very noticeable.  if the rtb.refresh command could be removed from SelChange and put in the Change event without the cursor leaving traces, this would be acceptable, but I do not know if that could be done.  
thanks again for your responses!  It is very helpful!  I will try to play around with this a little more and let you know how it goes.

0
 

Author Comment

by:rkitti4
ID: 8211881
I rewrote the code to do refresh only when necessary to minimize flickering.  It looks like something that cannot be avoided.

The second problem was hiding the cursor while formatting, and that was taken care of using Gahawn's LockWindowUpdate method (rahter than WM_SETREDRAW).  Thanks again!
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction In a recent article (http://www.experts-exchange.com/A_7811-A-Better-Concatenate-Function.html) for the Excel community, I showed an improved version of the Excel Concatenate() function.  While writing that article I realized that no o…
Background What I'm presenting in this article is the result of 2 conditions in my work area: We have a SQL Server production environment but no development or test environment; andWe have an MS Access front end using tables in SQL Server but we a…
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
Suggested Courses
Course of the Month13 days, 22 hours left to enroll

801 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question