Getting Windows Ribbon UI Framework RecentItems Pinned changes

64 Views Asked by At

So I've set up a RecentItems list with

          <ApplicationMenu.RecentItems>
            <RecentItems CommandName="cmdRecentItems" EnablePinning="true" MaxCount="7"/>
          </ApplicationMenu.RecentItems>

I can set the initial pinned status, I can read the new status if the item itself is clicked on from commandExecutionProperties, but when I try to get the status of all the items when the menu closes, I get false for every item, even the initially pinned ones.

Based on this post and this example and the SDK HTMLEdit sample (which doesn't have pinning but helped with RecentItems in general), here's what I'm doing:

    Private Sub OnRibbonCmdExecute(ByVal commandId As Long, ByVal verb As UI_EXECUTIONVERB, ByVal key As LongPtr, currentValue As Variant, ByVal bCurValWasNull As Boolean, ByVal commandExecutionProperties As IUISimplePropertySet, returnValue As Long) Handles pUIApp.OnRibbonCmdExecute
(...)
            Case IDC_RECENTITEMS
                    Dim nItem As Long
                    Dim pset As IUISimplePropertySet
                    Dim psa As LongPtr
                    Dim parray As LongPtr
                    Dim ct As Long
                    Dim pv As Variant
                    Dim blnRaw As Integer
                    If VariantUI4ToI4(currentValue, nItem) Then
                        LogMsg "Clicked Recent Items (MRU) List item " & nItem
                    End If
                    If IsEqualPKEY(pk, UI_PKEY_RecentItems) Then
                        Debug.Print "Got RecentItems pkey in cmdExec, valuetype=" & VTtoStr(VarType(currentValue))
                        If VarType(currentValue) = (VT_ARRAY Or VT_UNKNOWN) Then
                           
                            CopyMemory parray, ByVal PointerAdd(VarPtr(currentValue), 8), LenB(Of LongPtr)
                            SafeArrayCopy ByVal parray, psa
                            Dim res As Long = SafeArrayGetUBound(psa, 1, ct)
                            If res = S_OK Then
                                Dim i As Long
                                For i = 0 To ct
                                    If SafeArrayGetElement(psa, 1, pset) = S_OK Then
                                        pset.GetValue UI_PKEY_Pinned, pv
                                        Debug.Print "VarType(pv)=" & VTtoStr(VarType(pv))
                                        If VarType(pv) = VT_BOOL Then
                                            CopyMemory blnRaw, ByVal PointerAdd(VarPtr(pv), 8), 2
                                            Debug.Print "RawVal=0x" & Hex$(blnRaw)
                                        End If
                                        bMRUPinned(i) = CBool(pv)
                                        Debug.Print "Pinned(" & i & ")=" & bMRUPinned(i)
                                    End If
                                Next
                            End If
                            SafeArrayDestroy psa
                        End If
                    End If

The code is an apparent success; the debug output confirms that the count is equal to my MRU count, and that each time I'm getting a valid VT_BOOL variant. But the raw data, much like the automatic boolean handling, comes back 0 for every item every time.

There's just not a wealth of examples on this so despite looking fairly thoroughly, including a GitHub code search for UI_PKEY_Pinned, I haven't found any alternative approaches or anything to suggest why mine isn't valid.

(This is not through WinForms/.NET; the language is VB6/VBA compatible successor twinBASIC, if you're wondering why it looks just like those but has a couple syntax differences).

0

There are 0 best solutions below