使用C#/ F#中的IColumnManager获取/设置列

问题描述 投票:0回答:1

我想在详细信息视图中获取并设置可见列。我有一个shell扩展(用第三方库实现),当用户右键单击文件夹背景时,我在上下文菜单中添加一个菜单项。通过将IObjectWithSite添加到我的扩展,我已经能够获得IColumnManager的接口。

在www.pinvoke.net上没有IColumnManager的声明,并且我在.NET中找到的唯一一个调用它的例子是BExplorer的一个已经不存在的分支。基于此,我得到了GetColumnCount()。

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

(我在F#工作。但是现在我用C#来声明接口和结构)。

看起来我的下一步是通过调用GetColumns()来获取PROPERTYKEY数组。这被定义为

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);

以下是从C ++开始的一个例子,取自http://blogs3805.rssing.com/chan-16291381/all_p568.html

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

BExplorer为GetColumns提供此功能:

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

但在我看来,这里需要SizeParamIndex,因为我正在编组一个数组。所以我也试过了

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

两者都不起作用。当我这样做

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

我得到一个带有HResult = 0x80004003的System.AccessViolationException。

winapi f# shell-extensions
1个回答
0
投票

我的问题是,在使用IColumnManager的C#接口声明烦躁时,我改变了两个函数的顺序。函数的顺序必须与运行时在vtable中找到的顺序相匹配。

© www.soinside.com 2019 - 2024. All rights reserved.