IrcChatControl.Wpf 0.7.0

dotnet add package IrcChatControl.Wpf --version 0.7.0
                    
NuGet\Install-Package IrcChatControl.Wpf -Version 0.7.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="IrcChatControl.Wpf" Version="0.7.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="IrcChatControl.Wpf" Version="0.7.0" />
                    
Directory.Packages.props
<PackageReference Include="IrcChatControl.Wpf" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add IrcChatControl.Wpf --version 0.7.0
                    
#r "nuget: IrcChatControl.Wpf, 0.7.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package IrcChatControl.Wpf@0.7.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=IrcChatControl.Wpf&version=0.7.0
                    
Install as a Cake Addin
#tool nuget:?package=IrcChatControl.Wpf&version=0.7.0
                    
Install as a Cake Tool

IrcChatControl.Wpf

A high-throughput, console-style IRC chat control for WPF. Text is rendered by a native C++ DLL with Direct2D / DirectWrite into a D3D11 flip-model swapchain on a child HWND (hosted via HwndHost), bypassing WPF's retained-mode text stack entirely. A lock-free MPSC input queue and a fixed pre-allocated ring buffer let producer threads push thousands of lines per second without blocking the UI.

  • Throughput: 1,000–5,000+ lines/sec sustained; AddLine is thread-safe and cheap on the hot path.
  • Scrollback: 50,000-line pre-allocated ring buffer (configurable cap at runtime via SetMaxLines). The renderer is persistent: when the control leaves the visual tree its surface is parked (hidden and reparented), not destroyed, so hosts that cache and Content-swap chat views keep their history — and switching back costs a SetParent+ShowWindow, with no replay, re-parse, or GPU recreation.
  • Formatting: mIRC control codes (bold, italic, underline, strikethrough, reverse, indexed colors incl. the extended 0–98 range, \x04 hex colors) and ANSI SGR escape sequences (ESC[...m, incl. 38/48 extended colors).
  • Unicode: full UTF-8 pipeline with emoji (color font) and CJK wide-cell support.
  • Interaction: pixel-smooth wheel scrolling, PageUp/PageDown/Home/End, live scrollbar scrubbing, drag selection with clipboard copy, Ctrl+wheel font zoom.
  • Idle cost: the render timer parks when nothing changes — 0% CPU at idle.
  • Art-proof glyph atlas: monochrome glyphs are cached as color-independent alpha masks tinted at draw time, so rainbow-colored ASCII/Unicode art can't thrash the cache; atlas texture creation is additionally hard-capped per frame.

Requirements

  • Windows 10/11, x64 only (see note below)
  • .NET 8 (net8.0-windows)
  • No VC++ redistributable needed — the native renderer links the CRT statically

x64 note: the native renderer ships only as a win-x64 binary. Set <PlatformTarget>x64</PlatformTarget> in your app project. On Windows ARM64 an AnyCPU .NET 8 app runs as a native arm64 process and will not load the x64 DLL (win-arm64 does not fall back to win-x64 in the RID graph); forcing PlatformTarget=x64 makes the app run under x64 emulation instead, which works.

Install (NuGet)

dotnet add package IrcChatControl.Wpf

XAML:

<Window ...
        xmlns:irc="https://github.com/spenny2012/sIRCChatWindow">
    <irc:IrcChatControl x:Name="Chat" />
</Window>

(The clr-namespace form xmlns:irc="clr-namespace:IrcChatWpf;assembly=IrcChatControl.Wpf" works too.)

Code:

Chat.AddLine("\x0304Hello \x02world\x02 — colors, bold, ANSI \x1b[32mgreen\x1b[0m");

Use as a git submodule

git submodule add https://github.com/spenny2012/sIRCChatWindow.git external/sIRCChatWindow
  1. Add src/IrcRendererNative/IrcRendererNative.vcxproj and src/IrcChatControl.Wpf/IrcChatControl.Wpf.csproj to your solution (the native project needs the VS "Desktop development with C++" workload + Windows 10/11 SDK).
  2. Set a solution build dependency: IrcChatControl.Wpf → IrcRendererNative (the native DLL must exist before the library builds; you'll get a clear build warning if it doesn't).
  3. Reference IrcChatControl.Wpf from your app with a ProjectReference. The native DLL flows to your output automatically.

The native project always writes to <submodule>/build/<Configuration>/ regardless of where your solution lives, and the library looks it up there — no path wiring needed.

API

Member Description
AddLine(string text) Append a line (thread-safe). mIRC + ANSI codes parsed inline. Lines added while the control is unloaded are ingested immediately into the persistent scrollback.
Clear() Empty the scrollback (also decommits the arena).
LineCount Lines currently held in the ring buffer.
ScrollToEnd() Jump to the newest line and re-pin auto-follow.
SetMaxLines(int) Cap the scrollback line count at runtime.
WrapExtendedColors Classic-client color compatibility (default true): inbound \x03 indices 16–98 fold onto the basic palette (mod 16) instead of the standardized extended palette.
ParkedViewLimit (static) How many hidden controls keep their GPU surface parked for instant reattach (default 2). Hidden controls beyond the limit release their surface — scrollback is unaffected — and rebuild in a few ms when shown again.
Dispose() Deterministically frees the native renderer (scrollback + GPU) when a chat window closes for good; otherwise the SafeHandle finalizer frees it eventually.
TrimMemory() / TrimAllMemory() (static) Returns committed scrollback memory no longer in use to the OS (native arena compaction + decommit; content intact). Hook TrimAllMemory into an idle timer.
Background / Foreground / SelectionBrush Standard WPF brush properties — bindable, stylable, DynamicResource-friendly. Solid brushes reach the renderer.
FontFamily / FontSize Standard WPF font properties (default Consolas 14); inherit from the host window like any control.
SetBackgroundColor(Color) / SetForegroundColor(Color) / SetSelectionColor(Color) / SetFontFamily(string) / SetFontSize(double) Method equivalents of the properties above for code-driven theming.
EnableFontZoom Enable/disable Ctrl+wheel zoom (default on, clamped 6–72 pt).
CurrentFontSize The effective font size after zooming (same value as FontSize).

Keyboard scrolling (PageUp/PageDown/Home/End) activates after the control has been clicked (it takes focus on mouse-down).

Theming

The control themes like any WPF control — bind or style the standard properties:

<irc:IrcChatControl Background="{DynamicResource ChatBackgroundBrush}"
                    Foreground="{DynamicResource ChatForegroundBrush}"
                    FontFamily="Cascadia Mono" FontSize="13" />

Only SolidColorBrush values are forwarded to the native renderer (gradients/images can't be, and are applied to the WPF chrome only). FontFamily/FontSize are inherited properties, so a window-wide font cascades into the control; unstyled controls keep the console default (Consolas 14 on a dark palette). Theme changes are push-on-change only — nothing on the AddLine/render hot path reads these properties.

Formatting codes

Code Meaning
\x02 Toggle bold
\x03 mIRC color index 0–98, optional ,background (99 = default fg; bare resets fg and bg). Indices 16–98 fold mod-16 by default (WrapExtendedColors)
\x04 Hex color RRGGBB, optional ,RRGGBB background (bare = default)
\x0F Reset all formatting
\x16 Toggle reverse video (swap fg/bg)
\x1D Toggle italic
\x1E Toggle strikethrough
\x1F Toggle underline
\x1B[...m ANSI SGR: styles (1/3/4/7/9…), 16/256/truecolor via 38/48
\x01, \x11 Stripped (CTCP delimiter; monospace toggle — layout is always monospace)

Building from source

# 1. Native renderer (needs VS 2022 C++ workload + Windows SDK)
msbuild src\IrcRendererNative\IrcRendererNative.vcxproj -p:Configuration=Release -p:Platform=x64

# 2. Demo app (also builds the library)
dotnet build demo\IrcChatWpf\IrcChatWpf.csproj -c Release -p:Platform=x64

# Run the spam-test harness
demo\IrcChatWpf\bin\x64\Release\net8.0-windows\win-x64\IrcChatWpf.exe

Or open IrcChat.sln in Visual Studio 2022 (Release | x64) — build order is wired in the solution.

The demo harness generates random formatted lines at a configurable rate (default 2,000/sec) with buttons for theming, font cycling, scrollback capping, and a test pattern.

Architecture

IrcChat.sln
├── src/IrcRendererNative/       C++ native DLL (Direct2D/DirectWrite/D3D11)
│   ├── RingBuffer.h/cpp         Fixed-capacity line ring buffer (arena-backed)
│   ├── MpscQueue.h              Lock-free multi-producer/single-consumer queue
│   ├── IrcParser.h/cpp          Inline mIRC + ANSI SGR parser
│   ├── TextCells.h              Emoji/CJK cell model
│   └── Renderer.h/cpp           Flip-model swapchain, D2D/DWrite rendering
├── src/IrcChatControl.Wpf/      .NET 8 WPF class library (the NuGet package)
│   ├── NativeMethods.cs         P/Invoke layer
│   ├── IrcSwapchainHost.cs      HwndHost hosting the renderer's child HWND
│   └── IrcChatControl.xaml/.cs  Public UserControl + scrollbar/input handling
└── demo/IrcChatWpf/             Spam-test harness (WinExe)
  • AddLine UTF-8-encodes straight into the lock-free queue; the render pass drains it into pre-allocated ring-buffer slots — no std::string, no heap allocation, no exceptions on the hot path.
  • Only visible lines are drawn. A ~60 Hz DispatcherTimer drives frames and parks itself when idle (a wake protocol on the producer side restarts it), so an idle window costs zero CPU.
  • Word-wrap is column arithmetic against the monospace grid; each slot caches its wrapped row count and resizes re-wrap in one pass (deferred while zooming).
  • Rendering goes to a DXGI flip-model swapchain on a child HWND — no D3D9 interop, no D3DImage, no per-frame GPU copies through WPF.

Host-app memory tuning (optional)

The demo's App.xaml.cs shows two optional, app-level optimizations that meaningfully shrink a chat-centric app's footprint; both are choices for your application, not behavior of the control:

  • RenderOptions.ProcessRenderMode = RenderMode.SoftwareOnly — keeps WPF itself off the GPU. The chat surface has its own swapchain, so WPF hardware acceleration would only composite chrome, at the cost of a D3D9Ex device and vendor driver stack (~tens of MB). Set it before the first window is created; skip it if your app has GPU-heavy WPF UI of its own.
  • A settle-then-trim pattern (aggressive Gen2 collect + SetProcessWorkingSetSize once at startup and again after activity bursts go quiet) — startup XAML parsing and message floods leave garbage in committed GC regions that steady state never touches.

Tuning constants

Constant Location Effect
IrcLineCapacity RingBuffer.h Compile-time scrollback capacity (50,000).
IrcLineTextSize RingBuffer.h Max bytes per line (512).
IrcMaxSegments RingBuffer.h Max color/format runs per line (255 — enough for per-character colored ASCII art; storage packs by actual count).
InputQueueCapacity Renderer.h Lock-free queue depth (power of two).
MaxInputBatch Renderer.cpp Lines drained per frame; raise for >15k lines/sec.
Timer interval IrcSwapchainHost.cs ~16 ms (60 FPS); parks at idle.

License

GPL-3.0-or-later — see LICENSE. Note the copyleft implication: if you distribute an application that includes this control, the GPL's terms apply to that distribution. (© the repository owner; other arrangements are possible on request.)

Product Compatible and additional computed target framework versions.
.NET net8.0-windows7.0 is compatible.  net9.0-windows was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net8.0-windows7.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.7.0 41 7/20/2026