Skip to content

Commit

Permalink
Refactor DirectDraw classes
Browse files Browse the repository at this point in the history
DirectDraw's objects can be accessed from any thread.

Change ComScope.Value to .Pointer
  • Loading branch information
JeremyKuhne committed Feb 8, 2024
1 parent 4f83294 commit 74f7ad4
Show file tree
Hide file tree
Showing 37 changed files with 255 additions and 316 deletions.
3 changes: 3 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,9 @@ dotnet_diagnostic.SYSLIB1096.severity = none
# SA1117: Parameters should be on same line or separate lines
dotnet_diagnostic.SA1117.severity = silent

# SA1627: Documentation text should not be empty
dotnet_diagnostic.SA1627.severity = silent

[*.{cs,vb}]
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_null_propagation = true:silent
Expand Down
2 changes: 2 additions & 0 deletions src/thirtytwo/Application.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public static unsafe class Application
private static ActivationContext? s_visualStylesContext;
private static Direct2dFactory? s_direct2dFactory;
private static DirectWriteFactory? s_directWriteFactory;
private static DirectWriteGdiInterop? s_directWriteGdiInterop;

internal static ActivationScope ThemingScope => new(GetStylesContext());

Expand Down Expand Up @@ -211,4 +212,5 @@ public static void EnumerateThreadWindows(

public static Direct2dFactory Direct2dFactory => s_direct2dFactory ??= new();
public static DirectWriteFactory DirectWriteFactory => s_directWriteFactory ??= new();
public static DirectWriteGdiInterop DirectWriteGdiInterop => s_directWriteGdiInterop ??= new();
}
4 changes: 2 additions & 2 deletions src/thirtytwo/Controls/ActiveXControl.ConnectionPoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public ConnectionPoint(AgileComPointer<IUnknown> control, IManagedWrapper sink)
}

IConnectionPoint* connectionPoint;
if (container.Value->FindConnectionPoint(IID.Get<TSink>(), &connectionPoint).Failed)
if (container.Pointer->FindConnectionPoint(IID.Get<TSink>(), &connectionPoint).Failed)
{
return;
}
Expand Down Expand Up @@ -60,7 +60,7 @@ protected override void Dispose(bool disposing)
using var connectionPoint = TryGetInterface(out HRESULT hr);
if (hr.Succeeded)
{
hr = connectionPoint.Value->Unadvise(_cookie);
hr = connectionPoint.Pointer->Unadvise(_cookie);
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/thirtytwo/Controls/ActiveXControl.Site.cs
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ HRESULT IOleInPlaceSite.Interface.OnInPlaceDeactivate()
HRESULT IOleInPlaceSite.Interface.DeactivateAndUndo()
{
using var inPlace = _control._instance.GetInterface<IOleInPlaceObject>();
return inPlace.Value->UIDeactivate();
return inPlace.Pointer->UIDeactivate();
}

HRESULT IOleInPlaceSite.Interface.OnPosRectChange(RECT* lprcPosRect)
Expand All @@ -201,7 +201,7 @@ HRESULT IOleInPlaceSite.Interface.OnPosRectChange(RECT* lprcPosRect)

using var inPlace = _control._instance.GetInterface<IOleInPlaceObject>();
RECT clipRect = new(int.MinValue, int.MinValue, int.MaxValue, int.MaxValue);
HRESULT hr = inPlace.Value->SetObjectRects(lprcPosRect, &clipRect);
HRESULT hr = inPlace.Pointer->SetObjectRects(lprcPosRect, &clipRect);
return HRESULT.S_OK;
}

Expand Down
12 changes: 6 additions & 6 deletions src/thirtytwo/Controls/ActiveXControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public ActiveXControl(
_instanceAsActiveObject = unknown->QueryAgileInterface<IOleInPlaceActiveObject>();

using ComScope<IOleObject> oleObject = ComScope<IOleObject>.QueryFrom(unknown);
if (oleObject.Value->GetMiscStatus(DVASPECT.DVASPECT_CONTENT, out OLEMISC status).Succeeded)
if (oleObject.Pointer->GetMiscStatus(DVASPECT.DVASPECT_CONTENT, out OLEMISC status).Succeeded)
{
_status = status;
}
Expand All @@ -53,7 +53,7 @@ public ActiveXControl(
_site = new Site(this);

IOleClientSite* site = ComHelpers.GetComPointer<IOleClientSite>(_site);
HRESULT hr = oleObject.Value->SetClientSite(site);
HRESULT hr = oleObject.Pointer->SetClientSite(site);

_typeDescriptor = new ComTypeDescriptor(_instance);
}
Expand All @@ -70,7 +70,7 @@ protected internal override bool PreProcessMessage(ref MSG message)
using var scope = activeObject.GetInterface();
fixed (MSG* msg = &message)
{
if (scope.Value->TranslateAccelerator(msg) == HRESULT.S_OK)
if (scope.Pointer->TranslateAccelerator(msg) == HRESULT.S_OK)
{
return true;
}
Expand All @@ -94,7 +94,7 @@ private void DoVerb(OLEIVERB verb, Rectangle bounds)
RECT rect = bounds;
IOleClientSite* clientSite = ComHelpers.GetComPointer<IOleClientSite>(_site);

HRESULT hr = oleObject.Value->DoVerb(
HRESULT hr = oleObject.Pointer->DoVerb(
iVerb: (int)verb,
lpmsg: (MSG*)null,
pActiveSite: clientSite,
Expand Down Expand Up @@ -147,7 +147,7 @@ void PositionChanged()
{
// Not specifically called out in the SetExtent docs, but OLE defaults are HIMETRic
Size size = PixelToHiMetric(this.GetClientRectangle().Size);
oleObject.Value->SetExtent(DVASPECT.DVASPECT_CONTENT, (SIZE*)&size);
oleObject.Pointer->SetExtent(DVASPECT.DVASPECT_CONTENT, (SIZE*)&size);
}
}

Expand All @@ -157,7 +157,7 @@ void PositionChanged()
if (hr.Succeeded)
{
RECT rect = boundsInParent;
inPlaceObject.Value->SetObjectRects(&rect, &rect);
inPlaceObject.Pointer->SetObjectRects(&rect, &rect);
}
}

Expand Down
30 changes: 15 additions & 15 deletions src/thirtytwo/Dialogs/FileDialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public HWND Handle
if (_hwnd.IsNull)
{
using var scope = Interface.GetInterface<IOleWindow>();
scope.Value->GetWindow(out _hwnd);
scope.Pointer->GetWindow(out _hwnd);
}

return _hwnd;
Expand All @@ -52,7 +52,7 @@ public bool ShowDialog()
{
using var modalScope = Application.EnterThreadModalScope();
using var fileDialog = Interface.GetInterface();
HRESULT result = fileDialog.Value->Show(Owner?.Handle ?? default);
HRESULT result = fileDialog.Pointer->Show(Owner?.Handle ?? default);
return result.Succeeded || (result == WIN32_ERROR.ERROR_CANCELLED.ToHRESULT() ? false : throw result);
}

Expand All @@ -61,13 +61,13 @@ public Options DialogOptions
get
{
using ComScope<IFileDialog> dialog = Interface.GetInterface<IFileDialog>();
dialog.Value->GetOptions(out var options);
dialog.Pointer->GetOptions(out var options);
return (Options)options;
}
set
{
using ComScope<IFileDialog> dialog = Interface.GetInterface<IFileDialog>();
dialog.Value->SetOptions((FILEOPENDIALOGOPTIONS)value);
dialog.Pointer->SetOptions((FILEOPENDIALOGOPTIONS)value);
}
}

Expand All @@ -79,15 +79,15 @@ public string FileName
get
{
using ComScope<IFileDialog> dialog = Interface.GetInterface<IFileDialog>();
dialog.Value->GetFileName(out PWSTR pszName);
dialog.Pointer->GetFileName(out PWSTR pszName);
string result = new(pszName);
Interop.CoTaskMemFree(pszName);
return result;
}
set
{
using ComScope<IFileDialog> dialog = Interface.GetInterface<IFileDialog>();
dialog.Value->SetFileName(value);
dialog.Pointer->SetFileName(value);
}
}

Expand All @@ -99,7 +99,7 @@ public string FileNameLabel
set
{
using ComScope<IFileDialog> dialog = Interface.GetInterface<IFileDialog>();
dialog.Value->SetFileNameLabel(value);
dialog.Pointer->SetFileNameLabel(value);
}
}

Expand All @@ -111,7 +111,7 @@ public string OkButtonLabel
set
{
using ComScope<IFileDialog> dialog = Interface.GetInterface<IFileDialog>();
dialog.Value->SetOkButtonLabel(value);
dialog.Pointer->SetOkButtonLabel(value);
}
}

Expand All @@ -121,7 +121,7 @@ public string DefaultFolder
{
using ComScope<IFileDialog> dialog = Interface.GetInterface<IFileDialog>();
using ComScope<IShellItem> item = Interop.SHCreateShellItem(value);
dialog.Value->SetDefaultFolder(item);
dialog.Pointer->SetDefaultFolder(item);
}
}

Expand All @@ -131,7 +131,7 @@ public string InitialFolder
{
using ComScope<IFileDialog> dialog = Interface.GetInterface<IFileDialog>();
using ComScope<IShellItem> item = Interop.SHCreateShellItem(value);
dialog.Value->SetFolder(item);
dialog.Pointer->SetFolder(item);
}
}

Expand All @@ -141,8 +141,8 @@ public string? CurrentSelection
{
using ComScope<IFileDialog> dialog = Interface.GetInterface<IFileDialog>();
using ComScope<IShellItem> item = new(null);
HRESULT result = dialog.Value->GetCurrentSelection(item);
return result.Failed ? null : item.Value->GetFullPath();
HRESULT result = dialog.Pointer->GetCurrentSelection(item);
return result.Failed ? null : item.Pointer->GetFullPath();
}
}

Expand All @@ -155,7 +155,7 @@ public Guid ClientGuid
set
{
using ComScope<IFileDialog> dialog = Interface.GetInterface<IFileDialog>();
dialog.Value->SetClientGuid(value);
dialog.Pointer->SetClientGuid(value);
}
}

Expand All @@ -165,13 +165,13 @@ public Guid ClientGuid
public void ClearClientData()
{
using ComScope<IFileDialog> dialog = Interface.GetInterface<IFileDialog>();
dialog.Value->ClearClientData();
dialog.Pointer->ClearClientData();
}

public void Close()
{
using ComScope<IFileDialog> dialog = Interface.GetInterface<IFileDialog>();
dialog.Value->Close(WIN32_ERROR.ERROR_CANCELLED.ToHRESULT());
dialog.Pointer->Close(WIN32_ERROR.ERROR_CANCELLED.ToHRESULT());
}

protected override void Dispose(bool disposing)
Expand Down
8 changes: 4 additions & 4 deletions src/thirtytwo/Dialogs/FileOpenDialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@ public IReadOnlyList<string> GetResults()
{
using ComScope<IShellItemArray> items = new(null);
using ComScope<IFileOpenDialog> dialog = Interface.GetInterface<IFileOpenDialog>();
dialog.Value->GetResults(items).ThrowOnFailure();
items.Value->GetCount(out uint count).ThrowOnFailure();
dialog.Pointer->GetResults(items).ThrowOnFailure();
items.Pointer->GetCount(out uint count).ThrowOnFailure();
string[] paths = new string[(int)count];
for (int i = 0; i < count; i++)
{
using ComScope<IShellItem> item = new(null);
items.Value->GetItemAt(0, item).ThrowOnFailure();
paths[i] = item.Value->GetFullPath();
items.Pointer->GetItemAt(0, item).ThrowOnFailure();
paths[i] = item.Pointer->GetFullPath();
}

return paths;
Expand Down
4 changes: 2 additions & 2 deletions src/thirtytwo/Support/Error.cs
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,8 @@ public static string FormatMessage(
HRESULT hr = (HRESULT)messageId;
if (hr.Failed && hr.Facility == FACILITY_CODE.FACILITY_URT)
{
// .NET HRESULT, extract the message
string? dotNetMessage = Marshal.GetExceptionForHR((int)hr)?.Message;
// .NET HRESULT, extract the message (pass -1 to ignore whatever random IErrorInfo is on the thread)
string? dotNetMessage = Marshal.GetExceptionForHR((int)hr, -1)?.Message;
if (dotNetMessage is not null)
{
return dotNetMessage;
Expand Down
10 changes: 5 additions & 5 deletions src/thirtytwo/Win32/ComHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -157,17 +157,17 @@ internal static HRESULT UnwrapAndInvoke<TThis, TInterface>(TThis* @this, Func<TI
cbLicInfo = sizeof(LICINFO)
};

factory.Value->GetLicInfo(&info);
factory.Pointer->GetLicInfo(&info);
if (info.fRuntimeKeyAvail)
{
using BSTR key = default;
factory.Value->RequestLicKey(0, &key);
factory.Value->CreateInstanceLic(null, IID.GetRef<IUnknown>(), key, out void* unknown);
factory.Pointer->RequestLicKey(0, &key);
factory.Pointer->CreateInstanceLic(null, IID.GetRef<IUnknown>(), key, out void* unknown);
return (IUnknown*)unknown;
}
else
{
factory.Value->CreateInstance(null, IID.GetRef<IUnknown>(), out void* unknown);
factory.Pointer->CreateInstance(null, IID.GetRef<IUnknown>(), out void* unknown);
return (IUnknown*)unknown;
}
}
Expand Down Expand Up @@ -203,7 +203,7 @@ public static ComScope<ITypeInfo> GetRegisteredTypeInfo(
hr.ThrowOnFailure();

ComScope<ITypeInfo> typeInfo = new(null);
typelib.Value->GetTypeInfoOfGuid(interfaceId, typeInfo).ThrowOnFailure();
typelib.Pointer->GetTypeInfoOfGuid(interfaceId, typeInfo).ThrowOnFailure();
return typeInfo;
}
}
10 changes: 4 additions & 6 deletions src/thirtytwo/Win32/Graphics/Direct2D/Brush.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,11 @@ namespace Windows.Win32.Graphics.Direct2D;

public unsafe class Brush : Resource, IPointer<ID2D1Brush>
{
public unsafe new ID2D1Brush* Pointer { get; private set; }
public unsafe new ID2D1Brush* Pointer => (ID2D1Brush*)base.Pointer;

public Brush(ID2D1Brush* brush) : base((ID2D1Resource*)brush) => Pointer = brush;

protected override void Dispose(bool disposing)
public Brush(ID2D1Brush* brush) : base((ID2D1Resource*)brush)
{
Pointer = null;
base.Dispose(disposing);
}

public static implicit operator ID2D1Brush*(Brush brush) => brush.Pointer;
}
37 changes: 13 additions & 24 deletions src/thirtytwo/Win32/Graphics/Direct2D/Direct2dFactory.cs
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
// Copyright (c) Jeremy W. Kuhne. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using Windows.Support;
using Windows.Win32.System.Com;

namespace Windows.Win32.Graphics.Direct2D;

public unsafe class Direct2dFactory : DisposableBase.Finalizable, IPointer<ID2D1Factory>
/// <summary>
/// <see cref="ID2D1Factory"/> wrapper.
/// </summary>
/// <returns/>
/// <inheritdoc cref="Interop.D2D1CreateFactory(D2D1_FACTORY_TYPE, Guid*, D2D1_FACTORY_OPTIONS*, void**)"/>
public unsafe class Direct2dFactory : DirectDrawBase<ID2D1Factory>
{
private readonly AgileComPointer<ID2D1Factory> _factory;

public unsafe ID2D1Factory* Pointer { get; private set; }

public Direct2dFactory(
D2D1_FACTORY_TYPE factoryType = D2D1_FACTORY_TYPE.D2D1_FACTORY_TYPE_SINGLE_THREADED,
D2D1_FACTORY_TYPE factoryType = D2D1_FACTORY_TYPE.D2D1_FACTORY_TYPE_MULTI_THREADED,
D2D1_DEBUG_LEVEL factoryOptions = D2D1_DEBUG_LEVEL.D2D1_DEBUG_LEVEL_NONE)
: base(Create(factoryType, factoryOptions))
{
}

private static ID2D1Factory* Create(D2D1_FACTORY_TYPE factoryType, D2D1_DEBUG_LEVEL factoryOptions)
{
ID2D1Factory* factory;
Interop.D2D1CreateFactory(
Expand All @@ -23,20 +26,6 @@ public Direct2dFactory(
(D2D1_FACTORY_OPTIONS*)&factoryOptions,
(void**)&factory).ThrowOnFailure();

Pointer = factory;

// Ensure that this can be disposed on the finalizer thread by giving the "last" ref count
// to an agile pointer.
_factory = new AgileComPointer<ID2D1Factory>(factory, takeOwnership: true);
}

protected override void Dispose(bool disposing)
{
Pointer = null;

if (disposing)
{
_factory.Dispose();
}
return factory;
}
}
Loading

0 comments on commit 74f7ad4

Please sign in to comment.