Recent

Author Topic: [SOLVED] ListView flicker  (Read 5514 times)

Zaxxon

  • New Member
  • *
  • Posts: 30
[SOLVED] ListView flicker
« on: June 07, 2016, 09:14:47 am »
when you resize a listview there is a lot of flickering

I've tried to overrride the WM_ERASEBKGND message by

Code: Pascal  [Select][+][-]
  1. procedure TForm1.ListViewWndProc(var Msg:TMessage);
  2. begin
  3.   if Msg.msg=WM_ERASEBKGND then begin
  4.     Msg.Result:=1;
  5.   end
  6.   else begin
  7.     Self.OldListViewWndProc(Msg);  
  8.   end;
  9. end;
  10.  

and that removed the flicker, but that caused other issues. Is there a better way of getting rid of the flicker?
Or is the flicker a bug?

I'm using lazarus 1.6 / FPC 3.0.0 in win 7 64 bit.
« Last Edit: June 07, 2016, 10:31:17 am by Zaxxon »

Michl

  • Full Member
  • ***
  • Posts: 226
Re: ListView flicker
« Reply #1 on: June 07, 2016, 09:38:51 am »
Or is the flicker a bug?
Yes, it was a bug and should be fixed in Lazarus Trunk (http://bugs.freepascal.org/view.php?id=30076).

You can try the patch in the bug report, if it works for you too?!
« Last Edit: June 07, 2016, 09:40:53 am by Michl »
Code: [Select]
type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;

balazsszekely

  • Guest
Re: ListView flicker
« Reply #2 on: June 07, 2016, 10:16:08 am »
@Michl
I work with lazarus trunk, but the project still flickers a lot.

@Zaxxon
I see you're under windows. Please test the attached project:
Code: Pascal  [Select][+][-]
  1. uses windows;
  2. //...
  3. var
  4.   PrevWndProc: WNDPROC;
  5.  
  6. function WndCallback(AHWND: HWND; uMsg: UINT; wParam: WParam; lParam: LParam): LRESULT; stdcall;
  7. begin
  8.   case uMsg of
  9.     WM_ENTERSIZEMOVE: begin
  10.       LockWindowUpdate(Form1.ListView1.Handle);
  11.       Form1.ListView1.Align := alNone;
  12.       Form1.ListView1.Width := 10000;
  13.       Form1.ListView1.Height := 10000;
  14.       Form1.DisableAlign;
  15.       LockWindowUpdate(0);
  16.     end;
  17.     WM_EXITSIZEMOVE: begin
  18.       LockWindowUpdate(Form1.ListView1.Handle);
  19.       Form1.ListView1.Align := alClient;
  20.       Form1.EnableAlign;
  21.       LockWindowUpdate(0);
  22.     end;
  23.   end;
  24.   Result := CallWindowProc(PrevWndProc, Ahwnd, uMsg, WParam, LParam);
  25. end;
  26.  
  27. procedure TForm1.FormCreate(Sender: TObject);
  28. var I:Integer;
  29.     LI:TListItem;
  30.     B:Boolean;
  31. begin
  32.   Self.ListView1.DoubleBuffered:=True;
  33.   Self.ListView1.Font.Size:=11;
  34.   B:=True;
  35.   for I:=0 to 30 do begin
  36.     LI:=Self.ListView1.Items.Add;
  37.     LI.Caption:=IntToStr(Random(1000000));
  38.  
  39.     if B then LI.SubItems.Add('Yes')
  40.     else LI.SubItems.Add('No');
  41.  
  42.     B:=not B;
  43.   end;
  44.   PrevWndProc := Windows.WNDPROC(SetWindowLongPtr(Form1.Handle, GWL_WNDPROC, PtrInt(@WndCallback)));
  45. end;
  46.  
  47. procedure TForm1.ListView1CustomDrawItem(Sender: TCustomListView;
  48.   Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
  49. begin
  50.   if Item.SubItems[0]='Yes' then Self.ListView1.Canvas.Brush.Color:=clBlue
  51.   else Self.ListView1.Canvas.Brush.Color:=clGreen;
  52. end;

Zaxxon

  • New Member
  • *
  • Posts: 30
Re: ListView flicker
« Reply #3 on: June 07, 2016, 10:24:44 am »
GetMem, your version removed the flicker, Thanks!

serbod

  • Full Member
  • ***
  • Posts: 148
Re: [SOLVED] ListView flicker
« Reply #4 on: June 07, 2016, 10:45:49 am »
Another way - use VirtualTreeView ( http://wiki.freepascal.org/VirtualTreeview ). It not flickers, can be used as list and have many useful features.

Zaxxon

  • New Member
  • *
  • Posts: 30
Re: [SOLVED] ListView flicker
« Reply #5 on: June 07, 2016, 11:55:35 am »
A little update.

GetMem : your solution don't work well if you have other aligned components, such as panels.
So I contiuned on my first solution and used yours partially. I simply fill the areas that is not painted in the
WM_ERASEBKGND message. It's not perfect, but it will work for now. 

I attached the new version.

balazsszekely

  • Guest
Re: [SOLVED] ListView flicker
« Reply #6 on: June 07, 2016, 12:04:24 pm »
@Zaxxon
In theory, when you resize or move a form, the controls should not be updated until the operation is completed. I think the easiest solution, which works in all cases(it might not be the most elegant though) is this:
Code: Pascal  [Select][+][-]
  1. function WndCallback(AHWND: HWND; uMsg: UINT; wParam: WParam; lParam: LParam): LRESULT; stdcall;
  2. begin
  3.   case uMsg of
  4.     WM_ENTERSIZEMOVE: Form1.DisableAlign;
  5.     WM_EXITSIZEMOVE: Form1.EnableAlign;
  6.   end;
  7.   Result := CallWindowProc(PrevWndProc, Ahwnd, uMsg, WParam, LParam);
  8. end;

PS: Thanks for your feedback and your example.

 

TinyPortal © 2005-2018