Я хочу получить и установить видимые столбцы в подробном представлении. У меня есть расширение оболочки (реализовано с помощью сторонней библиотеки), и я добавляю пункт меню в контекстное меню, когда пользователь щелкает правой кнопкой мыши на фоне папки. Добавив IObjectWithSite к моему расширению, я смог получить интерфейс для IColumnManager.
На сайте www.pinvoke.net нет объявления для IColumnManager, и единственный пример его вызова, который я нашел в .NET, находится в несуществующей ветви BExplorer. Исходя из этого, я получил GetColumnCount () работает.
let mutable colCount = 0u;
columnManager.GetColumnCount (CM_ENUM_FLAGS.CM_ENUM_VISIBLE, &colCount)
(я работаю в F #. Но сейчас я использую C # для объявления интерфейсов и структур).
Похоже, что мой следующий шаг - получить массив PROPERTYKEY, вызвав GetColumns (). Это определяется как
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)
Я получаю исключение System.AccessViolationException с HResult = 0x80004003.