home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 1997 April
/
Chip_1997-04_cd.bin
/
prezent
/
cb
/
data.z
/
OLECTNRS.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1997-01-16
|
83KB
|
2,956 lines
{*******************************************************}
{ }
{ Delphi Visual Component Library }
{ }
{ Copyright (c) 1996 Borland International }
{ }
{*******************************************************}
unit OleCtnrs;
interface
uses Windows, Messages, CommCtrl, Ole2, OleDlg, SysUtils, Classes,
Controls, Forms, Menus, Graphics, OleAuto;
const
ovShow = -1;
ovOpen = -2;
ovHide = -3;
ovUIActivate = -4;
ovInPlaceActivate = -5;
ovDiscardUndoState = -6;
ovPrimary = -65536;
type
TOleContainer = class;
TOleForm = class;
TOleClientSite = class(IOleClientSite)
private
FContainer: TOleContainer;
public
constructor Create(Container: TOleContainer);
function QueryInterface(const iid: TIID; var obj): HResult; override;
function AddRef: Longint; override;
function Release: Longint; override;
function SaveObject: HResult; override;
function GetMoniker(dwAssign: Longint; dwWhichMoniker: Longint;
var mk: IMoniker): HResult; override;
function GetContainer(var container: IOleContainer): HResult; override;
function ShowObject: HResult; override;
function OnShowWindow(fShow: BOOL): HResult; override;
function RequestNewObjectLayout: HResult; override;
end;
TOleInPlaceSite = class(IOleInPlaceSite)
private
FContainer: TOleContainer;
public
constructor Create(Container: TOleContainer);
function QueryInterface(const iid: TIID; var obj): HResult; override;
function AddRef: Longint; override;
function Release: Longint; override;
function GetWindow(var wnd: HWnd): HResult; override;
function ContextSensitiveHelp(fEnterMode: BOOL): HResult; override;
function CanInPlaceActivate: HResult; override;
function OnInPlaceActivate: HResult; override;
function OnUIActivate: HResult; override;
function GetWindowContext(var frame: IOleInPlaceFrame;
var doc: IOleInPlaceUIWindow; var rcPosRect: TRect;
var rcClipRect: TRect; var frameInfo: TOleInPlaceFrameInfo): HResult;
override;
function Scroll(const scrollExtent: TPoint): HResult; override;
function OnUIDeactivate(fUndoable: BOOL): HResult; override;
function OnInPlaceDeactivate: HResult; override;
function DiscardUndoState: HResult; override;
function DeactivateAndUndo: HResult; override;
function OnPosRectChange(const rcPosRect: TRect): HResult; override;
end;
TAdviseSink = class(IAdviseSink)
private
FContainer: TOleContainer;
public
constructor Create(Container: TOleContainer);
function QueryInterface(const iid: TIID; var obj): HResult; override;
function AddRef: Longint; override;
function Release: Longint; override;
procedure OnDataChange(var formatetc: TFormatEtc; var stgmed: TStgMedium); override;
procedure OnViewChange(dwAspect: Longint; lindex: Longint); override;
procedure OnRename(mk: IMoniker); override;
procedure OnSave; override;
procedure OnClose; override;
end;
TAutoActivate = (aaManual, aaGetFocus, aaDoubleClick);
TSizeMode = (smClip, smCenter, smScale, smStretch, smAutoSize);
TObjectState = (osEmpty, osLoaded, osRunning, osOpen, osInPlaceActive,
osUIActive);
TCreateType = (ctNewObject, ctFromFile, ctLinkToFile, ctFromData,
ctLinkFromData);
TCreateInfo = record
CreateType: TCreateType;
ShowAsIcon: Boolean;
IconMetaPict: HGlobal;
ClassID: TCLSID;
FileName: string;
DataObject: IDataObject;
end;
TVerbInfo = record
Verb: Smallint;
Flags: Word;
end;
TObjectMoveEvent = procedure(OleContainer: TOleContainer;
const Bounds: TRect) of object;
TOleContainer = class(TCustomControl)
private
FRefCount: Longint;
FLockBytes: ILockBytes;
FStorage: IStorage;
FOleObject: IOleObject;
FOleClientSite: TOleClientSite;
FOleInPlaceSite: TOleInPlaceSite;
FAdviseSink: TAdviseSink;
FDrawAspect: Longint;
FViewSize: TPoint;
FObjectVerbs: TStringList;
FDataConnection: Longint;
FDocForm: TOleForm;
FFrameForm: TOleForm;
FOleInPlaceObject: IOleInPlaceObject;
FOleInPlaceActiveObject: IOleInPlaceActiveObject;
FAccelTable: HAccel;
FAccelCount: Integer;
FPopupVerbMenu: TPopupMenu;
FAllowInPlace: Boolean;
FAutoActivate: TAutoActivate;
FAutoVerbMenu: Boolean;
FBorderStyle: TBorderStyle;
FCopyOnSave: Boolean;
FOldStreamFormat: Boolean;
FSizeMode: TSizeMode;
FObjectOpen: Boolean;
FUIActive: Boolean;
FModified: Boolean;
FModSinceSave: Boolean;
FFocused: Boolean;
FNewInserted: Boolean;
FOnActivate: TNotifyEvent;
FOnDeactivate: TNotifyEvent;
FOnObjectMove: TObjectMoveEvent;
FOnResize: TNotifyEvent;
function AddRef: Longint;
procedure AdjustBounds;
procedure CheckObject;
procedure CreateAccelTable;
procedure CreateStorage;
procedure DesignModified;
procedure DestroyAccelTable;
procedure DestroyVerbs;
function GetBorderWidth: Integer;
function GetCanPaste: Boolean;
function GetIconic: Boolean;
function GetLinked: Boolean;
function GetObjectDataSize: Integer;
function GetObjectVerbs: TStrings;
function GetOleClassName: string;
function GetOleObject: Variant;
function GetPrimaryVerb: Integer;
function GetSourceDoc: string;
function GetState: TObjectState;
procedure InitObject;
procedure ObjectModified;
procedure ObjectMoved(const ObjectRect: TRect);
procedure ObjectShowWindow(Show: Boolean);
procedure ObjectViewChange(Aspect: Longint);
procedure PopupVerbMenuClick(Sender: TObject);
function QueryInterface(const iid: TIID; var obj): HResult;
function Release: Longint;
procedure SaveObject;
procedure SetBorderStyle(Value: TBorderStyle);
procedure SetDrawAspect(Iconic: Boolean; IconMetaPict: HGlobal);
procedure SetFocused(Value: Boolean);
procedure SetIconic(Value: Boolean);
procedure SetSizeMode(Value: TSizeMode);
procedure SetUIActive(Active: Boolean);
procedure SetViewAdviseSink(Enable: Boolean);
procedure UpdateObjectRect;
procedure UpdateView;
procedure CMCtl3DChanged(var Message: TMessage); message CM_CTL3DCHANGED;
procedure CMDocWindowActivate(var Message: TMessage); message CM_DOCWINDOWACTIVATE;
procedure CMUIDeactivate(var Message: TMessage); message CM_UIDEACTIVATE;
procedure WMKillFocus(var Message: TWMSetFocus); message WM_KILLFOCUS;
procedure WMSetFocus(var Message: TWMSetFocus); message WM_SETFOCUS;
procedure WMSize(var Message: TWMSize); message WM_SIZE;
procedure WMWindowPosChanged(var Message: TWMWindowPosChanged); message WM_WINDOWPOSCHANGED;
protected
procedure CreateParams(var Params: TCreateParams); override;
procedure DblClick; override;
procedure DefineProperties(Filer: TFiler); override;
procedure DoEnter; override;
function GetPopupMenu: TPopupMenu; override;
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer); override;
procedure Paint; override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function ChangeIconDialog: Boolean;
procedure Close;
procedure Copy;
procedure CreateLinkToFile(const FileName: string; Iconic: Boolean);
procedure CreateObject(const OleClassName: string; Iconic: Boolean);
procedure CreateObjectFromFile(const FileName: string; Iconic: Boolean);
procedure CreateObjectFromInfo(const CreateInfo: TCreateInfo);
procedure DestroyObject;
procedure DoVerb(Verb: Integer);
function GetIconMetaPict: HGlobal;
function InsertObjectDialog: Boolean;
procedure LoadFromFile(const FileName: string);
procedure LoadFromStream(Stream: TStream);
function ObjectPropertiesDialog: Boolean;
procedure Paste;
function PasteSpecialDialog: Boolean;
procedure Run;
procedure SaveToFile(const FileName: string);
procedure SaveToStream(Stream: TStream);
procedure UpdateObject;
procedure UpdateVerbs;
property CanPaste: Boolean read GetCanPaste;
property Linked: Boolean read GetLinked;
property Modified: Boolean read FModified write FModified;
property NewInserted: Boolean read FNewInserted;
property ObjectVerbs: TStrings read GetObjectVerbs;
property OleClassName: string read GetOleClassName;
property OleObject: Variant read GetOleObject;
property OleObjectInterface: IOleObject read FOleObject;
property PrimaryVerb: Integer read GetPrimaryVerb;
property SourceDoc: string read GetSourceDoc;
property State: TObjectState read GetState;
property StorageInterface: IStorage read FStorage;
published
property AllowInPlace: Boolean read FAllowInPlace write FAllowInPlace default True;
property AutoActivate: TAutoActivate read FAutoActivate write FAutoActivate default aaDoubleClick;
property AutoVerbMenu: Boolean read FAutoVerbMenu write FAutoVerbMenu default True;
property Align;
property BorderStyle: TBorderStyle read FBorderStyle write SetBorderStyle default bsSingle;
property Caption;
property Color;
property CopyOnSave: Boolean read FCopyOnSave write FCopyOnSave default True;
property Ctl3D;
property DragCursor;
property DragMode;
property Enabled;
property Iconic: Boolean read GetIconic write SetIconic stored False;
property OldStreamFormat: Boolean read FOldStreamFormat write FOldStreamFormat default False;
property ParentColor default False;
property ParentCtl3D;
property ParentShowHint;
property PopupMenu;
property ShowHint;
property SizeMode: TSizeMode read FSizeMode write SetSizeMode default smClip;
property TabOrder;
property TabStop default True;
property Visible;
property OnActivate: TNotifyEvent read FOnActivate write FOnActivate;
property OnDeactivate: TNotifyEvent read FOnDeactivate write FOnDeactivate;
property OnDragDrop;
property OnDragOver;
property OnEndDrag;
property OnEnter;
property OnExit;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property OnKeyDown;
property OnKeyPress;
property OnKeyUp;
property OnObjectMove: TObjectMoveEvent read FOnObjectMove write FOnObjectMove;
property OnResize: TNotifyEvent read FOnResize write FOnResize;
property OnStartDrag;
end;
TOleInPlaceFrame = class(IOleInPlaceFrame)
private
FOleForm: TOleForm;
public
constructor Create(OleForm: TOleForm);
function QueryInterface(const iid: TIID; var obj): HResult; override;
function AddRef: Longint; override;
function Release: Longint; override;
function GetWindow(var wnd: HWnd): HResult; override;
function ContextSensitiveHelp(fEnterMode: BOOL): HResult; override;
function GetBorder(var rectBorder: TRect): HResult; override;
function RequestBorderSpace(const borderwidths: TRect): HResult; override;
function SetBorderSpace(pborderwidths: PRect): HResult; override;
function SetActiveObject(activeObject: IOleInPlaceActiveObject;
pszObjName: POleStr): HResult; override;
function InsertMenus(hmenuShared: HMenu;
var menuWidths: TOleMenuGroupWidths): HResult; override;
function SetMenu(hmenuShared: HMenu; holemenu: HMenu;
hwndActiveObject: HWnd): HResult; override;
function RemoveMenus(hmenuShared: HMenu): HResult; override;
function SetStatusText(pszStatusText: POleStr): HResult; override;
function EnableModeless(fEnable: BOOL): HResult; override;
function TranslateAccelerator(var msg: TMsg; wID: Word): HResult; override;
end;
TOleForm = class(TOleFormObject)
private
FRefCount: Integer;
FForm: TForm;
FOleInPlaceFrame: TOleInPlaceFrame;
FContainers: TList;
FActiveObject: IOleInPlaceActiveObject;
FSaveWidth: Integer;
FSaveHeight: Integer;
FHiddenControls: TList;
FSpacers: array[0..3] of TControl;
function AddRef: Longint;
function BorderSpaceAvailable(const BorderWidths: TRect): Boolean;
procedure ClearBorderSpace;
procedure GetBorder(var BorderRect: TRect);
function IsSpacer(Control: TControl): Boolean;
function IsToolControl(Control: TControl): Boolean;
function Release: Longint;
procedure SetActiveObject(ActiveObject: IOleInPlaceActiveObject);
function SetBorderSpace(const BorderWidths: TRect): Boolean;
protected
procedure OnDestroy; override;
procedure OnResize; override;
public
constructor Create(Form: TForm);
destructor Destroy; override;
end;
procedure DestroyMetaPict(MetaPict: HGlobal);
implementation
uses OleConst;
const
DataFormatCount = 2;
StreamSignature = $434F4442; {'BDOC'}
type
TStreamHeader = record
case Integer of
0: ( { New }
Signature: Integer;
DrawAspect: Integer;
DataSize: Integer);
1: ( { Old }
PartRect: TSmallRect);
end;
{ Private variables }
var
PixPerInch: TPoint;
CFObjectDescriptor: Integer;
CFEmbeddedObject: Integer;
CFLinkSource: Integer;
DataFormats: array[0..DataFormatCount - 1] of TFormatEtc;
{ Release an object reference }
procedure ReleaseObject(var Obj);
begin
if IUnknown(Obj) <> nil then
begin
IUnknown(Obj).Release;
IUnknown(Obj) := nil;
end;
end;
{ Return length of PWideChar string }
function WStrLen(Str: PWideChar): Integer;
begin
Result := 0;
while Str[Result] <> #0 do Inc(Result);
end;
{ Convert point from pixels to himetric }
function PixelsToHimetric(const P: TPoint): TPoint;
begin
Result.X := MulDiv(P.X, 2540, PixPerInch.X);
Result.Y := MulDiv(P.Y, 2540, PixPerInch.Y);
end;
{ Convert point from himetric to pixels }
function HimetricToPixels(const P: TPoint): TPoint;
begin
Result.X := MulDiv(P.X, PixPerInch.X, 2540);
Result.Y := MulDiv(P.Y, PixPerInch.Y, 2540);
end;
{ Center the given window on the screen }
procedure CenterWindow(Wnd: HWnd);
var
Rect: TRect;
begin
GetWindowRect(Wnd, Rect);
SetWindowPos(Wnd, 0,
(GetSystemMetrics(SM_CXSCREEN) - Rect.Right + Rect.Left) div 2,
(GetSystemMetrics(SM_CYSCREEN) - Rect.Bottom + Rect.Top) div 3,
0, 0, SWP_NOACTIVATE or SWP_NOSIZE or SWP_NOZORDER);
end;
{ Generic dialog hook. Centers the dialog on the screen in response to
the WM_INITDIALOG message }
function OleDialogHook(Wnd: HWnd; Msg, WParam, LParam: Longint): Longint; stdcall;
begin
Result := 0;
if Msg = WM_INITDIALOG then
begin
if GetWindowLong(Wnd, GWL_STYLE) and WS_CHILD <> 0 then
Wnd := GetWindowLong(Wnd, GWL_HWNDPARENT);
CenterWindow(Wnd);
Result := 1;
end;
end;
{ Destroy a metafile picture }
procedure DestroyMetaPict(MetaPict: HGlobal);
begin
if MetaPict <> 0 then
begin
DeleteMetaFile(PMetaFilePict(GlobalLock(MetaPict))^.hMF);
GlobalUnlock(MetaPict);
GlobalFree(MetaPict);
end;
end;
{ Shade rectangle }
procedure ShadeRect(DC: HDC; const Rect: TRect);
const
HatchBits: array[0..7] of Word = ($11, $22, $44, $88, $11, $22, $44, $88);
var
Bitmap: HBitmap;
SaveBrush: HBrush;
SaveTextColor, SaveBkColor: TColorRef;
begin
Bitmap := CreateBitmap(8, 8, 1, 1, @HatchBits);
SaveBrush := SelectObject(DC, CreatePatternBrush(Bitmap));
SaveTextColor := SetTextColor(DC, clWhite);
SaveBkColor := SetBkColor(DC, clBlack);
with Rect do PatBlt(DC, Left, Top, Right - Left, Bottom - Top, $00A000C9);
SetBkColor(DC, SaveBkColor);
SetTextColor(DC, SaveTextColor);
DeleteObject(SelectObject(DC, SaveBrush));
DeleteObject(Bitmap);
end;
{ Return the first piece of a moniker }
function OleStdGetFirstMoniker(Moniker: IMoniker): IMoniker;
var
Mksys: Longint;
EnumMoniker: IEnumMoniker;
begin
Result := nil;
if Moniker <> nil then
begin
if (Moniker.IsSystemMoniker(Mksys) = 0) and
(Mksys = MKSYS_GENERICCOMPOSITE) then
begin
if Moniker.Enum(True, EnumMoniker) <> 0 then Exit;
EnumMoniker.Next(1, Result, nil);
EnumMoniker.Release;
end else
begin
Moniker.AddRef;
Result := Moniker;
end;
end;
end;
{ Return length of file moniker piece of the given moniker }
function OleStdGetLenFilePrefixOfMoniker(Moniker: IMoniker): Integer;
var
MkFirst: IMoniker;
BindCtx: IBindCtx;
Mksys: Longint;
P: PWideChar;
begin
Result := 0;
if Moniker <> nil then
begin
MkFirst := OleStdGetFirstMoniker(Moniker);
if MkFirst <> nil then
begin
if (MkFirst.IsSystemMoniker(Mksys) = 0) and
(Mksys = MKSYS_FILEMONIKER) then
begin
if CreateBindCtx(0, BindCtx) = 0 then
begin
if (MkFirst.GetDisplayName(BindCtx, nil, P) = 0) and (P <> nil) then
begin
Result := WStrLen(P);
CoTaskMemFree(P);
end;
BindCtx.Release;
end;
end;
MkFirst.Release;
end;
end;
end;
function CoAllocCStr(const S: string): PChar;
begin
Result := StrCopy(CoTaskMemAlloc(Length(S) + 1), PChar(S));
end;
function WStrToString(P: PWideChar): string;
begin
Result := '';
if P <> nil then
begin
Result := WideCharToString(P);
CoTaskMemFree(P);
end;
end;
function GetFullNameStr(OleObject: IOleObject): string;
var
P: PWideChar;
begin
OleObject.GetUserType(USERCLASSTYPE_FULL, P);
Result := WStrToString(P);
end;
function GetShortNameStr(OleObject: IOleObject): string;
var
P: PWideChar;
begin
OleObject.GetUserType(USERCLASSTYPE_SHORT, P);
Result := WStrToString(P);
end;
function GetDisplayNameStr(OleLink: IOleLink): string;
var
P: PWideChar;
begin
OleLink.GetSourceDisplayName(P);
Result := WStrToString(P);
end;
function GetOleForm(Form: TForm): TOleForm;
begin
if Form.OleFormObject = nil then
Form.OleFormObject := TOleForm.Create(Form);
Result := TOleForm(Form.OleFormObject);
end;
{ TOleUIObjInfo - helper interface for Object Properties dialog }
type
TOleUIObjInfo = class(iOleUIObjInfo)
private
FContainer: TOleContainer;
public
constructor Create(Container: TOleContainer);
function QueryInterface(const iid: TIID; var obj): HResult; override;
function AddRef: Longint; override;
function Release: Longint; override;
function GetObjectInfo(dwObject: Longint;
var dwObjSize: Longint; var lpszLabel: PChar;
var lpszType: PChar; var lpszShortType: PChar;
var lpszLocation: PChar): HResult; override;
function GetConvertInfo(dwObject: Longint; var ClassID: TCLSID;
var wFormat: Word; var ConvertDefaultClassID: TCLSID;
var lpClsidExclude: PCLSID; var cClsidExclude: Longint): HResult; override;
function ConvertObject(dwObject: Longint;
const clsidNew: TCLSID): HResult; override;
function GetViewInfo(dwObject: Longint; var hMetaPict: HGlobal;
var dvAspect: Longint; var nCurrentScale: Integer): HResult; override;
function SetViewInfo(dwObject: Longint; hMetaPict: HGlobal;
dvAspect: Longint; nCurrentScale: Integer;
bRelativeToOrig: BOOL): HResult; override;
end;
constructor TOleUIObjInfo.Create(Container: TOleContainer);
begin
FContainer := Container;
end;
function TOleUIObjInfo.QueryInterface(const iid: TIID; var obj): HResult;
begin
Pointer(obj) := nil;
Result := E_NOINTERFACE;
end;
function TOleUIObjInfo.AddRef: Longint;
begin
Result := 0;
end;
function TOleUIObjInfo.Release: Longint;
begin
Result := 0;
end;
function TOleUIObjInfo.GetObjectInfo(dwObject: Longint;
var dwObjSize: Longint; var lpszLabel: PChar;
var lpszType: PChar; var lpszShortType: PChar;
var lpszLocation: PChar): HResult;
begin
with FContainer do
begin
if @dwObjSize <> nil then
dwObjSize := GetObjectDataSize;
if @lpszLabel <> nil then
lpszLabel := CoAllocCStr(GetFullNameStr(FOleObject));
if @lpszType <> nil then
lpszType := CoAllocCStr(GetFullNameStr(FOleObject));
if @lpszShortType <> nil then
lpszShortType := CoAllocCStr(GetShortNameStr(FOleObject));
if @lpszLocation <> nil then
lpszLocation := CoAllocCStr(Caption);
end;
Result := S_OK;
end;
function TOleUIObjInfo.GetConvertInfo(dwObject: Longint; var ClassID: TCLSID;
var wFormat: Word; var ConvertDefaultClassID: TCLSID;
var lpClsidExclude: PCLSID; var cClsidExclude: Longint): HResult;
begin
FContainer.FOleObject.GetUserClassID(ClassID);
Result := S_OK;
end;
function TOleUIObjInfo.ConvertObject(dwObject: Longint;
const clsidNew: TCLSID): HResult;
begin
Result := E_NOTIMPL;
end;
function TOleUIObjInfo.GetViewInfo(dwObject: Longint; var hMetaPict: HGlobal;
var dvAspect: Longint; var nCurrentScale: Integer): HResult;
begin
with FContainer do
begin
if @hMetaPict <> nil then hMetaPict := GetIconMetaPict;
if @dvAspect <> nil then dvAspect := FDrawAspect;
if @nCurrentScale <> nil then nCurrentScale := 0;
end;
Result := S_OK;
end;
function TOleUIObjInfo.SetViewInfo(dwObject: Longint; hMetaPict: HGlobal;
dvAspect: Longint; nCurrentScale: Integer;
bRelativeToOrig: BOOL): HResult;
var
ShowAsIcon: Boolean;
begin
case dvAspect of
DVASPECT_CONTENT: ShowAsIcon := False;
DVASPECT_ICON: ShowAsIcon := True;
else
ShowAsIcon := FContainer.Iconic;
end;
FContainer.SetDrawAspect(ShowAsIcon, hMetaPict);
Result := S_OK;
end;
{ TOleUILinkInfo - helper interface for Object Properties dialog }
type
TOleUILinkInfo = class(iOleUILinkInfo)
private
FContainer: TOleContainer;
FOleLink: IOleLink;
public
constructor Create(Container: TOleContainer);
destructor Destroy; override;
function QueryInterface(const iid: TIID; var obj): HResult; override;
function AddRef: Longint; override;
function Release: Longint; override;
function GetNextLink(dwLink: Longint): Longint; override;
function SetLinkUpdateOptions(dwLink: Longint;
dwUpdateOpt: Longint): HResult; override;
function GetLinkUpdateOptions(dwLink: Longint;
var dwUpdateOpt: Longint): HResult; override;
function SetLinkSource(dwLink: Longint; pszDisplayName: PChar;
lenFileName: Longint; var chEaten: Longint;
fValidateSource: BOOL): HResult; override;
function GetLinkSource(dwLink: Longint; var pszDisplayName: PChar;
var lenFileName: Longint; var pszFullLinkType: PChar;
var pszShortLinkType: PChar; var fSourceAvailable: BOOL;
var fIsSelected: BOOL): HResult; override;
function OpenLinkSource(dwLink: Longint): HResult; override;
function UpdateLink(dwLink: Longint; fErrorMessage: BOOL;
fErrorAction: BOOL): HResult; override;
function CancelLink(dwLink: Longint): HResult; override;
function GetLastUpdate(dwLink: Longint;
var LastUpdate: TFileTime): HResult; override;
end;
procedure LinkError(Ident: Integer);
begin
Application.MessageBox(PChar(LoadStr(Ident)),
PChar(LoadStr(SLinkProperties)), MB_OK or MB_ICONSTOP);
end;
constructor TOleUILinkInfo.Create(Container: TOleContainer);
begin
FContainer := Container;
OleCheck(FContainer.FOleObject.QueryInterface(IID_IOleLink, FOleLink));
end;
destructor TOleUILinkInfo.Destroy;
begin
FOleLink.Release;
end;
function TOleUILinkInfo.QueryInterface(const iid: TIID; var obj): HResult;
begin
Pointer(obj) := nil;
Result := E_NOINTERFACE;
end;
function TOleUILinkInfo.AddRef: Longint;
begin
Result := 0;
end;
function TOleUILinkInfo.Release: Longint;
begin
Result := 0;
end;
function TOleUILinkInfo.GetNextLink(dwLink: Longint): Longint;
begin
if dwLink = 0 then Result := Longint(FContainer) else Result := 0;
end;
function TOleUILinkInfo.SetLinkUpdateOptions(dwLink: Longint;
dwUpdateOpt: Longint): HResult;
begin
Result := FOleLink.SetUpdateOptions(dwUpdateOpt);
if Result >= 0 then FContainer.ObjectModified;
end;
function TOleUILinkInfo.GetLinkUpdateOptions(dwLink: Longint;
var dwUpdateOpt: Longint): HResult;
begin
Result := FOleLink.GetUpdateOptions(dwUpdateOpt);
end;
function TOleUILinkInfo.SetLinkSource(dwLink: Longint; pszDisplayName: PChar;
lenFileName: Longint; var chEaten: Longint;
fValidateSource: BOOL): HResult;
var
DisplayName: string;
Buffer: array[0..255] of WideChar;
begin
Result := E_FAIL;
if fValidateSource then
begin
DisplayName := pszDisplayName;
if FOleLink.SetSourceDisplayName(StringToWideChar(DisplayName,
Buffer, SizeOf(Buffer) div 2)) >= 0 then
begin
chEaten := Length(DisplayName);
try
FContainer.UpdateObject;
except
Application.HandleException(FContainer);
end;
Result := S_OK;
end;
end else
LinkError(SInvalidLinkSource);
end;
function TOleUILinkInfo.GetLinkSource(dwLink: Longint; var pszDisplayName: PChar;
var lenFileName: Longint; var pszFullLinkType: PChar;
var pszShortLinkType: PChar; var fSourceAvailable: BOOL;
var fIsSelected: BOOL): HResult;
var
Moniker: IMoniker;
begin
with FContainer do
begin
if @pszDisplayName <> nil then
pszDisplayName := CoAllocCStr(GetDisplayNameStr(FOleLink));
if @lenFileName <> nil then
begin
lenFileName := 0;
FOleLink.GetSourceMoniker(Moniker);
if Moniker <> nil then
begin
lenFileName := OleStdGetLenFilePrefixOfMoniker(Moniker);
Moniker.Release;
end;
end;
if @pszFullLinkType <> nil then
pszFullLinkType := CoAllocCStr(GetFullNameStr(FOleObject));
if @pszShortLinkType <> nil then
pszShortLinkType := CoAllocCStr(GetShortNameStr(FOleObject));
end;
Result := S_OK;
end;
function TOleUILinkInfo.OpenLinkSource(dwLink: Longint): HResult;
begin
try
FContainer.DoVerb(ovShow);
except
Application.HandleException(FContainer);
end;
Result := S_OK;
end;
function TOleUILinkInfo.UpdateLink(dwLink: Longint; fErrorMessage: BOOL;
fErrorAction: BOOL): HResult;
begin
try
FContainer.UpdateObject;
except
Application.HandleException(FContainer);
end;
Result := S_OK;
end;
function TOleUILinkInfo.CancelLink(dwLink: Longint): HResult;
begin
LinkError(SCannotBreakLink);
Result := E_NOTIMPL;
end;
function TOleUILinkInfo.GetLastUpdate(dwLink: Longint;
var LastUpdate: TFileTime): HResult;
begin
Result := S_OK;
end;
{ TEnumFormatEtc - format enumerator for TDataObject }
type
PFormatList = ^TFormatList;
TFormatList = array[0..255] of TFormatEtc;
type
TEnumFormatEtc = class(IEnumFormatEtc)
private
FRefCount: Integer;
FFormatList: PFormatList;
FFormatCount: Integer;
FIndex: Integer;
public
constructor Create(FormatList: PFormatList; FormatCount, Index: Integer);
function QueryInterface(const iid: TIID; var obj): HResult; override;
function AddRef: Longint; override;
function Release: Longint; override;
function Next(celt: Longint; var elt;
pceltFetched: PLongint): HResult; override;
function Skip(celt: Longint): HResult; override;
function Reset: HResult; override;
function Clone(var enum: IEnumFormatEtc): HResult; override;
end;
constructor TEnumFormatEtc.Create(FormatList: PFormatList;
FormatCount, Index: Integer);
begin
FRefCount := 1;
FFormatList := FormatList;
FFormatCount := FormatCount;
FIndex := Index;
end;
function TEnumFormatEtc.QueryInterface(const iid: TIID; var obj): HResult;
begin
if IsEqualIID(iid, IID_IUnknown) or IsEqualIID(iid, IID_IEnumFormatEtc) then
begin
Pointer(obj) := Self;
AddRef;
Result := S_OK;
end else
begin
Pointer(obj) := nil;
Result := E_NOINTERFACE;
end;
end;
function TEnumFormatEtc.AddRef: Longint;
begin
Inc(FRefCount);
Result := FRefCount;
end;
function TEnumFormatEtc.Release: Longint;
begin
Dec(FRefCount);
Result := FRefCount;
if FRefCount = 0 then Free;
end;
function TEnumFormatEtc.Next(celt: Longint; var elt;
pceltFetched: PLongint): HResult;
var
I: Integer;
begin
I := 0;
while (I < celt) and (FIndex < FFormatCount) do
begin
TFormatList(elt)[I] := FFormatList[FIndex];
Inc(FIndex);
Inc(I);
end;
if pceltFetched <> nil then pceltFetched^ := I;
if I = celt then Result := S_OK else Result := S_FALSE;
end;
function TEnumFormatEtc.Skip(celt: Longint): HResult;
begin
if celt <= FFormatCount - FIndex then
begin
FIndex := FIndex + celt;
Result := S_OK;
end else
begin
FIndex := FFormatCount;
Result := S_FALSE;
end;
end;
function TEnumFormatEtc.Reset: HResult;
begin
FIndex := 0;
Result := S_OK;
end;
function TEnumFormatEtc.Clone(var enum: IEnumFormatEtc): HResult;
begin
enum := TEnumFormatEtc.Create(FFormatList, FFormatCount, FIndex);
Result := S_OK;
end;
{ TDataObject - data object for use in clipboard transfers }
type
TDataObject = class(IDataObject)
private
FRefCount: Integer;
FOleObject: IOleObject;
function GetObjectDescriptor: HGlobal;
public
constructor Create(OleObject: IOleObject);
destructor Destroy; override;
function QueryInterface(const iid: TIID; var obj): HResult; override;
function AddRef: Longint; override;
function Release: Longint; override;
function GetData(var formatetcIn: TFormatEtc;
var medium: TStgMedium): HResult; override;
function GetDataHere(var formatetc: TFormatEtc;
var medium: TStgMedium): HResult; override;
function QueryGetData(var formatetc: TFormatEtc): HResult; override;
function GetCanonicalFormatEtc(var formatetc: TFormatEtc;
var formatetcOut: TFormatEtc): HResult; override;
function SetData(var formatetc: TFormatEtc; var medium: TStgMedium;
fRelease: BOOL): HResult; override;
function EnumFormatEtc(dwDirection: Longint; var enumFormatEtc:
IEnumFormatEtc): HResult; override;
function DAdvise(var formatetc: TFormatEtc; advf: Longint;
advSink: IAdviseSink; var dwConnection: Longint): HResult; override;
function DUnadvise(dwConnection: Longint): HResult; override;
function EnumDAdvise(var enumAdvise: IEnumStatData): HResult; override;
end;
constructor TDataObject.Create(OleObject: IOleObject);
begin
FRefCount := 1;
FOleObject := OleObject;
FOleObject.AddRef;
end;
destructor TDataObject.Destroy;
begin
FOleObject.Release;
end;
function TDataObject.GetObjectDescriptor: HGlobal;
var
DescSize: Integer;
Descriptor: PObjectDescriptor;
UserTypeName, SourceOfCopy: string;
OleLink: IOleLink;
begin
UserTypeName := GetFullNameStr(FOleObject);
SourceOfCopy := UserTypeName;
FOleObject.QueryInterface(IID_IOleLink, OleLink);
if OleLink <> nil then
begin
UserTypeName := FmtLoadStr(SLinkedObject, [UserTypeName]);
SourceOfCopy := GetDisplayNameStr(OleLink);
OleLink.Release;
end;
DescSize := SizeOf(TObjectDescriptor) +
MultiByteToWideChar(0, 0, PChar(UserTypeName),
Length(UserTypeName), nil, 0) +
MultiByteToWideChar(0, 0, PChar(SourceOfCopy),
Length(SourceOfCopy), nil, 0) + 4;
Result := GlobalAlloc(GMEM_MOVEABLE, DescSize);
if Result <> 0 then
begin
Descriptor := GlobalLock(Result);
FillChar(Descriptor^, 0, DescSize);
with Descriptor^ do
begin
cbSize := DescSize;
FOleObject.GetUserClassID(clsid);
dwDrawAspect := DVASPECT_CONTENT;
FOleObject.GetMiscStatus(DVASPECT_CONTENT, dwStatus);
dwFullUserTypeName := SizeOf(TObjectDescriptor);
StringToWideChar(UserTypeName, PWideChar(Integer(Descriptor) +
dwFullUserTypeName), 256);
dwSrcOfCopy := SizeOf(TObjectDescriptor) +
MultiByteToWideChar(0, 0, PChar(UserTypeName),
Length(UserTypeName), nil, 0) + 2;
StringToWideChar(SourceOfCopy, PWideChar(Integer(Descriptor) +
dwSrcOfCopy), 256);
end;
GlobalUnlock(Result);
end;
end;
function TDataObject.QueryInterface(const iid: TIID; var obj): HResult;
begin
if IsEqualIID(iid, IID_IUnknown) or IsEqualIID(iid, IID_IDataObject) then
begin
Pointer(obj) := Self;
AddRef;
Result := S_OK;
end else
begin
Pointer(obj) := nil;
Result := E_NOINTERFACE;
end;
end;
function TDataObject.AddRef: Longint;
begin
Inc(FRefCount);
Result := FRefCount;
end;
function TDataObject.Release: Longint;
begin
Dec(FRefCount);
Result := FRefCount;
if FRefCount = 0 then Free;
end;
function TDataObject.GetData(var formatetcIn: TFormatEtc;
var medium: TStgMedium): HResult;
var
Descriptor: HGlobal;
begin
Result := DV_E_FORMATETC;
medium.tymed := 0;
medium.hGlobal := 0;
medium.unkForRelease := nil;
with formatetcIn do
begin
if (cfFormat = CFObjectDescriptor) and (dwAspect = DVASPECT_CONTENT) and
(tymed = TYMED_HGLOBAL) then
begin
Descriptor := GetObjectDescriptor;
if Descriptor <> 0 then
begin
medium.tymed := TYMED_HGLOBAL;
medium.hGlobal := Descriptor;
Result := S_OK;
end;
end;
end;
end;
function TDataObject.GetDataHere(var formatetc: TFormatEtc;
var medium: TStgMedium): HResult;
var
PersistStorage: IPersistStorage;
begin
Result := DV_E_FORMATETC;
with formatetc do
if (cfFormat = CFEmbeddedObject) and (dwAspect = DVASPECT_CONTENT) and
(tymed = TYMED_ISTORAGE) then
begin
medium.unkForRelease := nil;
FOleObject.QueryInterface(IID_IPersistStorage, PersistStorage);
if PersistStorage <> nil then
begin
Result := OleSave(PersistStorage, medium.stg, False);
PersistStorage.SaveCompleted(nil);
PersistStorage.Release;
end;
end;
end;
function TDataObject.QueryGetData(var formatetc: TFormatEtc): HResult;
begin
Result := DV_E_FORMATETC;
with formatetc do
if dwAspect = DVASPECT_CONTENT then
if (cfFormat = CFEmbeddedObject) and (tymed = TYMED_ISTORAGE) or
(cfFormat = CFObjectDescriptor) and (tymed = TYMED_HGLOBAL) then
Result := S_OK;
end;
function TDataObject.GetCanonicalFormatEtc(var formatetc: TFormatEtc;
var formatetcOut: TFormatEtc): HResult;
begin
formatetcOut.ptd := nil;
Result := E_NOTIMPL;
end;
function TDataObject.SetData(var formatetc: TFormatEtc; var medium: TStgMedium;
fRelease: BOOL): HResult;
begin
Result := E_NOTIMPL;
end;
function TDataObject.EnumFormatEtc(dwDirection: Longint; var enumFormatEtc:
IEnumFormatEtc): HResult;
begin
if dwDirection = DATADIR_GET then
begin
enumFormatEtc := TEnumFormatEtc.Create(@DataFormats, DataFormatCount, 0);
Result := S_OK;
end else
begin
enumFormatEtc := nil;
Result := E_NOTIMPL;
end;
end;
function TDataObject.DAdvise(var formatetc: TFormatEtc; advf: Longint;
advSink: IAdviseSink; var dwConnection: Longint): HResult;
begin
Result := OLE_E_ADVISENOTSUPPORTED;
end;
function TDataObject.DUnadvise(dwConnection: Longint): HResult;
begin
Result := OLE_E_ADVISENOTSUPPORTED;
end;
function TDataObject.EnumDAdvise(var enumAdvise: IEnumStatData): HResult;
begin
Result := OLE_E_ADVISENOTSUPPORTED;
end;
{ TOleClientSite }
constructor TOleClientSite.Create(Container: TOleContainer);
begin
FContainer := Container;
end;
function TOleClientSite.QueryInterface(const iid: TIID; var obj): HResult;
begin
Result := FContainer.QueryInterface(iid, obj);
end;
function TOleClientSite.AddRef: Longint;
begin
Result := FContainer.AddRef;
end;
function TOleClientSite.Release: Longint;
begin
Result := FContainer.Release;
end;
function TOleClientSite.SaveObject: HResult;
begin
FContainer.SaveObject;
Result := S_OK;
end;
function TOleClientSite.GetMoniker(dwAssign: Longint; dwWhichMoniker: Longint;
var mk: IMoniker): HResult;
begin
mk := nil;
Result := E_NOTIMPL;
end;
function TOleClientSite.GetContainer(var container: IOleContainer): HResult;
begin
container := nil;
Result := E_NOTIMPL;
end;
function TOleClientSite.ShowObject: HResult;
begin
Result := S_OK;
end;
function TOleClientSite.OnShowWindow(fShow: BOOL): HResult;
begin
FContainer.ObjectShowWindow(fShow);
Result := S_OK;
end;
function TOleClientSite.RequestNewObjectLayout: HResult;
begin
Result := E_NOTIMPL;
end;
{ TOleInPlaceSite }
constructor TOleInPlaceSite.Create(Container: TOleContainer);
begin
FContainer := Container;
end;
function TOleInPlaceSite.QueryInterface(const iid: TIID; var obj): HResult;
begin
Result := FContainer.QueryInterface(iid, obj);
end;
function TOleInPlaceSite.AddRef: Longint;
begin
Result := FContainer.AddRef;
end;
function TOleInPlaceSite.Release: Longint;
begin
Result := FContainer.Release;
end;
function TOleInPlaceSite.GetWindow(var wnd: HWnd): HResult;
begin
wnd := FContainer.Parent.Handle;
Result := S_OK;
end;
function TOleInPlaceSite.ContextSensitiveHelp(fEnterMode: BOOL): HResult;
begin
Result := S_OK;
end;
function TOleInPlaceSite.CanInPlaceActivate: HResult;
begin
with FContainer do
if not (csDesigning in ComponentState) and Visible and
AllowInPlace and not Iconic then
Result := S_OK else
Result := S_FALSE;
end;
function TOleInPlaceSite.OnInPlaceActivate: HResult;
begin
with FContainer do
begin
FOleObject.QueryInterface(IID_IOleInPlaceObject, FOleInPlaceObject);
FOleObject.QueryInterface(IID_IOleInPlaceActiveObject, FOleInPlaceActiveObject);
end;
Result := S_OK;
end;
function TOleInPlaceSite.OnUIActivate: HResult;
begin
FContainer.SetUIActive(True);
Result := S_OK;
end;
function TOleInPlaceSite.GetWindowContext(var frame: IOleInPlaceFrame;
var doc: IOleInPlaceUIWindow; var rcPosRect: TRect;
var rcClipRect: TRect; var frameInfo: TOleInPlaceFrameInfo): HResult;
var
Origin: TPoint;
begin
with FContainer do
begin
frame := FFrameForm.FOleInPlaceFrame;
frame.AddRef;
doc := nil;
Origin := Parent.ScreenToClient(ClientOrigin);
SetRect(rcPosRect, Origin.X, Origin.Y,
Origin.X + ClientWidth, Origin.Y + ClientHeight);
SetRect(rcClipRect, -16384, -16384, 16383, 16383);
CreateAccelTable;
with frameInfo do
begin
fMDIApp := False;
hWndFrame := FFrameForm.FForm.Handle;
hAccel := FAccelTable;
cAccelEntries := FAccelCount;
end;
end;
Result := S_OK;
end;
function TOleInPlaceSite.Scroll(const scrollExtent: TPoint): HResult;
begin
Result := E_NOTIMPL;
end;
function TOleInPlaceSite.OnUIDeactivate(fUndoable: BOOL): HResult;
begin
FContainer.FFrameForm.FOleInPlaceFrame.SetMenu(0, 0, 0);
FContainer.FFrameForm.ClearBorderSpace;
FContainer.SetUIActive(False);
Result := S_OK;
end;
function TOleInPlaceSite.OnInPlaceDeactivate: HResult;
begin
ReleaseObject(FContainer.FOleInPlaceActiveObject);
ReleaseObject(FContainer.FOleInPlaceObject);
Result := S_OK;
end;
function TOleInPlaceSite.DiscardUndoState: HResult;
begin
Result := E_NOTIMPL;
end;
function TOleInPlaceSite.DeactivateAndUndo: HResult;
begin
FContainer.FOleInPlaceObject.UIDeactivate;
Result := S_OK;
end;
function TOleInPlaceSite.OnPosRectChange(const rcPosRect: TRect): HResult;
begin
try
FContainer.ObjectMoved(rcPosRect);
FContainer.UpdateObjectRect;
except
Application.HandleException(Self);
end;
Result := S_OK;
end;
{ TAdviseSink }
constructor TAdviseSink.Create(Container: TOleContainer);
begin
FContainer := Container;
end;
function TAdviseSink.QueryInterface(const iid: TIID; var obj): HResult;
begin
Result := FContainer.QueryInterface(iid, obj);
end;
function TAdviseSink.AddRef: Longint;
begin
Result := FContainer.AddRef;
end;
function TAdviseSink.Release: Longint;
begin
Result := FContainer.Release;
end;
procedure TAdviseSink.OnDataChange(var formatetc: TFormatEtc; var stgmed: TStgMedium);
begin
FContainer.ObjectModified;
end;
procedure TAdviseSink.OnViewChange(dwAspect: Longint; lindex: Longint);
begin
FContainer.ObjectViewChange(dwAspect);
end;
procedure TAdviseSink.OnRename(mk: IMoniker);
begin
end;
procedure TAdviseSink.OnSave;
begin
end;
procedure TAdviseSink.OnClose;
begin
end;
{ TOleContainer }
constructor TOleContainer.Create(AOwner: TComponent);
const
ContainerStyle = [csClickEvents, csSetCaption, csOpaque, csDoubleClicks];
begin
inherited Create(AOwner);
if NewStyleControls then
ControlStyle := ContainerStyle else
ControlStyle := ContainerStyle + [csFramed];
Width := 121;
Height := 121;
TabStop := True;
ParentColor := False;
FAllowInPlace := True;
FAutoActivate := aaDoubleClick;
FAutoVerbMenu := True;
FBorderStyle := bsSingle;
FCopyOnSave := True;
FOleClientSite := TOleClientSite.Create(Self);
FOleInPlaceSite := TOleInPlaceSite.Create(Self);
FAdviseSink := TAdviseSink.Create(Self);
FDrawAspect := DVASPECT_CONTENT;
end;
destructor TOleContainer.Destroy;
begin
DestroyObject;
FAdviseSink.Free;
FOleInPlaceSite.Free;
FOleClientSite.Free;
inherited Destroy;
end;
function TOleContainer.AddRef: Longint;
begin
Inc(FRefCount);
Result := FRefCount;
end;
procedure TOleContainer.AdjustBounds;
var
Size: TPoint;
Extra: Integer;
begin
if not (csReading in ComponentState) and (FSizeMode = smAutoSize) and
(FOleObject <> nil) then
begin
Size := HimetricToPixels(FViewSize);
Extra := GetBorderWidth * 2;
SetBounds(Left, Top, Size.X + Extra, Size.Y + Extra);
end;
end;
function TOleContainer.ChangeIconDialog: Boolean;
var
Data: TOleUIChangeIcon;
begin
CheckObject;
Result := False;
FillChar(Data, SizeOf(Data), 0);
Data.cbStruct := SizeOf(Data);
Data.dwFlags := CIF_SELECTCURRENT;
Data.hWndOwner := Application.Handle;
Data.lpfnHook := OleDialogHook;
OleCheck(FOleObject.GetUserClassID(Data.clsid));
Data.hMetaPict := GetIconMetaPict;
try
if OleUIChangeIcon(Data) = OLEUI_OK then
begin
SetDrawAspect(True, Data.hMetaPict);
Result := True;
end;
finally
DestroyMetaPict(Data.hMetaPict);
end;
end;
procedure TOleContainer.CheckObject;
begin
if FOleObject = nil then
raise EOleError.CreateRes(SEmptyContainer);
end;
procedure TOleContainer.Close;
begin
CheckObject;
OleCheck(FOleObject.Close(OLECLOSE_SAVEIFDIRTY));
end;
procedure TOleContainer.Copy;
begin
Close;
OleCheck(OleSetClipboard(TDataObject.Create(FOleObject)));
end;
procedure TOleContainer.CreateAccelTable;
var
Menu: TMainMenu;
begin
if FAccelTable = 0 then
begin
Menu := FFrameForm.FForm.Menu;
if Menu <> nil then
Menu.GetOle2AcceleratorTable(FAccelTable, FAccelCount, [0, 2, 4]);
end;
end;
procedure TOleContainer.CreateLinkToFile(const FileName: string;
Iconic: Boolean);
var
CreateInfo: TCreateInfo;
begin
CreateInfo.CreateType := ctLinkToFile;
CreateInfo.ShowAsIcon := Iconic;
CreateInfo.IconMetaPict := 0;
CreateInfo.FileName := FileName;
CreateObjectFromInfo(CreateInfo);
end;
procedure TOleContainer.CreateObject(const OleClassName: string;
Iconic: Boolean);
var
CreateInfo: TCreateInfo;
begin
CreateInfo.CreateType := ctNewObject;
CreateInfo.ShowAsIcon := Iconic;
CreateInfo.IconMetaPict := 0;
CreateInfo.ClassID := ProgIDToClassID(OleClassName);
CreateObjectFromInfo(CreateInfo);
end;
procedure TOleContainer.CreateObjectFromFile(const FileName: string;
Iconic: Boolean);
var
CreateInfo: TCreateInfo;
begin
CreateInfo.CreateType := ctFromFile;
CreateInfo.ShowAsIcon := Iconic;
CreateInfo.IconMetaPict := 0;
CreateInfo.FileName := FileName;
CreateObjectFromInfo(CreateInfo);
end;
procedure TOleContainer.CreateObjectFromInfo(const CreateInfo: TCreateInfo);
var
Buffer: array[0..255] of WideChar;
begin
DestroyObject;
try
CreateStorage;
with CreateInfo do
begin
case CreateType of
ctNewObject:
OleCheck(OleCreate(ClassID, IID_IOleObject, OLERENDER_DRAW, nil,
FOleClientSite, FStorage, FOleObject));
ctFromFile:
OleCheck(OleCreateFromFile(GUID_NULL, StringToWideChar(FileName,
Buffer, SizeOf(Buffer) div 2), IID_IOleObject, OLERENDER_DRAW,
nil, FOleClientSite, FStorage, FOleObject));
ctLinkToFile:
OleCheck(OleCreateLinkToFile(StringToWideChar(FileName, Buffer,
SizeOf(Buffer) div 2), IID_IOleObject, OLERENDER_DRAW, nil,
FOleClientSite, FStorage, FOleObject));
ctFromData:
OleCheck(OleCreateFromData(DataObject, IID_IOleObject,
OLERENDER_DRAW, nil, FOleClientSite, FStorage, FOleObject));
ctLinkFromData:
OleCheck(OleCreateLinkFromData(DataObject, IID_IOleObject,
OLERENDER_DRAW, nil, FOleClientSite, FStorage, FOleObject));
end;
FDrawAspect := DVASPECT_CONTENT;
InitObject;
FOleObject.SetExtent(DVASPECT_CONTENT, PixelsToHimetric(
Point(ClientWidth, ClientHeight)));
SetDrawAspect(ShowAsIcon, IconMetaPict);
UpdateView;
end;
except
DestroyObject;
raise;
end;
end;
procedure TOleContainer.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
if FBorderStyle = bsSingle then
if NewStyleControls and Ctl3D then
Params.ExStyle := Params.ExStyle or WS_EX_CLIENTEDGE else
Params.Style := Params.Style or WS_BORDER;
end;
procedure TOleContainer.CreateStorage;
begin
OleCheck(CreateILockBytesOnHGlobal(0, True, FLockBytes));
OleCheck(StgCreateDocfileOnILockBytes(FLockBytes, STGM_READWRITE
or STGM_SHARE_EXCLUSIVE or STGM_CREATE, 0, FStorage));
end;
procedure TOleContainer.DblClick;
begin
if FAutoActivate = aaDoubleClick then
DoVerb(ovPrimary)
else
inherited;
end;
procedure TOleContainer.DefineProperties(Filer: TFiler);
begin
inherited DefineProperties(Filer);
Filer.DefineBinaryProperty('Data', LoadFromStream, SaveToStream,
FOleObject <> nil);
end;
procedure TOleContainer.DesignModified;
var
Form: TForm;
begin
Form := GetParentForm(Self);
if (Form <> nil) and (Form.Designer <> nil) then Form.Designer.Modified;
end;
procedure TOleContainer.DestroyAccelTable;
begin
if FAccelTable <> 0 then
begin
DestroyAcceleratorTable(FAccelTable);
FAccelTable := 0;
FAccelCount := 0;
end;
end;
procedure TOleContainer.DestroyObject;
var
DataObject: IDataObject;
begin
if FOleObject <> nil then
begin
SetViewAdviseSink(False);
if FDataConnection <> 0 then
begin
FOleObject.QueryInterface(IID_IDataObject, DataObject);
if DataObject <> nil then
begin
DataObject.DUnadvise(FDataConnection);
DataObject.Release;
end;
FDataConnection := 0;
end;
FOleObject.Close(OLECLOSE_NOSAVE);
Invalidate;
ObjectModified;
end;
ReleaseObject(FOleObject);
ReleaseObject(FStorage);
ReleaseObject(FLockBytes);
DestroyVerbs;
DestroyAccelTable;
if FDocForm <> nil then
begin
if FFrameForm <> FDocForm then FFrameForm.FContainers.Remove(Self);
FDocForm.FContainers.Remove(Self);
FFrameForm := nil;
FDocForm := nil;
end;
end;
procedure TOleContainer.DestroyVerbs;
begin
FPopupVerbMenu.Free;
FPopupVerbMenu := nil;
FObjectVerbs.Free;
FObjectVerbs := nil;
end;
procedure TOleContainer.DoEnter;
begin
if FAutoActivate = aaGetFocus then DoVerb(ovShow);
inherited;
end;
procedure TOleContainer.DoVerb(Verb: Integer);
begin
CheckObject;
if Verb >= 0 then
begin
if FObjectVerbs = nil then UpdateVerbs;
if Verb >= FObjectVerbs.Count then
raise EOleError.CreateRes(SInvalidVerb);
Verb := Smallint(Integer(FObjectVerbs.Objects[Verb]) and $0000FFFF);
end else
if Verb = ovPrimary then Verb := 0;
OleCheck(FOleObject.DoVerb(Verb, nil, FOleClientSite, 0,
Parent.Handle, BoundsRect));
end;
function TOleContainer.GetBorderWidth: Integer;
begin
if FBorderStyle = bsNone then
Result := 0
else
if NewStyleControls and Ctl3D then
Result := 2
else
Result := 1;
end;
function TOleContainer.GetCanPaste: Boolean;
var
DataObject: IDataObject;
begin
Result := False;
if OleGetClipboard(DataObject) >= 0 then
begin
if (OleQueryCreateFromData(DataObject) = 0) or
(OleQueryLinkFromData(DataObject) = 0) then Result := True;
DataObject.Release;
end;
end;
function TOleContainer.GetIconic: Boolean;
begin
Result := FDrawAspect = DVASPECT_ICON;
end;
function TOleContainer.GetIconMetaPict: HGlobal;
var
DataObject: IDataObject;
FormatEtc: TFormatEtc;
Medium: TStgMedium;
ClassID: TCLSID;
begin
CheckObject;
Result := 0;
if FDrawAspect = DVASPECT_ICON then
begin
FOleObject.QueryInterface(IID_IDataObject, DataObject);
if DataObject <> nil then
begin
FormatEtc.cfFormat := CF_METAFILEPICT;
FormatEtc.ptd := nil;
FormatEtc.dwAspect := DVASPECT_ICON;
FormatEtc.lIndex := -1;
FormatEtc.tymed := TYMED_MFPICT;
if DataObject.GetData(FormatEtc, Medium) >= 0 then
Result := Medium.hMetaFilePict;
DataObject.Release;
end;
end;
if Result = 0 then
begin
OleCheck(FOleObject.GetUserClassID(ClassID));
Result := OleGetIconOfClass(ClassID, nil, True);
end;
end;
function TOleContainer.GetLinked: Boolean;
var
OleLink: IOleLink;
begin
CheckObject;
Result := False;
FOleObject.QueryInterface(IID_IOleLink, OleLink);
if OleLink <> nil then
begin
Result := True;
OleLink.Release;
end;
end;
function TOleContainer.GetObjectDataSize: Integer;
var
DataHandle: HGlobal;
begin
if GetHGlobalFromILockBytes(FLockBytes, DataHandle) >= 0 then
Result := GlobalSize(DataHandle) else
Result := 0;
end;
function TOleContainer.GetObjectVerbs: TStrings;
begin
if FObjectVerbs = nil then UpdateVerbs;
Result := FObjectVerbs;
end;
function TOleContainer.GetOleClassName: string;
var
ClassID: TCLSID;
begin
CheckObject;
OleCheck(FOleObject.GetUserClassID(ClassID));
Result := ClassIDToProgID(ClassID);
end;
function TOleContainer.GetOleObject: Variant;
begin
CheckObject;
Result := VarFromInterface(FOleObject);
end;
function TOleContainer.GetPopupMenu: TPopupMenu;
var
I: Integer;
Item: TMenuItem;
begin
if FAutoVerbMenu and (FOleObject <> nil) and (ObjectVerbs.Count > 0) then
begin
if FPopupVerbMenu = nil then
begin
FPopupVerbMenu := TPopupMenu.Create(Self);
for I := 0 to ObjectVerbs.Count - 1 do
begin
Item := TMenuItem.Create(Self);
Item.Caption := ObjectVerbs[I];
Item.Tag := I;
Item.OnClick := PopupVerbMenuClick;
FPopupVerbMenu.Items.Add(Item);
end;
end;
Result := FPopupVerbMenu;
end else
Result := inherited GetPopupMenu;
end;
function TOleContainer.GetPrimaryVerb: Integer;
begin
if FObjectVerbs = nil then UpdateVerbs;
for Result := 0 to FObjectVerbs.Count - 1 do
if Integer(FObjectVerbs.Objects[Result]) and $0000FFFF = 0 then Exit;
Result := 0;
end;
function TOleContainer.GetSourceDoc: string;
var
OleLink: IOleLink;
begin
CheckObject;
Result := '';
FOleObject.QueryInterface(IID_IOleLink, OleLink);
if OleLink <> nil then
begin
Result := GetDisplayNameStr(OleLink);
OleLink.Release;
end;
end;
function TOleContainer.GetState: TObjectState;
begin
if FOleObject = nil then
Result := osEmpty
else if FObjectOpen then
Result := osOpen
else if FUIActive then
Result := osUIActive
else if OleIsRunning(FOleObject) then
Result := osRunning
else
Result := osLoaded;
end;
procedure TOleContainer.InitObject;
var
DataObject: IDataObject;
FormatEtc: TFormatEtc;
AppNameBuf: array[0..127] of WideChar;
DocNameBuf: array[0..127] of WideChar;
begin
FDocForm := GetOleForm(ValidParentForm(Self));
FFrameForm := FDocForm;
FDocForm.FContainers.Add(Self);
if FDocForm.FForm.FormStyle = fsMDIChild then
begin
FFrameForm := GetOleForm(Application.MainForm);
FFrameForm.FContainers.Add(Self);
end;
SetViewAdviseSink(True);
FOleObject.SetHostNames(
StringToWideChar(Application.Title, AppNameBuf, SizeOf(AppNameBuf) div 2),
StringToWideChar(Caption, DocNameBuf, SizeOf(DocNameBuf) div 2));
OleSetContainedObject(FOleObject, True);
FOleObject.QueryInterface(IID_IDataObject, DataObject);
if DataObject <> nil then
begin
FormatEtc.cfFormat := 0;
FormatEtc.ptd := nil;
FormatEtc.dwAspect := -1;
FormatEtc.lIndex := -1;
FormatEtc.tymed := -1;
DataObject.DAdvise(FormatEtc, ADVF_NODATA, FAdviseSink, FDataConnection);
DataObject.Release;
end;
end;
function TOleContainer.InsertObjectDialog: Boolean;
var
Data: TOleUIInsertObject;
NameBuffer: array[0..255] of Char;
CreateInfo: TCreateInfo;
begin
Result := False;
FNewInserted := False;
FillChar(Data, SizeOf(Data), 0);
FillChar(NameBuffer, SizeOf(NameBuffer), 0);
Data.cbStruct := SizeOf(Data);
Data.dwFlags := IOF_SELECTCREATENEW;
Data.hWndOwner := Application.Handle;
Data.lpfnHook := OleDialogHook;
Data.lpszFile := NameBuffer;
Data.cchFile := SizeOf(NameBuffer);
try
if OleUIInsertObject(Data) = OLEUI_OK then
begin
if Data.dwFlags and IOF_SELECTCREATENEW <> 0 then
begin
CreateInfo.CreateType := ctNewObject;
CreateInfo.ClassID := Data.clsid;
end else
begin
if Data.dwFlags and IOF_CHECKLINK = 0 then
CreateInfo.CreateType := ctFromFile else
CreateInfo.CreateType := ctLinkToFile;
CreateInfo.FileName := NameBuffer;
end;
CreateInfo.ShowAsIcon := Data.dwFlags and IOF_CHECKDISPLAYASICON <> 0;
CreateInfo.IconMetaPict := Data.hMetaPict;
CreateObjectFromInfo(CreateInfo);
if CreateInfo.CreateType = ctNewObject then FNewInserted := True;
Result := True;
end;
finally
DestroyMetaPict(Data.hMetaPict);
end;
end;
procedure TOleContainer.KeyDown(var Key: Word; Shift: TShiftState);
begin
inherited KeyDown(Key, Shift);
if (FAutoActivate <> aaManual) and (Key = VK_RETURN) then
begin
if ssCtrl in Shift then DoVerb(ovShow) else DoVerb(ovPrimary);
Key := 0;
end;
end;
procedure TOleContainer.LoadFromFile(const FileName: string);
var
Stream: TStream;
begin
Stream := TFileStream.Create(FileName, fmOpenRead);
try
LoadFromStream(Stream);
finally
Stream.Free;
end;
end;
procedure TOleContainer.LoadFromStream(Stream: TStream);
var
DataHandle: HGlobal;
Buffer: Pointer;
Header: TStreamHeader;
begin
DestroyObject;
Stream.ReadBuffer(Header, SizeOf(Header));
if (Header.Signature <> StreamSignature) and not FOldStreamFormat then
raise EOleError.CreateRes(SInvalidStreamFormat);
DataHandle := GlobalAlloc(GMEM_MOVEABLE, Header.DataSize);
if DataHandle = 0 then OutOfMemoryError;
try
Buffer := GlobalLock(DataHandle);
try
Stream.Read(Buffer^, Header.DataSize);
finally
GlobalUnlock(DataHandle);
end;
OleCheck(CreateILockBytesOnHGlobal(DataHandle, True, FLockBytes));
DataHandle := 0;
OleCheck(StgOpenStorageOnILockBytes(FLockBytes, nil, STGM_READWRITE or
STGM_SHARE_EXCLUSIVE, nil, 0, FStorage));
OleCheck(OleLoad(FStorage, IID_IOleObject, FOleClientSite, FOleObject));
FDrawAspect := Header.DrawAspect;
InitObject;
UpdateView;
except
if DataHandle <> 0 then GlobalFree(DataHandle);
DestroyObject;
raise;
end;
end;
procedure TOleContainer.MouseDown(Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if Button = mbLeft then SetFocus;
inherited MouseDown(Button, Shift, X, Y);
end;
procedure TOleContainer.ObjectModified;
begin
if not (csReading in ComponentState) then
begin
FModified := True;
FModSinceSave := True;
DesignModified;
end;
end;
procedure TOleContainer.ObjectMoved(const ObjectRect: TRect);
var
R: TRect;
I: Integer;
begin
if Assigned(FOnObjectMove) then
begin
R := ObjectRect;
I := GetBorderWidth;
InflateRect(R, I, I);
FOnObjectMove(Self, R);
end;
end;
function TOleContainer.ObjectPropertiesDialog: Boolean;
var
ObjectProps: TOleUIObjectProps;
PropSheet: TPropSheetHeader;
GeneralProps: TOleUIGnrlProps;
ViewProps: TOleUIViewProps;
LinkProps: TOleUILinkProps;
DialogCaption: string;
begin
CheckObject;
Result := False;
FillChar(ObjectProps, SizeOf(ObjectProps), 0);
FillChar(PropSheet, SizeOf(PropSheet), 0);
FillChar(GeneralProps, SizeOf(GeneralProps), 0);
FillChar(ViewProps, SizeOf(ViewProps), 0);
FillChar(LinkProps, SizeOf(LinkProps), 0);
try
ObjectProps.cbStruct := SizeOf(ObjectProps);
ObjectProps.dwFlags := OPF_DISABLECONVERT;
ObjectProps.lpPS := @PropSheet;
ObjectProps.lpObjInfo := TOleUIObjInfo.Create(Self);
if Linked then
begin
ObjectProps.dwFlags := ObjectProps.dwFlags or OPF_OBJECTISLINK;
ObjectProps.lpLinkInfo := TOleUILinkInfo.Create(Self);
end;
ObjectProps.lpGP := @GeneralProps;
ObjectProps.lpVP := @ViewProps;
ObjectProps.lpLP := @LinkProps;
PropSheet.dwSize := SizeOf(PropSheet);
PropSheet.hWndParent := Application.Handle;
PropSheet.hInstance := HInstance;
DialogCaption := FmtLoadStr(SPropDlgCaption, [GetFullNameStr(FOleObject)]);
PropSheet.pszCaption := PChar(DialogCaption);
GeneralProps.cbStruct := SizeOf(GeneralProps);
GeneralProps.lpfnHook := OleDialogHook;
ViewProps.cbStruct := SizeOf(ViewProps);
ViewProps.dwFlags := VPF_DISABLESCALE;
LinkProps.cbStruct := SizeOf(LinkProps);
LinkProps.dwFlags := ELF_DISABLECANCELLINK;
if OleUIObjectProperties(ObjectProps) = OLEUI_OK then Result := True;
finally
ObjectProps.lpLinkInfo.Free;
ObjectProps.lpObjInfo.Free;
end;
end;
procedure TOleContainer.ObjectShowWindow(Show: Boolean);
begin
if FObjectOpen <> Show then
begin
FObjectOpen := Show;
Invalidate;
end;
end;
procedure TOleContainer.ObjectViewChange(Aspect: Longint);
begin
if Aspect = FDrawAspect then UpdateView;
end;
procedure TOleContainer.Paint;
var
W, H: Integer;
S: TPoint;
R: TRect;
begin
Canvas.Brush.Style := bsSolid;
Canvas.Brush.Color := Color;
Canvas.FillRect(ClientRect);
if FOleObject <> nil then
begin
W := ClientWidth;
H := ClientHeight;
S := HimetricToPixels(FViewSize);
if (FDrawAspect = DVASPECT_CONTENT) and (FSizeMode = smScale) then
if W * S.Y > H * S.X then
begin
S.X := S.X * H div S.Y;
S.Y := H;
end else
begin
S.Y := S.Y * W div S.X;
S.X := W;
end;
if (FDrawAspect = DVASPECT_ICON) or (FSizeMode = smCenter) or
(FSizeMode = smScale) then
begin
R.Left := (W - S.X) div 2;
R.Top := (H - S.Y) div 2;
R.Right := R.Left + S.X;
R.Bottom := R.Top + S.Y;
end
else if FSizeMode = smClip then
SetRect(R, 0, 0, S.X, S.Y)
else
SetRect(R, 0, 0, W, H);
OleDraw(FOleObject, FDrawAspect, Canvas.Handle, R);
if FObjectOpen then ShadeRect(Canvas.Handle, ClientRect);
end;
if FFocused then Canvas.DrawFocusRect(ClientRect);
end;
procedure TOleContainer.Paste;
var
DataObject: IDataObject;
Descriptor: PObjectDescriptor;
FormatEtc: TFormatEtc;
Medium: TStgMedium;
CreateInfo: TCreateInfo;
begin
if not CanPaste then Exit;
OleCheck(OleGetClipboard(DataObject));
try
CreateInfo.CreateType := ctFromData;
CreateInfo.ShowAsIcon := False;
CreateInfo.IconMetaPict := 0;
CreateInfo.DataObject := DataObject;
FormatEtc.cfFormat := CFObjectDescriptor;
FormatEtc.ptd := nil;
FormatEtc.dwAspect := DVASPECT_CONTENT;
FormatEtc.lIndex := -1;
FormatEtc.tymed := TYMED_HGLOBAL;
if DataObject.GetData(FormatEtc, Medium) >= 0 then
begin
Descriptor := GlobalLock(Medium.hGlobal);
if Descriptor^.dwDrawAspect = DVASPECT_ICON then
CreateInfo.ShowAsIcon := True;
GlobalUnlock(Medium.hGlobal);
ReleaseStgMedium(Medium);
end;
if CreateInfo.ShowAsIcon then
begin
FormatEtc.cfFormat := CF_METAFILEPICT;
FormatEtc.ptd := nil;
FormatEtc.dwAspect := DVASPECT_ICON;
FormatEtc.lIndex := -1;
FormatEtc.tymed := TYMED_MFPICT;
if DataObject.GetData(FormatEtc, Medium) >= 0 then
CreateInfo.IconMetaPict := Medium.hMetaFilePict;
end;
CreateObjectFromInfo(CreateInfo);
finally
DestroyMetaPict(CreateInfo.IconMetaPict);
DataObject.Release;
end;
end;
function TOleContainer.PasteSpecialDialog: Boolean;
const
PasteFormatCount = 2;
var
Data: TOleUIPasteSpecial;
PasteFormats: array[0..PasteFormatCount - 1] of TOleUIPasteEntry;
CreateInfo: TCreateInfo;
begin
Result := False;
if not CanPaste then Exit;
FillChar(Data, SizeOf(Data), 0);
FillChar(PasteFormats, SizeOf(PasteFormats), 0);
Data.cbStruct := SizeOf(Data);
Data.hWndOwner := Application.Handle;
Data.lpfnHook := OleDialogHook;
Data.arrPasteEntries := @PasteFormats;
Data.cPasteEntries := PasteFormatCount;
Data.arrLinkTypes := @CFLinkSource;
Data.cLinkTypes := 1;
PasteFormats[0].fmtetc.cfFormat := CFEmbeddedObject;
PasteFormats[0].fmtetc.dwAspect := DVASPECT_CONTENT;
PasteFormats[0].fmtetc.lIndex := -1;
PasteFormats[0].fmtetc.tymed := TYMED_ISTORAGE;
PasteFormats[0].lpstrFormatName := '%s';
PasteFormats[0].lpstrResultText := '%s';
PasteFormats[0].dwFlags := OLEUIPASTE_PASTE or OLEUIPASTE_ENABLEICON;
PasteFormats[1].fmtetc.cfFormat := CFLinkSource;
PasteFormats[1].fmtetc.dwAspect := DVASPECT_CONTENT;
PasteFormats[1].fmtetc.lIndex := -1;
PasteFormats[1].fmtetc.tymed := TYMED_ISTREAM;
PasteFormats[1].lpstrFormatName := '%s';
PasteFormats[1].lpstrResultText := '%s';
PasteFormats[1].dwFlags := OLEUIPASTE_LINKTYPE1 or OLEUIPASTE_ENABLEICON;
try
if OleUIPasteSpecial(Data) = OLEUI_OK then
begin
if Data.fLink then
CreateInfo.CreateType := ctLinkFromData else
CreateInfo.CreateType := ctFromData;
CreateInfo.ShowAsIcon := Data.dwFlags and PSF_CHECKDISPLAYASICON <> 0;
CreateInfo.IconMetaPict := Data.hMetaPict;
CreateInfo.DataObject := Data.lpSrcDataObj;
CreateObjectFromInfo(CreateInfo);
Result := True;
end;
finally
DestroyMetaPict(Data.hMetaPict);
ReleaseObject(Data.lpSrcDataObj);
end;
end;
procedure TOleContainer.PopupVerbMenuClick(Sender: TObject);
begin
DoVerb((Sender as TMenuItem).Tag);
end;
function TOleContainer.QueryInterface(const iid: TIID; var obj): HResult;
var
P: IUnknown;
begin
P := nil;
if IsEqualIID(iid, IID_IUnknown) or
IsEqualIID(iid, IID_IOleClientSite) then P := FOleClientSite else
if IsEqualIID(iid, IID_IOleInPlaceSite) then P := FOleInPlaceSite else
if IsEqualIID(iid, IID_IAdviseSink) then P := FAdviseSink;
Pointer(obj) := P;
if P = nil then Result := E_NOINTERFACE else
begin
P.AddRef;
Result := S_OK;
end;
end;
function TOleContainer.Release: Longint;
begin
Dec(FRefCount);
Result := FRefCount;
end;
procedure TOleContainer.Run;
begin
CheckObject;
OleCheck(OleRun(FOleObject));
end;
procedure TOleContainer.SaveObject;
var
PersistStorage: IPersistStorage;
begin
if FOleObject <> nil then
begin
OleCheck(FOleObject.QueryInterface(IID_IPersistStorage, PersistStorage));
try
OleCheck(OleSave(PersistStorage, FStorage, True));
PersistStorage.SaveCompleted(nil);
finally
PersistStorage.Release;
end;
OleCheck(FStorage.Commit(STGC_DEFAULT));
FModSinceSave := False;
end;
end;
procedure TOleContainer.SaveToFile(const FileName: string);
var
Stream: TStream;
begin
Stream := TFileStream.Create(FileName, fmCreate);
try
SaveToStream(Stream);
finally
Stream.Free;
end;
end;
procedure TOleContainer.SaveToStream(Stream: TStream);
var
TempLockBytes: ILockBytes;
TempStorage: IStorage;
DataHandle: HGlobal;
Buffer: Pointer;
Header: TStreamHeader;
R: TRect;
begin
CheckObject;
if FModSinceSave then SaveObject;
TempLockBytes := nil;
TempStorage := nil;
try
if FCopyOnSave then
begin
OleCheck(CreateILockBytesOnHGlobal(0, True, TempLockBytes));
OleCheck(StgCreateDocfileOnILockBytes(TempLockBytes, STGM_READWRITE
or STGM_SHARE_EXCLUSIVE or STGM_CREATE, 0, TempStorage));
OleCheck(FStorage.CopyTo(0, nil, nil, TempStorage));
OleCheck(TempStorage.Commit(STGC_DEFAULT));
OleCheck(GetHGlobalFromILockBytes(TempLockBytes, DataHandle));
end else
OleCheck(GetHGlobalFromILockBytes(FLockBytes, DataHandle));
if FOldStreamFormat then
begin
R := BoundsRect;
Header.PartRect.Left := R.Left;
Header.PartRect.Top := R.Top;
Header.PartRect.Right := R.Right;
Header.PartRect.Bottom := R.Bottom;
end else
begin
Header.Signature := StreamSignature;
Header.DrawAspect := FDrawAspect;
end;
Header.DataSize := GlobalSize(DataHandle);
Stream.WriteBuffer(Header, SizeOf(Header));
Buffer := GlobalLock(DataHandle);
try
Stream.WriteBuffer(Buffer^, Header.DataSize);
finally
GlobalUnlock(DataHandle);
end;
finally
ReleaseObject(TempStorage);
ReleaseObject(TempLockBytes);
end;
end;
procedure TOleContainer.SetBorderStyle(Value: TBorderStyle);
begin
if FBorderStyle <> Value then
begin
FBorderStyle := Value;
AdjustBounds;
RecreateWnd;
end;
end;
procedure TOleContainer.SetDrawAspect(Iconic: Boolean;
IconMetaPict: HGlobal);
var
OleCache: IOleCache;
EnumStatData: IEnumStatData;
OldAspect, AdviseFlags, Connection: Longint;
TempMetaPict: HGlobal;
FormatEtc: TFormatEtc;
Medium: TStgMedium;
ClassID: TCLSID;
StatData: TStatData;
begin
OldAspect := FDrawAspect;
if Iconic then
begin
FDrawAspect := DVASPECT_ICON;
AdviseFlags := ADVF_NODATA;
end else
begin
FDrawAspect := DVASPECT_CONTENT;
AdviseFlags := ADVF_PRIMEFIRST;
end;
if (FDrawAspect <> OldAspect) or (FDrawAspect = DVASPECT_ICON) then
begin
OleCheck(FOleObject.QueryInterface(IID_IOleCache, OleCache));
try
if FDrawAspect <> OldAspect then
begin
OleCheck(OleCache.EnumCache(EnumStatData));
if EnumStatData <> nil then
try
while EnumStatData.Next(1, StatData, nil) = 0 do
if StatData.formatetc.dwAspect = OldAspect then
OleCache.Uncache(StatData.dwConnection);
finally
EnumStatData.Release;
end;
FillChar(FormatEtc, SizeOf(FormatEtc), 0);
FormatEtc.dwAspect := FDrawAspect;
FormatEtc.lIndex := -1;
OleCheck(OleCache.Cache(FormatEtc, AdviseFlags, Connection));
SetViewAdviseSink(True);
end;
if FDrawAspect = DVASPECT_ICON then
begin
TempMetaPict := 0;
if IconMetaPict = 0 then
begin
OleCheck(FOleObject.GetUserClassID(ClassID));
TempMetaPict := OleGetIconOfClass(ClassID, nil, True);
IconMetaPict := TempMetaPict;
end;
try
FormatEtc.cfFormat := CF_METAFILEPICT;
FormatEtc.ptd := nil;
FormatEtc.dwAspect := DVASPECT_ICON;
FormatEtc.lIndex := -1;
FormatEtc.tymed := TYMED_MFPICT;
Medium.tymed := TYMED_MFPICT;
Medium.hMetaFilePict := IconMetaPict;
Medium.unkForRelease := nil;
OleCheck(OleCache.SetData(FormatEtc, Medium, False));
finally
DestroyMetaPict(TempMetaPict);
end;
end;
finally
OleCache.Release;
end;
if FDrawAspect = DVASPECT_CONTENT then UpdateObject;
UpdateView;
end;
end;
procedure TOleContainer.SetFocused(Value: Boolean);
begin
if FFocused <> Value then
begin
FFocused := Value;
if GetUpdateRect(Handle, PRect(nil)^, False) then
Invalidate
else
Canvas.DrawFocusRect(ClientRect);
end;
end;
procedure TOleContainer.SetIconic(Value: Boolean);
begin
if GetIconic <> Value then
begin
CheckObject;
SetDrawAspect(Value, 0);
end;
end;
procedure TOleContainer.SetSizeMode(Value: TSizeMode);
begin
if FSizeMode <> Value then
begin
FSizeMode := Value;
AdjustBounds;
Invalidate;
end;
end;
procedure TOleContainer.SetUIActive(Active: Boolean);
var
Form: TForm;
begin
try
FUIActive := Active;
Form := GetParentForm(Self);
if Form <> nil then
if Active then
begin
if (Form.ActiveOleControl <> nil) and
(Form.ActiveOleControl <> Self) then
Form.ActiveOleControl.Perform(CM_UIDEACTIVATE, 0, 0);
Form.ActiveOleControl := Self;
SetFocus;
if Assigned(FOnActivate) then FOnActivate(Self);
end else
begin
if Form.ActiveOleControl = Self then Form.ActiveOleControl := nil;
if Form.ActiveControl = Self then Windows.SetFocus(Handle);
DestroyAccelTable;
if Assigned(FOnDeactivate) then FOnDeactivate(Self);
end;
except
Application.HandleException(Self);
end;
end;
procedure TOleContainer.SetViewAdviseSink(Enable: Boolean);
var
ViewObject: IViewObject;
AdviseSink: IAdviseSink;
begin
OleCheck(FOleObject.QueryInterface(IID_IViewObject, ViewObject));
if Enable then AdviseSink := FAdviseSink else AdviseSink := nil;
ViewObject.SetAdvise(FDrawAspect, 0, AdviseSink);
ViewObject.Release;
end;
procedure TOleContainer.UpdateObject;
begin
if FOleObject <> nil then
begin
OleCheck(FOleObject.Update);
ObjectModified;
end;
end;
procedure TOleContainer.UpdateObjectRect;
var
P: TPoint;
begin
if FOleInPlaceObject <> nil then
begin
P := Parent.ScreenToClient(ClientOrigin);
FOleInPlaceObject.SetObjectRects(
Rect(P.X, P.Y, P.X + ClientWidth, P.Y + ClientHeight),
Rect(-16384, -16384, 16383, 16383));
end;
end;
procedure TOleContainer.UpdateVerbs;
var
EnumOleVerb: IEnumOleVerb;
OleVerb: TOleVerb;
VerbInfo: TVerbInfo;
begin
CheckObject;
DestroyVerbs;
FObjectVerbs := TStringList.Create;
if FOleObject.EnumVerbs(EnumOleVerb) = 0 then
try
while (EnumOleVerb.Next(1, OleVerb, nil) = 0) and
(OleVerb.lVerb >= 0) and
(OleVerb.grfAttribs and OLEVERBATTRIB_ONCONTAINERMENU <> 0) do
begin
VerbInfo.Verb := OleVerb.lVerb;
VerbInfo.Flags := OleVerb.fuFlags;
FObjectVerbs.AddObject(WideCharToString(OleVerb.lpszVerbName),
TObject(VerbInfo));
end;
finally
EnumOleVerb.Release;
end;
end;
procedure TOleContainer.UpdateView;
var
ViewObject2: IViewObject2;
begin
if FOleObject.QueryInterface(IID_IViewObject2, ViewObject2) >= 0 then
begin
ViewObject2.GetExtent(FDrawAspect, -1, nil, FViewSize);
ViewObject2.Release;
AdjustBounds;
end;
Invalidate;
ObjectModified;
end;
procedure TOleContainer.CMCtl3DChanged(var Message: TMessage);
begin
if NewStyleControls and (FBorderStyle = bsSingle) then
begin
AdjustBounds;
RecreateWnd;
end;
inherited;
end;
procedure TOleContainer.CMDocWindowActivate(var Message: TMessage);
begin
if FDocForm.FForm.FormStyle = fsMDIChild then
begin
FOleInPlaceActiveObject.OnDocWindowActivate(LongBool(Message.WParam));
if Message.WParam = 0 then
begin
FFrameForm.FOleInPlaceFrame.SetMenu(0, 0, 0);
FFrameForm.ClearBorderSpace;
end;
end;
end;
procedure TOleContainer.CMUIDeactivate(var Message: TMessage);
begin
if GetParentForm(Self).ActiveOleControl = Self then
FOleInPlaceObject.UIDeactivate;
end;
procedure TOleContainer.WMKillFocus(var Message: TWMSetFocus);
begin
inherited;
SetFocused(False);
end;
procedure TOleContainer.WMSetFocus(var Message: TWMSetFocus);
var
Window: HWnd;
begin
inherited;
if FUIActive and (FOleInPlaceObject.GetWindow(Window) = 0) then
Windows.SetFocus(Window)
else
SetFocused(True);
end;
procedure TOleContainer.WMSize(var Message: TWMSize);
begin
inherited;
if not (csLoading in ComponentState) and Assigned(FOnResize) then
FOnResize(Self);
end;
procedure TOleContainer.WMWindowPosChanged(var Message: TWMWindowPosChanged);
var
R: TRect;
begin
R := BoundsRect;
inherited;
if FUIActive and not EqualRect(BoundsRect, R) then UpdateObjectRect;
end;
{ TOleInPlaceFrame }
constructor TOleInPlaceFrame.Create(OleForm: TOleForm);
begin
FOleForm := OleForm;
end;
function TOleInPlaceFrame.QueryInterface(const iid: TIID; var obj): HResult;
begin
if IsEqualIID(iid, IID_IUnknown) or
IsEqualIID(iid, IID_IOleInPlaceFrame) then
begin
Pointer(obj) := Self;
AddRef;
Result := S_OK;
end else
begin
Pointer(obj) := nil;
Result := E_NOINTERFACE;
end;
end;
function TOleInPlaceFrame.AddRef: Longint;
begin
Result := FOleForm.AddRef;
end;
function TOleInPlaceFrame.Release: Longint;
begin
Result := FOleForm.Release;
end;
function TOleInPlaceFrame.GetWindow(var wnd: HWnd): HResult;
begin
wnd := FOleForm.FForm.Handle;
Result := S_OK;
end;
function TOleInPlaceFrame.ContextSensitiveHelp(fEnterMode: BOOL): HResult;
begin
Result := S_OK;
end;
function TOleInPlaceFrame.GetBorder(var rectBorder: TRect): HResult;
begin
FOleForm.GetBorder(rectBorder);
Result := S_OK;
end;
function TOleInPlaceFrame.RequestBorderSpace(const borderwidths: TRect): HResult;
begin
if FOleForm.BorderSpaceAvailable(borderwidths) then
Result := S_OK else
Result := INPLACE_E_NOTOOLSPACE;
end;
function TOleInPlaceFrame.SetBorderSpace(pborderwidths: PRect): HResult;
begin
if (pborderwidths = nil) or FOleForm.SetBorderSpace(pborderwidths^) then
Result := S_OK else
Result := INPLACE_E_NOTOOLSPACE;
end;
function TOleInPlaceFrame.SetActiveObject(activeObject: IOleInPlaceActiveObject;
pszObjName: POleStr): HResult;
begin
FOleForm.SetActiveObject(activeObject);
Result := S_OK;
end;
function TOleInPlaceFrame.InsertMenus(hmenuShared: HMenu;
var menuWidths: TOleMenuGroupWidths): HResult;
var
Menu: TMainMenu;
begin
Menu := FOleForm.FForm.Menu;
if Menu <> nil then
Menu.PopulateOle2Menu(hmenuShared, [0, 2, 4], menuWidths.width);
Result := S_OK;
end;
function TOleInPlaceFrame.SetMenu(hmenuShared: HMenu; holemenu: HMenu;
hwndActiveObject: HWnd): HResult;
var
Menu: TMainMenu;
begin
Menu := FOleForm.FForm.Menu;
Result := S_OK;
if Menu <> nil then
begin
Menu.SetOle2MenuHandle(hmenuShared);
Result := OleSetMenuDescriptor(holemenu, Menu.WindowHandle,
hwndActiveObject, nil, nil);
end;
end;
function TOleInPlaceFrame.RemoveMenus(hmenuShared: HMenu): HResult;
begin
while GetMenuItemCount(hmenuShared) > 0 do
RemoveMenu(hmenuShared, 0, MF_BYPOSITION);
Result := S_OK;
end;
function TOleInPlaceFrame.SetStatusText(pszStatusText: POleStr): HResult;
var
StatusText: string;
begin
if pszStatusText <> nil then
StatusText := WideCharToString(pszStatusText) else
StatusText := '';
Application.Hint := StatusText;
Result := S_OK;
end;
function TOleInPlaceFrame.EnableModeless(fEnable: BOOL): HResult;
begin
Result := S_OK;
end;
function TOleInPlaceFrame.TranslateAccelerator(var msg: TMsg; wID: Word): HResult;
var
Menu: TMainMenu;
begin
Menu := FOleForm.FForm.Menu;
if (Menu <> nil) and Menu.DispatchCommand(wID) then
Result := S_OK else
Result := S_FALSE;
end;
{ TOleForm }
constructor TOleForm.Create(Form: TForm);
begin
FRefCount := 1;
FForm := Form;
FOleInPlaceFrame := TOleInPlaceFrame.Create(Self);
FContainers := TList.Create;
FHiddenControls := TList.Create;
FForm.OleFormObject := Self;
end;
destructor TOleForm.Destroy;
begin
if FForm <> nil then FForm.OleFormObject := nil;
FHiddenControls.Free;
FContainers.Free;
FOleInPlaceFrame.Free;
end;
function TOleForm.AddRef: Longint;
begin
Inc(FRefCount);
Result := FRefCount;
end;
function TOleForm.BorderSpaceAvailable(const BorderWidths: TRect): Boolean;
var
I: Integer;
begin
Result := True;
if FForm.FormStyle = fsMDIForm then Exit;
for I := 0 to FForm.ControlCount - 1 do
with FForm.Controls[I] do
if Visible and (Align = alClient) then Exit;
Result := False;
end;
procedure TOleForm.ClearBorderSpace;
var
I: Integer;
begin
FForm.DisableAlign;
for I := 0 to 3 do
begin
FSpacers[I].Free;
FSpacers[I] := nil;
end;
for I := 0 to FHiddenControls.Count - 1 do
TControl(FHiddenControls[I]).Visible := True;
FHiddenControls.Clear;
FForm.EnableAlign;
end;
procedure TOleForm.GetBorder(var BorderRect: TRect);
var
I: Integer;
Control: TControl;
begin
BorderRect := FForm.ClientRect;
for I := 0 to FForm.ControlCount - 1 do
begin
Control := FForm.Controls[I];
if Control.Visible and not IsSpacer(Control) and
not IsToolControl(Control) then
case Control.Align of
alLeft: Inc(BorderRect.Left, Control.Width);
alRight: Dec(BorderRect.Right, Control.Width);
alTop: Inc(BorderRect.Top, Control.Height);
alBottom: Dec(BorderRect.Bottom, Control.Height);
end;
end;
end;
function TOleForm.IsSpacer(Control: TControl): Boolean;
var
I: Integer;
begin
for I := 0 to 3 do
if Control = FSpacers[I] then
begin
Result := True;
Exit;
end;
Result := False;
end;
function TOleForm.IsToolControl(Control: TControl): Boolean;
begin
Result := Control.Visible and
(Control.Align in [alTop, alBottom, alLeft, alRight]) and
(Control.Perform(CM_ISTOOLCONTROL, 0, 0) <> 0);
end;
procedure TOleForm.OnDestroy;
var
I: Integer;
begin
for I := FContainers.Count - 1 downto 0 do
TOleContainer(FContainers[I]).DestroyObject;
end;
procedure TOleForm.OnResize;
var
BorderRect: TRect;
begin
if (FActiveObject <> nil) and (FForm.WindowState <> wsMinimized) and
((FForm.ClientWidth <> FSaveWidth) or
(FForm.ClientHeight <> FSaveHeight)) then
begin
GetBorder(BorderRect);
FActiveObject.ResizeBorder(BorderRect, FOleInPlaceFrame, True);
FSaveWidth := FForm.ClientWidth;
FSaveHeight := FForm.ClientHeight;
end;
end;
function TOleForm.Release: Longint;
begin
Dec(FRefCount);
Result := FRefCount;
end;
procedure TOleForm.SetActiveObject(ActiveObject: IOleInPlaceActiveObject);
var
Window, ParentWindow: HWnd;
begin
if FActiveObject <> nil then FActiveObject.Release;
FActiveObject := ActiveObject;
if FActiveObject <> nil then
begin
FActiveObject.AddRef;
if FActiveObject.GetWindow(Window) = 0 then
while True do
begin
ParentWindow := GetParent(Window);
if ParentWindow = 0 then Break;
if FindControl(ParentWindow) <> nil then
begin
SetWindowPos(Window, HWND_TOP, 0, 0, 0, 0,
SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE);
Break;
end;
Window := ParentWindow;
end;
FSaveWidth := FForm.ClientWidth;
FSaveHeight := FForm.ClientHeight;
end;
end;
function TOleForm.SetBorderSpace(const BorderWidths: TRect): Boolean;
type
TRectArray = array[0..3] of Integer;
const
Alignments: array[0..3] of TAlign = (alLeft, alTop, alRight, alBottom);
var
I, J, Size: Integer;
Control, Spacer: TControl;
begin
if not BorderSpaceAvailable(BorderWidths) then
begin
Result := False;
Exit;
end;
FForm.DisableAlign;
for I := 0 to FForm.ControlCount - 1 do
begin
Control := FForm.Controls[I];
if IsToolControl(Control) then
begin
Control.Visible := False;
FHiddenControls.Add(Control);
end;
end;
for I := 0 to 3 do
begin
Size := TRectArray(BorderWidths)[I];
if Size > 0 then
begin
Spacer := FSpacers[I];
if Spacer = nil then
begin
Spacer := TControl.Create(FForm);
if I < 2 then J := 10000 else J := -10000;
if Odd(I) then Spacer.Top := J else Spacer.Left := J;
Spacer.Align := Alignments[I];
Spacer.Parent := FForm;
FSpacers[I] := Spacer;
end;
if Odd(I) then Spacer.Height := Size else Spacer.Width := Size;
end;
end;
FForm.EnableAlign;
Result := True;
end;
{ Initialization }
procedure Initialize;
var
DC: HDC;
begin
DC := GetDC(0);
PixPerInch.X := GetDeviceCaps(DC, LOGPIXELSX);
PixPerInch.Y := GetDeviceCaps(DC, LOGPIXELSY);
ReleaseDC(0, DC);
CFObjectDescriptor := RegisterClipboardFormat('Object Descriptor');
CFEmbeddedObject := RegisterClipboardFormat('Embedded Object');
CFLinkSource := RegisterClipboardFormat('Link Source');
DataFormats[0].cfFormat := CFEmbeddedObject;
DataFormats[0].dwAspect := DVASPECT_CONTENT;
DataFormats[0].lIndex := -1;
DataFormats[0].tymed := TYMED_ISTORAGE;
DataFormats[1].cfFormat := CFObjectDescriptor;
DataFormats[1].dwAspect := DVASPECT_CONTENT;
DataFormats[1].lIndex := -1;
DataFormats[1].tymed := TYMED_HGLOBAL;
end;
begin
Initialize;
end.