unit DeskBandForm;

interface

uses Forms, Windows, ActiveX, ShlObj;

type
  // IInputObject not used by IE
  TDeskBandForm = class(TAggregatedObject, IDeskBand, IDockingWindow, IOleWindow)
  private
    FForm: TCustomForm;
    FFormOwned: boolean;
    FBandID: DWORD;
    FViewMode: DWORD;
    procedure SetForm(const Value: TCustomForm);
  protected
    { IDeskBand }
    function GetBandInfo(dwBandID, dwViewMode: DWORD; var pdbi: TDeskBandInfo):
      HResult; stdcall;
    { IDockingWindow }
    function ShowDW(fShow: BOOL): HResult; stdcall;
    function CloseDW(dwReserved: DWORD): HResult; stdcall;
    function ResizeBorderDW(var prcBorder: TRect; punkToolbarSite: IUnknown;
      fReserved: BOOL): HResult; stdcall;
    { IOleWindow }
    function GetWindow(out wnd: HWnd): HResult; stdcall;
    function ContextSensitiveHelp(fEnterMode: BOOL): HResult; stdcall;
  public
    constructor Create(const Controller: IInterface; FormOwned: boolean = true);
    destructor Destroy; override;
    property Form: TCustomForm read FForm write SetForm;
  end;

implementation

uses SysUtils;

{ TDeskBandForm }

constructor TDeskBandForm.Create(const Controller: IInterface; FormOwned: boolean = true);
begin
  inherited Create(Controller);
  FFormOwned:= FormOwned;
end;

destructor TDeskBandForm.Destroy;
begin
  SetForm(nil);
  inherited Destroy;
end;

procedure TDeskBandForm.SetForm(const Value: TCustomForm);
begin
  if Assigned(FForm) and FFormOwned then
    FForm.Free;
  FForm := Value;
end;

{ TDeskBandForm.IDeskBand }

function TDeskBandForm.GetBandInfo(dwBandID, dwViewMode: DWORD;
  var pdbi: TDeskBandInfo): HResult;
begin
  try
    if not Assigned(FForm) then
      Result:= E_FAIL
    else
    begin
      Result:= S_OK;
      FBandID:= dwBandID;
      FViewMode:= dwViewMode;
      if pdbi.dwMask and DBIM_MINSIZE > 0 then
      begin
        pdbi.ptMinSize.x:= FForm.Constraints.MinWidth;
        pdbi.ptMinSize.y:= FForm.Constraints.MinHeight;
      end;
      if pdbi.dwMask and DBIM_MAXSIZE > 0 then
      begin
        pdbi.ptMaxSize.x:= FForm.Constraints.MaxWidth;
        pdbi.ptMaxSize.y:= FForm.Constraints.MaxHeight;
      end;
      if pdbi.dwMask and DBIM_INTEGRAL > 0 then
      begin
        pdbi.ptIntegral.x:= 1;
        pdbi.ptIntegral.y:= 1;
      end;
      if pdbi.dwMask and DBIM_ACTUAL > 0 then
      begin
        pdbi.ptActual.x:= FForm.Width;
        pdbi.ptActual.y:= FForm.Height;
      end;
      if pdbi.dwMask and DBIM_TITLE > 0 then
        Move(WideString(FForm.Caption)[1], pdbi.wszTitle[1], (Length(WideString(FForm.Caption))+1)*2);
      if pdbi.dwMask and DBIM_MODEFLAGS > 0 then
        pdbi.dwModeFlags:= DBIMF_VARIABLEHEIGHT;
      if pdbi.dwMask and DBIM_BKCOLOR > 0 then
        //Use the default background color by removing this flag.
        pdbi.dwMask:= pdbi.dwMask and not DBIM_BKCOLOR;
    end;
  except
    Result:= E_INVALIDARG;
  end;
end;

{ TDeskBandForm.IDockingWindow }

function TDeskBandForm.CloseDW(dwReserved: DWORD): HResult;
begin
  Result:= S_OK;
  try
    if not Assigned(FForm) then
      raise Exception.Create('E_FAIL');
    FForm.Visible:= false;
  except
    Result:= E_FAIL;
  end;
end;

function TDeskBandForm.ResizeBorderDW(var prcBorder: TRect;
  punkToolbarSite: IInterface; fReserved: BOOL): HResult;
begin
  Result:= E_NOTIMPL; // MSDN like
end;

function TDeskBandForm.ShowDW(fShow: BOOL): HResult;
begin
  Result:= S_OK;
  try
    if not Assigned(FForm) then
      raise Exception.Create('E_FAIL');
    FForm.Visible:= fShow;
  except
    Result:= E_FAIL;
  end;
end;

{ TDeskBandForm.IOleWindow }

function TDeskBandForm.GetWindow(out wnd: HWnd): HResult;
begin
  Result := S_OK;
  if not Assigned(FForm) then
    Result:= E_FAIL
  else
    wnd := FForm.Handle;
end;

function TDeskBandForm.ContextSensitiveHelp(fEnterMode: BOOL): HResult;
begin
  Result := S_OK;
end;

end.
