Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

CRichEditCtrl & Fast Parsing

Posted on 1999-01-12
7
Medium Priority
?
544 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
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!

 

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 400 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

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

Question has a verified solution.

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

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…
Ready to get certified? Check out some courses that help you prepare for third-party exams.
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.
Look below the covers at a subform control , and the form that is inside it. Explore properties and see how easy it is to aggregate, get statistics, and synchronize results for your data. A Microsoft Access subform is used to show relevant calcul…
Suggested Courses

927 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