ZPreview is a .NET 10 WinForms application for Windows that shows a preview of the file currently selected in ZTreeWin.
The application uses ZaapZTreeState to track the current state of ZTreeWin
and to receive events for file changes, OnHold, quit, and Ctrl+Shift
shortcuts.
Download and Install
For end-user installation, use one of these downloads:
- Framework-dependent (smaller): /uv/ZPreview-fdd-win-x64.zip
- Self-contained (larger): /uv/ZPreview-sc-win-x64.zip
See ZAAP.net/ZPreview/INSTALL.md for guidance on which variant to choose and full installation steps.
Projects
ZAAP.net/
ZPreview/ WinForms application
ZPreview.Core/ Platform-neutral shortcut/core logic
ZPreview.Abstractions/ Interfaces and base classes for preview handlers
ZPreview.PreviewHandlers/ Built-in preview handlers
ZPreview.SQLitePreview/ SQLite preview handler in its own project
ZPreview.Core.Tests/ xUnit tests that also run on Linux
ZPreview.Tests/ UI xUnit tests for WinForms-bound code
Why WinForms
WinForms was chosen here because of:
- direct HWND/COM interop for Windows Preview Handlers
- consistency with the existing ZRelay application
- a simple plugin model where handlers just return a
Control
Architecture
The main application consists of:
MainFormZTreeMonitorControllerPreviewHandlerCatalogPreviewSettingsServiceWindowPositionManager
The event flow is:
ZaapZTreeStatedetects a change in ZTreeWin.ZTreeMonitorControllertranslates that into app events.MainFormdetermines which handler should be used.- The active preview control is replaced.
Preview Handler Model
Handlers implement IPreviewHandler from ZPreview.Abstractions.
Important contracts:
IPreviewHandlerIPreviewHandlerConfigIPreviewHandlerConfig<TConfig>IEncodingAwarePreviewIFileResourcePreviewIPreviewCommandHandlerIPreviewStatusSource
Handlers are discovered via assembly scanning:
- built-in handlers from
ZPreview.PreviewHandlers - external handlers from
plugins/*.dll
Plugin load failures are recorded in PluginLoadResult.
Built-in Preview Handlers
Text
- id:
builtin.text - encoding selection via toolbar
- search via
Ctrl+FandF3 - the search panel has been made more compact;
Nextis now about the same height as the search box - handler configuration for fallback encoding and word wrap
- large files are loaded asynchronously and as a bounded preview so the UI remains usable
- forwarded ZTreeWin navigation (
arrows,PgUp/PgDn,Home/End) scrolls the text preview directly
Zip Archive
- id:
builtin.zip - display name:
Archive - abstracts ZIP, TAR, and GZip sources behind the same archive preview UI
- detects ZIP containers based on the PK file signature instead of only by extension
- also detects
.tarand GZip files (.gz,.gzip,.tgz,.tar.gz) - therefore also supports archives with incorrect or missing extensions, as long as the signature or TAR header matches
- list views now auto-fit columns to either content or header, whichever is wider
- clicking a column header sorts by the underlying name, size, compression, or date values; clicking again reverses the sort direction
- the tree view is fully expanded when opened
- to the right of the list/tree there is now a preview pane that shows selected archive entries through the built-in preview handlers
- nested archives can therefore also be opened again via
builtin.zipin the preview pane on the right, for example a.zipinside a.zip - when switching between
ListandTree, the same archive file stays selected without reloading the preview pane on the right - the splitter between list and preview, and in the tree tab also the one between tree and file list, remember their relative position
- in the preview pane, you can now also choose the built-in handler manually;
(autodetect)chooses automatically and then synchronizes the actually used handler in the list - Windows preview handlers are intentionally not offered in this embedded archive preview selection; built-in handlers, including
builtin.zip, are
Hex
- id:
builtin.hex - fallback handler for any existing file
- configurable font, bytes per line, and ASCII mode
- the inspector always shows the length of the current selection at the top
- the configuration panel now keeps the inspector options in a separate scrollable pane so settings no longer overlap each other
- for large files, it uses a virtualized sliding window so even very large files, including files larger than 4 GB, remain navigable without loading the entire file into memory
HomeandEndjump to the start and end of the preview- navigation with arrow keys,
PgUp/PgDn,Home/End;Shift+ arrow keys extends the selection directly from the current byte
Image
- id:
builtin.image - fit-to-window by default
- zoom with
Ctrl+scroll - rotate with
RandL - reset with
Ctrl+0
Windows Preview Handler Host
- id:
builtin.shell - locates COM preview handlers through the standard
shellexregistration - hosts preview handlers through its own COM interop layer
- initializes handlers stream-first, with fallback to file or shell item
- concrete available Windows Preview Handlers are shown as separate choices in the handler list
- the configuration panel also shows a generic
Windows Preview Handler (registered)placeholder inDefault Order, which is replaced at runtime by the actually registered handler for the current file - initializes the COM preview only after the host control has a usable client size, then forwards resize updates
Thumbnail/Icon
- id:
builtin.thumbicon - manual fallback handler that tries to show a shell thumbnail for any file
- if no thumbnail is available, the handler falls back to the shell icon
SQLite
- id:
builtin.sqlite - lives in a separate project (
ZPreview.SQLitePreview) with its own dependency onMicrosoft.Data.Sqlite - shows objects from
sqlite_masteron the left (all columns exceptsql) - shows the SQL definition of the selected object on the right
- has a query tab with SQL editor, run/stop button, and result grid
- query execution is asynchronous with cancellable run
- result display uses a virtual-mode grid for larger datasets
- double-clicking a cell opens a detail window (text or hex for BLOB)
- context menu on result grid: Select All, Copy, Export As CSV
- configurable font for editor and grid, plus a default query template
- the query template field in settings immediately follows the selected editor font
Configuration
Configuration is stored in:
%APPDATA%\Zaap\ZPreview\settings.json
This includes, among other things:
defaultHandlerOrderextensionOverrideshandlerConfigwindowPositions
Runtime errors and exceptions are also logged to zpreview.log in the same
directory as settings.json.
The configuration window contains:
- default handler order
Default Ordernow supports multi-select, so multiple handlers can be moved up or down at once and have their mode changed in a single operation- per-extension overrides now store only explicit deviations; the rest is inherited from the default order
- the lists in
Per Extensionnow also support multi-select for removing multiple extensions or multiple handler overrides at once - handler-specific settings panels
- no separate window icon in the title bar anymore, so it no longer differs from the button icon choice
- toolbar buttons for
Use First For ExtensionandConfigurationnow have their own icon - the
Freezebutton now also has its own snowflake icon
Shortcuts
Global shortcuts from ZTreeWin and local shortcuts in the preview window:
Ctrl+Shift+Mminimize/restoreCtrl+Shift+F4close windowCtrl+Shift+Ffreeze/unfreeze previewCtrl+Shift+Hnext handler,Ctrl+Shift+Alt+Hprevious handlerCtrl+Shift+1throughCtrl+Shift+9select handler positions 1..9,Ctrl+Shift+0triggers autodetection
Ctrl+Shift+M now also restores a previously maximized window as maximized.
Handler-specific shortcuts:
Ctrl+Fsearch textF3next text matchF5/F9run/stop SQLite queryCtrl+0reset imageR/Lrotate imagebuiltin.hex: arrow keys,PgUp/PgDn,Home/End; through ZTreeWin,Ctrl+Shiftvariants are forwarded, andCtrl+Shift+Alt+ arrow keys is translated to selection withShift+ arrow keysbuiltin.text: through ZTreeWin,Ctrl+Shift+ arrow keys,PgUp/PgDn,Home, andEndscroll the text preview
Window Position
The window position is remembered per monitor configuration. The fingerprint is
calculated from the DeviceName and Bounds of all screens.
For a maximized window, the target monitor is now also remembered so restore happens on the same monitor.
Build and Test
Build:
dotnet build ZAAP.net/ZAAP.net.sln -p:EnableWindowsTargeting=true
Core tests that run on Linux:
dotnet test ZAAP.net/ZPreview.Core.Tests/ZPreview.Core.Tests.csproj
Build UI tests on Linux:
dotnet build ZAAP.net/ZPreview.Tests/ZPreview.Tests.csproj -p:EnableWindowsTargeting=true
ZPreview.Tests is the UI test project (ZPreview.UI.Tests in the solution)
and remains bound to WinForms/WindowsDesktop. On Linux you can usually build
that project, but not run it without Microsoft.WindowsDesktop.App.
Non-UI-bound or non-Windows-specific functionality belongs in ZPreview.Core,
with tests in ZPreview.Core.Tests, so regressions can also actually be run on
Linux.
Interactive validation of the UI and Windows Preview Handlers must be done on Windows.
Release Archive
Create and upload the release ZIP with either:
./scripts/publish-zpreview-release.sh
.\scripts\publish-zpreview-release.ps1
The script publishes ZAAP.net/ZPreview/ZPreview.csproj to
out/zpreview-release/publish-fdd and out/zpreview-release/publish-sc,
creates variant archives ZPreview-fdd-win-x64.zip and
ZPreview-sc-win-x64.zip, then uploads both as Fossil unversioned files under
/uv/.
Related Documents
PLAN.md: only open items and bug backlogarchives.PLAN.md: design plan for archive preview