Алекс Jenter - Программирование на Visual C++. Архив рассылки
- Название:Программирование на Visual C++. Архив рассылки
- Автор:
- Жанр:
- Издательство:неизвестно
- Год:неизвестен
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Алекс Jenter - Программирование на Visual C++. Архив рассылки краткое содержание
РАССЫЛКА ЯВЛЯЕТСЯ ЧАСТЬЮ ПРОЕКТА RSDN, НА САЙТЕ КОТОРОГО ВСЕГДА МОЖНО НАЙТИ ВСЮ НЕОБХОДИМУЮ РАЗРАБОТЧИКУ ИНФОРМАЦИЮ, СТАТЬИ, ФОРУМЫ, РЕСУРСЫ, ПОЛНЫЙ АРХИВ ПРЕДЫДУЩИХ ВЫПУСКОВ РАССЫЛКИ И МНОГОЕ ДРУГОЕ.
Программирование на Visual C++. Архив рассылки - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
}
[object, uuid(0002E011-0000-0000-C000-000000000046), pointer_default(unique)]
interface IEnumCATEGORYINFO : IUnknown {
HRESULT Next([in] ULONG celt,
[out, size_is(celt), length_is(*pceltFetched)] CATEGORYINFO *rgelt,
[out] ULONG *pceltFetched);
HRESULT Skip([in] ULONG celt);
HRESULT Reset();
HRESULT Clone([out] IEnumCATEGORYINFO **ppenum);
}
[object, uuid(0002E013-0000-0000-C000-000000000046), pointer_default(unique)]
interface ICatInformation : IUnknown {
HRESULT EnumCategories([in] LCID lcid,
[out] IEnumCATEGORYINFO** ppenumCategoryInfo);
HRESULT GetCategoryDesc([in] REFCATID rcatid,
[in] LCID lcid,
[out] LPWSTR* pszDesc);
[local]
HRESULT EnumClassesOfCategories([in] ULONG cImplemented,
[in,size_is(cImplemented)] CATID rgcatidImpl[],
[in] ULONG cRequired,
[in,size_is(cRequired)] CATID rgcatidReq[],
[out] IEnumCLSID** ppenumClsid);
[call_as(EnumClassesOfCategories)]
HRESULT RemoteEnumClassesOfCategories([in] ULONG cImplemented,
[in,unique,size_is(cImplemented)] CATID rgcatidImpl[],
[in] ULONG cRequired,
[in,unique,size_is(cRequired)] CATID rgcatidReq[],
[out] IEnumCLSID** ppenumClsid);
[local]
HRESULT IsClassOfCategories([in] REFCLSID rclsid,
[in] ULONG cImplemented,
[in,size_is(cImplemented)] CATID rgcatidImpl[],
[in] ULONG cRequired,
[in,size_is(cRequired)] CATID rgcatidReq[]);
[call_as(IsClassOfCategories)]
HRESULT RemoteIsClassOfCategories([in] REFCLSID rclsid,
[in] ULONG cImplemented,
[in,unique,size_is(cImplemented)] CATID rgcatidImpl[],
[in] ULONG cRequired,
[in,unique,size_is(cRequired)] CATID rgcatidReq[]);
HRESULT EnumImplCategoriesOfClass([in] REFCLSID rclsid,
[out] IEnumCATID** ppenumCatid);
HRESULT EnumReqCategoriesOfClass([in] REFCLSID rclsid,
[out] IEnumCATID** ppenumCatid);
}
C#
[ComImport, Guid("0002E000-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IEnumGUID {
[PreserveSig()]
int Next([In] uint celt,
[Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] Guid[] rgelt,
[Out] out uint pceltFetched);
[PreserveSig()]
int Skip([In] uint celt);
void Reset();
[return : MarshalAs(UnmanagedType.Interface)]
IEnumGUID Clone();
};
[ComImport, Guid("0002E011-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IEnumCATEGORYINFO {
[PreserveSig()]
int Next([In] uint celt,
[Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] CATEGORYINFO[] rgelt,
[Out] out uint pceltFetched);
[PreserveSig()]
int Skip([In] uint celt);
void Reset();
[return : MarshalAs(UnmanagedType.Interface)]
IEnumCATEGORYINFO Clone();
};
[ComImport, Guid("0002E013-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ICatInformation {
[return : MarshalAs(UnmanagedType.Interface)]
IEnumCATEGORYINFO EnumCategories([In] uint lcid);
[return : MarshalAs(UnmanagedType.LPWStr)]
String GetCategoryDesc([In] ref Guid rcatid, [In] uint lcid);
[return : MarshalAs(UnmanagedType.Interface)]
IEnumGUID EnumClassesOfCategories([In] uint cImplemented,
[In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] Guid[] rgcatidImpl,
[In] uint cRequired,
[In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=2)] Guid[] rgcatidReq);
[return : MarshalAs(UnmanagedType.Interface)]
IEnumGUID RemoteEnumClassesOfCategories([In] uint cImplemented,
[In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] Guid[] rgcatidImpl,
[In] uint cRequired,
[In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=2)] Guid[] rgcatidReq);
[PreserveSig()]
int IsClassOfCategories([In] ref Guid rclsid,
[In] uint cImplemented,
[In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] Guid[] rgcatidImpl,
[In] uint cRequired,
[In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=2)] Guid[] rgcatidReq);
[PreserveSig()]
int RemoteIsClassOfCategories([In] ref Guid rclsid,
[In] uint cImplemented,
[In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] Guid[] rgcatidImpl,
[In] uint cRequired,
[In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=2)] Guid[] rgcatidReq);
[return : MarshalAs(UnmanagedType.Interface)]
IEnumGUID EnumImplCategoriesOfClass([In] ref Guid rclsid);
[return : MarshalAs(UnmanagedType.Interface)]
IEnumGUID EnumReqCategoriesOfClass([In] ref Guid rclsid);
};
Для описания классов также используются атрибуты ComImport и Guid. Классы с атрибутом ComImport не могут иметь никаких данных и методов.
IDL
Описание отсутствует
C#
[ComImport, Guid("0002E005-0000-0000-C000-000000000046")]
public class StdComponentCategoriesMgr{};
C#
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using ComCatWrapper;
public class Test {
static void Main() {
StdComponentCategoriesMgr mgr = new StdComponentCategoriesMgr();
ICatInformation catInfoItf = (ICatInformation)mgr;
IEnumCATEGORYINFO enumCInfoItf = сatInfoItf.EnumCategories(0);
// и т.д.
}
}
Из этого примера видна еще одна особенность работы с COM-объектами в .NET: вместо привычного CoCreateInstance используется оператор new, а вместо QueryInterface используется приведение типов.
Демонстрационное приложение, демонстрирующее работу с COM-интерфейсами, написано на C#. Проект состоит из двух модулей: модуля, обеспечивающего интерфейс пользователя (файл MainForm.cs) и модуля, содержащего обертки COM-объекта (файл ComCatWrapper.cs).
Как уже упоминалось, в файле ComCatWrapper.cs содержатся описания структуры CATEGORYINFO и интерфейсов IEnumGUID, IEnumCATEGORYINFO и ICatInformation, а также кокласса StdComponentCategoriesMgr.
Файл MainForm.cs содержит код, необходимый для построения простейшего пользовательского интерфейса и использует интерфейсы из ComCatWrapper.cs.
Первоначально список категорий пуст, он заполняется при нажатии кнопки «Заполнить». Так сделано из-за того, что заполнение идет достаточно долго, а использование, например, дополнительных потоков усложнило бы логику программы.
Вся работа с COM-интерфейсами ведется в двух функциях: FillBtn_Click и FillNodes. Эти функции просты и достаточно подробно прокомментированы.
Визуально категории компонентов представляются в виде дерева следующего вида: описание категории, соответствующий ей идентификатор (CATID) и идентификаторы классов (CLSID), реализующих данную категорию.
Ниже приведен пример работы тестового приложения, использующего обертки COM-интерфейсов.
Как видим, обеспечить взаимодействие COM и .NET довольно просто для программиста на C#. Нужно только знать, какие параметры и как передавать между управляемым и неуправляемым кодом.
К сожалению, во время подготовки статьи выяснилось, что ManagedC++ и VB.NET не позволяют писать обертки для COM-объектов без использования tlb. Задание атрибута ComImport в этих языках приводит к выбрасыванию исключений при попытке создания экземпляров классов во время выполнения программы, хотя компиляция проходит без проблем. Что это – ошибка или так было задумано, я не знаю. В то же время классы-обертки, написанные на C#, можно использовать и из ManagedC++ и VB.NET.
ВОПРОС-ОТВЕТ
Как подменить функцию API?
Автор: Павел Блудов
Демонстрационное приложение (WTL Dialog) HookAPI (100kb)Требует наличия звуковой карты. Методы 3, 4 и 5 не будут работать под windows9x/ME.
Демонстрационное приложение (WTL Dialog) HookAPI2 (20kb)Требует наличия WinSockets 1.0.
#include
WINUSERAPI BOOL WINAPI MyMessageBeep(IN UINT uType) {
//Your code here
}
#define MessageBeep MyMessageBeep
Интервал:
Закладка: