Getting/setting columns with IColumnManager from C#/F#

0

I want to get and set visible columns in the Details View. I have a shell extension (implemented with a 3rd party library), and I add a menu item to the context menu when the user right-clicks on the folder background. By adding IObjectWithSite to my extension, I've been able to get the interface to IColumnManager.

There is no declaration for IColumnManager on www.pinvoke.net, and the only example of calling it that I have found in .NET is in a defunct branch of BExplorer. Based on that, I got GetColumnCount() working.

let mutable colCount = 0u;
columnManager.GetColumnCount (CM_ENUM_FLAGS.CM_ENUM_VISIBLE, &colCount)

(I'm working in F#. But for now I'm using C# to declare the interfaces and structures).

It looks like my next step is to get a PROPERTYKEY array by calling GetColumns(). This is defined as

HRESULT ( STDMETHODCALLTYPE *GetColumns )( 
    __RPC__in IColumnManager * This,
    /* [in] */ CM_ENUM_FLAGS dwFlags,
    /* [size_is][out] */ __RPC__out_ecount_full(cColumns) PROPERTYKEY *rgkeyOrder,
    /* [in] */ UINT cColumns);

And here is an example doing it from C++, taken from http://blogs3805.rssing.com/chan-16291381/all_p568.html:

PROPERTYKEY *columns = new PROPERTYKEY[nColumns];
            hr = pColumnManager->GetColumns(CM_ENUM_VISIBLE, 
                                            columns, 
                                            nColumns);

BExplorer has this for GetColumns:

void GetColumns(CM_ENUM_FLAGS dwFlags, [Out] [MarshalAs(UnmanagedType.LPArray)] PropertyKey[] rgkeyOrder, uint cColumns);

But it seems to me that SizeParamIndex would be needed here, since I'm marshaling an array. So I've also tried

void GetColumns([In] CM_ENUM_FLAGS dwFlags, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] PROPERTYKEY[] columns, [In] uint colCount);

Neither one works. When I do this

let columns = Array.init (int colCount) (fun i -> PROPERTYKEY())
columnManager.GetColumns (CM_ENUM_FLAGS.CM_ENUM_VISIBLE, columns, colCount)

I get a System.AccessViolationException with HResult=0x80004003.

winapi
f#
shell-extensions
asked on Stack Overflow Apr 2, 2019 by Jim Foye

1 Answer

0

My problem was that while fidgeting with the C# interface declaration for IColumnManager, I had changed the order of two functions. The order of functions has to match the order that will be found in the vtable at runtime.

answered on Stack Overflow Apr 3, 2019 by Jim Foye

User contributions licensed under CC BY-SA 3.0