diff --git a/Capture/Capture.csproj b/Capture/Capture.csproj index d37c1d3..5ba2870 100644 --- a/Capture/Capture.csproj +++ b/Capture/Capture.csproj @@ -112,6 +112,7 @@ + diff --git a/Capture/Hook/BaseDXHook.cs b/Capture/Hook/BaseDXHook.cs index f5c9fa2..44dd424 100644 --- a/Capture/Hook/BaseDXHook.cs +++ b/Capture/Hook/BaseDXHook.cs @@ -27,9 +27,12 @@ public BaseDXHook(CaptureInterface ssInterface) Interface.ScreenshotRequested += InterfaceEventProxy.ScreenshotRequestedProxyHandler; Interface.DisplayText += InterfaceEventProxy.DisplayTextProxyHandler; + Interface.DrawOverlay += InterfaceEventProxy.DrawOverlayProxyHandler; InterfaceEventProxy.ScreenshotRequested += new ScreenshotRequestedEvent(InterfaceEventProxy_ScreenshotRequested); InterfaceEventProxy.DisplayText += new DisplayTextEvent(InterfaceEventProxy_DisplayText); + InterfaceEventProxy.DrawOverlay += InterfaceEventProxy_DrawOverlay; } + ~BaseDXHook() { Dispose(false); @@ -50,6 +53,14 @@ protected virtual void InterfaceEventProxy_ScreenshotRequested(ScreenshotRequest this.Request = request; } + private void InterfaceEventProxy_DrawOverlay(DrawOverlayEventArgs args) + { + Overlays = new List(); + if (args.Overlay != null) + Overlays.Add(args.Overlay); + IsOverlayUpdatePending = true; + } + protected Stopwatch Timer { get; set; } /// @@ -59,6 +70,10 @@ protected virtual void InterfaceEventProxy_ScreenshotRequested(ScreenshotRequest protected TextDisplay TextDisplay { get; set; } + protected List Overlays { get; set; } + + protected bool IsOverlayUpdatePending { get; set; } + int _processId = 0; protected int ProcessId { @@ -394,6 +409,7 @@ protected override void Dispose(bool disposeManagedResources) // Remove the event handlers Interface.ScreenshotRequested -= InterfaceEventProxy.ScreenshotRequestedProxyHandler; Interface.DisplayText -= InterfaceEventProxy.DisplayTextProxyHandler; + Interface.DrawOverlay -= InterfaceEventProxy_DrawOverlay; } catch (RemotingException) { } // Ignore remoting exceptions (host process may have been closed) } diff --git a/Capture/Hook/Common/Element.cs b/Capture/Hook/Common/Element.cs index 676208d..6750079 100644 --- a/Capture/Hook/Common/Element.cs +++ b/Capture/Hook/Common/Element.cs @@ -8,7 +8,7 @@ namespace Capture.Hook.Common { [Serializable] - public abstract class Element: MarshalByRefObject, IOverlayElement, IDisposable + public abstract class Element: IOverlayElement, IDisposable { public virtual bool Hidden { get; set; } @@ -41,7 +41,6 @@ protected virtual void Dispose(bool disposing) { if (disposing) { - Disconnect(); } } @@ -50,22 +49,5 @@ protected void SafeDispose(IDisposable disposableObj) if (disposableObj != null) disposableObj.Dispose(); } - - /// - /// Disconnects the remoting channel(s) of this object and all nested objects. - /// - private void Disconnect() - { - RemotingServices.Disconnect(this); - } - - [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.Infrastructure)] - public override object InitializeLifetimeService() - { - // Returning null designates an infinite non-expiring lease. - // We must therefore ensure that RemotingServices.Disconnect() is called when - // it's no longer needed otherwise there will be a memory leak. - return null; - } } } diff --git a/Capture/Hook/Common/FramesPerSecond.cs b/Capture/Hook/Common/FramesPerSecond.cs index ce4cc3c..b129289 100644 --- a/Capture/Hook/Common/FramesPerSecond.cs +++ b/Capture/Hook/Common/FramesPerSecond.cs @@ -5,6 +5,7 @@ namespace Capture.Hook.Common { + [Serializable] public class FramesPerSecond: TextElement { string _fpsFormat = "{0:N0} fps"; diff --git a/Capture/Hook/Common/IOverlay.cs b/Capture/Hook/Common/IOverlay.cs index 6b37d2d..9dc2614 100644 --- a/Capture/Hook/Common/IOverlay.cs +++ b/Capture/Hook/Common/IOverlay.cs @@ -6,7 +6,7 @@ namespace Capture.Hook.Common { - internal interface IOverlay: IOverlayElement + public interface IOverlay: IOverlayElement { List Elements { get; set; } } diff --git a/Capture/Hook/Common/ImageElement.cs b/Capture/Hook/Common/ImageElement.cs index 0bbf4ce..aed7352 100644 --- a/Capture/Hook/Common/ImageElement.cs +++ b/Capture/Hook/Common/ImageElement.cs @@ -1,21 +1,41 @@ -using System; +using Capture.Interface; +using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Capture.Hook.Common { + [Serializable] public class ImageElement: Element { - public virtual System.Drawing.Bitmap Bitmap { get; set; } - + /// + /// The image file bytes + /// + public virtual byte[] Image { get; set; } + + System.Drawing.Bitmap _bitmap = null; + internal virtual System.Drawing.Bitmap Bitmap { + get + { + if (_bitmap == null && Image != null) + { + _bitmap = Image.ToBitmap(); + _ownsBitmap = true; + } + + return _bitmap; + } + set { _bitmap = value; } + } + /// /// This value is multiplied with the source color (e.g. White will result in same color as source image) /// /// /// Defaults to . /// - public virtual System.Drawing.Color Tint { get; set; } + public virtual System.Drawing.Color Tint { get; set; } = System.Drawing.Color.White; /// /// The location of where to render this image element @@ -24,12 +44,14 @@ public class ImageElement: Element public float Angle { get; set; } - public float Scale { get; set; } + public float Scale { get; set; } = 1.0f; public string Filename { get; set; } bool _ownsBitmap = false; + public ImageElement() { } + public ImageElement(string filename): this(new System.Drawing.Bitmap(filename), true) { diff --git a/Capture/Hook/Common/Overlay.cs b/Capture/Hook/Common/Overlay.cs index 0396373..0442518 100644 --- a/Capture/Hook/Common/Overlay.cs +++ b/Capture/Hook/Common/Overlay.cs @@ -5,6 +5,7 @@ namespace Capture.Hook.Common { + [Serializable] public class Overlay: IOverlay { List _elements = new List(); diff --git a/Capture/Hook/Common/TextElement.cs b/Capture/Hook/Common/TextElement.cs index 4c87cec..ad77219 100644 --- a/Capture/Hook/Common/TextElement.cs +++ b/Capture/Hook/Common/TextElement.cs @@ -5,13 +5,16 @@ namespace Capture.Hook.Common { + [Serializable] public class TextElement: Element { public virtual string Text { get; set; } - public virtual System.Drawing.Font Font { get; set; } - public virtual System.Drawing.Color Color { get; set; } + public virtual System.Drawing.Font Font { get; set; } = System.Drawing.SystemFonts.DefaultFont; + public virtual System.Drawing.Color Color { get; set; } = System.Drawing.Color.Black; public virtual System.Drawing.Point Location { get; set; } - public virtual bool AntiAliased { get; set; } + public virtual bool AntiAliased { get; set; } = false; + + public TextElement() { } public TextElement(System.Drawing.Font font) { diff --git a/Capture/Hook/DX11/DXOverlayEngine.cs b/Capture/Hook/DX11/DXOverlayEngine.cs index 3c2bafa..dcfa7de 100644 --- a/Capture/Hook/DX11/DXOverlayEngine.cs +++ b/Capture/Hook/DX11/DXOverlayEngine.cs @@ -38,7 +38,8 @@ public DXOverlayEngine() private void EnsureInitiliased() { - Debug.Assert(_initialised); + if (!_initialised) + throw new InvalidOperationException("DXOverlayEngine must be initialised."); } public bool Initialise(SharpDX.DXGI.SwapChain swapChain) @@ -48,7 +49,6 @@ public bool Initialise(SharpDX.DXGI.SwapChain swapChain) public bool Initialise(Device device, Texture2D renderTarget) { - Debug.Assert(!_initialised); if (_initialising) return false; @@ -82,7 +82,7 @@ public bool Initialise(Device device, Texture2D renderTarget) return false; // Initialise any resources required for overlay elements - IntialiseElementResources(); + InitialiseElementResources(); _initialised = true; return true; @@ -93,7 +93,7 @@ public bool Initialise(Device device, Texture2D renderTarget) } } - private void IntialiseElementResources() + void InitialiseElementResources() { foreach (var overlay in Overlays) { @@ -135,6 +135,9 @@ public void Draw() foreach (var overlay in Overlays) { + if (overlay.Hidden) + continue; + foreach (var element in overlay.Elements) { if (element.Hidden) @@ -175,7 +178,7 @@ DXFont GetFontForTextElement(TextElement element) { DXFont result = null; - string fontKey = String.Format("{0}{1}{2}", element.Font.Name, element.Font.Size, element.Font.Style, element.AntiAliased); + string fontKey = String.Format("{0}{1}{2}{3}", element.Font.Name, element.Font.Size, element.Font.Style, element.AntiAliased); if (!_fontCache.TryGetValue(fontKey, out result)) { diff --git a/Capture/Hook/DX9/DXOverlayEngine.cs b/Capture/Hook/DX9/DXOverlayEngine.cs index 08551fc..b496f8c 100644 --- a/Capture/Hook/DX9/DXOverlayEngine.cs +++ b/Capture/Hook/DX9/DXOverlayEngine.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Text; @@ -114,9 +115,17 @@ public void Draw() } else if (imageElement != null) { + //Apply the scaling of the imageElement + var rotation = Matrix.RotationZ(imageElement.Angle); + var scaling = Matrix.Scaling(imageElement.Scale); + _sprite.Transform = rotation * scaling; + Texture image = GetImageForImageElement(imageElement); if (image != null) _sprite.Draw(image, new SharpDX.ColorBGRA(imageElement.Tint.R, imageElement.Tint.G, imageElement.Tint.B, imageElement.Tint.A), null, null, new Vector3(imageElement.Location.X, imageElement.Location.Y, 0)); + + //Reset the transform for other elements + _sprite.Transform = Matrix.Identity; } } } @@ -149,7 +158,7 @@ Font GetFontForTextElement(TextElement element) { Font result = null; - string fontKey = String.Format("{0}{1}{2}", element.Font.Name, element.Font.Size, element.Font.Style, element.AntiAliased); + string fontKey = String.Format("{0}{1}{2}{3}", element.Font.Name, element.Font.Size, element.Font.Style, element.AntiAliased); if (!_fontCache.TryGetValue(fontKey, out result)) { @@ -178,6 +187,17 @@ Texture GetImageForImageElement(ImageElement element) _imageCache[element] = result; } } + else if (!_imageCache.TryGetValue(element, out result) && element.Bitmap != null) + { + using (var ms = new MemoryStream()) + { + element.Bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png); + ms.Seek(0, SeekOrigin.Begin); + result = ToDispose(Texture.FromStream(Device, ms)); + } + + _imageCache[element] = result; + } return result; } diff --git a/Capture/Hook/DXHookD3D11.cs b/Capture/Hook/DXHookD3D11.cs index fa74e3b..5e76343 100644 --- a/Capture/Hook/DXHookD3D11.cs +++ b/Capture/Hook/DXHookD3D11.cs @@ -11,6 +11,7 @@ using System.IO; using Capture.Interface; using SharpDX.Direct3D; +using Capture.Hook.Common; namespace Capture.Hook { @@ -508,30 +509,26 @@ int PresentHook(IntPtr swapChainPtr, int syncInterval, SharpDX.DXGI.PresentFlags #endregion #region Draw overlay (after screenshot so we don't capture overlay as well) - if (this.Config.ShowOverlay) + var displayOverlays = Overlays; + if (this.Config.ShowOverlay && displayOverlays != null) { // Initialise Overlay Engine - if (_swapChainPointer != swapChain.NativePointer || _overlayEngine == null) + if (_swapChainPointer != swapChain.NativePointer || _overlayEngine == null + || IsOverlayUpdatePending) { if (_overlayEngine != null) _overlayEngine.Dispose(); _overlayEngine = new DX11.DXOverlayEngine(); - _overlayEngine.Overlays.Add(new Capture.Hook.Common.Overlay - { - Elements = - { - //new Capture.Hook.Common.TextElement(new System.Drawing.Font("Times New Roman", 22)) { Text = "Test", Location = new System.Drawing.Point(200, 200), Color = System.Drawing.Color.Yellow, AntiAliased = false}, - new Capture.Hook.Common.FramesPerSecond(new System.Drawing.Font("Arial", 16)) { Location = new System.Drawing.Point(5,5), Color = System.Drawing.Color.Red, AntiAliased = true }, - //new Capture.Hook.Common.ImageElement(@"C:\Temp\test.bmp") { Location = new System.Drawing.Point(20, 20) } - } - }); + _overlayEngine.Overlays.AddRange((IEnumerable)displayOverlays); _overlayEngine.Initialise(swapChain); _swapChainPointer = swapChain.NativePointer; + + IsOverlayUpdatePending = false; } // Draw Overlay(s) - else if (_overlayEngine != null) + if (_overlayEngine != null) { foreach (var overlay in _overlayEngine.Overlays) overlay.Frame(); diff --git a/Capture/Hook/DXHookD3D9.cs b/Capture/Hook/DXHookD3D9.cs index 22a74d9..31d660b 100644 --- a/Capture/Hook/DXHookD3D9.cs +++ b/Capture/Hook/DXHookD3D9.cs @@ -10,6 +10,7 @@ using System.Drawing; using Capture.Interface; using SharpDX.Direct3D9; +using Capture.Hook.Common; namespace Capture.Hook { @@ -377,34 +378,26 @@ void DoCaptureRenderTarget(Device device, string hook) #endregion - if (this.Config.ShowOverlay) + var displayOverlays = Overlays; + if (this.Config.ShowOverlay && displayOverlays != null) { #region Draw Overlay // Check if overlay needs to be initialised - if (_overlayEngine == null || _overlayEngine.Device.NativePointer != device.NativePointer) + if (_overlayEngine == null || _overlayEngine.Device.NativePointer != device.NativePointer + || IsOverlayUpdatePending) { // Cleanup if necessary if (_overlayEngine != null) RemoveAndDispose(ref _overlayEngine); _overlayEngine = ToDispose(new DX9.DXOverlayEngine()); - // Create Overlay - _overlayEngine.Overlays.Add(new Capture.Hook.Common.Overlay - { - Elements = - { - // Add frame rate - new Capture.Hook.Common.FramesPerSecond(new System.Drawing.Font("Arial", 16, FontStyle.Bold)) { Location = new System.Drawing.Point(5,5), Color = System.Drawing.Color.Red, AntiAliased = true }, - // Example of adding an image to overlay (can implement semi transparency with Tint, e.g. Ting = Color.FromArgb(127, 255, 255, 255)) - //new Capture.Hook.Common.ImageElement(@"C:\Temp\test.bmp") { Location = new System.Drawing.Point(20, 20) } - } - }); - + _overlayEngine.Overlays.AddRange((IEnumerable)displayOverlays); _overlayEngine.Initialise(device); + IsOverlayUpdatePending = false; } // Draw Overlay(s) - else if (_overlayEngine != null) + if (_overlayEngine != null) { foreach (var overlay in _overlayEngine.Overlays) overlay.Frame(); diff --git a/Capture/Interface/CaptureInterface.cs b/Capture/Interface/CaptureInterface.cs index ff4f10c..d381096 100644 --- a/Capture/Interface/CaptureInterface.cs +++ b/Capture/Interface/CaptureInterface.cs @@ -4,6 +4,7 @@ using System.Text; using System.Drawing; using System.Threading; +using Capture.Hook.Common; namespace Capture.Interface { @@ -21,6 +22,8 @@ namespace Capture.Interface public delegate void ScreenshotRequestedEvent(ScreenshotRequest request); [Serializable] public delegate void DisplayTextEvent(DisplayTextEventArgs args); + [Serializable] + public delegate void DrawOverlayEvent(DrawOverlayEventArgs args); [Serializable] public class CaptureInterface : MarshalByRefObject @@ -73,6 +76,11 @@ public class CaptureInterface : MarshalByRefObject /// public event DisplayTextEvent DisplayText; + /// + /// Client event used to (re-)draw an overlay in-game. + /// + public event DrawOverlayEvent DrawOverlay; + #endregion #endregion @@ -239,6 +247,20 @@ public void DisplayInGameText(string text, TimeSpan duration) SafeInvokeDisplayText(new DisplayTextEventArgs(text, duration)); } + /// + /// Replace the in-game overlay with the one provided. + /// + /// Note: this is not designed for fast updates (i.e. only a couple of times per second) + /// + /// + public void DrawOverlayInGame(IOverlay overlay) + { + SafeInvokeDrawOverlay(new DrawOverlayEventArgs() + { + Overlay = overlay + }); + } + #endregion #region Private: Invoke message handlers @@ -411,14 +433,38 @@ private void SafeInvokeDisplayText(DisplayTextEventArgs displayTextEventArgs) } } + private void SafeInvokeDrawOverlay(DrawOverlayEventArgs drawOverlayEventArgs) + { + if (DrawOverlay == null) + return; //No Listeners + + DrawOverlayEvent listener = null; + var dels = DrawOverlay.GetInvocationList(); + + foreach (var del in dels) + { + try + { + listener = (DrawOverlayEvent)del; + listener.Invoke(drawOverlayEventArgs); + } + catch (Exception) + { + //Could not reach the destination, so remove it + //from the list + DrawOverlay -= listener; + } + } + } + #endregion /// - /// Used + /// Used to confirm connection to IPC server channel /// - public void Ping() + public DateTime Ping() { - + return DateTime.Now; } } @@ -455,6 +501,11 @@ public class ClientCaptureInterfaceEventProxy : MarshalByRefObject /// public event DisplayTextEvent DisplayText; + /// + /// Client event used to (re-)draw an overlay in-game. + /// + public event DrawOverlayEvent DrawOverlay; + #endregion #region Lifetime Services @@ -498,5 +549,11 @@ public void DisplayTextProxyHandler(DisplayTextEventArgs args) if (DisplayText != null) DisplayText(args); } + + public void DrawOverlayProxyHandler(DrawOverlayEventArgs args) + { + if (DrawOverlay != null) + DrawOverlay(args); + } } } diff --git a/Capture/Interface/DrawOverlayEventArgs.cs b/Capture/Interface/DrawOverlayEventArgs.cs new file mode 100644 index 0000000..128d58f --- /dev/null +++ b/Capture/Interface/DrawOverlayEventArgs.cs @@ -0,0 +1,24 @@ +using Capture.Hook.Common; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Capture.Interface +{ + /// + /// Note: Deliberately not using MarshalByRefObj + /// + [Serializable] + public class DrawOverlayEventArgs + { + public IOverlay Overlay { get; set; } + + public bool IsUpdatePending { get; set; } + + public DrawOverlayEventArgs() + { + } + } +} diff --git a/TestScreenshot/Form1.Designer.cs b/TestScreenshot/Form1.Designer.cs index 9b44b8e..c8d4f88 100644 --- a/TestScreenshot/Form1.Designer.cs +++ b/TestScreenshot/Form1.Designer.cs @@ -62,15 +62,15 @@ private void InitializeComponent() this.label11 = new System.Windows.Forms.Label(); this.label12 = new System.Windows.Forms.Label(); this.cmbFormat = new System.Windows.Forms.ComboBox(); + this.btnDisplayOverlay = new System.Windows.Forms.Button(); ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); this.SuspendLayout(); // // btnInject // - this.btnInject.Location = new System.Drawing.Point(168, 46); - this.btnInject.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.btnInject.Location = new System.Drawing.Point(112, 30); this.btnInject.Name = "btnInject"; - this.btnInject.Size = new System.Drawing.Size(111, 35); + this.btnInject.Size = new System.Drawing.Size(74, 23); this.btnInject.TabIndex = 0; this.btnInject.Text = "Inject"; this.btnInject.UseVisualStyleBackColor = true; @@ -79,10 +79,9 @@ private void InitializeComponent() // btnCapture // this.btnCapture.Enabled = false; - this.btnCapture.Location = new System.Drawing.Point(168, 91); - this.btnCapture.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.btnCapture.Location = new System.Drawing.Point(112, 59); this.btnCapture.Name = "btnCapture"; - this.btnCapture.Size = new System.Drawing.Size(112, 63); + this.btnCapture.Size = new System.Drawing.Size(75, 41); this.btnCapture.TabIndex = 1; this.btnCapture.Text = "Request Capture"; this.btnCapture.UseVisualStyleBackColor = true; @@ -93,20 +92,18 @@ private void InitializeComponent() this.pictureBox1.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.pictureBox1.Location = new System.Drawing.Point(290, 20); - this.pictureBox1.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.pictureBox1.Location = new System.Drawing.Point(193, 13); this.pictureBox1.Name = "pictureBox1"; - this.pictureBox1.Size = new System.Drawing.Size(1196, 623); + this.pictureBox1.Size = new System.Drawing.Size(797, 405); this.pictureBox1.TabIndex = 2; this.pictureBox1.TabStop = false; // // btnLoadTest // this.btnLoadTest.Enabled = false; - this.btnLoadTest.Location = new System.Drawing.Point(168, 163); - this.btnLoadTest.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.btnLoadTest.Location = new System.Drawing.Point(112, 106); this.btnLoadTest.Name = "btnLoadTest"; - this.btnLoadTest.Size = new System.Drawing.Size(112, 35); + this.btnLoadTest.Size = new System.Drawing.Size(75, 23); this.btnLoadTest.TabIndex = 3; this.btnLoadTest.Text = "Load Test"; this.btnLoadTest.UseVisualStyleBackColor = true; @@ -114,112 +111,100 @@ private void InitializeComponent() // // txtNumber // - this.txtNumber.Location = new System.Drawing.Point(9, 166); - this.txtNumber.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.txtNumber.Location = new System.Drawing.Point(6, 108); this.txtNumber.Name = "txtNumber"; - this.txtNumber.Size = new System.Drawing.Size(148, 26); + this.txtNumber.Size = new System.Drawing.Size(100, 20); this.txtNumber.TabIndex = 4; this.txtNumber.Text = "100"; // // progressBar1 // - this.progressBar1.Location = new System.Drawing.Point(9, 208); - this.progressBar1.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.progressBar1.Location = new System.Drawing.Point(6, 135); this.progressBar1.Name = "progressBar1"; - this.progressBar1.Size = new System.Drawing.Size(270, 35); + this.progressBar1.Size = new System.Drawing.Size(180, 23); this.progressBar1.TabIndex = 5; // // textBox1 // - this.textBox1.Location = new System.Drawing.Point(12, 49); - this.textBox1.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.textBox1.Location = new System.Drawing.Point(8, 32); this.textBox1.Name = "textBox1"; - this.textBox1.Size = new System.Drawing.Size(145, 26); + this.textBox1.Size = new System.Drawing.Size(98, 20); this.textBox1.TabIndex = 6; // // label1 // this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(18, 277); - this.label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.label1.Location = new System.Drawing.Point(12, 180); this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(20, 20); + this.label1.Size = new System.Drawing.Size(14, 13); this.label1.TabIndex = 7; this.label1.Text = "X"; // // label2 // this.label2.AutoSize = true; - this.label2.Location = new System.Drawing.Point(180, 277); - this.label2.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.label2.Location = new System.Drawing.Point(120, 180); this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(20, 20); + this.label2.Size = new System.Drawing.Size(14, 13); this.label2.TabIndex = 8; this.label2.Text = "Y"; // // label3 // this.label3.AutoSize = true; - this.label3.Location = new System.Drawing.Point(10, 317); - this.label3.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.label3.Location = new System.Drawing.Point(7, 206); this.label3.Name = "label3"; - this.label3.Size = new System.Drawing.Size(50, 20); + this.label3.Size = new System.Drawing.Size(35, 13); this.label3.TabIndex = 9; this.label3.Text = "Width"; // // label4 // this.label4.AutoSize = true; - this.label4.Location = new System.Drawing.Point(144, 317); - this.label4.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.label4.Location = new System.Drawing.Point(96, 206); this.label4.Name = "label4"; - this.label4.Size = new System.Drawing.Size(56, 20); + this.label4.Size = new System.Drawing.Size(38, 13); this.label4.TabIndex = 10; this.label4.Text = "Height"; // // txtCaptureX // - this.txtCaptureX.Location = new System.Drawing.Point(64, 272); - this.txtCaptureX.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.txtCaptureX.Location = new System.Drawing.Point(43, 177); this.txtCaptureX.Name = "txtCaptureX"; - this.txtCaptureX.Size = new System.Drawing.Size(68, 26); + this.txtCaptureX.Size = new System.Drawing.Size(47, 20); this.txtCaptureX.TabIndex = 11; this.txtCaptureX.Text = "0"; // // txtCaptureY // - this.txtCaptureY.Location = new System.Drawing.Point(210, 272); - this.txtCaptureY.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.txtCaptureY.Location = new System.Drawing.Point(140, 177); this.txtCaptureY.Name = "txtCaptureY"; - this.txtCaptureY.Size = new System.Drawing.Size(68, 26); + this.txtCaptureY.Size = new System.Drawing.Size(47, 20); this.txtCaptureY.TabIndex = 12; this.txtCaptureY.Text = "0"; // // txtCaptureWidth // - this.txtCaptureWidth.Location = new System.Drawing.Point(64, 312); - this.txtCaptureWidth.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.txtCaptureWidth.Location = new System.Drawing.Point(43, 203); this.txtCaptureWidth.Name = "txtCaptureWidth"; - this.txtCaptureWidth.Size = new System.Drawing.Size(68, 26); + this.txtCaptureWidth.Size = new System.Drawing.Size(47, 20); this.txtCaptureWidth.TabIndex = 13; this.txtCaptureWidth.Text = "0"; // // txtCaptureHeight // - this.txtCaptureHeight.Location = new System.Drawing.Point(210, 312); - this.txtCaptureHeight.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.txtCaptureHeight.Location = new System.Drawing.Point(140, 203); this.txtCaptureHeight.Name = "txtCaptureHeight"; - this.txtCaptureHeight.Size = new System.Drawing.Size(68, 26); + this.txtCaptureHeight.Size = new System.Drawing.Size(47, 20); this.txtCaptureHeight.TabIndex = 14; this.txtCaptureHeight.Text = "0"; // // label5 // this.label5.AutoSize = true; - this.label5.Location = new System.Drawing.Point(10, 348); - this.label5.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.label5.Location = new System.Drawing.Point(7, 226); this.label5.Name = "label5"; - this.label5.Size = new System.Drawing.Size(271, 20); + this.label5.Size = new System.Drawing.Size(184, 13); this.label5.TabIndex = 15; this.label5.Text = "Width of 0 means capture full window"; // @@ -227,41 +212,37 @@ private void InitializeComponent() // this.txtDebugLog.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.txtDebugLog.Location = new System.Drawing.Point(8, 652); - this.txtDebugLog.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.txtDebugLog.Location = new System.Drawing.Point(5, 424); this.txtDebugLog.Multiline = true; this.txtDebugLog.Name = "txtDebugLog"; this.txtDebugLog.ScrollBars = System.Windows.Forms.ScrollBars.Both; - this.txtDebugLog.Size = new System.Drawing.Size(1476, 136); + this.txtDebugLog.Size = new System.Drawing.Size(985, 90); this.txtDebugLog.TabIndex = 16; // // label6 // this.label6.AutoSize = true; - this.label6.Location = new System.Drawing.Point(8, 25); - this.label6.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.label6.Location = new System.Drawing.Point(5, 16); this.label6.Name = "label6"; - this.label6.Size = new System.Drawing.Size(259, 20); + this.label6.Size = new System.Drawing.Size(174, 13); this.label6.TabIndex = 17; this.label6.Text = "EXE Name of Direct3D Application:"; // // label7 // this.label7.AutoSize = true; - this.label7.Location = new System.Drawing.Point(10, 142); - this.label7.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.label7.Location = new System.Drawing.Point(7, 92); this.label7.Name = "label7"; - this.label7.Size = new System.Drawing.Size(128, 20); + this.label7.Size = new System.Drawing.Size(86, 13); this.label7.TabIndex = 18; this.label7.Text = "Capture Multiple:"; // // cbAutoGAC // this.cbAutoGAC.AutoSize = true; - this.cbAutoGAC.Location = new System.Drawing.Point(8, 582); - this.cbAutoGAC.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.cbAutoGAC.Location = new System.Drawing.Point(5, 378); this.cbAutoGAC.Name = "cbAutoGAC"; - this.cbAutoGAC.Size = new System.Drawing.Size(270, 24); + this.cbAutoGAC.Size = new System.Drawing.Size(179, 17); this.cbAutoGAC.TabIndex = 25; this.cbAutoGAC.Text = "Auto register GAC (run as admin)"; this.cbAutoGAC.UseVisualStyleBackColor = true; @@ -269,10 +250,9 @@ private void InitializeComponent() // rbDirect3D9 // this.rbDirect3D9.AutoSize = true; - this.rbDirect3D9.Location = new System.Drawing.Point(140, 475); - this.rbDirect3D9.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.rbDirect3D9.Location = new System.Drawing.Point(93, 309); this.rbDirect3D9.Name = "rbDirect3D9"; - this.rbDirect3D9.Size = new System.Drawing.Size(110, 24); + this.rbDirect3D9.Size = new System.Drawing.Size(76, 17); this.rbDirect3D9.TabIndex = 21; this.rbDirect3D9.Text = "Direct3D 9"; this.rbDirect3D9.UseVisualStyleBackColor = true; @@ -280,10 +260,9 @@ private void InitializeComponent() // rbDirect3D10 // this.rbDirect3D10.AutoSize = true; - this.rbDirect3D10.Location = new System.Drawing.Point(15, 511); - this.rbDirect3D10.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.rbDirect3D10.Location = new System.Drawing.Point(10, 332); this.rbDirect3D10.Name = "rbDirect3D10"; - this.rbDirect3D10.Size = new System.Drawing.Size(119, 24); + this.rbDirect3D10.Size = new System.Drawing.Size(82, 17); this.rbDirect3D10.TabIndex = 22; this.rbDirect3D10.Text = "Direct3D 10"; this.rbDirect3D10.UseVisualStyleBackColor = true; @@ -291,10 +270,9 @@ private void InitializeComponent() // rbDirect3D11 // this.rbDirect3D11.AutoSize = true; - this.rbDirect3D11.Location = new System.Drawing.Point(15, 546); - this.rbDirect3D11.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.rbDirect3D11.Location = new System.Drawing.Point(10, 355); this.rbDirect3D11.Name = "rbDirect3D11"; - this.rbDirect3D11.Size = new System.Drawing.Size(119, 24); + this.rbDirect3D11.Size = new System.Drawing.Size(82, 17); this.rbDirect3D11.TabIndex = 24; this.rbDirect3D11.Text = "Direct3D 11"; this.rbDirect3D11.UseVisualStyleBackColor = true; @@ -304,10 +282,9 @@ private void InitializeComponent() this.cbDrawOverlay.AutoSize = true; this.cbDrawOverlay.Checked = true; this.cbDrawOverlay.CheckState = System.Windows.Forms.CheckState.Checked; - this.cbDrawOverlay.Location = new System.Drawing.Point(8, 617); - this.cbDrawOverlay.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.cbDrawOverlay.Location = new System.Drawing.Point(5, 401); this.cbDrawOverlay.Name = "cbDrawOverlay"; - this.cbDrawOverlay.Size = new System.Drawing.Size(128, 24); + this.cbDrawOverlay.Size = new System.Drawing.Size(90, 17); this.cbDrawOverlay.TabIndex = 26; this.cbDrawOverlay.Text = "Draw Overlay"; this.cbDrawOverlay.UseVisualStyleBackColor = true; @@ -316,10 +293,9 @@ private void InitializeComponent() // this.rbAutodetect.AutoSize = true; this.rbAutodetect.Checked = true; - this.rbAutodetect.Location = new System.Drawing.Point(15, 475); - this.rbAutodetect.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.rbAutodetect.Location = new System.Drawing.Point(10, 309); this.rbAutodetect.Name = "rbAutodetect"; - this.rbAutodetect.Size = new System.Drawing.Size(113, 24); + this.rbAutodetect.Size = new System.Drawing.Size(77, 17); this.rbAutodetect.TabIndex = 20; this.rbAutodetect.TabStop = true; this.rbAutodetect.Text = "Autodetect"; @@ -328,10 +304,9 @@ private void InitializeComponent() // rbDirect3D10_1 // this.rbDirect3D10_1.AutoSize = true; - this.rbDirect3D10_1.Location = new System.Drawing.Point(140, 511); - this.rbDirect3D10_1.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.rbDirect3D10_1.Location = new System.Drawing.Point(93, 332); this.rbDirect3D10_1.Name = "rbDirect3D10_1"; - this.rbDirect3D10_1.Size = new System.Drawing.Size(132, 24); + this.rbDirect3D10_1.Size = new System.Drawing.Size(91, 17); this.rbDirect3D10_1.TabIndex = 23; this.rbDirect3D10_1.Text = "Direct3D 10.1"; this.rbDirect3D10_1.UseVisualStyleBackColor = true; @@ -339,66 +314,59 @@ private void InitializeComponent() // label8 // this.label8.AutoSize = true; - this.label8.Location = new System.Drawing.Point(9, 252); - this.label8.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.label8.Location = new System.Drawing.Point(6, 164); this.label8.Name = "label8"; - this.label8.Size = new System.Drawing.Size(77, 20); + this.label8.Size = new System.Drawing.Size(52, 13); this.label8.TabIndex = 27; this.label8.Text = "REGION:"; // // label9 // this.label9.AutoSize = true; - this.label9.Location = new System.Drawing.Point(8, 371); - this.label9.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.label9.Location = new System.Drawing.Point(5, 241); this.label9.Name = "label9"; - this.label9.Size = new System.Drawing.Size(73, 20); + this.label9.Size = new System.Drawing.Size(49, 13); this.label9.TabIndex = 28; this.label9.Text = "RESIZE:"; // // txtResizeHeight // - this.txtResizeHeight.Location = new System.Drawing.Point(210, 392); - this.txtResizeHeight.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.txtResizeHeight.Location = new System.Drawing.Point(140, 255); this.txtResizeHeight.Name = "txtResizeHeight"; - this.txtResizeHeight.Size = new System.Drawing.Size(68, 26); + this.txtResizeHeight.Size = new System.Drawing.Size(47, 20); this.txtResizeHeight.TabIndex = 32; // // txtResizeWidth // - this.txtResizeWidth.Location = new System.Drawing.Point(64, 392); - this.txtResizeWidth.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.txtResizeWidth.Location = new System.Drawing.Point(43, 255); this.txtResizeWidth.Name = "txtResizeWidth"; - this.txtResizeWidth.Size = new System.Drawing.Size(68, 26); + this.txtResizeWidth.Size = new System.Drawing.Size(47, 20); this.txtResizeWidth.TabIndex = 31; // // label10 // this.label10.AutoSize = true; - this.label10.Location = new System.Drawing.Point(144, 397); - this.label10.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.label10.Location = new System.Drawing.Point(96, 258); this.label10.Name = "label10"; - this.label10.Size = new System.Drawing.Size(56, 20); + this.label10.Size = new System.Drawing.Size(38, 13); this.label10.TabIndex = 30; this.label10.Text = "Height"; // // label11 // this.label11.AutoSize = true; - this.label11.Location = new System.Drawing.Point(10, 397); - this.label11.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.label11.Location = new System.Drawing.Point(7, 258); this.label11.Name = "label11"; - this.label11.Size = new System.Drawing.Size(50, 20); + this.label11.Size = new System.Drawing.Size(35, 13); this.label11.TabIndex = 29; this.label11.Text = "Width"; // // label12 // this.label12.AutoSize = true; - this.label12.Location = new System.Drawing.Point(4, 437); - this.label12.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.label12.Location = new System.Drawing.Point(3, 284); this.label12.Name = "label12"; - this.label12.Size = new System.Drawing.Size(80, 20); + this.label12.Size = new System.Drawing.Size(55, 13); this.label12.TabIndex = 33; this.label12.Text = "FORMAT:"; // @@ -410,18 +378,28 @@ private void InitializeComponent() "Jpeg", "Png", "PixelData"}); - this.cmbFormat.Location = new System.Drawing.Point(98, 434); - this.cmbFormat.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.cmbFormat.Location = new System.Drawing.Point(65, 282); this.cmbFormat.Name = "cmbFormat"; - this.cmbFormat.Size = new System.Drawing.Size(180, 28); + this.cmbFormat.Size = new System.Drawing.Size(121, 21); this.cmbFormat.TabIndex = 34; this.cmbFormat.Text = "Bitmap"; // + // btnDisplayOverlay + // + this.btnDisplayOverlay.Location = new System.Drawing.Point(94, 397); + this.btnDisplayOverlay.Name = "btnDisplayOverlay"; + this.btnDisplayOverlay.Size = new System.Drawing.Size(75, 23); + this.btnDisplayOverlay.TabIndex = 35; + this.btnDisplayOverlay.Text = "Display"; + this.btnDisplayOverlay.UseVisualStyleBackColor = true; + this.btnDisplayOverlay.Click += new System.EventHandler(this.btnDisplayOverlay_Click); + // // Form1 // - this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F); + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(1503, 809); + this.ClientSize = new System.Drawing.Size(1002, 526); + this.Controls.Add(this.btnDisplayOverlay); this.Controls.Add(this.cmbFormat); this.Controls.Add(this.label12); this.Controls.Add(this.txtResizeHeight); @@ -456,7 +434,6 @@ private void InitializeComponent() this.Controls.Add(this.pictureBox1); this.Controls.Add(this.btnCapture); this.Controls.Add(this.btnInject); - this.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); this.Name = "Form1"; this.Text = "Test Screenshot Direct3D API Hook"; this.Load += new System.EventHandler(this.Form1_Load); @@ -502,6 +479,7 @@ private void InitializeComponent() private System.Windows.Forms.Label label11; private System.Windows.Forms.Label label12; private System.Windows.Forms.ComboBox cmbFormat; + private System.Windows.Forms.Button btnDisplayOverlay; } } diff --git a/TestScreenshot/Form1.cs b/TestScreenshot/Form1.cs index 7be56d8..02e9dbf 100644 --- a/TestScreenshot/Form1.cs +++ b/TestScreenshot/Form1.cs @@ -258,5 +258,22 @@ void Callback(IAsyncResult result) { } } + + private void btnDisplayOverlay_Click(object sender, EventArgs e) + { + _captureProcess.CaptureInterface.DrawOverlayInGame(new Capture.Hook.Common.Overlay + { + Elements = new List + { + new Capture.Hook.Common.FramesPerSecond(new System.Drawing.Font("Arial", 16, FontStyle.Bold)) { + Location = new Point(25, 25), + Color = Color.Red, + AntiAliased = true, + Text = "{0:N0} fps" + }, + }, + Hidden = !cbDrawOverlay.Checked + }); + } } }