In your initial code your Create constructor hides the original Create. Which is why the compiler complains about TfrmC overriding a constructor it can no longer see from there.
You would normally get a compiler message about this, but "reintroduce" suppresses this. Whenever you need "reintroduce" to suppress compiler messages, alarm bells should go off as it is an indication that you are breaking polymorphism. Doesn't mean you shouldn't use it, but you should be aware of the implications.
In these cases, if I want to retain the ability to override the original constructor, I tend to add a different constructor, ie
constructor CreateWithParent(AOwner: TComponent; const AWndParent: HWnd); virtual;
and call the original constructor in its implementation. It does mean I need to call a different constructor, but as you already need to pass another parameter, that doesn't seem like such a bad trade-off.
Edit:
As I mentioned in the comments, the compiler complains about tfrmC.Create(nil, 0); having too many parameters. It seems as though tfrmC.Create(AOwner) hides tfrmA.Create(AOwner, AWndParent); Thinking about it on the way home (traffic jams seem to have an advantage after all), there is an explanation for this.
1) The overload on the tfrmA.Create serves no direct purpose other than to allow introduction of other constructors with the same name.
2) The TfrmC constructor effectively hides the TfrmA constructor, reintroducing the signature that was hidden by the TfrmA constructor. In effect this isn't an override of the original constructor but a re-introduction of a re-introduced one.
3) I feel the compiler should have emitted a warning about this hiding. The reason it doesn't is possibly the overload directive on the TfrmA constructor. When you remove that, you get an error about the TfrmC.Create declaration differing from the previous one.
4) As the TfrmA constructor was hidden by TfrmC the compiler correctly complains about TFrmC.Create(nil, 0) having too many parameters.
What is described under 2) becomes obvious when you add the signature of the TfrmA constructor to TfrmC with just the override directive. This constructor is then immediately redlined by the IDE. The reason: two constructors with the same name and a missing overload directive for the TfrmC constructor that only has the AOwner parameter.
It also becomes clear when you comment out the second parameter in the instantiation of tfrmC and had only coded "inherited;" instead of "inherited Create(AOwner);" in its implementation. The compiler then complains about incompatible types.
The latter could have been solved by using either "inherited Create(AOwner);" (as you did) or "inherited Create(AOwner, 0);". While the latter would have ensured a walk back up the inheritance tree, the former would have jumped straight back to TForm1.Create.
Using a slightly modified version of your code and provided TfrmC is instantiated with a single parameter, the result of "inherited Create(AOwner)" would have been:
while the result of "inherited Create(AOwner, 0);" would have been:
Adding overload to the TfrmC constructor as I suggested in the comments overrides the original TForm1.Create and allows for two constructors with the same name. This can be illustrated in the test project by turning on the TFRMC_OVERLOAD and INSTANTIATE2 conditional defines. This instantiates TfrmC with TfrmC.Create(nil, 0) and results in:
Which shows TfrmB.Create being called for TfrmC as TfrmB is the first ancestor with an implementation for the two-parameter constructor. While instantiating TfrmC with TfrmC.Create(nil) (turn the INSTANTIATE2 conditional define back off), results in the same picture as the first or second (depending on the TWOPARAMS define).