diff --git a/WInterop.sln b/WInterop.sln index 37fd753d..e6fa5043 100644 --- a/WInterop.sln +++ b/WInterop.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.28729.10 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31717.71 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WInterop.Desktop", "src\WInterop.Desktop\WInterop.Desktop.csproj", "{AC918478-F510-44DD-92AE-6E0B013546F5}" ProjectSection(ProjectDependencies) = postProject @@ -126,6 +126,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Scratch", "src\Samples\OldN EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WInterop.SourceGenerators", "src\WInterop.SourceGenerators\WInterop.SourceGenerators.csproj", "{89E7FD50-13F6-45DA-8823-C3F6D38170C8}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WInterop.Winforms", "Winterop.Winforms\WInterop.Winforms.csproj", "{2ADA4398-33F9-4163-A669-54C82310EA08}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WinForms", "WinForms", "{D27AB6D6-1BE5-448C-9BAE-F0D2D89E6CDC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WinFormsDirect2D", "WinFormsDirect2D\WinFormsDirect2D.csproj", "{C37EC799-BBB5-46C7-A469-66677C316F9B}" +EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution src\Common\Common.projitems*{ac918478-f510-44dd-92ae-6e0b013546f5}*SharedItemsImports = 5 @@ -796,6 +802,38 @@ Global {89E7FD50-13F6-45DA-8823-C3F6D38170C8}.Release|x64.Build.0 = Release|Any CPU {89E7FD50-13F6-45DA-8823-C3F6D38170C8}.Release|x86.ActiveCfg = Release|Any CPU {89E7FD50-13F6-45DA-8823-C3F6D38170C8}.Release|x86.Build.0 = Release|Any CPU + {2ADA4398-33F9-4163-A669-54C82310EA08}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2ADA4398-33F9-4163-A669-54C82310EA08}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2ADA4398-33F9-4163-A669-54C82310EA08}.Debug|ARM.ActiveCfg = Debug|Any CPU + {2ADA4398-33F9-4163-A669-54C82310EA08}.Debug|ARM.Build.0 = Debug|Any CPU + {2ADA4398-33F9-4163-A669-54C82310EA08}.Debug|x64.ActiveCfg = Debug|Any CPU + {2ADA4398-33F9-4163-A669-54C82310EA08}.Debug|x64.Build.0 = Debug|Any CPU + {2ADA4398-33F9-4163-A669-54C82310EA08}.Debug|x86.ActiveCfg = Debug|Any CPU + {2ADA4398-33F9-4163-A669-54C82310EA08}.Debug|x86.Build.0 = Debug|Any CPU + {2ADA4398-33F9-4163-A669-54C82310EA08}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2ADA4398-33F9-4163-A669-54C82310EA08}.Release|Any CPU.Build.0 = Release|Any CPU + {2ADA4398-33F9-4163-A669-54C82310EA08}.Release|ARM.ActiveCfg = Release|Any CPU + {2ADA4398-33F9-4163-A669-54C82310EA08}.Release|ARM.Build.0 = Release|Any CPU + {2ADA4398-33F9-4163-A669-54C82310EA08}.Release|x64.ActiveCfg = Release|Any CPU + {2ADA4398-33F9-4163-A669-54C82310EA08}.Release|x64.Build.0 = Release|Any CPU + {2ADA4398-33F9-4163-A669-54C82310EA08}.Release|x86.ActiveCfg = Release|Any CPU + {2ADA4398-33F9-4163-A669-54C82310EA08}.Release|x86.Build.0 = Release|Any CPU + {C37EC799-BBB5-46C7-A469-66677C316F9B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C37EC799-BBB5-46C7-A469-66677C316F9B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C37EC799-BBB5-46C7-A469-66677C316F9B}.Debug|ARM.ActiveCfg = Debug|Any CPU + {C37EC799-BBB5-46C7-A469-66677C316F9B}.Debug|ARM.Build.0 = Debug|Any CPU + {C37EC799-BBB5-46C7-A469-66677C316F9B}.Debug|x64.ActiveCfg = Debug|Any CPU + {C37EC799-BBB5-46C7-A469-66677C316F9B}.Debug|x64.Build.0 = Debug|Any CPU + {C37EC799-BBB5-46C7-A469-66677C316F9B}.Debug|x86.ActiveCfg = Debug|Any CPU + {C37EC799-BBB5-46C7-A469-66677C316F9B}.Debug|x86.Build.0 = Debug|Any CPU + {C37EC799-BBB5-46C7-A469-66677C316F9B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C37EC799-BBB5-46C7-A469-66677C316F9B}.Release|Any CPU.Build.0 = Release|Any CPU + {C37EC799-BBB5-46C7-A469-66677C316F9B}.Release|ARM.ActiveCfg = Release|Any CPU + {C37EC799-BBB5-46C7-A469-66677C316F9B}.Release|ARM.Build.0 = Release|Any CPU + {C37EC799-BBB5-46C7-A469-66677C316F9B}.Release|x64.ActiveCfg = Release|Any CPU + {C37EC799-BBB5-46C7-A469-66677C316F9B}.Release|x64.Build.0 = Release|Any CPU + {C37EC799-BBB5-46C7-A469-66677C316F9B}.Release|x86.ActiveCfg = Release|Any CPU + {C37EC799-BBB5-46C7-A469-66677C316F9B}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -843,6 +881,8 @@ Global {A6FC8457-8223-4DBE-841B-EFC82C535680} = {9BFE01D1-0EF4-4CFC-8E20-254A7E39FB14} {2A9BA0DC-C329-45AD-972B-83E063445289} = {F5D72A2B-8550-493A-8E91-A88FBB29643D} {78444ABC-5425-457C-882C-4C928704971C} = {2A9BA0DC-C329-45AD-972B-83E063445289} + {D27AB6D6-1BE5-448C-9BAE-F0D2D89E6CDC} = {F5D72A2B-8550-493A-8E91-A88FBB29643D} + {C37EC799-BBB5-46C7-A469-66677C316F9B} = {D27AB6D6-1BE5-448C-9BAE-F0D2D89E6CDC} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {1D0C3A88-8F05-4858-97B6-0E554C1064BD} diff --git a/WinFormsDirect2D/DemoRenderer.HelloWorld.cs b/WinFormsDirect2D/DemoRenderer.HelloWorld.cs new file mode 100644 index 00000000..bffe0356 --- /dev/null +++ b/WinFormsDirect2D/DemoRenderer.HelloWorld.cs @@ -0,0 +1,55 @@ +using WInterop.Direct2d; +using System.Drawing; +using WInterop.Winforms; +using System.Diagnostics.CodeAnalysis; +using WInterop.DirectWrite; + +namespace WinFormsDirect2D +{ + internal partial class DemoRenderer + { + private class HelloWorld : IRenderItem + { + protected ITextFormat? _textFormat; + protected ITextLayout? _textLayout; + protected ITypography? _typography; + + protected ISolidColorBrush? _blackBrush; + + public HelloWorld() + { + } + + [AllowNull] + public ID2DFactoryProvider D2DFactoryProvider { get; set; } + + public void InitializeComponent() + { + _textFormat = D2DFactoryProvider.GetDirectWriteFactory().CreateTextFormat("Gabriola", fontSize: 64); + _textFormat.SetTextAlignment(TextAlignment.Center); + _textFormat.SetParagraphAlignment(ParagraphAlignment.Center); + } + + public void CreateD2DResources(IRenderTarget renderTarget) + { + string text = "Hello World From ... DirectWrite!"; + _blackBrush = renderTarget.CreateSolidColorBrush(Color.Black); + _textLayout = D2DFactoryProvider.GetDirectWriteFactory().CreateTextLayout(text, _textFormat, renderTarget.GetSize()); + + // (21, 12) is the range around "DirectWrite!" + _textLayout.SetFontSize(100, (21, 12)); + _typography = D2DFactoryProvider.GetDirectWriteFactory().CreateTypography(); + _typography.AddFontFeature(new FontFeature(FontFeatureTag.StylisticSet7, 1)); + _textLayout.SetTypography(_typography, (0, text.Length)); + _textLayout.SetUnderline(true, (21, 12)); + _textLayout.SetFontWeight(FontWeight.Bold, (21, 12)); + } + + public void D2DPaint(IRenderTarget renderTarget) + { + renderTarget.Clear(Color.CornflowerBlue); + renderTarget.DrawTextLayout(default, _textLayout, _blackBrush); + } + } + } +} diff --git a/WinFormsDirect2D/DemoRenderer.SimpleTestPicture.cs b/WinFormsDirect2D/DemoRenderer.SimpleTestPicture.cs new file mode 100644 index 00000000..9e8f4d1a --- /dev/null +++ b/WinFormsDirect2D/DemoRenderer.SimpleTestPicture.cs @@ -0,0 +1,67 @@ +using WInterop.Direct2d; +using System.Drawing; +using WInterop.Winforms; +using System.Diagnostics.CodeAnalysis; + +namespace WinFormsDirect2D +{ + internal partial class DemoRenderer + { + private class SimpleTestPicture : IRenderItem + { + private ISolidColorBrush? _lightSlateGrayBrush; + private ISolidColorBrush? _cornflowerBlueBrush; + + public SimpleTestPicture() + { + } + + [AllowNull] + public ID2DFactoryProvider D2DFactoryProvider { get; set; } + + public void CreateD2DResources(IRenderTarget renderTarget) + { + _lightSlateGrayBrush = renderTarget.CreateSolidColorBrush(Color.LightSlateGray); + _cornflowerBlueBrush = renderTarget.CreateSolidColorBrush(Color.CornflowerBlue); + } + + public void D2DPaint(IRenderTarget renderTarget) + { + renderTarget.SetTransform(); + renderTarget.Clear(Color.White); + Size size = renderTarget.GetSize().ToSize(); + + _lightSlateGrayBrush!.GetColor(out ColorF color); + + for (int x = 0; x < size.Width; x += 10) + { + renderTarget.DrawLine( + new Point(x, 0), new Point(x, size.Height), + _lightSlateGrayBrush, 0.5f); + } + + for (int y = 0; y < size.Height; y += 10) + { + renderTarget.DrawLine( + new Point(0, y), new Point(size.Width, y), + _lightSlateGrayBrush, 0.5f); + } + + Rectangle rectangle1 = Rectangle.FromLTRB( + size.Width / 2 - 50, + size.Height / 2 - 50, + size.Width / 2 + 50, + size.Height / 2 + 50); + + Rectangle rectangle2 = Rectangle.FromLTRB( + size.Width / 2 - 100, + size.Height / 2 - 100, + size.Width / 2 + 100, + size.Height / 2 + 100); + + renderTarget.FillRectangle(rectangle1, _lightSlateGrayBrush); + renderTarget.DrawRectangle(rectangle2, _cornflowerBlueBrush); + } + } + } +} diff --git a/WinFormsDirect2D/DemoRenderer.cs b/WinFormsDirect2D/DemoRenderer.cs new file mode 100644 index 00000000..e0f3bbb1 --- /dev/null +++ b/WinFormsDirect2D/DemoRenderer.cs @@ -0,0 +1,32 @@ +using System.Collections.Generic; +using System.Collections.Immutable; +using WInterop.Winforms; + +namespace WinFormsDirect2D +{ + internal partial class DemoRenderer + { + private readonly ImmutableDictionary _demos; + + public DemoRenderer(ID2DFactoryProvider factoryProvider) + { + var temp = new Dictionary() + { + { + nameof(SimpleTestPicture), + new SimpleTestPicture() { D2DFactoryProvider = factoryProvider } + }, + { + nameof(HelloWorld), + new HelloWorld() { D2DFactoryProvider = factoryProvider } + }, + + }; + + _demos = temp.ToImmutableDictionary(); + } + + public ImmutableDictionary Demos + => _demos; + } +} diff --git a/WinFormsDirect2D/MainForm.Designer.cs b/WinFormsDirect2D/MainForm.Designer.cs new file mode 100644 index 00000000..a11104ff --- /dev/null +++ b/WinFormsDirect2D/MainForm.Designer.cs @@ -0,0 +1,111 @@ +using WInterop.Winforms; + +namespace WinFormsDirect2D +{ + partial class MainForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.d2DPanel = new WInterop.Winforms.D2DPanel(); + this.menuStrip1 = new System.Windows.Forms.MenuStrip(); + this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.quitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.viewToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.menuStrip1.SuspendLayout(); + this.SuspendLayout(); + // + // d2DPanel + // + this.d2DPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.d2DPanel.Location = new System.Drawing.Point(12, 36); + this.d2DPanel.Name = "d2DPanel"; + this.d2DPanel.Size = new System.Drawing.Size(955, 581); + this.d2DPanel.TabIndex = 0; + this.d2DPanel.D2DPaint += new System.EventHandler(this.D2DPanel_D2DPaint); + this.d2DPanel.CreateD2DResources += new System.EventHandler(this.D2DPanel_CreateD2DResources); + // + // menuStrip1 + // + this.menuStrip1.ImageScalingSize = new System.Drawing.Size(24, 24); + this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.fileToolStripMenuItem, + this.viewToolStripMenuItem}); + this.menuStrip1.Location = new System.Drawing.Point(0, 0); + this.menuStrip1.Name = "menuStrip1"; + this.menuStrip1.Size = new System.Drawing.Size(979, 33); + this.menuStrip1.TabIndex = 1; + this.menuStrip1.Text = "menuStrip1"; + // + // fileToolStripMenuItem + // + this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.quitToolStripMenuItem}); + this.fileToolStripMenuItem.Name = "fileToolStripMenuItem"; + this.fileToolStripMenuItem.Size = new System.Drawing.Size(54, 29); + this.fileToolStripMenuItem.Text = "&File"; + // + // quitToolStripMenuItem + // + this.quitToolStripMenuItem.Name = "quitToolStripMenuItem"; + this.quitToolStripMenuItem.Size = new System.Drawing.Size(148, 34); + this.quitToolStripMenuItem.Text = "Quit"; + // + // viewToolStripMenuItem + // + this.viewToolStripMenuItem.Name = "viewToolStripMenuItem"; + this.viewToolStripMenuItem.Size = new System.Drawing.Size(65, 29); + this.viewToolStripMenuItem.Text = "&View"; + // + // MainForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(10F, 25F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(979, 629); + this.Controls.Add(this.d2DPanel); + this.Controls.Add(this.menuStrip1); + this.MainMenuStrip = this.menuStrip1; + this.Name = "MainForm"; + this.Text = "D2D/DWrite Demo"; + this.menuStrip1.ResumeLayout(false); + this.menuStrip1.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private D2DPanel d2DPanel; + private System.Windows.Forms.MenuStrip menuStrip1; + private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem quitToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem viewToolStripMenuItem; + } +} + diff --git a/WinFormsDirect2D/MainForm.cs b/WinFormsDirect2D/MainForm.cs new file mode 100644 index 00000000..a295d27a --- /dev/null +++ b/WinFormsDirect2D/MainForm.cs @@ -0,0 +1,58 @@ +using System.Windows.Forms; +using WInterop.Winforms; + +namespace WinFormsDirect2D +{ + public partial class MainForm : Form + { + private bool _resourcesCreated; + private DemoRenderer _demoRenderer; + private IRenderItem? _currentRenderItem; + + public MainForm() + { + InitializeComponent(); + _demoRenderer = new DemoRenderer(d2DPanel); + + foreach (var item in _demoRenderer.Demos) + { + ToolStripMenuItem menuItem = new() + { + Text = item.Key, + Tag = item.Value + }; + + menuItem.Click += MenuItem_Click; + viewToolStripMenuItem.DropDownItems.Add(menuItem); + } + } + + private void MenuItem_Click(object? sender, System.EventArgs e) + { + _currentRenderItem = (IRenderItem)((ToolStripMenuItem)sender!).Tag; + _resourcesCreated = false; + d2DPanel.Reset(); + } + + private void D2DPanel_D2DPaint(object sender, WInterop.Winforms.D2DPaintEventArgs e) + { + if (!_resourcesCreated || _currentRenderItem is null) + { + return; + } + + _currentRenderItem.D2DPaint(e.RenderTarget); + } + + private void D2DPanel_CreateD2DResources(object sender, WInterop.Winforms.D2DPaintEventArgs e) + { + _resourcesCreated = true; + if (_currentRenderItem is null) + { + return; + } + + _currentRenderItem.CreateD2DResources(e.RenderTarget); + } + } +} diff --git a/WinFormsDirect2D/MainForm.resx b/WinFormsDirect2D/MainForm.resx new file mode 100644 index 00000000..938108af --- /dev/null +++ b/WinFormsDirect2D/MainForm.resx @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + \ No newline at end of file diff --git a/WinFormsDirect2D/Program.cs b/WinFormsDirect2D/Program.cs new file mode 100644 index 00000000..650c0dfc --- /dev/null +++ b/WinFormsDirect2D/Program.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace WinFormsDirect2D +{ + internal static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + Application.SetHighDpiMode(HighDpiMode.SystemAware); + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new MainForm()); + } + } +} diff --git a/WinFormsDirect2D/WinFormsDirect2D.csproj b/WinFormsDirect2D/WinFormsDirect2D.csproj new file mode 100644 index 00000000..85ff1065 --- /dev/null +++ b/WinFormsDirect2D/WinFormsDirect2D.csproj @@ -0,0 +1,14 @@ + + + + WinExe + net5.0-windows + enable + true + + + + + + + \ No newline at end of file diff --git a/Winterop.Winforms/D2DPanel/D2DPaintEventArgs.cs b/Winterop.Winforms/D2DPanel/D2DPaintEventArgs.cs new file mode 100644 index 00000000..7aa8886c --- /dev/null +++ b/Winterop.Winforms/D2DPanel/D2DPaintEventArgs.cs @@ -0,0 +1,15 @@ +using System; +using WInterop.Direct2d; + +namespace WInterop.Winforms +{ + public class D2DPaintEventArgs : EventArgs + { + public D2DPaintEventArgs(IRenderTarget renderTarget) + { + RenderTarget = renderTarget; + } + + public IRenderTarget RenderTarget { get; } + } +} diff --git a/Winterop.Winforms/D2DPanel/D2DPanel.cs b/Winterop.Winforms/D2DPanel/D2DPanel.cs new file mode 100644 index 00000000..ddeb7c52 --- /dev/null +++ b/Winterop.Winforms/D2DPanel/D2DPanel.cs @@ -0,0 +1,160 @@ +using System; +using System.Windows.Forms; +using WInterop.Direct2d; +using WInterop.DirectWrite; +using WInterop.Errors; +using WInterop.Windows; + +namespace WInterop.Winforms +{ + public class D2DPanel : Control, ID2DFactoryProvider + { + private bool _baseResourcesValid; + private IWindowRenderTarget? _renderTarget; + private object _objectLock=new object(); + + private event EventHandler? _d2DPaint; + private event EventHandler? _createD2DResources; + + public D2DPanel() : base() + { + ResizeRedraw = true; + } + + protected IRenderTarget? RenderTarget => _renderTarget; + protected static Direct2d.IFactory Direct2dFactory { get; } = Direct2d.Direct2d.CreateFactory(); + protected static DirectWrite.IFactory DirectWriteFactory { get; } = DirectWrite.DirectWrite.CreateFactory(); + + public ITextFormat CreateTextFormat( + string fontFamilyname, + FontWeight fontWeight = FontWeight.Normal, + FontStyle fontStyle = FontStyle.Normal, + FontStretch fontStretch = FontStretch.Normal, + float fontSize = 12, + string? localName = null) + { + return DirectWriteFactory.CreateTextFormat( + fontFamilyname, + fontWeight, + fontStyle, + fontStretch, + fontSize, + localName); + } + + private void CreateResourcesInternal(WindowHandle window) + { + if (!_baseResourcesValid) + { + _renderTarget = Direct2dFactory.CreateWindowRenderTarget( + default, new WindowRenderTargetProperties(window, window.GetClientRectangle().Size)); + OnCreateD2DResources(); + _baseResourcesValid = true; + } + } + + private void CreateResourcesInternal(WindowHandle window, in Windows.Message.Size size) + { + if (!_baseResourcesValid) + { + _renderTarget = Direct2dFactory.CreateWindowRenderTarget( + default, new WindowRenderTargetProperties(window, size.NewSize)); + OnCreateD2DResources(); + _baseResourcesValid = true; + } + else + { + _renderTarget!.Resize(size.NewSize); + } + } + + protected override void OnPaint(PaintEventArgs e) + { + base.OnPaint(e); + var windowHandle = new WindowHandle(new Windows.Native.HWND(Handle)); + CreateResourcesInternal(windowHandle); + if (_baseResourcesValid) + { + _renderTarget!.BeginDraw(); + OnD2DPaint(); + HResult result = _renderTarget.EndDraw(); + } + } + + protected override void OnResize(EventArgs e) + { + base.OnResize(e); + var sizeMessage = Windows.Message.Size.FromDrawingSize(ClientSize); + var windowHandle = new WindowHandle(new Windows.Native.HWND(Handle)); + CreateResourcesInternal(windowHandle, in sizeMessage); + } + + protected virtual void OnD2DPaint() + { + if (_baseResourcesValid) + { + _d2DPaint?.Invoke(this, new D2DPaintEventArgs(RenderTarget!)); + } + } + + protected virtual void OnCreateD2DResources() + { + _createD2DResources?.Invoke(this, new D2DPaintEventArgs(RenderTarget!)); + } + + Direct2d.IFactory ID2DFactoryProvider.GetDirect2dFactory() + => Direct2dFactory; + + DirectWrite.IFactory ID2DFactoryProvider.GetDirectWriteFactory() + => DirectWriteFactory; + + public void Reset() + { + _renderTarget = null; + _baseResourcesValid = false; + Invalidate(); + } + + public event EventHandler D2DPaint + { + add + { + lock (_objectLock) + { + _d2DPaint += value; + } + } + remove + { + lock (_objectLock) + { + _d2DPaint -= value; + } + } + } + + public event EventHandler CreateD2DResources + { + add + { + lock (_objectLock) + { + _createD2DResources += value; + if (_baseResourcesValid) + { + // If the event was wired _after_ we already have created the resources + // we need to fire it immediately. + OnCreateD2DResources(); + } + } + } + remove + { + lock (_objectLock) + { + _createD2DResources -= value; + } + } + } + } +} diff --git a/Winterop.Winforms/D2DPanel/ID2DFactoryProvider.cs b/Winterop.Winforms/D2DPanel/ID2DFactoryProvider.cs new file mode 100644 index 00000000..2cde1abe --- /dev/null +++ b/Winterop.Winforms/D2DPanel/ID2DFactoryProvider.cs @@ -0,0 +1,8 @@ +namespace WInterop.Winforms +{ + public interface ID2DFactoryProvider + { + Direct2d.IFactory GetDirect2dFactory(); + DirectWrite.IFactory GetDirectWriteFactory(); + } +} diff --git a/Winterop.Winforms/D2DPanel/IRenderItem.cs b/Winterop.Winforms/D2DPanel/IRenderItem.cs new file mode 100644 index 00000000..3ccf07d9 --- /dev/null +++ b/Winterop.Winforms/D2DPanel/IRenderItem.cs @@ -0,0 +1,11 @@ +using WInterop.Direct2d; + +namespace WInterop.Winforms +{ + public interface IRenderItem + { + void D2DPaint(IRenderTarget renderTarget); + void CreateD2DResources(IRenderTarget renderTarget); + ID2DFactoryProvider D2DFactoryProvider { get; set; } + } +} diff --git a/Winterop.Winforms/WInterop.Winforms.csproj b/Winterop.Winforms/WInterop.Winforms.csproj new file mode 100644 index 00000000..a26ec9d9 --- /dev/null +++ b/Winterop.Winforms/WInterop.Winforms.csproj @@ -0,0 +1,13 @@ + + + + net5.0-windows;net6.0-windows + enable + true + + + + + + + diff --git a/src/Tests/NativeTestLibrary/NativeTestLibrary.vcxproj b/src/Tests/NativeTestLibrary/NativeTestLibrary.vcxproj index 4fe6d263..87187a28 100644 --- a/src/Tests/NativeTestLibrary/NativeTestLibrary.vcxproj +++ b/src/Tests/NativeTestLibrary/NativeTestLibrary.vcxproj @@ -28,26 +28,26 @@ DynamicLibrary true - v142 + v143 Unicode DynamicLibrary false - v142 + v143 true Unicode DynamicLibrary true - v142 + v143 Unicode DynamicLibrary false - v142 + v143 true Unicode diff --git a/src/WInterop.Desktop/Windows/Messages/Message.Size.cs b/src/WInterop.Desktop/Windows/Messages/Message.Size.cs index 7ea87f05..f81afa01 100644 --- a/src/WInterop.Desktop/Windows/Messages/Message.Size.cs +++ b/src/WInterop.Desktop/Windows/Messages/Message.Size.cs @@ -15,6 +15,17 @@ public Size(WParam wParam, LParam lParam) NewSize = new System.Drawing.Size(lParam.LowWord, lParam.HighWord); SizeType = (SizeType)(int)wParam; } + + private Size(System.Drawing.Size size) + { + NewSize = size; + SizeType = SizeType.MaxShow; + } + + public static Size FromDrawingSize(System.Drawing.Size size) + { + return new Size(size); + } } } -} \ No newline at end of file +}