Solved

CRichEditCtrl & Fast Parsing

Posted on 1999-01-12
7
509 Views
Last Modified: 2013-11-20
I have created an ActiveX control that's an MFC Doc/View Rich Edit Control. I need to add color to the text as it is displayed to highlight syntax, keywords, etc. I can fairly quickly handle files up to 32K or so but beyond that it is as slow as molasses. So my question is...
How can I speed this up prior to displaying it?


I've tried a worker thread without much/any speed improvements.
I've tried the EDITSTREAM callback figuring that I could modify the StreamIn text prior to display. Unfortunately the callback is never executed (I'm missing something there)

I really can't use a 3rd party one since I need to add some specific bells & whistles not found in any I've reviewed.

Thanks in advance,
Lisa
0
Comment
Question by:lisab
  • 3
  • 3
7 Comments
 
LVL 11

Expert Comment

by:mikeblas
ID: 1327546
When you ran your application under the profiler, what exactly was the slow part?

Your own parsing? Only you can help yourself there.

You mentioned throwing a thread at the problem. Why did you expect that to help? Is your code I/O-intensive?

If you don't pass the right parameters to EDITSTREAM, the stream functions will return errors and your streaming functions won't be called. If you show your code, maybe I can spot your error. This is by far the fastest way to stream in (or out) the content of a rich edit control.

But if you're working line-by-line, you probably want to use SetSel() to append your new text to the end of the control. If you're taking this approach, then you'll also want to make sure you have turned off redraw for the duration of your replacement and formatting.

Unfortunately, I've had to provide a shotgun answer because your question is too vague to give a specific response.

B ekiM


0
 
LVL 1

Expert Comment

by:The_Brain
ID: 1327547
?sdrawkcab eman ruoy si yhW
niarB

(^:

0
 

Author Comment

by:lisab
ID: 1327548
I have not run it under Profiler, I will, however I think the problem lies in SetSelectionCharFormat. If I comment this line out my parsing runs significantly faster. (Except no text color change which is critical)

::ZeroMemory(&cf, sizeof(cf));            
cf.cbSize = sizeof(cf);
cf.dwMask = CFM_COLOR;            
cf.crTextColor = RGB(245, 0, 0);
dwFlags = NULL;
            
_tcscpy (pFT.lpstrText, "//");
pFT.chrg.cpMin = *cpMin;
pFT.chrg.cpMax = *cpMax;
dwFlags = NULL;
nIndex = -1;
do  //search for "//" comments
{      
      nResult = theCtrl.FindText(dwFlags, &pFT) ;
      if (nResult != -1)
      {//advance to the end of the line
            nIndex = theCtrl.LineIndex (theCtrl.LineFromChar (nResult) + 1) - 1;
            theCtrl.SetSel(nResult, nIndex);
            theCtrl.SetSelectionCharFormat(cf);
            pFT.chrg.cpMin = nIndex;
      }
}while (nResult != -1);

Yes, it is my own parsing. For comments I'm using the approach above, for keywords I build a string list of keywords and search for each word in the file. If you have an alternative suggestion that would be great.  Would searching this text as CString instead of Rich Edit work any faster?

Parsing a giant CString was my next approach. I could not get the EditStreamCallback to work at all. I could find no useful documentation on this function so I copied code from ?VIEWRICH.CPP? My callback is never executed so apparantly this is incorrect. It looks as follows:

EDITSTREAM es = {0, 0, EditStreamCallBack};
_afxRichEditCookie cookie(ar);
es.dwCookie = (DWORD)&cookie;
GetRichEditCtrl().StreamIn(nFormat, es);


I tried the thread to enable me to parse part of a large file, allow the user to edit his code and continue parsing in a thread. I know this isn't a great solution, but I could not improve the parsing and couldn't get the editstream callback to work. Desparate, I know.

Thanks for your help.
Lisa
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Author Comment

by:lisab
ID: 1327549
Update:

I modified all my parsing code to use ::SendMessage for updating the rich edit ctrl. This is significantly faster, but still not the light speed I was hoping for. Any ideas?

Lisa

::ZeroMemory(&cf, sizeof(CHARFORMAT));            
      cf.cbSize = sizeof(cf);
      cf.dwMask = CFM_COLOR;            
      cf.crTextColor = RGB(245, 0, 0);
      dwFlags = FR_DOWN;
            
      _tcscpy (pFT.lpstrText, "//");
      pFT.chrg.cpMin = *cpMin;
      pFT.chrg.cpMax = *cpMax;
      dwFlags = NULL;
      nIndex = -1;
      CHARRANGE cr;
      do  
      {      
            //nResult = theCtrl.FindText(dwFlags, &pFT) ;
            nResult = ::SendMessage(m_hWnd, EM_FINDTEXTEX, dwFlags, (LPARAM)&pFT);
            if (nResult != -1)
            {
                  cr.cpMax =  (long)::SendMessage(m_hWnd, EM_EXLINEFROMCHAR, 0, nResult);
                  cr.cpMax = ((long)::SendMessage(m_hWnd, EM_LINEINDEX, cr.cpMax + 1, 0)) - 1;
                  cr.cpMin = nResult;
                  ::SendMessage(m_hWnd, EM_EXSETSEL, 0, (LPARAM)&cr);
                  ::SendMessage(m_hWnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
                  pFT.chrg.cpMin = cr.cpMax;
            }
      }while (nResult != -1);
0
 
LVL 11

Expert Comment

by:mikeblas
ID: 1327550
> Would searching this text as CString
 > instead of Rich Edit work any faster?

Yes.  Using the RichEdit control for syntax colouring is not a great idea; it's just not designed for that kind of high-bandwidth formatting. Visual C++ (and the other Visual Studio editors) do their syntax colouring with a window that's painted from scratch.

If you don't have time to develop such a window, you can make a run at it with Rich Edit. In the loading phase (which is what I guess you're talking about here, because you've written code to parse the whole file) you'll want to load your file into memory. There, you should parse it and fluff it into an actual RTF stream.  Then, you can use stream in to load that buffer into the rich edit control.

As the user changes the content of the control, you can reparse the line(s) surrounding their change and use the selection formatting.

Using that approach, I think you'll realize the best performance.

That you've noticed a speedup by switching to ::SendMessage() calls makes no sense to me. For the calls you show in the code you've posted here, MFC supplies inline functions that do, exactly, a ::SendMessage().  Are your observations based on a release build or a debug build?

You really need to use the profiler to identify the hot-spots in your code.

B ekiM


0
 
LVL 11

Accepted Solution

by:
mikeblas earned 100 total points
ID: 1327551
I guess I should've submitted that as an answer, and not a comment.

B ekiM
0
 

Author Comment

by:lisab
ID: 1327552
Thanks for the help, Mike. It is much appreciated.

Lisa
0

Featured Post

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

This is to be the first in a series of articles demonstrating the development of a complete windows based application using the MFC classes.  I’ll try to keep each article focused on one (or a couple) of the tasks that one may meet.   Introductio…
Introduction: Hints for the grid button.  Nested classes, templated collections.  Squash that darned bug! Continuing from the sixth article about sudoku.   Open the project in visual studio. First we will finish with the SUD_SETVALUE messa…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…

746 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

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now