Question

This is specifically related to the accepted answer of another question I asked. During conversion of my already-existing collections to this new 'named collection item' structure (as explained in the previous question), I came across a compiler error...

[Error] JDSockets.pas(818): Incompatible types: 'tagWNDCLASSA' and 'Class reference'

This is coming from the Register procedure, in the first line RegisterClass(TSvrCommandComp);

TSvrCommandComp is my version of the TChildComponent in the previous answer, and TJDServerSocket is my version of the TParentComponent.

Now in the previous answer, there were actually 2 units defined. I skipped that concept and built them into the same unit. And this unit is very huge. Here I have it below with as much irrelevant stuff stripped out as possible...

unit JDSockets;

interface

uses
  Classes, Windows, SysUtils, StrUtils, ScktComp, ExtCtrls,
  DesignEditors, DesignIntf;

type
  TSvrCommands = class;
  TSvrCommand = class;
  TSvrCommandComp = class; 
  TSvrCommandParentComp = class;
// ---------- CODE REMOVED HERE ------------

////////////////////////////////////////////////////////////////////////////////
//  Command Collections
//  Goal: Allow entering pre-set commands with unique Name and ID
//  Each command has its own event which is triggered when command is received
//  IN PROGRESS: Implementing named command components from collection

  //Determines how commands are displayed in collection editor in design-time
  TJDCmdDisplay = (cdName, cdID, cdCaption, cdIDName, cdIDCaption);

  TJDScktSvrCmdEvent = procedure(Sender: TObject; Socket: TJDServerClientSocket;
    const Data: TStrings) of object;

  TSvrCommandComp = class(TComponent)
  private
    FParent: TSvrCommandParentComp;
    procedure SetParent(const Value: TSvrCommandParentComp);
  protected
    procedure SetParentComponent(AParent: TComponent); override;
  public
    destructor Destroy; override;
    function GetParentComponent: TComponent; override;
    function HasParent: Boolean; override;
    property Parent: TSvrCommandParentComp read FParent write SetParent;
  end;

  TSvrCommandParentComp = class(TComponent)
  private
    FChilds: TList;
  protected
    procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    property Childs: TList read FChilds;
  end;

  TSvrCommand = class(TCollectionItem)
  private
    FComp: TSvrCommandComp;
    fID: Integer;
    fOnCommand: TJDScktSvrCmdEvent;
    fParamCount: Integer;
    fCollection: TSvrCommands;
    fCaption: String;
    function GetName: string;
    procedure SetID(Value: Integer);
    procedure SetName(Value: String);
    procedure SetCaption(const Value: String);
  protected                                   
    property ChildComponent: TSvrCommandComp read FComp write FComp;
    function GetDisplayName: String; override;
  public
    procedure Assign(Source: TPersistent); override;
    constructor Create(Collection: TCollection); override;
    destructor Destroy; override;
  published
    property ID: Integer read fID write SetID;
    property Name: String read GetName write SetName;
    property Caption: String read fCaption write SetCaption;
    property ParamCount: Integer read fParamCount write fParamCount;
    property OnCommand: TJDScktSvrCmdEvent read fOnCommand write fOnCommand;
  end;

  TSvrCommands = class(TCollection)
  private
    FDesigner: IDesigner;
    fOnUnknownCommand: TJDScktSvrCmdEvent;
    fDisplay: TJDCmdDisplay;
    function GetItem(Index: Integer): TSvrCommand;
    procedure SetItem(Index: Integer; Value: TSvrCommand);
    procedure SetDisplay(const Value: TJDCmdDisplay);
  public
    constructor Create(AOwner: TPersistent);
    destructor Destroy; override;
    procedure DoCommand(const Socket: TJDServerClientSocket;
      const Cmd: Integer; const Data: TStrings);
    function Add: TSvrCommand;
    property Items[Index: Integer]: TSvrCommand read GetItem write SetItem;
    property Designer: IDesigner read FDesigner write FDesigner;
  published
    property Display: TJDCmdDisplay read fDisplay write SetDisplay;
    property OnUnknownCommand: TJDScktSvrCmdEvent
      read fOnUnknownCommand write fOnUnknownCommand;
  end;

// ---------- A BUNCH OF CODE REMOVED HERE ------------

type
  TSvrCommandEditor = class(TComponentEditor)
    procedure ExecuteVerb(Index: Integer); override;
    function GetVerb(Index: Integer): string; override;
    function GetVerbCount: Integer; override;
  end;

// ---------- CODE REMOVED HERE ------------

procedure Register;

implementation

uses
  ColnEdit;

procedure Register;
begin
  RegisterClass(TSvrCommandComp); //<-- ERROR
  RegisterNoIcon([TSvrCommandComp]);
  RegisterComponents('JD Custom', [TJDServerSocket]);
  RegisterComponentEditor(TSvrCommandParentComp, TSvrCommandEditor);
end;

// ---------- A BUNCH OF CODE REMOVED HERE ------------

{ TSvrCommands }

function TSvrCommands.Add: TSvrCommand;
begin
  Result:= inherited Add as TSvrCommand;
end;

constructor TSvrCommands.Create(AOwner: TPersistent);
begin
  inherited Create(TSvrCommand);
  Self.fOwner:= AOwner;
end;

destructor TSvrCommands.Destroy;
begin
  inherited Destroy;
end;

procedure TSvrCommands.DoCommand(const Socket: TJDServerClientSocket;
  const Cmd: Integer; const Data: TStrings);
var
  X: Integer;
  C: TSvrCommand;
  F: Bool;
begin
  F:= False;
  for X:= 0 to Self.Count - 1 do begin
    C:= GetItem(X);
    if C.ID = Cmd then begin
      F:= True;
      try
        if assigned(C.fOnCommand) then
          C.fOnCommand(Self, Socket, Data);
      except
        on e: exception do begin
          raise Exception.Create(
            'Failed to execute command '+IntToStr(Cmd)+': '+#10+e.Message);
        end;
      end;
      Break;
    end;
  end;
  if not F then begin
    //Command not found

  end;
end;

function TSvrCommands.GetItem(Index: Integer): TSvrCommand;
begin
  Result:= TSvrCommand(inherited GetItem(Index));
end;

function TSvrCommands.GetOwner: TPersistent;
begin
  Result:= fOwner;
end;

procedure TSvrCommands.SetDisplay(const Value: TJDCmdDisplay);
begin
  fDisplay := Value;
  //Refresh collection items

end;

procedure TSvrCommands.SetItem(Index: Integer; Value: TSvrCommand);
begin
  inherited SetItem(Index, Value);
end;

{ TSvrCommand }

procedure TSvrCommand.Assign(Source: TPersistent);
begin
  inherited;

end;

constructor TSvrCommand.Create(Collection: TCollection);
begin
  inherited Create(Collection);
  FComp:= TSvrCommandComp.Create(Collection.Owner);
end;

destructor TSvrCommand.Destroy;
begin
  FComp.Free;
  inherited Destroy;
end;

function TSvrCommand.GetDisplayName: String;
begin        
  case Self.fCollection.fDisplay of
    cdName: begin
      Result:= fName;
    end;
    cdID: begin
      Result:= '['+IntToStr(fID)+']';
    end;
    cdCaption: begin
      Result:= fCaption;
    end;
    cdIDName: begin
      Result:= '['+IntToStr(fID)+'] '+fName;
    end;
    cdIDCaption: begin
      Result:= '['+IntToStr(fID)+'] '+fCaption;
    end;
  end;
end;

function TSvrCommand.GetName: string;
begin
  Result:= FComp.Name;
end;

procedure TSvrCommand.SetCaption(const Value: String);
begin
  fCaption := Value;
end;

procedure TSvrCommand.SetID(Value: Integer);
begin
  FID:= Value;
end;

procedure TSvrCommand.SetName(Value: String);
begin
  FComp.Name := Value;
end;

{ TSvrCommandComp }

destructor TSvrCommandComp.Destroy;
begin
  Parent:= nil;
  inherited;
end;

function TSvrCommandComp.GetParentComponent: TComponent;
begin
  Result := FParent;
end;

function TSvrCommandComp.HasParent: Boolean;
begin
  Result := Assigned(FParent);
end;

procedure TSvrCommandComp.SetParent(const Value: TSvrCommandParentComp);
begin
  if FParent <> Value then
  begin
    if Assigned(FParent) then
      FParent.FChilds.Remove(Self);
    FParent := Value;
    if Assigned(FParent) then
      FParent.FChilds.Add(Self);
  end;
end;

procedure TSvrCommandComp.SetParentComponent(AParent: TComponent);
begin
  if AParent is TSvrCommandParentComp then
    SetParent(AParent as TSvrCommandParentComp);
end;

{ TSvrCommandParentComp }

constructor TSvrCommandParentComp.Create(AOwner: TComponent);
begin
  inherited;
  FChilds := TList.Create;
end;

destructor TSvrCommandParentComp.Destroy;
begin
  FChilds.Free;
  inherited;
end;

procedure TSvrCommandParentComp.GetChildren(Proc: TGetChildProc;
  Root: TComponent);
var
  i: Integer;
begin
  for i := 0 to FChilds.Count - 1 do
    Proc(TComponent(FChilds[i]));
end;

{ TSvrCommandEditor }

procedure TSvrCommandEditor.ExecuteVerb(Index: Integer);
var
  LCollection: TChildComponentCollection;
  i: Integer;
begin
  LCollection := TChildComponentCollection.Create(Component, TChildComponentCollectionItem);
  LCollection.Designer := Designer;
  for i := 0 to TParentComponent(Component).Childs.Count - 1 do
    with TChildComponentCollectionItem.Create(nil) do
    begin
      ChildComponent := TChildComponent(TParentComponent(Component).Childs[i]);
      Collection := LCollection;
    end;
  ShowCollectionEditorClass(Designer, TCollectionEditor, Component, LCollection, 'Childs');
end;

function TSvrCommandEditor.GetVerb(Index: Integer): string;
begin
  Result := 'Edit Commands...';
end;

function TSvrCommandEditor.GetVerbCount: Integer;
begin
  Result := 1;
end;

end.
Was it helpful?

Solution

Your uses clause has Windows after Classes and so the wrong RegisterClass is in scope. There is a windows API function of that name but you want the function in the Classes unit.

Either fully qualify the name (Classes.RegisterClass) or re-order the units in your uses clause.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top