home *** CD-ROM | disk | FTP | other *** search
-
- {*******************************************************}
- { }
- { Delphi Visual Component Library }
- { }
- { Copyright (c) 1996 Borland International }
- { }
- {*******************************************************}
-
- unit OleCtrls;
-
- {$R-}
-
- interface
-
- uses Windows, Messages, Ole2, OleCtl, SysUtils, Classes, Controls, Forms,
- Menus, Graphics, OleAuto;
-
- type
-
- TOleControl = class;
-
- TOleClientSite = class(IOleClientSite)
- private
- FControl: TOleControl;
- public
- constructor Create(Control: TOleControl);
- 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;
-
- TOleControlSite = class(IOleControlSite)
- private
- FControl: TOleControl;
- public
- constructor Create(Control: TOleControl);
- function QueryInterface(const iid: TIID; var obj): HResult; override;
- function AddRef: Longint; override;
- function Release: Longint; override;
- function OnControlInfoChanged: HResult; override;
- function LockInPlaceActive(fLock: BOOL): HResult; override;
- function GetExtendedControl(var disp: IDispatch): HResult; override;
- function TransformCoords(var ptlHimetric: TPoint; var ptfContainer: TPointF;
- flags: Longint): HResult; override;
- function TranslateAccelerator(msg: PMsg; grfModifiers: Longint): HResult;
- override;
- function OnFocus(fGotFocus: BOOL): HResult; override;
- function ShowPropertyFrame: HResult; override;
- end;
-
- TOleInPlaceSite = class(IOleInPlaceSite)
- private
- FControl: TOleControl;
- public
- constructor Create(Control: TOleControl);
- 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;
-
- TOleInPlaceFrame = class(IOleInPlaceFrame)
- private
- FControl: TOleControl;
- public
- constructor Create(Control: TOleControl);
- 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;
-
- TAmbientDispatch = class(IDispatch)
- private
- FControl: TOleControl;
- public
- constructor Create(Control: TOleControl);
- function QueryInterface(const iid: TIID; var obj): HResult; override;
- function AddRef: Longint; override;
- function Release: Longint; override;
- function GetTypeInfoCount(var ctinfo: Integer): HResult; override;
- function GetTypeInfo(itinfo: Integer; lcid: TLCID;
- var tinfo: ITypeInfo): HResult; override;
- function GetIDsOfNames(const iid: TIID; rgszNames: POleStrList;
- cNames: Integer; lcid: TLCID; rgdispid: PDispIDList): HResult; override;
- function Invoke(dispIDMember: TDispID; const iid: TIID; lcid: TLCID;
- flags: Word; var dispParams: TDispParams; varResult: PVariant;
- excepInfo: PExcepInfo; argErr: PInteger): HResult; override;
- end;
-
- TEventDispatch = class(IDispatch)
- private
- FControl: TOleControl;
- public
- constructor Create(Control: TOleControl);
- function QueryInterface(const iid: TIID; var obj): HResult; override;
- function AddRef: Longint; override;
- function Release: Longint; override;
- function GetTypeInfoCount(var ctinfo: Integer): HResult; override;
- function GetTypeInfo(itinfo: Integer; lcid: TLCID;
- var tinfo: ITypeInfo): HResult; override;
- function GetIDsOfNames(const iid: TIID; rgszNames: POleStrList;
- cNames: Integer; lcid: TLCID; rgdispid: PDispIDList): HResult; override;
- function Invoke(dispIDMember: TDispID; const iid: TIID; lcid: TLCID;
- flags: Word; var dispParams: TDispParams; varResult: PVariant;
- excepInfo: PExcepInfo; argErr: PInteger): HResult; override;
- end;
-
- TPropertyNotifySink = class(IPropertyNotifySink)
- private
- FControl: TOleControl;
- public
- constructor Create(Control: TOleControl);
- function QueryInterface(const iid: TIID; var obj): HResult; override;
- function AddRef: Longint; override;
- function Release: Longint; override;
- function OnChanged(dispid: TDispID): HResult; override;
- function OnRequestEdit(dispid: TDispID): HResult; override;
- end;
-
- TSimpleFrameSite = class(ISimpleFrameSite)
- private
- FControl: TOleControl;
- public
- constructor Create(Control: TOleControl);
- function QueryInterface(const iid: TIID; var obj): HResult; override;
- function AddRef: Longint; override;
- function Release: Longint; override;
- function PreMessageFilter(wnd: HWnd; msg, wp, lp: Integer;
- var res: Integer; var Cookie: Longint): HResult; override;
- function PostMessageFilter(wnd: HWnd; msg, wp, lp: Integer;
- var res: Integer; Cookie: Longint): HResult; override;
- end;
-
- TOleEnum = -32768..32767;
-
- TEnumValue = record
- Value: Longint;
- Ident: string;
- end;
-
- PEnumValueList = ^TEnumValueList;
- TEnumValueList = array[0..32767] of TEnumValue;
-
- TEnumPropDesc = class
- private
- FDispID: Integer;
- FValueCount: Integer;
- FValues: PEnumValueList;
- public
- constructor Create(DispID, ValueCount: Integer; TypeInfo: ITypeInfo);
- destructor Destroy; override;
- procedure GetStrings(Proc: TGetStrProc);
- function StringToValue(const S: string): Integer;
- function ValueToString(V: Integer): string;
- end;
-
- PControlData = ^TControlData;
- TControlData = record
- ClassID: TCLSID;
- EventIID: TIID;
- EventCount: Longint;
- EventDispIDs: Pointer;
- LicenseKey: Pointer;
- Flags: Integer;
- InstanceCount: Integer;
- EnumPropDescs: TList;
- end;
-
- TOleControl = class(TWinControl)
- private
- FControlData: PControlData;
- FRefCount: Longint;
- FOleClientSite: TOleClientSite;
- FOleControlSite: TOleControlSite;
- FOleInPlaceSite: TOleInPlaceSite;
- FOleInPlaceFrame: TOleInPlaceFrame;
- FAmbientDispatch: TAmbientDispatch;
- FEventDispatch: TEventDispatch;
- FPropertyNotifySink: TPropertyNotifySink;
- FSimpleFrameSite: TSimpleFrameSite;
- FObjectData: HGlobal;
- FOleObject: IOleObject;
- FPersistStream: IPersistStreamInit;
- FOleControl: IOleControl;
- FControlDispatch: IDispatch;
- FPropBrowsing: IPerPropertyBrowsing;
- FOleInPlaceObject: IOleInPlaceObject;
- FOleInPlaceActiveObject: IOleInPlaceActiveObject;
- FPropConnection: Longint;
- FEventsConnection: Longint;
- FMiscStatus: Longint;
- FUpdatingColor: Boolean;
- FUpdatingFont: Boolean;
- FUpdatingEnabled: Boolean;
- function AddRef: Longint;
- procedure CreateControl;
- procedure CreateEnumPropDescs;
- procedure CreateInstance;
- procedure CreateStorage;
- procedure DesignModified;
- procedure DestroyControl;
- procedure DestroyEnumPropDescs;
- procedure DestroyStorage;
- procedure GetEventMethod(DispID: TDispID; var Method: TMethod);
- function GetMainMenu: TMainMenu;
- function GetOleObject: Variant;
- procedure HookControlWndProc;
- procedure InvokeEvent(DispID: TDispID; var Params: TDispParams);
- function QueryInterface(const iid: TIID; var obj): HResult;
- procedure ReadData(Stream: TStream);
- function Release: Longint;
- procedure SetUIActive(Active: Boolean);
- procedure StandardEvent(DispID: TDispID; var Params: TDispParams);
- procedure WriteData(Stream: TStream);
- procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
- procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
- procedure CMDocWindowActivate(var Message: TMessage); message CM_DOCWINDOWACTIVATE;
- procedure CMColorChanged(var Message: TMessage); message CM_COLORCHANGED;
- procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED;
- procedure CMFontChanged(var Message: TMessage); message CM_FONTCHANGED;
- procedure CMDialogKey(var Message: TMessage); message CM_DIALOGKEY;
- procedure CMUIActivate(var Message: TMessage); message CM_UIACTIVATE;
- procedure CMUIDeactivate(var Message: TMessage); message CM_UIDEACTIVATE;
- protected
- FEvents: Integer;
- procedure CreateWnd; override;
- procedure DefaultHandler(var Message); override;
- procedure DefineProperties(Filer: TFiler); override;
- procedure DestroyWindowHandle; override;
- function GetColorProp(Index: Integer): TColor;
- function GetCurrencyProp(Index: Integer): TCurrency;
- function GetDoubleProp(Index: Integer): Double;
- function GetIntegerProp(Index: Integer): Integer;
- function GetOleBoolProp(Index: Integer): TOleBool;
- function GetOleDateProp(Index: Integer): TOleDate;
- function GetOleEnumProp(Index: Integer): TOleEnum;
- procedure GetProperty(Index: Integer; var Value: TVarData);
- function GetSingleProp(Index: Integer): Single;
- function GetSmallintProp(Index: Integer): Smallint;
- function GetStringProp(Index: Integer): string;
- function GetVariantProp(Index: Integer): Variant;
- procedure InitControlData; virtual; abstract;
- procedure InvokeMethod(var DispInfo; Result: Pointer);
- function PaletteChanged(Foreground: Boolean): Boolean; override;
- procedure SetColorProp(Index: Integer; Value: TColor);
- procedure SetCurrencyProp(Index: Integer; Value: TCurrency);
- procedure SetDoubleProp(Index: Integer; Value: Double);
- procedure SetIntegerProp(Index: Integer; Value: Integer);
- procedure SetName(const Value: TComponentName); override;
- procedure SetOleBoolProp(Index: Integer; Value: TOleBool);
- procedure SetOleDateProp(Index: Integer; Value: TOleDate);
- procedure SetOleEnumProp(Index: Integer; Value: TOleEnum);
- procedure SetProperty(Index: Integer; const Value: TVarData);
- procedure SetSingleProp(Index: Integer; Value: Single);
- procedure SetSmallintProp(Index: Integer; Value: Smallint);
- procedure SetStringProp(Index: Integer; const Value: string);
- procedure SetVariantProp(Index: Integer; const Value: Variant);
- procedure WndProc(var Message: TMessage); override;
- property ControlData: PControlData read FControlData write FControlData;
- public
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- procedure BrowseProperties;
- procedure DoObjectVerb(Verb: Integer);
- function GetEnumPropDesc(DispID: Integer): TEnumPropDesc;
- function GetHelpContext(Member: string; var HelpCtx: Integer;
- var HelpFile: string): Boolean;
- procedure GetObjectVerbs(List: TStrings);
- function GetPropDisplayString(DispID: Integer): string;
- procedure GetPropDisplayStrings(DispID: Integer; List: TStrings);
- function IsCustomProperty(DispID: Integer): Boolean;
- procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override;
- procedure SetPropDisplayString(DispID: Integer; const Value: string);
- procedure ShowAboutBox;
- property OleObject: Variant read GetOleObject;
- property TabStop default True;
- end;
-
- EOleCtrlError = class(Exception);
-
- function FontToOleFont(Font: TFont): Variant;
- procedure OleFontToFont(const OleFont: Variant; Font: TFont);
-
- implementation
-
- uses OleConst;
-
- {$J+}
-
- const
- OCM_BASE = $2000;
-
- { Control flags }
-
- const
- cfBackColor = $00000001;
- cfForeColor = $00000002;
- cfFont = $00000004;
- cfEnabled = $00000008;
- cfCaption = $00000010;
- cfText = $00000020;
-
- type
-
- PDispInfo = ^TDispInfo;
- TDispInfo = packed record
- DispID: TDispID;
- ResType: Byte;
- CallDesc: TCallDesc;
- end;
-
- TArgKind = (akDWord, akSingle, akDouble);
-
- PEventArg = ^TEventArg;
- TEventArg = record
- Kind: TArgKind;
- Data: array[0..1] of Integer;
- end;
-
- TEventInfo = record
- Method: TMethod;
- Sender: TObject;
- ArgCount: Integer;
- Args: array[0..MaxDispArgs - 1] of TEventArg;
- end;
-
- { Private variables }
-
- var
- PixPerInch: TPoint;
-
- { Release an object reference }
-
- procedure ReleaseObject(var Obj);
- begin
- if IUnknown(Obj) <> nil then
- begin
- IUnknown(Obj).Release;
- IUnknown(Obj) := nil;
- end;
- end;
-
- { Connect an IConnectionPoint interface }
-
- procedure InterfaceConnect(Source: IUnknown; const IID: TIID;
- Sink: IUnknown; var Connection: Longint);
- var
- CPC: IConnectionPointContainer;
- CP: IConnectionPoint;
- begin
- Connection := 0;
- if Source.QueryInterface(IID_IConnectionPointContainer, CPC) >= 0 then
- begin
- if CPC.FindConnectionPoint(IID, CP) >= 0 then
- begin
- CP.Advise(Sink, Connection);
- CP.Release;
- end;
- CPC.Release;
- end;
- end;
-
- { Disconnect an IConnectionPoint interface }
-
- procedure InterfaceDisconnect(Source: IUnknown; const IID: TIID;
- var Connection: Longint);
- var
- CPC: IConnectionPointContainer;
- CP: IConnectionPoint;
- begin
- if Connection <> 0 then
- if Source.QueryInterface(IID_IConnectionPointContainer, CPC) >= 0 then
- begin
- if CPC.FindConnectionPoint(IID, CP) >= 0 then
- begin
- if CP.Unadvise(Connection) >= 0 then Connection := 0;
- CP.Release;
- end;
- CPC.Release;
- end;
- end;
-
- function FontToOleFont(Font: TFont): Variant;
- var
- FontDesc: TFontDesc;
- FontName: array[0..63] of WideChar;
- begin
- StringToWideChar(Font.Name, FontName, SizeOf(FontName));
- with FontDesc do
- begin
- cbSizeOfStruct := SizeOf(FontDesc);
- lpstrName := FontName;
- cySize := Font.Size * 10000;
- if fsBold in Font.Style then sWeight := 700 else sWeight := 400;
- sCharset := DEFAULT_CHARSET;
- fItalic := fsItalic in Font.Style;
- fUnderline := fsUnderline in Font.Style;
- fStrikethrough := fsStrikeout in Font.Style;
- end;
- VarClear(Result);
- OleCheck(OleCreateFontIndirect(FontDesc, IID_IFontDisp,
- TVarData(Result).VDispatch));
- TVarData(Result).VType := varDispatch;
- end;
-
- procedure OleFontToFont(const OleFont: Variant; Font: TFont);
- var
- TempFont: TFont;
- Style: TFontStyles;
- begin
- TempFont := TFont.Create;
- try
- TempFont.Assign(Font);
- TempFont.Name := OleFont.Name;
- TempFont.Size := OleFont.Size;
- Style := [];
- if OleFont.Bold then Include(Style, fsBold);
- if OleFont.Italic then Include(Style, fsItalic);
- if OleFont.Underline then Include(Style, fsUnderline);
- if OleFont.Strikethrough then Include(Style, fsStrikeout);
- TempFont.Style := Style;
- Font.Assign(TempFont);
- finally
- TempFont.Free;
- end;
- end;
-
- function StringToVarOleStr(const S: string): Variant;
- begin
- VarClear(Result);
- TVarData(Result).VOleStr := StringToOleStr(S);
- TVarData(Result).VType := varOleStr;
- end;
-
- { TOleClientSite }
-
- constructor TOleClientSite.Create(Control: TOleControl);
- begin
- FControl := Control;
- end;
-
- function TOleClientSite.QueryInterface(const iid: TIID; var obj): HResult;
- begin
- Result := FControl.QueryInterface(iid, obj);
- end;
-
- function TOleClientSite.AddRef: Longint;
- begin
- Result := FControl.AddRef;
- end;
-
- function TOleClientSite.Release: Longint;
- begin
- Result := FControl.Release;
- end;
-
- function TOleClientSite.SaveObject: HResult;
- begin
- 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
- FControl.HookControlWndProc;
- Result := S_OK;
- end;
-
- function TOleClientSite.OnShowWindow(fShow: BOOL): HResult;
- begin
- Result := S_OK;
- end;
-
- function TOleClientSite.RequestNewObjectLayout: HResult;
- begin
- Result := E_NOTIMPL;
- end;
-
- { TOleControlSite }
-
- constructor TOleControlSite.Create(Control: TOleControl);
- begin
- FControl := Control;
- end;
-
- function TOleControlSite.QueryInterface(const iid: TIID; var obj): HResult;
- begin
- Result := FControl.QueryInterface(iid, obj);
- end;
-
- function TOleControlSite.AddRef: Longint;
- begin
- Result := FControl.AddRef;
- end;
-
- function TOleControlSite.Release: Longint;
- begin
- Result := FControl.Release;
- end;
-
- function TOleControlSite.OnControlInfoChanged: HResult;
- begin
- Result := E_NOTIMPL;
- end;
-
- function TOleControlSite.LockInPlaceActive(fLock: BOOL): HResult;
- begin
- Result := E_NOTIMPL;
- end;
-
- function TOleControlSite.GetExtendedControl(var disp: IDispatch): HResult;
- begin
- disp := nil;
- Result := E_NOTIMPL;
- end;
-
- function TOleControlSite.TransformCoords(var ptlHimetric: TPoint;
- var ptfContainer: TPointF; flags: Longint): HResult;
- begin
- if flags and XFORMCOORDS_HIMETRICTOCONTAINER <> 0 then
- begin
- ptfContainer.X := MulDiv(ptlHimetric.X, PixPerInch.X, 2540);
- ptfContainer.Y := MulDiv(ptlHimetric.Y, PixPerInch.Y, 2540);
- end else
- begin
- ptlHimetric.X := Round(ptfContainer.X * 2540 / PixPerInch.X);
- ptlHimetric.Y := Round(ptfContainer.Y * 2540 / PixPerInch.Y);
- end;
- Result := S_OK;
- end;
-
- function TOleControlSite.TranslateAccelerator(msg: PMsg; grfModifiers: Longint): HResult;
- begin
- Result := E_NOTIMPL;
- end;
-
- function TOleControlSite.OnFocus(fGotFocus: BOOL): HResult;
- begin
- Result := E_NOTIMPL;
- end;
-
- function TOleControlSite.ShowPropertyFrame: HResult;
- begin
- Result := E_NOTIMPL;
- end;
-
- { TOleInPlaceSite }
-
- constructor TOleInPlaceSite.Create(Control: TOleControl);
- begin
- FControl := Control;
- end;
-
- function TOleInPlaceSite.QueryInterface(const iid: TIID; var obj): HResult;
- begin
- Result := FControl.QueryInterface(iid, obj);
- end;
-
- function TOleInPlaceSite.AddRef: Longint;
- begin
- Result := FControl.AddRef;
- end;
-
- function TOleInPlaceSite.Release: Longint;
- begin
- Result := FControl.Release;
- end;
-
- function TOleInPlaceSite.GetWindow(var wnd: HWnd): HResult;
- begin
- if FControl.Parent <> nil then
- begin
- wnd := FControl.Parent.Handle;
- Result := S_OK;
- end else
- begin
- wnd := 0;
- Result := E_FAIL;
- end;
- end;
-
- function TOleInPlaceSite.ContextSensitiveHelp(fEnterMode: BOOL): HResult;
- begin
- Result := S_OK;
- end;
-
- function TOleInPlaceSite.CanInPlaceActivate: HResult;
- begin
- Result := S_OK;
- end;
-
- function TOleInPlaceSite.OnInPlaceActivate: HResult;
- begin
- with FControl do
- begin
- FOleObject.QueryInterface(IID_IOleInPlaceObject, FOleInPlaceObject);
- FOleObject.QueryInterface(IID_IOleInPlaceActiveObject, FOleInPlaceActiveObject);
- end;
- Result := S_OK;
- end;
-
- function TOleInPlaceSite.OnUIActivate: HResult;
- begin
- FControl.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;
- begin
- with FControl do
- begin
- frame := FOleInPlaceFrame;
- FOleInPlaceFrame.AddRef;
- doc := nil;
- rcPosRect := BoundsRect;
- SetRect(rcClipRect, 0, 0, 32767, 32767);
- with frameInfo do
- begin
- fMDIApp := False;
- hWndFrame := GetParentForm(FControl).Handle;
- hAccel := 0;
- cAccelEntries := 0;
- 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
- FControl.FOleInPlaceFrame.SetMenu(0, 0, 0);
- FControl.SetUIActive(False);
- Result := S_OK;
- end;
-
- function TOleInPlaceSite.OnInPlaceDeactivate: HResult;
- begin
- ReleaseObject(FControl.FOleInPlaceActiveObject);
- ReleaseObject(FControl.FOleInPlaceObject);
- Result := S_OK;
- end;
-
- function TOleInPlaceSite.DiscardUndoState: HResult;
- begin
- Result := E_NOTIMPL;
- end;
-
- function TOleInPlaceSite.DeactivateAndUndo: HResult;
- begin
- FControl.FOleInPlaceObject.UIDeactivate;
- Result := S_OK;
- end;
-
- function TOleInPlaceSite.OnPosRectChange(const rcPosRect: TRect): HResult;
- begin
- FControl.FOleInPlaceObject.SetObjectRects(rcPosRect,
- Rect(0, 0, 32767, 32767));
- Result := S_OK;
- end;
-
- { TOleInPlaceFrame }
-
- constructor TOleInPlaceFrame.Create(Control: TOleControl);
- begin
- FControl := Control;
- 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 := FControl.AddRef;
- end;
-
- function TOleInPlaceFrame.Release: Longint;
- begin
- Result := FControl.Release;
- end;
-
- function TOleInPlaceFrame.GetWindow(var wnd: HWnd): HResult;
- begin
- wnd := GetParentForm(FControl).Handle;
- Result := S_OK;
- end;
-
- function TOleInPlaceFrame.ContextSensitiveHelp(fEnterMode: BOOL): HResult;
- begin
- Result := S_OK;
- end;
-
- function TOleInPlaceFrame.GetBorder(var rectBorder: TRect): HResult;
- begin
- Result := INPLACE_E_NOTOOLSPACE;
- end;
-
- function TOleInPlaceFrame.RequestBorderSpace(const borderwidths: TRect): HResult;
- begin
- Result := INPLACE_E_NOTOOLSPACE;
- end;
-
- function TOleInPlaceFrame.SetBorderSpace(pborderwidths: PRect): HResult;
- begin
- Result := E_NOTIMPL;
- end;
-
- function TOleInPlaceFrame.SetActiveObject(activeObject: IOleInPlaceActiveObject;
- pszObjName: POleStr): HResult;
- begin
- Result := S_OK;
- end;
-
- function TOleInPlaceFrame.InsertMenus(hmenuShared: HMenu;
- var menuWidths: TOleMenuGroupWidths): HResult;
- var
- Menu: TMainMenu;
- begin
- Menu := FControl.GetMainMenu;
- 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 := FControl.GetMainMenu;
- 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;
- begin
- Result := S_OK;
- end;
-
- function TOleInPlaceFrame.EnableModeless(fEnable: BOOL): HResult;
- begin
- Result := S_OK;
- end;
-
- function TOleInPlaceFrame.TranslateAccelerator(var msg: TMsg; wID: Word): HResult;
- begin
- Result := S_FALSE;
- end;
-
- { TAmbientDispatch }
-
- constructor TAmbientDispatch.Create(Control: TOleControl);
- begin
- FControl := Control;
- end;
-
- function TAmbientDispatch.QueryInterface(const iid: TIID; var obj): HResult;
- begin
- Result := FControl.QueryInterface(iid, obj);
- end;
-
- function TAmbientDispatch.AddRef: Longint;
- begin
- Result := FControl.AddRef;
- end;
-
- function TAmbientDispatch.Release: Longint;
- begin
- Result := FControl.Release;
- end;
-
- function TAmbientDispatch.GetTypeInfoCount(var ctinfo: Integer): HResult;
- begin
- ctinfo := 0;
- Result := S_OK;
- end;
-
- function TAmbientDispatch.GetTypeInfo(itinfo: Integer; lcid: TLCID;
- var tinfo: ITypeInfo): HResult;
- begin
- tinfo := nil;
- Result := E_NOTIMPL;
- end;
-
- function TAmbientDispatch.GetIDsOfNames(const iid: TIID;
- rgszNames: POleStrList; cNames: Integer; lcid: TLCID;
- rgdispid: PDispIDList): HResult;
- begin
- Result := E_NOTIMPL;
- end;
-
- function TAmbientDispatch.Invoke(dispIDMember: TDispID; const iid: TIID;
- lcid: TLCID; flags: Word; var dispParams: TDispParams; varResult: PVariant;
- excepInfo: PExcepInfo; argErr: PInteger): HResult;
- begin
- if (Flags and DISPATCH_PROPERTYGET <> 0) and (VarResult <> nil) then
- begin
- Result := S_OK;
- with FControl do
- case DispIDMember of
- DISPID_AMBIENT_BACKCOLOR:
- VarResult^ := Color;
- DISPID_AMBIENT_DISPLAYNAME:
- VarResult^ := StringToVarOleStr(Name);
- DISPID_AMBIENT_FONT:
- if (Parent <> nil) and ParentFont then
- VarResult^ := FontToOleFont(TOleControl(Parent).Font) else
- Result := DISP_E_MEMBERNOTFOUND;
- DISPID_AMBIENT_FORECOLOR:
- VarResult^ := Font.Color;
- DISPID_AMBIENT_LOCALEID:
- VarResult^ := GetUserDefaultLCID;
- DISPID_AMBIENT_MESSAGEREFLECT:
- VarResult^ := True;
- DISPID_AMBIENT_USERMODE:
- VarResult^ := not (csDesigning in ComponentState);
- DISPID_AMBIENT_UIDEAD:
- VarResult^ := csDesigning in ComponentState;
- DISPID_AMBIENT_SHOWGRABHANDLES:
- VarResult^ := False;
- DISPID_AMBIENT_SHOWHATCHING:
- VarResult^ := False;
- DISPID_AMBIENT_SUPPORTSMNEMONICS:
- VarResult^ := True;
- DISPID_AMBIENT_AUTOCLIP:
- VarResult^ := True;
- else
- Result := DISP_E_MEMBERNOTFOUND;
- end;
- end else
- Result := DISP_E_MEMBERNOTFOUND;
- end;
-
- { TEventDispatch }
-
- constructor TEventDispatch.Create(Control: TOleControl);
- begin
- FControl := Control;
- end;
-
- function TEventDispatch.QueryInterface(const iid: TIID; var obj): HResult;
- begin
- Result := FControl.QueryInterface(iid, obj);
- end;
-
- function TEventDispatch.AddRef: Longint;
- begin
- Result := FControl.AddRef;
- end;
-
- function TEventDispatch.Release: Longint;
- begin
- Result := FControl.Release;
- end;
-
- function TEventDispatch.GetTypeInfoCount(var ctinfo: Integer): HResult;
- begin
- ctinfo := 0;
- Result := S_OK;
- end;
-
- function TEventDispatch.GetTypeInfo(itinfo: Integer; lcid: TLCID;
- var tinfo: ITypeInfo): HResult;
- begin
- tinfo := nil;
- Result := E_NOTIMPL;
- end;
-
- function TEventDispatch.GetIDsOfNames(const iid: TIID;
- rgszNames: POleStrList; cNames: Integer; lcid: TLCID;
- rgdispid: PDispIDList): HResult;
- begin
- Result := E_NOTIMPL;
- end;
-
- function TEventDispatch.Invoke(dispIDMember: TDispID; const iid: TIID;
- lcid: TLCID; flags: Word; var dispParams: TDispParams; varResult: PVariant;
- excepInfo: PExcepInfo; argErr: PInteger): HResult;
- begin
- if (dispIDMember >= DISPID_MOUSEUP) and (dispIDMember <= DISPID_CLICK) then
- FControl.StandardEvent(dispIDMember, dispParams) else
- FControl.InvokeEvent(dispIDMember, dispParams);
- Result := S_OK;
- end;
-
- { TPropertyNotifySink }
-
- constructor TPropertyNotifySink.Create(Control: TOleControl);
- begin
- FControl := Control;
- end;
-
- function TPropertyNotifySink.QueryInterface(const iid: TIID; var obj): HResult;
- begin
- Result := FControl.QueryInterface(iid, obj);
- end;
-
- function TPropertyNotifySink.AddRef: Longint;
- begin
- Result := FControl.AddRef;
- end;
-
- function TPropertyNotifySink.Release: Longint;
- begin
- Result := FControl.Release;
- end;
-
- function TPropertyNotifySink.OnChanged(dispid: TDispID): HResult;
- begin
- with FControl do
- case dispid of
- DISPID_BACKCOLOR:
- if not FUpdatingColor then
- begin
- FUpdatingColor := True;
- try
- Color := GetIntegerProp(DISPID_BACKCOLOR);
- finally
- FUpdatingColor := False;
- end;
- end;
- DISPID_ENABLED:
- if not FUpdatingEnabled then
- begin
- FUpdatingEnabled := True;
- try
- Enabled := GetOleBoolProp(DISPID_ENABLED);
- finally
- FUpdatingEnabled := False;
- end;
- end;
- DISPID_FONT:
- if not FUpdatingFont then
- begin
- FUpdatingFont := True;
- try
- OleFontToFont(GetVariantProp(DISPID_FONT), Font);
- finally
- FUpdatingFont := False;
- end;
- end;
- DISPID_FORECOLOR:
- if not FUpdatingFont then
- begin
- FUpdatingFont := True;
- try
- Font.Color := GetIntegerProp(DISPID_FORECOLOR);
- finally
- FUpdatingFont := False;
- end;
- end;
- end;
- Result := S_OK;
- end;
-
- function TPropertyNotifySink.OnRequestEdit(dispid: TDispID): HResult;
- begin
- Result := S_OK;
- end;
-
- { TSimpleFrameSite }
-
- constructor TSimpleFrameSite.Create(Control: TOleControl);
- begin
- FControl := Control;
- end;
-
- function TSimpleFrameSite.QueryInterface(const iid: TIID; var obj): HResult;
- begin
- Result := FControl.QueryInterface(iid, obj);
- end;
-
- function TSimpleFrameSite.AddRef: Longint;
- begin
- Result := FControl.AddRef;
- end;
-
- function TSimpleFrameSite.Release: Longint;
- begin
- Result := FControl.Release;
- end;
-
- function TSimpleFrameSite.PreMessageFilter(wnd: HWnd; msg, wp, lp: Integer;
- var res: Integer; var Cookie: Longint): HResult;
- begin
- Result := S_OK;
- end;
-
- function TSimpleFrameSite.PostMessageFilter(wnd: HWnd; msg, wp, lp: Integer;
- var res: Integer; Cookie: Longint): HResult;
- begin
- Result := S_OK;
- end;
-
- { TEnumPropDesc }
-
- constructor TEnumPropDesc.Create(DispID, ValueCount: Integer;
- TypeInfo: ITypeInfo);
- var
- I: Integer;
- VarDesc: PVarDesc;
- BStr: TBStr;
- begin
- FDispID := DispID;
- FValueCount := ValueCount;
- FValues := AllocMem(ValueCount * SizeOf(TEnumValue));
- for I := 0 to ValueCount - 1 do
- begin
- OleCheck(TypeInfo.GetVarDesc(I, VarDesc));
- try
- OleCheck(TypeInfo.GetDocumentation(VarDesc^.memid, @BStr,
- nil, nil, nil));
- try
- with FValues^[I] do
- begin
- Value := TVarData(VarDesc^.lpVarValue^).VInteger;
- OleStrToStrVar(BStr, Ident);
- while (Length(Ident) > 1) and (Ident[1] = '_') do
- Delete(Ident, 1, 1);
- end;
- finally
- SysFreeString(BStr);
- end;
- finally
- TypeInfo.ReleaseVarDesc(VarDesc);
- end;
- end;
- end;
-
- destructor TEnumPropDesc.Destroy;
- begin
- if FValues <> nil then
- begin
- Finalize(FValues^[0], FValueCount);
- FreeMem(FValues, FValueCount * SizeOf(TEnumValue));
- end;
- end;
-
- procedure TEnumPropDesc.GetStrings(Proc: TGetStrProc);
- var
- I: Integer;
- begin
- for I := 0 to FValueCount - 1 do
- with FValues^[I] do Proc(Format('%d - %s', [Value, Ident]));
- end;
-
- function TEnumPropDesc.StringToValue(const S: string): Integer;
- var
- I: Integer;
- begin
- I := 1;
- while (I <= Length(S)) and (S[I] in ['0'..'9', '-']) do Inc(I);
- if I > 1 then
- begin
- Result := StrToInt(Copy(S, 1, I - 1));
- for I := 0 to FValueCount - 1 do
- if Result = FValues^[I].Value then Exit;
- end else
- for I := 0 to FValueCount - 1 do
- with FValues^[I] do
- if AnsiCompareText(S, Ident) = 0 then
- begin
- Result := Value;
- Exit;
- end;
- raise EOleError.CreateResFmt(SBadPropValue, [S]);
- end;
-
- function TEnumPropDesc.ValueToString(V: Integer): string;
- var
- I: Integer;
- begin
- for I := 0 to FValueCount - 1 do
- with FValues^[I] do
- if V = Value then
- begin
- Result := Format('%d - %s', [Value, Ident]);
- Exit;
- end;
- Result := IntToStr(V);
- end;
-
- { TOleControl }
-
- constructor TOleControl.Create(AOwner: TComponent);
- var
- W, H: Integer;
- Extent: TPoint;
- begin
- inherited Create(AOwner);
- Include(FComponentStyle, csCheckPropAvail);
- InitControlData;
- Inc(FControlData^.InstanceCount);
- FOleClientSite := TOleClientSite.Create(Self);
- FOleControlSite := TOleControlSite.Create(Self);
- FOleInPlaceSite := TOleInPlaceSite.Create(Self);
- FOleInPlaceFrame := TOleInPlaceFrame.Create(Self);
- FAmbientDispatch := TAmbientDispatch.Create(Self);
- FEventDispatch := TEventDispatch.Create(Self);
- FPropertyNotifySink := TPropertyNotifySink.Create(Self);
- FSimpleFrameSite := TSimpleFrameSite.Create(Self);
- CreateInstance;
- OleCheck(FOleObject.SetClientSite(FOleClientSite));
- OleCheck(FOleObject.QueryInterface(IID_IPersistStreamInit,
- FPersistStream));
- OleCheck(FOleObject.GetMiscStatus(DVASPECT_CONTENT, FMiscStatus));
- OleCheck(FOleObject.GetExtent(DVASPECT_CONTENT, Extent));
- W := MulDiv(Extent.X, PixPerInch.X, 2540);
- H := MulDiv(Extent.Y, PixPerInch.Y, 2540);
- if FMiscStatus and OLEMISC_INVISIBLEATRUNTIME <> 0 then
- begin
- Visible := False;
- if W > 32 then W := 32;
- if H > 32 then H := 32;
- end;
- inherited SetBounds(Left, Top, W, H);
- if FMiscStatus and OLEMISC_SIMPLEFRAME <> 0 then
- ControlStyle := [csAcceptsControls, csDoubleClicks, csNoStdEvents] else
- ControlStyle := [csDoubleClicks, csNoStdEvents];
- TabStop := FMiscStatus and (OLEMISC_ACTSLIKELABEL or
- OLEMISC_NOUIACTIVATE) = 0;
- end;
-
- destructor TOleControl.Destroy;
- begin
- if FOleObject <> nil then FOleObject.Close(OLECLOSE_NOSAVE);
- DestroyControl;
- DestroyStorage;
- ReleaseObject(FPersistStream);
- if FOleObject <> nil then FOleObject.SetClientSite(nil);
- ReleaseObject(FOleObject);
- FSimpleFrameSite.Free;
- FPropertyNotifySink.Free;
- FEventDispatch.Free;
- FAmbientDispatch.Free;
- FOleInPlaceFrame.Free;
- FOleInPlaceSite.Free;
- FOleControlSite.Free;
- FOleClientSite.Free;
- Dec(FControlData^.InstanceCount);
- if FControlData^.InstanceCount = 0 then DestroyEnumPropDescs;
- inherited Destroy;
- end;
-
- function TOleControl.AddRef: Longint;
- begin
- Inc(FRefCount);
- Result := FRefCount;
- end;
-
- procedure TOleControl.BrowseProperties;
- begin
- DoObjectVerb(OLEIVERB_PROPERTIES);
- end;
-
- procedure TOleControl.CreateControl;
- var
- Stream: IStream;
- begin
- if FOleControl = nil then
- try
- if FObjectData = 0 then OleCheck(FPersistStream.InitNew) else
- begin
- OleCheck(CreateStreamOnHGlobal(FObjectData, False, Stream));
- try
- OleCheck(FPersistStream.Load(Stream));
- finally
- Stream.Release;
- end;
- DestroyStorage;
- end;
- OleCheck(FOleObject.QueryInterface(IID_IOleControl, FOleControl));
- OleCheck(FOleObject.QueryInterface(IID_IDispatch, FControlDispatch));
- FOleObject.QueryInterface(IID_IPerPropertyBrowsing, FPropBrowsing);
- InterfaceConnect(FOleObject, IID_IPropertyNotifySink,
- FPropertyNotifySink, FPropConnection);
- InterfaceConnect(FOleObject, FControlData^.EventIID,
- FEventDispatch, FEventsConnection);
- if FControlData^.Flags and cfBackColor <> 0 then
- FPropertyNotifySink.OnChanged(DISPID_BACKCOLOR);
- if FControlData^.Flags and cfEnabled <> 0 then
- FPropertyNotifySink.OnChanged(DISPID_ENABLED);
- if FControlData^.Flags and cfFont <> 0 then
- FPropertyNotifySink.OnChanged(DISPID_FONT);
- if FControlData^.Flags and cfForeColor <> 0 then
- FPropertyNotifySink.OnChanged(DISPID_FORECOLOR);
- FOleObject.SetExtent(DVASPECT_CONTENT, Point(
- MulDiv(Width, 2540, PixPerInch.X),
- MulDiv(Height, 2540, PixPerInch.Y)));
- except
- DestroyControl;
- raise;
- end;
- end;
-
- procedure TOleControl.CreateEnumPropDescs;
- var
- I: Integer;
- TypeInfo, RefInfo: ITypeInfo;
- TypeAttr, RefAttr: PTypeAttr;
- VarDesc: PVarDesc;
- begin
- CreateControl;
- FControlData^.EnumPropDescs := TList.Create;
- try
- OleCheck(FControlDispatch.GetTypeInfo(0, 0, TypeInfo));
- try
- OleCheck(TypeInfo.GetTypeAttr(TypeAttr));
- try
- for I := 0 to TypeAttr^.cVars - 1 do
- begin
- OleCheck(TypeInfo.GetVarDesc(I, VarDesc));
- try
- if VarDesc^.elemdescVar.tdesc.vt = VT_USERDEFINED then
- begin
- OleCheck(TypeInfo.GetRefTypeInfo(
- VarDesc^.elemdescVar.tdesc.hreftype, RefInfo));
- try
- OleCheck(RefInfo.GetTypeAttr(RefAttr));
- try
- if RefAttr^.typekind = TKIND_ENUM then
- FControlData^.EnumPropDescs.Expand.Add(
- TEnumPropDesc.Create(VarDesc^.memid,
- RefAttr^.cVars, RefInfo));
- finally
- RefInfo.ReleaseTypeAttr(RefAttr);
- end;
- finally
- RefInfo.Release;
- end;
- end;
- finally
- TypeInfo.ReleaseVarDesc(VarDesc);
- end;
- end;
- finally
- TypeInfo.ReleaseTypeAttr(TypeAttr);
- end;
- finally
- TypeInfo.Release;
- end;
- except
- DestroyEnumPropDescs;
- raise;
- end;
- end;
-
- procedure TOleControl.CreateInstance;
- var
- ClassFactory2: IClassFactory2;
- LicKeyStr: TBStr;
-
- procedure LicenseCheck(Status: HResult; Ident: Integer);
- begin
- if Status = CLASS_E_NOTLICENSED then
- raise EOleError.CreateResFmt(Ident, [ClassName]);
- OleCheck(Status);
- end;
-
- begin
- if not (csDesigning in ComponentState) and
- (FControlData^.LicenseKey <> nil) then
- begin
- LicKeyStr := nil;
- OleCheck(CoGetClassObject(FControlData^.ClassID, CLSCTX_INPROC_SERVER or
- CLSCTX_LOCAL_SERVER, nil, IID_IClassFactory2, ClassFactory2));
- try
- LicKeyStr := SysAllocString(FControlData^.LicenseKey);
- LicenseCheck(ClassFactory2.CreateInstanceLic(nil, nil, IID_IOleObject,
- LicKeyStr, FOleObject), SInvalidLicense);
- finally
- if LicKeyStr <> nil then SysFreeString(LicKeyStr);
- ClassFactory2.Release;
- end;
- end else
- LicenseCheck(CoCreateInstance(FControlData^.ClassID, nil,
- CLSCTX_INPROC_SERVER or CLSCTX_LOCAL_SERVER, IID_IOleObject,
- FOleObject), SNotLicensed);
- end;
-
- procedure TOleControl.CreateStorage;
- var
- Stream: IStream;
- begin
- DestroyStorage;
- FObjectData := GlobalAlloc(GMEM_MOVEABLE, 0);
- if FObjectData = 0 then OutOfMemoryError;
- try
- OleCheck(CreateStreamOnHGlobal(FObjectData, False, Stream));
- try
- OleCheck(FPersistStream.Save(Stream, True));
- finally
- Stream.Release;
- end;
- except
- DestroyStorage;
- raise;
- end;
- end;
-
- procedure TOleControl.CreateWnd;
- begin
- CreateControl;
- if FMiscStatus and OLEMISC_INVISIBLEATRUNTIME = 0 then
- begin
- FOleObject.DoVerb(OLEIVERB_INPLACEACTIVATE, nil, FOleClientSite, 0,
- Parent.Handle, BoundsRect);
- if FOleInPlaceObject = nil then
- raise EOleError.CreateRes(SCannotActivate);
- HookControlWndProc;
- if not Visible and IsWindowVisible(Handle) then
- ShowWindow(Handle, SW_HIDE);
- end else
- inherited CreateWnd;
- end;
-
- procedure TOleControl.DefaultHandler(var Message);
- begin
- if HandleAllocated then
- with TMessage(Message) do
- begin
- if (Msg >= CN_BASE) and (Msg < CN_BASE + WM_USER) then
- Msg := Msg - (CN_BASE - OCM_BASE);
- if FMiscStatus and OLEMISC_SIMPLEFRAME = 0 then
- begin
- Result := CallWindowProc(DefWndProc, Handle, Msg, WParam, LParam);
- Exit;
- end;
- end;
- inherited DefaultHandler(Message);
- end;
-
- procedure TOleControl.DefineProperties(Filer: TFiler);
- begin
- inherited DefineProperties(Filer);
- Filer.DefineBinaryProperty('ControlData', ReadData, WriteData, FOleObject <> nil);
- end;
-
- procedure TOleControl.DesignModified;
- var
- Form: TForm;
- begin
- Form := GetParentForm(Self);
- if (Form <> nil) and (Form.Designer <> nil) then Form.Designer.Modified;
- end;
-
- procedure TOleControl.DestroyControl;
- begin
- InterfaceDisconnect(FOleObject, FControlData^.EventIID, FEventsConnection);
- InterfaceDisconnect(FOleObject, IID_IPropertyNotifySink, FPropConnection);
- ReleaseObject(FPropBrowsing);
- ReleaseObject(FControlDispatch);
- ReleaseObject(FOleControl);
- end;
-
- procedure TOleControl.DestroyEnumPropDescs;
- var
- I: Integer;
- begin
- with FControlData^ do
- if EnumPropDescs <> nil then
- begin
- for I := 0 to EnumPropDescs.Count - 1 do
- TEnumPropDesc(EnumPropDescs[I]).Free;
- EnumPropDescs.Free;
- EnumPropDescs := nil;
- end;
- end;
-
- procedure TOleControl.DestroyStorage;
- begin
- if FObjectData <> 0 then
- begin
- GlobalFree(FObjectData);
- FObjectData := 0;
- end;
- end;
-
- procedure TOleControl.DestroyWindowHandle;
- begin
- if FMiscStatus and OLEMISC_INVISIBLEATRUNTIME = 0 then
- begin
- SetWindowLong(WindowHandle, GWL_WNDPROC, Longint(DefWndProc));
- if FOleObject <> nil then FOleObject.Close(OLECLOSE_NOSAVE);
- WindowHandle := 0;
- end else
- inherited DestroyWindowHandle;
- end;
-
- procedure TOleControl.DoObjectVerb(Verb: Integer);
- var
- ActiveWindow: HWnd;
- WindowList: Pointer;
- begin
- CreateControl;
- ActiveWindow := GetActiveWindow;
- WindowList := DisableTaskWindows(0);
- try
- OleCheck(FOleObject.DoVerb(Verb, nil, FOleClientSite, 0,
- Parent.Handle, BoundsRect));
- finally
- EnableTaskWindows(WindowList);
- SetActiveWindow(ActiveWindow);
- end;
- if FPersistStream.IsDirty <> S_FALSE then DesignModified;
- end;
-
- function TOleControl.GetColorProp(Index: Integer): TColor;
- begin
- Result := GetIntegerProp(Index);
- end;
-
- function TOleControl.GetCurrencyProp(Index: Integer): TCurrency;
- var
- Temp: TVarData;
- begin
- GetProperty(Index, Temp);
- Result := Temp.VCurrency;
- end;
-
- function TOleControl.GetDoubleProp(Index: Integer): Double;
- var
- Temp: TVarData;
- begin
- GetProperty(Index, Temp);
- Result := Temp.VDouble;
- end;
-
- function TOleControl.GetEnumPropDesc(DispID: Integer): TEnumPropDesc;
- var
- I: Integer;
- begin
- with FControlData^ do
- begin
- if EnumPropDescs = nil then CreateEnumPropDescs;
- for I := 0 to EnumPropDescs.Count - 1 do
- begin
- Result := EnumPropDescs[I];
- if Result.FDispID = DispID then Exit;
- end;
- Result := nil;
- end;
- end;
-
- procedure TOleControl.GetEventMethod(DispID: TDispID; var Method: TMethod);
- asm
- PUSH EBX
- PUSH ESI
- PUSH EDI
- MOV EBX,EAX
- MOV ESI,[EBX].TOleControl.FControlData
- MOV EDI,[ESI].TControlData.EventCount
- MOV ESI,[ESI].TControlData.EventDispIDs
- XOR EAX,EAX
- JMP @@1
- @@0: CMP EDX,[ESI].Integer[EAX*4]
- JE @@2
- INC EAX
- @@1: CMP EAX,EDI
- JNE @@0
- XOR EAX,EAX
- XOR EDX,EDX
- JMP @@3
- @@2: MOV EDX,[EBX].TOleControl.FEvents[4][EAX*8].TMethod.Data
- MOV EAX,[EBX].TOleControl.FEvents[4][EAX*8].TMethod.Code
- @@3: MOV [ECX].TMethod.Code,EAX
- MOV [ECX].TMethod.Data,EDX
- POP EDI
- POP ESI
- POP EBX
- end;
-
- procedure Exchange(var A,B); register;
- asm
- MOV ECX, [EDX]
- XCHG ECX, [EAX]
- MOV [EDX], ECX
- end;
-
- { TOleControl.GetHelpContext: Fetch the help file name and help context
- id of the given member (property, event, or method) of the Ole Control from
- the control's ITypeInfo interfaces. GetHelpContext returns False if
- the member name is not found in the control's ITypeInfo.
- To obtain a help context for the entire control class, pass an empty
- string as the Member name. }
-
- function TOleControl.GetHelpContext(Member: String;
- var HelpCtx: Integer; var HelpFile: String): Boolean;
- var
- ProvideClassInfo: IProvideClassInfo;
- TypeInfo: ITypeInfo;
- HlpFile: TBStr;
- ImplTypes, MemberID: Integer;
- TypeAttr: PTypeAttr;
-
- function Find(const MemberStr: string; var TypeInfo: ITypeInfo): Boolean;
- var
- Code: HResult;
- I, Flags: Integer;
- RefType: HRefType;
- Name: TBStr;
- Temp: ITypeInfo;
- begin
- Result := False;
- Name := StringToOleStr(Member);
- try
- I := 0;
- while (I < ImplTypes) do
- begin
- OleCheck(TypeInfo.GetImplTypeFlags(I, Flags));
- if Flags and (IMPLTYPEFLAG_FDEFAULT or IMPLTYPEFLAG_FSOURCE) <> 0 then
- begin
- OleCheck(TypeInfo.GetRefTypeOfImplType(I, RefType));
- OleCheck(TypeInfo.GetRefTypeInfo(RefType, Temp));
- try
- Code := Temp.GetIDsOfNames(@Name, 1, @MemberID);
- if Code <> DISP_E_UNKNOWNNAME then
- begin
- OleCheck(Code);
- Exchange(TypeInfo, Temp);
- Result := True;
- Break;
- end;
- finally
- Temp.Release;
- end;
- end;
- Inc(I);
- end;
- finally
- SysFreeString(Name);
- end;
- end;
-
- begin
- Result := False;
- HelpCtx := 0;
- HelpFile := '';
- CreateControl;
- OleCheck(FOleObject.QueryInterface(IID_IProvideClassInfo, ProvideClassInfo));
- try
- OleCheck(ProvideClassInfo.GetClassInfo(TypeInfo));
- try
- MemberID := MEMBERID_NIL;
- if Length(Member) > 0 then
- begin
- OleCheck(TypeInfo.GetTypeAttr(TypeAttr));
- ImplTypes := TypeAttr.cImplTypes;
- TypeInfo.ReleaseTypeAttr(TypeAttr);
- Result := Find(Member, TypeInfo);
- if (not Result) and (Member[Length(Member)] = '_') then
- begin
- Delete(Member, Length(Member)-1, 1);
- Result := Find(Member, TypeInfo);
- end;
- if (not Result) and (Pos('On', Member) = 1) then
- begin
- Delete(Member, 1, 2);
- Result := Find(Member, TypeInfo);
- end;
- if not Result then Exit;
- end;
- OleCheck(TypeInfo.GetDocumentation(MemberID, nil, nil, @HelpCtx, @HlpFile));
- HelpFile := OleStrToString(HlpFile);
- SysFreeString(HlpFile);
- finally
- TypeInfo.Release;
- end;
- finally
- ProvideClassInfo.Release;
- end;
- Result := True;
- end;
-
- function TOleControl.GetIntegerProp(Index: Integer): Integer;
- var
- Temp: TVarData;
- begin
- GetProperty(Index, Temp);
- Result := Temp.VInteger;
- end;
-
- function TOleControl.GetMainMenu: TMainMenu;
- var
- Form: TForm;
- begin
- Result := nil;
- Form := GetParentForm(Self);
- if Form <> nil then
- if Form.FormStyle <> fsMDIChild then
- Result := Form.Menu
- else
- if Application.MainForm <> nil then
- Result := Application.MainForm.Menu;
- end;
-
- procedure TOleControl.GetObjectVerbs(List: TStrings);
- var
- I: Integer;
- S: string;
- EnumOleVerb: IEnumOleVerb;
- OleVerb: TOleVerb;
- begin
- CreateControl;
- List.Clear;
- if FOleObject.EnumVerbs(EnumOleVerb) = 0 then
- try
- while (EnumOleVerb.Next(1, OleVerb, nil) = 0) and
- (OleVerb.grfAttribs and OLEVERBATTRIB_ONCONTAINERMENU <> 0) do
- begin
- S := WideCharToString(OleVerb.lpszVerbName);
- for I := Length(S) downto 1 do if S[I] = '&' then Delete(S, I, 1);
- List.AddObject(S, TObject(OleVerb.lVerb));
- end;
- finally
- EnumOleVerb.Release;
- end;
- end;
-
- function TOleControl.GetOleBoolProp(Index: Integer): TOleBool;
- var
- Temp: TVarData;
- begin
- GetProperty(Index, Temp);
- Result := Temp.VBoolean;
- end;
-
- function TOleControl.GetOleDateProp(Index: Integer): TOleDate;
- var
- Temp: TVarData;
- begin
- GetProperty(Index, Temp);
- Result := Temp.VDate;
- end;
-
- function TOleControl.GetOleEnumProp(Index: Integer): TOleEnum;
- begin
- Result := GetSmallintProp(Index);
- end;
-
- function TOleControl.GetOleObject: Variant;
- begin
- CreateControl;
- Result := VarFromInterface(FOleObject);
- end;
-
- function TOleControl.GetPropDisplayString(DispID: Integer): string;
- var
- BStr: TBStr;
- begin
- CreateControl;
- if (FPropBrowsing <> nil) and
- (FPropBrowsing.GetDisplayString(DispID, BStr) = 0) then
- begin
- Result := OleStrToString(BStr);
- SysFreeString(BStr);
- end else
- Result := GetStringProp(DispID);
- end;
-
- procedure TOleControl.GetPropDisplayStrings(DispID: Integer; List: TStrings);
- var
- Strings: TCAPOleStr;
- Cookies: TCALongint;
- I: Integer;
- begin
- CreateControl;
- List.Clear;
- if (FPropBrowsing <> nil) and
- (FPropBrowsing.GetPredefinedStrings(DispID, Strings, Cookies) = 0) then
- try
- for I := 0 to Strings.cElems - 1 do
- List.AddObject(WideCharToString(Strings.pElems^[I]),
- TObject(Cookies.pElems^[I]));
- finally
- for I := 0 to Strings.cElems - 1 do
- CoTaskMemFree(Strings.pElems^[I]);
- CoTaskMemFree(Strings.pElems);
- CoTaskMemFree(Cookies.pElems);
- end;
- end;
-
- procedure TOleControl.GetProperty(Index: Integer; var Value: TVarData);
- const
- DispParams: TDispParams = ();
- var
- Status: HResult;
- ExcepInfo: TExcepInfo;
- begin
- CreateControl;
- FillChar(ExcepInfo, SizeOf(ExcepInfo), 0);
- Value.VType := varEmpty;
- Status := FControlDispatch.Invoke(Index, GUID_NULL, 0,
- DISPATCH_PROPERTYGET, DispParams, @Value, @ExcepInfo, nil);
- if Status <> 0 then DispInvokeError(Status, ExcepInfo);
- end;
-
- function TOleControl.GetSingleProp(Index: Integer): Single;
- var
- Temp: TVarData;
- begin
- GetProperty(Index, Temp);
- Result := Temp.VSingle;
- end;
-
- function TOleControl.GetSmallintProp(Index: Integer): Smallint;
- var
- Temp: TVarData;
- begin
- GetProperty(Index, Temp);
- Result := Temp.VSmallint;
- end;
-
- function TOleControl.GetStringProp(Index: Integer): string;
- var
- Temp: TVarData;
- begin
- GetProperty(Index, Temp);
- try
- OleStrToStrVar(Temp.VOleStr, Result);
- finally
- SysFreeString(Temp.VOleStr);
- end;
- end;
-
- function TOleControl.GetVariantProp(Index: Integer): Variant;
- begin
- VarClear(Result);
- GetProperty(Index, TVarData(Result));
- end;
-
- procedure TOleControl.HookControlWndProc;
- var
- WndHandle: HWnd;
- begin
- if (FOleInPlaceObject <> nil) and (WindowHandle = 0) then
- begin
- WndHandle := 0;
- FOleInPlaceObject.GetWindow(WndHandle);
- if WndHandle = 0 then raise EOleError.CreateRes(SNoWindowHandle);
- WindowHandle := WndHandle;
- DefWndProc := Pointer(GetWindowLong(WindowHandle, GWL_WNDPROC));
- CreationControl := Self;
- SetWindowLong(WindowHandle, GWL_WNDPROC, Longint(@InitWndProc));
- SendMessage(WindowHandle, WM_NULL, 0, 0);
- end;
- end;
-
- procedure CallEventMethod(const EventInfo: TEventInfo);
- asm
- PUSH EBX
- PUSH ESI
- PUSH EBP
- MOV EBP,ESP
- MOV EBX,EAX
- MOV EDX,[EBX].TEventInfo.ArgCount
- TEST EDX,EDX
- JE @@5
- XOR EAX,EAX
- LEA ESI,[EBX].TEventInfo.Args
- @@1: MOV AL,[ESI].TEventArg.Kind
- CMP AL,1
- JA @@2
- JE @@3
- TEST AH,AH
- JNE @@3
- MOV ECX,[ESI].Integer[4]
- MOV AH,1
- JMP @@4
- @@2: PUSH [ESI].Integer[8]
- @@3: PUSH [ESI].Integer[4]
- @@4: ADD ESI,12
- DEC EDX
- JNE @@1
- @@5: MOV EDX,[EBX].TEventInfo.Sender
- MOV EAX,[EBX].TEventInfo.Method.Data
- CALL [EBX].TEventInfo.Method.Code
- MOV ESP,EBP
- POP EBP
- POP ESI
- POP EBX
- end;
-
- procedure TOleControl.InvokeEvent(DispID: TDispID; var Params: TDispParams);
- type
- PVarArg = ^TVarArg;
- TVarArg = array[0..3] of Integer;
- TStringDesc = record
- PStr: Pointer;
- BStr: PBStr;
- end;
- var
- I, J, K, ArgType, ArgCount, StrCount: Integer;
- ArgPtr: PEventArg;
- ParamPtr: PVarArg;
- Strings: array[0..MaxDispArgs - 1] of TStringDesc;
- EventInfo: TEventInfo;
- begin
- GetEventMethod(DispID, EventInfo.Method);
- if Integer(EventInfo.Method.Code) >= $10000 then
- begin
- StrCount := 0;
- try
- ArgCount := Params.cArgs;
- EventInfo.Sender := Self;
- EventInfo.ArgCount := ArgCount;
- if ArgCount <> 0 then
- begin
- ParamPtr := @Params.rgvarg^[EventInfo.ArgCount];
- ArgPtr := @EventInfo.Args;
- I := 0;
- repeat
- Dec(Integer(ParamPtr), SizeOf(TVarArg));
- ArgType := ParamPtr^[0] and $0000FFFF;
- if ArgType and varTypeMask = varOleStr then
- begin
- ArgPtr^.Kind := akDWord;
- with Strings[StrCount] do
- begin
- PStr := nil;
- if ArgType and varByRef <> 0 then
- begin
- OleStrToStrVar(PBStr(ParamPtr^[2])^, string(PStr));
- BStr := PBStr(ParamPtr^[2]);
- ArgPtr^.Data[0] := Integer(@PStr);
- end else
- begin
- OleStrToStrVar(TBStr(ParamPtr^[2]), string(PStr));
- BStr := nil;
- ArgPtr^.Data[0] := Integer(PStr);
- end;
- end;
- Inc(StrCount);
- end else
- begin
- case ArgType of
- varSingle:
- begin
- ArgPtr^.Kind := akSingle;
- ArgPtr^.Data[0] := ParamPtr^[2];
- end;
- varDouble..varDate:
- begin
- ArgPtr^.Kind := akDouble;
- ArgPtr^.Data[0] := ParamPtr^[2];
- ArgPtr^.Data[1] := ParamPtr^[3];
- end;
- varDispatch:
- begin
- ArgPtr^.Kind := akDWord;
- ArgPtr^.Data[0] := Integer(ParamPtr)
- end;
- else
- ArgPtr^.Kind := akDWord;
- if (ArgType and varArray) <> 0 then
- ArgPtr^.Data[0] := Integer(ParamPtr)
- else
- ArgPtr^.Data[0] := ParamPtr^[2];
- end;
- end;
- Inc(Integer(ArgPtr), SizeOf(TEventArg));
- Inc(I);
- until I = EventInfo.ArgCount;
- end;
- CallEventMethod(EventInfo);
- J := StrCount;
- while J <> 0 do
- begin
- Dec(J);
- with Strings[J] do
- if BStr <> nil then BStr^ := StringToOleStr(string(PStr));
- end;
- except
- Application.HandleException(Self);
- end;
- K := StrCount;
- while K <> 0 do
- begin
- Dec(K);
- string(Strings[K].PStr) := '';
- end;
- end;
- end;
-
- procedure GetStringResult(BStr: TBStr; var Result: string);
- begin
- try
- OleStrToStrVar(BStr, Result);
- finally
- SysFreeString(BStr);
- end;
- end;
-
- procedure TOleControl.InvokeMethod(var DispInfo; Result: Pointer); assembler;
- asm
- PUSH EBX
- PUSH ESI
- PUSH EDI
- MOV EBX,EAX
- MOV ESI,EDX
- MOV EDI,ECX
- CALL TOleControl.CreateControl
- PUSH [ESI].TDispInfo.DispID
- MOV ECX,ESP
- XOR EAX,EAX
- PUSH EAX
- PUSH EAX
- PUSH EAX
- PUSH EAX
- MOV EDX,ESP
- LEA EAX,[EBP+16]
- CMP [ESI].TDispInfo.ResType,varOleStr
- JE @@1
- CMP [ESI].TDispInfo.ResType,varVariant
- JE @@1
- LEA EAX,[EBP+12]
- @@1: PUSH EAX
- PUSH EDX
- LEA EDX,[ESI].TDispInfo.CallDesc
- MOV EAX,[EBX].TOleControl.FControlDispatch
- CALL DispInvoke
- XOR EAX,EAX
- MOV AL,[ESI].TDispInfo.ResType
- JMP @ResultTable.Pointer[EAX*4]
-
- @ResultTable:
- DD @ResEmpty
- DD @ResNull
- DD @ResSmallint
- DD @ResInteger
- DD @ResSingle
- DD @ResDouble
- DD @ResCurrency
- DD @ResDate
- DD @ResString
- DD @ResDispatch
- DD @ResError
- DD @ResBoolean
- DD @ResVariant
-
- @ResSmallint:
- @ResBoolean:
- MOV AX,[ESP+8]
- MOV [EDI],AX
- JMP @ResDone
-
- @ResString:
- MOV EAX,[ESP+8]
- MOV EDX,EDI
- CALL GetStringResult
- JMP @ResDone
-
- @ResVariant:
- MOV EAX,EDI
- CALL VarClear
- MOV ESI,ESP
- MOV ECX,4
- REP MOVSD
- JMP @ResDone
-
- @ResDouble:
- @ResCurrency:
- @ResDate:
- MOV EAX,[ESP+12]
- MOV [EDI+4],EAX
-
- @ResInteger:
- @ResSingle:
- MOV EAX,[ESP+8]
- MOV [EDI],EAX
-
- @ResEmpty:
- @ResNull:
- @ResDispatch:
- @ResError:
- @ResDone:
- ADD ESP,20
- POP EDI
- POP ESI
- POP EBX
- end;
-
- function TOleControl.IsCustomProperty(DispID: Integer): Boolean;
- begin
- Result := (FPropBrowsing <> nil) and
- (FPropBrowsing.GetDisplayString(DispID, PBStr(nil)^) = 0);
- end;
-
- function TOleControl.PaletteChanged(Foreground: Boolean): Boolean;
- begin
- Result := False;
- if HandleAllocated and Foreground then
- Result := CallWindowProc(DefWndProc, Handle, WM_QUERYNEWPALETTE, 0, 0) <> 0;
- if not Result then
- Result := inherited PaletteChanged(Foreground);
- end;
-
- function TOleControl.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_IOleControlSite) then P := FOleControlSite else
- if IsEqualIID(iid, IID_IOleInPlaceSite) then P := FOleInPlaceSite else
- if IsEqualIID(iid, IID_IDispatch) then P := FAmbientDispatch else
- if IsEqualIID(iid, IID_IPropertyNotifySink) then P := FPropertyNotifySink else
- if IsEqualIID(iid, IID_ISimpleFrameSite) then P := FSimpleFrameSite else
- if IsEqualIID(iid, FControlData^.EventIID) then P := FEventDispatch;
- Pointer(obj) := P;
- if P = nil then Result := E_NOINTERFACE else
- begin
- P.AddRef;
- Result := S_OK;
- end;
- end;
-
- procedure TOleControl.ReadData(Stream: TStream);
- var
- Buffer: Pointer;
- begin
- DestroyStorage;
- try
- FObjectData := GlobalAlloc(GMEM_MOVEABLE, Stream.Size);
- if FObjectData = 0 then OutOfMemoryError;
- Buffer := GlobalLock(FObjectData);
- try
- Stream.Read(Buffer^, Stream.Size);
- finally
- GlobalUnlock(FObjectData);
- end;
- except
- DestroyStorage;
- end;
- end;
-
- function TOleControl.Release: Longint;
- begin
- Dec(FRefCount);
- Result := FRefCount;
- end;
-
- procedure TOleControl.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
- begin
- if (AWidth <> Width) or (AHeight <> Height) then
- if (FMiscStatus and OLEMISC_INVISIBLEATRUNTIME <> 0) or
- (FOleControl <> nil) and
- (FOleObject.SetExtent(DVASPECT_CONTENT, Point(
- MulDiv(AWidth, 2540, PixPerInch.X),
- MulDiv(AHeight, 2540, PixPerInch.Y))) <> S_OK) then
- begin
- AWidth := Width;
- AHeight := Height;
- end;
- inherited SetBounds(ALeft, ATop, AWidth, AHeight);
- end;
-
- procedure TOleControl.SetColorProp(Index: Integer; Value: TColor);
- begin
- SetIntegerProp(Index, Value);
- end;
-
- procedure TOleControl.SetCurrencyProp(Index: Integer; Value: TCurrency);
- var
- Temp: TVarData;
- begin
- Temp.VType := varCurrency;
- Temp.VCurrency := Value;
- SetProperty(Index, Temp);
- end;
-
- procedure TOleControl.SetDoubleProp(Index: Integer; Value: Double);
- var
- Temp: TVarData;
- begin
- Temp.VType := varDouble;
- Temp.VDouble := Value;
- SetProperty(Index, Temp);
- end;
-
- procedure TOleControl.SetIntegerProp(Index: Integer; Value: Integer);
- var
- Temp: TVarData;
- begin
- Temp.VType := varInteger;
- Temp.VInteger := Value;
- SetProperty(Index, Temp);
- end;
-
- procedure TOleControl.SetName(const Value: TComponentName);
- var
- OldName: string;
- DispID: Integer;
- begin
- OldName := Name;
- inherited SetName(Value);
- if FOleControl <> nil then
- begin
- FOleControl.OnAmbientPropertyChange(DISPID_AMBIENT_DISPLAYNAME);
- if FControlData^.Flags and (cfCaption or cfText) <> 0 then
- begin
- if FControlData^.Flags and cfCaption <> 0 then
- DispID := DISPID_CAPTION else
- DispID := DISPID_TEXT;
- if OldName = GetStringProp(DispID) then SetStringProp(DispID, Value);
- end;
- end;
- end;
-
- procedure TOleControl.SetOleBoolProp(Index: Integer; Value: TOleBool);
- var
- Temp: TVarData;
- begin
- Temp.VType := varBoolean;
- if Value then
- Temp.VBoolean := WordBool(-1) else
- Temp.VBoolean := WordBool(0);
- SetProperty(Index, Temp);
- end;
-
- procedure TOleControl.SetOleDateProp(Index: Integer; Value: TOleDate);
- var
- Temp: TVarData;
- begin
- Temp.VType := varDate;
- Temp.VDate := Value;
- SetProperty(Index, Temp);
- end;
-
- procedure TOleControl.SetOleEnumProp(Index: Integer; Value: TOleEnum);
- begin
- SetSmallintProp(Index, Value);
- end;
-
- procedure TOleControl.SetPropDisplayString(DispID: Integer;
- const Value: string);
- var
- I: Integer;
- Values: TStringList;
- V: Variant;
- begin
- Values := TStringList.Create;
- try
- GetPropDisplayStrings(DispID, Values);
- for I := 0 to Values.Count - 1 do
- if AnsiCompareText(Value, Values[I]) = 0 then
- begin
- OleCheck(FPropBrowsing.GetPredefinedValue(DispID,
- Integer(Values.Objects[I]), V));
- SetProperty(DispID, TVarData(V));
- Exit;
- end;
- finally
- Values.Free;
- end;
- SetStringProp(DispID, Value);
- end;
-
- procedure TOleControl.SetProperty(Index: Integer; const Value: TVarData);
- const
- DispIDArgs: Longint = DISPID_PROPERTYPUT;
- var
- Status, InvKind: Integer;
- DispParams: TDispParams;
- ExcepInfo: TExcepInfo;
- begin
- CreateControl;
- DispParams.rgvarg := @Value;
- DispParams.rgdispidNamedArgs := @DispIDArgs;
- DispParams.cArgs := 1;
- DispParams.cNamedArgs := 1;
- FillChar(ExcepInfo, SizeOf(ExcepInfo), 0);
- if Value.VType <> varDispatch then
- InvKind := DISPATCH_PROPERTYPUT else
- InvKind := DISPATCH_PROPERTYPUTREF;
- Status := FControlDispatch.Invoke(Index, GUID_NULL, 0,
- InvKind, DispParams, nil, @ExcepInfo, nil);
- if Status <> 0 then DispInvokeError(Status, ExcepInfo);
- end;
-
- procedure TOleControl.SetSingleProp(Index: Integer; Value: Single);
- var
- Temp: TVarData;
- begin
- Temp.VType := varSingle;
- Temp.VSingle := Value;
- SetProperty(Index, Temp);
- end;
-
- procedure TOleControl.SetSmallintProp(Index: Integer; Value: Smallint);
- var
- Temp: TVarData;
- begin
- Temp.VType := varSmallint;
- Temp.VSmallint := Value;
- SetProperty(Index, Temp);
- end;
-
- procedure TOleControl.SetStringProp(Index: Integer; const Value: string);
- var
- Temp: TVarData;
- begin
- Temp.VType := varOleStr;
- Temp.VOleStr := StringToOleStr(Value);
- try
- SetProperty(Index, Temp);
- finally
- SysFreeString(Temp.VOleStr);
- end;
- end;
-
- procedure TOleControl.SetUIActive(Active: Boolean);
- var
- Form: TForm;
- begin
- 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;
- end else
- if Form.ActiveOleControl = Self then Form.ActiveOleControl := nil;
- end;
-
- procedure TOleControl.SetVariantProp(Index: Integer; const Value: Variant);
- begin
- if TVarData(Value).VType = varString then
- SetStringProp(Index, string(TVarData(Value).VString))
- else
- SetProperty(Index, TVarData(Value));
- end;
-
- procedure TOleControl.ShowAboutBox;
- const
- DispInfo: array[0..7] of Byte = ($D8,$FD,$FF,$FF,$00,$01,$00,$00);
- begin
- InvokeMethod(DispInfo, nil);
- end;
-
- procedure TOleControl.StandardEvent(DispID: TDispID; var Params: TDispParams);
- type
- PVarDataList = ^TVarDataList;
- TVarDataList = array[0..3] of TVarData;
- const
- ShiftMap: array[0..7] of TShiftState = (
- [],
- [ssShift],
- [ssCtrl],
- [ssShift, ssCtrl],
- [ssAlt],
- [ssShift, ssAlt],
- [ssCtrl, ssAlt],
- [ssShift, ssCtrl, ssAlt]);
- MouseMap: array[0..7] of TShiftState = (
- [],
- [ssLeft],
- [ssRight],
- [ssLeft, ssRight],
- [ssMiddle],
- [ssLeft, ssMiddle],
- [ssRight, ssMiddle],
- [ssLeft, ssRight, ssMiddle]);
- ButtonMap: array[0..7] of TMouseButton = (
- mbLeft, mbLeft, mbRight, mbLeft, mbMiddle, mbLeft, mbRight, mbLeft);
- var
- Args: PVarDataList;
- Shift: TShiftState;
- Button: TMouseButton;
- X, Y: Integer;
- begin
- Args := PVarDataList(Params.rgvarg);
- try
- case DispID of
- DISPID_CLICK:
- Click;
- DISPID_DBLCLICK:
- DblClick;
- DISPID_KEYDOWN:
- KeyDown(Word(Args^[1].VPointer^), ShiftMap[Args^[0].VInteger and 7]);
- DISPID_KEYPRESS:
- KeyPress(Char(Args^[0].VPointer^));
- DISPID_KEYUP:
- KeyUp(Word(Args^[1].VPointer^), ShiftMap[Args^[0].VInteger and 7]);
- DISPID_MOUSEDOWN, DISPID_MOUSEMOVE, DISPID_MOUSEUP:
- begin
- Button := ButtonMap[Args^[3].VInteger and 7];
- Shift := ShiftMap[Args^[2].VInteger and 7] +
- MouseMap[Args^[3].VInteger and 7];
- X := Args^[1].VInteger;
- Y := Args^[0].VInteger;
- case DispID of
- DISPID_MOUSEDOWN:
- MouseDown(Button, Shift, X, Y);
- DISPID_MOUSEMOVE:
- MouseMove(Shift, X, Y);
- DISPID_MOUSEUP:
- MouseUp(Button, Shift, X, Y);
- end;
- end;
- end;
- except
- Application.HandleException(Self);
- end;
- end;
-
- procedure TOleControl.WndProc(var Message: TMessage);
- var
- WinMsg: TMsg;
- begin
- if (Message.Msg >= CN_BASE + WM_KEYFIRST) and
- (Message.Msg <= CN_BASE + WM_KEYLAST) and
- (FOleInPlaceActiveObject <> nil) then
- begin
- WinMsg.HWnd := Handle;
- WinMsg.Message := Message.Msg - CN_BASE;
- WinMsg.WParam := Message.WParam;
- WinMsg.LParam := Message.LParam;
- WinMsg.Time := GetMessageTime;
- WinMsg.Pt.X := 0;
- WinMsg.Pt.Y := 0;
- if FOleInPlaceActiveObject.TranslateAccelerator(WinMsg) = S_OK then
- begin
- Message.Result := 1;
- Exit;
- end;
- end;
- inherited WndProc(Message);
- end;
-
- procedure TOleControl.WriteData(Stream: TStream);
- var
- StorageExists: Boolean;
- Buffer: Pointer;
- begin
- StorageExists := FObjectData <> 0;
- if not StorageExists then CreateStorage;
- try
- Buffer := GlobalLock(FObjectData);
- try
- Stream.Write(Buffer^, GlobalSize(FObjectData));
- finally
- GlobalUnlock(FObjectData);
- end;
- finally
- if not StorageExists then DestroyStorage;
- end;
- end;
-
- procedure TOleControl.WMEraseBkgnd(var Message: TWMEraseBkgnd);
- begin
- if FMiscStatus and OLEMISC_INVISIBLEATRUNTIME = 0 then
- DefaultHandler(Message) else
- inherited;
- end;
-
- procedure TOleControl.WMPaint(var Message: TWMPaint);
- var
- DC: HDC;
- PS: TPaintStruct;
- begin
- if FMiscStatus and OLEMISC_INVISIBLEATRUNTIME <> 0 then
- begin
- DC := Message.DC;
- if DC = 0 then DC := BeginPaint(Handle, PS);
- OleDraw(FOleObject, DVASPECT_CONTENT, DC, ClientRect);
- if Message.DC = 0 then EndPaint(Handle, PS);
- end else
- inherited;
- end;
-
- procedure TOleControl.CMDocWindowActivate(var Message: TMessage);
- begin
- if GetParentForm(Self).FormStyle = fsMDIChild then
- begin
- FOleInPlaceActiveObject.OnDocWindowActivate(LongBool(Message.WParam));
- if Message.WParam = 0 then FOleInPlaceFrame.SetMenu(0, 0, 0);
- end;
- end;
-
- procedure TOleControl.CMColorChanged(var Message: TMessage);
- begin
- inherited;
- if (FControlData^.Flags and cfBackColor <> 0) and not FUpdatingColor and
- HandleAllocated then
- begin
- FUpdatingColor := True;
- try
- SetColorProp(DISPID_BACKCOLOR, Color);
- finally
- FUpdatingColor := False;
- end;
- end;
- end;
-
- procedure TOleControl.CMEnabledChanged(var Message: TMessage);
- begin
- inherited;
- if (FControlData^.Flags and cfEnabled <> 0) and not FUpdatingEnabled and
- HandleAllocated then
- begin
- FUpdatingEnabled := True;
- try
- SetOleBoolProp(DISPID_ENABLED, Enabled);
- finally
- FUpdatingEnabled := False;
- end;
- end;
- end;
-
- procedure TOleControl.CMFontChanged(var Message: TMessage);
- begin
- inherited;
- if (FControlData^.Flags and (cfForeColor or cfFont) <> 0) and
- not FUpdatingFont and HandleAllocated then
- begin
- FUpdatingFont := True;
- try
- if FControlData^.Flags and cfForeColor <> 0 then
- SetIntegerProp(DISPID_FORECOLOR, Font.Color);
- if FControlData^.Flags and cfFont <> 0 then
- SetVariantProp(DISPID_FONT, FontToOleFont(Font));
- finally
- FUpdatingFont := False;
- end;
- end;
- end;
-
- procedure TOleControl.CMDialogKey(var Message: TMessage);
- var
- Info: TControlInfo;
- Msg: TMsg;
- Cmd: Word;
- begin
- if CanFocus then
- begin
- Info.cb := SizeOf(Info);
- if (FOleControl.GetControlInfo(Info) = S_OK) and (Info.cAccel <> 0) then
- begin
- FillChar(Msg, SizeOf(Msg), 0);
- Msg.hwnd := Handle;
- Msg.message := WM_KEYDOWN;
- Msg.wParam := Message.WParam;
- Msg.lParam := Message.LParam;
- if IsAccelerator(Info.hAccel, Info.cAccel, @Msg, Cmd) then
- begin
- FOleControl.OnMnemonic(@Msg);
- Message.Result := 1;
- Exit;
- end;
- end;
- end;
- inherited;
- end;
-
- procedure TOleControl.CMUIActivate(var Message: TMessage);
- begin
- if GetParentForm(Self).ActiveOleControl <> Self then
- FOleObject.DoVerb(OLEIVERB_UIACTIVATE, nil, FOleClientSite, 0,
- Parent.Handle, BoundsRect);
- end;
-
- procedure TOleControl.CMUIDeactivate(var Message: TMessage);
- begin
- if GetParentForm(Self).ActiveOleControl = Self then
- FOleInPlaceObject.UIDeactivate;
- end;
-
- procedure Initialize;
- var
- DC: HDC;
- begin
- DC := GetDC(0);
- PixPerInch.X := GetDeviceCaps(DC, LOGPIXELSX);
- PixPerInch.Y := GetDeviceCaps(DC, LOGPIXELSY);
- ReleaseDC(0, DC);
- end;
-
- initialization
- begin
- Initialize;
- end;
-
- end.
-