Virtual ListView with checkbox support for vsIcon and vsSmallIcon?












-3















I am using ListView in Delphi. I set the OwnerData property to true so that I will provide data of the item in OnData event.



Moreover, I want to add a checkbox to each item of the list view. But the Checkbox property only supports vsList and vsReport mode, not vsIcon and vsSmallicon. Is there a workaround for it? Or is there any ready-to-use 3rd party VCL that supports such a feature?










share|improve this question

























  • Use virtual tree view

    – David Heffernan
    Nov 19 '18 at 10:43











  • @DavidHeffernan Do you mean virtual tree view at jam-software.com/virtual-treeview ? But this is a tree view, not list view.

    – alancc
    Nov 19 '18 at 12:40











  • Look harder. That control can do what you want.

    – David Heffernan
    Nov 19 '18 at 13:13











  • @alancc despite its name, TVirtualTreeView can also be used in a ListView-like fashion.

    – Remy Lebeau
    Nov 19 '18 at 21:44
















-3















I am using ListView in Delphi. I set the OwnerData property to true so that I will provide data of the item in OnData event.



Moreover, I want to add a checkbox to each item of the list view. But the Checkbox property only supports vsList and vsReport mode, not vsIcon and vsSmallicon. Is there a workaround for it? Or is there any ready-to-use 3rd party VCL that supports such a feature?










share|improve this question

























  • Use virtual tree view

    – David Heffernan
    Nov 19 '18 at 10:43











  • @DavidHeffernan Do you mean virtual tree view at jam-software.com/virtual-treeview ? But this is a tree view, not list view.

    – alancc
    Nov 19 '18 at 12:40











  • Look harder. That control can do what you want.

    – David Heffernan
    Nov 19 '18 at 13:13











  • @alancc despite its name, TVirtualTreeView can also be used in a ListView-like fashion.

    – Remy Lebeau
    Nov 19 '18 at 21:44














-3












-3








-3








I am using ListView in Delphi. I set the OwnerData property to true so that I will provide data of the item in OnData event.



Moreover, I want to add a checkbox to each item of the list view. But the Checkbox property only supports vsList and vsReport mode, not vsIcon and vsSmallicon. Is there a workaround for it? Or is there any ready-to-use 3rd party VCL that supports such a feature?










share|improve this question
















I am using ListView in Delphi. I set the OwnerData property to true so that I will provide data of the item in OnData event.



Moreover, I want to add a checkbox to each item of the list view. But the Checkbox property only supports vsList and vsReport mode, not vsIcon and vsSmallicon. Is there a workaround for it? Or is there any ready-to-use 3rd party VCL that supports such a feature?







listview delphi checkbox vcl






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 19 '18 at 10:43









David Heffernan

517k348181211




517k348181211










asked Nov 19 '18 at 8:42









alanccalancc

4282721




4282721













  • Use virtual tree view

    – David Heffernan
    Nov 19 '18 at 10:43











  • @DavidHeffernan Do you mean virtual tree view at jam-software.com/virtual-treeview ? But this is a tree view, not list view.

    – alancc
    Nov 19 '18 at 12:40











  • Look harder. That control can do what you want.

    – David Heffernan
    Nov 19 '18 at 13:13











  • @alancc despite its name, TVirtualTreeView can also be used in a ListView-like fashion.

    – Remy Lebeau
    Nov 19 '18 at 21:44



















  • Use virtual tree view

    – David Heffernan
    Nov 19 '18 at 10:43











  • @DavidHeffernan Do you mean virtual tree view at jam-software.com/virtual-treeview ? But this is a tree view, not list view.

    – alancc
    Nov 19 '18 at 12:40











  • Look harder. That control can do what you want.

    – David Heffernan
    Nov 19 '18 at 13:13











  • @alancc despite its name, TVirtualTreeView can also be used in a ListView-like fashion.

    – Remy Lebeau
    Nov 19 '18 at 21:44

















Use virtual tree view

– David Heffernan
Nov 19 '18 at 10:43





Use virtual tree view

– David Heffernan
Nov 19 '18 at 10:43













@DavidHeffernan Do you mean virtual tree view at jam-software.com/virtual-treeview ? But this is a tree view, not list view.

– alancc
Nov 19 '18 at 12:40





@DavidHeffernan Do you mean virtual tree view at jam-software.com/virtual-treeview ? But this is a tree view, not list view.

– alancc
Nov 19 '18 at 12:40













Look harder. That control can do what you want.

– David Heffernan
Nov 19 '18 at 13:13





Look harder. That control can do what you want.

– David Heffernan
Nov 19 '18 at 13:13













@alancc despite its name, TVirtualTreeView can also be used in a ListView-like fashion.

– Remy Lebeau
Nov 19 '18 at 21:44





@alancc despite its name, TVirtualTreeView can also be used in a ListView-like fashion.

– Remy Lebeau
Nov 19 '18 at 21:44












1 Answer
1






active

oldest

votes


















4















But the Checkbox property only supports vsList and vsReport mode ...




That's not correct. You are looking at VCL documentation which states




Set Checkboxes to true to make check boxes appear next to the list
items when ViewStyle is vsList or vsReport. ...




This is outdated information. See the documentation for the native control:




Version 6.00 and later Check boxes are visible and functional with all
list view modes except the tile view mode introduced in ComCtl32.dll
version 6. ...




Indeed if you try it on a regular TListView control in one of the icon modes, you'll see there are no problems with check boxes.







However that's not going to help you. In this regard your question is malformed, it has the assumption that Checkboxes work OK in list and report modes with a virtual list view control. That's not the case.



Check boxes are good when you can use the Checked property on a list item. In a virtual list view control there are no items you can check. I'm quoting from the LVM_SETITEMCOUNT message:




If the list-view control was created without the LVS_OWNERDATA style,
sending this message causes the control to allocate its internal data
structures for the specified number of items. ...



...



If the list-view control was created with the LVS_OWNERDATA style (a
virtual list view), sending this message sets the virtual number of
items that the control contains.




All the control knows is that there are that many items, there is no per item storage. VCL reflects the API control: when you request an item and your control has OwnerData set, the OnData event handler is called on a temporary item to reflect the item's properties.



In a virtual list view you manage checks by using state images. Quoting from the documentation:




... You can use state images, such as checked and cleared check boxes,
to indicate application-defined item states. State images are
displayed in icon view, small icon view, list view, and report view.








Below you'll find a basic implementation which holds item state information in a separate array. To run it, create a blank new form, create an OnCreate handler for the form and paste the code.



unit Unit1;

interface

uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ComCtrls, Vcl.ImgList;

type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
FListView: TListView;
FListViewCheckStateArray: array of 0..1;
procedure ListViewData(Sender: TObject; Item: TListItem);
procedure ListViewMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
Bmp: TBitmap;
begin
FListView := TListView.Create(Self);
FListView.Parent := Self;
FListView.Align := alClient;
FListView.OwnerData := True;
FListView.ViewStyle := vsSmallIcon;

FListView.StateImages := TImageList.Create(Self);
Bmp := TBitmap.Create;
Bmp.PixelFormat := pf32bit;
Bmp.SetSize(16, 16);
DrawFrameControl(Bmp.Canvas.Handle, Rect(0, 0, 16, 16), DFC_BUTTON,
DFCS_BUTTONCHECK);
FListView.StateImages.Add(Bmp, nil);
DrawFrameControl(Bmp.Canvas.Handle, Rect(0, 0, 16, 16), DFC_BUTTON,
DFCS_BUTTONCHECK or DFCS_CHECKED);
FListView.StateImages.Add(Bmp, nil);
Bmp.Free;

FListView.Items.Count := 257;
SetLength(FListViewCheckStateArray, FListView.Items.Count);

FListView.OnData := ListViewData;
FListView.OnMouseDown := ListViewMouseDown;
end;

procedure TForm1.ListViewData(Sender: TObject; Item: TListItem);
begin
Item.Caption := Format('This is item %.2d', [Item.Index]);
Item.StateIndex := FListViewCheckStateArray[Item.Index];
end;

procedure TForm1.ListViewMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
Item: TListItem;
begin
if (Button = mbLeft) and
(htOnStateIcon in FListView.GetHitTestInfoAt(X, Y)) then begin
Item := FListView.GetItemAt(X, Y);
Assert(Assigned(Item));
FListViewCheckStateArray[Item.Index] :=
Ord(not Boolean(FListViewCheckStateArray[Item.Index]));
FListView.UpdateItems(Item.Index, Item.Index);
end;
end;

end.


PS: Drawing artifacts should be the subject of a different question.






share|improve this answer

























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53371002%2fvirtual-listview-with-checkbox-support-for-vsicon-and-vssmallicon%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    4















    But the Checkbox property only supports vsList and vsReport mode ...




    That's not correct. You are looking at VCL documentation which states




    Set Checkboxes to true to make check boxes appear next to the list
    items when ViewStyle is vsList or vsReport. ...




    This is outdated information. See the documentation for the native control:




    Version 6.00 and later Check boxes are visible and functional with all
    list view modes except the tile view mode introduced in ComCtl32.dll
    version 6. ...




    Indeed if you try it on a regular TListView control in one of the icon modes, you'll see there are no problems with check boxes.







    However that's not going to help you. In this regard your question is malformed, it has the assumption that Checkboxes work OK in list and report modes with a virtual list view control. That's not the case.



    Check boxes are good when you can use the Checked property on a list item. In a virtual list view control there are no items you can check. I'm quoting from the LVM_SETITEMCOUNT message:




    If the list-view control was created without the LVS_OWNERDATA style,
    sending this message causes the control to allocate its internal data
    structures for the specified number of items. ...



    ...



    If the list-view control was created with the LVS_OWNERDATA style (a
    virtual list view), sending this message sets the virtual number of
    items that the control contains.




    All the control knows is that there are that many items, there is no per item storage. VCL reflects the API control: when you request an item and your control has OwnerData set, the OnData event handler is called on a temporary item to reflect the item's properties.



    In a virtual list view you manage checks by using state images. Quoting from the documentation:




    ... You can use state images, such as checked and cleared check boxes,
    to indicate application-defined item states. State images are
    displayed in icon view, small icon view, list view, and report view.








    Below you'll find a basic implementation which holds item state information in a separate array. To run it, create a blank new form, create an OnCreate handler for the form and paste the code.



    unit Unit1;

    interface

    uses
    Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
    Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ComCtrls, Vcl.ImgList;

    type
    TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    private
    FListView: TListView;
    FListViewCheckStateArray: array of 0..1;
    procedure ListViewData(Sender: TObject; Item: TListItem);
    procedure ListViewMouseDown(Sender: TObject; Button: TMouseButton;
    Shift: TShiftState; X, Y: Integer);
    end;

    var
    Form1: TForm1;

    implementation

    {$R *.dfm}

    procedure TForm1.FormCreate(Sender: TObject);
    var
    Bmp: TBitmap;
    begin
    FListView := TListView.Create(Self);
    FListView.Parent := Self;
    FListView.Align := alClient;
    FListView.OwnerData := True;
    FListView.ViewStyle := vsSmallIcon;

    FListView.StateImages := TImageList.Create(Self);
    Bmp := TBitmap.Create;
    Bmp.PixelFormat := pf32bit;
    Bmp.SetSize(16, 16);
    DrawFrameControl(Bmp.Canvas.Handle, Rect(0, 0, 16, 16), DFC_BUTTON,
    DFCS_BUTTONCHECK);
    FListView.StateImages.Add(Bmp, nil);
    DrawFrameControl(Bmp.Canvas.Handle, Rect(0, 0, 16, 16), DFC_BUTTON,
    DFCS_BUTTONCHECK or DFCS_CHECKED);
    FListView.StateImages.Add(Bmp, nil);
    Bmp.Free;

    FListView.Items.Count := 257;
    SetLength(FListViewCheckStateArray, FListView.Items.Count);

    FListView.OnData := ListViewData;
    FListView.OnMouseDown := ListViewMouseDown;
    end;

    procedure TForm1.ListViewData(Sender: TObject; Item: TListItem);
    begin
    Item.Caption := Format('This is item %.2d', [Item.Index]);
    Item.StateIndex := FListViewCheckStateArray[Item.Index];
    end;

    procedure TForm1.ListViewMouseDown(Sender: TObject; Button: TMouseButton;
    Shift: TShiftState; X, Y: Integer);
    var
    Item: TListItem;
    begin
    if (Button = mbLeft) and
    (htOnStateIcon in FListView.GetHitTestInfoAt(X, Y)) then begin
    Item := FListView.GetItemAt(X, Y);
    Assert(Assigned(Item));
    FListViewCheckStateArray[Item.Index] :=
    Ord(not Boolean(FListViewCheckStateArray[Item.Index]));
    FListView.UpdateItems(Item.Index, Item.Index);
    end;
    end;

    end.


    PS: Drawing artifacts should be the subject of a different question.






    share|improve this answer






























      4















      But the Checkbox property only supports vsList and vsReport mode ...




      That's not correct. You are looking at VCL documentation which states




      Set Checkboxes to true to make check boxes appear next to the list
      items when ViewStyle is vsList or vsReport. ...




      This is outdated information. See the documentation for the native control:




      Version 6.00 and later Check boxes are visible and functional with all
      list view modes except the tile view mode introduced in ComCtl32.dll
      version 6. ...




      Indeed if you try it on a regular TListView control in one of the icon modes, you'll see there are no problems with check boxes.







      However that's not going to help you. In this regard your question is malformed, it has the assumption that Checkboxes work OK in list and report modes with a virtual list view control. That's not the case.



      Check boxes are good when you can use the Checked property on a list item. In a virtual list view control there are no items you can check. I'm quoting from the LVM_SETITEMCOUNT message:




      If the list-view control was created without the LVS_OWNERDATA style,
      sending this message causes the control to allocate its internal data
      structures for the specified number of items. ...



      ...



      If the list-view control was created with the LVS_OWNERDATA style (a
      virtual list view), sending this message sets the virtual number of
      items that the control contains.




      All the control knows is that there are that many items, there is no per item storage. VCL reflects the API control: when you request an item and your control has OwnerData set, the OnData event handler is called on a temporary item to reflect the item's properties.



      In a virtual list view you manage checks by using state images. Quoting from the documentation:




      ... You can use state images, such as checked and cleared check boxes,
      to indicate application-defined item states. State images are
      displayed in icon view, small icon view, list view, and report view.








      Below you'll find a basic implementation which holds item state information in a separate array. To run it, create a blank new form, create an OnCreate handler for the form and paste the code.



      unit Unit1;

      interface

      uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
      Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ComCtrls, Vcl.ImgList;

      type
      TForm1 = class(TForm)
      procedure FormCreate(Sender: TObject);
      private
      FListView: TListView;
      FListViewCheckStateArray: array of 0..1;
      procedure ListViewData(Sender: TObject; Item: TListItem);
      procedure ListViewMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
      end;

      var
      Form1: TForm1;

      implementation

      {$R *.dfm}

      procedure TForm1.FormCreate(Sender: TObject);
      var
      Bmp: TBitmap;
      begin
      FListView := TListView.Create(Self);
      FListView.Parent := Self;
      FListView.Align := alClient;
      FListView.OwnerData := True;
      FListView.ViewStyle := vsSmallIcon;

      FListView.StateImages := TImageList.Create(Self);
      Bmp := TBitmap.Create;
      Bmp.PixelFormat := pf32bit;
      Bmp.SetSize(16, 16);
      DrawFrameControl(Bmp.Canvas.Handle, Rect(0, 0, 16, 16), DFC_BUTTON,
      DFCS_BUTTONCHECK);
      FListView.StateImages.Add(Bmp, nil);
      DrawFrameControl(Bmp.Canvas.Handle, Rect(0, 0, 16, 16), DFC_BUTTON,
      DFCS_BUTTONCHECK or DFCS_CHECKED);
      FListView.StateImages.Add(Bmp, nil);
      Bmp.Free;

      FListView.Items.Count := 257;
      SetLength(FListViewCheckStateArray, FListView.Items.Count);

      FListView.OnData := ListViewData;
      FListView.OnMouseDown := ListViewMouseDown;
      end;

      procedure TForm1.ListViewData(Sender: TObject; Item: TListItem);
      begin
      Item.Caption := Format('This is item %.2d', [Item.Index]);
      Item.StateIndex := FListViewCheckStateArray[Item.Index];
      end;

      procedure TForm1.ListViewMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
      var
      Item: TListItem;
      begin
      if (Button = mbLeft) and
      (htOnStateIcon in FListView.GetHitTestInfoAt(X, Y)) then begin
      Item := FListView.GetItemAt(X, Y);
      Assert(Assigned(Item));
      FListViewCheckStateArray[Item.Index] :=
      Ord(not Boolean(FListViewCheckStateArray[Item.Index]));
      FListView.UpdateItems(Item.Index, Item.Index);
      end;
      end;

      end.


      PS: Drawing artifacts should be the subject of a different question.






      share|improve this answer




























        4












        4








        4








        But the Checkbox property only supports vsList and vsReport mode ...




        That's not correct. You are looking at VCL documentation which states




        Set Checkboxes to true to make check boxes appear next to the list
        items when ViewStyle is vsList or vsReport. ...




        This is outdated information. See the documentation for the native control:




        Version 6.00 and later Check boxes are visible and functional with all
        list view modes except the tile view mode introduced in ComCtl32.dll
        version 6. ...




        Indeed if you try it on a regular TListView control in one of the icon modes, you'll see there are no problems with check boxes.







        However that's not going to help you. In this regard your question is malformed, it has the assumption that Checkboxes work OK in list and report modes with a virtual list view control. That's not the case.



        Check boxes are good when you can use the Checked property on a list item. In a virtual list view control there are no items you can check. I'm quoting from the LVM_SETITEMCOUNT message:




        If the list-view control was created without the LVS_OWNERDATA style,
        sending this message causes the control to allocate its internal data
        structures for the specified number of items. ...



        ...



        If the list-view control was created with the LVS_OWNERDATA style (a
        virtual list view), sending this message sets the virtual number of
        items that the control contains.




        All the control knows is that there are that many items, there is no per item storage. VCL reflects the API control: when you request an item and your control has OwnerData set, the OnData event handler is called on a temporary item to reflect the item's properties.



        In a virtual list view you manage checks by using state images. Quoting from the documentation:




        ... You can use state images, such as checked and cleared check boxes,
        to indicate application-defined item states. State images are
        displayed in icon view, small icon view, list view, and report view.








        Below you'll find a basic implementation which holds item state information in a separate array. To run it, create a blank new form, create an OnCreate handler for the form and paste the code.



        unit Unit1;

        interface

        uses
        Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
        Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ComCtrls, Vcl.ImgList;

        type
        TForm1 = class(TForm)
        procedure FormCreate(Sender: TObject);
        private
        FListView: TListView;
        FListViewCheckStateArray: array of 0..1;
        procedure ListViewData(Sender: TObject; Item: TListItem);
        procedure ListViewMouseDown(Sender: TObject; Button: TMouseButton;
        Shift: TShiftState; X, Y: Integer);
        end;

        var
        Form1: TForm1;

        implementation

        {$R *.dfm}

        procedure TForm1.FormCreate(Sender: TObject);
        var
        Bmp: TBitmap;
        begin
        FListView := TListView.Create(Self);
        FListView.Parent := Self;
        FListView.Align := alClient;
        FListView.OwnerData := True;
        FListView.ViewStyle := vsSmallIcon;

        FListView.StateImages := TImageList.Create(Self);
        Bmp := TBitmap.Create;
        Bmp.PixelFormat := pf32bit;
        Bmp.SetSize(16, 16);
        DrawFrameControl(Bmp.Canvas.Handle, Rect(0, 0, 16, 16), DFC_BUTTON,
        DFCS_BUTTONCHECK);
        FListView.StateImages.Add(Bmp, nil);
        DrawFrameControl(Bmp.Canvas.Handle, Rect(0, 0, 16, 16), DFC_BUTTON,
        DFCS_BUTTONCHECK or DFCS_CHECKED);
        FListView.StateImages.Add(Bmp, nil);
        Bmp.Free;

        FListView.Items.Count := 257;
        SetLength(FListViewCheckStateArray, FListView.Items.Count);

        FListView.OnData := ListViewData;
        FListView.OnMouseDown := ListViewMouseDown;
        end;

        procedure TForm1.ListViewData(Sender: TObject; Item: TListItem);
        begin
        Item.Caption := Format('This is item %.2d', [Item.Index]);
        Item.StateIndex := FListViewCheckStateArray[Item.Index];
        end;

        procedure TForm1.ListViewMouseDown(Sender: TObject; Button: TMouseButton;
        Shift: TShiftState; X, Y: Integer);
        var
        Item: TListItem;
        begin
        if (Button = mbLeft) and
        (htOnStateIcon in FListView.GetHitTestInfoAt(X, Y)) then begin
        Item := FListView.GetItemAt(X, Y);
        Assert(Assigned(Item));
        FListViewCheckStateArray[Item.Index] :=
        Ord(not Boolean(FListViewCheckStateArray[Item.Index]));
        FListView.UpdateItems(Item.Index, Item.Index);
        end;
        end;

        end.


        PS: Drawing artifacts should be the subject of a different question.






        share|improve this answer
















        But the Checkbox property only supports vsList and vsReport mode ...




        That's not correct. You are looking at VCL documentation which states




        Set Checkboxes to true to make check boxes appear next to the list
        items when ViewStyle is vsList or vsReport. ...




        This is outdated information. See the documentation for the native control:




        Version 6.00 and later Check boxes are visible and functional with all
        list view modes except the tile view mode introduced in ComCtl32.dll
        version 6. ...




        Indeed if you try it on a regular TListView control in one of the icon modes, you'll see there are no problems with check boxes.







        However that's not going to help you. In this regard your question is malformed, it has the assumption that Checkboxes work OK in list and report modes with a virtual list view control. That's not the case.



        Check boxes are good when you can use the Checked property on a list item. In a virtual list view control there are no items you can check. I'm quoting from the LVM_SETITEMCOUNT message:




        If the list-view control was created without the LVS_OWNERDATA style,
        sending this message causes the control to allocate its internal data
        structures for the specified number of items. ...



        ...



        If the list-view control was created with the LVS_OWNERDATA style (a
        virtual list view), sending this message sets the virtual number of
        items that the control contains.




        All the control knows is that there are that many items, there is no per item storage. VCL reflects the API control: when you request an item and your control has OwnerData set, the OnData event handler is called on a temporary item to reflect the item's properties.



        In a virtual list view you manage checks by using state images. Quoting from the documentation:




        ... You can use state images, such as checked and cleared check boxes,
        to indicate application-defined item states. State images are
        displayed in icon view, small icon view, list view, and report view.








        Below you'll find a basic implementation which holds item state information in a separate array. To run it, create a blank new form, create an OnCreate handler for the form and paste the code.



        unit Unit1;

        interface

        uses
        Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
        Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ComCtrls, Vcl.ImgList;

        type
        TForm1 = class(TForm)
        procedure FormCreate(Sender: TObject);
        private
        FListView: TListView;
        FListViewCheckStateArray: array of 0..1;
        procedure ListViewData(Sender: TObject; Item: TListItem);
        procedure ListViewMouseDown(Sender: TObject; Button: TMouseButton;
        Shift: TShiftState; X, Y: Integer);
        end;

        var
        Form1: TForm1;

        implementation

        {$R *.dfm}

        procedure TForm1.FormCreate(Sender: TObject);
        var
        Bmp: TBitmap;
        begin
        FListView := TListView.Create(Self);
        FListView.Parent := Self;
        FListView.Align := alClient;
        FListView.OwnerData := True;
        FListView.ViewStyle := vsSmallIcon;

        FListView.StateImages := TImageList.Create(Self);
        Bmp := TBitmap.Create;
        Bmp.PixelFormat := pf32bit;
        Bmp.SetSize(16, 16);
        DrawFrameControl(Bmp.Canvas.Handle, Rect(0, 0, 16, 16), DFC_BUTTON,
        DFCS_BUTTONCHECK);
        FListView.StateImages.Add(Bmp, nil);
        DrawFrameControl(Bmp.Canvas.Handle, Rect(0, 0, 16, 16), DFC_BUTTON,
        DFCS_BUTTONCHECK or DFCS_CHECKED);
        FListView.StateImages.Add(Bmp, nil);
        Bmp.Free;

        FListView.Items.Count := 257;
        SetLength(FListViewCheckStateArray, FListView.Items.Count);

        FListView.OnData := ListViewData;
        FListView.OnMouseDown := ListViewMouseDown;
        end;

        procedure TForm1.ListViewData(Sender: TObject; Item: TListItem);
        begin
        Item.Caption := Format('This is item %.2d', [Item.Index]);
        Item.StateIndex := FListViewCheckStateArray[Item.Index];
        end;

        procedure TForm1.ListViewMouseDown(Sender: TObject; Button: TMouseButton;
        Shift: TShiftState; X, Y: Integer);
        var
        Item: TListItem;
        begin
        if (Button = mbLeft) and
        (htOnStateIcon in FListView.GetHitTestInfoAt(X, Y)) then begin
        Item := FListView.GetItemAt(X, Y);
        Assert(Assigned(Item));
        FListViewCheckStateArray[Item.Index] :=
        Ord(not Boolean(FListViewCheckStateArray[Item.Index]));
        FListView.UpdateItems(Item.Index, Item.Index);
        end;
        end;

        end.


        PS: Drawing artifacts should be the subject of a different question.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 19 '18 at 18:24

























        answered Nov 19 '18 at 18:15









        Sertac AkyuzSertac Akyuz

        48.1k372128




        48.1k372128






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53371002%2fvirtual-listview-with-checkbox-support-for-vsicon-and-vssmallicon%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Guess what letter conforming each word

            Port of Spain

            Run scheduled task as local user group (not BUILTIN)