Базовый класс для всех 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.
Виртуальный выделенный сервер (VDS) становится отличным выбором
ПРОБОВАЛ ВОТ ТАК ТОЖЕ НЕ РАБОТАЕТ
значит имеем мы страничку, на ней плеер, чатпринцип работы, отправляет отрывки видео (длительностью в 2 секунды)(media
Сценарий следующий: пользователь отмечает "чекбоксами" варианты в соответствующем мета-поле в админпанели и на выходе (в зависимости от выбранного...