From 94af78513c578b4aa7dbf78e085f18c5026ae108 Mon Sep 17 00:00:00 2001 From: Zaafar Ahmed Date: Sat, 26 Jan 2019 12:41:25 -0500 Subject: [PATCH] code refactor (#2) * Added StyleCop.Analyser to clean the code * updated HookController and AssemblyInfo code quality * code refactor * minor fixup * refactor code * minor fixup --- .../ClickableTransparentOverlay.csproj | 7 + ClickableTransparentOverlay/HookController.cs | 157 +++--- .../ImGuiController.cs | 498 +++++++++++------- ClickableTransparentOverlay/NativeMethods.cs | 62 ++- ClickableTransparentOverlay/Overlay.cs | 236 +++++---- .../Properties/AssemblyInfo.cs | 7 +- ClickableTransparentOverlay/packages.config | 1 + ClickableTransparentOverlay/stylecop.json | 14 + DriverProgram/App.config | 12 + DriverProgram/Program.cs | 12 +- 10 files changed, 646 insertions(+), 360 deletions(-) create mode 100644 ClickableTransparentOverlay/stylecop.json diff --git a/ClickableTransparentOverlay/ClickableTransparentOverlay.csproj b/ClickableTransparentOverlay/ClickableTransparentOverlay.csproj index b501d62..232276e 100644 --- a/ClickableTransparentOverlay/ClickableTransparentOverlay.csproj +++ b/ClickableTransparentOverlay/ClickableTransparentOverlay.csproj @@ -44,6 +44,7 @@ true false false + bin\x64\Debug\ClickableTransparentOverlay.xml bin\x64\Release\ @@ -58,6 +59,7 @@ Off + bin\x64\Release\ClickableTransparentOverlay.xml @@ -112,12 +114,17 @@ + PreserveNewest + + + + diff --git a/ClickableTransparentOverlay/HookController.cs b/ClickableTransparentOverlay/HookController.cs index 8554aef..141159b 100644 --- a/ClickableTransparentOverlay/HookController.cs +++ b/ClickableTransparentOverlay/HookController.cs @@ -1,52 +1,104 @@ -namespace ClickableTransparentOverlay +// +// Copyright (c) Zaafar Ahmed. All rights reserved. +// + +namespace ClickableTransparentOverlay { - using Gma.System.MouseKeyHook; - using ImGuiNET; using System.Numerics; using System.Windows.Forms; + using Gma.System.MouseKeyHook; + using ImGuiNET; + /// + /// This class Hooks the Global Window Mouse/Keyboard events + /// and pass them into ImGui Overlay. + /// public class HookController { - private IKeyboardMouseEvents _hook; - private bool Enable; - private int WindowX; - private int WindowY; + private IKeyboardMouseEvents myHook; + private bool enable; + private int windowX; + private int windowY; + /// + /// Initializes a new instance of the class. + /// + /// + /// Transparent SDL2Window top left corner X axis. + /// + /// + /// Transparent SDL2Window top left corner Y axis. + /// public HookController(int x, int y) { - WindowX = x; - WindowY = y; - Enable = true; - _hook = Hook.GlobalEvents(); + this.windowX = x; + this.windowY = y; + this.enable = true; + this.myHook = Hook.GlobalEvents(); } + /// + /// Enable this class functionality ( only call it once ). + /// public void EnableHooks() { - _hook.KeyDown += _hook_KeyDown; - _hook.KeyUp += _hook_KeyUp; - _hook.KeyPress += _hook_KeyPress; + this.myHook.KeyDown += this.HookKeyDown; + this.myHook.KeyUp += this.HookKeyUp; + this.myHook.KeyPress += this.HookKeyPress; - _hook.MouseDownExt += _hook_MouseDownExt; - _hook.MouseMove += _hook_MouseMove; - _hook.MouseUpExt += _hook_MouseUpExt; + this.myHook.MouseDownExt += this.HookMouseDownExt; + this.myHook.MouseMove += this.HookMouseMove; + this.myHook.MouseUpExt += this.HookMouseUpExt; - _hook.MouseWheelExt += _hook_MouseWheelExt; + this.myHook.MouseWheelExt += this.HookMouseWheelExt; } + /// + /// Update transparent SDL2Window top left position. + /// + /// + /// X axis of the SDL2Window top left corner + /// + /// + /// Y axis of the SDL2Window top left corner + /// public void UpdateWindowPosition(int x, int y) { - WindowX = x; - WindowY = y; + this.windowX = x; + this.windowY = y; } + /// + /// Pause the hooks. + /// public void PauseHooks() { - Enable = false; + this.enable = false; } + /// + /// Resume the hooks. + /// public void ResumeHooks() { - Enable = true; + this.enable = true; + } + + /// + /// Dispose the resources acquired by this class + /// + public void Dispose() + { + this.myHook.KeyDown -= this.HookKeyDown; + this.myHook.KeyUp -= this.HookKeyUp; + this.myHook.KeyPress -= this.HookKeyPress; + + this.myHook.MouseDownExt -= this.HookMouseDownExt; + this.myHook.MouseMove -= this.HookMouseMove; + this.myHook.MouseUpExt -= this.HookMouseUpExt; + + this.myHook.MouseWheelExt -= this.HookMouseWheelExt; + this.myHook.Dispose(); } private void MouseButtonFunction(MouseEventExtArgs e, bool isDownEvent) @@ -83,39 +135,40 @@ } } - private void _hook_MouseUpExt(object sender, MouseEventExtArgs e) + private void HookMouseUpExt(object sender, MouseEventExtArgs e) { - if (Enable) + if (this.enable) { - MouseButtonFunction(e, false); + this.MouseButtonFunction(e, false); } } - private void _hook_MouseDownExt(object sender, MouseEventExtArgs e) + private void HookMouseDownExt(object sender, MouseEventExtArgs e) { - if (Enable) + if (this.enable) { - MouseButtonFunction(e, true); + this.MouseButtonFunction(e, true); } } - private void _hook_MouseMove(object sender, MouseEventArgs e) + private void HookMouseMove(object sender, MouseEventArgs e) { - if (!Enable) + if (!this.enable) { return; } ImGuiIOPtr io = ImGui.GetIO(); - io.MousePos = new Vector2(e.X - WindowX, e.Y - WindowY); - // TODO: Show ImGUI Cursor/Hide ImGui Cursor + io.MousePos = new Vector2(e.X - this.windowX, e.Y - this.windowY); + + // TODO: Show ImGUI Cursor/Hide ImGui Cursor // ImGui.GetIO().MouseDrawCursor = true; // Window32 API ShowCursor(false) } - private void _hook_MouseWheelExt(object sender, MouseEventExtArgs e) + private void HookMouseWheelExt(object sender, MouseEventExtArgs e) { - if (!Enable) + if (!this.enable) { return; } @@ -128,8 +181,7 @@ } } - - private void _hook_KeyUp(object sender, KeyEventArgs e) + private void HookKeyUp(object sender, KeyEventArgs e) { var io = ImGui.GetIO(); io.KeysDown[e.KeyValue] = false; @@ -157,9 +209,9 @@ } } - private void _hook_KeyDown(object sender, KeyEventArgs e) + private void HookKeyDown(object sender, KeyEventArgs e) { - if (!Enable) + if (!this.enable) { return; } @@ -180,11 +232,10 @@ io.KeyCtrl = true; e.Handled = true; break; - case Keys.LMenu: - case Keys.RMenu: + case Keys.LMenu: // LAlt is LMenu + case Keys.RMenu: // RAlt is RMenu io.KeyAlt = true; break; - // Alt is LMenu/RMenu case Keys.LShiftKey: case Keys.RShiftKey: io.KeyShift = true; @@ -192,20 +243,22 @@ default: // Ignoring ALT key so we can do ALT+TAB or ALT+F4 etc. // Not sure if ImGUI needs to use ALT+XXX key for anything. - // Ignoring Capital/NumLock key so Windows can use it - // Ignoring Win/Super key so we can do Win+D or other stuff + // Ignoring Capital/NumLock key so Windows can use it. + // Ignoring Win/Super key so we can do Win+D or other stuff. + // Create a new issue on the repo if I miss any important key. if (!io.KeyAlt && e.KeyCode != Keys.Capital && e.KeyCode != Keys.NumLock && !io.KeySuper) { e.Handled = true; } + break; } } } - private void _hook_KeyPress(object sender, KeyPressEventArgs e) + private void HookKeyPress(object sender, KeyPressEventArgs e) { - if (!Enable) + if (!this.enable) { return; } @@ -226,19 +279,5 @@ e.Handled = true; } } - - public void Dispose() - { - _hook.KeyDown -= _hook_KeyDown; - _hook.KeyUp -= _hook_KeyUp; - _hook.KeyPress -= _hook_KeyPress; - - _hook.MouseDownExt -= _hook_MouseDownExt; - _hook.MouseMove -= _hook_MouseMove; - _hook.MouseUpExt -= _hook_MouseUpExt; - - _hook.MouseWheelExt -= _hook_MouseWheelExt; - _hook.Dispose(); - } } } diff --git a/ClickableTransparentOverlay/ImGuiController.cs b/ClickableTransparentOverlay/ImGuiController.cs index d68fddc..1973345 100644 --- a/ClickableTransparentOverlay/ImGuiController.cs +++ b/ClickableTransparentOverlay/ImGuiController.cs @@ -1,14 +1,15 @@ -namespace ClickableTransparentOverlay +// +namespace ClickableTransparentOverlay { using System; using System.Collections.Generic; + using System.IO; using System.Numerics; using System.Reflection; - using System.IO; - using Veldrid; using System.Runtime.CompilerServices; using ImGuiNET; using NativeLibraryLoader; + using Veldrid; /// /// A modified version of ImGui.NET.SampleProgram's ImGuiController. @@ -16,93 +17,135 @@ /// public sealed class ImGuiController : IDisposable { - private GraphicsDevice _gd; - private bool _frameBegun; +#pragma warning disable CS0169 // Force Copy this DLL + private readonly DefaultPathResolver useless; +#pragma warning restore CS0169 - // Veldrid objects - private DeviceBuffer _vertexBuffer; - private DeviceBuffer _indexBuffer; - private DeviceBuffer _projMatrixBuffer; - private Texture _fontTexture; - private TextureView _fontTextureView; - private Shader _vertexShader; - private Shader _fragmentShader; - private ResourceLayout _layout; - private ResourceLayout _textureLayout; - private Pipeline _pipeline; - private ResourceSet _mainResourceSet; - private ResourceSet _fontTextureResourceSet; - - private IntPtr _fontAtlasID = (IntPtr)1; - - private int _windowWidth; - private int _windowHeight; - private Vector2 _scaleFactor = Vector2.One; + private readonly IntPtr fontAtlasID = (IntPtr)1; // Image trackers - private readonly Dictionary _setsByView + private readonly Dictionary setsByView = new Dictionary(); - private readonly Dictionary _autoViewsByTexture + + private readonly Dictionary autoViewsByTexture = new Dictionary(); - private readonly Dictionary _viewsById = new Dictionary(); - private readonly List _ownedResources = new List(); - private int _lastAssignedID = 100; -#pragma warning disable CS0169 // Force Copy this DLL - private static DefaultPathResolver ___; -#pragma warning restore CS0169 + private readonly Dictionary viewsById + = new Dictionary(); + + private readonly List ownedResources + = new List(); + + private int lastAssignedID = 100; + + private GraphicsDevice gd; + private bool frameBegun; + + // Veldrid objects + private DeviceBuffer vertexBuffer; + private DeviceBuffer indexBuffer; + private DeviceBuffer projMatrixBuffer; + private Texture fontTexture; + private TextureView fontTextureView; + private Shader vertexShader; + private Shader fragmentShader; + private ResourceLayout layout; + private ResourceLayout textureLayout; + private Pipeline pipeline; + private ResourceSet mainResourceSet; + private ResourceSet fontTextureResourceSet; + + private int windowWidth; + private int windowHeight; + private Vector2 scaleFactor = Vector2.One; /// - /// Constructs a new ImGuiController. + /// Initializes a new instance of the class. /// + /// + /// Graphic Device + /// + /// + /// Output Description + /// + /// + /// SDL2Window Window width + /// + /// + /// SDL2Window Window height + /// + /// + /// desired FPS of the ImGui Overlay + /// public ImGuiController(GraphicsDevice gd, OutputDescription outputDescription, int width, int height, int fps) { - _gd = gd; - _windowWidth = width; - _windowHeight = height; + this.gd = gd; + this.windowWidth = width; + this.windowHeight = height; IntPtr context = ImGui.CreateContext(); ImGui.SetCurrentContext(context); ImGui.GetIO().Fonts.AddFontDefault(); - CreateDeviceResources(gd, outputDescription); + this.CreateDeviceResources(gd, outputDescription); SetKeyMappings(); - SetPerFrameImGuiData(1f / fps); + this.SetPerFrameImGuiData(1f / fps); ImGui.NewFrame(); - _frameBegun = true; + this.frameBegun = true; } + /// + /// Updates the ImGui about the SDL2Window Size + /// + /// + /// Width of the SDL2Window + /// + /// + /// Height of the SDL2Window + /// public void WindowResized(int width, int height) { - _windowWidth = width; - _windowHeight = height; + this.windowWidth = width; + this.windowHeight = height; } + /// + /// Disposes the resources acquired by the ImGuiController class. + /// public void DestroyDeviceObjects() { - Dispose(); + this.Dispose(); } + /// + /// Initializes different resources for ImGui Controller class. + /// + /// + /// Graphic Device + /// + /// + /// Output Description + /// public void CreateDeviceResources(GraphicsDevice gd, OutputDescription outputDescription) { - _gd = gd; + this.gd = gd; ResourceFactory factory = gd.ResourceFactory; - _vertexBuffer = factory.CreateBuffer(new BufferDescription(10000, BufferUsage.VertexBuffer | BufferUsage.Dynamic)); - _vertexBuffer.Name = "ImGui.NET Vertex Buffer"; - _indexBuffer = factory.CreateBuffer(new BufferDescription(2000, BufferUsage.IndexBuffer | BufferUsage.Dynamic)); - _indexBuffer.Name = "ImGui.NET Index Buffer"; - RecreateFontDeviceTexture(gd); + this.vertexBuffer = factory.CreateBuffer(new BufferDescription(10000, BufferUsage.VertexBuffer | BufferUsage.Dynamic)); + this.vertexBuffer.Name = "ImGui.NET Vertex Buffer"; + this.indexBuffer = factory.CreateBuffer(new BufferDescription(2000, BufferUsage.IndexBuffer | BufferUsage.Dynamic)); + this.indexBuffer.Name = "ImGui.NET Index Buffer"; + this.RecreateFontDeviceTexture(gd); - _projMatrixBuffer = factory.CreateBuffer(new BufferDescription(64, BufferUsage.UniformBuffer | BufferUsage.Dynamic)); - _projMatrixBuffer.Name = "ImGui.NET Projection Buffer"; + this.projMatrixBuffer = factory.CreateBuffer(new BufferDescription(64, BufferUsage.UniformBuffer | BufferUsage.Dynamic)); + this.projMatrixBuffer.Name = "ImGui.NET Projection Buffer"; - byte[] vertexShaderBytes = LoadEmbeddedShaderCode(gd.ResourceFactory, "imgui-vertex", ShaderStages.Vertex); - byte[] fragmentShaderBytes = LoadEmbeddedShaderCode(gd.ResourceFactory, "imgui-frag", ShaderStages.Fragment); - _vertexShader = factory.CreateShader(new ShaderDescription(ShaderStages.Vertex, vertexShaderBytes, "VS")); - _fragmentShader = factory.CreateShader(new ShaderDescription(ShaderStages.Fragment, fragmentShaderBytes, "FS")); + byte[] vertexShaderBytes = this.LoadEmbeddedShaderCode(gd.ResourceFactory, "imgui-vertex", ShaderStages.Vertex); + byte[] fragmentShaderBytes = this.LoadEmbeddedShaderCode(gd.ResourceFactory, "imgui-frag", ShaderStages.Fragment); + this.vertexShader = factory.CreateShader(new ShaderDescription(ShaderStages.Vertex, vertexShaderBytes, "VS")); + this.fragmentShader = factory.CreateShader(new ShaderDescription(ShaderStages.Fragment, fragmentShaderBytes, "FS")); VertexLayoutDescription[] vertexLayouts = new VertexLayoutDescription[] { @@ -112,10 +155,10 @@ new VertexElementDescription("in_color", VertexElementSemantic.Color, VertexElementFormat.Byte4_Norm)) }; - _layout = factory.CreateResourceLayout(new ResourceLayoutDescription( + this.layout = factory.CreateResourceLayout(new ResourceLayoutDescription( new ResourceLayoutElementDescription("ProjectionMatrixBuffer", ResourceKind.UniformBuffer, ShaderStages.Vertex), new ResourceLayoutElementDescription("MainSampler", ResourceKind.Sampler, ShaderStages.Fragment))); - _textureLayout = factory.CreateResourceLayout(new ResourceLayoutDescription( + this.textureLayout = factory.CreateResourceLayout(new ResourceLayoutDescription( new ResourceLayoutElementDescription("MainTexture", ResourceKind.TextureReadOnly, ShaderStages.Fragment))); GraphicsPipelineDescription pd = new GraphicsPipelineDescription( @@ -123,65 +166,85 @@ new DepthStencilStateDescription(false, false, ComparisonKind.Always), new RasterizerStateDescription(FaceCullMode.None, PolygonFillMode.Solid, FrontFace.Clockwise, false, true), PrimitiveTopology.TriangleList, - new ShaderSetDescription(vertexLayouts, new[] { _vertexShader, _fragmentShader }), - new ResourceLayout[] { _layout, _textureLayout }, + new ShaderSetDescription(vertexLayouts, new[] { this.vertexShader, this.fragmentShader }), + new ResourceLayout[] { this.layout, this.textureLayout }, outputDescription); - _pipeline = factory.CreateGraphicsPipeline(ref pd); + this.pipeline = factory.CreateGraphicsPipeline(ref pd); - _mainResourceSet = factory.CreateResourceSet(new ResourceSetDescription(_layout, - _projMatrixBuffer, - gd.PointSampler)); + this.mainResourceSet = factory.CreateResourceSet(new ResourceSetDescription( + this.layout, this.projMatrixBuffer, gd.PointSampler)); - _fontTextureResourceSet = factory.CreateResourceSet(new ResourceSetDescription(_textureLayout, _fontTextureView)); + this.fontTextureResourceSet = factory.CreateResourceSet( + new ResourceSetDescription(this.textureLayout, this.fontTextureView)); } /// /// Gets or creates a handle for a texture to be drawn with ImGui. /// Pass the returned handle to Image() or ImageButton(). /// + /// + /// Resource Factory + /// + /// + /// Texture View + /// + /// + /// Creates ImGui Binding + /// public IntPtr GetOrCreateImGuiBinding(ResourceFactory factory, TextureView textureView) { - if (!_setsByView.TryGetValue(textureView, out ResourceSetInfo rsi)) + if (!this.setsByView.TryGetValue(textureView, out ResourceSetInfo rsi)) { - ResourceSet resourceSet = factory.CreateResourceSet(new ResourceSetDescription(_textureLayout, textureView)); - rsi = new ResourceSetInfo(GetNextImGuiBindingID(), resourceSet); + ResourceSet resourceSet = factory.CreateResourceSet( + new ResourceSetDescription(this.textureLayout, textureView)); + + rsi = new ResourceSetInfo(this.GetNextImGuiBindingID(), resourceSet); - _setsByView.Add(textureView, rsi); - _viewsById.Add(rsi.ImGuiBinding, rsi); - _ownedResources.Add(resourceSet); + this.setsByView.Add(textureView, rsi); + this.viewsById.Add(rsi.ImGuiBinding, rsi); + this.ownedResources.Add(resourceSet); } return rsi.ImGuiBinding; } - private IntPtr GetNextImGuiBindingID() - { - int newID = _lastAssignedID++; - return (IntPtr)newID; - } - /// /// Gets or creates a handle for a texture to be drawn with ImGui. /// Pass the returned handle to Image() or ImageButton(). /// + /// + /// Resource Factory + /// + /// + /// Texture information + /// + /// + /// Pointer to the resource + /// public IntPtr GetOrCreateImGuiBinding(ResourceFactory factory, Texture texture) { - if (!_autoViewsByTexture.TryGetValue(texture, out TextureView textureView)) + if (!this.autoViewsByTexture.TryGetValue(texture, out TextureView textureView)) { textureView = factory.CreateTextureView(texture); - _autoViewsByTexture.Add(texture, textureView); - _ownedResources.Add(textureView); + this.autoViewsByTexture.Add(texture, textureView); + this.ownedResources.Add(textureView); } - return GetOrCreateImGuiBinding(factory, textureView); + return this.GetOrCreateImGuiBinding(factory, textureView); } /// /// Retrieves the shader texture binding for the given helper handle. /// + /// + /// ImGui Binding resource pointer. + /// + /// + /// Resource + /// public ResourceSet GetImageResourceSet(IntPtr imGuiBinding) { - if (!_viewsById.TryGetValue(imGuiBinding, out ResourceSetInfo tvi)) + if (!this.viewsById.TryGetValue(imGuiBinding, out ResourceSetInfo tvi)) { throw new InvalidOperationException("No registered ImGui binding with id " + imGuiBinding.ToString()); } @@ -189,83 +252,51 @@ return tvi.ResourceSet; } + /// + /// Clears the cache images. + /// public void ClearCachedImageResources() { - foreach (IDisposable resource in _ownedResources) + foreach (IDisposable resource in this.ownedResources) { resource.Dispose(); } - _ownedResources.Clear(); - _setsByView.Clear(); - _viewsById.Clear(); - _autoViewsByTexture.Clear(); - _lastAssignedID = 100; - } - - private byte[] LoadEmbeddedShaderCode(ResourceFactory factory, string name, ShaderStages stage) - { - switch (factory.BackendType) - { - case GraphicsBackend.Direct3D11: - { - string resourceName = name + ".hlsl.bytes"; - return GetEmbeddedResourceBytes(resourceName); - } - case GraphicsBackend.OpenGL: - { - string resourceName = name + ".glsl"; - return GetEmbeddedResourceBytes(resourceName); - } - case GraphicsBackend.Vulkan: - { - string resourceName = name + ".spv"; - return GetEmbeddedResourceBytes(resourceName); - } - case GraphicsBackend.Metal: - { - string resourceName = name + ".metallib"; - return GetEmbeddedResourceBytes(resourceName); - } - default: - throw new NotImplementedException(); - } - } - - private byte[] GetEmbeddedResourceBytes(string resourceName) - { - Assembly assembly = typeof(ImGuiController).Assembly; - using (Stream s = assembly.GetManifestResourceStream(resourceName)) - { - byte[] ret = new byte[s.Length]; - s.Read(ret, 0, (int)s.Length); - return ret; - } + this.ownedResources.Clear(); + this.setsByView.Clear(); + this.viewsById.Clear(); + this.autoViewsByTexture.Clear(); + this.lastAssignedID = 100; } /// /// Recreates the device texture used to render text. /// + /// + /// Graphic Device + /// public unsafe void RecreateFontDeviceTexture(GraphicsDevice gd) { ImGuiIOPtr io = ImGui.GetIO(); + // Build byte* pixels; int width, height, bytesPerPixel; io.Fonts.GetTexDataAsRGBA32(out pixels, out width, out height, out bytesPerPixel); + // Store our identifier - io.Fonts.SetTexID(_fontAtlasID); + io.Fonts.SetTexID(this.fontAtlasID); - _fontTexture = gd.ResourceFactory.CreateTexture(TextureDescription.Texture2D( + this.fontTexture = gd.ResourceFactory.CreateTexture(TextureDescription.Texture2D( (uint)width, (uint)height, 1, 1, PixelFormat.R8_G8_B8_A8_UNorm, TextureUsage.Sampled)); - _fontTexture.Name = "ImGui.NET Font Texture"; + this.fontTexture.Name = "ImGui.NET Font Texture"; gd.UpdateTexture( - _fontTexture, + this.fontTexture, (IntPtr)pixels, (uint)(bytesPerPixel * width * height), 0, @@ -276,7 +307,7 @@ 1, 0, 0); - _fontTextureView = gd.ResourceFactory.CreateTextureView(_fontTexture); + this.fontTextureView = gd.ResourceFactory.CreateTextureView(this.fontTexture); io.Fonts.ClearTexData(); } @@ -287,46 +318,67 @@ /// or index data has increased beyond the capacity of the existing buffers. /// A is needed to submit drawing and resource update commands. /// + /// + /// Graphic Device + /// + /// + /// Command List + /// public void Render(GraphicsDevice gd, CommandList cl) { - if (_frameBegun) + if (this.frameBegun) { - _frameBegun = false; + this.frameBegun = false; ImGui.Render(); - RenderImDrawData(ImGui.GetDrawData(), gd, cl); + this.RenderImDrawData(ImGui.GetDrawData(), gd, cl); } } /// /// Initilizes a new frame /// + /// + /// FPS delay + /// public void InitlizeFrame(float deltaSeconds) { - if (_frameBegun) + if (this.frameBegun) { ImGui.Render(); } - SetPerFrameImGuiData(deltaSeconds); + this.SetPerFrameImGuiData(deltaSeconds); - _frameBegun = true; + this.frameBegun = true; ImGui.NewFrame(); } /// - /// Sets per-frame data based on the associated window. - /// This is called by Update(float). + /// Frees all graphics resources used by the renderer. /// - private void SetPerFrameImGuiData(float deltaSeconds) + public void Dispose() { - ImGuiIOPtr io = ImGui.GetIO(); - io.DisplaySize = new Vector2( - _windowWidth / _scaleFactor.X, - _windowHeight / _scaleFactor.Y); - io.DisplayFramebufferScale = _scaleFactor; - io.DeltaTime = deltaSeconds; // DeltaTime is in seconds. + this.vertexBuffer.Dispose(); + this.indexBuffer.Dispose(); + this.projMatrixBuffer.Dispose(); + this.fontTexture.Dispose(); + this.fontTextureView.Dispose(); + this.vertexShader.Dispose(); + this.fragmentShader.Dispose(); + this.layout.Dispose(); + this.textureLayout.Dispose(); + this.pipeline.Dispose(); + this.mainResourceSet.Dispose(); + + foreach (IDisposable resource in this.ownedResources) + { + resource.Dispose(); + } } + /// + /// Allows ImGui to identify the Keys + /// private static void SetKeyMappings() { ImGuiIOPtr io = ImGui.GetIO(); @@ -343,7 +395,8 @@ io.KeyMap[(int)ImGuiKey.Backspace] = (int)System.Windows.Forms.Keys.Back; io.KeyMap[(int)ImGuiKey.Enter] = (int)System.Windows.Forms.Keys.Enter; io.KeyMap[(int)ImGuiKey.Escape] = (int)System.Windows.Forms.Keys.Escape; - //io.KeyMap[(int)ImGuiKey.COUNT] = (int)System.Windows.Forms.Keys.un; + + // io.KeyMap[(int)ImGuiKey.COUNT] = (int)System.Windows.Forms.Keys.un; io.KeyMap[(int)ImGuiKey.Insert] = (int)System.Windows.Forms.Keys.Insert; io.KeyMap[(int)ImGuiKey.Space] = (int)System.Windows.Forms.Keys.Space; io.KeyMap[(int)ImGuiKey.A] = (int)System.Windows.Forms.Keys.A; @@ -354,6 +407,94 @@ io.KeyMap[(int)ImGuiKey.Z] = (int)System.Windows.Forms.Keys.Z; } + /// + /// Get the Next ImGui Binding ID. + /// + /// + /// ImGui next binding ID. + /// + private IntPtr GetNextImGuiBindingID() + { + int newID = this.lastAssignedID++; + return (IntPtr)newID; + } + + /// + /// Loading Shader Code + /// + /// + /// Resource Factory + /// + /// + /// Shader file name + /// + /// + /// Shader stage + /// + /// + /// Returns shader byte code + /// + private byte[] LoadEmbeddedShaderCode(ResourceFactory factory, string name, ShaderStages stage) + { + switch (factory.BackendType) + { + case GraphicsBackend.Direct3D11: + string resourceName = name + ".hlsl.bytes"; + return this.GetEmbeddedResourceBytes(resourceName); + default: + throw new NotImplementedException(); + } + } + + /// + /// Get embedded resource file in bytes + /// + /// + /// Name of the resource file + /// + /// + /// Byte code of the resource file + /// + private byte[] GetEmbeddedResourceBytes(string resourceName) + { + Assembly assembly = typeof(ImGuiController).Assembly; + using (Stream s = assembly.GetManifestResourceStream(resourceName)) + { + byte[] ret = new byte[s.Length]; + s.Read(ret, 0, (int)s.Length); + return ret; + } + } + + /// + /// Sets per-frame data based on the associated window. + /// This is called by Update(float). + /// + /// + /// FPS delay + /// + private void SetPerFrameImGuiData(float deltaSeconds) + { + ImGuiIOPtr io = ImGui.GetIO(); + io.DisplaySize = new Vector2( + this.windowWidth / this.scaleFactor.X, + this.windowHeight / this.scaleFactor.Y); + io.DisplayFramebufferScale = this.scaleFactor; + io.DeltaTime = deltaSeconds; // DeltaTime is in seconds. + } + + /// + /// Draw the ImGui graphic data + /// + /// + /// ImGui data to draw + /// + /// + /// Graphic Device + /// + /// + /// Command List + /// private void RenderImDrawData(ImDrawDataPtr draw_data, GraphicsDevice gd, CommandList cl) { uint vertexOffsetInVertices = 0; @@ -365,17 +506,19 @@ } uint totalVBSize = (uint)(draw_data.TotalVtxCount * Unsafe.SizeOf()); - if (totalVBSize > _vertexBuffer.SizeInBytes) + if (totalVBSize > this.vertexBuffer.SizeInBytes) { - gd.DisposeWhenIdle(_vertexBuffer); - _vertexBuffer = gd.ResourceFactory.CreateBuffer(new BufferDescription((uint)(totalVBSize * 1.5f), BufferUsage.VertexBuffer | BufferUsage.Dynamic)); + gd.DisposeWhenIdle(this.vertexBuffer); + this.vertexBuffer = gd.ResourceFactory.CreateBuffer(new BufferDescription( + (uint)(totalVBSize * 1.5f), BufferUsage.VertexBuffer | BufferUsage.Dynamic)); } uint totalIBSize = (uint)(draw_data.TotalIdxCount * sizeof(ushort)); - if (totalIBSize > _indexBuffer.SizeInBytes) + if (totalIBSize > this.indexBuffer.SizeInBytes) { - gd.DisposeWhenIdle(_indexBuffer); - _indexBuffer = gd.ResourceFactory.CreateBuffer(new BufferDescription((uint)(totalIBSize * 1.5f), BufferUsage.IndexBuffer | BufferUsage.Dynamic)); + gd.DisposeWhenIdle(this.indexBuffer); + this.indexBuffer = gd.ResourceFactory.CreateBuffer(new BufferDescription( + (uint)(totalIBSize * 1.5f), BufferUsage.IndexBuffer | BufferUsage.Dynamic)); } for (int i = 0; i < draw_data.CmdListsCount; i++) @@ -383,13 +526,13 @@ ImDrawListPtr cmd_list = draw_data.CmdListsRange[i]; cl.UpdateBuffer( - _vertexBuffer, + this.vertexBuffer, vertexOffsetInVertices * (uint)Unsafe.SizeOf(), cmd_list.VtxBuffer.Data, (uint)(cmd_list.VtxBuffer.Size * Unsafe.SizeOf())); cl.UpdateBuffer( - _indexBuffer, + this.indexBuffer, indexOffsetInElements * sizeof(ushort), cmd_list.IdxBuffer.Data, (uint)(cmd_list.IdxBuffer.Size * sizeof(ushort))); @@ -408,12 +551,12 @@ -1.0f, 1.0f); - _gd.UpdateBuffer(_projMatrixBuffer, 0, ref mvp); + this.gd.UpdateBuffer(this.projMatrixBuffer, 0, ref mvp); - cl.SetVertexBuffer(0, _vertexBuffer); - cl.SetIndexBuffer(_indexBuffer, IndexFormat.UInt16); - cl.SetPipeline(_pipeline); - cl.SetGraphicsResourceSet(0, _mainResourceSet); + cl.SetVertexBuffer(0, this.vertexBuffer); + cl.SetIndexBuffer(this.indexBuffer, IndexFormat.UInt16); + cl.SetPipeline(this.pipeline); + cl.SetGraphicsResourceSet(0, this.mainResourceSet); draw_data.ScaleClipRects(io.DisplayFramebufferScale); @@ -434,13 +577,15 @@ { if (pcmd.TextureId != IntPtr.Zero) { - if (pcmd.TextureId == _fontAtlasID) + if (pcmd.TextureId == this.fontAtlasID) { - cl.SetGraphicsResourceSet(1, _fontTextureResourceSet); + cl.SetGraphicsResourceSet( + 1, this.fontTextureResourceSet); } else { - cl.SetGraphicsResourceSet(1, GetImageResourceSet(pcmd.TextureId)); + cl.SetGraphicsResourceSet( + 1, this.GetImageResourceSet(pcmd.TextureId)); } } @@ -456,33 +601,14 @@ idx_offset += (int)pcmd.ElemCount; } + vtx_offset += cmd_list.VtxBuffer.Size; } } /// - /// Frees all graphics resources used by the renderer. + /// ResourceSetInfo /// - public void Dispose() - { - _vertexBuffer.Dispose(); - _indexBuffer.Dispose(); - _projMatrixBuffer.Dispose(); - _fontTexture.Dispose(); - _fontTextureView.Dispose(); - _vertexShader.Dispose(); - _fragmentShader.Dispose(); - _layout.Dispose(); - _textureLayout.Dispose(); - _pipeline.Dispose(); - _mainResourceSet.Dispose(); - - foreach (IDisposable resource in _ownedResources) - { - resource.Dispose(); - } - } - private struct ResourceSetInfo { public readonly IntPtr ImGuiBinding; @@ -490,8 +616,8 @@ public ResourceSetInfo(IntPtr imGuiBinding, ResourceSet resourceSet) { - ImGuiBinding = imGuiBinding; - ResourceSet = resourceSet; + this.ImGuiBinding = imGuiBinding; + this.ResourceSet = resourceSet; } } } diff --git a/ClickableTransparentOverlay/NativeMethods.cs b/ClickableTransparentOverlay/NativeMethods.cs index f82697b..1b68415 100644 --- a/ClickableTransparentOverlay/NativeMethods.cs +++ b/ClickableTransparentOverlay/NativeMethods.cs @@ -1,8 +1,16 @@ -namespace ClickableTransparentOverlay +// +// Copyright (c) Zaafar Ahmed. All rights reserved. +// + +namespace ClickableTransparentOverlay { using System; + using System.Drawing; using System.Runtime.InteropServices; + /// + /// This class allow user to access Win32 API functions. + /// public static class NativeMethods { private const int GWL_EXSTYLE = -20; @@ -12,7 +20,16 @@ private const int SW_HIDE = 0x00; private const int SW_SHOW = 0x05; - public static void EnableTransparent(IntPtr handle, System.Drawing.Rectangle size) + /// + /// Allows the SDL2Window to become transparent. + /// + /// + /// Veldrid window handle in IntPtr format. + /// + /// + /// Size of the SDL2Window. + /// + public static void EnableTransparent(IntPtr handle, Rectangle size) { IntPtr windowLong = GetWindowLongPtr(handle, GWL_EXSTYLE); windowLong = new IntPtr(windowLong.ToInt64() | WS_EX_LAYERED | WS_EX_TRANSPARENT); @@ -21,22 +38,46 @@ DwmExtendFrameIntoClientArea(handle, ref margins); } + /// + /// Allows hiding the console window. + /// public static void HideConsoleWindow() { var handle = GetConsoleWindow(); ShowWindow(handle, SW_HIDE); } + /// + /// Allows displaying the console window. + /// public static void ShowConsoleWindow() { var handle = GetConsoleWindow(); ShowWindow(handle, SW_SHOW); } + [DllImport("dwmapi.dll")] + private static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref Margins pMarInset); + + [DllImport("user32.dll", EntryPoint = "GetWindowLongPtr")] + private static extern IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex); + + [DllImport("user32.dll", EntryPoint = "SetWindowLongPtr")] + private static extern IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr dwNewLong); + + [DllImport("kernel32.dll")] + private static extern IntPtr GetConsoleWindow(); + + [DllImport("user32.dll", EntryPoint = "ShowWindow", SetLastError = true)] + private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); + [StructLayout(LayoutKind.Sequential)] private struct Margins { - private int left, right, top, bottom; + private int left; + private int right; + private int top; + private int bottom; public static Margins FromRectangle(System.Drawing.Rectangle rectangle) { @@ -50,20 +91,5 @@ return margins; } } - - [DllImport("dwmapi.dll")] - private static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref Margins pMarInset); - - [DllImport("user32.dll", EntryPoint = "GetWindowLongPtr")] - private static extern IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex); - - [DllImport("user32.dll", EntryPoint = "SetWindowLongPtr")] - private static extern IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr dwNewLong); - - [DllImport("kernel32.dll")] - static extern IntPtr GetConsoleWindow(); - - [DllImport("user32.dll", EntryPoint = "ShowWindow", SetLastError = true)] - static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); } } \ No newline at end of file diff --git a/ClickableTransparentOverlay/Overlay.cs b/ClickableTransparentOverlay/Overlay.cs index b5d80d7..d58fdfc 100644 --- a/ClickableTransparentOverlay/Overlay.cs +++ b/ClickableTransparentOverlay/Overlay.cs @@ -1,4 +1,8 @@ -namespace ClickableTransparentOverlay +// +// Copyright (c) Zaafar Ahmed. All rights reserved. +// + +namespace ClickableTransparentOverlay { using System; using System.Numerics; @@ -8,160 +12,214 @@ using Veldrid.Sdl2; using Veldrid.StartupUtilities; + /// + /// A class to create clickable transparent overlay + /// public class Overlay { - private static Sdl2Window _window; - private static GraphicsDevice _gd; - private static CommandList _cl; - private static ImGuiController _im_controller; - private static HookController _hook_controller; - private static Thread _ui_thread; - public event EventHandler SubmitUI; + private static Sdl2Window window; + private static GraphicsDevice graphicsDevice; + private static CommandList commandList; + private static ImGuiController imController; + private static HookController hookController; + private static Thread uiThread; // UI State - private static Vector4 _clearColor; - private static Vector2 _future_pos; - private static Vector2 _future_size; - private static int _fps; - private static bool _is_visible; - private static bool _is_closed; - private static bool _require_resize; - private static bool _start_resizing; - private static object _resize_thread_lock; - + private static Vector4 clearColor; + private static Vector2 futurePos; + private static Vector2 futureSize; + private static int myFps; + private static bool isVisible; + private static bool isClosed; + private static bool requireResize; + private static bool startResizing; + private static object resizeLock; + + /// + /// Initializes a new instance of the class. + /// + /// + /// x position of the overlay + /// + /// + /// y position of the overlay + /// + /// + /// width of the overlay + /// + /// + /// height of the Overlay + /// + /// + /// fps of the overlay + /// public Overlay(int x, int y, int width, int height, int fps) { - _clearColor = new Vector4(0.00f, 0.00f, 0.00f, 0.00f); - _fps = fps; - _is_visible = true; - _is_closed = false; + clearColor = new Vector4(0.00f, 0.00f, 0.00f, 0.00f); + myFps = fps; + isVisible = true; + isClosed = false; + // Stuff related to (thread safe) resizing of SDL2Window - _require_resize = false; - _start_resizing = false; - _resize_thread_lock = new object(); - _future_size = Vector2.Zero; - _future_pos = Vector2.Zero; - - _window = new Sdl2Window("Overlay", x, x, width, height, SDL_WindowFlags.Borderless | SDL_WindowFlags.AlwaysOnTop | SDL_WindowFlags.SkipTaskbar, true); - // TODO: Create a new branch for Non-Veldrid dependent version. Ideally, we can directly use SDL2Window. - _gd = VeldridStartup.CreateGraphicsDevice(_window, new GraphicsDeviceOptions(true, null, true), GraphicsBackend.Direct3D11); - NativeMethods.EnableTransparent(_window.Handle, new System.Drawing.Rectangle(_window.X , _window.Y, _window.Width, _window.Height)); - _window.Resized += () => + requireResize = false; + startResizing = false; + resizeLock = new object(); + futureSize = Vector2.Zero; + futurePos = Vector2.Zero; + + window = new Sdl2Window("Overlay", x, x, width, height, SDL_WindowFlags.Borderless | SDL_WindowFlags.AlwaysOnTop | SDL_WindowFlags.SkipTaskbar, true); + graphicsDevice = VeldridStartup.CreateGraphicsDevice(window, new GraphicsDeviceOptions(true, null, true), GraphicsBackend.Direct3D11); + NativeMethods.EnableTransparent(window.Handle, new System.Drawing.Rectangle(window.X, window.Y, window.Width, window.Height)); + window.Resized += () => { - _gd.MainSwapchain.Resize((uint)_window.Width, (uint)_window.Height); - _im_controller.WindowResized(_window.Width, _window.Height); - lock (_resize_thread_lock) + graphicsDevice.MainSwapchain.Resize((uint)window.Width, (uint)window.Height); + imController.WindowResized(window.Width, window.Height); + lock (resizeLock) { - _require_resize = false; - _start_resizing = false; + requireResize = false; + startResizing = false; } }; - _window.Closed += () => + window.Closed += () => { - _is_closed = true; + isClosed = true; }; - _cl = _gd.ResourceFactory.CreateCommandList(); - _im_controller = new ImGuiController(_gd, _gd.MainSwapchain.Framebuffer.OutputDescription, _window.Width, _window.Height, _fps); - _ui_thread = new Thread(WhileLoop); - _hook_controller = new HookController(_window.X, _window.Y); + commandList = graphicsDevice.ResourceFactory.CreateCommandList(); + imController = new ImGuiController(graphicsDevice, graphicsDevice.MainSwapchain.Framebuffer.OutputDescription, window.Width, window.Height, myFps); + uiThread = new Thread(this.WhileLoop); + hookController = new HookController(window.X, window.Y); } + /// + /// To submit ImGui code for generating the UI. + /// + public event EventHandler SubmitUI; + + /// + /// Starts the overlay + /// public void Run() { - _ui_thread.Start(); - _hook_controller.EnableHooks(); + uiThread.Start(); + hookController.EnableHooks(); NativeMethods.HideConsoleWindow(); Application.Run(new ApplicationContext()); } + /// + /// Free all resources acquired by the overlay + /// public void Dispose() { - _is_visible = false; - _window.Close(); - while (!_is_closed) + isVisible = false; + window.Close(); + while (!isClosed) { Thread.Sleep(10); } - _ui_thread.Join(); - _gd.WaitForIdle(); - _im_controller.Dispose(); - _cl.Dispose(); - _gd.Dispose(); - _hook_controller.Dispose(); + uiThread.Join(); + graphicsDevice.WaitForIdle(); + imController.Dispose(); + commandList.Dispose(); + graphicsDevice.Dispose(); + hookController.Dispose(); NativeMethods.ShowConsoleWindow(); - _resize_thread_lock = null; - SubmitUI = null; + resizeLock = null; + this.SubmitUI = null; Console.WriteLine("All Overlay resources are cleared."); Application.Exit(); } - public void ResizeWindow(int x, int y, int width, int height) + /// + /// Resizes the overlay + /// + /// + /// x axis of the overlay + /// + /// + /// y axis of the overlay + /// + /// + /// width of the overlay + /// + /// + /// height of the overlay + /// + public void Resize(int x, int y, int width, int height) { - _future_pos.X = x; - _future_pos.Y = y; - _future_size.X = width; - _future_size.Y = height; + futurePos.X = x; + futurePos.Y = y; + futureSize.X = width; + futureSize.Y = height; + // TODO: move following two lines to _window.Moved - _hook_controller.UpdateWindowPosition(x, y); - NativeMethods.EnableTransparent(_window.Handle, new System.Drawing.Rectangle(x, y, width, height)); - _require_resize = true; + hookController.UpdateWindowPosition(x, y); + NativeMethods.EnableTransparent(window.Handle, new System.Drawing.Rectangle(x, y, width, height)); + requireResize = true; } - public void ShowWindow() + /// + /// Shows the overlay + /// + public void Show() { - _hook_controller.ResumeHooks(); - _is_visible = true; + hookController.ResumeHooks(); + isVisible = true; } - public void HideWindow() + /// + /// hides the overlay + /// + public void Hide() { // TODO: Improve this function to do the following // 1: Hide SDL2Window // 2: Pause WhileLoop // This will ensure we don't waste CPU/GPU resources while window is hidden - _hook_controller.PauseHooks(); - _is_visible = false; + hookController.PauseHooks(); + isVisible = false; } private void WhileLoop() { - while (_window.Exists) + while (window.Exists) { - lock (_resize_thread_lock) + lock (resizeLock) { - if (_require_resize) + if (requireResize) { - if (!_start_resizing) + if (!startResizing) { - Sdl2Native.SDL_SetWindowPosition(_window.SdlWindowHandle, (int)_future_pos.X, (int)_future_pos.Y); - Sdl2Native.SDL_SetWindowSize(_window.SdlWindowHandle, (int)_future_size.X, (int)_future_size.Y); - _start_resizing = true; + Sdl2Native.SDL_SetWindowPosition(window.SdlWindowHandle, (int)futurePos.X, (int)futurePos.Y); + Sdl2Native.SDL_SetWindowSize(window.SdlWindowHandle, (int)futureSize.X, (int)futureSize.Y); + startResizing = true; } + continue; } } - if (!_window.Exists) + if (!window.Exists) { break; } - _im_controller.InitlizeFrame(1f / _fps); + imController.InitlizeFrame(1f / myFps); - if (_is_visible) + if (isVisible) { - SubmitUI?.Invoke(this, new EventArgs()); + this.SubmitUI?.Invoke(this, new EventArgs()); } - _cl.Begin(); - _cl.SetFramebuffer(_gd.MainSwapchain.Framebuffer); - _cl.ClearColorTarget(0, new RgbaFloat(_clearColor.X, _clearColor.Y, _clearColor.Z, _clearColor.W)); - _im_controller.Render(_gd, _cl); - _cl.End(); - _gd.SubmitCommands(_cl); - _gd.SwapBuffers(_gd.MainSwapchain); + commandList.Begin(); + commandList.SetFramebuffer(graphicsDevice.MainSwapchain.Framebuffer); + commandList.ClearColorTarget(0, new RgbaFloat(clearColor.X, clearColor.Y, clearColor.Z, clearColor.W)); + imController.Render(graphicsDevice, commandList); + commandList.End(); + graphicsDevice.SubmitCommands(commandList); + graphicsDevice.SwapBuffers(graphicsDevice.MainSwapchain); } } } diff --git a/ClickableTransparentOverlay/Properties/AssemblyInfo.cs b/ClickableTransparentOverlay/Properties/AssemblyInfo.cs index 01d3c07..42b9748 100644 --- a/ClickableTransparentOverlay/Properties/AssemblyInfo.cs +++ b/ClickableTransparentOverlay/Properties/AssemblyInfo.cs @@ -1,5 +1,8 @@ -using System.Reflection; -using System.Runtime.CompilerServices; +// +// Copyright (c) Zaafar Ahmed. All rights reserved. +// + +using System.Reflection; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following diff --git a/ClickableTransparentOverlay/packages.config b/ClickableTransparentOverlay/packages.config index b93a716..9335366 100644 --- a/ClickableTransparentOverlay/packages.config +++ b/ClickableTransparentOverlay/packages.config @@ -6,6 +6,7 @@ + diff --git a/ClickableTransparentOverlay/stylecop.json b/ClickableTransparentOverlay/stylecop.json new file mode 100644 index 0000000..81fde14 --- /dev/null +++ b/ClickableTransparentOverlay/stylecop.json @@ -0,0 +1,14 @@ +{ + // ACTION REQUIRED: This file was automatically added to your project, but it + // will not take effect until additional steps are taken to enable it. See the + // following page for additional information: + // + // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/EnableConfiguration.md + + "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json", + "settings": { + "documentationRules": { + "companyName": "Zaafar Ahmed" + } + } +} diff --git a/DriverProgram/App.config b/DriverProgram/App.config index 21f44c2..7accef2 100644 --- a/DriverProgram/App.config +++ b/DriverProgram/App.config @@ -17,6 +17,18 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/DriverProgram/Program.cs b/DriverProgram/Program.cs index cd4aed7..c45ca71 100644 --- a/DriverProgram/Program.cs +++ b/DriverProgram/Program.cs @@ -41,12 +41,12 @@ public static void DistroyDemo() { Thread.Sleep(RunFor * 1000); - //demo.ResizeWindow(0, 0, 2560, 1440); - //Thread.Sleep(10000); - //demo.HideWindow(); - //Thread.Sleep(10000); - //demo.ShowWindow(); - //Thread.Sleep(10000); + demo.Resize(200, 200, 1024, 1024); + Thread.Sleep(RunFor * 1000); + demo.Hide(); + Thread.Sleep(RunFor * 1000); + demo.Show(); + Thread.Sleep(RunFor * 1000); demo.Dispose(); } }