unit iAddIn;

(* CONTENT: This file specifies the Delphi version of the interfaces  *)
(* Paradox calls to get information about add-ins.  It also specifies *)
(* the IParadox and IPdoxAutoPascal interfaces, which Paradox         *)
(* provides so that you can talk back to Paradox.                     *)

(* To create a Paradox Add-In you must provide an implementation      *)
(* of the IPdxAddin interface as specified below.  To support menu    *)
(* items you must also supply IPdxMenuList.  To support forms you     *)
(* must also supply IPdxFormList and an IAddinForm for each form.     *)
(* This is all done for you in uADDIN.pas.                            *)

(* In order for Paradox to recognize your DLL as an Add-in, you must  *)
(* Export a routine called "ParadoxRegisterAddin" using the           *)
(* TRegisterFunc prototype specified below.  Paradox will pass you    *)
(* an IParadox interface, which you should addref and keep so that    *)
(* you can talk back to Paradox.                                      *)
(* This is all done for you in PdxAddin.pas                           *)

interface

Uses
  Windows, OLE2;

const
  IID_PdxAddin: TGUID = (
      D1: $656905B0;
      D2: $A8F6;
      D3: $11CF;
      D4: ($88,$59, $00,$20,$AF,$32,$94,$69));

  IID_PdxInfoList: TGUID = (
      D1: $656905B1;
      D2: $A8F6;
      D3: $11CF;
      D4: ($88,$59, $00,$20,$AF,$32,$94,$69));

  IID_PdxMenuList: TGUID = (
      D1: $656905B2;
      D2: $A8F6;
      D3: $11CF;
      D4: ($88,$59, $00,$20,$AF,$32,$94,$69));

  IID_PdxFormList: TGUID = (
      D1: $656905B3;
      D2: $A8F6;
      D3: $11CF;
      D4: ($88,$59, $00,$20,$AF,$32,$94,$69));

  { Reserved for future use }
  IID_PdxAutoList: TGUID = (
      D1: $656905B4;
      D2: $A8F6;
      D3: $11CF;
      D4: ($88,$59, $00,$20,$AF,$32,$94,$69));

  { Reserved for future use }
  IID_PdxDataModelList: TGUID = (
      D1: $656905B5;
      D2: $A8F6;
      D3: $11CF;
      D4: ($88,$59, $00,$20,$AF,$32,$94,$69));

  IID_AddinForm: TGUID = (
      D1: $656905C0;
      D2: $A8F6;
      D3: $11CF;
      D4: ($88,$59, $00,$20,$AF,$32,$94,$69));

  { Reserved for future use }
  IID_DataModule: TGUID = (
      D1: $656905C1;
      D2: $A8F6;
      D3: $11CF;
      D4: ($88,$59, $00,$20,$AF,$32,$94,$69));

Type
     { Specifies where the menu node is to be hooked in }
     // from DESKTOP.CPP.  Must match this:
     // int FileMenuMsg[NUMFILEMENUS] = { DM_CREATE, DM_OPEN, DM_UTIL, DM_NET,
     //                               DM_INFO, DM_FILE, DM_PROPS, DM_TOOLS, DM_HELP };

     TPdxMenuNode = ( pdxmFileNew, pdxmFileOpen,
                      pdxmUtilities, pdxmNet{obsolete}, pdxmInfo,
                      pdxmFile, pdxmProps{obsolete}, pdxmTools,
                      pdxmHelp );


Type
  IPdxAddinRoot = Class ( IUnknown )
    protected
      fRefCount :Integer;
    public
{      function QueryInterface(const iid: TIID; var obj): HResult; override; stdcall; }
      function doAddRef: Longint;
      function doRelease: Longint;
      Procedure Free;  { Used to block inadvertant Free's in Delphi code }
    end;

  IPdxAddin = Class ( IPdxAddinRoot )
     { Paradox uses this as a central hook to get to all the other interfaces. }
     { No special methods - just use queryInterface. }
    End;

  IPdxInfoList = Class(IPdxAddinRoot)
      { Base class definition for interfaces that give us a list of items/interfaces }
      Procedure Clear; Virtual; StdCall; Abstract;
      Function GetCount:Integer; Virtual; StdCall; Abstract;
      Function GetName(Index:Integer):TBStr; Virtual; StdCall; Abstract;
      Function IndexOf(Name:TBStr):Integer; Virtual; StdCall; Abstract;
    end;

  IPdxMenuList = Class(IPdxInfoList)
      { Paradox calls this to access each registered menu }
      Procedure DoInit(Index:Integer); Virtual; StdCall; Abstract;
        { Paradox calls this to let you know the menu system is being (re)initialized }
      Function InSubMenu(Index:Integer; Node:TPdxMenuNode):Boolean; Virtual; StdCall; Abstract;
        { Paradox calls this to find out if this index belogs in the NODE menu of Paradox }
      Function GetHandle(Index:Integer):HMENU; Virtual; StdCall; Abstract;
        { Paradox calls this to get the Windows menu handle for an item }
      Procedure DoClick(Command:Word); Virtual; StdCall; Abstract;
        { Paradox calls this to let you know the menu item was selected }
      Procedure DoClickHelp(Command:Word); Virtual; StdCall; Abstract;
        { Paradox calls this to let you know that help for the menu item was selected }
    end;

  IPdxFormList = Class(IPdxInfoList)
      { Paradox calls this to get an IAddinForm for each registered form or form class  }
      Function Instance(Index:Integer):IUnknown; Virtual; StdCall; Abstract;
        { Instance will return an IAddinForm }
      Function AttachWindow(wnd:HWND; title:TBSTR):IUnknown; Virtual; StdCall; Abstract;
        { Returns an IAddInForm for the specified window or window title, if match found }
    end;

  IPdxAutoList = Class(IPdxInfoList)  { Reserved for future - DO NOT IMPLEMENT }
      Function Instance(Index:Integer):IUnknown; Virtual; StdCall; Abstract;
        { Instance will return an IDispatch }
    end;

  IAddInForm = Class(IPdxAddinRoot)
      { Paradox calls this to manipulate an Add In Form }
      Procedure bringToTop; Virtual; StdCall; Abstract;
      Function close:BOOL; Virtual; StdCall; Abstract;
      Function closeQuery:BOOL; Virtual; StdCall; Abstract;
      Procedure getPosition(var x,y,w,h:longint); Virtual; StdCall; Abstract; {pixels}
      Function getTitle:TBStr; Virtual; StdCall; Abstract;
      Procedure hide; Virtual; StdCall; Abstract;
      Function isMaximized:Bool; Virtual; StdCall; Abstract;
      Function isMinimized:Bool; Virtual; StdCall; Abstract;
      Function isVisible:Bool; Virtual; StdCall; Abstract;
      Procedure maximize; Virtual; StdCall; Abstract;
      Function menuAction(Command:Integer):BOOL; Virtual; StdCall; Abstract;
      Procedure minimize; Virtual; StdCall; Abstract;
      Procedure open; Virtual; StdCall; Abstract;
      Procedure openAs(bDialog:Bool;bVisible:Bool); Virtual; StdCall; Abstract;
      Procedure postMessage(Command:Cardinal; W:WPARAM; L:LPARAM); Virtual; StdCall; Abstract;
      Function sendMessage(Command:Cardinal; W:WPARAM; L:LPARAM):LRESULT; Virtual; StdCall; Abstract;
      Procedure setPosition(var x,y,w,h:longint); Virtual; StdCall; Abstract; {pixels}
      Procedure setTitle(Title:TBStr); Virtual; StdCall; Abstract;
      Procedure show; Virtual; StdCall; Abstract;
      Function showModal:Integer; Virtual; StdCall; Abstract; { In place of Wait }
      Function windowClientHandle:HWND; Virtual; StdCall; Abstract;
      Function windowHandle:HWND; Virtual; StdCall; Abstract;
      { You can define whatever properties you want.  The default Delphi implementation
        maps these to Delphi Published Properties. }
      Function getProperty(Name:TBStr; Index:Variant):Variant; Virtual; StdCall; Abstract;
      Procedure setProperty(Name:TBStr; Index, Value:Variant); Virtual; StdCall; Abstract;
      Function getPropAsString(Name:TBStr):TBStr; Virtual; StdCall; Abstract;
      Procedure setPropAsString(Name, Value:TBStr); Virtual; StdCall; Abstract;
      Function getPropAsInteger(Name:TBStr):Integer; Virtual; StdCall; Abstract;
      Procedure setPropAsInteger(Name:TBStr; Value:Integer); Virtual; StdCall; Abstract;
      Function getPropAsFloat(Name:TBStr):Double; Virtual; StdCall; Abstract;
      Procedure setPropAsFloat(Name:TBStr; Value:Double); Virtual; StdCall; Abstract;
    end;

  IPdoxAutoPascal = Class ( IUnknown ) // Paradox's Automation Interface
    public
    // =================== Properties - status of the desktop
    function getVisible:BOOL; virtual; stdcall; abstract;
    function setVisible(newValue:BOOL):BOOL; virtual; stdcall; abstract;
    // =================== Automation methods
    // Desktop automation
    function FormOpen(filename:TBSTR):longint;  virtual; stdcall; abstract;
    function ReportOpen(filename:TBSTR):longint;  virtual; stdcall; abstract;
    function ScriptOpen(filename:TBSTR):longint;  virtual; stdcall; abstract;
    function LibraryOpen(filename:TBSTR):longint;  virtual; stdcall; abstract;
    function TableOpen(filename:TBSTR):longint;  virtual; stdcall; abstract;
    function FormDesign(filename:TBSTR):longint;  virtual; stdcall; abstract;
    function ReportDesign(filename:TBSTR):longint;  virtual; stdcall; abstract;
    function ScriptDesign(filename:TBSTR):longint;  virtual; stdcall; abstract;
    function LibraryDesign(filename:TBSTR):longint;  virtual; stdcall; abstract;
    function FormNew:longint;  virtual; stdcall; abstract;
    function ReportNew:longint;  virtual; stdcall; abstract;
    function ScriptNew:longint;  virtual; stdcall; abstract;
    function LibraryNew:longint;  virtual; stdcall; abstract;
    function ReportPrint(filename:TBSTR):longint;  virtual; stdcall; abstract;
    function TableInfoStructure(filename:TBSTR):longint;  virtual; stdcall; abstract;
    function TableRestructure(filename:TBSTR):longint;  virtual; stdcall; abstract;
    function TableAdd(filename:TBSTR):longint;  virtual; stdcall; abstract;
    function TableEmpty(filename:TBSTR):longint;  virtual; stdcall; abstract;
    function TableSubtract(filename:TBSTR):longint;  virtual; stdcall; abstract;
    function Copy(filename:TBSTR):longint;  virtual; stdcall; abstract;
    function Rename(filename:TBSTR):longint;  virtual; stdcall; abstract;
    function Delete(filename:TBSTR):longint;  virtual; stdcall; abstract;
    function QueryOpen(filename:TBSTR):longint;  virtual; stdcall; abstract;
    function QueryDesign(filename:TBSTR):longint;  virtual; stdcall; abstract;
    function QueryNew:longint;  virtual; stdcall; abstract;
    function TableExport(filename:TBSTR):longint;  virtual; stdcall; abstract;
    function TableSort(filename:TBSTR):longint;  virtual; stdcall; abstract;
    function SQLQueryOpen(filename:TBSTR):longint;  virtual; stdcall; abstract;
    function SQLQueryDesign(filename:TBSTR):longint;  virtual; stdcall; abstract;
    function SQLQueryNew:longint;  virtual; stdcall; abstract;
    function DataModelDesign(filename:TBSTR):longint;  virtual; stdcall; abstract;
    function ScreenSheetDesign(filename:TBSTR):longint;  virtual; stdcall; abstract;
    function PrinterSheetDesign(filename:TBSTR):longint;  virtual; stdcall; abstract;
    function executeString(scriptStr:TBSTR; usesStr:TBSTR):TBSTR;  virtual; stdcall; abstract;
    function GetLastError:longint;  virtual; stdcall; abstract;
    function GetLastErrorAsString:TBSTR;  virtual; stdcall; abstract;
    procedure ShowLastErrorStack;  virtual; stdcall; abstract;
    function GetLastErrorStackDepth:longint;  virtual; stdcall; abstract;
    function GetLastErrorAtDepth(depth:longint):longint;  virtual; stdcall; abstract;
    function GetLastErrorAtDepthAsString(depth:longint):TBSTR;  virtual; stdcall; abstract;
    function MsgBox(strTitle:TBSTR; strMsg:TBSTR):longint;  virtual; stdcall; abstract;
    procedure Quit;  virtual; stdcall; abstract;
      { Call this to shutdown Paradox }
  end;

  IParadox = Class ( IUnknown ) // Paradox provides this interface
    public
      { Desktop }
      Function GetDesktopHandle:HWND; Virtual; StdCall; Abstract;
      Function GetDesktopClientHandle:HWND; Virtual; StdCall; Abstract;
      { Menu }
      Procedure SetMenu( hwnd:HWND; menu:HMENU ); Virtual; StdCall; Abstract;
      Procedure SetDeskMenu; Virtual; StdCall; Abstract;
      Procedure RevertMenu;  Virtual; StdCall; Abstract; // Use on close
      Procedure RebuildMenu; Virtual; StdCall; Abstract;

      Procedure SetStatusRegions(nRegions:Integer; RegionSizes:PInteger); Virtual; StdCall; Abstract;
      Procedure SetStatusText(nRegion:Integer; RegionText:PChar); Virtual; StdCall; Abstract;

      Procedure ShowHelp(HelpContext:Integer); Virtual; StdCall; Abstract;
      Procedure DoMenuAction(Command:Word); Virtual; StdCall; Abstract;

      Procedure RaiseError(ErrorId:Integer; ErrorText:PChar); Virtual; StdCall; Abstract;
        // Delphi doesn't need (and shouldn't use) RaiseError.
        // Paradox understands Delphi Exceptions, so use them instead.
        // ONLY C/C++ should use, and only to return errors to PAL
        // This routine doesn't return.

      Function GetResourceHandle:Longint; Virtual; StdCall; Abstract;
        // Paradox stores all it's resources in a central DLL.
        // This routine provides the instance handle for that DLL so that
        // you can access Paradox resources (via LoadString, etal).
      Function GetAutomationInterface:IPdoxAutoPascal; Virtual; StdCall; Abstract;
        // Paradox's Automation Interface (defined above)
        // Use for opening tables, forms, etc.
    end;


  TRegisterFunc = Function(ParadoxInterface:IParadox) :IPdxAddin; StdCall;

implementation

function IPdxAddinRoot.doAddRef: Longint;
begin
  Inc(FRefCount);
  Result := FRefCount;
end;

function IPdxAddinRoot.doRelease: Longint;
begin
  Dec(FRefCount);
  Result := FRefCount;
  if FRefCount = 0 then Destroy;
end;

procedure IPdxAddinRoot.Free;  { Used to block inadvertant Free's in Delphi code }
begin
  if Self <> nil then Release;
end;

end.
