News

FileDropArea: Building a FoxPro-Friendly Drag-and-Drop ActiveX Control on .NET

FileDropArea was built to solve a practical integration problem: legacy Visual FoxPro applications needed a modern, user-friendly drag-and-drop surface for files, Outlook attachments, and links, without rewriting the host application stack. The result was a COM-visible ActiveX control built on .NET Framework 4.8 and packaged for 32-bit FoxPro environments.

FileDropArea: Building a FoxPro-Friendly Drag-and-Drop ActiveX Control on .NET

FileDropArea: Building a FoxPro-Friendly Drag-and-Drop ActiveX Control on .NET

Portfolio article | ROSE Development | ActiveX, COM interop, Visual FoxPro, Windows desktop integration

FileDropArea was built to solve a practical integration problem: legacy Visual FoxPro applications needed a modern, user-friendly drag-and-drop surface for files, Outlook attachments, and links, without rewriting the host application stack. The result was a COM-visible ActiveX control built on .NET Framework 4.8 and packaged for 32-bit FoxPro environments.

The Problem We Set Out to Solve

The host application needed more than a simple file picker. Users wanted to drag documents directly from Windows Explorer, drop attachments out of Microsoft Outlook, rename items inline, open linked files, and trigger application-specific business logic before anything was stored. In a modern .NET or web stack, none of that is unusual. In a FoxPro desktop environment, it requires careful interop design.

The project had two hard constraints from the start. First, the solution had to behave like a native ActiveX control inside Visual FoxPro forms. Second, it had to remain predictable in a 32-bit COM world where deployment, registration, and callback stability matter more than novelty.

Architecture in Practice

The implementation uses a WinForms UserControl as the visual host and exposes that control through a COM-safe interface. Instead of relying on automatic class interfaces, the component defines an explicit command interface and a separate event interface. That matters because it keeps the COM surface stable and makes the FoxPro integration contract much easier to document and maintain.

The control exposes a focused API: add items, remove items, rename items, redraw the surface, toggle copy behavior, set a base directory, and raise event callbacks into FoxPro when user actions occur.

Internally, the control maintains an in-memory list of file elements, each represented by a compact metadata object containing a path, ID, type, and description. The UI is rendered with a large-icon ListView, while the command layer remains simple enough for FoxPro to consume comfortably through COM.

Why the Control Uses Explicit COM Interfaces

COM interop becomes fragile when public .NET class members drift over time. To avoid that, the component uses an explicit default interface for callable methods and a dedicated dispatch interface for events. That gave us three advantages:

  • A stable method contract for FoxPro.
  • Fixed event DISPIDs for callback handling.
  • Freedom to improve internal implementation without changing the external automation surface.

How the UI Works

The visible control is intentionally compact: a button row across the top and a large drop area underneath. The button bar handles common actions such as add, delete, open, and properties. The list view beneath it supports drag/drop, selection change callbacks, double-click open behavior, and inline renaming.

A detail that mattered in real-world use was icon rendering. The control does not simply show a generic file icon for everything. It extracts shell icons by file extension and caches them, so different file types look distinct without repeatedly hitting the shell for the same icon. URL entries are rendered separately with a dedicated browser-style icon to make linked content visually different from file system items.

The Hard Part: Drag-and-Drop from Outlook

Drag-and-drop from Explorer is straightforward by Windows desktop standards. Outlook is not. When users drag attachments out of Outlook, they are often not dragging real files from disk. They are dragging virtual file descriptors and in-memory streams exposed through Outlook-specific data formats such as FileGroupDescriptor and FileContents.

This was one of the central engineering challenges in the project: Outlook data looks like files to the user, but it does not arrive like files to the control.

To handle that cleanly, the control wraps the incoming data object and normalizes the Outlook payload into something the rest of the component can process. Attachments are extracted as streams, written to disk when needed, and then transformed into normal file-backed list entries. If the dropped payload is actually a URL from Outlook, the control recognizes that path separately and stores it as a URL item instead of forcing it through the attachment pipeline.

Giving FoxPro Control Before the File Is Accepted

One of the most important design decisions was the BeforeFileDrop callback. Rather than making file handling rigid, the control raises a mutable parameter object back to FoxPro before a dropped or selected file is committed. That allows the FoxPro application to:

  • Reject a file entirely.
  • Rename the incoming file.
  • Change the storage path.
  • Decide whether the file should be physically copied or only referenced.

This event turned the control from a passive UI widget into an application-aware integration point. It allowed the business rules to stay in FoxPro, where they belonged, while the .NET control handled the difficult Windows interaction work.

BeforeFileDrop(FileInfo parameters)

- AcceptFile controls whether the operation continues
- FileName can be changed before storage
- FilePath can be redirected to a different folder or target
- CopyFile controls whether the file is physically copied or only linked

Managing Copy Semantics Correctly

File handling turned out to be more nuanced than simply copying or not copying. Explorer drops, manual file selection, and Outlook attachment drops each start from different assumptions. Standard files may already exist on disk and can be referenced directly. Outlook attachments usually need to be materialized from a stream into a real file. Manual add operations behave more like an explicit import action.

The implementation separates those flows instead of forcing them through a single generalized path. That makes the code easier to reason about and reduces the chance of side effects. It also makes room for application-specific policy. For example, some deployments want to preserve source file locations, while others want every incoming file copied into a managed storage folder with unique names.

Challenges Around COM Callback Reliability

COM event callbacks are easy to underestimate until they fail in the field. A FoxPro-side callback can throw an error, reject a parameter state, or leave the host UI in an inconsistent moment if the control does not defend itself. That is why the implementation wraps callback execution and treats event failures as first-class error cases.

Instead of letting a callback exception tear through the interaction, the control catches failures, logs debug details, and shows an actionable error message. In the BeforeFileDrop path, callback failure is treated as a rejected add operation. That is the correct default because it prevents partial file operations when business logic could not run successfully.

In COM-based desktop integration, failure handling is part of the API design. The host application and the control must fail predictably together.

Why 32-Bit Still Mattered

Modern .NET development often assumes x64 by default. This project could not. Visual FoxPro is a 32-bit host, and ActiveX interoperability follows that reality. The control is compiled for x86, registered through 32-bit RegAsm, and packaged with that deployment story in mind.

That sounds simple, but it affects everything from registration documentation to troubleshooting. A control that is technically correct but registered with the wrong toolchain is still broken in production. Part of the implementation work was making sure the component behaved like a proper ActiveX control in the registry, including insertable control markers and codebase registration.

Small Details That Improved the End Result

Several smaller implementation details had an outsized impact on usability:

  • Inline label editing lets users correct descriptions without leaving the screen.
  • Context menus adapt depending on whether the user right-clicks an item or empty space.
  • Duplicate file names are resolved automatically with unique suffixes.
  • The button interface can be hidden so the control can fit multiple UI layouts.
  • Cleanup logic disposes icons, menus, and WinForms resources explicitly to avoid long-session instability.

What This Project Represents

FileDropArea is a good example of the work that often matters most in enterprise software: not replacing legacy systems for the sake of it, but extending them carefully with modern capabilities. The technical challenge was not building a drag-and-drop list in isolation. It was building one that respected FoxPro, COM, Outlook, Windows shell behavior, deployment constraints, and user expectations at the same time.

That is the kind of engineering tradeoff we enjoy: practical desktop integration, strong interface boundaries, and targeted modernization that solves a real workflow problem without destabilizing the system around it.

If you are maintaining a legacy desktop platform and need modern UI behavior without rewriting the application core, this project shows the pattern clearly: put the difficult platform integration where it belongs, keep the external contract stable, and let the host system keep ownership of business rules.

Back to news
Share:

More

Related Articles

Want to work with us?

Get in touch and let's discuss your project.