Quantcast
Channel: VBForums - CodeBank - Visual Basic 6 and earlier
Viewing all articles
Browse latest Browse all 1448

[VB6, Vista+] Undocumented ListView feature: Groups in Virtual Mode

$
0
0

Well, this project has been a long time coming. Just when I thought I had it, a mysterious and difficult-to-trace crash reared its head. But that last issue has finally been resolved.

According to Microsoft, Group Mode can't be used when the ListView is in Virtual Mode-- when LVS_OWNERDATA is set. But they have confused 'can't be done' with 'undocumented and unsupported'. Through the use of undocumented interfaces, IListView and IOwnerDataCallback, I have brought grouping while in virtual mode to VB6 as a port of some excellent work by Timo Kunze. You can also thank LucasMKG here since if he hadn't kept on me to work on this and finally got me looking at OnCacheHint, this project might never have been completed.

How It Works

-A class module must implement the IOwnerDataCallback interface
-Then, the reference is set like this:
Set cLVODC = New cLVOwnerDataCB
Dim pILV As IListView
Call SendMessage(hLVVG, LVM_QUERYINTERFACE, VarPtr(IID_IListView), pILV)
pILV.SetOwnerDataCallback cLVODC

-After that, it's just a matter of creating the ListView.

Project Notes
-This project fully supports Unicode by responding to WM_NOTIFYFORMAT with NFR_UNICODE and responding to LVN_GETDISPINFOW. Currently I'm experiencing a problem with StrPtr that corrupts subitem text; I haven't had this problem before (as in, it was fine the other day with this same unchanged code) and it shouldn't effect anyone else, but if for some reason it does let me know; but when compiled the problem goes away.
-This project is mainly a proof of concept; information about the groups is hard-coded. In a real project you'll need to be careful to keep item numbers and information updated, including the .cItems LVGROUP member (which isn't read-only, it must be set), and to return the correct group information in cLVOwnerDataCB--- see below.
-You could probably apply this method to a Comctllib (5) ListView, but this project makes its own with CreateWindowEx.

Requirements
-Windows 7 or higher (for Vista, the typelib needs to be recompiled with a different IID for IListView; if anyone wants this let me know)
-lvundoc.tlb - Must be added as a reference. If you have a previous version, make sure to replace it with the one in this download.
-Common Controls 6.0 Manifest - Your project (and the IDE if you want to see groups) needs a manifest specifying 6.0 controls; see here. The demo project has a manifest built in.

Setting Group Callback Information
The demo project has these hardcoded for 99 items in 3 groups. You'll need to change that for real-world projects. Refer to the following information from Timo's project:
Quote:

/// \brief <em>Will be called to retrieve an item's zero-based control-wide index</em>
///
/// This method is called by the listview control to retrieve an item's zero-based control-wide index.
/// The item is identified by a zero-based group index, which identifies the listview group in which
/// the item is displayed, and a zero-based group-wide item index, which identifies the item within its
/// group.
///
/// \param[in] groupIndex The zero-based index of the listview group containing the item.
/// \param[in] groupWideItemIndex The item's zero-based group-wide index within the listview group
/// specified by \c groupIndex.
/// \param[out] pTotalItemIndex Receives the item's zero-based control-wide index.
///
/// \return An \c HRESULT error code.
virtual HRESULT STDMETHODCALLTYPE GetItemInGroup(int groupIndex, int groupWideItemIndex, PINT pTotalItemIndex) = 0;
/// \brief <em>Will be called to retrieve the group containing a specific occurrence of an item</em>
///
/// This method is called by the listview control to retrieve the listview group in which the specified
/// occurrence of the specified item is displayed.
///
/// \param[in] itemIndex The item's zero-based (control-wide) index.
/// \param[in] occurrenceIndex The zero-based index of the item's copy for which the group membership is
/// retrieved.
/// \param[out] pGroupIndex Receives the zero-based index of the listview group that shall contain the
/// specified copy of the specified item.
///
/// \return An \c HRESULT error code.
virtual HRESULT STDMETHODCALLTYPE GetItemGroup(int itemIndex, int occurenceIndex, PINT pGroupIndex) = 0;
/// \brief <em>Will be called to determine how often an item occurs in the listview control</em>
///
/// This method is called by the listview control to determine how often the specified item occurs in the
/// listview control.
///
/// \param[in] itemIndex The item's zero-based (control-wide) index.
/// \param[out] pOccurrencesCount Receives the number of occurrences of the item in the listview control.
///
/// \return An \c HRESULT error code.
virtual HRESULT STDMETHODCALLTYPE GetItemGroupCount(int itemIndex, PINT pOccurenceCount) = 0;
Attached Files

Viewing all articles
Browse latest Browse all 1448

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>