As you intend to use the getValue() method from the "end of conversion" interrupt, I am going to propose a completely different architecture.
Conceptually, the interrupt handler for the "end of conversion" interrupt of the internal ADC is part of the AdcInt driver and the corresponding interrupt handler for the external ADC is part of the ...
You don't need AdcDriver at all. It does nothing. AdcInt and AdcExt both expose the same interface.
If you want to have an object that accepts AdxInt or AdcExt based on runtime information, you will need virtual somewhere. If not, you can use a simpler template.
float getValue(Input input)
// ... implementation ...
The problem is we can't modify the components to implement a polymorphic method to display the correct window since it's a extern library.
You may not be able to modify the component, but you can almost certainly compose them to produce the same effect. Pseudo code, adapt to your favourite language:
Use the power of C++, specifically, CRTP, to implement a registration mixin (Mixin-Based Programming with C++ (Smaragdakis, Batory)).
Your classes then don't even have to inherit (directly) from the same base class (as they would in an abstract class pattern). (Though they can from a base registration class that the CRTP class is derived from.) (Because ...