Базовый класс для всех COM
объектов:
public class ComObject<T> : IDisposable
{
protected T NativeObject;
protected internal ComObject(object nativeObject)
{
NativeObject = (T)nativeObject;
}
protected virtual void ReleaseUnmanagedResources()
{
if(NativeObject == default)
{
return;
}
Marshal.ReleaseComObject(NativeObject);
NativeObject = default;
}
public void Dispose()
{
ReleaseUnmanagedResources();
GC.SuppressFinalize(this);
}
}
Где T
— интерфейс IUnknown
.
Далее, есть несколько обобщенных интерфейсов таких как ID2D1Rendertarget
, ID2D1HwndRenderTarget
, ID2D1BitmapRenderTarget
и т.д.
Задача состоит в том, что мне необходимо чтобы фабрика умела создавать объекты обобщенного типа, одним методом, с несколькими перегрузками.
На данном этапе не могу решить как правильно это провернуть.
То что я надумал:
Базовый интерфейс для описанных выше интерфейсов, является интерфейс ID2D1Resource
, по моему мнению, у класса Resource
должно быть 2 перегрузки:
public class Resource : Resource<ID2D1Resource>
{
protected internal Resource(object nativeObject) : base(nativeObject)
{
}
}
public class Resource<T> : ComObject<T>
{
protected internal Resource(object nativeObject) : base(nativeObject)
{
}
public Factory Factory
{
get
{
Marshal.ThrowExceptionForHR(((ID2D1Resource)NativeObject).GetFactory(out object factoryObject));
return new Factory(factoryObject);
}
}
}
Но я считаю что здесь что-то не так как должно быть...
Как реализовать правильно такое наследование?
UPD:
На данный момент реализовал такое представление:
public class ComObject<T> : IDisposable
{
protected internal object NativeObject;
protected internal ComObject(object nativeObject)
{
NativeObject = nativeObject;
}
protected internal T2 As<T2>() => (T2)NativeObject;
protected virtual void ReleaseUnmanagedResources()
{
Marshal.ReleaseComObject(NativeObject);
}
public void Dispose()
{
ReleaseUnmanagedResources();
GC.SuppressFinalize(this);
}
}
public class Resource : ComObject<ID2D1Resource>
{
protected internal Resource(object nativeObject) :
base(nativeObject)
{
}
public ID2D1Factory Factory
{
get
{
Marshal.ThrowExceptionForHR(As<ID2D1Resource>().GetFactory(out object factoryObject));
return (ID2D1Factory)factoryObject;
}
}
}
public class RenderTarget : Resource
{
internal RenderTarget(object o) :
base(o)
{
}
public Bitmap CreateBitmap(SizeU size, IntPtr srcData, uint pitch, ref BitmapProperties bitmapProperties)
{
Marshal.ThrowExceptionForHR(As<ID2D1RenderTarget>().CreateBitmap(size, srcData, pitch, ref bitmapProperties, out object o));
return new Bitmap(o);
}
public BitmapBrush CreateBitmapBrush(Bitmap bitmap, BitmapBrushProperties bitmapBrushProperties, BitmapProperties bitmapProperties)
{
Marshal.ThrowExceptionForHR(As<ID2D1RenderTarget>().CreateBitmapBrush(bitmap.NativeObject, ref bitmapBrushProperties, ref bitmapProperties, out object o));
return new BitmapBrush(o);
}
public SolidColorBrush CreateSolidColorBrush(Color color, BrushProperties brushProperties)
{
Marshal.ThrowExceptionForHR(As<ID2D1RenderTarget>().CreateSolidColorBrush(ref color, ref brushProperties, out object o));
return new SolidColorBrush(o);
}
public SizeF Size
{
get
{
return As<ID2D1RenderTarget>().GetSize();
}
}
public SizeU PixelSize
{
get
{
return As<ID2D1RenderTarget>().GetPixelSize();
}
}
public void Clear()
{
Clear(new Color(.0f, .0f,.0f));
}
public void Clear(Color color)
{
As<ID2D1RenderTarget>().Clear(ref color);
}
public void BeginDraw()
{
As<ID2D1RenderTarget>().BeginDraw();
}
public Tags EndDraw()
{
Tags tags = new Tags();
As<ID2D1RenderTarget>().EndDraw(out tags.Tag1, out tags.Tag2);
return tags;
}
public uint MaximumBitmapSize
{
get
{
return As<ID2D1RenderTarget>().GetMaximumBitmapSize();
}
}
public Dpi Dpi
{
get
{
Dpi dpi = new Dpi();
As<ID2D1RenderTarget>().GetDpi(out dpi.X, out dpi.Y);
return dpi;
}
set
{
As<ID2D1RenderTarget>().SetDpi(value.X, value.Y);
}
}
public void DrawRectangle(RectF rect, Brush brush, float strokeWidth)
{
As<ID2D1RenderTarget>().DrawRectangle(ref rect, (ID2D1Brush)brush.NativeObject, strokeWidth);
}
public void FillRectangle(RectF rect, Brush brush)
{
As<ID2D1RenderTarget>().FillRectangle(ref rect, (ID2D1Brush)brush.NativeObject);
}
public Matrix3X2F Transform
{
get
{
As<ID2D1RenderTarget>().GetTransform(out Matrix3X2F transform);
return transform;
}
set
{
As<ID2D1RenderTarget>().SetTransform(ref value);
}
}
}
Но при таком раскладе, вызывая метод например FillRectangle
, Direct2D
засыпает окно отладки сообщениями о том что был передан не правильный ресурс.
Думаю где-то тут что-то не так.
D2D DEBUG ERROR - The given resource [069FDED0] is not of an expected type.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
ПРОБОВАЛ ВОТ ТАК ТОЖЕ НЕ РАБОТАЕТ
значит имеем мы страничку, на ней плеер, чатпринцип работы, отправляет отрывки видео (длительностью в 2 секунды)(media
Сценарий следующий: пользователь отмечает "чекбоксами" варианты в соответствующем мета-поле в админпанели и на выходе (в зависимости от выбранного...