I have installed Delphi 10.4 Sydney w/ Patch 2 in a new virtual machine, and copied Delphi 10.3 Tokyo sources to it.
When rebuilding a visualizer (for DevExpress TcxSchedulerEvents) I get this error:
[dcc32 Error] EventVisualizr.pas(19): E2291 Missing implementation of interface method IOTAThreadNotifier.EvaluateComplete
I had only removed the compiled packages cxLibraryRS26
, cxSchedulerRS26
, dxCoreRS26
, dxGDIPlusRS26
, and added cxLibraryRS27
, cxSchedulerRS27
, dxCoreRS27
, dxGDIPlusRS27
- no other code changes:
I get the error on the first line of the TEventViewerFrame
type definition:
unit EventVisualizr;
// Copied and modified from TStringListVisualizer. Shows values for TcxSchedulerEvent properties:
// - ID
// - Caption
// - Custom property tt_fromdate (if it exists)
// - Custom property tt_todate (if it exists)
// - Start
// - Finish
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, ToolsAPI, Vcl.ExtCtrls;
type
TAvailableState = (asAvailable, asProcRunning, asOutOfScope, asNotAvailable);
TEventViewerFrame = class(TFrame, IOTADebuggerVisualizerExternalViewerUpdater, IOTAThreadNotifier, IOTAThreadNotifier160)
EventListView: TListView;
procedure EventListViewData(Sender: TObject; Item: TListItem);
private
FOwningForm: TCustomForm;
FClosedProc: TOTAVisualizerClosedProcedure;
FNotifierIndex: Integer;
FCompleted: Boolean;
FDeferredResult: string;
FDeferredError: Boolean;
FPropValues,
FPropNames: TStrings;
FAvailableState: TAvailableState;
function Evaluate(Expression: string): string;
protected
procedure SetParent(AParent: TWinControl); override;
public
procedure CloseVisualizer;
procedure MarkUnavailable(Reason: TOTAVisualizerUnavailableReason);
procedure RefreshVisualizer(const Expression, TypeName, EvalResult: string);
procedure SetClosedCallback(ClosedProc: TOTAVisualizerClosedProcedure);
procedure SetForm(AForm: TCustomForm);
procedure AddEventItems(const Expression, TypeName, EvalResult: string);
{ IOTAThreadNotifier }
procedure AfterSave;
procedure BeforeSave;
procedure Destroyed;
procedure Modified;
procedure ThreadNotify(Reason: TOTANotifyReason);
procedure EvaluteComplete(const ExprStr, ResultStr: string; CanModify: Boolean;
ResultAddress, ResultSize: LongWord; ReturnCode: Integer);
procedure ModifyComplete(const ExprStr, ResultStr: string; ReturnCode: Integer);
{ IOTAThreadNotifier160 }
procedure EvaluateComplete(const ExprStr, ResultStr: string; CanModify: Boolean;
ResultAddress: TOTAAddress; ResultSize: LongWord; ReturnCode: Integer);
end;
In the ToolsAPI.pas
, both have an EvaluateComplete
definition, but no implementation in that source file:
IOTAThreadNotifier = interface(IOTANotifier)
['{34B2E2D7-E36F-11D1-AB0E-00C04FB16FB3}']
{ This is called when the process state changes for this thread }
procedure ThreadNotify(Reason: TOTANotifyReason);
{ This is called when an evaluate that returned erDeferred completes.
ReturnCode <> 0 if error }
procedure EvaluateComplete(const ExprStr, ResultStr: string; CanModify: Boolean;
ResultAddress, ResultSize: LongWord; ReturnCode: Integer);
{ This is called when a modify that returned erDeferred completes.
ReturnCode <> 0 if error }
procedure ModifyComplete(const ExprStr, ResultStr: string; ReturnCode: Integer);
end;
IOTAThreadNotifier160 = interface(IOTAThreadNotifier)
['{46F94C52-E225-4054-A5F0-F5E67E29B2C2}']
{ This is called when an evaluate that returned erDeferred completes.
ReturnCode <> 0 if error }
procedure EvaluateComplete(const ExprStr, ResultStr: string; CanModify: Boolean;
ResultAddress: TOTAAddress; ResultSize: LongWord; ReturnCode: Integer); overload;
end;
When comparing ToolsAPI files, I see:
- It was named
EvaluteComplete
(missing 'a') in 10.3 and that has been fixed toEvaluateComplete
- The
IOTAThreadNotifier160.EvaluateComplete
now gets an overload directive (of course, and not relevant to the issue I think)
Could that name change be the reason? There are no 'implementation' for the EvaluateComplete
procedures in the 10.3 version either (which seems to be fine, from the very little I know about interfaces).
From Why do I get the error Missing implementation of interface method in Delphi XE2? and Why do I get error Missing implementation?, I understand that the reason for the error can be that the parameter lists differ, but I have no idea where to look for the correct ones in this case.
Your
TEventViewerFrame
still contains the implementation for the 'old'EvaluteComplete
.Fix it by simply renaming
TEventViewerFrame.EvaluteComplete
toTEventViewerFrame.EvaluateComplete
(to satisfy the new interface contract).