first commit
This commit is contained in:
16
src/Overlay.NET/App.config
Normal file
16
src/Overlay.NET/App.config
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" />
|
||||
</startup>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="SharpDX" publicKeyToken="b4dcf0f35e5521f1" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.2.0.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
|
||||
</configuration>
|
||||
58
src/Overlay.NET/Common/FileLogger.cs
Normal file
58
src/Overlay.NET/Common/FileLogger.cs
Normal file
@@ -0,0 +1,58 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
|
||||
namespace Overlay.NET.Common {
|
||||
public sealed class FileLogger : ILogger {
|
||||
public string Path { get; set; }
|
||||
|
||||
public bool IsDisposed { get; set; }
|
||||
public bool MustBeDisposed { get; set; } = true;
|
||||
|
||||
public void WriteLine(string entry) {
|
||||
try {
|
||||
_stream.WriteLine(entry);
|
||||
}
|
||||
|
||||
catch (Exception e) {
|
||||
Trace.WriteLine(e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public static readonly FileLogger Instance = new FileLogger();
|
||||
|
||||
private readonly StreamWriter _stream;
|
||||
|
||||
public FileLogger(RelativeFile file) {
|
||||
Path = file.GetFullPath();
|
||||
_stream = new StreamWriter(Path, true) {AutoFlush = true};
|
||||
}
|
||||
|
||||
public FileLogger(string file) {
|
||||
Path = file;
|
||||
_stream = new StreamWriter(Path, true) {AutoFlush = true};
|
||||
}
|
||||
|
||||
private FileLogger() {
|
||||
var file = new RelativeFile {
|
||||
Name = "AppLog",
|
||||
Extension = ".txt",
|
||||
SubDirectory = "Logs",
|
||||
TimeStampFile = true,
|
||||
UseDetailedTimeStamp = false
|
||||
};
|
||||
|
||||
Path = file.GetFullPath();
|
||||
_stream = new StreamWriter(Path, true) {AutoFlush = true};
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
if (IsDisposed) {
|
||||
return;
|
||||
}
|
||||
IsDisposed = true;
|
||||
_stream.Flush();
|
||||
_stream.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
42
src/Overlay.NET/Common/ISerializer.cs
Normal file
42
src/Overlay.NET/Common/ISerializer.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using System.Text;
|
||||
|
||||
namespace Overlay.NET.Common {
|
||||
/// <summary>
|
||||
/// Interface that defines common ways to serialize/deserialize objects to and from strings.
|
||||
/// </summary>
|
||||
public interface ISerializer {
|
||||
/// <summary>
|
||||
/// Serializes the specified object and returns the document.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the object to serialize.</typeparam>
|
||||
/// <param name="obj">The object to serialize.</param>
|
||||
/// <returns>XML document of the serialized object.</returns>
|
||||
string ExportToString<T>(T obj);
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes the document to the specified object.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the object to deserialize.</typeparam>
|
||||
/// <param name="serializedObj">The string representing the serialized object.</param>
|
||||
/// <returns>The deserialized object.</returns>
|
||||
T ImportFromString<T>(string serializedObj);
|
||||
|
||||
/// <summary>
|
||||
/// Serializes the specified object and writes the document to the specified path.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the object to serialize.</typeparam>
|
||||
/// <param name="obj">The object to serialize.</param>
|
||||
/// <param name="file">The path where the file is saved.</param>
|
||||
/// <param name="encoding">The encoding to generate.</param>
|
||||
void ExportToFile<T>(T obj, string file, Encoding encoding);
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes the specified file into an object.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the object to deserialize.</typeparam>
|
||||
/// <param name="path">The path where the object is read.</param>
|
||||
/// <param name="encoding">The character encoding to use. </param>
|
||||
/// <returns>The deserialized object.</returns>
|
||||
T ImportFromFile<T>(string path, Encoding encoding);
|
||||
}
|
||||
}
|
||||
27
src/Overlay.NET/Common/ISettings.cs
Normal file
27
src/Overlay.NET/Common/ISettings.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
namespace Overlay.NET.Common {
|
||||
/// <summary>
|
||||
/// Interface that defines a way to load and save settings.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public interface ISettings<out T> {
|
||||
/// <summary>
|
||||
/// Gets the current settings instance
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The current settings.
|
||||
/// </value>
|
||||
T Current { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Saves the settings to the specified target.
|
||||
/// </summary>
|
||||
/// <param name="target">The target.</param>
|
||||
void Save(string target = "");
|
||||
|
||||
/// <summary>
|
||||
/// Loads the settings from the specified location.
|
||||
/// </summary>
|
||||
/// <param name="location">The location.</param>
|
||||
void Load(string location = "");
|
||||
}
|
||||
}
|
||||
67
src/Overlay.NET/Common/Log.cs
Normal file
67
src/Overlay.NET/Common/Log.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Overlay.NET.Common {
|
||||
public enum LogLevel {
|
||||
Normal,
|
||||
Debug,
|
||||
Information,
|
||||
Warning,
|
||||
Error,
|
||||
Fatal
|
||||
}
|
||||
|
||||
public interface ILogger {
|
||||
void WriteLine(string line);
|
||||
}
|
||||
|
||||
public static class Log {
|
||||
public static Func<LogLevel, string, object[], string> LogFormatterFunc { get; set; }
|
||||
|
||||
private static Dictionary<string, ILogger> Loggers { get; }
|
||||
|
||||
static Log() {
|
||||
Loggers = new Dictionary<string, ILogger>();
|
||||
LogFormatterFunc = DefaultFormatter;
|
||||
Loggers.Add("File", FileLogger.Instance);
|
||||
}
|
||||
|
||||
public static void Register(string publicKey, ILogger logger) => Loggers.Add(publicKey, logger);
|
||||
|
||||
public static bool Unregister(string publicKey) => Loggers.Remove(publicKey);
|
||||
|
||||
public static ILogger Get(string key) => !Loggers.ContainsKey(key) ? Loggers["File"] : Loggers[key];
|
||||
|
||||
public static void WriteLine(string format, params object[] args) => WriteLogEntry(LogLevel.Normal, format, args);
|
||||
|
||||
public static void Debug(string format, params object[] args) => WriteLogEntry(LogLevel.Debug, format, args);
|
||||
|
||||
public static void Info(string format, params object[] args) => WriteLogEntry(LogLevel.Information, format, args);
|
||||
|
||||
public static void Warn(string format, params object[] args) => WriteLogEntry(LogLevel.Warning, format, args);
|
||||
|
||||
public static void Error(string format, params object[] args) => WriteLogEntry(LogLevel.Error, format, args);
|
||||
|
||||
public static void Fatal(string format, params object[] args) => WriteLogEntry(LogLevel.Fatal, format, args);
|
||||
|
||||
private static void WriteLogEntry(LogLevel logLevel, string format, params object[] args) {
|
||||
var formatted = LogFormatterFunc(logLevel, format, args);
|
||||
|
||||
foreach (var logger in Loggers.ToArray()) {
|
||||
logger.Value.WriteLine(formatted);
|
||||
}
|
||||
}
|
||||
|
||||
private static string DefaultFormatter(LogLevel type, string format, params object[] args) {
|
||||
if (args != null && args.Any()) {
|
||||
format = string.Format(format, args);
|
||||
}
|
||||
|
||||
var time = DateTime.Now;
|
||||
var logType = type == LogLevel.Normal ? "" : $"[{type}]";
|
||||
|
||||
return $"{logType}[{time}] {format}";
|
||||
}
|
||||
}
|
||||
}
|
||||
91
src/Overlay.NET/Common/Native.cs
Normal file
91
src/Overlay.NET/Common/Native.cs
Normal file
@@ -0,0 +1,91 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Overlay.NET.Common {
|
||||
internal class Native {
|
||||
[DllImport("user32.dll")]
|
||||
public static extern IntPtr CreateWindowEx(
|
||||
uint dwExStyle,
|
||||
string lpClassName,
|
||||
string lpWindowName,
|
||||
uint dwStyle,
|
||||
int x,
|
||||
int y,
|
||||
int nWidth,
|
||||
int nHeight,
|
||||
IntPtr hWndParent,
|
||||
IntPtr hMenu,
|
||||
IntPtr hInstance,
|
||||
IntPtr lpParam);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern int DestroyWindow(IntPtr hwnd);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern int SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int y, int cx, int cy,
|
||||
uint uFlags);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern IntPtr GetDesktopWindow();
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern int GetSystemMetrics(int index);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern int ShowWindow(IntPtr hWnd, uint nCmdShow);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern int GetWindowRect(IntPtr hwnd, out Rect lpRect);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool SetLayeredWindowAttributes(IntPtr hwnd, uint crKey, byte bAlpha, uint dwFlags);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool UpdateLayeredWindow(IntPtr hwnd, IntPtr hdc, ref Point point, ref Point size,
|
||||
IntPtr hdcSrc, IntPtr pptSrc, int crKey, IntPtr blend, uint flags);
|
||||
|
||||
[DllImport("dwmapi.dll")]
|
||||
public static extern void DwmExtendFrameIntoClientArea(IntPtr hWnd, ref RawMargin pMargins);
|
||||
|
||||
public static IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr dwNewLong)
|
||||
=> IntPtr.Size == 8 ? SetWindowLongPtr64(hWnd, nIndex, dwNewLong) : new IntPtr(SetWindowLong32(hWnd, nIndex, dwNewLong.ToInt32()));
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "SetWindowLong")]
|
||||
private static extern int SetWindowLong32(IntPtr hWnd, int nIndex, int dwNewLong);
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "SetWindowLongPtr")]
|
||||
private static extern IntPtr SetWindowLongPtr64(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "GetWindowLong")]
|
||||
private static extern IntPtr GetWindowLongPtr32(IntPtr hWnd, int nIndex);
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "GetWindowLongPtr")]
|
||||
private static extern IntPtr GetWindowLongPtr64(IntPtr hWnd, int nIndex);
|
||||
|
||||
// This static method is required because Win32 does not support
|
||||
// GetWindowLongPtr directly
|
||||
public static IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex) => IntPtr.Size == 8 ? GetWindowLongPtr64(hWnd, nIndex) : GetWindowLongPtr32(hWnd, nIndex);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct Rect {
|
||||
public int Left;
|
||||
public int Top;
|
||||
public int Right;
|
||||
public int Bottom;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct Point {
|
||||
public int X;
|
||||
public int Y;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct RawMargin {
|
||||
public int cxLeftWidth;
|
||||
public int cxRightWidth;
|
||||
public int cyTopHeight;
|
||||
public int cyBottomHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
123
src/Overlay.NET/Common/PluginBase.cs
Normal file
123
src/Overlay.NET/Common/PluginBase.cs
Normal file
@@ -0,0 +1,123 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Overlay.NET.Common {
|
||||
/// <summary>
|
||||
/// The abstract base class for plugins.
|
||||
/// </summary>
|
||||
public abstract class PluginBase {
|
||||
/// <summary>
|
||||
/// Gets the plugin's Author, or empty string if it fails.
|
||||
/// </summary>
|
||||
/// <param name="type">The plugin's Type.</param>
|
||||
/// <returns>The plugin's Author, or empty string if it fails.</returns>
|
||||
public static string GetAuthor(Type type) {
|
||||
var attribute = GetAttribute(type);
|
||||
return attribute == null ? string.Empty : attribute.Author ?? string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the plugin's Description, or empty string if it fails.
|
||||
/// </summary>
|
||||
/// <param name="type">The plugin's Type.</param>
|
||||
/// <returns>The plugin's Description, or empty string if it fails.</returns>
|
||||
public static string GetDescription(Type type) {
|
||||
var attribute = GetAttribute(type);
|
||||
return attribute == null ? string.Empty : attribute.Description ?? string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the identifier for the plugin, or empty string if it fails.
|
||||
/// </summary>
|
||||
/// <param name="type">The plugin's Type.</param>
|
||||
/// <returns>The identifier for the plugin, or empty string if it fails.</returns>
|
||||
public static string GetIdentifier(Type type) {
|
||||
var attribute = GetAttribute(type);
|
||||
return attribute == null ? string.Empty : attribute.Identifier ?? string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the plugin's Name, or empty string if it fails.
|
||||
/// </summary>
|
||||
/// <param name="type">The plugin's Type.</param>
|
||||
/// <returns>The plugin's Name, or empty string if it fails.</returns>
|
||||
public static string GetName(Type type) {
|
||||
var attribute = GetAttribute(type);
|
||||
return attribute == null ? string.Empty : attribute.Name ?? string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the plugin's Version, or empty string if it fails.
|
||||
/// </summary>
|
||||
/// <param name="type">The plugin's Type.</param>
|
||||
/// <returns>The plugin's Version, or empty string if it fails.</returns>
|
||||
public static string GetVersion(Type type) {
|
||||
var attribute = GetAttribute(type);
|
||||
return attribute == null ? string.Empty : attribute.Version ?? string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether the Type is a registered plugin or not.
|
||||
/// </summary>
|
||||
/// <param name="type">The plugin's Type.</param>
|
||||
/// <returns>Whether the Type is a registered plugin or not.</returns>
|
||||
public static bool IsRegisteredPlugin(Type type) => GetAttribute(type) != null;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the plugin's RegisteredPluginAttribute, or null if it fails.
|
||||
/// </summary>
|
||||
/// <param name="type">The plugin's Type.</param>
|
||||
/// <returns>The plugin's RegisteredPluginAttribute, or null if it fails.</returns>
|
||||
private static RegisterPluginAttribute GetAttribute(Type type) => (RegisterPluginAttribute)
|
||||
type.GetCustomAttributes(typeof(RegisterPluginAttribute), false).FirstOrDefault();
|
||||
|
||||
/// <summary>
|
||||
/// Marks a PluginBase derived class as to be loaded and contains some optional information about the plugin.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class, Inherited = false)]
|
||||
protected sealed class RegisterPluginAttribute : Attribute {
|
||||
/// <summary>
|
||||
/// Gets the plugin's Author.
|
||||
/// </summary>
|
||||
public string Author { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the plugin's Description.
|
||||
/// </summary>
|
||||
public string Description { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets an identifier for the plugin.
|
||||
/// </summary>
|
||||
public string Identifier { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the plugin's Name.
|
||||
/// </summary>
|
||||
public string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the plugin's Version.
|
||||
/// </summary>
|
||||
public string Version { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="SharpPlugins.PluginBase.RegisterPluginAttribute" /> class
|
||||
/// with the identifier, given optional information about the plugin to mark it as to be loaded.
|
||||
/// </summary>
|
||||
/// <param name="identifier">The identifier for the plugin.</param>
|
||||
/// <param name="author">The plugin's Author.</param>
|
||||
/// <param name="name">The plugin's Name.</param>
|
||||
/// <param name="version">The plugin's Version.</param>
|
||||
/// <param name="description">The plugin's Description.</param>
|
||||
public RegisterPluginAttribute(string identifier, string author = "", string name = "", string version = "",
|
||||
string description = "") {
|
||||
Identifier = identifier;
|
||||
Author = author;
|
||||
Name = name;
|
||||
Version = version;
|
||||
Description = description;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
74
src/Overlay.NET/Common/PluginLoader.cs
Normal file
74
src/Overlay.NET/Common/PluginLoader.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Overlay.NET.Common {
|
||||
/// <summary>
|
||||
/// Contains static methods for loading plugin types from .dll files.
|
||||
/// </summary>
|
||||
public static class PluginLoader {
|
||||
/// <summary>
|
||||
/// Creates instances of all the given types that are instanciable plugins.
|
||||
/// </summary>
|
||||
/// <typeparam name="TPlugin">The PluginBase derived plugin type.</typeparam>
|
||||
/// <param name="types">The types to create instances from.</param>
|
||||
/// <returns>Instances of all the types that are instanciable plugins.</returns>
|
||||
public static IEnumerable<TPlugin> InstanciatePlugins<TPlugin>(IEnumerable<Type> types)
|
||||
where TPlugin : PluginBase => InstanciatePlugins<TPlugin>(types, new object[0]);
|
||||
|
||||
/// <summary>
|
||||
/// Creates instances of all the given Types that are instanciable plugins using the given arguments for the
|
||||
/// constructor.
|
||||
/// </summary>
|
||||
/// <typeparam name="TPlugin">The PluginBase derived plugin type.</typeparam>
|
||||
/// <param name="types">The Types to create instances from.</param>
|
||||
/// <param name="args">The arguments for the constructor.</param>
|
||||
/// <returns>Instances of all the types that are instanciable plugins.</returns>
|
||||
public static IEnumerable<TPlugin> InstanciatePlugins<TPlugin>(IEnumerable<Type> types, params object[] args)
|
||||
where TPlugin : PluginBase => from type in types
|
||||
where IsInstanciablePlugin(type)
|
||||
select (TPlugin) Activator.CreateInstance(type, args);
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the given Type is an instanciable plugin or not.
|
||||
/// </summary>
|
||||
/// <param name="type">The Type to check.</param>
|
||||
/// <returns>Whether the given Type is an instanciable plugin or not.</returns>
|
||||
public static bool IsInstanciablePlugin(Type type) => PluginBase.IsRegisteredPlugin(type) && !type.IsAbstract;
|
||||
|
||||
/// <summary>
|
||||
/// Takes file paths and checks if each exists, and loads .dll files to find the instanciable plugin types deriving
|
||||
/// from TPlugin.
|
||||
/// </summary>
|
||||
/// <typeparam name="TPlugin">The Type that the plugins have to be derived from.</typeparam>
|
||||
/// <param name="pluginFiles">The paths to the .dll files to check.</param>
|
||||
/// <returns>The Types of the found instanciable plugins.</returns>
|
||||
public static IEnumerable<Type> LoadPluginsFromFiles<TPlugin>(IEnumerable<string> pluginFiles)
|
||||
where TPlugin : PluginBase => from pluginFile in pluginFiles
|
||||
let extension = Path.GetExtension(pluginFile)
|
||||
where
|
||||
extension != null && File.Exists(pluginFile) &&
|
||||
extension.Equals(".dll", StringComparison.InvariantCultureIgnoreCase)
|
||||
let assembly = Assembly.LoadFrom(pluginFile)
|
||||
from type in assembly.GetExportedTypes()
|
||||
where typeof(TPlugin).IsAssignableFrom(type) && IsInstanciablePlugin(type)
|
||||
select type;
|
||||
|
||||
/// <summary>
|
||||
/// Takes directory paths and checks if each exists, and loads .dll files, including from subfolders,
|
||||
/// to find the instanciable plugin types deriving from TPlugin.
|
||||
/// </summary>
|
||||
/// <typeparam name="TPlugin">The Type that the plugins have to be derived from.</typeparam>
|
||||
/// <param name="pluginFolders">The paths to the folders to check.</param>
|
||||
/// <returns>The Types of the found instanciable plugins.</returns>
|
||||
public static IEnumerable<Type> LoadPluginsFromFolders<TPlugin>(IEnumerable<string> pluginFolders)
|
||||
where TPlugin : PluginBase => from pluginFolder in pluginFolders
|
||||
where Directory.Exists(pluginFolder)
|
||||
let files = Directory.EnumerateFiles(pluginFolder, "*.dll", SearchOption.AllDirectories)
|
||||
let types = LoadPluginsFromFiles<TPlugin>(files)
|
||||
from type in types
|
||||
select type;
|
||||
}
|
||||
}
|
||||
163
src/Overlay.NET/Common/RelativeFile.cs
Normal file
163
src/Overlay.NET/Common/RelativeFile.cs
Normal file
@@ -0,0 +1,163 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace Overlay.NET.Common {
|
||||
/// <summary>
|
||||
/// Class representing a relative file on the device's storage.
|
||||
/// </summary>
|
||||
public class RelativeFile {
|
||||
/// <summary>
|
||||
/// Gets the base directory.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The base directory.
|
||||
/// </value>
|
||||
public string Directory {
|
||||
get {
|
||||
if (string.IsNullOrEmpty(_directory)) {
|
||||
_directory = AppDomain.CurrentDomain.BaseDirectory;
|
||||
}
|
||||
|
||||
return _directory;
|
||||
}
|
||||
set { _directory = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the folder.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The folder.
|
||||
/// </value>
|
||||
public string SubDirectory { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The name.
|
||||
/// </value>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the extension.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The extension.
|
||||
/// </value>
|
||||
public string Extension { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether [use detailed time stamp].
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if [use detailed time stamp]; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool UseDetailedTimeStamp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether [time stamp file].
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if [time stamp file]; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool TimeStampFile { get; set; }
|
||||
|
||||
private string _directory;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RelativeFile" /> class.
|
||||
/// </summary>
|
||||
/// <param name="directory">The base directory.</param>
|
||||
public RelativeFile(string directory) {
|
||||
_directory = directory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RelativeFile" /> class.
|
||||
/// </summary>
|
||||
public RelativeFile() : this(AppDomain.CurrentDomain.BaseDirectory) {}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the a text file in a your app domains base directory, or if a subdirectory is set, in a sub directory
|
||||
/// relative to your app folder.
|
||||
/// </summary>
|
||||
/// <param name="fileName">Name of the file.</param>
|
||||
/// <param name="relativeSubDirectoryName">The name of the relative sub directory, if any.</param>
|
||||
/// <param name="timeStampFile">if set to <c>true</c> [the file will be time stamped]</param>
|
||||
/// <param name="useDetailedTimeStamp">if set to <c>true</c> [the time stamp will be more detailed, if one is used].</param>
|
||||
/// <returns>
|
||||
/// <see cref="RelativeFile" />
|
||||
/// </returns>
|
||||
public static RelativeFile JsonFile(string fileName, string relativeSubDirectoryName = "",
|
||||
bool timeStampFile = false, bool useDetailedTimeStamp = true) => new RelativeFile {
|
||||
Name = fileName,
|
||||
Extension = ".json",
|
||||
SubDirectory = relativeSubDirectoryName,
|
||||
TimeStampFile = timeStampFile,
|
||||
UseDetailedTimeStamp = useDetailedTimeStamp
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Creates the a text file in a your app domains base directory, or if a subdirectory is set, in a sub directory
|
||||
/// relative to your app folder.
|
||||
/// </summary>
|
||||
/// <param name="fileName">Name of the file.</param>
|
||||
/// <param name="relativeSubDirectoryName">The name of the relative sub directory, if any.</param>
|
||||
/// <param name="timeStampFile">if set to <c>true</c> [the file will be time stamped]</param>
|
||||
/// <param name="useDetailedTimeStamp">if set to <c>true</c> [the time stamp will be more detailed, if one is used].</param>
|
||||
/// <returns>
|
||||
/// <see cref="RelativeFile" />
|
||||
/// </returns>
|
||||
public static RelativeFile XmlFile(string fileName, string relativeSubDirectoryName = "",
|
||||
bool timeStampFile = false, bool useDetailedTimeStamp = true) => new RelativeFile {
|
||||
Name = fileName,
|
||||
Extension = ".xml",
|
||||
SubDirectory = relativeSubDirectoryName,
|
||||
TimeStampFile = timeStampFile,
|
||||
UseDetailedTimeStamp = useDetailedTimeStamp
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Gets the full path.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="System.ArgumentException">@The file detail can not be blank or null</exception>
|
||||
public string GetFullPath() {
|
||||
var checks = new[] {
|
||||
Directory, Name, Extension
|
||||
};
|
||||
|
||||
foreach (var fileDetail in checks.Where(string.IsNullOrEmpty)) {
|
||||
throw new ArgumentException($@"The file detail can not be blank or null {fileDetail}", fileDetail);
|
||||
}
|
||||
|
||||
if (!Extension.StartsWith(".")) {
|
||||
Extension = "." + Extension;
|
||||
}
|
||||
|
||||
if (TimeStampFile) {
|
||||
Name = UseDetailedTimeStamp
|
||||
? $"{Name}-{DateTime.Now:yyyy-MM-dd_hh-mm-ss}"
|
||||
: $"{Name}-{DateTime.Now:yyyy-MM-dd}";
|
||||
}
|
||||
|
||||
var path = Directory;
|
||||
|
||||
var combineDirectory = !string.IsNullOrEmpty(SubDirectory);
|
||||
|
||||
if (combineDirectory) {
|
||||
path = Path.Combine(Directory, SubDirectory);
|
||||
}
|
||||
|
||||
if (!System.IO.Directory.Exists(path)) {
|
||||
System.IO.Directory.CreateDirectory(path);
|
||||
}
|
||||
|
||||
return combineDirectory
|
||||
? Path.Combine(Directory, SubDirectory, Name + Extension)
|
||||
: Path.Combine(Directory, Name + Extension);
|
||||
}
|
||||
}
|
||||
}
|
||||
201
src/Overlay.NET/Common/SerializableSettings.cs
Normal file
201
src/Overlay.NET/Common/SerializableSettings.cs
Normal file
@@ -0,0 +1,201 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace Overlay.NET.Common {
|
||||
public class SerializableSettings<T> : ISettings<T> where T : new() {
|
||||
/// <summary>
|
||||
/// Gets or sets the file.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The file.
|
||||
/// </value>
|
||||
public RelativeFile SettingsFile {
|
||||
get { return _file ?? (_file = RelativeFile.XmlFile(typeof(T).Name, "Settings")); }
|
||||
set { _file = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether [backup on save].
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if [backup on save]; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool BackupOnSave { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the path.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The path.
|
||||
/// </value>
|
||||
public string Path {
|
||||
get {
|
||||
if (string.IsNullOrEmpty(_path)) {
|
||||
_path = SettingsFile.GetFullPath();
|
||||
}
|
||||
|
||||
return _path;
|
||||
}
|
||||
protected set { _path = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the settings.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The name.
|
||||
/// </value>
|
||||
public string Name {
|
||||
get {
|
||||
if (string.IsNullOrEmpty(_name)) {
|
||||
_name = typeof(T).Name;
|
||||
}
|
||||
|
||||
return _name;
|
||||
}
|
||||
set { _name = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the encoding.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The encoding.
|
||||
/// </value>
|
||||
public Encoding Encoding {
|
||||
get { return _encoding ?? (_encoding = Encoding.UTF8); }
|
||||
set { _encoding = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current settings instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The current.
|
||||
/// </value>
|
||||
public T Current {
|
||||
get {
|
||||
if (_currentExist) {
|
||||
return _current;
|
||||
}
|
||||
_current = new T();
|
||||
_currentExist = true;
|
||||
|
||||
return _current;
|
||||
}
|
||||
|
||||
set {
|
||||
_current = value;
|
||||
_currentExist = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the serializer.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The serializer.
|
||||
/// </value>
|
||||
protected ISerializer Serializer {
|
||||
get {
|
||||
if (_serializer != null) {
|
||||
return _serializer;
|
||||
}
|
||||
_serializer = new XmlSerializerEx();
|
||||
SettingsFile.Extension = ".xml";
|
||||
SettingsFile.SubDirectory = "XmlSettings";
|
||||
|
||||
return _serializer;
|
||||
}
|
||||
set { _serializer = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves the settings to the specified file.
|
||||
/// </summary>
|
||||
/// <param name="file">The file.</param>
|
||||
public void Save(string file = "") {
|
||||
if (string.IsNullOrEmpty(file)) {
|
||||
file = Path;
|
||||
}
|
||||
|
||||
if (File.Exists(file) && BackupOnSave) {
|
||||
BackupSettings(file);
|
||||
}
|
||||
|
||||
Serializer.ExportToFile(Current, file, Encoding.UTF8);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads the settings from the specified location.
|
||||
/// </summary>
|
||||
/// <param name="location">
|
||||
/// The location of the file./param>
|
||||
/// <exception cref="System.ArgumentNullException"></exception>
|
||||
/// </param>
|
||||
public void Load(string location = "") {
|
||||
if (string.IsNullOrEmpty(location)) {
|
||||
location = Path;
|
||||
}
|
||||
|
||||
if (!File.Exists(location)) {
|
||||
Save(location);
|
||||
}
|
||||
|
||||
var settings = Serializer.ImportFromFile<T>(location, Encoding);
|
||||
|
||||
if (settings == null) {
|
||||
throw new ArgumentNullException(nameof(settings));
|
||||
}
|
||||
|
||||
Current = settings;
|
||||
|
||||
RaiseOnSettingsChanged(location);
|
||||
}
|
||||
|
||||
private T _current;
|
||||
private bool _currentExist;
|
||||
private Encoding _encoding;
|
||||
private RelativeFile _file;
|
||||
private string _name;
|
||||
private string _path;
|
||||
private ISerializer _serializer;
|
||||
|
||||
/// <summary>
|
||||
/// Backups the settings if one already exist.
|
||||
/// </summary>
|
||||
/// <param name="target">The target to back up settings to.</param>
|
||||
/// <exception cref="System.ArgumentNullException"></exception>
|
||||
protected void BackupSettings(string target = "") {
|
||||
if (string.IsNullOrEmpty(target)) {
|
||||
target = Path;
|
||||
}
|
||||
|
||||
var extension = System.IO.Path.GetExtension(target);
|
||||
|
||||
if (extension == null) {
|
||||
throw new ArgumentNullException(Path + " does not contain an extension.");
|
||||
}
|
||||
|
||||
var time = DateTime.Now;
|
||||
|
||||
var backup = target.Replace(extension,
|
||||
$"-{time.ToString("yyyy-MM-dd-HH-mm-ss", CultureInfo.InvariantCulture)}{extension}");
|
||||
|
||||
Serializer.ExportToFile(Current, backup, Encoding);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when [on settings changed].
|
||||
/// </summary>
|
||||
public event EventHandler<string> OnSettingsChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Raises the on settings changed.
|
||||
/// </summary>
|
||||
/// <param name="e">The e.</param>
|
||||
protected virtual void RaiseOnSettingsChanged(string e) => OnSettingsChanged?.Invoke(this, e);
|
||||
}
|
||||
}
|
||||
87
src/Overlay.NET/Common/TickEngine.cs
Normal file
87
src/Overlay.NET/Common/TickEngine.cs
Normal file
@@ -0,0 +1,87 @@
|
||||
using System;
|
||||
|
||||
namespace Overlay.NET.Common {
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
public class TickEngine {
|
||||
/// <summary>
|
||||
/// Gets or sets the interval.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The interval.
|
||||
/// </value>
|
||||
public TimeSpan Interval {
|
||||
get { return _waitTimer.WaitTime; }
|
||||
set { _waitTimer.WaitTime = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this instance is ticking.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance is ticking; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool IsTicking { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The wait timer
|
||||
/// </summary>
|
||||
private readonly WaitTimer _waitTimer = new WaitTimer();
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when [pre tick].
|
||||
/// </summary>
|
||||
public event EventHandler PreTick;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when [tick].
|
||||
/// </summary>
|
||||
public event EventHandler Tick;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when [post tick].
|
||||
/// </summary>
|
||||
public event EventHandler PostTick;
|
||||
|
||||
/// <summary>
|
||||
/// Stops this instance.
|
||||
/// </summary>
|
||||
public void Stop() => _waitTimer.Stop();
|
||||
|
||||
/// <summary>
|
||||
/// Pulses this instance.
|
||||
/// </summary>
|
||||
public void Pulse() {
|
||||
if (!IsTicking) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_waitTimer.Update()) {
|
||||
return;
|
||||
}
|
||||
|
||||
OnPreTick();
|
||||
|
||||
OnTick();
|
||||
|
||||
OnPostTick();
|
||||
|
||||
_waitTimer.Reset();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when [tick].
|
||||
/// </summary>
|
||||
protected virtual void OnTick() => Tick?.Invoke(this, EventArgs.Empty);
|
||||
|
||||
/// <summary>
|
||||
/// Called when [pre tick].
|
||||
/// </summary>
|
||||
protected virtual void OnPreTick() => PreTick?.Invoke(this, EventArgs.Empty);
|
||||
|
||||
/// <summary>
|
||||
/// Called when [post tick].
|
||||
/// </summary>
|
||||
protected virtual void OnPostTick() => PostTick?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
15
src/Overlay.NET/Common/TimeSpanExtensions.cs
Normal file
15
src/Overlay.NET/Common/TimeSpanExtensions.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
|
||||
namespace Overlay.NET.Common {
|
||||
public static class TimeSpanExtensions {
|
||||
public static TimeSpan Days(this int days) => new TimeSpan(days, 0, 0, 0);
|
||||
|
||||
public static TimeSpan Hours(this int hours) => new TimeSpan(0, hours, 0, 0);
|
||||
|
||||
public static TimeSpan Minutes(this int minutes) => new TimeSpan(0, 0, minutes, 0);
|
||||
|
||||
public static TimeSpan Seconds(this int seconds) => new TimeSpan(0, 0, 0, seconds);
|
||||
|
||||
public static TimeSpan Milliseconds(this int milliseconds) => new TimeSpan(0, 0, 0, 0, milliseconds);
|
||||
}
|
||||
}
|
||||
132
src/Overlay.NET/Common/WaitTimer.cs
Normal file
132
src/Overlay.NET/Common/WaitTimer.cs
Normal file
@@ -0,0 +1,132 @@
|
||||
using System;
|
||||
|
||||
namespace Overlay.NET.Common {
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
/// <seealso cref="System.EventArgs" />
|
||||
public sealed class WaitTimerEventArgs : EventArgs {
|
||||
/// <summary>
|
||||
/// Gets or sets the time finished.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The time finished.
|
||||
/// </value>
|
||||
public DateTime TimeFinished { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the wait time.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The wait time.
|
||||
/// </value>
|
||||
public TimeSpan WaitTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the time started.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The time started.
|
||||
/// </value>
|
||||
public DateTime TimeStarted { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
public class WaitTimer {
|
||||
/// <summary>
|
||||
/// Gets or sets the wait time.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The wait time.
|
||||
/// </value>
|
||||
public TimeSpan WaitTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the end time.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The end time.
|
||||
/// </value>
|
||||
public DateTime EndTime => StartTime + WaitTime;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the start time.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The start time.
|
||||
/// </value>
|
||||
public DateTime StartTime { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance is finished.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance is finished; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool IsFinished => EndTime <= DateTime.Now;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the time left.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The time left.
|
||||
/// </value>
|
||||
public TimeSpan TimeLeft => EndTime - DateTime.Now;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="WaitTimer" /> class.
|
||||
/// </summary>
|
||||
/// <param name="waitTime">The wait time.</param>
|
||||
public WaitTimer(TimeSpan waitTime) {
|
||||
WaitTime = waitTime;
|
||||
Stop();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="WaitTimer" /> class.
|
||||
/// </summary>
|
||||
public WaitTimer() {
|
||||
WaitTime = TimeSpan.Zero;
|
||||
Stop();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when [finished].
|
||||
/// </summary>
|
||||
public event EventHandler<WaitTimerEventArgs> Finished;
|
||||
|
||||
/// <summary>
|
||||
/// Resets this instance.
|
||||
/// </summary>
|
||||
public void Reset() => StartTime = DateTime.Now;
|
||||
|
||||
/// <summary>
|
||||
/// Stops this instance.
|
||||
/// </summary>
|
||||
public void Stop() => StartTime = DateTime.Now.AddDays(-5.0);
|
||||
|
||||
/// <summary>
|
||||
/// Updates this instance.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool Update() {
|
||||
if (!IsFinished) {
|
||||
return false;
|
||||
}
|
||||
|
||||
OnFinished(new WaitTimerEventArgs {
|
||||
TimeFinished = DateTime.Now,
|
||||
TimeStarted = StartTime,
|
||||
WaitTime = WaitTime
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raises the <see cref="E:Finished" /> event.
|
||||
/// </summary>
|
||||
/// <param name="e">The <see cref="WaitTimerEventArgs" /> instance containing the event data.</param>
|
||||
protected virtual void OnFinished(WaitTimerEventArgs e) => Finished?.Invoke(this, e);
|
||||
}
|
||||
}
|
||||
81
src/Overlay.NET/Common/WindowConstants.cs
Normal file
81
src/Overlay.NET/Common/WindowConstants.cs
Normal file
@@ -0,0 +1,81 @@
|
||||
namespace Overlay.NET.Common {
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
internal class WindowConstants {
|
||||
/// <summary>
|
||||
/// The sm cx screen
|
||||
/// </summary>
|
||||
public const int SmCxScreen = 0;
|
||||
|
||||
/// <summary>
|
||||
/// The sm cy screen
|
||||
/// </summary>
|
||||
public const int SmCyScreen = 1;
|
||||
|
||||
/// <summary>
|
||||
/// The desktop class
|
||||
/// </summary>
|
||||
public const string DesktopClass = "Static"; // System Class for a static control
|
||||
|
||||
/// <summary>
|
||||
/// The window style dx
|
||||
/// </summary>
|
||||
public const uint WindowStyleDx = 0x8000000 //WS_DISABLED
|
||||
| 0x10000000 //WS_VISIBLE
|
||||
| 0x80000000; //WS_POPUP
|
||||
|
||||
/// <summary>
|
||||
/// The window ex style dx
|
||||
/// </summary>
|
||||
public const uint WindowExStyleDx = 0x8000000 //WS_EX_NOACTIVATE
|
||||
| 0x80000 //WS_EX_LAYERED
|
||||
| 0x80 //WS_EX_TOOLWINDOW -> Not in taskbar
|
||||
| 0x8 //WS_EX_TOPMOST
|
||||
| 0x20; //WS_EX_TRANSPARENT
|
||||
|
||||
/// <summary>
|
||||
/// The layered window attribute alpha (LWA_ALPHA)
|
||||
/// </summary>
|
||||
public const int LwaAlpha = 0x00000002;
|
||||
|
||||
/// <summary>
|
||||
/// The HWND notopmost
|
||||
/// </summary>
|
||||
public const int HwndNotopmost = -2;
|
||||
|
||||
/// <summary>
|
||||
/// The HWND topmost
|
||||
/// </summary>
|
||||
public const int HwndTopmost = -1;
|
||||
|
||||
/// <summary>
|
||||
/// The HWND top
|
||||
/// </summary>
|
||||
public const int HwndTop = 0;
|
||||
|
||||
/// <summary>
|
||||
/// The HWND bottom
|
||||
/// </summary>
|
||||
public const int HwndBottom = 1;
|
||||
|
||||
/// <summary>
|
||||
/// The SWP flags show
|
||||
/// </summary>
|
||||
public const uint SwpFlagsShow = 0x40;
|
||||
|
||||
/// <summary>
|
||||
/// The SWP flags hide
|
||||
/// </summary>
|
||||
public const uint SwpFlagsHide = 0x80;
|
||||
|
||||
/// <summary>
|
||||
/// The sw show
|
||||
/// </summary>
|
||||
public const uint SwShow = 5;
|
||||
|
||||
/// <summary>
|
||||
/// The sw hide
|
||||
/// </summary>
|
||||
public const uint SwHide = 0;
|
||||
}
|
||||
}
|
||||
19
src/Overlay.NET/Common/WindowExtensions.cs
Normal file
19
src/Overlay.NET/Common/WindowExtensions.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows;
|
||||
using System.Windows.Interop;
|
||||
|
||||
namespace Overlay.NET.Common {
|
||||
public static class WindowExtensions {
|
||||
private const int GwlExstyle = -20;
|
||||
private const int WsExTransparent = 0x00000020;
|
||||
|
||||
public static void MakeWindowTransparent(this Window wnd) {
|
||||
if (!wnd.IsInitialized)
|
||||
throw new Exception("The extension method MakeWindowTransparent can not be called prior to the window being initialized.");
|
||||
var hwnd = new WindowInteropHelper(wnd).Handle;
|
||||
var extendedStyle = Native.GetWindowLongPtr(hwnd, GwlExstyle);
|
||||
Native.SetWindowLongPtr(hwnd, GwlExstyle, new IntPtr(extendedStyle.ToInt32() | WsExTransparent));
|
||||
}
|
||||
}
|
||||
}
|
||||
68
src/Overlay.NET/Common/XmlSerializerEx.cs
Normal file
68
src/Overlay.NET/Common/XmlSerializerEx.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace Overlay.NET.Common {
|
||||
/// <summary>
|
||||
/// Class to serialize/deserialize XML objects to and from strings, and to and from files.
|
||||
/// </summary>
|
||||
/// <seealso cref="ISerializer" />
|
||||
public class XmlSerializerEx : ISerializer {
|
||||
/// <summary>
|
||||
/// Serializes the specified object and returns the document.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the object to serialize.</typeparam>
|
||||
/// <param name="obj">The object to serialize.</param>
|
||||
/// <returns>
|
||||
/// XML document of the serialized object.
|
||||
/// </returns>
|
||||
public string ExportToString<T>(T obj) {
|
||||
var serializer = new XmlSerializer(typeof(T));
|
||||
using (var stringWriter = new StringWriter()) {
|
||||
serializer.Serialize(stringWriter, obj);
|
||||
return stringWriter.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes the document to the specified object.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the object to deserialize.</typeparam>
|
||||
/// <param name="serializedObj">The string representing the serialized object.</param>
|
||||
/// <returns>
|
||||
/// The deserialized object.
|
||||
/// </returns>
|
||||
public T ImportFromString<T>(string serializedObj) {
|
||||
var serializer = new XmlSerializer(typeof(T));
|
||||
using (var stringWriter = new StringReader(serializedObj)) {
|
||||
return (T) serializer.Deserialize(stringWriter);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serializes the specified object and writes the document to the specified path.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the object to serialize.</typeparam>
|
||||
/// <param name="obj">The object to serialize.</param>
|
||||
/// <param name="file">The path where the file is saved.</param>
|
||||
/// <param name="encoding">The encoding to generate.</param>
|
||||
public void ExportToFile<T>(T obj, string file, Encoding encoding) {
|
||||
using (var fileWriter = new StreamWriter(file, false, encoding)) {
|
||||
fileWriter.Write(ExportToString(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes the specified file into an object.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the object to deserialize.</typeparam>
|
||||
/// <param name="path">The path where the object is read.</param>
|
||||
/// <param name="encoding">The character encoding to use. </param>
|
||||
/// <returns>The deserialized object.</returns>
|
||||
public T ImportFromFile<T>(string path, Encoding encoding) {
|
||||
using (var fileReader = new StreamReader(path, encoding)) {
|
||||
return ImportFromString<T>(fileReader.ReadToEnd());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
644
src/Overlay.NET/Directx/Direct2DRenderer.cs
Normal file
644
src/Overlay.NET/Directx/Direct2DRenderer.cs
Normal file
@@ -0,0 +1,644 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Overlay.NET.Common;
|
||||
using SharpDX;
|
||||
using SharpDX.Direct2D1;
|
||||
using SharpDX.DirectWrite;
|
||||
using SharpDX.DXGI;
|
||||
using SharpDX.Mathematics.Interop;
|
||||
using AlphaMode = SharpDX.Direct2D1.AlphaMode;
|
||||
using Color = System.Drawing.Color;
|
||||
using Factory = SharpDX.DirectWrite.Factory;
|
||||
using TextAntialiasMode = SharpDX.Direct2D1.TextAntialiasMode;
|
||||
|
||||
namespace Overlay.NET.Directx {
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
public class Direct2DRenderer {
|
||||
/// <summary>
|
||||
/// Gets the size of the buffer brush.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The size of the buffer brush.
|
||||
/// </value>
|
||||
public int BufferBrushSize { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the size of the buffer font.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The size of the buffer font.
|
||||
/// </value>
|
||||
public int BufferFontSize { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the size of the buffer layout.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The size of the buffer layout.
|
||||
/// </value>
|
||||
public int BufferLayoutSize { get; private set; }
|
||||
|
||||
//transparent background color
|
||||
/// <summary>
|
||||
/// The GDI transparent
|
||||
/// </summary>
|
||||
private static Color _gdiTransparent = Color.Transparent;
|
||||
|
||||
/// <summary>
|
||||
/// The transparent
|
||||
/// </summary>
|
||||
private static readonly RawColor4 Transparent = new RawColor4(_gdiTransparent.R, _gdiTransparent.G, _gdiTransparent.B,
|
||||
_gdiTransparent.A);
|
||||
|
||||
//direct x vars
|
||||
/// <summary>
|
||||
/// The device
|
||||
/// </summary>
|
||||
private readonly WindowRenderTarget _device;
|
||||
|
||||
/// <summary>
|
||||
/// The factory
|
||||
/// </summary>
|
||||
private readonly SharpDX.Direct2D1.Factory _factory;
|
||||
|
||||
/// <summary>
|
||||
/// The font factory
|
||||
/// </summary>
|
||||
private readonly Factory _fontFactory;
|
||||
|
||||
/// <summary>
|
||||
/// The brush container
|
||||
/// </summary>
|
||||
private List<SolidColorBrush> _brushContainer = new List<SolidColorBrush>(32);
|
||||
|
||||
//thread safe resizing
|
||||
/// <summary>
|
||||
/// The do resize
|
||||
/// </summary>
|
||||
private bool _doResize;
|
||||
|
||||
/// <summary>
|
||||
/// The font container
|
||||
/// </summary>
|
||||
private List<TextFormat> _fontContainer = new List<TextFormat>(32);
|
||||
|
||||
/// <summary>
|
||||
/// The layout container
|
||||
/// </summary>
|
||||
private List<TextLayoutBuffer> _layoutContainer = new List<TextLayoutBuffer>(32);
|
||||
|
||||
/// <summary>
|
||||
/// The resize x
|
||||
/// </summary>
|
||||
private int _resizeX;
|
||||
|
||||
/// <summary>
|
||||
/// The resize y
|
||||
/// </summary>
|
||||
private int _resizeY;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Direct2DRenderer" /> class.
|
||||
/// </summary>
|
||||
/// <param name="hwnd">The HWND.</param>
|
||||
/// <param name="limitFps">if set to <c>true</c> [limit FPS].</param>
|
||||
public Direct2DRenderer(IntPtr hwnd, bool limitFps) {
|
||||
_factory = new SharpDX.Direct2D1.Factory();
|
||||
|
||||
_fontFactory = new Factory();
|
||||
|
||||
Native.Rect bounds;
|
||||
Native.GetWindowRect(hwnd, out bounds);
|
||||
|
||||
var targetProperties = new HwndRenderTargetProperties {
|
||||
Hwnd = hwnd,
|
||||
PixelSize = new Size2(bounds.Right - bounds.Left, bounds.Bottom - bounds.Top),
|
||||
PresentOptions = limitFps ? PresentOptions.None : PresentOptions.Immediately
|
||||
};
|
||||
|
||||
var prop = new RenderTargetProperties(RenderTargetType.Hardware,
|
||||
new PixelFormat(Format.B8G8R8A8_UNorm, AlphaMode.Premultiplied), 0, 0, RenderTargetUsage.None,
|
||||
FeatureLevel.Level_DEFAULT);
|
||||
|
||||
_device = new WindowRenderTarget(_factory, prop, targetProperties) {
|
||||
TextAntialiasMode = TextAntialiasMode.Aliased,
|
||||
AntialiasMode = AntialiasMode.Aliased
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Do not call if you use OverlayWindow class
|
||||
/// </summary>
|
||||
public void Dispose() {
|
||||
DeleteBrushContainer();
|
||||
DeleteFontContainer();
|
||||
DeleteLayoutContainer();
|
||||
|
||||
_brushContainer = null;
|
||||
_fontContainer = null;
|
||||
_layoutContainer = null;
|
||||
|
||||
_fontFactory.Dispose();
|
||||
_factory.Dispose();
|
||||
_device.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// tells renderer to resize when possible
|
||||
/// </summary>
|
||||
/// <param name="x">Width</param>
|
||||
/// <param name="y">Height</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void AutoResize(int x, int y) {
|
||||
_doResize = true;
|
||||
_resizeX = x;
|
||||
_resizeY = y;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this after EndScene if you created brushes within a loop
|
||||
/// </summary>
|
||||
public void DeleteBrushContainer() {
|
||||
BufferBrushSize = _brushContainer.Count;
|
||||
foreach (var solidColorBrush in _brushContainer) {
|
||||
solidColorBrush.Dispose();
|
||||
}
|
||||
_brushContainer = new List<SolidColorBrush>(BufferBrushSize);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this after EndScene if you created fonts within a loop
|
||||
/// </summary>
|
||||
public void DeleteFontContainer() {
|
||||
BufferFontSize = _fontContainer.Count;
|
||||
foreach (var textFormat in _fontContainer) {
|
||||
textFormat.Dispose();
|
||||
}
|
||||
_fontContainer = new List<TextFormat>(BufferFontSize);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this after EndScene if you changed your text's font or have problems with huge memory usage
|
||||
/// </summary>
|
||||
public void DeleteLayoutContainer() {
|
||||
BufferLayoutSize = _layoutContainer.Count;
|
||||
foreach (var layoutBuffer in _layoutContainer) {
|
||||
layoutBuffer.Dispose();
|
||||
}
|
||||
_layoutContainer = new List<TextLayoutBuffer>(BufferLayoutSize);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new SolidColorBrush
|
||||
/// </summary>
|
||||
/// <param name="color">0x7FFFFFF Premultiplied alpha color</param>
|
||||
/// <returns>
|
||||
/// int Brush identifier
|
||||
/// </returns>
|
||||
public int CreateBrush(int color) {
|
||||
_brushContainer.Add(new SolidColorBrush(_device,
|
||||
new RawColor4((color >> 16) & 255L, (color >> 8) & 255L, (byte) color & 255L, (color >> 24) & 255L)));
|
||||
return _brushContainer.Count - 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new SolidColorBrush. Make sure you applied an alpha value
|
||||
/// </summary>
|
||||
/// <param name="color">System.Drawing.Color struct</param>
|
||||
/// <returns>
|
||||
/// int Brush identifier
|
||||
/// </returns>
|
||||
public int CreateBrush(Color color) {
|
||||
if (color.A == 0) {
|
||||
color = Color.FromArgb(255, color);
|
||||
}
|
||||
|
||||
_brushContainer.Add(new SolidColorBrush(_device, new RawColor4(color.R, color.G, color.B, color.A / 255.0f)));
|
||||
return _brushContainer.Count - 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Font
|
||||
/// </summary>
|
||||
/// <param name="fontFamilyName">i.e. Arial</param>
|
||||
/// <param name="size">size in units</param>
|
||||
/// <param name="bold">print bold text</param>
|
||||
/// <param name="italic">print italic text</param>
|
||||
/// <returns></returns>
|
||||
public int CreateFont(string fontFamilyName, float size, bool bold = false, bool italic = false) {
|
||||
_fontContainer.Add(new TextFormat(_fontFactory, fontFamilyName, bold ? FontWeight.Bold : FontWeight.Normal,
|
||||
italic ? FontStyle.Italic : FontStyle.Normal, size));
|
||||
return _fontContainer.Count - 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Do your drawing after this
|
||||
/// </summary>
|
||||
public void BeginScene() {
|
||||
if (_doResize) {
|
||||
_device.Resize(new Size2(_resizeX, _resizeY));
|
||||
|
||||
_doResize = false;
|
||||
}
|
||||
_device.BeginDraw();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Present frame. Do not draw after this.
|
||||
/// </summary>
|
||||
public void EndScene() {
|
||||
_device.EndDraw();
|
||||
if (!_doResize) {
|
||||
return;
|
||||
}
|
||||
_device.Resize(new Size2(_resizeX, _resizeY));
|
||||
|
||||
_doResize = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the frame
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void ClearScene() => _device.Clear(Transparent);
|
||||
|
||||
/// <summary>
|
||||
/// Draws the line.
|
||||
/// </summary>
|
||||
/// <param name="startX">The start x.</param>
|
||||
/// <param name="startY">The start y.</param>
|
||||
/// <param name="endX">The end x.</param>
|
||||
/// <param name="endY">The end y.</param>
|
||||
/// <param name="stroke">The stroke.</param>
|
||||
/// <param name="brush">The brush.</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void DrawLine(int startX, int startY, int endX, int endY, float stroke, int brush) => _device.DrawLine(new RawVector2(startX, startY), new RawVector2(endX, endY), _brushContainer[brush], stroke);
|
||||
|
||||
/// <summary>
|
||||
/// Draws the rectangle.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <param name="y">The y.</param>
|
||||
/// <param name="width">The width.</param>
|
||||
/// <param name="height">The height.</param>
|
||||
/// <param name="stroke">The stroke.</param>
|
||||
/// <param name="brush">The brush.</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void DrawRectangle(int x, int y, int width, int height, float stroke, int brush) => _device.DrawRectangle(new RawRectangleF(x, y, x + width, y + height), _brushContainer[brush], stroke);
|
||||
|
||||
/// <summary>
|
||||
/// Draws the circle.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <param name="y">The y.</param>
|
||||
/// <param name="radius">The radius.</param>
|
||||
/// <param name="stroke">The stroke.</param>
|
||||
/// <param name="brush">The brush.</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void DrawCircle(int x, int y, int radius, float stroke, int brush) => _device.DrawEllipse(new Ellipse(new RawVector2(x, y), radius, radius), _brushContainer[brush], stroke);
|
||||
|
||||
/// <summary>
|
||||
/// Draws the box2 d.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <param name="y">The y.</param>
|
||||
/// <param name="width">The width.</param>
|
||||
/// <param name="height">The height.</param>
|
||||
/// <param name="stroke">The stroke.</param>
|
||||
/// <param name="brush">The brush.</param>
|
||||
/// <param name="interiorBrush">The interior brush.</param>
|
||||
public void DrawBox2D(int x, int y, int width, int height, float stroke, int brush, int interiorBrush) {
|
||||
_device.DrawRectangle(new RawRectangleF(x, y, x + width, y + height), _brushContainer[brush], stroke);
|
||||
_device.FillRectangle(new RawRectangleF(x + stroke, y + stroke, x + width - stroke, y + height - stroke),
|
||||
_brushContainer[interiorBrush]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draws the box3 d.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <param name="y">The y.</param>
|
||||
/// <param name="width">The width.</param>
|
||||
/// <param name="height">The height.</param>
|
||||
/// <param name="length">The length.</param>
|
||||
/// <param name="stroke">The stroke.</param>
|
||||
/// <param name="brush">The brush.</param>
|
||||
/// <param name="interiorBrush">The interior brush.</param>
|
||||
public void DrawBox3D(int x, int y, int width, int height, int length, float stroke, int brush,
|
||||
int interiorBrush) {
|
||||
var first = new RawRectangleF(x, y, x + width, y + height);
|
||||
var second = new RawRectangleF(x + length, y - length, first.Right + length, first.Bottom - length);
|
||||
|
||||
var lineStart = new RawVector2(x, y);
|
||||
var lineEnd = new RawVector2(second.Left, second.Top);
|
||||
|
||||
_device.DrawRectangle(first, _brushContainer[brush], stroke);
|
||||
_device.DrawRectangle(second, _brushContainer[brush], stroke);
|
||||
|
||||
_device.FillRectangle(first, _brushContainer[interiorBrush]);
|
||||
_device.FillRectangle(second, _brushContainer[interiorBrush]);
|
||||
|
||||
_device.DrawLine(lineStart, lineEnd, _brushContainer[brush], stroke);
|
||||
|
||||
lineStart.X += width;
|
||||
lineEnd.X = lineStart.X + length;
|
||||
|
||||
_device.DrawLine(lineStart, lineEnd, _brushContainer[brush], stroke);
|
||||
|
||||
lineStart.Y += height;
|
||||
lineEnd.Y += height;
|
||||
|
||||
_device.DrawLine(lineStart, lineEnd, _brushContainer[brush], stroke);
|
||||
|
||||
lineStart.X -= width;
|
||||
lineEnd.X -= width;
|
||||
|
||||
_device.DrawLine(lineStart, lineEnd, _brushContainer[brush], stroke);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draws the rectangle3 d.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <param name="y">The y.</param>
|
||||
/// <param name="width">The width.</param>
|
||||
/// <param name="height">The height.</param>
|
||||
/// <param name="length">The length.</param>
|
||||
/// <param name="stroke">The stroke.</param>
|
||||
/// <param name="brush">The brush.</param>
|
||||
public void DrawRectangle3D(int x, int y, int width, int height, int length, float stroke, int brush) {
|
||||
var first = new RawRectangleF(x, y, x + width, y + height);
|
||||
var second = new RawRectangleF(x + length, y - length, first.Right + length, first.Bottom - length);
|
||||
|
||||
var lineStart = new RawVector2(x, y);
|
||||
var lineEnd = new RawVector2(second.Left, second.Top);
|
||||
|
||||
_device.DrawRectangle(first, _brushContainer[brush], stroke);
|
||||
_device.DrawRectangle(second, _brushContainer[brush], stroke);
|
||||
|
||||
_device.DrawLine(lineStart, lineEnd, _brushContainer[brush], stroke);
|
||||
|
||||
lineStart.X += width;
|
||||
lineEnd.X = lineStart.X + length;
|
||||
|
||||
_device.DrawLine(lineStart, lineEnd, _brushContainer[brush], stroke);
|
||||
|
||||
lineStart.Y += height;
|
||||
lineEnd.Y += height;
|
||||
|
||||
_device.DrawLine(lineStart, lineEnd, _brushContainer[brush], stroke);
|
||||
|
||||
lineStart.X -= width;
|
||||
lineEnd.X -= width;
|
||||
|
||||
_device.DrawLine(lineStart, lineEnd, _brushContainer[brush], stroke);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draws the plus.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <param name="y">The y.</param>
|
||||
/// <param name="length">The length.</param>
|
||||
/// <param name="stroke">The stroke.</param>
|
||||
/// <param name="brush">The brush.</param>
|
||||
public void DrawPlus(int x, int y, int length, float stroke, int brush) {
|
||||
var first = new RawVector2(x - length, y);
|
||||
var second = new RawVector2(x + length, y);
|
||||
|
||||
var third = new RawVector2(x, y - length);
|
||||
var fourth = new RawVector2(x, y + length);
|
||||
|
||||
_device.DrawLine(first, second, _brushContainer[brush], stroke);
|
||||
_device.DrawLine(third, fourth, _brushContainer[brush], stroke);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draws the edge.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <param name="y">The y.</param>
|
||||
/// <param name="width">The width.</param>
|
||||
/// <param name="height">The height.</param>
|
||||
/// <param name="length">The length.</param>
|
||||
/// <param name="stroke">The stroke.</param>
|
||||
/// <param name="brush">The brush.</param>
|
||||
public void DrawEdge(int x, int y, int width, int height, int length, float stroke, int brush) //geht
|
||||
{
|
||||
var first = new RawVector2(x, y);
|
||||
var second = new RawVector2(x, y + length);
|
||||
var third = new RawVector2(x + length, y);
|
||||
|
||||
_device.DrawLine(first, second, _brushContainer[brush], stroke);
|
||||
_device.DrawLine(first, third, _brushContainer[brush], stroke);
|
||||
|
||||
first.Y += height;
|
||||
second.Y = first.Y - length;
|
||||
third.Y = first.Y;
|
||||
third.X = first.X + length;
|
||||
|
||||
_device.DrawLine(first, second, _brushContainer[brush], stroke);
|
||||
_device.DrawLine(first, third, _brushContainer[brush], stroke);
|
||||
|
||||
first.X = x + width;
|
||||
first.Y = y;
|
||||
second.X = first.X - length;
|
||||
second.Y = first.Y;
|
||||
third.X = first.X;
|
||||
third.Y = first.Y + length;
|
||||
|
||||
_device.DrawLine(first, second, _brushContainer[brush], stroke);
|
||||
_device.DrawLine(first, third, _brushContainer[brush], stroke);
|
||||
|
||||
first.Y += height;
|
||||
second.X += length;
|
||||
second.Y = first.Y - length;
|
||||
third.Y = first.Y;
|
||||
third.X = first.X - length;
|
||||
|
||||
_device.DrawLine(first, second, _brushContainer[brush], stroke);
|
||||
_device.DrawLine(first, third, _brushContainer[brush], stroke);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draws the bar h.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <param name="y">The y.</param>
|
||||
/// <param name="width">The width.</param>
|
||||
/// <param name="height">The height.</param>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <param name="stroke">The stroke.</param>
|
||||
/// <param name="brush">The brush.</param>
|
||||
/// <param name="interiorBrush">The interior brush.</param>
|
||||
public void DrawBarH(int x, int y, int width, int height, float value, float stroke, int brush,
|
||||
int interiorBrush) {
|
||||
var first = new RawRectangleF(x, y, x + width, y + height);
|
||||
|
||||
_device.DrawRectangle(first, _brushContainer[brush], stroke);
|
||||
|
||||
if (Math.Abs(value) < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
first.Top += height - height / 100.0f * value;
|
||||
|
||||
_device.FillRectangle(first, _brushContainer[interiorBrush]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draws the bar v.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <param name="y">The y.</param>
|
||||
/// <param name="width">The width.</param>
|
||||
/// <param name="height">The height.</param>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <param name="stroke">The stroke.</param>
|
||||
/// <param name="brush">The brush.</param>
|
||||
/// <param name="interiorBrush">The interior brush.</param>
|
||||
public void DrawBarV(int x, int y, int width, int height, float value, float stroke, int brush,
|
||||
int interiorBrush) {
|
||||
var first = new RawRectangleF(x, y, x + width, y + height);
|
||||
|
||||
_device.DrawRectangle(first, _brushContainer[brush], stroke);
|
||||
|
||||
if (Math.Abs(value) < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
first.Right -= width - width / 100.0f * value;
|
||||
|
||||
_device.FillRectangle(first, _brushContainer[interiorBrush]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fills the rectangle.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <param name="y">The y.</param>
|
||||
/// <param name="width">The width.</param>
|
||||
/// <param name="height">The height.</param>
|
||||
/// <param name="brush">The brush.</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void FillRectangle(int x, int y, int width, int height, int brush) => _device.FillRectangle(new RawRectangleF(x, y, x + width, y + height), _brushContainer[brush]);
|
||||
|
||||
/// <summary>
|
||||
/// Fills the circle.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <param name="y">The y.</param>
|
||||
/// <param name="radius">The radius.</param>
|
||||
/// <param name="brush">The brush.</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void FillCircle(int x, int y, int radius, int brush) => _device.FillEllipse(new Ellipse(new RawVector2(x, y), radius, radius), _brushContainer[brush]);
|
||||
|
||||
/// <summary>
|
||||
/// Bordereds the line.
|
||||
/// </summary>
|
||||
/// <param name="startX">The start x.</param>
|
||||
/// <param name="startY">The start y.</param>
|
||||
/// <param name="endX">The end x.</param>
|
||||
/// <param name="endY">The end y.</param>
|
||||
/// <param name="stroke">The stroke.</param>
|
||||
/// <param name="brush">The brush.</param>
|
||||
/// <param name="borderBrush">The border brush.</param>
|
||||
public void BorderedLine(int startX, int startY, int endX, int endY, float stroke, int brush, int borderBrush) {
|
||||
_device.DrawLine(new RawVector2(startX, startY), new RawVector2(endX, endY), _brushContainer[brush], stroke);
|
||||
|
||||
_device.DrawLine(new RawVector2(startX, startY - stroke), new RawVector2(endX, endY - stroke),
|
||||
_brushContainer[borderBrush], stroke);
|
||||
_device.DrawLine(new RawVector2(startX, startY + stroke), new RawVector2(endX, endY + stroke),
|
||||
_brushContainer[borderBrush], stroke);
|
||||
|
||||
_device.DrawLine(new RawVector2(startX - stroke / 2, startY - stroke * 1.5f),
|
||||
new RawVector2(startX - stroke / 2, startY + stroke * 1.5f), _brushContainer[borderBrush], stroke);
|
||||
_device.DrawLine(new RawVector2(endX - stroke / 2, endY - stroke * 1.5f),
|
||||
new RawVector2(endX - stroke / 2, endY + stroke * 1.5f), _brushContainer[borderBrush], stroke);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Bordereds the rectangle.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <param name="y">The y.</param>
|
||||
/// <param name="width">The width.</param>
|
||||
/// <param name="height">The height.</param>
|
||||
/// <param name="stroke">The stroke.</param>
|
||||
/// <param name="borderStroke">The border stroke.</param>
|
||||
/// <param name="brush">The brush.</param>
|
||||
/// <param name="borderBrush">The border brush.</param>
|
||||
public void BorderedRectangle(int x, int y, int width, int height, float stroke, float borderStroke, int brush,
|
||||
int borderBrush) {
|
||||
_device.DrawRectangle(
|
||||
new RawRectangleF(x - (stroke - borderStroke), y - (stroke - borderStroke),
|
||||
x + width + stroke - borderStroke, y + height + stroke - borderStroke), _brushContainer[borderBrush],
|
||||
borderStroke);
|
||||
|
||||
_device.DrawRectangle(new RawRectangleF(x, y, x + width, y + height), _brushContainer[brush], stroke);
|
||||
|
||||
_device.DrawRectangle(
|
||||
new RawRectangleF(x + (stroke - borderStroke), y + (stroke - borderStroke),
|
||||
x + width - stroke + borderStroke, y + height - stroke + borderStroke), _brushContainer[borderBrush],
|
||||
borderStroke);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Bordereds the circle.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <param name="y">The y.</param>
|
||||
/// <param name="radius">The radius.</param>
|
||||
/// <param name="stroke">The stroke.</param>
|
||||
/// <param name="brush">The brush.</param>
|
||||
/// <param name="borderBrush">The border brush.</param>
|
||||
public void BorderedCircle(int x, int y, int radius, float stroke, int brush, int borderBrush) {
|
||||
_device.DrawEllipse(new Ellipse(new RawVector2(x, y), radius + stroke, radius + stroke),
|
||||
_brushContainer[borderBrush], stroke);
|
||||
|
||||
_device.DrawEllipse(new Ellipse(new RawVector2(x, y), radius, radius), _brushContainer[brush], stroke);
|
||||
|
||||
_device.DrawEllipse(new Ellipse(new RawVector2(x, y), radius - stroke, radius - stroke),
|
||||
_brushContainer[borderBrush], stroke);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Do not buffer text if you draw i.e. FPS. Use buffer for player names, rank....
|
||||
/// </summary>
|
||||
/// <param name="text">The text.</param>
|
||||
/// <param name="font">The font.</param>
|
||||
/// <param name="brush">The brush.</param>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <param name="y">The y.</param>
|
||||
/// <param name="bufferText">if set to <c>true</c> [buffer text].</param>
|
||||
public void DrawText(string text, int font, int brush, int x, int y, bool bufferText = true) {
|
||||
if (bufferText) {
|
||||
var bufferPos = -1;
|
||||
|
||||
for (var i = 0; i < _layoutContainer.Count; i++) {
|
||||
if (_layoutContainer[i].Text.Length != text.Length || _layoutContainer[i].Text != text) {
|
||||
continue;
|
||||
}
|
||||
bufferPos = i;
|
||||
break;
|
||||
}
|
||||
|
||||
if (bufferPos == -1) {
|
||||
_layoutContainer.Add(new TextLayoutBuffer(text,
|
||||
new TextLayout(_fontFactory, text, _fontContainer[font], float.MaxValue, float.MaxValue)));
|
||||
bufferPos = _layoutContainer.Count - 1;
|
||||
}
|
||||
|
||||
_device.DrawTextLayout(new RawVector2(x, y), _layoutContainer[bufferPos].TextLayout,
|
||||
_brushContainer[brush], DrawTextOptions.NoSnap);
|
||||
}
|
||||
else {
|
||||
var layout = new TextLayout(_fontFactory, text, _fontContainer[font], float.MaxValue, float.MaxValue);
|
||||
_device.DrawTextLayout(new RawVector2(x, y), layout, _brushContainer[brush]);
|
||||
layout.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
14
src/Overlay.NET/Directx/DirectExternalXOverlayPlugin.cs
Normal file
14
src/Overlay.NET/Directx/DirectExternalXOverlayPlugin.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
namespace Overlay.NET.Directx {
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
/// <seealso cref="Overlay.NET.OverlayPlugin" />
|
||||
public abstract class DirectXOverlayPlugin : OverlayPlugin {
|
||||
/// <summary>
|
||||
/// Gets or sets the overlay window.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The overlay window.
|
||||
/// </value>
|
||||
public DirectXOverlayWindow OverlayWindow { get; protected set; }
|
||||
}
|
||||
}
|
||||
318
src/Overlay.NET/Directx/DirectXOverlayWindow.cs
Normal file
318
src/Overlay.NET/Directx/DirectXOverlayWindow.cs
Normal file
@@ -0,0 +1,318 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Overlay.NET.Common;
|
||||
|
||||
namespace Overlay.NET.Directx {
|
||||
public class DirectXOverlayWindow {
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance is disposing.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance is disposing; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool IsDisposing { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether [parent window exists].
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if [parent window exists]; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool ParentWindowExists { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance is top most.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance is top most; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool IsTopMost { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance is visible.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance is visible; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool IsVisible { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the x.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The x.
|
||||
/// </value>
|
||||
public int X { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the y.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The y.
|
||||
/// </value>
|
||||
public int Y { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the width.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The width.
|
||||
/// </value>
|
||||
public int Width { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the height.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The height.
|
||||
/// </value>
|
||||
public int Height { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the handle.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The handle.
|
||||
/// </value>
|
||||
public IntPtr Handle { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the parent window.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The parent window.
|
||||
/// </value>
|
||||
public IntPtr ParentWindow { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The margin
|
||||
/// </summary>
|
||||
private Native.RawMargin _margin;
|
||||
|
||||
/// <summary>
|
||||
/// The graphics
|
||||
/// </summary>
|
||||
public Direct2DRenderer Graphics;
|
||||
|
||||
/// <summary>
|
||||
/// Makes a transparent Fullscreen window
|
||||
/// </summary>
|
||||
/// <param name="limitFps">VSync</param>
|
||||
/// <exception cref="Exception">Could not create OverlayWindow</exception>
|
||||
public DirectXOverlayWindow(bool limitFps = true) {
|
||||
IsDisposing = false;
|
||||
IsVisible = true;
|
||||
IsTopMost = true;
|
||||
|
||||
ParentWindowExists = false;
|
||||
|
||||
X = 0;
|
||||
Y = 0;
|
||||
Width = Native.GetSystemMetrics(WindowConstants.SmCxScreen);
|
||||
Height = Native.GetSystemMetrics(WindowConstants.SmCyScreen);
|
||||
|
||||
ParentWindow = IntPtr.Zero;
|
||||
|
||||
if (!CreateWindow()) {
|
||||
throw new Exception("Could not create OverlayWindow");
|
||||
}
|
||||
|
||||
Graphics = new Direct2DRenderer(Handle, limitFps);
|
||||
|
||||
SetBounds(X, Y, Width, Height);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Makes a transparent window which adjust it's size and position to fit the parent window
|
||||
/// </summary>
|
||||
/// <param name="parent">HWND/Handle of a window</param>
|
||||
/// <param name="limitFps">VSync</param>
|
||||
/// <exception cref="Exception">
|
||||
/// The handle of the parent window isn't valid
|
||||
/// or
|
||||
/// Could not create OverlayWindow
|
||||
/// </exception>
|
||||
public DirectXOverlayWindow(IntPtr parent, bool limitFps = true) {
|
||||
if (parent == IntPtr.Zero) {
|
||||
throw new Exception("The handle of the parent window isn't valid");
|
||||
}
|
||||
|
||||
Native.Rect bounds;
|
||||
Native.GetWindowRect(parent, out bounds);
|
||||
|
||||
IsDisposing = false;
|
||||
IsVisible = true;
|
||||
IsTopMost = true;
|
||||
|
||||
ParentWindowExists = true;
|
||||
|
||||
X = bounds.Left;
|
||||
Y = bounds.Top;
|
||||
|
||||
Width = bounds.Right - bounds.Left;
|
||||
Height = bounds.Bottom - bounds.Top;
|
||||
|
||||
ParentWindow = parent;
|
||||
|
||||
if (!CreateWindow()) {
|
||||
throw new Exception("Could not create OverlayWindow");
|
||||
}
|
||||
|
||||
Graphics = new Direct2DRenderer(Handle, limitFps);
|
||||
|
||||
SetBounds(X, Y, Width, Height);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finalizes an instance of the <see cref="DirectXOverlayWindow" /> class.
|
||||
/// </summary>
|
||||
~DirectXOverlayWindow() {
|
||||
Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clean up used ressources and destroy window
|
||||
/// </summary>
|
||||
public void Dispose() {
|
||||
IsDisposing = true;
|
||||
Graphics.Dispose();
|
||||
Native.DestroyWindow(Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a window with the information's stored in this class
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// true on success
|
||||
/// </returns>
|
||||
private bool CreateWindow() {
|
||||
Handle = Native.CreateWindowEx(
|
||||
WindowConstants.WindowExStyleDx,
|
||||
WindowConstants.DesktopClass,
|
||||
"",
|
||||
WindowConstants.WindowStyleDx,
|
||||
X,
|
||||
Y,
|
||||
Width,
|
||||
Height,
|
||||
IntPtr.Zero,
|
||||
IntPtr.Zero,
|
||||
IntPtr.Zero,
|
||||
IntPtr.Zero);
|
||||
|
||||
if (Handle == IntPtr.Zero) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Native.SetLayeredWindowAttributes(Handle, 0, 255, WindowConstants.LwaAlpha);
|
||||
|
||||
ExtendFrameIntoClient();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resize and set new position if the parent window's bounds change
|
||||
/// </summary>
|
||||
public void Update() {
|
||||
if (!ParentWindowExists)
|
||||
return;
|
||||
|
||||
Native.Rect bounds;
|
||||
Native.GetWindowRect(ParentWindow, out bounds);
|
||||
|
||||
if (X != bounds.Left || Y != bounds.Top || Width != bounds.Right - bounds.Left ||
|
||||
Height != bounds.Bottom - bounds.Top) {
|
||||
SetBounds(bounds.Left, bounds.Top, bounds.Right - bounds.Left, bounds.Bottom - bounds.Top);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extends the frame into client.
|
||||
/// </summary>
|
||||
private void ExtendFrameIntoClient() {
|
||||
_margin.cxLeftWidth = X;
|
||||
_margin.cxRightWidth = Width;
|
||||
_margin.cyBottomHeight = Height;
|
||||
_margin.cyTopHeight = Y;
|
||||
Native.DwmExtendFrameIntoClientArea(Handle, ref _margin);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the position.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <param name="y">The y.</param>
|
||||
public void SetPos(int x, int y) {
|
||||
X = x;
|
||||
Y = y;
|
||||
|
||||
Native.SetWindowPos(Handle, WindowConstants.HwndTopmost, X, Y, Width, Height, 0);
|
||||
|
||||
ExtendFrameIntoClient();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the size.
|
||||
/// </summary>
|
||||
/// <param name="width">The width.</param>
|
||||
/// <param name="height">The height.</param>
|
||||
public void SetSize(int width, int height) {
|
||||
Width = width;
|
||||
Height = height;
|
||||
|
||||
Native.SetWindowPos(Handle, WindowConstants.HwndTopmost, X, Y, Width, Height, 0);
|
||||
|
||||
Graphics.AutoResize(Width, Height);
|
||||
|
||||
ExtendFrameIntoClient();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the bounds.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <param name="y">The y.</param>
|
||||
/// <param name="width">The width.</param>
|
||||
/// <param name="height">The height.</param>
|
||||
public void SetBounds(int x, int y, int width, int height) {
|
||||
X = x;
|
||||
Y = y;
|
||||
Width = width;
|
||||
Height = height;
|
||||
|
||||
Native.SetWindowPos(Handle, WindowConstants.HwndTopmost, X, Y, Width, Height, 0);
|
||||
|
||||
Graphics?.AutoResize(Width, Height);
|
||||
|
||||
ExtendFrameIntoClient();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shows this instance.
|
||||
/// </summary>
|
||||
public void Show() {
|
||||
if (IsVisible) {
|
||||
return;
|
||||
}
|
||||
|
||||
Native.ShowWindow(Handle, WindowConstants.SwShow);
|
||||
IsVisible = true;
|
||||
|
||||
ExtendFrameIntoClient();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Hides this instance.
|
||||
/// </summary>
|
||||
public void Hide() {
|
||||
if (!IsVisible) {
|
||||
return;
|
||||
}
|
||||
|
||||
Native.ShowWindow(Handle, WindowConstants.SwHide);
|
||||
IsVisible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
37
src/Overlay.NET/Directx/TextLayoutBuffer.cs
Normal file
37
src/Overlay.NET/Directx/TextLayoutBuffer.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using SharpDX.DirectWrite;
|
||||
|
||||
namespace Overlay.NET.Directx {
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
internal class TextLayoutBuffer {
|
||||
/// <summary>
|
||||
/// The text
|
||||
/// </summary>
|
||||
public string Text { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The text layout
|
||||
/// </summary>
|
||||
public TextLayout TextLayout { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TextLayoutBuffer" /> class.
|
||||
/// </summary>
|
||||
/// <param name="text">The text.</param>
|
||||
/// <param name="layout">The layout.</param>
|
||||
public TextLayoutBuffer(string text, TextLayout layout) {
|
||||
Text = text;
|
||||
TextLayout = layout;
|
||||
TextLayout.TextAlignment = TextAlignment.Leading;
|
||||
TextLayout.WordWrapping = WordWrapping.NoWrap;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Releases unmanaged and - optionally - managed resources.
|
||||
/// </summary>
|
||||
public void Dispose() {
|
||||
TextLayout.Dispose();
|
||||
Text = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
135
src/Overlay.NET/Overlay.NET.csproj
Normal file
135
src/Overlay.NET/Overlay.NET.csproj
Normal file
@@ -0,0 +1,135 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{2D411EA5-BC00-4630-B25E-43C554323E72}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Overlay.NET</RootNamespace>
|
||||
<AssemblyName>Overlay.NET</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<StartupObject />
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Process.NET, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Process.NET.1.0.8\lib\Process.NET.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SharpDX, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\SharpDX.4.2.0\lib\net45\SharpDX.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SharpDX.Direct2D1, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\SharpDX.Direct2D1.4.2.0\lib\net45\SharpDX.Direct2D1.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SharpDX.DXGI, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\SharpDX.DXGI.4.2.0\lib\net45\SharpDX.DXGI.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SharpDX.Mathematics, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\SharpDX.Mathematics.4.2.0\lib\net45\SharpDX.Mathematics.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xaml">
|
||||
<RequiredTargetFramework>4.0</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="WindowsBase" />
|
||||
<Reference Include="PresentationCore" />
|
||||
<Reference Include="PresentationFramework" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Include="Wpf\OverlayWindow.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Common\FileLogger.cs" />
|
||||
<Compile Include="Common\ISerializer.cs" />
|
||||
<Compile Include="Common\ISettings.cs" />
|
||||
<Compile Include="Common\Log.cs" />
|
||||
<Compile Include="Common\Native.cs" />
|
||||
<Compile Include="Common\PluginBase.cs" />
|
||||
<Compile Include="Common\PluginLoader.cs" />
|
||||
<Compile Include="Common\RelativeFile.cs" />
|
||||
<Compile Include="Common\SerializableSettings.cs" />
|
||||
<Compile Include="Common\TickEngine.cs" />
|
||||
<Compile Include="Common\TimeSpanExtensions.cs" />
|
||||
<Compile Include="Common\WaitTimer.cs" />
|
||||
<Compile Include="Common\XmlSerializerEx.cs" />
|
||||
<Compile Include="Directx\Direct2DRenderer.cs" />
|
||||
<Compile Include="Directx\DirectExternalXOverlayPlugin.cs" />
|
||||
<Compile Include="Directx\DirectXOverlayWindow.cs" />
|
||||
<Compile Include="Directx\TextLayoutBuffer.cs" />
|
||||
<Compile Include="Common\WindowConstants.cs" />
|
||||
<Compile Include="OverlayPlugin.cs" />
|
||||
<Compile Include="Wpf\OverlayWindow.xaml.cs">
|
||||
<DependentUpon>OverlayWindow.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Properties\AssemblyInfo.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Properties\Settings.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
<Compile Include="Common\WindowExtensions.cs" />
|
||||
<Compile Include="Wpf\WpfOverlayPlugin.cs" />
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
<None Include="packages.config" />
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<AppDesigner Include="Properties\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
54
src/Overlay.NET/OverlayPlugin.cs
Normal file
54
src/Overlay.NET/OverlayPlugin.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
using System;
|
||||
using Overlay.NET.Common;
|
||||
using Process.NET.Windows;
|
||||
|
||||
namespace Overlay.NET {
|
||||
/// <summary>
|
||||
/// Abstract class that defines basic overlay operations and values.
|
||||
/// </summary>
|
||||
/// <seealso cref="Overlay.NET.Common.PluginBase" />
|
||||
/// <seealso cref="System.IDisposable" />
|
||||
public abstract class OverlayPlugin : PluginBase, IDisposable {
|
||||
/// <summary>
|
||||
/// Gets or sets the target window that the overlay is to 'attach' to.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The target window.
|
||||
/// </value>
|
||||
public IWindow TargetWindow { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this instance is enabled.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance is enabled; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool IsEnabled { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
||||
/// </summary>
|
||||
public virtual void Dispose() {}
|
||||
|
||||
/// <summary>
|
||||
/// Enables this instance.
|
||||
/// </summary>
|
||||
public virtual void Enable() => IsEnabled = true;
|
||||
|
||||
/// <summary>
|
||||
/// Disables this instance.
|
||||
/// </summary>
|
||||
public virtual void Disable() => IsEnabled = false;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the specified target window.
|
||||
/// </summary>
|
||||
/// <param name="targetWindow">The target window.</param>
|
||||
public virtual void Initialize(IWindow targetWindow) => TargetWindow = targetWindow;
|
||||
|
||||
/// <summary>
|
||||
/// Updates this instance.
|
||||
/// </summary>
|
||||
public virtual void Update() {}
|
||||
}
|
||||
}
|
||||
54
src/Overlay.NET/Properties/AssemblyInfo.cs
Normal file
54
src/Overlay.NET/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
|
||||
[assembly: AssemblyTitle("Overlay.NET")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Overlay.NET")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2016")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
//In order to begin building localizable applications, set
|
||||
//<UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file
|
||||
//inside a <PropertyGroup>. For example, if you are using US english
|
||||
//in your source files, set the <UICulture> to en-US. Then uncomment
|
||||
//the NeutralResourceLanguage attribute below. Update the "en-US" in
|
||||
//the line below to match the UICulture setting in the project file.
|
||||
|
||||
//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
|
||||
|
||||
[assembly: ThemeInfo(
|
||||
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
|
||||
//(used if a resource is not found in the page,
|
||||
// or application resource dictionaries)
|
||||
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
|
||||
//(used if a resource is not found in the page,
|
||||
// app, or any theme specific resource dictionaries)
|
||||
)]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
63
src/Overlay.NET/Properties/Resources.Designer.cs
generated
Normal file
63
src/Overlay.NET/Properties/Resources.Designer.cs
generated
Normal file
@@ -0,0 +1,63 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Overlay.NET.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Overlay.NET.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
117
src/Overlay.NET/Properties/Resources.resx
Normal file
117
src/Overlay.NET/Properties/Resources.resx
Normal file
@@ -0,0 +1,117 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
26
src/Overlay.NET/Properties/Settings.Designer.cs
generated
Normal file
26
src/Overlay.NET/Properties/Settings.Designer.cs
generated
Normal file
@@ -0,0 +1,26 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Overlay.NET.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.0.1.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
public static Settings Default {
|
||||
get {
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
8
src/Overlay.NET/Properties/Settings.settings
Normal file
8
src/Overlay.NET/Properties/Settings.settings
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
|
||||
<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
|
||||
<Profiles>
|
||||
<Profile Name="(Default)" />
|
||||
</Profiles>
|
||||
<Settings />
|
||||
</SettingsFile>
|
||||
15
src/Overlay.NET/Wpf/OverlayWindow.xaml
Normal file
15
src/Overlay.NET/Wpf/OverlayWindow.xaml
Normal file
@@ -0,0 +1,15 @@
|
||||
<Window x:Class="Overlay.NET.Wpf.OverlayWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
Title="WowSharp Overlay OverlayWindow" Height="300" Width="300"
|
||||
WindowStyle="None"
|
||||
Topmost="True"
|
||||
AllowsTransparency="True">
|
||||
<Window.Background>
|
||||
<SolidColorBrush Opacity="0.0" Color="Black" />
|
||||
</Window.Background>
|
||||
<Canvas x:Name="OverlayGrid" HorizontalAlignment="Left" Height="300" VerticalAlignment="Top" Width="300" />
|
||||
</Window>
|
||||
93
src/Overlay.NET/Wpf/OverlayWindow.xaml.cs
Normal file
93
src/Overlay.NET/Wpf/OverlayWindow.xaml.cs
Normal file
@@ -0,0 +1,93 @@
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using Overlay.NET.Common;
|
||||
using Process.NET.Windows;
|
||||
|
||||
namespace Overlay.NET.Wpf {
|
||||
/// <summary>
|
||||
/// Interaction logic for OverlayWindow.xaml
|
||||
/// </summary>
|
||||
public partial class OverlayWindow : Window {
|
||||
private readonly IWindow _targetWindow;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="OverlayWindow" /> class.
|
||||
/// </summary>
|
||||
/// <param name="targetWindow">The window.</param>
|
||||
public OverlayWindow(IWindow targetWindow) {
|
||||
_targetWindow = targetWindow;
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public event EventHandler<DrawingContext> Draw;
|
||||
|
||||
/// <summary>
|
||||
/// Updates this instance.
|
||||
/// </summary>
|
||||
public void Update() {
|
||||
Width = _targetWindow.Width;
|
||||
Height = _targetWindow.Height;
|
||||
Left = _targetWindow.X;
|
||||
Top = _targetWindow.Y;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raises the <see cref="E:System.Windows.Window.SourceInitialized" /> event.
|
||||
/// </summary>
|
||||
/// <param name="e">An <see cref="T:System.EventArgs" /> that contains the event data.</param>
|
||||
protected override void OnSourceInitialized(EventArgs e) {
|
||||
base.OnSourceInitialized(e);
|
||||
// We need to do this in order to allow shapes
|
||||
// drawn on the canvas to be click-through.
|
||||
// There is no other way to do this.
|
||||
// Source: https://social.msdn.microsoft.com/Forums/en-US/c32889d3-effa-4b82-b179-76489ffa9f7d/how-to-clicking-throughpassing-shapesellipserectangle?forum=wpf
|
||||
this.MakeWindowTransparent();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// When overridden in a derived class, participates in rendering operations that are directed by the layout system.
|
||||
/// The rendering instructions for this element are not used directly when this method is invoked, and are instead
|
||||
/// preserved for later asynchronous use by layout and drawing.
|
||||
/// </summary>
|
||||
/// <param name="drawingContext">
|
||||
/// The drawing instructions for a specific element. This context is provided to the layout
|
||||
/// system.
|
||||
/// </param>
|
||||
protected override void OnRender(DrawingContext drawingContext) {
|
||||
OnDraw(drawingContext);
|
||||
base.OnRender(drawingContext);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the specified element.
|
||||
/// </summary>
|
||||
/// <param name="element">The element.</param>
|
||||
public void Add(UIElement element) => OverlayGrid.Children.Add(element);
|
||||
|
||||
/// <summary>
|
||||
/// Removes the specified element.
|
||||
/// </summary>
|
||||
/// <param name="element">The element.</param>
|
||||
public void Remove(UIElement element) => OverlayGrid.Children.Remove(element);
|
||||
|
||||
/// <summary>
|
||||
/// Adds the specified element.
|
||||
/// </summary>
|
||||
/// <param name="element">The element.</param>
|
||||
/// <param name="index">The index.</param>
|
||||
public void Add(UIElement element, int index) => OverlayGrid.Children[index] = element;
|
||||
|
||||
/// <summary>
|
||||
/// Removes the specified index.
|
||||
/// </summary>
|
||||
/// <param name="index">The index.</param>
|
||||
public void Remove(int index) => OverlayGrid.Children.RemoveAt(index);
|
||||
|
||||
/// <summary>
|
||||
/// Called when [draw].
|
||||
/// </summary>
|
||||
/// <param name="e">The e.</param>
|
||||
protected virtual void OnDraw(DrawingContext e) => Draw?.Invoke(this, e);
|
||||
}
|
||||
}
|
||||
15
src/Overlay.NET/Wpf/WpfOverlayPlugin.cs
Normal file
15
src/Overlay.NET/Wpf/WpfOverlayPlugin.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
namespace Overlay.NET.Wpf {
|
||||
/// <summary>
|
||||
/// Abstract overlay that uses a transparent WPF window to do its rendering.
|
||||
/// </summary>
|
||||
/// <seealso cref="Overlay.NET.OverlayPlugin" />
|
||||
public abstract class WpfOverlayPlugin : OverlayPlugin {
|
||||
/// <summary>
|
||||
/// Gets or sets the overlay window.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The overlay window.
|
||||
/// </value>
|
||||
public OverlayWindow OverlayWindow { get; protected set; }
|
||||
}
|
||||
}
|
||||
8
src/Overlay.NET/packages.config
Normal file
8
src/Overlay.NET/packages.config
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Process.NET" version="1.0.8" targetFramework="net461" />
|
||||
<package id="SharpDX" version="4.2.0" targetFramework="net462" />
|
||||
<package id="SharpDX.Direct2D1" version="4.2.0" targetFramework="net462" />
|
||||
<package id="SharpDX.DXGI" version="4.2.0" targetFramework="net462" />
|
||||
<package id="SharpDX.Mathematics" version="4.2.0" targetFramework="net462" />
|
||||
</packages>
|
||||
Reference in New Issue
Block a user