Page 1 of 2 12 LastLast
Results 1 to 40 of 55

Thread: [PARTIALLY RESOLVED] Listview - Grouping in Virtual Mode

  1. #1

    Thread Starter
    Hyperactive Member LucasMKG's Avatar
    Join Date
    Jun 2015
    Location
    South Africa (ZAR)
    Posts
    338

    Resolved [PARTIALLY RESOLVED] Listview - Grouping in Virtual Mode

    I'm still trying to convert the 'Grouping in Virtual Mode' portion from:
    http://www.codeproject.com/Articles/...-View-Features... I struggle to follow the logic behind this language, is it C++.

    Snippet Code:
    .................................................................
    fafalone was able to convert this line;
    const IID IID_IListViewFooter = {0xF0034DA8, 0x8A22, 0x4151,
    {0x8F, 0x16, 0x2E, 0xBA, 0x76, 0x56, 0x5B, 0xCC}};
    TO,
    Public Const IID_IListViewFooter = "{F0034DA8-8A22-4151-8F16-2EBA76565BCC}"

    I get that you dropped '0x' but from '{0x8F, 0x16, 0x2E, 0xBA, 0x76, 0x56, 0x5B, 0xCC}' how did you know that '0x8F, 0x16' and '0x2E, 0xBA, 0x76, 0x56, 0x5B, 0xCC' has to be combined

    Or will I be correct to interpret the above like this;
    Public Const IID_IListViewFooter = (&H2FFE2979 + &H5928 + &H4386 + &H9C + &HDB + &H8E + &H1F + &H15 + &HB7 + &H2F + &HB4)

    While answering that, how will you convert this;
    const IID IID_IListView = {0x2FFE2979, 0x5928, 0x4386,
    {0x9C, 0xDB, 0x8E, 0x1F, 0x15, 0xB7, 0x2F, 0xB4}};
    Edit:: or will it be;
    Public Const IID_IListView = "{2FFE2979-5928-4386-9CDB-8E1F15B72FB4}" ::
    '................................................................................................... ..........


    LucasMKG
    in need of the best Grid
    Hala to Giorgio Brausi (gibra)
    Last edited by LucasMKG; Nov 11th, 2015 at 07:49 AM.

  2. #2

    Thread Starter
    Hyperactive Member LucasMKG's Avatar
    Join Date
    Jun 2015
    Location
    South Africa (ZAR)
    Posts
    338

    Re: Grouping in Virtual Mode

    This code is said to be responsible for showing groups in virtual mode (from the above link), if only it can be converted to VB6

    Code:
    -------------------------------------------------------------------
    This interface must be implemented by your app. To make your implementation known to the list view control, IListView::SetOwnerDataCallback must be called:
    Hide Copy Code

    const IID IID_IListView = {0x2FFE2979, 0x5928, 0x4386,
    {0x9C, 0xDB, 0x8E, 0x1F, 0x15, 0xB7, 0x2F, 0xB4}};

    class IListView :
    public IOleWindow
    {
    public:
    // ...
    virtual HRESULT STDMETHODCALLTYPE SetOwnerDataCallback(
    IOwnerDataCallback* pCallback) = 0;
    // ...
    };

    #define LVM_QUERYINTERFACE (LVM_FIRST + 189)

    IListView* pListView = NULL;
    SendMessage(hWndLvw, LVM_QUERYINTERFACE, reinterpret_cast<WPARAM>(&IID_IListView),
    reinterpret_cast<LPARAM>(&pListView));
    pListView->SetOwnerDataCallback(...);
    // insert a pointer to the implementation of IOwnerDataCallback here
    -------------------------------------------------------------------
    EDIT:: I gather that reinterpret_cast<WPARAM>(&IID_IListView) might be converted to
    ByVal VarPtr(IID_IListView), is this correct. ::



    LucasMKG
    tracking Timo Kunze
    Last edited by LucasMKG; Sep 22nd, 2015 at 05:57 AM.

  3. #3
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,710

    Re: Listview - Grouping in Virtual Mode

    Public Const IID_IListViewFooter = "{F0034DA8-8A22-4151-8F16-2EBA76565BCC}" 'UNDOCUMENTED INTERFACE
    Public Const IID_IListView = "{E5B16AF2-3990-4681-A609-1F060CD14269}" 'UNDOCUMENTED INTERFACE


    They're GUIDs, and can be written different ways depending on what function you're using to convert them to the actual GUID structure or what the compiler expects. As a string, they have to look like that^, with the same number of characters in each group.

    I did finish with all the interfaces... didn't write an class module for IOwnerDataCallback, but it's the same principal as cLVFooterCallback.

    This zip contains that class module, the finished TLB+source.


    Edit:
    When calling the IListView.SetOwnerDataCallback, you'll do it like this:
    Code:
    Public Declare Function CLSIDFromString Lib "ole32" (ByVal lpszGuid As Long, pGuid As Any) As Long
    
    Dim pILV As IListView
    Dim iidLV As LGUID 'type included in TLB
    Call CLSIDFromString(StrPtr(IID_IListView), iidLV)
    
    Call SendMessage(hLVS, LVM_QUERYINTERFACE, VarPtr(iidLV), pILV) 'where hLVS is the ListView hWnd
    
    Dim cLVODC As cLVOwnerDataCB 'the class module implementing IOwnerDataCallback
    Set cLVODC = New cLVOwnerDataCB
    
    pILV.SetOwnerDataCallback cLVODC
    Here's the prototypes for a class implementing IOwnerDataCallback:
    Code:
    Option Explicit
    
    Implements IOwnerDataCallback
    
    Private Sub IOwnerDataCallback_GetItemPosition(ByVal iItem As Long, pt As lvundoc.POINT)
    
    End Sub
    Private Sub IOwnerDataCallback_SetItemPosition(ByVal iItem As Long, pt As lvundoc.POINT)
    
    End Sub
    Private Sub IOwnerDataCallback_GetItemInGroup(ByVal groupindex As Long, ByVal groupWideItemIndex As Long, pTotalItemIndex As Long)
    
    End Sub
    Private Sub IOwnerDataCallback_GetItemGroup(ByVal iItem As Long, ByVal occurenceIndex As Long, pGroupIndex As Long)
    
    End Sub
    Private Sub IOwnerDataCallback_GetItemGroupCount(ByVal iItem As Long, pOccurenceCount As Long)
    
    End Sub
    Private Sub IOwnerDataCallback_OnCacheHint(lviiFirst As lvundoc.tagLVITEMINDEX, lviiLast As lvundoc.tagLVITEMINDEX)
    
    End Sub
    Edit 2: The IID you have for IID_IListView is only for Windows Vista. For Windows 7 and above, make sure you use the one at the top of this post. If you're actually using Windows Vista, then the TLB will have to be changed to the Vista IID too.


    Edit 3: Actually you may not need IListView at all. You could send another undocumented message, SendMessage(hLVS, LVM_SETOWNERDATACALLBACK, ObjPtr(cLVODC), ByVal 0&) '(LVM_FIRST + 187)
    May not work on Vista, but will on 7.
    Attached Files Attached Files
    Last edited by fafalone; Sep 23rd, 2015 at 07:02 PM. Reason: Replaced attachment with bugfixed version; see a few posts down for why

  4. #4

    Thread Starter
    Hyperactive Member LucasMKG's Avatar
    Join Date
    Jun 2015
    Location
    South Africa (ZAR)
    Posts
    338

    Re: Listview - Grouping in Virtual Mode

    thanks, fafalone

    I'll have to go through all of that

    LucasMKG
    loving VB6

  5. #5
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,710

    Re: Listview - Grouping in Virtual Mode

    Yeah it should be good to go, there's not anything that strikes me as being a roadblock for VB. I don't think any of the class functions will need a vtable-swap as S_OK is the expected response on the major ones.

    As per the comments on CodeProject between me and the author, the LVM_SETOWNERDATACALLBACK message (as well as LVM_SET/GETGROUPSUBSETCOUNT) wasn't discovered until after the article was published. I'd suggest using that instead, as IListView isn't exactly the most stable thing, as one expects with undocumented, unsupported things, especially trying to use those in VB.

    Edit: This doesn't effect the function needed for this topic, but the IListView interface posted in the previous TLB had a number of functions that would produce automation errors; this was due to VB not being able to pass user types ByVal and the interface not being able to handle the pointer reference; this has been corrected by splitting all tagLVITEMINDEX [in] parameters into 2 [in] parameters. Unfortunately this didn't fix the edit group label and edit subitem calls, but a number of other functions are fixed.
    Attached Files Attached Files
    Last edited by fafalone; Sep 23rd, 2015 at 07:01 PM.

  6. #6

    Thread Starter
    Hyperactive Member LucasMKG's Avatar
    Join Date
    Jun 2015
    Location
    South Africa (ZAR)
    Posts
    338

    Re: Listview - Grouping in Virtual Mode

    fafalone,

    when you have time at your disposal, please complete "class module for IOwnerDataCallback".
    I really need to integrate that to vhGrid.

    LucasMKG
    not giving-up on vhGrid

  7. #7
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,710

    Re: Listview - Grouping in Virtual Mode

    I wrote out all the prototypes; what to do with them is just 1-2 lines on a couple of them; have a look at the codeproject source:

    Code:
    	virtual STDMETHODIMP GetItemInGroup(int groupIndex, int groupWideItemIndex, PINT pTotalItemIndex)
    	{
    		// we want group 0 to contain items 0, 3, 6...
    		//         group 1            items 1, 4, 7...
    		//         group 2            items 2, 5, 8...
    		*pTotalItemIndex = groupIndex + groupWideItemIndex * 3;
    		return S_OK;
    	}
    
    	virtual STDMETHODIMP GetItemGroup(int itemIndex, int occurenceIndex, PINT pGroupIndex)
    	{
    		// group 0 contains items 0, 3, 6...
    		// group 1 contains items 1, 4, 7...
    		// group 2 contains items 2, 5, 8...
    		*pGroupIndex = itemIndex % 3;
    		return S_OK;
    	}
    
    	virtual STDMETHODIMP GetItemGroupCount(int itemIndex, PINT pOccurenceCount)
    	{
    		// keep the one-item-in-multiple-groups stuff for another articel :-)
    		*pOccurenceCount = 1;
    		return S_OK;
    	}
    Should be a straightforward conversion to VB; the rest are all E_NOTIMPL... I have no idea if you have to return that (S_OK is returned when left blank), if you do I'll help you with vtable swapping.

  8. #8

    Thread Starter
    Hyperactive Member LucasMKG's Avatar
    Join Date
    Jun 2015
    Location
    South Africa (ZAR)
    Posts
    338

    Re: Listview - Grouping in Virtual Mode

    fafalone,

    'vtable swapping' is like saying '@#%$' to me...I'm just a rookie, be easy on me.

    when I activate either method:
    Code:
    ' based on © fafalone : ListView Undocumented Features TLB @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    'Virtual groups - Classes and interfaces needed to implement virtual groups
    
    Private Declare Function CLSIDFromString Lib "ole32" (ByVal lpszGuid As Long, pGuid As Any) As Long
    
    Private Const IID_IListView = "{E5B16AF2-3990-4681-A609-1F060CD14269}" 'UNDOCUMENTED INTERFACE
    Private Const LVM_SETOWNERDATACALLBACK          As Long = (LVM_FIRST + 187)
    Private Const LVM_QUERYINTERFACE                As Long = (LVM_FIRST + 189)
    
    Private m_VirtualGroups_QueryInterface          As Boolean
    Private m_VirtualGroups_SetOwnerDataCallBack    As Boolean
    
    
    Public Property Get VirtualGroups_QueryInterface() As Boolean
        VirtualGroups_QueryInterface = m_VirtualGroups_QueryInterface
    End Property
    Public Property Let VirtualGroups_QueryInterface(ByVal PropVal As Boolean)
    
        Dim pILV As IListView
        Dim iidLV As LGUID 'type included in TLB
        Call CLSIDFromString(StrPtr(IID_IListView), iidLV)
    
        m_VirtualGroups_QueryInterface = PropVal
        If Not (m_lHGHwnd = 0) Then
            Call SendMessage(m_lHGHwnd, LVM_QUERYINTERFACE, VarPtr(iidLV), pILV) 'where hLVS is the ListView hWnd
            If (pILV Is Nothing) Then
                MsgBox "Failed to get LVM_QUERYINTERFACE"
                Exit Property
            Else
                MsgBox "LVM_QUERYINTERFACE loaded . . . yeah!"
                Dim cLVODC As cLVOwnerDataCB                    'the class module implementing IOwnerDataCallback
                Set cLVODC = New cLVOwnerDataCB
        
                pILV.SetOwnerDataCallback cLVODC
            End If
        End If
    End Property
    
    'Other Method
    
    Public Property Get VirtualGroups_SetOwnerDataCallBack() As Boolean
        VirtualGroups_SetOwnerDataCallBack = m_VirtualGroups_SetOwnerDataCallBack
    End Property
    Public Property Let VirtualGroups_SetOwnerDataCallBack(ByVal PropVal As Boolean)
        m_VirtualGroups_SetOwnerDataCallBack = PropVal
        If Not (m_lHGHwnd = 0) Then
            If PropVal Then
                Dim cLVODC As cLVOwnerDataCB                    'the class module implementing IOwnerDataCallback
                Set cLVODC = New cLVOwnerDataCB
     
                Call SendMessage(m_lHGHwnd, LVM_SETOWNERDATACALLBACK, ObjPtr(cLVODC), ByVal 0&)
            Else
                Call SendMessageLongA(m_lHGHwnd, LVM_SETOWNERDATACALLBACK, 0, 0)
            End If
        End If
    End Property
    '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    
    Public Property Let GroupsEnable(Enable As Boolean)
        If Not (m_lHGHwnd = 0) Then Call SendMessage(m_lHGHwnd, LVM_ENABLEGROUPVIEW, Enable, 0)
    End Property
    Its promising, since, when I choose either method and enable groups...groups are enabled (yeah!)...but the virtual listview (vhGrid) crashes without showing antything...and I get the following error msg;
    Run-time error '-2147417848 (80010108)': Automation error The object invoked has disconnected from its clients.

    >>> my comctl32.dll version is '6.1.7601.18201'...even Krool's Listview (groups) crushes and says it require "comctl32.dll version 6.0 or higher" ---- It might be me or my PC..but something is wrong..as I suspect my 'comctl32.dll' version for the Run-time error '-2147417848 (80010108)'


    LucasMKG
    still talking VB6
    Last edited by LucasMKG; Oct 21st, 2015 at 07:40 PM.

  9. #9

    Thread Starter
    Hyperactive Member LucasMKG's Avatar
    Join Date
    Jun 2015
    Location
    South Africa (ZAR)
    Posts
    338

    Re: Listview - Grouping in Virtual Mode

    fafalone,

    Let's try converting the below to VB6:
    Code:
    *pTotalItemIndex = groupIndex + groupWideItemIndex * 3;
    
    *pGroupIndex = itemIndex % 3;
    
    return S_OK;
    LucasMKG
    still on VB6 and growing stronger

  10. #10
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,710

    Re: Listview - Grouping in Virtual Mode

    pTotalItemIndex = groupIndex + groupWideItemIndex * 3
    pGroupIndex = itemIndex Mod 3


    Also, put debug outputs as the first line and confirm the procedure is even being called before you worry about its content (every interface class entry should have one when you're checking an error like that, to see if anything at all is being called)

    One idea to try, it's possible since you've declared it entirely inside that function (cLVODC) it's going out of scope. Making it module level might correct that.

  11. #11

    Thread Starter
    Hyperactive Member LucasMKG's Avatar
    Join Date
    Jun 2015
    Location
    South Africa (ZAR)
    Posts
    338

    Re: Listview - Grouping in Virtual Mode

    I really need to add groups in virtual listview!
    It has been done in C++ ....and I'm currently not able to translate it to VB6...anyone with the knowhow of C++ and VB6 please translate the groups part http://www.codeproject.com/Articles/...-View-Features to VB6

    LucasMKG
    needing groups in virtual listview

  12. #12
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,253

    Re: Listview - Grouping in Virtual Mode

    Quote Originally Posted by LucasMKG View Post
    I really need to add groups in virtual listview!
    Could you show a "Photomontage" or something, so that one gets a better
    "picture", what you want to achieve in the end?

    Is this a "Grouping for Icon-View-Mode" (as shown in the C++ article) -
    or are you after "GridRow-Grouping" (for the "Details-View").

    If the latter, then I'd simly use an ownerdrawn (virtual) TreeView
    (or an ownerdrawn TreeList, or an ownerdrawn VList)-Control or -Widget.

    As said, with an uploaded Picture from you, one could make better
    suggestions with regards to possible alternatives.

    Olaf

  13. #13
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,710

    Re: Listview - Grouping in Virtual Mode

    It's the same thing as regular group mode (LVM_ENABLEGROUPVIEW, LVM_INSERTGROUP, etc), except he wants to use it while LVS_OWNERDATA is set.

    Lucas, did you get the same error after making the LVODC class module-level so it didn't go out of scope? Did you add Debug.Print statements in each class module method to see if it's even being entered?

    Edit: I got it working. I ALMOST got it working ...The code is very straightforward. What threw me the most was that if I used LVM_SETOWNERDATACALLBACK, things kept crashing with access violations. But once I went back to IListView.SetOwnerDataCallback, it worked.

    Due to the large number of APIs and declares involved, it will take a while for me to rip things out of the full project I used (since it was already set up with all the apis/declares/subclassing funcs), so there's a lot of superfluous code since I took an existing ListView setup to make things easier, but you'll be able to see how it works. I'll post a cleaned up demo in the codebank when I can. For this initial test, like the sample project, it just uses a fixed number of items and groups. Inserting/deleting items you should already be familiar with from regular virtual listviews; to change the group info you need to update the cItems like you do the listview item count.

    form:
    Code:
    Option Explicit
    Private m_himlSysSmall As Long
    Private pIML As iImageList
    Private cLVODC As cLVOwnerDataCB
    
    Private Function CreateListView(hwndParent As Long, _
                                                      iid As Long, _
                                                      dwStyle As Long, _
                                                      dwExStyle As Long) As Long
      Dim rc As RECT
      Dim hwndLV As Long
      DebugAppend "frmSearch.CreateListView.entry"
      ' Initialize the listview class in the common controls DLL .
     ' Call InitCC(ICC_LISTVIEW_CLASSES) this should be done in sub main
    
      ' Get the client area of the parent.
      Call GetClientRect(hwndParent, rc)
      DebugAppend "frmSearch.CreateListView.gcr"
      hwndLV = CreateWindowEx(dwExStyle, WC_LISTVIEW, "", _
                                                    dwStyle, 218, 2, 650, rc.Bottom - 30, _
                                                    hwndParent, iid, App.hInstance, 0)
    Debug.Print "hwnd=" & hwndLV & "err=" & GetLastError()
    Call Subclass2(hwndLV, AddressOf LVGWndProc)
       ListView_SetItemCount hwndLV, 999
          CreateListView = hwndLV
    End Function
    Private Sub InitListView()
      Dim dwStyle As Long, dwStyle2 As Long
      Dim lvcol As LVCOLUMN
      Dim i As Long
      Dim iCurViewMode As Long
      iCurViewMode = LV_VIEW_DETAILS
      
    DebugAppend "InitLVS()::Entry, mode=" & iCurViewMode
    hLVVG = CreateListView(Me.hWnd, IDD_LISTVIEW, _
                        LVS_REPORT Or LVS_AUTOARRANGE Or LVS_SHAREIMAGELISTS Or LVS_EDITLABELS Or LVS_SHOWSELALWAYS Or LVS_OWNERDATA Or _
                        WS_TABSTOP Or WS_VISIBLE Or WS_CHILD Or WS_BORDER, WS_EX_CLIENTEDGE)
                        
    Dim rc As RECT
    
    Call GetClientRect(Me.hWnd, rc)
    SetWindowPos hLVVG, 0, 0, 0, rc.Right, rc.Bottom, 0
    
      'm_himlSysSmall = GetSystemImagelist(SHGFI_SMALLICON)
      
      Dim pIML As iImageList
      Call SHGetImageList(SHIL_SMALL, IID_IImageList, pIML)
      m_himlSysSmall = ObjPtr(pIML)
    
        Call ListView_SetImageList(hLVVG, m_himlSysSmall, LVSIL_SMALL)
        Call ListView_SetImageList(hLVVG, m_himlSysSmall, LVSIL_GROUPHEADER)
        
        'DebugAppend "InitLVS()::lvSearch.SetImageList"Or LVS_EX_FULLROWSELECT
        Dim lvsex As LVStylesEx
        lvsex = LVS_EX_SUBITEMIMAGES Or LVS_EX_HEADERDRAGDROP Or LVS_EX_LABELTIP 'Or LVS_EX_DOUBLEBUFFER 'Or LVS_EX_GRIDLINES 'Or LVS_EX_TRACKSELECT
    
    Call ListView_SetExtendedStyle(hLVVG, lvsex)
    'If bNoTheme = False Then
    Dim swt1 As String
    Dim swt2 As String
    swt1 = "explorer"
    swt2 = ""
    Call SetWindowTheme(hLVVG, StrPtr(swt1), 0&)
    'End If
    'Call SendMessage(hLVVG, LVM_SETCALLBACKMASK, LVIS_FOCUSED, ByVal 0)
    
    If (iCurViewMode = 0) Then
    ''    hSysIL = GetSystemImagelist(SHGFI_LARGEICON)
        Call SHGetImageList(SHIL_LARGE, IID_IImageList, pIML)
        Debug.Print "InitLVS Set Large=32"
    Else
    ''  Dim CI As New cIcon
    ''  hSysIL = CI.GetImageList48()
        Call SHGetImageList(SHIL_EXTRALARGE, IID_IImageList, pIML)
      Debug.Print "InitLVS Set Large=48"
    End If
    hSysIL = ObjPtr(pIML)
    Call ListView_SetImageList(hLVVG, hSysIL, LVSIL_NORMAL)
    Debug.Print "InitLVS.SC_VM " & iCurViewMode
    iCurViewMode = LV_VIEW_DETAILS
    Select Case iCurViewMode
        Case LV_VIEW_ICON, LV_VIEW_DETAILS, LV_VIEW_SMALLICON, LV_VIEW_LIST
            Debug.Print "SetView 4"
            Call SendMessage(hLVVG, LVM_SETVIEW, iCurViewMode, ByVal 0&)
            Debug.Print "SetView 4"
        Case LV_VIEW_XLICON 'large icon view, but assigned imagelist is xl
            Call SendMessage(hLVVG, LVM_SETVIEW, 0, ByVal 0&)
        Case LV_VIEW_TILE
            Call SetTileView(hLVS)
        Case LV_VIEW_THUMBNAIL
            'Call ShowThumbsAPI
            'Exit Sub
    End Select
    Dim dwRtn As Long
    
    'Set LVDT = New cDropTarget
    'If ((LVDT Is Nothing)) Then
    '    Debug.Print "FAILED TO CREATE DROP OBJS"
    'End If
    ''Call RevokeDragDrop(hLVS)
    'LVDT.DropHWND = hLVS
    'Call CoLockObjectExternal(ObjPtr(LVDT), 1, 0)
    'dwRtn = RegisterDragDrop(hLVVG, LVDT)
    'Call oleexp3.RegisterDragDrop(hLVVG, LVDT)
    
        hLVVGHdr = SendMessage(hLVVG, LVM_GETHEADER, 0, ByVal 0&)
        
        ReDim sColText(4)
        sColText(0) = sLVSc1
        sColText(1) = sLVSc2
        sColText(2) = sLVSc3
        sColText(3) = sLVSc4
        sColText(4) = sLVSc5
        
        lvcol.mask = LVCF_TEXT Or LVCF_WIDTH
        lvcol.cchTextMax = Len(sLVSc1) + 1
        lvcol.pszText = sLVSc1
        lvcol.CX = 190
        uColData(lDefColIdx(0)).Pos = 0
        uColData(lDefColIdx(0)).Visible = True
        Call SendMessage(hLVVG, LVM_INSERTCOLUMN, 1, lvcol)
    
        lvcol.cchTextMax = Len(sLVSc2) + 1
        lvcol.pszText = sLVSc2
        lvcol.CX = 65
        uColData(lDefColIdx(1)).Pos = 1
        uColData(lDefColIdx(1)).Visible = True
        Call SendMessage(hLVVG, LVM_INSERTCOLUMN, 2, lvcol)
    
        lvcol.cchTextMax = Len(sLVSc3) + 1
        lvcol.pszText = sLVSc3
        lvcol.CX = 200
        uColData(lDefColIdx(2)).Pos = 2
        uColData(lDefColIdx(2)).Visible = True
        Call SendMessage(hLVVG, LVM_INSERTCOLUMN, 3, lvcol)
    
        lvcol.cchTextMax = Len(sLVSc4) + 1
        lvcol.pszText = sLVSc4
        lvcol.CX = 120
        uColData(lDefColIdx(3)).Pos = 3
        uColData(lDefColIdx(3)).Visible = True
        Call SendMessage(hLVVG, LVM_INSERTCOLUMN, 4, lvcol)
        
        lvcol.cchTextMax = Len(sLVSc5) + 1
        lvcol.pszText = sLVSc5
        lvcol.CX = 120
        uColData(lDefColIdx(4)).Pos = 4
        uColData(lDefColIdx(4)).Visible = True
        Call SendMessage(hLVVG, LVM_INSERTCOLUMN, 5, lvcol)
       
      
        
    'add dropdown menu for name col
    Dim sLVSh1 As String
    sLVSh1 = "Name"
    Dim HDI As HDITEMW
    HDI.mask = HDI_FORMAT Or HDI_TEXT Or HDI_LPARAM
    HDI.fmt = HDF_SPLITBUTTON Or HDF_STRING
    HDI.cchTextMax = Len(sLVSh1)
    HDI.pszText = StrPtr(sLVSh1 & vbNullChar)
    HDI.lParam = lDefColIdx(0)
    Call SendMessage(hLVVGHdr, HDM_SETITEMW, 0, HDI)
    
    'add dropdown menu for size col
    Dim sLVSh2 As String
    sLVSh2 = uColData(lDefColIdx(1)).szDisplayName
    'Dim HDI As HDITEMW
    HDI.mask = HDI_FORMAT Or HDI_TEXT Or HDI_LPARAM
    HDI.fmt = HDF_SPLITBUTTON Or HDF_STRING
    HDI.cchTextMax = Len(sLVSh2)
    HDI.pszText = StrPtr(sLVSh2 & vbNullChar)
    HDI.lParam = lDefColIdx(1)
    Call SendMessage(hLVVGHdr, HDM_SETITEMW, 1, HDI)
    
    HDI.mask = HDI_LPARAM
    HDI.fmt = 0
    HDI.cchTextMax = 0
    HDI.pszText = 0
    For i = 2 To 4
        HDI.lParam = lDefColIdx(i)
        Call SendMessage(hLVVGHdr, HDM_SETITEMW, i, HDI)
    Next i
    
    Dim dwHdrStyle As HeaderStyles
    dwHdrStyle = GetWindowLong(hLVVGHdr, GWL_STYLE)
    dwHdrStyle = dwHdrStyle Or HDS_OVERFLOW Or HDS_BUTTONS
    Call SetWindowLong(hLVVGHdr, GWL_STYLE, dwHdrStyle)
    skipcol:
    'End If
    'If iCurViewMode <> LV_VIEW_THUMBNAIL Then Call Subclass2(hLVVG, AddressOf LVSWndProc) 'ShowThumbsAPI performs the subclass
    
    DebugAppend "InitLVS()::lvSearch.Subclass"
    
    'LVPostLoad = True
    '  m_himlSysSmall = GetSystemImagelist(SHGFI_LARGEICON)
        
        
    '    Call SendMessage(hLVVG, LVM_SETIMAGELIST, 4, ByVal hIML_Footer)
    Debug.Print "Setting callback..."
    Set cLVODC = New cLVOwnerDataCB
    Dim pILV As IListView
    Call SendMessage(hLVVG, LVM_QUERYINTERFACE, VarPtr(IID_IListView), pILV)
    If (pILV Is Nothing) Then
        Debug.Print "no pilv"
        Exit Sub
    End If
    pILV.SetOwnerDataCallback cLVODC
    Set pILV = Nothing
    
    'Call SendMessage(hLVVG, LVM_SETOWNERDATACALLBACK, ObjPtr(cLVODC), ByVal 0&)
    Debug.Print "Callback set, inserting groups..."
    
    Dim group As LVGROUP
            group.cbSize = LenB(group)
            group.mask = LVGF_ALIGN Or LVGF_GROUPID Or LVGF_HEADER Or LVGF_ITEMS Or LVGF_STATE
            group.iGroupId = 1
            group.uAlign = LVGA_HEADER_LEFT
            group.cItems = 333 '         // we must tell the list view how many items are in the group
            group.State = LVGS_COLLAPSIBLE
            group.StateMask = LVGS_COLLAPSIBLE
    
            group.pszHeader = StrPtr("Group 1")
            ListView_InsertGroup hLVVG, 0, group
            group.iGroupId = 2
            group.pszHeader = StrPtr("Group 2")
            ListView_InsertGroup hLVVG, 1, group
            group.iGroupId = 3
            group.pszHeader = StrPtr("Group 3")
            ListView_InsertGroup hLVVG, 2, group
    
            ListView_EnableGroupView hLVVG, 1
    
    
    
    
    
    End Sub
    
    
    Private Sub Form_Load()
    Call Subclass2(Me.hWnd, AddressOf FGVWndProc)
    InitListView
    
    End Sub
    module:
    Code:
    Public Function FGVWndProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long, ByVal uIdSubclass As Long, ByVal dwRefData As Long) As Long
    
    Select Case uMsg
            Case WM_NOTIFYFORMAT
                Debug.Print "Got NFMT on ftv main"
                FGVWndProc = NFR_UNICODE
                Exit Function
    
            Case WM_NOTIFY
                Dim dwRtn As Long
                Static nmh As NMHDR
        
          
                If (wParam = IDD_LISTVIEW) Then
                    dwRtn = DoGVNotify(hWnd, lParam)
                End If
                If dwRtn Then
                  FGVWndProc = dwRtn
                  Exit Function
                End If
        
    
    
            Case WM_DESTROY
                Call UnSubclass2(hWnd, PtrFGVWndProc(), uIdSubclass)
    End Select
    FGVWndProc = DefSubclassProc(hWnd, uMsg, wParam, lParam)
    End Function
    Public Function PtrFGVWndProc() As Long
    PtrFGVWndProc = FARPROC(AddressOf FGVWndProc)
    End Function
    Public Function LVGWndProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long, ByVal uIdSubclass As Long, ByVal dwRefData As Long) As Long
    Dim sText As String
    Select Case uMsg
    
        Case WM_DESTROY
            Call UnSubclass2(hWnd, PtrLVGWndProc, uIdSubclass)
    End Select
    LVGWndProc = DefSubclassProc(hWnd, uMsg, wParam, lParam)
    End Function
    Public Function PtrLVGWndProc() As Long
    PtrLVGWndProc = FARPROC(AddressOf LVGWndProc)
    End Function
    Public Function DoGVNotify(hWnd As Long, lParam As Long) As Long
            Dim sText As String
            Dim tNMH As NMHDR
            CopyMemory tNMH, ByVal lParam, Len(tNMH)
      
            Select Case tNMH.Code
        
                Case LVN_GETDISPINFO, LVN_GETDISPINFOW
    '                Debug.Print "GetDispInfo"
                    Dim LVDI As NMLVDISPINFO
                    CopyMemory ByVal VarPtr(LVDI), ByVal lParam, LenB(LVDI)
                    With LVDI.Item
                        
                        If (.mask And LVIF_TEXT) Then
                            Select Case .iSubItem
                                Case 0
                                    sText = "Item " & .iItem
                                    Debug.Print sText
                                    .cchTextMax = Len(sText)
                                    .pszText = StrPtr(sText)
                                Case Else
                                    sText = "Subitem " & .iSubItem
                                    .cchTextMax = Len(sText)
                                    .pszText = StrPtr(sText)
                            End Select
                        End If
                        If (.mask And LVIF_IMAGE) Then
                            Select Case .iSubItem
                                Case 0
                                    .iImage = CLng(Right(CStr(.iItem), 1))
                            End Select
                        End If
                        CopyMemory ByVal lParam, ByVal VarPtr(LVDI), LenB(LVDI)
                    End With
                End Select
            Exit Function
    End Function
    Last edited by fafalone; Nov 3rd, 2015 at 04:03 AM.

  14. #14
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,710

    Re: Listview - Grouping in Virtual Mode

    Went over post length.

    cLVOwnerDataCallback class:
    Code:
    Option Explicit
    
    Implements IOwnerDataCallback
    
    Private Sub IOwnerDataCallback_GetItemPosition(ByVal iItem As Long, pt As lvundoc.POINT)
    
    End Sub
    Private Sub IOwnerDataCallback_SetItemPosition(ByVal iItem As Long, pt As lvundoc.POINT)
    
    End Sub
    Private Sub IOwnerDataCallback_GetItemInGroup(ByVal groupindex As Long, ByVal groupWideItemIndex As Long, pTotalItemIndex As Long)
    'Debug.Print "GetItemInGroup"
    pTotalItemIndex = groupindex + groupWideItemIndex * 3 'you can just change *3 to *numberofgroups, unless you have an item appearing in multiple groups, then i dunno.. read the codeproject comments
    End Sub
    Private Sub IOwnerDataCallback_GetItemGroup(ByVal iItem As Long, ByVal occurenceIndex As Long, pGroupIndex As Long)
    'Debug.Print "GetItemGroup"
    pGroupIndex = iItem Mod 3
    End Sub
    Private Sub IOwnerDataCallback_GetItemGroupCount(ByVal iItem As Long, pOccurenceCount As Long)
    'Debug.Print "GetItemGroupCount"
    pOccurenceCount = 1
    End Sub
    Private Sub IOwnerDataCallback_OnCacheHint(lviiFirst As lvundoc.tagLVITEMINDEX, lviiLast As lvundoc.tagLVITEMINDEX)
    
    End Sub

    Edit: Unfortunately I may have jumped the gun. It's crashing out if you click the listview more than once, and I haven't got the faintest idea of how that might be corrected. Scrolling, collapsing and expanding groups, item images, columns, and everything else is all working fine.. no idea what's going on. I've tried not calling DefSubclassProc after LVN_GETDISPINFO, I've tried returned E_NOTIMPL on the blank functions, and a few other things to no avail.
    The access violation occurs at >comctl32.dll!CLVDrawManager::InvalidateSelectedOrCutOwnerData() + 0x11e63 bytes
    if that means anything to anyone
    Last edited by fafalone; Nov 3rd, 2015 at 04:35 AM.

  15. #15

    Thread Starter
    Hyperactive Member LucasMKG's Avatar
    Join Date
    Jun 2015
    Location
    South Africa (ZAR)
    Posts
    338

    Re: Listview - Grouping in Virtual Mode

    fafalone,

    I'm glad that it partially works...but I can't get vhGrid to even show groups in virtual mode.
    So, i'll be waiting for a 'cleaned up demo in the codebank' from you.

    LucasMKG
    rooting for fafalone to crack open virtual groups in VB6

  16. #16
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,710

    Re: Listview - Grouping in Virtual Mode

    Yeah I was all set to post it when I discovered the crash. Click once, ok. Click twice, boom. Very weird.

    So, I've attached what I was about the put in the Codebank, it's a cleaned up* demo project that will at least display the items and groups. You can also expand and collapse groups, scroll up and down, resize, select one item... everything except select a second item or deselect the first. Maybe you'll even be really lucky and this crash is unique to my system, which is not unprecedented-- INamespaceTreeControl crashes on right-click, but only on my system.

    You'll probably have to re-add the reference to lvundoc.tlb, since it's in another folder on my system... make sure you use the one in this zip and not a previous version.

    As a small consolation prize, the ListView and Header modules found in the ZIP are a new toy... unlike any other definition module, they're absolutely complete for all constants, types, and macros up through common control 6.0 (the only other definition modules with this level of completeness were done by Brad Martinez, and only cover common controls through 4.71), and can be dropped in to any project that will be doing advanced ListView work. You have no idea how many hours something like this takes, even with the program I made that can convert most common control macros from the C++ .h files to VB.

    * - it does contain commented out code for things I've tried that you can add back in, mainly unicode support and better subclassing. Also in InitListView there's code to show it with multiple columns in report mode, which works fine besides the selection crash- just be sure to also uncomment the LVN_DISPINFO response for multiple subitems.


    PS... I've just gotta ask one more time; are you really going to be loading 100,000 or more items into the ListView? If not you really don't need LVS_OWNERDATA on any system made in the past 15 years.
    Attached Files Attached Files
    Last edited by fafalone; Nov 4th, 2015 at 04:19 PM.

  17. #17
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,253

    Re: Listview - Grouping in Virtual Mode

    Quote Originally Posted by fafalone View Post
    It's the same thing as regular group mode (LVM_ENABLEGROUPVIEW, LVM_INSERTGROUP, etc), except he wants to use it while LVS_OWNERDATA is set.
    That's the point I wanted to make...

    Because *if* the ListView is OwnerDrawn (using a DataContainer,
    which is sitting outside the Control)- then one doesn't really need
    any special "group-mode-support" on the Control itself.

    @Lucas
    In case you want to achieve something like in the following ScreenShot:
    (the Demo-Shot currently shows the selected Item in the Caption,
    and the hovered Group2-Entry is currently in collapsed state).



    Then all you need is just a normal OwnerDrawn-ListControl or -Widget,
    and a DataContainer-Class which supports multiple Columns (e.g. an ADO-
    Recordset would do nicely - but also any Collection-Class which allows
    easy access on its "two Columns" as well (the Key+Value-Pairs it contains).


    If there's interest in the Source-Code (about 100 Lines in the Control-Class,
    and only 40 Lines in the VB-Form) I can show it - but alternatively I could
    explain, how to work with a suitable DataContainer-Class, to allow Grouping
    (and even SubGrouping) in conjunction with any normal ownerdrawn List-Control.

    Olaf

  18. #18

    Thread Starter
    Hyperactive Member LucasMKG's Avatar
    Join Date
    Jun 2015
    Location
    South Africa (ZAR)
    Posts
    338

    Re: Listview - Grouping in Virtual Mode

    Olaf,

    If there's interest in the Source-Code (about 100 Lines in the Control-Class,
    and only 40 Lines in the VB-Form) I can show it
    I'm extremely interested, only if its NOT like [Brad Martinez - LVItemTree] 'where lvisCollapsed..items are added and when lvisExpanded..ChildItems are deleted' The ADDING and DELETING part I don't like.


    If its not like the previous line, then - Olaf, you would have achieved what many have failed to do, that is 'the ability to HIDE A Listview Row'...because I don't like the available options, like hiding a listview row [by using the ImageList hack (SmallImageList)] http://stackoverflow.com/questions/6...ms-rows-height.

    LucasMKG
    liking vbforums

  19. #19

    Thread Starter
    Hyperactive Member LucasMKG's Avatar
    Join Date
    Jun 2015
    Location
    South Africa (ZAR)
    Posts
    338

    Re: Listview - Grouping in Virtual Mode

    fafalone,

    I have tried your attachment
    and it doesn't load groups...since pILV = Is Nothing
    Code:
    Code:
    If (pILV Is Nothing) Then
        Debug.Print "no pilv"
        MsgBox "no pilv"
        Exit Sub
    End If
    When I [make/compile Project1.exe], Gridinsoft trojan killer..warns that 'Project1.exe'..is a..Trojan.Win32.Agent.vb!n...even when I disable gridinsoft trojan killer it doesn't show groups (since pILV = Is Nothing)

    EDIT:: fafalone, I need LVS_OWNERDATA ...its part of the grid project I'm busy with...my next project will be according to post #12 of Olaf (integrating TreeList to my grid (like vbAccelerator's - MultiColumnTreeView 'pure treeview with drawn_lines' I'm Done with that part [and not node_to_cell like http://www.vbforums.com/showthread.p...light=lynxgrid] . . . for now I'm struggling with headers..I want to use TVM_INSERTCOLUMN like in github https://github.com/sebkirche/treelis.../TreeListWnd.h..not 'WC_HEADER' route)::

    LucasMKG
    thanking 'Olaf' and 'fafalone' for sharing their vast archives of vb6 knowledge.
    Last edited by LucasMKG; Nov 6th, 2015 at 01:49 AM.

  20. #20
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,710

    Re: Listview - Grouping in Virtual Mode

    What do you mean it's part of the grid project? You can respond to LVN_GETDISPINFO to set text and images without it by setting them to -1 initially (LPSTR_TEXTCALLBACK and I_IMAGECALLBACK.. the LVITEM.pszText member should be a Long; to assign an actual string in the callback use StrPtr)

    What OS are you on? Only reason you wouldn't be able to get a pointer to IListView is if the IID was wrong... which AFAIK only applies to Vista (XP and earlier won't work at all).
    Last edited by fafalone; Nov 6th, 2015 at 05:18 AM.

  21. #21
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,253

    Re: Listview - Grouping in Virtual Mode

    Quote Originally Posted by LucasMKG View Post
    I'm extremely interested, only if its NOT like [Brad Martinez - LVItemTree] 'where lvisCollapsed..items
    are added and when lvisExpanded..ChildItems are deleted' The ADDING and DELETING part I don't like.
    There's no deletion or addition when Groups are collapsed or expanded again.

    In "virtual" OwnerDraw- or "OwnedData"-mode there's just no need for any
    such actions, since what an OwnerDrawn List-Control only needs to know
    (when Groups or Nodes are collapsed/expanded), is the new ListCount ... (so
    that the Control can adjust its V-Scrollbar, perform a Refresh - and that's it).

    On the User-end (in the OwnerDraw-Events) you can then skip the collapsed
    Members in your DataContainer as you like (as needed) ... according to the
    new List-Count you calculated priorily -> and set the ownerdrawn Control to.

    The Demo which produced the ScreenShot above, is based on the cwVList-
    Widget of my RichClient-stuff - working in conjunction with an RC5-cCollection
    as the (two Column) DataContainer.
    VList_GroupDemo.zip

    But as said, roughly the same output could be accomplished also with
    an MS-Scripting-Dictionary as replacement for the cCollection - and
    with any simple Virtual-List-Control (as replacement for the cwVList-
    Widget). I think "The Trick" posted a nice one (with a still small and
    managable codebase) into the CodeBank recently.

    In case you don't plan to use the RichClient in the near future, let me know -
    could help you then, to implement a similar Demo with some other virtual List
    (or for the virtual Mode of your Grid).

    Personally I don't consider these "heavy Grid-Controls" (as I have the feeling
    you're attempting to write) a good idea.

    All one ever needs (for Lists, Trees, TreeLists) is a simple VirtualList-Ctl,
    which offers just a decent Scrolling-Support - and reliably throws the
    few Events one needs at the outside:
    - Click
    - MouseMove
    - OwnerDrawHeader
    - OwnerDrawItem

    Add a few Properties for Selection-Handling - and "prepared you are, for
    anything that comes your way".

    Olaf

  22. #22
    Frenzied Member
    Join Date
    Jan 2010
    Posts
    1,103

    Re: Listview - Grouping in Virtual Mode

    Look like the Cairo.Theme is independent with Windows Theme. In Windows Classic, the list is themed.

  23. #23
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,253

    Re: Listview - Grouping in Virtual Mode

    Quote Originally Posted by Jonney View Post
    Look like the Cairo.Theme is independent with Windows Theme. In Windows Classic, the list is themed.
    I think you missed the point, that we talk about OwnerDrawn Lists.

    FWIW, it took me 5 minutes, to change the output to this darker color-scheme here:



    Didn't put much efforts into the fine-tuning of that darker output of the
    same ScreenShot as further above - but an "In-App User-switchable Color-
    Scheme" is quite easy to accomplish.

    One can even write (derive) a new cTheme-Class which uses the MS-
    uxTheme.dll internally (to go with the current system-settings - at least
    for the ScrollBar in this OwnerDrawn-case) ...
    The current (Win7-like) cTheme-Class is available in the vbWidgets-Project on GitHub.


    Olaf

  24. #24

    Thread Starter
    Hyperactive Member LucasMKG's Avatar
    Join Date
    Jun 2015
    Location
    South Africa (ZAR)
    Posts
    338

    Re: Listview - Grouping in Virtual Mode

    Its VB6 installed on Windows7 Ultimate 32Bit
    - fafalone, trim down the core of showing groups in virtual groups (only whats needed, since I can't get it to work, sample code will be appreciated);
    >>> LVM_QUERYINTERFACE or LVM_SETOWNERDATACALLBACK, which one works well? and exactly how
    >>> [LPSTR_TEXTCALLBACK and I_IMAGECALLBACK] isn't that triggered when Listview is set to LVS_OWNERDATA?

    - Olaf, please implement a similar Demo with vhGrid

    LucasMKG
    i'm bloated...to much info to digest

  25. #25
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,710

    Re: Listview - Grouping in Virtual Mode

    LVM_SETOWNERDATACALLBACK didn't work for me but IListView.SetOwnerDataCallback did. I'm on Win7 too and downloaded and double checked the zip I posted... did you run the code exactly as-is? With the lvundoc.tlb in that zip, and not the one posted earlier in this thread (you have to be careful, if another instance of lvundoc.tlb still exists it would be the one registered, and VB6 would use that even if you manually selected the new one. the old one needs to be overwritten with the new one, or unregistered)

    LPSTR_TEXTCALLBACK and I_IMAGECALLBACK are ALWAYS used with LVS_OWNERDATA; but they can OPTIONALLY be used without it. With LVS_OWNERDATA not set, you can still use them for .pszText and .iImage when adding an LVITEM, and you'll still receive and can use LVN_GETDISPINFO. Only the internal behavior of the ListView is different (it will cache the data).

  26. #26
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,253

    Re: Listview - Grouping in Virtual Mode

    Quote Originally Posted by LucasMKG View Post
    - Olaf, please implement a similar Demo with vhGrid
    Can't find your vhGrid anywhere - but as said, I wouldn't try to implement
    a larger Grid-Control anymore these days... (as they come e.g. on PSC -
    most of them overly complex with "thousands of Properties" - and at least
    3K lines of code - not easy to manage ...)

    For almost any purpose it'd be enough to use a small Virtual-List-Control...

    I've posted a little Demo around a simple VList-Control I've made some years ago,
    into the Codebank here: http://www.vbforums.com/showthread.p...eeList-Demo%29

    It does basically the same thing (well, a little bit more) as the Demo I've posted further above...

    Perhaps you can use it as a base for a re-design of your current Grid-Control -
    it also has no dependencies to the RichClient (or anything else) - maybe the
    surrounding code is easier to understand this way.

    HTH

    Olaf

  27. #27

    Thread Starter
    Hyperactive Member LucasMKG's Avatar
    Join Date
    Jun 2015
    Location
    South Africa (ZAR)
    Posts
    338

    Re: Listview - Grouping in Virtual Mode

    Maybe its me or my System is malfunctioning - but I'll like to know if anyone is able to get Post#16 (VirtualGroupsDemo.zip) to show groups on their Systems?

    - fafalone omitted MAKELPARAM
    but you may add the below code to the 'mListview' module, otherwise you won't be able to 'Make Project1.exe' (groups can only show in executable file, not in IDE)

    Code:
    Code:
    Public Function MAKELONG(wLow As Long, wHigh As Long) As Long
        MAKELONG = LoWord(wLow) Or (&H10000 * LoWord(wHigh))
    End Function
    
    Private Function MAKELPARAM(wLow As Long, wHigh As Long) As Long
        MAKELPARAM = MAKELONG(wLow, wHigh)
    End Function
    
    Public Function LoWord(ByVal dwValue As Long) As Integer
    ' Returns the low 16-bit integer from a 32-bit long integer
        CopyMemory LoWord, dwValue, 2&
    End Function
    or maybe my additional code is wrong. please help

    NB: Olaf, I'm not ignoring you...currently I can't multitask, I need to focus on onething at a time.

    LucasMKG
    frustrated
    Last edited by LucasMKG; Nov 9th, 2015 at 01:42 AM.

  28. #28
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,710

    Re: Listview - Grouping in Virtual Mode

    Quote Originally Posted by LucasMKG View Post
    (groups can only show in executable file, not in IDE)
    wat

    it requires a manifest. if the IDE is manifested it works in the IDE too. Use the resource file option.. an external one didn't work for me.

    edit: attached is a manifested version...
    Attached Files Attached Files
    Last edited by fafalone; Nov 9th, 2015 at 03:08 AM.

  29. #29

    Thread Starter
    Hyperactive Member LucasMKG's Avatar
    Join Date
    Jun 2015
    Location
    South Africa (ZAR)
    Posts
    338

    Re: Listview - Grouping in Virtual Mode

    fafalone (your a genius),
    It worked when I added 'resManifest.res from the manifest link you provided' and 'Made Project1.exe' Yeah! I'm happy now.

    - Now I'm busy learning how to manifest the IDE ::: http://vbnet.mvps.org/index.html?cod...vbidevista.htm

    Thanks fafalone

    LucasMKG
    now I'm happy...much progress.

  30. #30
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,710

    Re: Listview - Grouping in Virtual Mode

    Does it crash for you if you click on an item, then click on another item?

  31. #31

    Thread Starter
    Hyperactive Member LucasMKG's Avatar
    Join Date
    Jun 2015
    Location
    South Africa (ZAR)
    Posts
    338

    Re: Listview - Grouping in Virtual Mode

    fafalone,

    YES, it crushes...by just one-click.

    LucasMKG
    loving VB6...

  32. #32

    Thread Starter
    Hyperactive Member LucasMKG's Avatar
    Join Date
    Jun 2015
    Location
    South Africa (ZAR)
    Posts
    338

    Re: Listview - Grouping in Virtual Mode

    manifest the IDE ::: http://vbnet.mvps.or/index.html?cod...vbidevista.htm

    -I'm stuck on Step 12 ... since Step 13 requires Visual C which I don't have, will c++ work for step 13

    LucasMKG
    running VB6 on Windows 7 Ultimate 32Bit...Yeah!

  33. #33
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,710

    Re: Listview - Grouping in Virtual Mode

    For the IDE I haven't had any problems with an external manifest... just put vb6.exe.manifest in the same folder as vb6.exe
    Attached Files Attached Files

  34. #34

    Thread Starter
    Hyperactive Member LucasMKG's Avatar
    Join Date
    Jun 2015
    Location
    South Africa (ZAR)
    Posts
    338

    Re: Listview - Grouping in Virtual Mode

    fafalone,
    - I put vb6.exe.manifest in the same folder as vb6.exe and it does nothing.
    - VirtualGroups: did you figure out why it crash, when clicked twice?

    LucasMKG
    to fafalone, for achieving VB6 (groups_in_virtual_mode) :::: Much Respect - I Salute
    Last edited by LucasMKG; Nov 10th, 2015 at 06:09 AM.

  35. #35

    Thread Starter
    Hyperactive Member LucasMKG's Avatar
    Join Date
    Jun 2015
    Location
    South Africa (ZAR)
    Posts
    338

    Re: Listview - Grouping in Virtual Mode

    fafalone,

    here http://www.codeproject.com/Articles/...o-Use-ListView . . . in file 'ObjectListView\Implementation\VirtualGroups.cs',
    has the following code:
    Code:
            #region IOwnerDataCallback Members
    
            public void GetItemPosition(int i, out NativeMethods.POINT pt) {
                //System.Diagnostics.Debug.WriteLine("GetItemPosition");
                throw new NotSupportedException();
            }
    
            public void SetItemPosition(int t, NativeMethods.POINT pt) {
                //System.Diagnostics.Debug.WriteLine("SetItemPosition");
                throw new NotSupportedException();
            }
    
            public void GetItemInGroup(int groupIndex, int n, out int itemIndex) {
                //System.Diagnostics.Debug.WriteLine(String.Format("-> GetItemInGroup({0}, {1})", groupIndex, n));
                itemIndex = this.olv.GroupingStrategy.GetGroupMember(this.olv.OLVGroups[groupIndex], n);
                //System.Diagnostics.Debug.WriteLine(String.Format("<- {0}", itemIndex));
            }
    
            public void GetItemGroup(int itemIndex, int occurrenceCount, out int groupIndex) {
                //System.Diagnostics.Debug.WriteLine(String.Format("GetItemGroup({0}, {1})", itemIndex, occurrenceCount));
                groupIndex = this.olv.GroupingStrategy.GetGroup(itemIndex);
                //System.Diagnostics.Debug.WriteLine(String.Format("<- {0}", groupIndex));
            }
    
            public void GetItemGroupCount(int itemIndex, out int occurrenceCount) {
                //System.Diagnostics.Debug.WriteLine(String.Format("GetItemGroupCount({0})", itemIndex));
                occurrenceCount = 1;
            }
    
            public void OnCacheHint(NativeMethods.LVITEMINDEX from, NativeMethods.LVITEMINDEX to) {
                //System.Diagnostics.Debug.WriteLine(String.Format("OnCacheHint({0}, {1}, {2}, {3})", from.iGroup, from.iItem, to.iGroup, to.iItem));
                this.olv.GroupingStrategy.CacheHint(from.iGroup, from.iItem, to.iGroup, to.iItem);
            }
    does this alter anything...especially 'OnCacheHint', might have to do with mouse click.

    LucasMKG
    excited on the progress made < implementation of virtual groups in VB6>

  36. #36
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,710

    Re: Listview - Grouping in Virtual Mode

    I tried returning E_NOTIMPL for OnCacheHint and the other ones that are blank (you do some complicated memory stuff to redirect the call to a function, since you can only have subs in the class implementation).

    The code that is at fault has been identified, but since it's in comctl32.dll I don't know how to not cause the error.

    Edit: Unfortunately I may have jumped the gun. It's crashing out if you click the listview more than once, and I haven't got the faintest idea of how that might be corrected. Scrolling, collapsing and expanding groups, item images, columns, and everything else is all working fine.. no idea what's going on. I've tried not calling DefSubclassProc after LVN_GETDISPINFO, I've tried returned E_NOTIMPL on the blank functions, and a few other things to no avail.
    The access violation occurs at >comctl32.dll!CLVDrawManager::InvalidateSelectedOrCutOwnerData() + 0x11e63 bytes
    if that means anything to anyone



    -------------------------------
    Edit: Taking a break and looking at things fresh sometimes helps. After taking another look at OnCacheHint, just on hunch I tried a solution similar to one that had worked on previous interface that had mysterious crashes, but I hadn't thought to try since it wasn't for an implemented interface, and the variables here are untouched. The LVITEMINDEX items are supposed to be passed ByVal, but VB doesn't allow this. So instead of passing 2 LVITEMINDEX's, I passed the 4 Long's that make up the members. That unexpectedly got rid of the crashes.
    (and before you believe this is a rule that was just overlooked, it's not... even within this class notice how the POINT structure with its two longs has no such problem.. indeed the list is Interfaces With This Problem: IOwnerDataCallback, IShellItemImageFactory; Interfaces Without This Problem: Every other interface I've ever encountered that uses a strcuture)

    Edit2: Cleaned up version posted in Code Bank. [VB6, Vista+] Undocumented ListView feature: Groups in Virtual Mode

    Next up: Subitem and Group Header editing, which make virtual groups look like Hello World.
    Attached Files Attached Files
    Last edited by fafalone; Nov 11th, 2015 at 05:51 AM.

  37. #37

    Thread Starter
    Hyperactive Member LucasMKG's Avatar
    Join Date
    Jun 2015
    Location
    South Africa (ZAR)
    Posts
    338

    Re: Listview - Grouping in Virtual Mode

    Quote Originally Posted by fafalone View Post

    Next up: Subitem and Group Header editing, which make virtual groups look like Hello World.
    EDIT:::I'll be waiting for that...and don't forget Footer + footer_buttons
    ...for now I'll mark this thread partially resolved::

    LucasMKG
    still on VB6 and growing stronger
    Last edited by LucasMKG; Nov 11th, 2015 at 07:54 AM.

  38. #38
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,710

    Re: [PARTIALLY RESOLVED] Listview - Grouping in Virtual Mode

    Footer buttons were the first thing I did: [VB6, Vista+] Undocumented ListView feature: Footer items.. you can use the lvundoc.tlb from virtual groups instead of the one attached to that project; lvundoc.tlb contains all of the listview interfaces.

  39. #39

    Thread Starter
    Hyperactive Member LucasMKG's Avatar
    Join Date
    Jun 2015
    Location
    South Africa (ZAR)
    Posts
    338

    Re: [PARTIALLY RESOLVED] Listview - Grouping in Virtual Mode

    howto set varying group.citems for virtual groups
    - if i set varying group.citems for different groups (i.e. group 1..citems = 5; group 2 citems = 3; group3 citems 1)...some invalid items are drawn(additional icon + invalid unicode name...which are unclickable and unselectable) to makeup for the specified number of items.

    LucasMKG
    loving VB6

  40. #40
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,710

    Re: [PARTIALLY RESOLVED] Listview - Grouping in Virtual Mode

    When you set cItems you need to be sure you can respond to that number of items in a few different places. That's a major issue with the sample project, everything is so hard-coded around a fixed number of items.

    -You need to make sure LVN_GETDISPINFO returns the text for the item (and its subitems if in report mode)
    -IOwnerDataCallback.GetItemGroup code in the demo project is completely useless outside of the demo... you need to assign the correct number of items to each group
    -GetItemInGroup is going to be trouble. It gives you the zero-based group index, and the zero-based item number within that group, and based on that you need to return the absolute item index. The existing code for that function is useless outside the demo too. I'm not too lucid at the moment so maybe there's a better way; but one way would be to not only have a list of items, but a list of groups too, and when you add an item record the new position in that group (current group item count + 1), then you could look it up like pTotalItemIndex = groupitems(groupindex).itemindex(groupwideitemindex)

    Given how much work was put into the original demo, I don't understand why it uses mathematical tricks that only work for 33, 333, 999 etc items assigned in a specific way. I was so concerned with just getting it working that I didn't worry about it.
    Last edited by fafalone; Nov 13th, 2015 at 03:34 AM.

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width