Skip to content

Architecture

abbaye edited this page Apr 16, 2026 · 12 revisions

Architecture — WPF HexEditor IDE

WpfHexEditor is a full binary analysis IDE for Windows built entirely with WPF and .NET 8.0. This page documents the complete architecture — IDE application layer, plugin system, terminal, build system, and HexEditor control internals.

Current version: v0.6.4.75


Table of Contents

🏗️ Foundation

🖥️ IDE Application

🔌 Extensibility

⚙️ HexEditor Engine

✏️ Editors

🎨 UI & Quality

📐 Engineering


High-Level Overview

flowchart TD
    App["🖥️ WpfHexEditor.App\nIDE Application"]

    subgraph IDEInfra["IDE Infrastructure"]
        Shell["WpfHexEditor.Shell\nVS-style docking engine (v0.6.0 rename)"]
        ProjectSys["WpfHexEditor.ProjectSystem\n.whsln / .whproj"]
        BuildSys["WpfHexEditor.BuildSystem\nIBuildAdapter + IBuildSystem"]
        Events["WpfHexEditor.Events\nIIDEEventBus + 21 domain events"]
        LSP["WpfHexEditor.LSP\nLanguage intelligence"]
        Options["WpfHexEditor.Options\nSettings pages"]
    end

    subgraph PluginLayer["Plugin System"]
        SDK["WpfHexEditor.SDK\nIWpfHexEditorPluginV2\nIIDEHostContext"]
        Host["WpfHexEditor.PluginHost\nWpfPluginHost · PluginManagerControl\nPluginMonitoring · PluginWatchdog"]
        Sandbox["WpfHexEditor.PluginSandbox\nOut-of-process IPC"]
        Terminal["WpfHexEditor.Terminal\nTerminalPanel\nTerminalExportService"]
        CoreTerm["WpfHexEditor.Core.Terminal\n31+ commands · HxScriptEngine"]
    end

    subgraph FirstPartyPlugins["First-Party Plugins"]
        P1["DataInspector · ParsedFields"]
        P2["AssemblyExplorer\n.NET PE + decompilation"]
        P3["SynalysisGrammar\nUFWB grammar (priority 45)"]
        P4["SolutionLoader.VS (priority 90)\nSolutionLoader.Folder (priority 85)\nSolutionLoader.WH (priority 95)"]
        P5["Build.MSBuild (priority 85)\ndotnet CLI adapter"]
        P6["XamlDesigner plugin\n9 VS-like panels"]
    end

    subgraph Editors["Editors (IDocumentEditor)"]
        HexEd["WpfHexEditor.HexEditor (~75%)"]
        CodeEd["WpfHexEditor.Editor.CodeEditor (~90%)\nNavBar · Inline Hints · UndoEngine"]
        XamlEd["WpfHexEditor.Editor.XamlDesigner (~70%)\nLive canvas · bidirectional sync"]
        TxtEd["WpfHexEditor.Editor.TextEditor (~50%)"]
        TblEd["WpfHexEditor.Editor.TblEditor"]
        JsonEd["WpfHexEditor.Editor.JsonEditor"]
    end

    subgraph CoreLayer["Core Layer"]
        Core["WpfHexEditor.Core\nByteProvider + 21 services"]
        EdCore["WpfHexEditor.Editor.Core\nIDocumentEditor · UndoEngine"]
        BinAnalysis["WpfHexEditor.BinaryAnalysis\n690+ format detection"]
        SrcAnalysis["WpfHexEditor.Core.SourceAnalysis\nBCL-only outline engine"]
        Definitions["WpfHexEditor.Definitions\n.whfmt format catalog\n55+ language definitions"]
    end

    App --> IDEInfra
    App --> SDK
    SDK --> Host
    Host --> Sandbox
    Terminal --> CoreTerm
    App --> Editors
    App --> FirstPartyPlugins
    FirstPartyPlugins -->|IWpfHexEditorPluginV2| Host
    HexEd --> Core
    CodeEd --> EdCore
    XamlEd --> EdCore
    Core --> BinAnalysis
    BinAnalysis --> Definitions
Loading

Solution Structure

WpfHexEditorControl.sln
│
├── WpfHexEditor.App                — Full IDE application (startup project)
│                                     MainWindow: 5 partial classes
│                                     10 service adapters (DockingAdapter, MenuAdapter,
│                                       StatusBarAdapter, HexEditorServiceImpl, etc.)
│
├── — IDE Infrastructure —
├── WpfHexEditor.Shell              — VS-style docking engine (renamed from Docking.Wpf)
├── WpfHexEditor.SDK                — Public plugin API
├── WpfHexEditor.PluginHost         — Plugin runtime host
├── WpfHexEditor.PluginSandbox      — Out-of-process plugin sandbox
├── WpfHexEditor.Core.Terminal      — Command engine (31+ commands)
├── WpfHexEditor.Terminal           — Terminal panel WPF UI
├── WpfHexEditor.ProjectSystem      — Solution/project model (.whsln/.whproj)
├── WpfHexEditor.BuildSystem        — Build orchestration + IBuildAdapter contracts
├── WpfHexEditor.Events             — IIDEEventBus + 21 domain event records
├── WpfHexEditor.LSP                — Language intelligence engine
├── WpfHexEditor.Options            — Options dialog pages
├── WpfHexEditor.Panels.IDE         — Solution Explorer, Properties, Error List
│
├── — Editors —
├── WpfHexEditor.Editor.Core        — IDocumentEditor · UndoEngine (coalescing, transactions)
├── WpfHexEditor.Editor.CodeEditor  — Code editor (~90%): NavBar, Inline Hints, Ctrl+Click
├── WpfHexEditor.Editor.XamlDesigner— XAML visual designer (~70%): live canvas, sync
├── WpfHexEditor.Editor.TextEditor  — Text editor (~50%)
├── WpfHexEditor.Editor.TblEditor   — TBL character table editor
├── WpfHexEditor.Editor.JsonEditor  — JSON editor with live validation
├── WpfHexEditor.Editor.ImageViewer — Image viewer (zoom/pan/crop)
├── WpfHexEditor.Editor.EntropyViewer — Entropy graph
├── WpfHexEditor.Editor.DiffViewer  — Binary diff viewer
├── WpfHexEditor.Editor.StructureEditor — .whfmt binary template editor
├── WpfHexEditor.Editor.DocumentEditor      — RTF/DOCX/ODT WYSIWYG editor (~35%)
├── WpfHexEditor.Editor.DocumentEditor.Core — IDocumentLoader · IExtensionRegistry · BinaryMap · IDocumentSaver
│
├── — Core Control —
├── WpfHexEditor.HexEditor          — WPF HexEditor UserControl (~75%)
├── WpfHexEditor.Core               — ByteProvider + 21 services
├── WpfHexEditor.Core.SourceAnalysis— BCL-only regex outline engine (no WPF)
├── WpfHexEditor.BinaryAnalysis     — 690+ format detection engine
├── WpfHexEditor.Definitions        — Format definitions (.whfmt), 55+ language defs
├── WpfHexEditor.Core.Workspaces    — .whidews workspace engine (ZIP+JSON snapshots, WorkspaceManager, WorkspaceSerializer)
│
├── — Plugins (first-party) —
└── Sources/Plugins/
    ├── WpfHexEditor.Plugins.DataInspector         (40+ type interpretations)
    ├── WpfHexEditor.Plugins.ParsedFields           (binary structure overlay)
    ├── WpfHexEditor.Plugins.AssemblyExplorer       (.NET PE inspection, decompilation)
    ├── WpfHexEditor.Plugins.SynalysisGrammar       (UFWB binary grammar, priority 45)
    ├── WpfHexEditor.Plugins.XamlDesigner           (9 XAML designer panels)
    ├── WpfHexEditor.Plugins.SolutionLoader.VS      (.sln/.csproj loader, priority 90)
    ├── WpfHexEditor.Plugins.SolutionLoader.Folder  (open-folder mode, priority 85)
    ├── WpfHexEditor.Plugins.SolutionLoader.WH      (.whsln/.whproj, priority 95)
    └── WpfHexEditor.Plugins.Build.MSBuild          (dotnet CLI adapter, priority 85)

IDE Application Layer

WpfHexEditor.App hosts everything. MainWindow is split into 5 partial classes by responsibility:

Partial class Responsibility
MainWindow.xaml.cs Docking layout, menu bindings, status bar
MainWindow.PluginSystem.cs Plugin init/shutdown, focus context
MainWindow.ProjectSystem.cs Solution open/close, build integration, project tree sync
MainWindow.Editors.cs Editor factory, ContentId routing, tab management
MainWindow.Build.cs Build orchestration, error list integration

Service Adapters (10)

MainWindow implements IIDEHostContext through 10 service adapters, each isolating a concern:

Adapter Contract Responsibility
DockingAdapter IDockingAdapter Docking engine operations
MenuAdapter IMenuAdapter Dynamic menu integration
StatusBarAdapter IStatusBarAdapter Status bar updates
HexEditorServiceImpl IHexEditorService Active HexEditor access
DocumentHostService IDocumentHost Tab lifecycle management
OutputServiceImpl IOutputService Output panel writes
ErrorPanelServiceImpl IErrorPanelService Diagnostics posting
ThemeServiceImpl IThemeService Theme switching
TerminalServiceImpl ITerminalService Terminal commands
SolutionExplorerServiceImpl ISolutionExplorerService Project tree access

Docking Engine

WpfHexEditor.Shell is a 100% in-house VS-style docking engine — zero third-party dependency.

Features: float · dock · auto-hide · tab strip · colored tabs · live themes · layout persistence · hover preview

Full Docking Engine documentation with usage examples

Project System

Supports three project formats via ISolutionLoader plugins:

  • .whsln / .whproj — native format (priority 95)
  • .sln / .csproj — Visual Studio (priority 90)
  • Open-folderSolutionLoader.Folder (priority 85)

Format migration via MigrationPipeline (chain of IFormatMigrator).

Full Project System documentation with API examples

Editor Registry

EditorRegistry.FindFactory(filePath, preferredEditorId?) — preferred-first, fallback first-match. Every editor implements IDocumentEditor; optional IEditorPersistable and IDiagnosticSource.

Full Editor Registry documentation with IDocumentEditor contract

ContentId Routing

BuildContentForItem() maps ContentId strings to WPF factories on layout restore:

ContentId Panel / Editor
doc-welcome WelcomePanel
doc-proj-{itemId} Auto editor selection
doc-proj-{factoryId}-{itemId} Specific editor
doc-nuget-solution-{name} NuGet Solution Manager
panel-terminal TerminalPanel
panel-plugin-monitoring PluginMonitoringPanel
panel-plugin-manager PluginManagerControl
panel-solution-explorer SolutionExplorerPanel
panel-errors ErrorPanel
panel-assembly-explorer AssemblyExplorerPanel
panel-xd-toolbox XAML Toolbox
panel-xd-resource-browser XAML Resource Browser
panel-xd-history XAML Design History

Full ContentId Routing documentation with sequence diagrams


Plugin System

SDK Contracts

WpfHexEditor.SDK exposes the public plugin API — plugins only reference this project:

IWpfHexEditorPluginV2
├── string Id / Name / Version / Description
├── int LoadPriority                          ← lower = loads first (0-100)
├── void Init(IIDEHostContext context)
├── void Activate()
├── void Deactivate()
└── void Dispose()

IPluginWithOptions          — auto-registers an Options page
IIDEHostContext             — gateway to all IDE services
IUIRegistry                 — Show/Hide/Toggle/Focus dockable panels
IDockingAdapter             — underlying docking operations
IPluginEventBus             — subscribe/publish IDE-wide events
ISolutionLoader             — load a solution format (VS, Folder, WH)
IBuildAdapter               — plug a build backend (MSBuild, Cargo, etc.)
IEditorToolbarContributor   — add toolbar items to an editor
IStatusBarContributor       — add status bar segments
IQuickInfoProvider          — hover Quick Info in Code Editor
IGrammarProvider            — binary grammar overlay (SynalysisGrammar)
ISourceOutlineService       — code outline / navigation bar

Services available to plugins:
IHexEditorService           — read bytes, search, go to offset
ICodeEditorService          — access active code editor
IOutputService              — write to Output panel
IErrorPanelService          — post diagnostics (Info/Warning/Error)
ISolutionExplorerService    — open files, query project tree
IParsedFieldService         — read parsed fields from HexEditor
ITerminalService            — execute commands, write output, export
IFocusContextService        — query active editor focus
IPermissionService          — check/request permissions
IThemeService               — current theme, subscribe to changes
IIDEEventBus                — subscribe to IDE-wide domain events
IMarketplaceService         — (stub) browse/install plugins online

Plugin Lifecycle

sequenceDiagram
    participant Host as WpfPluginHost
    participant ALC as PluginLoadContext (collectible ALC)
    participant Plugin as IWpfHexEditorPluginV2
    participant IDE as IIDEHostContext

    Host->>ALC: Load assembly
    ALC->>Plugin: new PluginImpl()
    Host->>Plugin: Init(context)
    Plugin->>IDE: RegisterPanel / Subscribe events / RegisterOptions
    Host->>Plugin: Activate()
    Note over Plugin: Plugin running
    Host->>Plugin: Deactivate()
    Host->>Plugin: Dispose()
    Host->>ALC: Unload() — clears collectible ALC reference
    Note over ALC: GC collects all plugin assemblies
Loading
  • Discover: scans %AppData%\WpfHexEditor\Plugins\ + bin\Plugins\
  • Sort: by LoadPriority (WH=95, VS=90, Folder=85, MSBuild=85)
  • Load: PluginLoadContext — collectible AssemblyLoadContext
  • Init: register panels, commands, event subscriptions
  • Activate/Deactivate: called on enable/disable without restart
  • Unload: clears ALC reference → GC collects all plugin assemblies

PluginWatchdog.WrapAsync() measures elapsed time per plugin call (returns Task<TimeSpan>). PluginCrashHandler catches exceptions → marks plugin Faulted.

Hot-Unload

Each plugin loads into a collectible AssemblyLoadContext. Disable or reload in Plugin Manager triggers:

  1. Deactivate() + Dispose() on plugin instance
  2. PluginEntry.Unload() clears the ALC reference
  3. GC releases all plugin assemblies — no IDE restart needed

Terminal

WpfHexEditor.Core.Terminal
├── TerminalCommandRegistry   — 31+ built-in commands, tab completion
├── CommandHistory            — persistent cross-session history
├── HxScriptEngine            — .hxscript file execution
├── ITerminalContext          — CWD, output writer, command dispatch
└── ITerminalOutput           — WriteLine, WriteTable, Clear

WpfHexEditor.Terminal
├── TerminalPanel.xaml(.cs)   — RichTextBox output, input row, toolbar
├── TerminalPanelViewModel    — implements ITerminalContext + ITerminalOutput
├── TerminalExportService     — 6 export formats (txt/html/rtf/ansi/md/xml)
└── TerminalMode              — Interactive / Script / ReadOnly

WpfHexEditor.SDK
├── ITerminalService          — plugin-facing contract
└── PluginCapabilities.Terminal

Built-in command categories: Core · File System · Editor · Project/Solution · Panels · Plugins · Diagnostics

TerminalPanelViewModel implements both ITerminalContext and ITerminalOutput, keeping the command engine decoupled from WPF.


Build System

WpfHexEditor.BuildSystem
├── IBuildSystem              — orchestrate builds, configs, adapters
├── IBuildAdapter             — pluggable backend (dotnet CLI, Cargo, CMake…)
├── IBuildConfiguration       — Debug/Release/custom configurations
├── BuildDependencyResolver   — Kahn's algorithm for build order
└── ConfigurationManager      — manage build configs per project

WpfHexEditor.Plugins.Build.MSBuild (priority 85)
├── MsBuildAdapter            — IBuildAdapter impl via `dotnet build`/`dotnet run`
├── BuildOutputParser         — parse dotnet CLI output → DiagnosticEntry
└── Streams to Output panel + Error Panel during build

Build is invoked from MainWindow.Build.cs:

  1. ClearDiagnostics() on Error Panel before build
  2. IBuildSystem.BuildAsync() streams progress to Output panel
  3. Parser extracts errors → IErrorPanelService.PostDiagnostic()
  4. Build result notification in status bar

Code Editor

WpfHexEditor.Editor.CodeEditor — ~90% complete.

Key features:

  • Navigation Bar — type/member dropdowns, Ctrl+Click go-to-definition
  • Inline Hints — inline hints above methods (references count, test status)
  • Quick Info — hover tooltip with 400 ms debounce (HoverQuickInfoService)
  • Find ReferencesFindReferencesPanel dockable panel
  • Rect Selection — Alt+Click drag rectangle selection
  • Drag-to-Move — drag selected text or rect block
  • #Region Colorization — collapsible regions with color fade
  • Bracket Highlight — matching bracket highlight (Inline Hints-aware Y offset)
  • Scope Guides — vertical indent guides
  • Scroll Markers — errors/warnings/search results in scroll bar
  • Word Highlight — all occurrences of word under caret
  • URL Hover — clickable URLs in comments
  • Shared UndoEngine — coalescing (500 ms Insert+Insert merge), transactions, save-point

Integrated with WpfHexEditor.LSP for language intelligence (SmartComplete, diagnostics, refactoring).


XAML Designer

WpfHexEditor.Editor.XamlDesigner — ~70% complete.

Key features:

  • Split-pane layout — 4 modes: HorizontalDesignRight/Left, VerticalDesignBottom/Top
  • Live canvas (DesignCanvas, ZoomPanCanvas) with real-time element rendering
  • Bidirectional sync — canvas↔XAML code sync, ~95% fidelity, 150 ms debounce
  • UID injection — auto-assigns x:Uid for stable element mapping
  • 5 adorner types — resize, drag, rotate, anchor, snap guide
  • Snap SystemSnapEngineService: element edges, center lines, grid
  • AlignmentAlignmentService: 12 operations (align left/right/top/bottom/center, distribute)
  • Overkill UndoDesignUndoManager (max 200): SingleDesignUndoEntry, BatchDesignUndoEntry, SnapshotDesignUndoEntry
  • 9 dockable panels — Toolbox, ResourceBrowser, DesignData, Animation, LiveVisualTree, PropertyGrid, StateMachine, StyleEditor, DesignHistory
  • 30 XD_* brush tokens across all 8 themes

Shared Undo Engine

WpfHexEditor.Editor.Core.Undo.UndoEngine — shared by Code Editor and Text Editor:

UndoEngine
├── List<IUndoEntry>          — the history stack
├── int _splitPointer         — current position
├── TryMerge()                — coalescing: Insert+Insert within 500 ms window
├── BeginTransaction()        — start a batch operation
├── CommitTransaction()       — commit as CompositeUndoEntry
├── MarkSaved()               — set save-point
├── IsAtSavePoint             — IsDirty = !IsAtSavePoint
└── StateChanged event        — notifies IDocumentEditor

IUndoEntry implementations:
├── CodeEditorUndoEntry       — Insert+Insert coalescing
├── TextEdit → IUndoEntry     — Text Editor migration
└── CompositeUndoEntry        — batch transaction

IDocumentEditor extended with UndoCount and RedoCount default interface members.


HexEditor Control

ByteProvider System

Virtual view over the physical file. Modifications, insertions, and deletions are tracked in memory via PositionMapper (O(log n) segment tree). Save() uses a fast in-place path (modifications only) or atomic File.Replace() (insertions/deletions). Full Command-pattern undo/redo.

Full ByteProvider documentation with API examples

21 Services

Service Responsibility
ClipboardService Copy/paste with 8+ formats
FindReplaceService Boyer-Moore + SIMD + parallel search
AdvancedSearchService Extended search (wildcards, regex, structured patterns)
UndoRedoService Command-pattern undo/redo stacks
SelectionService Selection validation, get selected bytes
ByteModificationService Insert / delete / modify bytes
PositionService Line/column calculations
HighlightService Visual byte marking (search results, custom)
BookmarkService Bookmark management
BookmarkSearchService Search within bookmarks
BookmarkExportService Export bookmarks to various formats
TblService ROM hack character table mapping
CustomBackgroundService User-defined color block overlays
StructureOverlayService Parsed-field structure overlays
ComparisonService Byte-level file comparison (+ SIMD variant)
FileDiffService Diff view between two files
PatternRecognitionService Heuristic pattern analysis
VirtualizationService Virtual rendering / lazy row loading
LongRunningOperationService Cancellable async operations with progress
StateService Editor state snapshots
FormatDetectionService 690+ format identification

Rendering Engine

DrawingContext-based — direct pixel rendering on a single DrawingVisual. 50 000 bytes rendered in ~30 ms vs ~3 000 ms with the legacy ItemsControl approach (99% faster). Only the visible region is drawn; on scroll, only the delta is redrawn.

Full Rendering Engine documentation

Search Architecture

LRU cache + Boyer-Moore-Horspool + SIMD AVX2/SSE2 (single-byte) + Parallel.ForEach (files ≥ 10 MB). Repeat searches return instantly from cache (10–100× faster).

Full Search Architecture documentation with pipeline diagram


Themes

8 built-in themes, each a ResourceDictionary with complete brush key sets:

Theme File
Dark Themes/Dark/
Light Themes/Light/
VS2022Dark Themes/VS2022Dark/
DarkGlass Themes/DarkGlass/
Minimal Themes/Minimal/
Office Themes/Office/
Cyberpunk Themes/Cyberpunk/
VisualStudio Themes/VisualStudio/

Brush key naming convention:

  • Dock* — docking engine chrome (WpfHexEditor.Shell)
  • Panel* / PanelIcon* — VS-style panel toolbars
  • XD_* — XAML Designer (30 tokens)
  • PM_* — Plugin Monitoring panel
  • ERR_* — Error Panel
  • PFP_* — ParsedFields Panel
  • CE_* — Code Editor

Design Patterns

Pattern Where Used
MVVM HexEditor, all panels, all editors, Plugin Monitoring
Plugin / Strategy IDocumentEditor, IWpfHexEditorPluginV2, IEditorFactory, ISolutionLoader, IBuildAdapter
Command Undo/Redo (UndoEngine, ModifyCommand, InsertCommand, DeleteCommand, CompositeUndoEntry)
Repository ByteProvider — data access abstraction over file/stream/memory
Observer IPluginEventBus, IIDEEventBus, DependencyPropertyDescriptor.ValueChanged, INotifyPropertyChanged
Factory EditorRegistry.FindFactory(), PluginLoadContext per plugin
Adapter DockingAdapterIDockingAdapter, 10 service adapters in MainWindow
Mediator IIDEHostContext — central service locator for plugins
Decorator PluginWatchdog.WrapAsync() — wraps plugin calls with timing
State TerminalMode (Interactive/Script/ReadOnly), PluginState (Loaded/Faulted/Disabled)
Pipeline ImageTransformPipeline, MigrationPipeline (format migrations)
Facade WpfPluginHost — orchestrates discovery, load, watchdog, crash handler
Null Object StandaloneIDEHostContext — no-op IIDEHostContext for standalone samples

Performance

Metric Result
Rendering 99% faster vs V1 (DrawingContext vs ItemsControl)
Search (repeated) 10-100x faster (LRU cache)
Search (large file) 2-4x faster (parallel multi-core)
Single-byte search 4-8x faster (SIMD AVX2/SSE2)
Memory allocation 80-90% reduction (Span<T> + ArrayPool)
Save (modifications only) 10-100x faster (in-place fast path)
Startup 30-50% faster (ReadyToRun AOT)
Runtime (net8.0) 10-30% boost (Profile-Guided Optimization)

See also: Plugin System · Terminal · Getting Started · API Reference

Navigation

Getting Started

IDE Documentation

HexEditor Control

Advanced

Development


v0.6.4.75 Highlights

  • whfmt.FileFormatCatalog v1.0.0 NuGet (cross-platform net8.0)
  • 690+ .whfmt definitions (schema v2.3)
  • Structure Editor — block DataGrid, drag-drop, validation, SmartComplete
  • WhfmtBrowser/Catalog panels — browse all embedded formats
  • AI Assistant (5 providers, 25 MCP tools)
  • Tab Groups, Document Structure, Lazy Plugin Loading
  • Window Menu + Win32 Fullscreen (F11)
  • Git Integration UI (changes, history, blame)
  • Shared Undo Engine (HexEditor ↔ CodeEditor)
  • Bracket pair colorization, sticky scroll, peek definition
  • Format detection hardening (thread-safe, crash guard)

Links

Clone this wiki locally