Code:
      //if CurrentState<>nil then CurrentState.Destroy; // This you can't call.
      //CurrentState = MainMenuState sometimes, and calling Destroy on already Destroyed object brings trouble...
      if MainMenuState<>nil then MainMenuState.Destroy;
Not entirely sure, but i think you need to override them all. CurrentState is type TState, so calling CurrentState.Update etc must refer to object it was created as. Hence override.
Code:
TMainMenuState = class(TState)
    public
      constructor Create; override;
      destructor Destroy; override;
      procedure Update; override;
      procedure BeforeDraw; override;
      procedure Draw; override;
      procedure Main; override;