2

I have a timer that I display to the user in a RichEdit20A that is inside a CDialog. The problem is every time I update the RichEdit20A, the screen flickers.

Since I have several RichEdit20A in my Dialog, I have a method below that I use to update them. I have tried ModifyStyle(0, WS_CLIPCHILDREN, 0); OnInitDialog but it erases all my RichEdit20A texts. I also tried RedrawWindow(Null,Null, RDW_Erase)--Dialog still flickers and RedrawWindow(Null,Null, RDW_Invalidate)--All the text gets written on top of the old one making it unreadable.

//UpdateData(TRUE);

if(!pRECtrl)
    return;

CHARFORMAT cf = {0};

cf.cbSize = sizeof(cf);
cf.dwMask = (bold ? CFM_BOLD : 0) | (italic ? CFM_ITALIC : 0) | CFM_COLOR;
cf.dwEffects = (bold ? CFE_BOLD : 0) | (italic ? CFE_ITALIC : 0) |~CFE_AUTOCOLOR;
cf.crTextColor = color;

pRECtrl->SetSel(0, -1); // Set the cursor to the end of the text area and deselect everything.
pRECtrl->Clear();
pRECtrl->ReplaceSel(text);

// Apply formating to the just inserted text.
pRECtrl->SetSel(0, pRECtrl->GetTextLength());
pRECtrl->SetSelectionCharFormat(cf);


//UpdateData(FALSE);

Invalidate();

I know that Invalidate is what is causing the flickering and that double buffering(I've never done it before) is what is used to fix this kind of issue for CViews...and I don't know what to do to stop the flickering for a CDialog, which is the window I am using for my program. Any help would be appreciated. Thank you!

Barmak Shemirani
  • 30,904
  • 6
  • 40
  • 77
user3768804
  • 139
  • 1
  • 1
  • 15
  • 1
    Use the [`SetEventMask()`](https://docs.microsoft.com/en-us/cpp/mfc/reference/cricheditctrl-class?view=vs-2019#seteventmask) method to disable notifications (especially `EN_SELCHANGE`) from the RichEdit while you are manipulating it, then restore the previous mask when finished. See [Notifications from a Rich Edit Control](https://docs.microsoft.com/en-us/cpp/mfc/notifications-from-a-rich-edit-control?view=vs-2019). Also, instead of using `SetSel(0, -1)`+`Clear()`+`ReplaceSel()` as 3 separate operations, consider using the `WM_SETTEXT` or `EM_SETTEXTEX` message as 1 operation instead. – Remy Lebeau Oct 07 '19 at 22:58
  • 1
    Use [`m_richedit.SetRedraw(FALSE)`](https://learn.microsoft.com/en-us/cpp/mfc/reference/cwnd-class?view=vs-2019#setredraw) to prevent changes to rich_edit from being shown, then put `m_richedit.SetRedraw(TRUE)` when control is ready. This should stop the rich_edit flicker. I am not sure what you mean by dialog flicker, or screen flicker. – Barmak Shemirani Oct 08 '19 at 04:14
  • Not sure how to use SetEventMask() in this context but I tried SetRedraw and it works fine. but the RichEdit only get's drawn once on initDialog but it does not get Redrawn when I call my function again. I put SetRedraw(FALSE) AND SetRedraw(TRUE) inside my function. By Dialog or Screen flicker I mean that everything on my dialog gets erased and redrawn every time I call my function which causes a noticeable flicker. – user3768804 Oct 08 '19 at 13:16
  • After `m_richedit.SetRedraw(TRUE)` you want to put `m_richedit.Invalidate()` or `m_richedit.SetSel(0,0)` - Your dialog has `WS_CLIPCHILDREN` flag? Don't remove that flag with `ModifyStyle`. You might not need to call `Invalidate` or `RedrawWindow` for the dialog – Barmak Shemirani Oct 08 '19 at 14:04
  • yes my dialog has ModifyStyle(0, WS_CLIPCHILDREN, 0); and unfortunately I've tried all your suggestions in all combinations possible and I couldn't make it work. – user3768804 Oct 09 '19 at 19:50
  • Why do you need to call `Invalidate()` (for the whole dialog)? The commands before it should update the rich-edit boxes. You may even call `RedrawWindow()', but for each rich-edit control, not the dialog, if you want an immediate update. But i think this is not needed either, controls have their own invalidate/paint functionality. – Constantine Georgiou Oct 10 '19 at 15:20

0 Answers0