Results 1 to 24 of 24

Thread: [VB6, Vista+] Undocumented ListView feature: Footer items

  1. #1

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,625

    [VB6, Vista+] Undocumented ListView feature: Footer items

    Name:  lvftr3.jpg
Views: 456
Size:  56.5 KBName:  lvftr2.jpg
Views: 443
Size:  15.7 KBName:  lvftr.jpg
Views: 362
Size:  29.5 KB
    Pic 1: In production app. Pic 2: Standard Comctl 6+ LV. Pic 3: VB default 5.0 LV
    Undocumented ListView Features : Part 1 - Footer Items
    See Also: Part 2 - Subsetted Groups | Part 3 - Groups With Virtual Mode | Part 4 - Column Backcolor | Part 5 - Explorer-style selection


    This project was updated on 26 Feb 2016. There's several bits of additional information throughout this post, then see the bottom of this post for details of the new demo project.

    Ran across this nifty thing on codeproject, and successfully got it working in VB.

    Tested and working with 5.0 ListView and API ListView (it will also work on krool's Common Control Replacement ListView), have not tried with 6.0 ListView and presumably it wouldn't work (Windows Common Controls 5.0 is actually the more modern control due to linkage with the real comctl32.dll, and required for a lot of modern features like this and group view). The items are present and displayed the same way in all views, including tile and group view modes.

    This one is a little complicated to set up, but straightforward to use. First, it requires a type library with the undocumented interfaces IListViewFooter and IListViewFooterCallback, then the latter has to be implemented by a class module. From there, more undocumented goodness: LVM_SETIMAGELIST with a wParam of 4 will set the icons used in the footer, and LVM_QUERYINTERFACE retrieves an instance of IListViewFooter.
    For the purposes of this code, I'll assume you have a ListView set up already. I use the system imagelist, but you can assign any imagelist (well, api imagelist.. also note that while technically you can use icons larger than 16x16, the focus/highlight rectangle and text will not adjust so it won't look good):

    Code:
    Public Const IID_IListViewFooter = "{F0034DA8-8A22-4151-8F16-2EBA76565BCC}"
    Public Const LVM_QUERYINTERFACE = (LVM_FIRST + 189)
    Public Declare Function CLSIDFromString Lib "ole32" (ByVal lpszGuid As Long, pGuid As Any) As Long
    Public Type GUIDA
       Data1 As Long
       Data2 As Integer
       Data3 As Integer
       Data4(7) As Byte
    End Type
    Public m_himlSysSmall As Long
    Public Function GetFileTypeIconIndex(ext As String) As Long
      Dim sfi As SHFILEINFO
      Dim pidl As Long
    If SHGetFileInfo(ext, FILE_ATTRIBUTE_NORMAL, sfi, Len(sfi), SHGFI_SYSICONINDEX Or SHGFI_SMALLICON Or SHGFI_USEFILEATTRIBUTES) Then
        GetFileTypeIconIndex = sfi.iIcon
      End If
    End Function
    The code to insert items can be placed wherever, but it won't show until there's items in the ListView.
    Code:
      m_himlSysSmall = GetSystemImagelist(SHGFI_SMALLICON)
        Call SendMessage(ListView1.hWnd, LVM_SETIMAGELIST, 4, ByVal m_himlSysSmall)
    
    Dim pLVF As IListViewFooter
    Dim pFtrCB As cLVFooterCallback
    Set pFtrCB = New cLVFooterCallback
    Dim iidLVF As GUIDA
    Call CLSIDFromString(StrPtr(IID_IListViewFooter), iidLVF)
    
    Call SendMessage(hLVS, LVM_QUERYINTERFACE, VarPtr(iidLVF), pLVF)
    If (pLVF Is Nothing) Then
        Debug.Print "Failed to get LV Footer interface"
        Exit Sub
    End If
    Dim lFtrIco As Long
    lFtrIco = GetFileTypeIconIndex(".jpg") 'just an example, it's a standard index for the assigned image list.
    With pLVF
        .SetIntroText "Intro text - hello!"
        .InsertButton 0, "Test Item 1", "Alt", lFtrIco, 2000
        .Show pFtrCB
    End With
    '2000' - the lParam - has no special meaning, you can store whatever Long you want there. NOTE: It must not be 0, otherwise the buttonclick/buttondelete callback events won't fire.
    UPDATE: I finally figured out what that second string argument for .InsertButton is: an alternate text that is displayed when there's not enough room for the first string. It will only show up if it has the same or fewer number of characters.

    The attached ZIP contains the typelib, the typelib source code, a batch file to compile it from a standard VS6 install, and the class module implementing the callback. I didn't bother will a full fledged example because presumably anyone interested in this would be adding it onto an already well set-up ListView, but if really needed let me know.

    Coming up next in the world of undocumented ListView: subsetted groups (link for "Display all x items"), subitem label editing, and if I'm particularly ambitious.. apparently you can use groups in full virtual mode.

    2015-11-20 UPDATE: It turns out you can indeed have more than 4 items. You can't specify a position >3, but you can insert at 0-3 again and the new button is inserted at that position. So for example you if you always use 0 for InsertAt, just add as many buttons as you want in reverse order (add the button you want first last).
    A couple practical limits tho; there's no way to get a second row, and >4 results in squeezing to fit the listview width (but icon will always show).

    2016-02-26 UPDATE: I made a demo project for another user in another thread, and thought I would add it here as well. It shows how you can include the IListViewFooterCallback interface inside an existing UserControl. The UserControl in the project contains a 5.0 ListView that shows the adding of footer items and how to assign the system imagelist to those items. It also uses SetWindowTheme to get the light-blue item highlighting like in the first two screenshots at the top; without the theme it looks like the 3rd.

    footertest.zip includes both the new demo project and an updated TLB (lvundoc.tlb - a single typelib for all the undocumented listview projects, source included).

    lvfooter.zip is the original attachment to this thread, and includes just the simple TLB for only footer items, the source of that, and a sample class module for IListViewFooterCallback


    NOTE (15 May 2018): All of lvundoc.tlb (and lvfooter) are included in oleexp.tlb as of version 4.42. So if your project has that version or higher, you don't need the TLBs in this thread. The types have been standardized however so the code needs to be updated to run with that (i.e. LGUID now is the standard UUID instead, LPROPKEY is PROPERTYKEY, and the 'tag' has been dropped from the ListView types). The switch is optional; I'm still going to leave the standalone TLBs here.
    Attached Files Attached Files
    Last edited by fafalone; Jan 25th, 2022 at 01:20 AM. Reason: Added link to Part 5

  2. #2

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,625

    Re: [VB6, Vista+] Undocumented ListView feature: Footer items

    For reference.. these are in the zip but I thought I'd put them up here too.
    Interface def:
    Code:
    [
        odl,
        uuid(88EB9442-913B-4AB4-A741-DD99DCB7558B)
    ]
    interface IListViewFooterCallback : stdole.IUnknown
    {
    	HRESULT OnButtonClicked(
    		[in] int itemIndex,
    		[in] LONG lParam,
    		[in, out] LONG *pRemoveFooter);
    	HRESULT OnDestroyButton(
    		[in] int ItemIndex,
    		[in] LONG lParam);
    }
    
    [
        odl,
        uuid(F0034DA8-8A22-4151-8F16-2EBA76565BCC)
    ]
    interface IListViewFooter : stdole.IUnknown
    {
    	HRESULT IsVisible(
    		[in] LONG pVisible);
    	HRESULT GetFooterFocus(
    		[out] LONG *pItemIndex);
    	HRESULT SetFooterFocus(
    		[in] LONG pItemIndex);
    	HRESULT SetIntroText(
    		[in] LPWSTR pText);
        HRESULT Show(
    		[in] IListViewFooterCallback *pCallbackObject);
    	HRESULT RemoveAllButtons();
    	HRESULT InsertButton(
    		[in] int insertAt,
    		[in] LPWSTR pText,
    		[in] LPWSTR pUnknown,
    		[in] LONG iconIndex,
    		[in] LONG lParam);
    	HRESULT GetButtonLParam(
    		[in] int itemIndex,
    		[out] LONG *lParam);
    }
    and class:
    Code:
    Option Explicit
    
    Implements IListViewFooterCallback
    
    Public Sub IListViewFooterCallback_OnButtonClicked(ByVal itemIndex As Long, ByVal lParam As Long, pRemoveFooter As Long)
    Debug.Print "Get footer button click, index=" & itemIndex & ",lparam=" & lParam
    End Sub
    Public Sub IListViewFooterCallback_OnDestroyButton(ByVal itemIndex As Long, ByVal lParam As Long)
    
    End Sub

  3. #3
    Hyperactive Member LucasMKG's Avatar
    Join Date
    Jun 2015
    Location
    South Africa (ZAR)
    Posts
    338

    Re: [VB6, Vista+] Undocumented ListView feature: Footer items

    Quote Originally Posted by fafalone View Post
    Coming up next in the world of undocumented ListView: subsetted groups (link for "Display all x items"), subitem label editing, and if I'm particularly ambitious.. apparently you can use groups in full virtual mode.
    It seems you were ambitious enough...you did it 'GROUPS IN FULL VIRTUAL MODE'..yeah!

    - Can you have more than one instance of 'FooterWorkArea' (meaning one for every Group created)?

    LucasMKG
    going through fafalone's archives..for solutions

  4. #4

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,625

    Re: [VB6, Vista+] Undocumented ListView feature: Footer items

    Not with this method no. Would have to be all custom drawing.

  5. #5
    Hyperactive Member LucasMKG's Avatar
    Join Date
    Jun 2015
    Location
    South Africa (ZAR)
    Posts
    338

    Re: [VB6, Vista+] Undocumented ListView feature: Footer items

    Quote Originally Posted by fafalone View Post
    Not with this method no. Would have to be all custom drawing.
    - all custom drawing, share some light.

    LucasMKG
    curious...(...and what did the cat exactly do to curiosity? lol)

  6. #6

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,625

    Re: [VB6, Vista+] Undocumented ListView feature: Footer items

    As in, you'd have to draw absolutely everything yourself with graphics apis. You wouldn't even be using IListviewFooter, instead you'd be using DrawText, DrawIcon, etc.

  7. #7
    Hyperactive Member LucasMKG's Avatar
    Join Date
    Jun 2015
    Location
    South Africa (ZAR)
    Posts
    338

    Re: [VB6, Vista+] Undocumented ListView feature: Footer items

    I would like to toggle between IListViewFooter.Show and (IListViewFooter.Hide [currently, not existing] ), and i don't want to remove any button (in this case referring to 'RemoveAllButtons')

    IListViewFooter...has IsVisible and when is set to false...listview hangs

    - since IListViewFooter has 'Show'...can the Hide feature be inserted (since i can't edit 'lvundoc.tlb').

    LucasMKG
    !
    Last edited by LucasMKG; Feb 24th, 2016 at 04:21 AM.

  8. #8

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,625

    Re: [VB6, Vista+] Undocumented ListView feature: Footer items

    The type libraries are like APIs... they call methods in other modules. All the existing functions are included; if it's not already there it doesn't exist. But FWIW, the download does include the source to lvundoc.tlb and can be edited-- but look at the source and you'll see how it works.

    What is the problem with just removing all the buttons to hide it (the entire thing is hidden then; the header line/text too)? You could make them module-level so you don't have to rebuild them from scratch; although it's so very few lines of code I can't see the dilemma.

    IsVisible is read-only; you have to pass a variable (a Long) using VarPtr().


    Edit: I don't recall how exactly it happened, I somehow forgot to include the lvundoc.tlb source in most of the downloads that used it. Attached is the most recent version/source of it/example callback classes. Sorry it's the one time I've forgotten to include TLB source.
    Attached Files Attached Files
    Last edited by fafalone; Feb 25th, 2016 at 02:30 AM.

  9. #9
    Hyperactive Member LucasMKG's Avatar
    Join Date
    Jun 2015
    Location
    South Africa (ZAR)
    Posts
    338

    Re: [VB6, Vista+] Undocumented ListView feature: Footer items

    - in the 'cLVOwnerDataCB' you've added the 'glbRes(iItem).lGroup'...of which in the 'VirtualGroupsDemoAdvanced' doesn't feature. -> i guess the demo has to be updated.

    - to terminate virtual groups interface...i simply insert this line
    Code:
    'If Not (cLVODC is Nothing) Then Set cLVODC = Nothing'
    LucasMKG

  10. #10

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,625

    Re: [VB6, Vista+] Undocumented ListView feature: Footer items

    It's just meant as an example; what's important is the function declarations so to make sure it matched the TLB version the class came from my production project rather than the demo; the demo is still pGroupIndex = VLItems(iItem).iGrp.

    If you're switching out of virtual mode you have to destroy and recreate the entire ListView since LVS_OWNERDATA must be set in the CreateWindowEx call.. but yeah if you're just switching to non-grouped but still virtual just kill the class like that.

  11. #11
    Hyperactive Member LucasMKG's Avatar
    Join Date
    Jun 2015
    Location
    South Africa (ZAR)
    Posts
    338

    Re: [VB6, Vista+] Undocumented ListView feature: Footer items

    got it

    LucasMKG
    I'm hopelessly addicted to VBForums...somebody stop/help me.

  12. #12
    PowerPoster
    Join Date
    Jun 2012
    Posts
    2,371

    Re: [VB6, Vista+] Undocumented ListView feature: Footer items

    Is there a way to implement IListViewFooterCallback without a type lib? Because I want to maintain backward compatibility.

  13. #13

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,625

    Re: [VB6, Vista+] Undocumented ListView feature: Footer items

    What do you mean by backwards compatibility in this case? XP?

    The interface could exist in the typelib, and have a class module implementing it, and still run on XP as long as it wasn't called. Edit: In fact I just fired up the XP VM and you can even have the callback implemented inside a UserControl, and it won't cause a problem.

    Not sure there's any other way to go about it in this case. How would you even get IListViewFooter, nevermind worrying about the callback. It's one thing to simulate things by calling the v-table manually with DispCallFunc, but here it has to be retrieved via SendMessage LVM_QUERYINTERFACE.. so I'm not even sure you could cast it to stdole.IUnknown and call by offset. Then after that I'm even less confident in being able to build the callback on IUnknown as I've never even seen such a thing done before.
    Last edited by fafalone; Feb 26th, 2016 at 05:54 AM.

  14. #14
    PowerPoster
    Join Date
    Jun 2012
    Posts
    2,371

    Re: [VB6, Vista+] Undocumented ListView feature: Footer items

    Quote Originally Posted by fafalone View Post
    What do you mean by backwards compatibility in this case? XP?

    The interface could exist in the typelib, and have a class module implementing it, and still run on XP as long as it wasn't called. Edit: In fact I just fired up the XP VM and you can even have the callback implemented inside a UserControl, and it won't cause a problem.

    Not sure there's any other way to go about it in this case. How would you even get IListViewFooter, nevermind worrying about the callback. It's one thing to simulate things by calling the v-table manually with DispCallFunc, but here it has to be retrieved via SendMessage LVM_QUERYINTERFACE.. so I'm not even sure you could cast it to stdole.IUnknown and call by offset. Then after that I'm even less confident in being able to build the callback on IUnknown as I've never even seen such a thing done before.
    Creating IListViewFooter is not a problem, cast LVM_QUERYINTERFACE to IUnknown then calling via DispCallFunc. This is working. (CoCreateInstance with IID_IListViewFooter is not needed as the ListView already have an instance you just retrieve it by LVM_QUERYINTERFACE)

    I was just wondering if there is a way also with IListViewFooterCallback. But that seems very difficult as it has to be 'Implement'.
    But if you are saying it does not cause any compatibility issues to implement IListViewFooterCallback via type lib then I might consider this way. (Haven't tested yet on my own on XP so I was not aware)
    Last edited by Krool; Feb 26th, 2016 at 06:48 AM.

  15. #15

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,625

    Re: [VB6, Vista+] Undocumented ListView feature: Footer items

    Yeah it's ok to have a control/class implement it in XP. On XP, the LVM_QUERYINTERFACE call will smoothly fail (pLVF or pUnk object will = Nothing; it's not a crash or error), so you can cancel out of IListViewFooter calls from there, and nothing related to IListViewFooterCallback is ever called- and the uncalled 'Implements' statement never even raises an error since it never gets to the point of checking with the system whether the interface exists or not, and since it is defined in the typelib it exists as far as running/compiling is concerned. Verified on XP SP3 (IDE was manifested; and I compiled the test without a manifest and got the same result).
    Since your ListView is already using a typelib, it's definitely better to just throw in the definition there.
    Code:
    [
        odl,
        uuid(88EB9442-913B-4AB4-A741-DD99DCB7558B)
    ]
    interface IListViewFooterCallback : stdole.IUnknown
    {
    	HRESULT OnButtonClicked(
    		[in] int itemIndex,
    		[in] LONG lParam,
    		[in, out] LONG *pRemoveFooter);
    	HRESULT OnDestroyButton(
    		[in] int ItemIndex,
    		[in] LONG lParam);
    }
    If you still do want to pursue the other way; what about just putting it on top of IUnknown.. have the class use 'Implements IUnknown' and then just use DispCallFunc like elsewhere. You'd have to include implementations of the 3 IUnknown methods, but that at least I have seen done in VB before. But I'd really advise against it, as there's no compatibility problems with uncalled interfaces (you could have used IListViewFooter from a typelib too; it's same deal, LVM_QUERYINTERFACE's lParam object =Nothing, and you just skip over).


    Edit: To further verify, I added Implements IListViewFooterCallback and the two prototypes right into your latest ListView.ctl on XP, and it ran fine with no errors.
    Last edited by fafalone; Feb 26th, 2016 at 11:42 PM.

  16. #16
    Hyperactive Member LucasMKG's Avatar
    Join Date
    Jun 2015
    Location
    South Africa (ZAR)
    Posts
    338

    Re: [VB6, Vista+] Undocumented ListView feature: Footer items

    ...for the above discussion, this might help;
    ©ucListView.ctl: Original by Carles P.V. (*) Modified by Raul338 (raul338@elhacker.net)
    ' CallInterface Function by AndRAY (To remove TLB and module)
    '
    ' From Original post "ITaskBarList3 (implementing Windows 7 taskbar features)"
    '
    ' http://www.planetsourcecode.com/vb/s...xtCodeId=72856
    LucasMKG
    allover VBForums....
    Last edited by LucasMKG; Mar 3rd, 2016 at 01:59 AM.

  17. #17
    Hyperactive Member LucasMKG's Avatar
    Join Date
    Jun 2015
    Location
    South Africa (ZAR)
    Posts
    338

    Re: [VB6, Vista+] Undocumented ListView feature: Footer items

    ...for now,
    Code:
    'In UserControl
    'Seal.added.based on ©fafalone : cLVFooterCallback - IListViewFooterCallback
    Public Property Let FooterAreaButtonFocus(lItemIndex As Long)
        If Not (m_lHGHwnd = 0) Then
            If Not (pLVF Is Nothing) Then m_lFooterAreaButtonFocus = pLVF.SetFooterFocus(lItemIndex)
        End If
    End Property
    
    'In Form
    Private Sub cmdFooterAreaButtonFocus_Click()
        With ucVHGrid1
            .FooterAreaButtonFocus = 2
        End With
    End Sub
    , triggers this error 'Error: Expected Function or variable'

    LucasMKG
    rolling like that....
    Last edited by LucasMKG; Mar 3rd, 2016 at 02:00 AM.

  18. #18

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,625

    Re: [VB6, Vista+] Undocumented ListView feature: Footer items

    SetFooterFocus is treated by VB as a sub, so it has no return value you can assign to m_lFooterAreaButtonFocus

    Regarding ITaskbarList, the buttons send their message through the windowproc via a WM_COMMAND; a callback interface is an entirely different animal.
    Last edited by fafalone; Mar 3rd, 2016 at 06:06 PM.

  19. #19
    Hyperactive Member LucasMKG's Avatar
    Join Date
    Jun 2015
    Location
    South Africa (ZAR)
    Posts
    338

    Re: [VB6, Vista+] Undocumented ListView feature: Footer items

    fafalone,
    brilliant...
    If Not (pLVF Is Nothing) Then pLVF.SetFooterFocus (lItemIndex)
    works fine.

    - although, I would have fancied toggling FooterArea visibility.

    LucasMKG
    cool like that..yeah

  20. #20
    Hyperactive Member LucasMKG's Avatar
    Join Date
    Jun 2015
    Location
    South Africa (ZAR)
    Posts
    338

    Re: [VB6, Vista+] Undocumented ListView feature: Footer items

    fafalone,
    - since you found 'InsertButton-pUnknown'...you might want to update the TLB with:
    Code:
    	HRESULT InsertButton(
    		[in] int insertAt,
    		[in] LPWSTR pText,
    		[in] LPWSTR pAltText
    		[in] LONG iconIndex,
    		[in] LONG lParam);
    I don't have the TLB Editor

    LucasMKG
    ....rebooting

  21. #21

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,625

    Re: [VB6, Vista+] Undocumented ListView feature: Footer items

    It'll be in the next major update (when I finally nail down subitem controls) but I'm not going to post a whole new version just for that.

    .odl files are plain text if you were feeling adventurous (although you'd still need mktyplib / midl.exe to compile into a TLB).
    Last edited by fafalone; Mar 12th, 2016 at 09:14 PM.

  22. #22
    Hyperactive Member LucasMKG's Avatar
    Join Date
    Jun 2015
    Location
    South Africa (ZAR)
    Posts
    338

    Re: [VB6, Vista+] Undocumented ListView feature: Footer items

    Quote Originally Posted by fafalone View Post
    ...if you were feeling adventurous (although you'd still need mktyplib / midl.exe to compile into a TLB).
    - I've been fiddling with the above MS-DOS Tools but they need something like language description...that's where i halted.
    - but "EditTLB.exe" is ideal but one need to buy a book (Advanced Visual Basic 6) which is no longer in print from PowerVB - I have the "EditTLBEval.exe" which is the evaluation version.

    LucasMKG
    researching...

  23. #23

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,625

    Re: [VB6, Vista+] Undocumented ListView feature: Footer items

    They're just compilers... for example see the mklv.bat file in the TLB source folder; it's used like C:\path\to\mktyplib.exe lvundocdefs.odl
    and that's it. I didn't use anything besides plain text editing for either lvundocdefs or oleexp.

  24. #24
    Hyperactive Member LucasMKG's Avatar
    Join Date
    Jun 2015
    Location
    South Africa (ZAR)
    Posts
    338

    Re: [VB6, Vista+] Undocumented ListView feature: Footer items

    thanks fafalone, (I had to figure-out MKTYPLIB related files)
    for those (like mwaa!) who opted not to install Visual C++...here is a list of files needed to run 'MKTYPLIB' successfully;

    EDIT::
    (File + File location in CD)
    C1.DLL...............VC98\BIN
    CL.EXE...............VC98\BIN
    MKTYPLIB.EXE.....VC98\BIN
    MSPDB60.DLL......VB98
    ::

    LucasMKG
    making progress...
    Last edited by LucasMKG; Mar 27th, 2016 at 01:44 AM.

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