Flicker Control

Category: Controls - RichEdit

Date: 02-16-2022

Return to Index


 
'When performing several actions, or actions on text that is not currently
'in the visible window, or when changing selections repeatedly - a RichEdit
'control may flicker.  Disabling a control with WM_SetReDraw before taking
'actions, then turning enabling it after the actions have been taken can
'significantly improve performance.
 
'Compiler Comments:
'This code is written to compile with PBWin10. To compile with PBWin9,
'add this line:
#Include "CommCtrl.inc"
 
'Primary Code:
'Credit: Borje Hagsten, Chris Holbrook
'Precede action code with these statements:
Events& = SendMessage(hEdit, %EM_GETEVENTMASK, 0, 0   'Original event mask, so can restore later
SendMessage hRichEdit, %EM_SETEVENTMASK, 0, 0         'Disable the event mask, for better speed
SendMessage hRichEdit, %WM_SETREDRAW, 0, 0            'Turn off redraw for faster and smoother action
SendMessage hRichEdit, %EM_HIDESELECTION,1,0
 
'After the code is complete, use these statements:
SendMessage hRichEdit, %WM_SETREDRAW, 1, 0                             'Turn on redraw again and refresh
SendMessage hRichEdit, %EM_HIDESELECTION,0,0                           'Turn on selection display
If xEvents Then SendMessage(hRichEdit, %EM_SETEVENTMASK, 0, Events&)   'Reset the event mask
 
'Compilable Example:  (Jose Includes)
'This shows the impact of the flicker control statements. Press the first
'button and see the flicker. Press the second button and see the improved
'performance - no flicker and much faster!
'Note: %EM_EXSETSEL is used over %EM_SETSEL in the example below
'       %EM_SetSel supports both edit and richedit controls, but has a 64K
'       text limit. For larger text content in richedit controls, use %EM_EXSETSEL
#Compiler PBWin 10
#Compile EXE
#Dim All
%Unicode=1
#Include "win32api.inc
#Include "RichEdit.inc"
Global hDlg as DWord, hRichEdit1 as DWord, hRichEdit2 as DWord
 
Function PBMain() As Long
   Local buf$
   Dialog New Pixels, 0, "Test Code",300,300,250,200, %WS_OverlappedWindow To hDlg
   LoadLibrary("riched32.dll") : InitCommonControls
   buf$ = "This is sample" + $CrLf + "text for the" + $CrLf + "RichEdit control."
   buf$ = buf$ + $CrLf + buf$ + $CrLf + buf$ + $CrLf + buf$ + $CrLf + buf$ + $CrLf + buf$
   Control Add Button, hDlg, 100,"Flicker", 10,20,80,20
   Control Add Button, hDlg, 150,"Non-Flicker", 130,20,80,20
   Control Add "RichEdit", hDlg, 500, buf$,10,50,100,100, 1345393092   'style& is the integer value of common styles
   Control Add "RichEdit", hDlg, 600, buf$,130,50,100,100, 1345393092  'style& is the integer value of common styles
   Control Handle hDlg, 500 To hRichEdit1
   Control Handle hDlg, 600 To hRichEdit2
   Control Add Label, hDlg, 300,"Flicker", 20,160,80,20
   Control Add Label, hDlg, 350,"Non-Flicker", 130,160,80,20
   Dialog Show Modal hDlg Call DlgProc
End Function
 
CallBack Function DlgProc() As Long
   Local i As Long, iResult&, xEvents&, P as CharRange
   Dim iStart As Long, iEnd As Long, Result As String
   If CB.Msg = %WM_Command AND CB.Ctl = 100 AND CB.Ctlmsg = %BN_Clicked Then
      iStart = GetTickCount
      For i = 1 To 5000
         P.cpmin = Rnd(0,240)
         P.cpmax = Rnd(P.cpmin,240)
         iResult& = SendMessage(hRichEdit1, %EM_EXSetSel, 0, VarPTR(P))
      Next i
      P.cpmin = 1 : P.cpmax = 2
      iResult& = SendMessage(hRichEdit1, %EM_EXSetSel, 0, VarPTR(P))
      iEnd = GetTickCount
      Control Set Text hDlg, 300, Format$((iEnd - iStart)/1000,3) & " seconds"
   End If
   If CB.Msg = %WM_Command AND CB.Ctl = 150 AND CB.Ctlmsg = %BN_Clicked Then
      iStart = GetTickCount
      xEvents& = SendMessage(hRichEdit2, %EM_GETEVENTMASK, 0, 0)   'Original event mask, so can restore later
      SendMessage(hRichEdit2, %EM_SETEVENTMASK, 0, 0)               'Disable the event mask, for better speed
      SendMessage(hRichEdit2, %WM_SETREDRAW, 0, 0)    'Turn off redraw for faster and smoother action
      SendMessage hRichEdit2, %EM_HIDESELECTION,1,0
      For i = 1 To 5000
         P.cpmin = Rnd(0,240)
         P.cpmax = Rnd(P.cpmin,240)
         iResult& = SendMessage(hRichEdit2, %EM_EXSetSel, 0, VarPTR(P))
      Next i
      SendMessage hRichEdit2, %WM_SETREDRAW, 1, 0    'Turn on redraw again and refresh
      SendMessage hRichEdit2, %EM_HIDESELECTION,0,0  'Turn on selection display
      If xEvents Then Call SendMessage(hRichEdit2, %EM_SETEVENTMASK, 0, xEvents&)   'Reset the event mask
      P.cpmin = 1 : P.cpmax = 2
      iResult& = SendMessage(hRichEdit2, %EM_EXSetSel, 0, VarPTR(P))
      iEnd = GetTickCount
      Control Set Text hDlg, 350, Format$((iEnd - iStart)/1000,3) & " seconds"
   End If
End Function
 
'gbs_00226
'Date: 03-10-2012


created by gbSnippets
http://www.garybeene.com/sw/gbsnippets.htm