4

Basing on this answer I'm trying to override OnShowWindow method of TOleContainer in Delphi 7.

unit MyOleContainer;

interface

uses
    Windows, OleCtnrs;

type
  TOleContainer = class(OleCtnrs.TOleContainer)
  private
    function OnShowWindow(fShow: BOOL): HResult; stdcall; override;
  end;

implementation

function TOleContainer.OnShowWindow(fShow: BOOL): HResult;
begin
   Result := S_OK;
end;

end.

But this won't compile giving following error: [Error] MyOleContainer.pas(11): Field definition not allowed after methods or properties Why?

Edit:

Could you please explain how to "declare implementation of IOleClientSite, inherit from TOleContainer and hide the method OnShowWindow [...] use a TOleContainer as IOleClientSite"?

Edit2:

Is this what you meant?

TMyContainer = class(TOleContainer, IOleClientSite)
private 
   FIOleClientSite: IOleClientSite;
   function SaveObject: HResult; stdcall;
   ...

constructor TMyContainer.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Self.OleObjectInterface.GetClientSite(FIOleClientSite);
end;

function TMyContainer.SaveObject: HResult;
begin
  Result := FIOleClientSite.SaveObject;
end;

...
Community
  • 1
  • 1
forsajt
  • 857
  • 1
  • 7
  • 13
  • 1
    Inherit from TOleContainer to implement IOleClientSite: `TMyContainer = class(TOleContainer, IOleClientSite, etc...)`. Now give it a private variable of type IOleClientSite, initialize that in the constructor, and implement all methods required by IOleClientSite by simply calling the methods of the internal IOleClientSite with the same parameters and return type, except of course the methods you want to change. In other words: it is not easy to override a non-virtual method of a class, but it is pretty easy to override methods of an interface. – Rudy Velthuis Mar 08 '13 at 14:38
  • I updated my post with the code. Is that correct way of doing this? Thanks. – forsajt Mar 08 '13 at 22:39

1 Answers1

5

The error message is a little misleading. What it is saying, essentially, is that the override keyword cannot appear after the stdcall keyword.

This is a bit of an aside, but if you are overriding a method then you do not need to, and should not, re-state the calling convention. You cannot modify the calling convention when you override a method so it's best not to repeat it.

However, when you fix that problem, your code will still not compile. And that is because he OnShowWindow function is not virtual. Therefore you cannot override it.

I don't see how you can change the behaviour of the IOleClientSite.OnShowWindow implementation without re-declaring and re-implementing the entire implementation of IOleClientSite. And I don't think that's at all easy to do.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • 1
    OTOH, if he only needs it as implementation of IOleClientSide, then it is pretty easy to "override" an interface method: declare implementation of IOleClientSite, inherit from TOleContainer and hide the method OnShowWindow. Now the interface will use the new method. – Rudy Velthuis Mar 06 '13 at 14:55
  • 1
    @RudyVelthuis He also needs to reimplement all the other methods in `IOleClientSite` because the implementations in `TOleContainer` all have private visibility. – David Heffernan Mar 06 '13 at 14:58
  • Ok, that's worse. He could use a TOleContainer as IOleClientSite to implement the rest. – Rudy Velthuis Mar 07 '13 at 01:12
  • Yes, of course, I just updated the question because I can't figure out a proper way of doing what Rudy Velthuis says. – forsajt Mar 08 '13 at 14:30