// Example of creating and assigning event handlers at design-time in Delphi 5/6
// Created March, 2001
// Erik Berry <eberry@gexperts.org>

unit CreateMethod;

interface

procedure Register;

implementation

uses SysUtils, Classes, Windows, ToolsApi,
  {$IFDEF VER130}
  DsgnIntf,   // Delphi 5
  {$ELSE not VER130}
  DesignIntf, // Delphi 6+
  {$ENDIF}
  TypInfo;

type
  TOnClickWizard = class(TNotifierObject, IOTAMenuWizard, IOTAWizard)
  public
    procedure Execute;
    function GetIDString: string;
    function GetMenuText: string;
    function GetName: string;
    function GetState: TWizardState;
  end;

  {$IFDEF VER130}
  FormDesignerInterface = IFormDesigner; // Delphi 5
  {$ELSE not VER130}
  FormDesignerInterface = IDesigner;     // Delphi 6+
  {$ENDIF}

procedure Register;
begin
  RegisterPackageWizard(TOnClickWizard.Create);
end;

// Use to create a new method in the source and assign it to a TPersistent
procedure DoCreateMethod(FormDesigner: FormDesignerInterface; Persistent: TPersistent;
            MethodShortName, MethodSourceName: string);
var
  Method: TMethod;
  PropInfo: PPropInfo;
  TypeInfo: PTypeInfo;
begin
  TypeInfo := PTypeInfo(Persistent.ClassInfo);
  PropInfo := GetPropInfo(TypeInfo, 'On' + MethodShortName); // Ex: MethodName := "Click"
  Method   := FormDesigner.CreateMethod(MethodSourceName, GetTypeData(PropInfo^.PropType^));
  SetMethodProp(Persistent, PropInfo, Method);
end;

function GetCurrentIdeModule: IOTAModule;
var
  ModuleServices: IOTAModuleServices;
begin
  ModuleServices := BorlandIDEServices as IOTAModuleServices;
  Assert(Assigned(ModuleServices));
  Result := ModuleServices.CurrentModule;
end;

function GetFormEditorFromModule(const Module: IOTAModule): IOTAFormEditor;
var
  i: Integer;
  Editor: IOTAEditor;
  FormEditor: IOTAFormEditor;
begin
  Result := nil;
  if Module = nil then Exit;
  for i := 0 to Module.GetModuleFileCount-1 do
  begin
    Editor := Module.GetModuleFileEditor(i);
    if Supports(Editor, IOTAFormEditor, FormEditor) then
    begin
      Assert(not Assigned(Result));
      Result := FormEditor;
      Break;
    end;
  end;
end;

procedure TOnClickWizard.Execute;
var
  FormEditor: IOTAFormEditor;
  NativeFormEditor: INTAFormEditor;
begin
  FormEditor := GetFormEditorFromModule(GetCurrentIdeModule);
  if Supports(FormEditor, INTAFormEditor, NativeFormEditor) then
  begin
    if NativeFormEditor.FormDesigner <> nil then
    begin
      DoCreateMethod(NativeFormEditor.FormDesigner,
          NativeFormEditor.FormDesigner.GetRoot, 'Click', 'FormClick');
      NativeFormEditor.FormDesigner.ShowMethod('FormClick');
      NativeFormEditor.FormDesigner.Modified;
    end;
  end;
end;

function TOnClickWizard.GetIDString: string;
begin
  Result := 'EB.TestCreateOnClick';
end;

function TOnClickWizard.GetMenuText: string;
begin
  Result := 'Create OnClick for Form';
end;

function TOnClickWizard.GetName: string;
begin
  Result := 'Test Create OnClick';
end;

function TOnClickWizard.GetState: TWizardState;
begin
  Result := [wsEnabled];
end;

end.

