Become a member!

WinInspector 2.1: Advanced Features for Delphi Developers

  • 👉 This article is available in english.
  • 👉 Questo articolo è disponibile anche in italiano.
  • 👉 Este artículo también está disponible en español.

A few months ago I released WinInspector, the spiritual successor to my 20-year-old TDWinInfo. The community response has been positive, and several developers have submitted feature requests and suggestions. WinInspector 2.1 introduces new features specifically designed for Delphi and C++Builder developers.

What’s New in Version 2.1

This version transforms WinInspector into a complete analysis toolkit for Windows developers. Here are the main additions.

🎨 VCL Component Inspector: Behavioral Validation

The VCL Component Inspector identifies VCL/FMX components in Delphi and C++Builder applications using a behavioral validation approach instead of relying solely on class names.

The Class Name Problem:

Windows class names (obtained via GetClassName) can be ambiguous or generic. A control named “TCheckBox” might not actually be a VCL checkbox, but a custom control with a similar name.

The Solution: Validation Through Windows Messages:

WinInspector verifies control identity by sending specific Windows messages and analyzing the responses. If a control responds correctly to the typical messages for its type, it is considered validated.

// Example: Verify if it's really a checkbox
var CheckState := SendMessage(Handle, BM_GETCHECK, 0, 0);
case CheckState of
  BST_UNCHECKED: // Responds as checkbox → validated
  BST_CHECKED: // Responds as checkbox → validated
  BST_INDETERMINATE: // Three-state checkbox → validated
end;

Validation Messages by Type:

  • CheckBox/RadioButton: BM_GETCHECK to verify the ability to handle checked/unchecked states
  • ListBox/ComboBox: LB_GETCOUNT / CB_GETCOUNT to confirm item list management
  • Edit/Memo: Verification of style flags (ES_READONLY, ES_MULTILINE, ES_PASSWORD)
  • Button: Style analysis to detect default buttons (BS_DEFPUSHBUTTON)

Why This Approach is Superior:

  1. Type certainty: We don’t just trust the name, we verify that the control actually behaves as it should
  2. Cross-process: Works through Windows API messages, without needing RTTI (limited to in-process)
  3. Robustness: If a control doesn’t respond to expected messages, it’s simply excluded from VCL analysis
  4. Compatibility: Works on any external Delphi/C++Builder application, even in production

This behavioral validation method ensures that WinInspector identifies only authentic VCL components, avoiding false positives.

🔗 Complete Window Hierarchy

One of the most useful features of WinInspector 2.1 is the display of the complete window hierarchy. When you position the mouse over a control, the tool doesn’t just show the current control, but the entire parent chain up to the root window.

Why it’s important:

In complex VCL/FMX applications, controls are often nested in multiple container levels (Panel, GroupBox, TabSheet, etc.). Understanding this structure is fundamental for:

  • Debugging layout and positioning issues
  • Analyzing UI structure of third-party applications
  • Understanding complex form architecture
  • Identifying a control’s context

Example output:

📊 WINDOW HIERARCHY (bottom → top):
   [0] 0x12345 - TButton ("OK")
      [1] 0x23456 - TPanel
         [2] 0x34567 - TGroupBox ("Options")
            [3] 0x45678 - TTabSheet ("General")
               [4] 0x56789 - TPageControl
                  [5] 0x67890 - TForm1 ("Settings")

The hierarchy shows for each level:

  • Level number [0], [1], [2]… from control to root
  • Handle of the window in hexadecimal format
  • Class of the control (TButton, TPanel, TForm, etc.)
  • Title/Caption of the window (if present)
  • Visual indentation highlighting nesting depth

This visualization immediately clarifies the interface’s hierarchical structure, allowing you to understand the context in which a specific control is located.

📚 DLL/Library Inspector: Dependency Analysis

The DLL Inspector provides detailed information about libraries loaded by an application, facilitating dependency troubleshooting and deployment issues.

Main Features:

Complete Enumeration:

  • Lists all DLLs loaded by the process
  • Full paths for each library
  • File version information extraction
  • Alphabetical sorting

Heuristic Detection of Delphi/C++Builder Version:

WinInspector automatically identifies the Delphi or C++Builder version by analyzing the loaded BPL packages. Detection is heuristic and based on version numbers embedded in BPL file names.

Each Delphi version uses a specific package number:

  • rtl370.bpl, vcl370.bplDelphi 13 Florence
  • rtl290.bpl, vcl290.bplDelphi 12 Athens
  • rtl280.bpl, vcl280.bplDelphi 11 Alexandria
  • rtl270.bpl, vcl270.bplDelphi 10.4 Sydney
  • rtl260.bplDelphi 10.3 Rio
  • And so on down to XE2 (160)

The tool searches for these numeric patterns (370, 290, 280, etc.) in BPL file names and automatically maps to the corresponding version. This heuristic approach is reliable because Embarcadero uses a consistent naming convention for runtime packages.

Note: Detection is based on the presence of at least one BPL with a recognizable pattern. Applications compiled with runtime linking will show the version, while those compiled statically (without BPL) will not show this information.

WOW64 File System Redirection Bypass:

On 64-bit Windows, when a 32-bit process accesses C:\Windows\System32, Windows automatically redirects to C:\Windows\SysWOW64. This virtualization can make debugging complex.

WinInspector 2.1 uses GetModuleFileNameEx() to bypass this redirection and show the actual paths:

function GetRealModulePath(ProcessHandle: THandle;
                          ModuleHandle: HMODULE): string;
var
  Buffer: array[0..MAX_PATH] of Char;
begin
  // This returns the REAL path, not the redirected one
  GetModuleFileNameEx(ProcessHandle, ModuleHandle, Buffer, MAX_PATH);
  Result := string(Buffer);
end;

32-bit processes correctly show C:\Windows\SysWOW64\kernel32.dll instead of the virtualized System32 path, providing accurate information for deployment troubleshooting.

Lazy Loading Optimization:

The DLL inspector runs only when the “DLL/Libraries” tab is active, maintaining high performance for the main window inspection.

⏸️ Auto-Pause: Usability Improvement

When the mouse moves over WinInspector to scroll long lists, the automatic update timer can reset the scroll position.

Implemented Solution:

WinInspector 2.1 detects when the mouse is over its own window and automatically pauses updates, allowing you to scroll and analyze data without interruptions.

Visual Feedback:

A status panel at the top indicates the current state:

  • PAUSED: Red background when mouse is over WinInspector

    • Message: “⏸️ PAUSED - Mouse over WinInspector (move mouse away to resume)”
  • ACTIVE: Green background during inspection

    • Message: “▶️ Inspecting: explorer.exe (PID: 1234)”

This feature improves user experience by allowing reading without interference from automatic updates.

🎯 Tabbed Interface

To manage the new features, version 2.1 introduces an organized tabbed interface:

Tab 1: Window Info

  • Mouse position and current window details
  • Complete window hierarchy: full chain from the control under the mouse to the root window, showing all nesting levels with handle, class, and title for each level
  • VCL component analysis
  • Monitor information

Tab 2: DLL/Libraries

  • Complete DLL enumeration
  • BPL package detection
  • Version information
  • All loaded libraries with full paths

Use Cases

The new features prove useful in various scenarios:

Runtime VCL Form Debugging

For troubleshooting abnormal behaviors in production without resorting to a debugger:

  1. Run WinInspector
  2. Position the mouse over the component in question
  3. Verify real-time state: Checked, Enabled, parent container
  4. Compare with expectations

This approach doesn’t require debug sessions, code modifications, or application restarts.

DLL Dependency Analysis

To diagnose execution issues related to library version incompatibilities:

  1. Run WinInspector on the client machine
  2. Access the DLL/Libraries tab
  3. Analyze the complete list of loaded DLLs
  4. Compare with the development environment

This process can reveal discrepancies in library versions, such as msvcr140.dll v14.0.24215 in production versus v14.0.27508 in the test environment.

UI Structure Analysis

To understand the architecture of complex interfaces:

  1. Position the mouse over controls with WinInspector
  2. Examine the complete hierarchy from control to root form
  3. Identify component types and nesting patterns
  4. Analyze container dimensions and positioning

Useful for learning UI design patterns and for refactoring legacy applications.

Technical Details

WinInspector is implemented in Delphi using Windows APIs directly. Some relevant technical aspects:

  • Cross-process communication: SendMessage and SendMessageTimeout to query external controls
  • Lazy loading: DLL enumeration occurs only when the corresponding tab is active
  • Robust error handling: All potential failure points are protected with try/except
  • Performance: 500ms timer with auto-pause when mouse is over WinInspector

Future Developments

Some features under consideration for future versions:

  • Message Spy: Real-time logging of Windows messages sent to a window
  • Hotkey Support: Capture window information with Ctrl+Shift+I without changing focus
  • Style Inspector: Detection and analysis of VCL Styles and theme information
  • Export Functions: Save DLL lists and window hierarchies to files
  • History: Tracking of recently inspected windows

Version 2.1 represents a significant advancement in terms of functionality and reliability.

Tool Evolution

The basic concept of TDWinInfo from 2001 remains unchanged: move the mouse, get information. However, the implementation has evolved considerably.

From a simple utility, WinInspector has become a professional development tool with version 2.1.

For the Delphi Community

Features have been designed specifically for the Delphi and C++Builder ecosystem:

  • VCL component detection through behavioral validation
  • BPL package analysis with heuristic version identification
  • Complete window hierarchy for structural analysis
  • Cross-process inspection through Windows API messages

A useful tool for Windows application developers using Delphi or C++Builder.

Download and Contributions

WinInspector 2.1 is available on GitHub:

github.com/danieleteti/wininspector

The project is open source (Apache 2.0 license), and contributions are welcome. The codebase is documented and can serve as a reference for Windows API programming in Delphi.

Conclusions

The development of WinInspector demonstrates Delphi’s capabilities for Windows desktop development: direct API access, stable VCL framework, and high productivity.

Feedback, feature requests, and bug reports are welcome. The tool is developed based on the needs of the developers who use it.


WinInspector 2.1 is available on GitHub: github.com/danieleteti/wininspector

Thanks to all developers who provided feedback and suggestions for this release.

Comments

comments powered by Disqus