Initial commit: Complete open-source Decal rebuild

All 5 phases of the open-source Decal rebuild:

Phase 1: 14 decompiled .NET projects (Interop.*, Adapter, FileService, DecalUtil)
Phase 2: 10 native DLLs rewritten as C# COM servers with matching GUIDs
  - DecalDat, DHS, SpellFilter, DecalInput, DecalNet, DecalFilters
  - Decal.Core, DecalControls, DecalRender, D3DService
Phase 3: C++ shims for Inject.DLL (D3D9 hooking) and LauncherHook.DLL
Phase 4: DenAgent WinForms tray application
Phase 5: WiX installer and build script

25 C# projects building with 0 errors.
Native C++ projects require VS 2022 + Windows SDK (x86).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
erik 2026-02-08 18:27:56 +01:00
commit d1442e3747
1382 changed files with 170725 additions and 0 deletions

View file

@ -0,0 +1,45 @@
using System.Runtime.InteropServices;
using Decal.Interop.Controls;
using Decal.Interop.Inject;
namespace Decal.DecalControls
{
[ComVisible(true)]
[Guid("5AE37451-F79C-478A-834E-EDCF95F01B0E")]
[ClassInterface(ClassInterfaceType.None)]
[ComSourceInterfaces("Decal.Interop.Controls.ICheckboxEvents\0\0")]
[ProgId("DecalControls.Checkbox")]
public class CheckboxImpl : ControlBase, ICheckbox
{
public event ICheckboxEvents_DestroyEventHandler Destroy;
public event ICheckboxEvents_ChangeEventHandler Change;
private IFontCache _font;
private string _text = "";
private int _textColor;
private bool _checked;
private bool _rightToLeft;
public IFontCache Font { get => _font; set { _font = value; Invalidate(); } }
public string Text { get => _text; set { _text = value; Invalidate(); } }
public int TextColor { get => _textColor; set { _textColor = value; Invalidate(); } }
public bool Checked
{
get => _checked;
set
{
if (_checked != value)
{
_checked = value;
Invalidate();
Change?.Invoke(ID, _checked);
}
}
}
public bool RightToLeft { get => _rightToLeft; set { _rightToLeft = value; Invalidate(); } }
protected override void OnDestroy() => Destroy?.Invoke(ID);
}
}

View file

@ -0,0 +1,113 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Decal.Interop.Controls;
using Decal.Interop.Inject;
namespace Decal.DecalControls
{
[ComVisible(true)]
[Guid("E099DC60-0F19-4690-AB7C-8B5834DA286E")]
[ClassInterface(ClassInterfaceType.None)]
[ComSourceInterfaces("Decal.Interop.Controls.IChoiceEvents\0\0")]
[ProgId("DecalControls.Choice")]
public class ChoiceImpl : ControlBase, IChoice
{
public event IChoiceEvents_DestroyEventHandler Destroy;
public event IChoiceEvents_ChangeEventHandler Change;
public event IChoiceEvents_DropDownEventHandler DropDown;
private struct ChoiceItem
{
public string Display;
public object Data;
}
private readonly List<ChoiceItem> _items = new List<ChoiceItem>();
private int _selected = -1;
private bool _dropped;
private int _dropLines = 5;
public void AddChoice(string strDisplay, object vData = null)
{
_items.Add(new ChoiceItem { Display = strDisplay, Data = vData });
}
public int ChoiceCount => _items.Count;
public object Data
{
get => (_selected >= 0 && _selected < _items.Count) ? _items[_selected].Data : null;
set
{
if (_selected >= 0 && _selected < _items.Count)
{
var item = _items[_selected];
item.Data = value;
_items[_selected] = item;
}
}
}
public string Text
{
get => (_selected >= 0 && _selected < _items.Count) ? _items[_selected].Display : "";
set
{
if (_selected >= 0 && _selected < _items.Count)
{
var item = _items[_selected];
item.Display = value ?? "";
_items[_selected] = item;
Invalidate();
}
}
}
public void RemoveChoice(int nIndex)
{
if (nIndex >= 0 && nIndex < _items.Count)
{
_items.RemoveAt(nIndex);
if (_selected >= _items.Count) _selected = _items.Count - 1;
Invalidate();
}
}
public bool Dropped
{
get => _dropped;
set
{
_dropped = value;
if (_dropped) DropDown?.Invoke(ID);
Invalidate();
}
}
public int Selected
{
get => _selected;
set
{
if (value >= -1 && value < _items.Count && value != _selected)
{
_selected = value;
Invalidate();
Change?.Invoke(ID, _selected);
}
}
}
public int DropLines { get => _dropLines; set { _dropLines = value; Invalidate(); } }
public void Clear()
{
_items.Clear();
_selected = -1;
Invalidate();
}
protected override void OnDestroy() => Destroy?.Invoke(ID);
}
}

View file

@ -0,0 +1,58 @@
using System.Runtime.InteropServices;
using Decal.Interop.Core;
using Decal.Interop.Inject;
namespace Decal.DecalControls
{
[ComVisible(true)]
public abstract class ControlBase : ILayer, IControl
{
protected Layer _site;
private int _id;
// ILayer
public void LayerCreate(Layer pSite)
{
_site = pSite;
var site = (ILayerSite)(object)pSite;
_id = site.ID;
OnCreate();
}
public void LayerDestroy()
{
OnDestroy();
_site = null;
}
public tagRECT Position
{
get
{
if (_site != null)
return ((ILayerSite)(object)_site).Position;
return default;
}
set
{
if (_site != null)
((ILayerSite)(object)_site).Position = value;
}
}
public void Invalidate()
{
if (_site != null)
((ILayerSite)(object)_site).Invalidate();
}
// IControl
public void DestroyChild(int nIndex, ePositionType posType) { }
public int ID => _id;
public int ChildCount => (_site != null) ? ((ILayerSite)(object)_site).ChildCount : 0;
public IControl Child => null;
protected virtual void OnCreate() { }
protected virtual void OnDestroy() { }
}
}

View file

@ -0,0 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\Decal.Interop.Core\Decal.Interop.Core.csproj" />
<ProjectReference Include="..\Decal.Interop.Inject\Decal.Interop.Inject.csproj" />
<ProjectReference Include="..\Decal.Interop.Controls\Decal.Interop.Controls.csproj" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,27 @@
using System.Runtime.InteropServices;
using Decal.Interop.Controls;
using Decal.Interop.Inject;
using CmdDestroy = Decal.Interop.Inject.ICommandEvents_DestroyEventHandler;
using CmdHit = Decal.Interop.Inject.ICommandEvents_HitEventHandler;
using CmdUnhit = Decal.Interop.Inject.ICommandEvents_UnhitEventHandler;
using CmdAccepted = Decal.Interop.Inject.ICommandEvents_AcceptedEventHandler;
using CmdCanceled = Decal.Interop.Inject.ICommandEvents_CanceledEventHandler;
namespace Decal.DecalControls
{
[ComVisible(true)]
[Guid("3035299A-C5FB-4CC7-A63C-66400B80DCA4")]
[ClassInterface(ClassInterfaceType.None)]
[ComSourceInterfaces("Decal.Interop.Inject.ICommandEvents\0\0")]
[ProgId("DecalControls.DerethMap")]
public class DerethMapImpl : ControlBase, IDerethMap
{
public event CmdDestroy Destroy;
public event CmdHit Hit;
public event CmdUnhit Unhit;
public event CmdAccepted Accepted;
public event CmdCanceled Canceled;
protected override void OnDestroy() => Destroy?.Invoke(ID);
}
}

View file

@ -0,0 +1,85 @@
using System.Runtime.InteropServices;
using Decal.Interop.Controls;
using Decal.Interop.Inject;
namespace Decal.DecalControls
{
[ComVisible(true)]
[Guid("8E8F88D2-AA47-474E-9DB7-912D49C8BE9D")]
[ClassInterface(ClassInterfaceType.None)]
[ComSourceInterfaces("Decal.Interop.Controls.IEditEvents\0\0")]
[ProgId("DecalControls.Edit")]
public class EditImpl : ControlBase, IEdit
{
public event IEditEvents_DestroyEventHandler Destroy;
public event IEditEvents_BeginEventHandler Begin;
public event IEditEvents_ChangeEventHandler Change;
public event IEditEvents_EndEventHandler End;
private string _text = "";
private int _caret;
private int _selStart, _selEnd;
private IImageCache _background;
private IFontCache _font;
private int _textColor;
public string Text
{
get => _text;
set
{
_text = value ?? "";
_caret = _text.Length;
Invalidate();
Change?.Invoke(ID, _text);
}
}
public int Caret { get => _caret; set { _caret = value; Invalidate(); } }
public void Select(int nStart, int nEnd)
{
_selStart = nStart;
_selEnd = nEnd;
Invalidate();
}
public string SelectedText
{
get
{
if (_selStart >= 0 && _selEnd > _selStart && _selEnd <= _text.Length)
return _text.Substring(_selStart, _selEnd - _selStart);
return "";
}
set
{
if (_selStart >= 0 && _selEnd > _selStart && _selEnd <= _text.Length)
{
_text = _text.Remove(_selStart, _selEnd - _selStart).Insert(_selStart, value ?? "");
_caret = _selStart + (value?.Length ?? 0);
_selStart = _selEnd = 0;
Invalidate();
Change?.Invoke(ID, _text);
}
}
}
public IImageCache Background { get => _background; set { _background = value; Invalidate(); } }
public IFontCache Font { get => _font; set { _font = value; Invalidate(); } }
public int TextColor { get => _textColor; set { _textColor = value; Invalidate(); } }
public void SetMargins(int nX, int nY) { }
public void Capture()
{
if (_site != null)
{
((ILayerSite)(object)_site).CaptureKeyboard();
Begin?.Invoke(ID);
}
}
protected override void OnDestroy() => Destroy?.Invoke(ID);
}
}

View file

@ -0,0 +1,92 @@
using System.Runtime.InteropServices;
using Decal.Interop.Controls;
using Decal.Interop.Core;
using Decal.Interop.Inject;
namespace Decal.DecalControls
{
[ComVisible(true)]
[Guid("CD6556CD-F8D9-4CB0-AB7C-7C33058294E4")]
[ClassInterface(ClassInterfaceType.None)]
[ComSourceInterfaces("Decal.Interop.Inject.IControlEvents\0\0")]
[ProgId("DecalControls.FixedLayout")]
public class FixedLayoutImpl : ControlBase, ILayout
{
public event IControlEvents_DestroyEventHandler Destroy;
private IImageCache _background;
public IImageCache Background { get => _background; set { _background = value; Invalidate(); } }
public void CreateChild(ref LayerParams @params, ILayer pSink)
{
if (_site != null)
((ILayerSite)(object)_site).CreateChild(ref @params, pSink);
}
public void PositionChild(int nID, ref tagRECT prcNew) { }
protected override void OnDestroy() => Destroy?.Invoke(ID);
}
[ComVisible(true)]
[Guid("CA121762-31BB-4073-8597-33BAB4BDCAA3")]
[ClassInterface(ClassInterfaceType.None)]
[ComSourceInterfaces("Decal.Interop.Inject.IControlEvents\0\0")]
[ProgId("DecalControls.BorderLayout")]
public class BorderLayoutImpl : ControlBase, ILayout
{
public event IControlEvents_DestroyEventHandler Destroy;
private IImageCache _background;
public IImageCache Background { get => _background; set { _background = value; Invalidate(); } }
public void CreateEdge(eBorderEdge eEdge, int nSize, ILayer pSink) { }
public void CreateCenter(ILayer pSink) { }
protected override void OnDestroy() => Destroy?.Invoke(ID);
}
[ComVisible(true)]
[Guid("5AD04D45-D4BF-4729-8A2E-5D37CF726CAA")]
[ClassInterface(ClassInterfaceType.None)]
[ComSourceInterfaces("Decal.Interop.Inject.IControlEvents\0\0")]
[ProgId("DecalControls.PageLayout")]
public class PageLayoutImpl : ControlBase, IPageLayout
{
public event IControlEvents_DestroyEventHandler Destroy;
private IImageCache _background;
private readonly System.Collections.Generic.List<ILayer> _pages = new System.Collections.Generic.List<ILayer>();
private int _active;
// ILayout
public IImageCache Background { get => _background; set { _background = value; Invalidate(); } }
// IPageLayoutDisp
public int Active
{
get => _active;
set
{
if (value >= 0 && value < _pages.Count)
{
_active = value;
Invalidate();
}
}
}
public int Count => _pages.Count;
// IPageLayout
public void CreatePage(ILayer pChild)
{
_pages.Add(pChild);
Invalidate();
}
protected override void OnDestroy() => Destroy?.Invoke(ID);
}
}

View file

@ -0,0 +1,48 @@
using System.Runtime.InteropServices;
using Decal.Interop.Controls;
using Decal.Interop.Core;
using Decal.Interop.Inject;
namespace Decal.DecalControls
{
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
public abstract class ListColumnBase : IListColumn
{
private int _width = 100;
public bool FixedWidth => false;
public int Width { get => _width; set => _width = value; }
public int DataColumns => 1;
public int Height => 16;
public virtual void Render(Canvas canvas, ref tagPOINT ptCell, int nColor) { }
public virtual void Initialize(IList newVal, PluginSite pSite) { }
public virtual void SchemaLoad(object pSchema) { }
public virtual void Activate(ref tagPOINT ptCell) { }
}
[ComVisible(true)]
[Guid("864DEABF-D079-4B61-A8CF-081418179239")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("DecalControls.TextColumn")]
public class TextColumnImpl : ListColumnBase
{
}
[ComVisible(true)]
[Guid("F12A2C4C-3B78-46EB-8722-68B27A75AE55")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("DecalControls.IconColumn")]
public class IconColumnImpl : ListColumnBase
{
}
[ComVisible(true)]
[Guid("48E444F1-8E30-4E4C-B203-4C87FC901586")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("DecalControls.CheckColumn")]
public class CheckColumnImpl : ListColumnBase
{
}
}

View file

@ -0,0 +1,129 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Decal.Interop.Controls;
using Decal.Interop.Core;
using Decal.Interop.Inject;
namespace Decal.DecalControls
{
[ComVisible(true)]
[Guid("3839008F-AF5B-43FC-9F6A-3376B99E3DAF")]
[ClassInterface(ClassInterfaceType.None)]
[ComSourceInterfaces("Decal.Interop.Controls.IListEvents\0\0")]
[ProgId("DecalControls.List")]
public class ListImpl : ControlBase, IList
{
public event IListEvents_DestroyEventHandler Destroy;
public event IListEvents_ChangeEventHandler Change;
private readonly List<IListColumn> _columns = new List<IListColumn>();
private readonly List<object[]> _rows = new List<object[]>();
private int _scrollPosition;
private bool _autoScroll;
private int _accessRow, _accessCol;
// IListDisp
public int AddRow()
{
int totalDataCols = 0;
foreach (var col in _columns)
totalDataCols += col.DataColumns;
_rows.Add(new object[Math.Max(1, totalDataCols)]);
if (_autoScroll)
_scrollPosition = Math.Max(0, _rows.Count - 1);
Invalidate();
return _rows.Count - 1;
}
public void DeleteRow(int nIndex)
{
if (nIndex >= 0 && nIndex < _rows.Count)
{
_rows.RemoveAt(nIndex);
Invalidate();
}
}
public object Data
{
get
{
if (_accessRow >= 0 && _accessRow < _rows.Count)
{
var row = _rows[_accessRow];
if (_accessCol >= 0 && _accessCol < row.Length)
return row[_accessCol];
}
return null;
}
set
{
if (_accessRow >= 0 && _accessRow < _rows.Count)
{
var row = _rows[_accessRow];
if (_accessCol >= 0 && _accessCol < row.Length)
{
row[_accessCol] = value;
Invalidate();
Change?.Invoke(ID, _accessCol, _accessRow);
}
}
}
}
public int RowEstimate { set { } }
public int Count => _rows.Count;
public int ColumnWidth
{
get => 0;
set { }
}
public int Color { get; set; }
public bool AutoScroll { get => _autoScroll; set => _autoScroll = value; }
public int ScrollPosition { get => _scrollPosition; set { _scrollPosition = value; Invalidate(); } }
public void Clear()
{
_rows.Clear();
_scrollPosition = 0;
Invalidate();
}
public void InsertRow(int lIndex)
{
int totalDataCols = 0;
foreach (var col in _columns)
totalDataCols += col.DataColumns;
if (lIndex < 0) lIndex = 0;
if (lIndex > _rows.Count) lIndex = _rows.Count;
_rows.Insert(lIndex, new object[Math.Max(1, totalDataCols)]);
Invalidate();
}
public void JumpToPosition(int newVal)
{
_scrollPosition = newVal;
Invalidate();
}
public int CountCols => _columns.Count;
// IList
public int AddColumn(IListColumn pNewColumn)
{
_columns.Add(pNewColumn);
return _columns.Count - 1;
}
public tagRECT CellRect => default;
protected override void OnDestroy() => Destroy?.Invoke(ID);
}
}

View file

@ -0,0 +1,64 @@
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Decal.Interop.Controls;
using Decal.Interop.Inject;
namespace Decal.DecalControls
{
[ComVisible(true)]
[Guid("ED14E7C5-11BE-4DFD-9829-873AB6BE3CFC")]
[ClassInterface(ClassInterfaceType.None)]
[ComSourceInterfaces("Decal.Interop.Controls.INotebookEvents\0\0")]
[ProgId("DecalControls.Notebook")]
public class NotebookImpl : ControlBase, INotebook
{
public event INotebookEvents_DestroyEventHandler Destroy;
public event INotebookEvents_ChangeEventHandler Change;
private struct Page
{
public string Text;
public IControl Client;
}
private readonly List<Page> _pages = new List<Page>();
private int _activeTab;
public void AddPage(string strText, IControl pClient)
{
_pages.Add(new Page { Text = strText ?? "", Client = pClient });
Invalidate();
}
public int ActiveTab
{
get => _activeTab;
set
{
if (value >= 0 && value < _pages.Count && value != _activeTab)
{
_activeTab = value;
Invalidate();
Change?.Invoke(ID, _activeTab);
}
}
}
public string PageText
{
get => (_activeTab >= 0 && _activeTab < _pages.Count) ? _pages[_activeTab].Text : "";
set
{
if (_activeTab >= 0 && _activeTab < _pages.Count)
{
var page = _pages[_activeTab];
page.Text = value ?? "";
_pages[_activeTab] = page;
Invalidate();
}
}
}
protected override void OnDestroy() => Destroy?.Invoke(ID);
}
}

View file

@ -0,0 +1,42 @@
using System.Runtime.InteropServices;
using Decal.Interop.Controls;
using Decal.Interop.Inject;
namespace Decal.DecalControls
{
[ComVisible(true)]
[Guid("FE361225-6BB7-4AE0-A10C-8A6420621680")]
[ClassInterface(ClassInterfaceType.None)]
[ComSourceInterfaces("Decal.Interop.Inject.IControlEvents\0\0")]
[ProgId("DecalControls.Progress")]
public class ProgressImpl : ControlBase, IProgress
{
public event IControlEvents_DestroyEventHandler Destroy;
private int _value;
private int _faceColor;
private int _fillColor;
private int _textColor;
private int _maxValue = 100;
private string _postText = "";
private string _alignment = "center";
private bool _decalDrawText;
private string _preText = "";
private int _borderWidth;
private int _borderColor;
public int Value { get => _value; set { _value = value; Invalidate(); } }
public int FaceColor { set { _faceColor = value; Invalidate(); } }
public int FillColor { set { _fillColor = value; Invalidate(); } }
public int TextColor { set { _textColor = value; Invalidate(); } }
public int MaxValue { set { _maxValue = value; Invalidate(); } }
public string PostText { set { _postText = value ?? ""; Invalidate(); } }
public string Alignment { set { _alignment = value ?? "center"; Invalidate(); } }
public bool DecalDrawText { set { _decalDrawText = value; Invalidate(); } }
public string PreText { set { _preText = value ?? ""; Invalidate(); } }
public int BorderWidth { set { _borderWidth = value; Invalidate(); } }
public int BorderColor { set { _borderColor = value; Invalidate(); } }
protected override void OnDestroy() => Destroy?.Invoke(ID);
}
}

View file

@ -0,0 +1,44 @@
using System.Runtime.InteropServices;
using Decal.Interop.Controls;
using Decal.Interop.Inject;
using CmdDestroy = Decal.Interop.Inject.ICommandEvents_DestroyEventHandler;
using CmdHit = Decal.Interop.Inject.ICommandEvents_HitEventHandler;
using CmdUnhit = Decal.Interop.Inject.ICommandEvents_UnhitEventHandler;
using CmdAccepted = Decal.Interop.Inject.ICommandEvents_AcceptedEventHandler;
using CmdCanceled = Decal.Interop.Inject.ICommandEvents_CanceledEventHandler;
namespace Decal.DecalControls
{
[ComVisible(true)]
[Guid("AE4525BE-81D1-40FB-9170-77172077EB49")]
[ClassInterface(ClassInterfaceType.None)]
[ComSourceInterfaces("Decal.Interop.Inject.ICommandEvents\0\0")]
[ProgId("DecalControls.PushButton")]
public class PushButtonImpl : ControlBase, IPushButton
{
public event CmdDestroy Destroy;
public event CmdHit Hit;
public event CmdUnhit Unhit;
public event CmdAccepted Accepted;
public event CmdCanceled Canceled;
private IImageCache _image;
private IFontCache _font;
private string _text = "";
private int _faceColor;
private int _textColor;
public IImageCache Image { get => _image; set { _image = value; Invalidate(); } }
public IFontCache Font { get => _font; set { _font = value; Invalidate(); } }
public string Text { get => _text; set { _text = value; Invalidate(); } }
public int FaceColor { get => _faceColor; set { _faceColor = value; Invalidate(); } }
public int TextColor { get => _textColor; set { _textColor = value; Invalidate(); } }
protected override void OnDestroy() => Destroy?.Invoke(ID);
internal void FireHit() => Hit?.Invoke(ID);
internal void FireUnhit() => Unhit?.Invoke(ID);
internal void FireAccepted() => Accepted?.Invoke(ID);
internal void FireCanceled() => Canceled?.Invoke(ID);
}
}

View file

@ -0,0 +1,67 @@
using System.Runtime.InteropServices;
using Decal.Interop.Controls;
using Decal.Interop.Core;
using Decal.Interop.Inject;
namespace Decal.DecalControls
{
[ComVisible(true)]
[Guid("8FC80D21-1731-4816-9AD3-B0364D5F2C27")]
[ClassInterface(ClassInterfaceType.None)]
[ComSourceInterfaces("Decal.Interop.Controls.IScrollerEvents\0\0")]
[ProgId("DecalControls.Scroller")]
public class ScrollerImpl : ControlBase, IScroller
{
public event IScrollerEvents_DestroyEventHandler Destroy;
public event IScrollerEvents_ChangeEventHandler Change;
private tagSIZE _area;
private tagPOINT _offset;
private tagSIZE _increments = new tagSIZE { cx = 1, cy = 1 };
private bool _horizontalEnabled = true;
private bool _verticalEnabled = true;
public tagSIZE Viewport
{
get
{
var pos = Position;
return new tagSIZE { cx = pos.right - pos.left, cy = pos.bottom - pos.top };
}
}
public tagSIZE Area { get => _area; set { _area = value; Invalidate(); } }
public bool HorizontalEnabled { get => _horizontalEnabled; set { _horizontalEnabled = value; Invalidate(); } }
public bool VerticalEnabled { get => _verticalEnabled; set { _verticalEnabled = value; Invalidate(); } }
public tagPOINT Offset
{
get => _offset;
set
{
_offset = value;
Invalidate();
Change?.Invoke(ID, _offset.x, _offset.y);
}
}
public tagSIZE Increments { get => _increments; set => _increments = value; }
public void CreateClient(ILayer pChild) { }
public void ScrollTo(ref tagPOINT ptOffset)
{
_offset = ptOffset;
Invalidate();
Change?.Invoke(ID, _offset.x, _offset.y);
}
public void ResetScroller()
{
_offset = default;
Invalidate();
}
protected override void OnDestroy() => Destroy?.Invoke(ID);
}
}

View file

@ -0,0 +1,46 @@
using System.Runtime.InteropServices;
using Decal.Interop.Controls;
using Decal.Interop.Inject;
namespace Decal.DecalControls
{
[ComVisible(true)]
[Guid("5D14557A-1268-43C6-A283-3B5B271359AA")]
[ClassInterface(ClassInterfaceType.None)]
[ComSourceInterfaces("Decal.Interop.Controls.ISliderEvents\0\0")]
[ProgId("DecalControls.Slider")]
public class SliderImpl : ControlBase, ISlider
{
public event ISliderEvents_DestroyEventHandler Destroy;
public event ISliderEvents_ChangeEventHandler Change;
private IFontCache _font;
private int _textColor;
private int _position;
private int _minimum;
private int _maximum = 100;
public IFontCache Font { get => _font; set { _font = value; Invalidate(); } }
public int TextColor { get => _textColor; set { _textColor = value; Invalidate(); } }
public int SliderPosition
{
get => _position;
set
{
int clamped = value < _minimum ? _minimum : (value > _maximum ? _maximum : value);
if (_position != clamped)
{
_position = clamped;
Invalidate();
Change?.Invoke(ID, _position);
}
}
}
public int Minimum { get => _minimum; set { _minimum = value; Invalidate(); } }
public int Maximum { get => _maximum; set { _maximum = value; Invalidate(); } }
protected override void OnDestroy() => Destroy?.Invoke(ID);
}
}

View file

@ -0,0 +1,26 @@
using System.Runtime.InteropServices;
using Decal.Interop.Controls;
using Decal.Interop.Inject;
namespace Decal.DecalControls
{
[ComVisible(true)]
[Guid("4887101C-A9F9-495B-921B-EF22822CFB97")]
[ClassInterface(ClassInterfaceType.None)]
[ComSourceInterfaces("Decal.Interop.Inject.IControlEvents\0\0")]
[ProgId("DecalControls.StaticText")]
public class StaticTextImpl : ControlBase, IStatic
{
public event IControlEvents_DestroyEventHandler Destroy;
private IFontCache _font;
private string _text = "";
private int _textColor;
public IFontCache Font { get => _font; set { _font = value; Invalidate(); } }
public string Text { get => _text; set { _text = value; Invalidate(); } }
public int TextColor { get => _textColor; set { _textColor = value; Invalidate(); } }
protected override void OnDestroy() => Destroy?.Invoke(ID);
}
}