{*******************************************************} { } { CodeGear Delphi Visual Component Library } { } { Copyright (c) 1995-2008 CodeGear } { } {*******************************************************} unit AxCtrls; {$WARN SYMBOL_PLATFORM OFF} {$T-,H+,X+} interface (*$HPPEMIT '' *) (*$HPPEMIT '#include ' *) (*$HPPEMIT '#include ' *) (*$HPPEMIT '' *) uses Variants, Windows, Messages, ActiveX, SysUtils, {$IFDEF LINUX} WinUtils, {$ENDIF} ComObj, Classes, Graphics, Controls, Forms, ExtCtrls, StdVCL; const { Delphi property page CLSIDs } Class_DColorPropPage: TGUID = '{5CFF5D59-5946-11D0-BDEF-00A024D1875C}'; Class_DFontPropPage: TGUID = '{5CFF5D5B-5946-11D0-BDEF-00A024D1875C}'; Class_DPicturePropPage: TGUID = '{5CFF5D5A-5946-11D0-BDEF-00A024D1875C}'; Class_DStringPropPage: TGUID = '{F42D677E-754B-11D0-BDFB-00A024D1875C}'; type TOleStream = class(TStream) private FStream: IStream; protected function GetIStream: IStream; public constructor Create(const Stream: IStream); function Read(var Buffer; Count: Longint): Longint; override; function Write(const Buffer; Count: Longint): Longint; override; function Seek(Offset: Longint; Origin: Word): Longint; override; end; TConnectionPoints = class; TConnectionKind = (ckSingle, ckMulti); {$EXTERNALSYM TConnectionKind} TConnectionPoint = class(TContainedObject, IConnectionPoint) private FContainer: TConnectionPoints; FIID: TGUID; FSinkList: TList; FOnConnect: TConnectEvent; FKind: TConnectionKind; function AddSink(const Sink: IUnknown): Integer; procedure RemoveSink(Cookie: Longint); protected { IConnectionPoint } function GetConnectionInterface(out iid: TIID): HResult; stdcall; function GetConnectionPointContainer( out cpc: IConnectionPointContainer): HResult; stdcall; function Advise(const unkSink: IUnknown; out dwCookie: Longint): HResult; stdcall; function Unadvise(dwCookie: Longint): HResult; stdcall; function EnumConnections(out enumconn: IEnumConnections): HResult; stdcall; public constructor Create(Container: TConnectionPoints; const IID: TGUID; Kind: TConnectionKind; OnConnect: TConnectEvent); property SinkList : TList read FSinkList; destructor Destroy; override; end; {$EXTERNALSYM TConnectionPoint} // IConnectionPointContainer TConnectionPoints = class private FController: Pointer; // weak ref to controller - don't keep it alive FConnectionPoints: TList; function GetController: IUnknown; protected { IConnectionPointContainer } function EnumConnectionPoints( out enumconn: IEnumConnectionPoints): HResult; stdcall; function FindConnectionPoint(const iid: TIID; out cp: IConnectionPoint): HResult; stdcall; public constructor Create(const AController: IUnknown); destructor Destroy; override; function CreateConnectionPoint(const IID: TGUID; Kind: TConnectionKind; OnConnect: TConnectEvent): TConnectionPoint; property Controller: IUnknown read GetController; end; {$EXTERNALSYM TConnectionPoints} TDefinePropertyPage = procedure(const GUID: TGUID) of object; TActiveXControlFactory = class; {$EXTERNALSYM TActiveXControlFactory} IAmbientDispatch = dispinterface ['{00020400-0000-0000-C000-000000000046}'] property BackColor: Integer dispid DISPID_AMBIENT_BACKCOLOR; property DisplayName: WideString dispid DISPID_AMBIENT_DISPLAYNAME; property Font: IFontDisp dispid DISPID_AMBIENT_FONT; property ForeColor: Integer dispid DISPID_AMBIENT_FORECOLOR; property LocaleID: Integer dispid DISPID_AMBIENT_LOCALEID; property MessageReflect: WordBool dispid DISPID_AMBIENT_MESSAGEREFLECT; property ScaleUnits: WideString dispid DISPID_AMBIENT_SCALEUNITS; property TextAlign: Smallint dispid DISPID_AMBIENT_TEXTALIGN; property UserMode: WordBool dispid DISPID_AMBIENT_USERMODE; property UIDead: WordBool dispid DISPID_AMBIENT_UIDEAD; property ShowGrabHandles: WordBool dispid DISPID_AMBIENT_SHOWGRABHANDLES; property ShowHatching: WordBool dispid DISPID_AMBIENT_SHOWHATCHING; property DisplayAsDefault: WordBool dispid DISPID_AMBIENT_DISPLAYASDEFAULT; property SupportsMnemonics: WordBool dispid DISPID_AMBIENT_SUPPORTSMNEMONICS; property AutoClip: WordBool dispid DISPID_AMBIENT_AUTOCLIP; end; TActiveXControl = class(TAutoObject, IConnectionPointContainer, IDataObject, IObjectSafety, IOleControl, IOleInPlaceActiveObject, IOleInPlaceObject, IOleObject, IPerPropertyBrowsing, IPersistPropertyBag, IPersistStorage, IPersistStreamInit, IQuickActivate, ISimpleFrameSite, ISpecifyPropertyPages, IViewObject, IViewObject2) private FControlFactory: TActiveXControlFactory; FConnectionPoints: TConnectionPoints; FPropertySinks: TConnectionPoint; FObjectSafetyFlags: DWORD; FOleClientSite: IOleClientSite; FOleControlSite: IOleControlSite; FSimpleFrameSite: ISimpleFrameSite; FAmbientDispatch: IAmbientDispatch; FOleInPlaceSite: IOleInPlaceSite; FOleInPlaceFrame: IOleInPlaceFrame; FOleInPlaceUIWindow: IOleInPlaceUIWindow; FOleAdviseHolder: IOleAdviseHolder; FDataAdviseHolder: IDataAdviseHolder; FAdviseSink: IAdviseSink; FAdviseFlags: Integer; FControl: TWinControl; FControlWndProc: TWndMethod; FWinControl: TWinControl; FIsDirty: Boolean; FInPlaceActive: Boolean; FUIActive: Boolean; FEventsFrozen: Boolean; FOleLinkStub: IInterface; // Pointer to a TOleLinkStub instance function CreateAdviseHolder: HResult; function GetPropertyID(const PropertyName: WideString): Integer; procedure RecreateWnd; procedure ViewChanged; protected { Renamed methods } function IPersistPropertyBag.InitNew = PersistPropBagInitNew; function IPersistPropertyBag.Load = PersistPropBagLoad; function IPersistPropertyBag.Save = PersistPropBagSave; function IPersistStreamInit.Load = PersistStreamLoad; function IPersistStreamInit.Save = PersistStreamSave; function IPersistStorage.InitNew = PersistStorageInitNew; function IPersistStorage.Load = PersistStorageLoad; function IPersistStorage.Save = PersistStorageSave; function IViewObject2.GetExtent = ViewObjectGetExtent; { IPersist } function GetClassID(out classID: TCLSID): HResult; stdcall; { IPersistPropertyBag } function PersistPropBagInitNew: HResult; stdcall; function PersistPropBagLoad(const pPropBag: IPropertyBag; const pErrorLog: IErrorLog): HResult; stdcall; function PersistPropBagSave(const pPropBag: IPropertyBag; fClearDirty: BOOL; fSaveAllProperties: BOOL): HResult; stdcall; { IPersistStreamInit } function IsDirty: HResult; stdcall; function PersistStreamLoad(const stm: IStream): HResult; stdcall; function PersistStreamSave(const stm: IStream; fClearDirty: BOOL): HResult; stdcall; function GetSizeMax(out cbSize: Largeint): HResult; stdcall; function InitNew: HResult; stdcall; { IPersistStorage } function PersistStorageInitNew(const stg: IStorage): HResult; stdcall; function PersistStorageLoad(const stg: IStorage): HResult; stdcall; function PersistStorageSave(const stgSave: IStorage; fSameAsLoad: BOOL): HResult; stdcall; function SaveCompleted(const stgNew: IStorage): HResult; stdcall; function HandsOffStorage: HResult; stdcall; { IObjectSafety } function GetInterfaceSafetyOptions(const IID: TIID; pdwSupportedOptions, pdwEnabledOptions: PDWORD): HResult; virtual; stdcall; function SetInterfaceSafetyOptions(const IID: TIID; dwOptionSetMask, dwEnabledOptions: DWORD): HResult; virtual; stdcall; { IOleObject } function SetClientSite(const clientSite: IOleClientSite): HResult; stdcall; function GetClientSite(out clientSite: IOleClientSite): HResult; stdcall; function SetHostNames(szContainerApp: POleStr; szContainerObj: POleStr): HResult; stdcall; function Close(dwSaveOption: Longint): HResult; stdcall; function SetMoniker(dwWhichMoniker: Longint; const mk: IMoniker): HResult; stdcall; function GetMoniker(dwAssign: Longint; dwWhichMoniker: Longint; out mk: IMoniker): HResult; stdcall; function InitFromData(const dataObject: IDataObject; fCreation: BOOL; dwReserved: Longint): HResult; stdcall; function GetClipboardData(dwReserved: Longint; out dataObject: IDataObject): HResult; stdcall; function DoVerb(iVerb: Longint; msg: PMsg; const activeSite: IOleClientSite; lindex: Longint; hwndParent: HWND; const posRect: TRect): HResult; stdcall; function EnumVerbs(out enumOleVerb: IEnumOleVerb): HResult; stdcall; function Update: HResult; stdcall; function IsUpToDate: HResult; stdcall; function GetUserClassID(out clsid: TCLSID): HResult; stdcall; function GetUserType(dwFormOfType: Longint; out pszUserType: POleStr): HResult; stdcall; function SetExtent(dwDrawAspect: Longint; const size: TPoint): HResult; stdcall; function GetExtent(dwDrawAspect: Longint; out size: TPoint): HResult; stdcall; function Advise(const advSink: IAdviseSink; out dwConnection: Longint): HResult; stdcall; function Unadvise(dwConnection: Longint): HResult; stdcall; function EnumAdvise(out enumAdvise: IEnumStatData): HResult; stdcall; function GetMiscStatus(dwAspect: Longint; out dwStatus: Longint): HResult; stdcall; function SetColorScheme(const logpal: TLogPalette): HResult; stdcall; { IOleControl } function GetControlInfo(var ci: TControlInfo): HResult; stdcall; function OnMnemonic(msg: PMsg): HResult; stdcall; function OnAmbientPropertyChange(dispid: TDispID): HResult; stdcall; function FreezeEvents(bFreeze: BOOL): HResult; stdcall; { IOleWindow } function GetWindow(out wnd: HWnd): HResult; stdcall; function ContextSensitiveHelp(fEnterMode: BOOL): HResult; stdcall; { IOleInPlaceObject } function InPlaceDeactivate: HResult; stdcall; function UIDeactivate: HResult; stdcall; function SetObjectRects(const rcPosRect: TRect; const rcClipRect: TRect): HResult; stdcall; function ReactivateAndUndo: HResult; stdcall; { IOleInPlaceActiveObject } function TranslateAccelerator(var msg: TMsg): HResult; stdcall; function OnFrameWindowActivate(fActivate: BOOL): HResult; stdcall; function OnDocWindowActivate(fActivate: BOOL): HResult; stdcall; function ResizeBorder(const rcBorder: TRect; const uiWindow: IOleInPlaceUIWindow; fFrameWindow: BOOL): HResult; stdcall; function EnableModeless(fEnable: BOOL): HResult; stdcall; { IViewObject } function Draw(dwDrawAspect: Longint; lindex: Longint; pvAspect: Pointer; ptd: PDVTargetDevice; hicTargetDev: HDC; hdcDraw: HDC; prcBounds: PRect; prcWBounds: PRect; fnContinue: TContinueFunc; dwContinue: Longint): HResult; stdcall; function GetColorSet(dwDrawAspect: Longint; lindex: Longint; pvAspect: Pointer; ptd: PDVTargetDevice; hicTargetDev: HDC; out colorSet: PLogPalette): HResult; stdcall; function Freeze(dwDrawAspect: Longint; lindex: Longint; pvAspect: Pointer; out dwFreeze: Longint): HResult; stdcall; function Unfreeze(dwFreeze: Longint): HResult; stdcall; function SetAdvise(aspects: Longint; advf: Longint; const advSink: IAdviseSink): HResult; stdcall; function GetAdvise(pAspects: PLongint; pAdvf: PLONGINT; out advSink: IAdviseSink): HResult; stdcall; { IViewObject2 } function ViewObjectGetExtent(dwDrawAspect: Longint; lindex: Longint; ptd: PDVTargetDevice; out size: TPoint): HResult; stdcall; { IPerPropertyBrowsing } function GetDisplayString(dispid: TDispID; out bstr: WideString): HResult; stdcall; function MapPropertyToPage(dispid: TDispID; out clsid: TCLSID): HResult; stdcall; function GetPredefinedStrings(dispid: TDispID; out caStringsOut: TCAPOleStr; out caCookiesOut: TCALongint): HResult; stdcall; function GetPredefinedValue(dispid: TDispID; dwCookie: Longint; out varOut: OleVariant): HResult; stdcall; { ISpecifyPropertyPages } function GetPages(out pages: TCAGUID): HResult; stdcall; { ISimpleFrameSite } function PreMessageFilter(wnd: HWnd; msg, wp, lp: Integer; out res: Integer; out Cookie: Longint): HResult; stdcall; function PostMessageFilter(wnd: HWnd; msg, wp, lp: Integer; out res: Integer; Cookie: Longint): HResult; stdcall; { IQuickActivate } function QuickActivate(var qaCont: tagQACONTAINER; var qaCtrl: tagQACONTROL): HResult; stdcall; function SetContentExtent(const sizel: TPoint): HResult; stdcall; function GetContentExtent(out sizel: TPoint): HResult; stdcall; { IDataObject } function GetData(const formatetcIn: TFormatEtc; out medium: TStgMedium): HResult; stdcall; function GetDataHere(const formatetc: TFormatEtc; out medium: TStgMedium): HResult; stdcall; function QueryGetData(const formatetc: TFormatEtc): HResult; stdcall; function GetCanonicalFormatEtc(const formatetc: TFormatEtc; out formatetcOut: TFormatEtc): HResult; stdcall; function SetData(const formatetc: TFormatEtc; var medium: TStgMedium; fRelease: BOOL): HResult; stdcall; function EnumFormatEtc(dwDirection: Longint; out enumFormatEtc: IEnumFormatEtc): HResult; stdcall; function DAdvise(const formatetc: TFormatEtc; advf: Longint; const advSink: IAdviseSink; out dwConnection: Longint): HResult; stdcall; function DUnadvise(dwConnection: Longint): HResult; stdcall; function EnumDAdvise(out enumAdvise: IEnumStatData): HResult; stdcall; { Standard properties } function Get_BackColor: Integer; safecall; function Get_Caption: WideString; safecall; function Get_Enabled: WordBool; safecall; function Get_Font: Font; safecall; function Get_ForeColor: Integer; safecall; function Get_HWnd: Integer; safecall; function Get_TabStop: WordBool; safecall; function Get_Text: WideString; safecall; procedure Set_BackColor(Value: Integer); safecall; procedure Set_Caption(const Value: WideString); safecall; procedure Set_Enabled(Value: WordBool); safecall; procedure Set_Font(const Value: Font); safecall; procedure Set_ForeColor(Value: Integer); safecall; procedure Set_TabStop(Value: WordBool); safecall; procedure Set_Text(const Value: WideString); safecall; { Standard event handlers } procedure StdClickEvent(Sender: TObject); procedure StdDblClickEvent(Sender: TObject); procedure StdKeyDownEvent(Sender: TObject; var Key: Word; Shift: TShiftState); procedure StdKeyPressEvent(Sender: TObject; var Key: Char); procedure StdKeyUpEvent(Sender: TObject; var Key: Word; Shift: TShiftState); procedure StdMouseDownEvent(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure StdMouseMoveEvent(Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure StdMouseUpEvent(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); { Helper methods } function InPlaceActivate(ActivateUI: Boolean): HResult; procedure ShowPropertyDialog; procedure SetInPlaceSite(const NewInPlaceSite: IOleInPlaceSite); { Overrideable methods } procedure DefinePropertyPages( DefinePropertyPage: TDefinePropertyPage); virtual; function GetPropertyString(DispID: Integer; var S: string): Boolean; virtual; function GetPropertyStrings(DispID: Integer; Strings: TStrings): Boolean; virtual; procedure GetPropertyValue(DispID, Cookie: Integer; var Value: OleVariant); virtual; procedure GetPropFromBag(const PropName: WideString; DispatchID: Integer; PropBag: IPropertyBag; ErrorLog: IErrorLog); virtual; procedure InitializeControl; virtual; procedure LoadFromStream(const Stream: IStream); virtual; procedure PerformVerb(Verb: Integer); virtual; procedure PutPropInBag(const PropName: WideString; DispatchID: Integer; PropBag: IPropertyBag); virtual; procedure SaveToStream(const Stream: IStream); virtual; procedure WndProc(var Message: TMessage); virtual; property ConnectionPoints: TConnectionPoints read FConnectionPoints implements IConnectionPointContainer; public destructor Destroy; override; procedure Initialize; override; function ObjQueryInterface(const IID: TGUID; out Obj): HResult; override; procedure PropChanged(const PropertyName: WideString); overload; procedure PropChanged(DispID: TDispID); overload; function PropRequestEdit(const PropertyName: WideString): Boolean; overload; function PropRequestEdit(DispID: TDispID): Boolean; overload; property ClientSite: IOleClientSite read FOleClientSite; property InPlaceSite: IOleInPlaceSite read FOleInPlaceSite; property Control: TWinControl read FControl; end; {$EXTERNALSYM TActiveXControl} TActiveXControlClass = class of TActiveXControl; {$EXTERNALSYM TActiveXControlClass} TActiveXControlFactory = class(TAutoObjectFactory) private FWinControlClass: TWinControlClass; FMiscStatus: Integer; FToolboxBitmapID: Integer; FVerbs: TStringList; FLicFileStrings: TStringList; FLicenseFileRead: Boolean; protected function GetLicenseFileName: string; virtual; function HasMachineLicense: Boolean; override; public constructor Create(ComServer: TComServerObject; ActiveXControlClass: TActiveXControlClass; WinControlClass: TWinControlClass; const ClassID: TGUID; ToolboxBitmapID: Integer; const LicStr: string; MiscStatus: Integer; ThreadingModel: TThreadingModel = tmSingle); destructor Destroy; override; procedure AddVerb(Verb: Integer; const VerbName: string); procedure UpdateRegistry(Register: Boolean); override; property MiscStatus: Integer read FMiscStatus; property ToolboxBitmapID: Integer read FToolboxBitmapID; property WinControlClass: TWinControlClass read FWinControlClass; end; {$EXTERNALSYM TActiveXControlFactory} { ActiveFormControl } TActiveFormControl = class(TActiveXControl, IVCLComObject) protected procedure DefinePropertyPages(DefinePropertyPage: TDefinePropertyPage); override; procedure EventSinkChanged(const EventSink: IUnknown); override; public procedure FreeOnRelease; procedure InitializeControl; override; function Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer; Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult; override; function ObjQueryInterface(const IID: TGUID; out Obj): HResult; override; end; {$EXTERNALSYM TActiveFormControl} { ActiveForm } TActiveForm = class(TCustomActiveForm) private FSinkChangeCount : Integer; FActiveFormControl: TActiveFormControl; protected procedure DoDestroy; override; procedure DefinePropertyPages(DefinePropertyPage: TDefinePropertyPage); virtual; procedure EventSinkChanged(const EventSink: IUnknown); virtual; procedure Initialize; virtual; public property ActiveFormControl: TActiveFormControl read FActiveFormControl; end; {$EXTERNALSYM TActiveForm} TActiveFormClass = class of TActiveForm; {$EXTERNALSYM TActiveFormClass} { ActiveFormFactory } TActiveFormFactory = class(TActiveXControlFactory) public function GetIntfEntry(Guid: TGUID): PInterfaceEntry; override; end; {$EXTERNALSYM TActiveFormFactory} { Property Page support } TPropertyPageImpl = class; TPropertyPage = class(TCustomForm) private FActiveXPropertyPage: TPropertyPageImpl; FOleObject: OleVariant; FOleObjects: TInterfaceList; procedure CMChanged(var Msg: TCMChanged); message CM_CHANGED; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; procedure Modified; procedure UpdateObject; virtual; procedure UpdatePropertyPage; virtual; property OleObject: OleVariant read FOleObject; property OleObjects: TInterfaceList read FOleObjects write FOleObjects; procedure EnumCtlProps(PropType: TGUID; PropNames: TStrings); published property ActiveControl; property AutoScroll; property Caption; property ClientHeight; property ClientWidth; property Ctl3D; property Color; property Enabled; property Font; property Height; property HorzScrollBar; property OldCreateOrder; property KeyPreview; property PixelsPerInch; property ParentFont; property PopupMenu; property PrintScale; property Scaled; property ShowHint; property VertScrollBar; property Visible; property Width; property OnActivate; property OnClick; property OnClose; property OnContextPopup; property OnCreate; property OnDblClick; property OnDestroy; property OnDeactivate; property OnDragDrop; property OnDragOver; property OnHide; property OnKeyDown; property OnKeyPress; property OnKeyUp; property OnMouseDown; property OnMouseMove; property OnMouseUp; property OnPaint; property OnResize; property OnShow; end; TPropertyPageClass = class of TPropertyPage; TPropertyPageImpl = class(TAggregatedObject, IUnknown, IPropertyPage, IPropertyPage2) private FPropertyPage: TPropertyPage; FPageSite: IPropertyPageSite; FActive: Boolean; FModified: Boolean; procedure Modified; protected { IPropertyPage } function SetPageSite(const pageSite: IPropertyPageSite): HResult; stdcall; function Activate(hwndParent: HWnd; const rc: TRect; bModal: BOOL): HResult; stdcall; function Deactivate: HResult; stdcall; function GetPageInfo(out pageInfo: TPropPageInfo): HResult; stdcall; function SetObjects(cObjects: Longint; pUnkList: PUnknownList): HResult; stdcall; function Show(nCmdShow: Integer): HResult; stdcall; function Move(const rect: TRect): HResult; stdcall; function IsPageDirty: HResult; stdcall; function Apply: HResult; stdcall; function Help(pszHelpDir: POleStr): HResult; stdcall; function TranslateAccelerator(msg: PMsg): HResult; stdcall; { IPropertyPage2 } function EditProperty(dispid: TDispID): HResult; stdcall; public procedure InitPropertyPage; virtual; property PropertyPage: TPropertyPage read FPropertyPage write FPropertyPage; end; TActiveXPropertyPage = class(TComObject, IPropertyPage, IPropertyPage2) private FPropertyPageImpl: TPropertyPageImpl; public destructor Destroy; override; procedure Initialize; override; property PropertyPageImpl: TPropertyPageImpl read FPropertyPageImpl implements IPropertyPage, IPropertyPage2; end; {$EXTERNALSYM TActiveXPropertyPage} TActiveXPropertyPageFactory = class(TComObjectFactory) public constructor Create(ComServer: TComServerObject; PropertyPageClass: TPropertyPageClass; const ClassID: TGUID); function CreateComObject(const Controller: IUnknown): TComObject; override; end; {$EXTERNALSYM TActiveXPropertyPageFactory} { Type adapter support } TCustomAdapter = class(TInterfacedObject) private FOleObject: IUnknown; FConnection: Longint; FNotifier: IUnknown; protected Updating: Boolean; procedure Changed; virtual; procedure ConnectOleObject(OleObject: IUnknown); procedure ReleaseOleObject; procedure Update; virtual; abstract; public constructor Create; destructor Destroy; override; end; TAdapterNotifier = class(TInterfacedObject, IPropertyNotifySink) private FAdapter: TCustomAdapter; protected { IPropertyNotifySink } function OnChanged(dispid: TDispID): HResult; stdcall; function OnRequestEdit(dispid: TDispID): HResult; stdcall; public constructor Create(Adapter: TCustomAdapter); end; IFontAccess = interface ['{CBA55CA0-0E57-11D0-BD2F-0020AF0E5B81}'] procedure GetOleFont(var OleFont: IFontDisp); procedure SetOleFont(const OleFont: IFontDisp); end; TFontAdapter = class(TCustomAdapter, IChangeNotifier, IFontAccess) private FFont: TFont; protected { IFontAccess } procedure GetOleFont(var OleFont: IFontDisp); procedure SetOleFont(const OleFont: IFontDisp); procedure Changed; override; procedure Update; override; public constructor Create(Font: TFont); end; IPictureAccess = interface ['{795D4D31-43D7-11D0-9E92-0020AF3D82DA}'] procedure GetOlePicture(var OlePicture: IPictureDisp); procedure SetOlePicture(const OlePicture: IPictureDisp); end; TPictureAdapter = class(TCustomAdapter, IChangeNotifier, IPictureAccess) private FPicture: TPicture; protected { IPictureAccess } procedure GetOlePicture(var OlePicture: IPictureDisp); procedure SetOlePicture(const OlePicture: IPictureDisp); procedure Update; override; public constructor Create(Picture: TPicture); end; TOleGraphic = class(TGraphic) private FPicture: IPicture; function GetMMHeight: Integer; function GetMMWidth: Integer; protected procedure Changed(Sender: TObject); override; procedure Draw(ACanvas: TCanvas; const Rect: TRect); override; function GetEmpty: Boolean; override; function GetHeight: Integer; override; function GetPalette: HPALETTE; override; function GetTransparent: Boolean; override; function GetWidth: Integer; override; procedure SetHeight(Value: Integer); override; procedure SetPalette(Value: HPALETTE); override; procedure SetWidth(Value: Integer); override; public procedure Assign(Source: TPersistent); override; procedure LoadFromFile(const Filename: string); override; procedure LoadFromStream(Stream: TStream); override; procedure SaveToStream(Stream: TStream); override; procedure LoadFromClipboardFormat(AFormat: Word; AData: THandle; APalette: HPALETTE); override; procedure SaveToClipboardFormat(var AFormat: Word; var AData: THandle; var APalette: HPALETTE); override; property MMHeight: Integer read GetMMHeight; // in .01 mm units property MMWidth: Integer read GetMMWidth; property Picture: IPicture read FPicture write FPicture; end; TStringsAdapter = class(TAutoIntfObject, IStrings, IStringsAdapter) private FStrings: TStrings; protected { IStringsAdapter } procedure ReferenceStrings(S: TStrings); procedure ReleaseStrings; { IStrings } function Get_ControlDefault(Index: Integer): OleVariant; safecall; procedure Set_ControlDefault(Index: Integer; Value: OleVariant); safecall; function Count: Integer; safecall; function Get_Item(Index: Integer): OleVariant; safecall; procedure Set_Item(Index: Integer; Value: OleVariant); safecall; procedure Remove(Index: Integer); safecall; procedure Clear; safecall; function Add(Item: OleVariant): Integer; safecall; function _NewEnum: IUnknown; safecall; public constructor Create(Strings: TStrings); end; TReflectorWindow = class(TWinControl) private FControl: TControl; FInSize: Boolean; procedure WMGetDlgCode(var Message: TMessage); message WM_GETDLGCODE; procedure WMSetFocus(var Message: TWMSetFocus); message WM_SETFOCUS; procedure WMSize(var Message: TWMSize); message WM_SIZE; protected procedure CreateParams(var Params: TCreateParams); override; public constructor Create(ParentWindow: HWND; Control: TControl); reintroduce; end; procedure EnumDispatchProperties(Dispatch: IDispatch; PropType: TGUID; VTCode: Integer; PropList: TStrings); procedure GetOleFont(Font: TFont; var OleFont: IFontDisp); procedure SetOleFont(Font: TFont; OleFont: IFontDisp); procedure GetOlePicture(Picture: TPicture; var OlePicture: IPictureDisp); procedure SetOlePicture(Picture: TPicture; OlePicture: IPictureDisp); procedure GetOleStrings(Strings: TStrings; var OleStrings: IStrings); procedure SetOleStrings(Strings: TStrings; OleStrings: IStrings); function ParkingWindow: HWND; implementation uses Consts; const OCM_BASE = $2000; type TWinControlAccess = class(TWinControl); IStdEvents = dispinterface ['{00020400-0000-0000-C000-000000000046}'] procedure Click; dispid DISPID_CLICK; procedure DblClick; dispid DISPID_DBLCLICK; procedure KeyDown(var KeyCode: Smallint; Shift: Smallint); dispid DISPID_KEYDOWN; procedure KeyPress(var KeyAscii: Smallint); dispid DISPID_KEYPRESS; procedure KeyUp(var KeyCode: Smallint; Shift: Smallint); dispid DISPID_KEYUP; procedure MouseDown(Button, Shift: Smallint; X, Y: Integer); dispid DISPID_MOUSEDOWN; procedure MouseMove(Button, Shift: Smallint; X, Y: Integer); dispid DISPID_MOUSEMOVE; procedure MouseUp(Button, Shift: Smallint; X, Y: Integer); dispid DISPID_MOUSEUP; end; var xParkingWindow: HWND; { Dynamically load functions used in OLEPRO32.DLL } function OleCreatePropertyFrame(hwndOwner: HWnd; x, y: Integer; lpszCaption: POleStr; cObjects: Integer; pObjects: Pointer; cPages: Integer; pPageCLSIDs: Pointer; lcid: TLCID; dwReserved: Longint; pvReserved: Pointer): HResult; forward; function OleCreateFontIndirect(const FontDesc: TFontDesc; const iid: TIID; out vObject): HResult; forward; function OleCreatePictureIndirect(const PictDesc: TPictDesc; const iid: TIID; fOwn: BOOL; out vObject): HResult; forward; function OleLoadPicture(stream: IStream; lSize: Longint; fRunmode: BOOL; const iid: TIID; out vObject): HResult; forward; function ParkingWindowProc(Wnd: HWND; Msg, wParam, lParam: Longint): Longint; stdcall; var ControlWnd: HWND; begin case Msg of WM_COMPAREITEM, WM_DELETEITEM, WM_DRAWITEM, WM_MEASUREITEM, WM_COMMAND: begin case Msg of WM_COMPAREITEM: ControlWnd := PCompareItemStruct(lParam).CtlID; WM_DELETEITEM: ControlWnd := PDeleteItemStruct(lParam).CtlID; WM_DRAWITEM: ControlWnd := PDrawItemStruct(lParam).CtlID; WM_MEASUREITEM: ControlWnd := PMeasureItemStruct(lParam).CtlID; WM_COMMAND: ControlWnd := HWND(lParam); else Result := 0; Exit; end; Result := SendMessage(ControlWnd, OCM_BASE + Msg, wParam, lParam); end; else if (Msg = WM_NCDESTROY) and (Wnd = xParkingWindow) then xParkingWindow := 0; Result := DefWindowProc(Wnd, Msg, WParam, LParam); end; end; function ParkingWindow: HWND; var TempClass: TWndClass; ParkingName : String; begin Result := xParkingWindow; //if Result <> 0 then Exit; // fix Dax error : accessviolation (win2k, win xp) ParkingName := 'DAXParkingWindow_' + Format('%p', [@ParkingWindowProc]); FillChar(TempClass, sizeof(TempClass), 0); if not GetClassInfo(HInstance, PChar(ParkingName), TempClass) then // fix Dax error : accessviolation (win2k, win xp) begin TempClass.hInstance := HInstance; TempClass.lpfnWndProc := @ParkingWindowProc; TempClass.lpszClassName := PChar(ParkingName); // fix Dax error : accessviolation (win2k, win xp) if Windows.RegisterClass(TempClass) = 0 then raise EOutOfResources.Create(SWindowClass); end; xParkingWindow := CreateWindowEx(WS_EX_TOOLWINDOW, TempClass.lpszClassName, nil, WS_POPUP, GetSystemMetrics(SM_CXSCREEN) div 2, GetSystemMetrics(SM_CYSCREEN) div 2, 0, 0, 0, 0, HInstance, nil); SetWindowPos(xParkingWindow, 0, 0, 0, 0, 0, SWP_NOACTIVATE or SWP_NOREDRAW or SWP_NOZORDER or SWP_SHOWWINDOW); Result := xParkingWindow; end; {function ParkingWindow: HWND; var TempClass: TWndClass; begin Result := xParkingWindow; if Result <> 0 then Exit; if GetClassInfo(HInstance, 'DAXParkingWindow', TempClass) and (TempClass.lpfnWndProc <> @ParkingWindowProc) and not Windows.UnregisterClass('DAXParkingWindow', HInstance) then RaiseLastOSError; FillChar(TempClass, sizeof(TempClass), 0); if not GetClassInfo(HInstance, 'DAXParkingWindow', TempClass) then begin TempClass.hInstance := HInstance; TempClass.lpfnWndProc := @ParkingWindowProc; TempClass.lpszClassName := 'DAXParkingWindow'; if Windows.RegisterClass(TempClass) = 0 then raise EOutOfResources.Create(SWindowClass); end; xParkingWindow := CreateWindowEx(WS_EX_TOOLWINDOW, TempClass.lpszClassName, nil, WS_POPUP, GetSystemMetrics(SM_CXSCREEN) div 2, GetSystemMetrics(SM_CYSCREEN) div 2, 0, 0, 0, 0, HInstance, nil); SetWindowPos(xParkingWindow, 0, 0, 0, 0, 0, SWP_NOACTIVATE or SWP_NOREDRAW or SWP_NOZORDER or SWP_SHOWWINDOW); Result := xParkingWindow; end; } function HandleException: HResult; var E: TObject; begin E := ExceptObject; if (E is EOleSysError) and (EOleSysError(E).ErrorCode < 0) then Result := EOleSysError(E).ErrorCode else Result := E_UNEXPECTED; end; procedure FreeObjects(List: TList); var I: Integer; begin for I := List.Count - 1 downto 0 do TObject(List[I]).Free; end; procedure FreeObjectList(List: TList); begin if List <> nil then begin FreeObjects(List); List.Free; end; end; function CoAllocMem(Size: Integer): Pointer; begin Result := CoTaskMemAlloc(Size); if Result = nil then OleError(E_OUTOFMEMORY); FillChar(Result^, Size, 0); end; procedure CoFreeMem(P: Pointer); begin if P <> nil then CoTaskMemFree(P); end; function CoAllocString(const S: string): POleStr; var W: WideString; Size: Integer; begin W := S; Size := (Length(W) + 1) * 2; Result := CoAllocMem(Size); Move(PWideChar(W)^, Result^, Size); end; { Fill list with properties of a given IDispatch } procedure EnumDispatchProperties(Dispatch: IDispatch; PropType: TGUID; VTCode: Integer; PropList: TStrings); const INVOKE_PROPERTYSET = INVOKE_PROPERTYPUT or INVOKE_PROPERTYPUTREF; var I: Integer; TypeInfo: ITypeInfo; TypeAttr: PTypeAttr; FuncDesc: PFuncDesc; VarDesc: PVarDesc; procedure SaveName(Id: Integer); var Name: WideString; begin OleCheck(TypeInfo.GetDocumentation(Id, @Name, nil, nil, nil)); if PropList.IndexOfObject(TObject(Id)) = -1 then PropList.AddObject(Name, TObject(Id)); end; function IsPropType(const TypeInfo: ITypeInfo; TypeDesc: PTypeDesc): Boolean; var RefInfo: ITypeInfo; RefAttr: PTypeAttr; IsNullGuid: Boolean; begin IsNullGuid := IsEqualGuid(PropType, GUID_NULL); Result := IsNullGuid and (VTCode = VT_EMPTY); if Result then Exit; case TypeDesc.vt of VT_PTR: Result := IsPropType(TypeInfo, TypeDesc.ptdesc); VT_USERDEFINED: begin OleCheck(TypeInfo.GetRefTypeInfo(TypeDesc.hreftype, RefInfo)); OleCheck(RefInfo.GetTypeAttr(RefAttr)); try Result := IsEqualGUID(RefAttr.guid, PropType); if not Result and (RefAttr.typekind = TKIND_ALIAS) then Result := IsPropType(RefInfo, @RefAttr.tdescAlias); finally RefInfo.ReleaseTypeAttr(RefAttr); end; end; else Result := IsNullGuid and (TypeDesc.vt = VTCode); end; end; function HasMember(const TypeInfo: ITypeInfo; Cnt, MemID, InvKind: Integer): Boolean; var I: Integer; FuncDesc: PFuncDesc; begin for I := 0 to Cnt - 1 do begin OleCheck(TypeInfo.GetFuncDesc(I, FuncDesc)); try if (FuncDesc.memid = MemID) and (FuncDesc.invkind and InvKind <> 0) then begin Result := True; Exit; end; finally TypeInfo.ReleaseFuncDesc(FuncDesc); end; end; Result := False; end; begin OleCheck(Dispatch.GetTypeInfo(0,0,TypeInfo)); if TypeInfo = nil then Exit; OleCheck(TypeInfo.GetTypeAttr(TypeAttr)); try for I := 0 to TypeAttr.cVars - 1 do begin OleCheck(TypeInfo.GetVarDesc(I, VarDesc)); try if (VarDesc.wVarFlags and VARFLAG_FREADONLY <> 0) and IsPropType(TypeInfo, @VarDesc.elemdescVar.tdesc) then SaveName(VarDesc.memid); finally TypeInfo.ReleaseVarDesc(VarDesc); end; end; for I := 0 to TypeAttr.cFuncs - 1 do begin OleCheck(TypeInfo.GetFuncDesc(I, FuncDesc)); try if ((FuncDesc.invkind = INVOKE_PROPERTYGET) and (FuncDesc.cParams < 1) and HasMember(TypeInfo, TypeAttr.cFuncs, FuncDesc.memid, INVOKE_PROPERTYSET) and IsPropType(TypeInfo, @FuncDesc.elemdescFunc.tdesc)) or ((FuncDesc.invkind and INVOKE_PROPERTYSET <> 0) and (FuncDesc.cParams < 2) and HasMember(TypeInfo, TypeAttr.cFuncs, FuncDesc.memid, INVOKE_PROPERTYGET) and IsPropType(TypeInfo, @FuncDesc.lprgelemdescParam[FuncDesc.cParams - 1].tdesc)) then SaveName(FuncDesc.memid); finally TypeInfo.ReleaseFuncDesc(FuncDesc); end; end; finally TypeInfo.ReleaseTypeAttr(TypeAttr); end; end; { Font and Picture support } function GetFontAccess(Font: TFont): IFontAccess; begin if Font.FontAdapter = nil then Font.FontAdapter := TFontAdapter.Create(Font); Result := Font.FontAdapter as IFontAccess; end; function GetPictureAccess(Picture: TPicture): IPictureAccess; begin if Picture.PictureAdapter = nil then Picture.PictureAdapter := TPictureAdapter.Create(Picture); Result := Picture.PictureAdapter as IPictureAccess; end; procedure GetOleFont(Font: TFont; var OleFont: IFontDisp); begin GetFontAccess(Font).GetOleFont(OleFont); end; procedure SetOleFont(Font: TFont; OleFont: IFontDisp); begin GetFontAccess(Font).SetOleFont(OleFont); end; procedure GetOlePicture(Picture: TPicture; var OlePicture: IPictureDisp); begin GetPictureAccess(Picture).GetOlePicture(OlePicture); end; procedure SetOlePicture(Picture: TPicture; OlePicture: IPictureDisp); begin GetPictureAccess(Picture).SetOlePicture(OlePicture); end; function GetKeyModifiers: Integer; begin Result := 0; if GetKeyState(VK_SHIFT) < 0 then Result := 1; if GetKeyState(VK_CONTROL) < 0 then Result := Result or 2; if GetKeyState(VK_MENU) < 0 then Result := Result or 4; end; function GetEventShift(Shift: TShiftState): Integer; const ShiftMap: array[0..7] of Byte = (0, 1, 4, 5, 2, 3, 6, 7); begin Result := ShiftMap[Byte(Shift) and 7]; end; function GetEventButton(Button: TMouseButton): Integer; begin Result := 1 shl Ord(Button); end; { TOleStream } constructor TOleStream.Create(const Stream: IStream); begin FStream := Stream; end; function TOleStream.Read(var Buffer; Count: Longint): Longint; begin OleCheck(FStream.Read(@Buffer, Count, @Result)); end; function TOleStream.Seek(Offset: Longint; Origin: Word): Longint; var Pos: Largeint; begin OleCheck(FStream.Seek(Offset, Origin, Pos)); Result := Longint(Pos); end; function TOleStream.Write(const Buffer; Count: Longint): Longint; begin OleCheck(FStream.Write(@Buffer, Count, @Result)); end; function TOleStream.GetIStream: IStream; begin Result := FStream; end; { TEnumConnections } type TEnumConnections = class(TInterfacedObject, IEnumConnections) private FConnectionPoint: TConnectionPoint; FController: IUnknown; FIndex: Integer; FCount: Integer; protected { IEnumConnections } function Next(celt: Longint; out elt; pceltFetched: PLongint): HResult; stdcall; function Skip(celt: Longint): HResult; stdcall; function Reset: HResult; stdcall; function Clone(out enumconn: IEnumConnections): HResult; stdcall; public constructor Create(ConnectionPoint: TConnectionPoint; Index: Integer); end; constructor TEnumConnections.Create(ConnectionPoint: TConnectionPoint; Index: Integer); begin inherited Create; FConnectionPoint := ConnectionPoint; // keep ConnectionPoint's controller alive as long as we're in use FController := FConnectionPoint.Controller; FIndex := Index; FCount := ConnectionPoint.FSinkList.Count; end; { TEnumConnections.IEnumConnections } function TEnumConnections.Next(celt: Longint; out elt; pceltFetched: PLongint): HResult; type TConnectDatas = array[0..1023] of TConnectData; var I: Integer; P: Pointer; begin I := 0; while (I < celt) and (FIndex < FCount) do begin P := FConnectionPoint.FSinkList[FIndex]; if P <> nil then begin Pointer(TConnectDatas(elt)[I].pUnk) := nil; TConnectDatas(elt)[I].pUnk := IUnknown(P); TConnectDatas(elt)[I].dwCookie := FIndex + 1; Inc(I); end; Inc(FIndex); end; if pceltFetched <> nil then pceltFetched^ := I; if I = celt then Result := S_OK else Result := S_FALSE; end; function TEnumConnections.Skip(celt: Longint): HResult; stdcall; begin Result := S_FALSE; while (celt > 0) and (FIndex < FCount) do begin if FConnectionPoint.FSinkList[FIndex] <> nil then Dec(celt); Inc(FIndex); end; if celt = 0 then Result := S_OK; end; function TEnumConnections.Reset: HResult; stdcall; begin FIndex := 0; Result := S_OK; end; function TEnumConnections.Clone(out enumconn: IEnumConnections): HResult; stdcall; begin try enumconn := TEnumConnections.Create(FConnectionPoint, FIndex); Result := S_OK; except Result := E_UNEXPECTED; end; end; { TConnectionPoint } constructor TConnectionPoint.Create(Container: TConnectionPoints; const IID: TGUID; Kind: TConnectionKind; OnConnect: TConnectEvent); begin inherited Create(IUnknown(Container.FController)); FContainer := Container; FContainer.FConnectionPoints.Add(Self); FSinkList := TList.Create; FIID := IID; FKind := Kind; FOnConnect := OnConnect; end; destructor TConnectionPoint.Destroy; var I: Integer; begin if FContainer <> nil then FContainer.FConnectionPoints.Remove(Self); if FSinkList <> nil then begin for I := 0 to FSinkList.Count - 1 do if FSinkList[I] <> nil then RemoveSink(I); FSinkList.Free; end; inherited Destroy; end; function TConnectionPoint.AddSink(const Sink: IUnknown): Integer; var I: Integer; begin I := 0; while I < FSinkList.Count do begin if FSinkList[I] = nil then Break else Inc(I); end; if I >= FSinkList.Count then FSinkList.Add(Pointer(Sink)) else FSinkList[I] := Pointer(Sink); Sink._AddRef; Result := I; end; procedure TConnectionPoint.RemoveSink(Cookie: Longint); var Sink: Pointer; begin Sink := FSinkList[Cookie]; FSinkList[Cookie] := nil; IUnknown(Sink)._Release; end; { TConnectionPoint.IConnectionPoint } function TConnectionPoint.GetConnectionInterface(out iid: TIID): HResult; begin iid := FIID; Result := S_OK; end; function TConnectionPoint.GetConnectionPointContainer( out cpc: IConnectionPointContainer): HResult; begin cpc := IUnknown(FContainer.FController) as IConnectionPointContainer; Result := S_OK; end; function TConnectionPoint.Advise(const unkSink: IUnknown; out dwCookie: Longint): HResult; begin if (FKind = ckSingle) and (FSinkList.Count > 0) and (FSinkList[0] <> nil) then begin Result := CONNECT_E_CANNOTCONNECT; Exit; end; try if Assigned(FOnConnect) then FOnConnect(unkSink, True); dwCookie := AddSink(unkSink) + 1; Result := S_OK; except Result := HandleException; end; end; function TConnectionPoint.Unadvise(dwCookie: Longint): HResult; begin Dec(dwCookie); if (dwCookie < 0) or (dwCookie >= FSinkList.Count) or (FSinkList[dwCookie] = nil) then begin Result := CONNECT_E_NOCONNECTION; Exit; end; try if Assigned(FOnConnect) then FOnConnect(IUnknown(FSinkList[dwCookie]), False); RemoveSink(dwCookie); Result := S_OK; except Result := HandleException; end; end; function TConnectionPoint.EnumConnections(out enumconn: IEnumConnections): HResult; begin try enumconn := TEnumConnections.Create(Self, 0); Result := S_OK; except Result := HandleException; end; end; { TEnumConnectionPoints } type TEnumConnectionPoints = class(TContainedObject, IEnumConnectionPoints) private FContainer: TConnectionPoints; FIndex: Integer; protected { IEnumConnectionPoints } function Next(celt: Longint; out elt; pceltFetched: PLongint): HResult; stdcall; function Skip(celt: Longint): HResult; stdcall; function Reset: HResult; stdcall; function Clone(out enumconn: IEnumConnectionPoints): HResult; stdcall; public constructor Create(Container: TConnectionPoints; Index: Integer); end; constructor TEnumConnectionPoints.Create(Container: TConnectionPoints; Index: Integer); begin inherited Create(IUnknown(Container.FController)); FContainer := Container; FIndex := Index; end; { TEnumConnectionPoints.IEnumConnectionPoints } type TPointerList = array[0..0] of Pointer; function TEnumConnectionPoints.Next(celt: Longint; out elt; pceltFetched: PLongint): HResult; var I: Integer; P: Pointer; begin I := 0; while (I < celt) and (FIndex < FContainer.FConnectionPoints.Count) do begin P := Pointer(IConnectionPoint(TConnectionPoint( FContainer.FConnectionPoints[FIndex]))); IConnectionPoint(P)._AddRef; TPointerList(elt)[I] := P; Inc(I); Inc(FIndex); end; if pceltFetched <> nil then pceltFetched^ := I; if I = celt then Result := S_OK else Result := S_FALSE; end; function TEnumConnectionPoints.Skip(celt: Longint): HResult; stdcall; begin if FIndex + celt <= FContainer.FConnectionPoints.Count then begin FIndex := FIndex + celt; Result := S_OK; end else begin FIndex := FContainer.FConnectionPoints.Count; Result := S_FALSE; end; end; function TEnumConnectionPoints.Reset: HResult; stdcall; begin FIndex := 0; Result := S_OK; end; function TEnumConnectionPoints.Clone( out enumconn: IEnumConnectionPoints): HResult; stdcall; begin try enumconn := TEnumConnectionPoints.Create(FContainer, FIndex); Result := S_OK; except Result := E_UNEXPECTED; end; end; { TConnectionPoints } constructor TConnectionPoints.Create(const AController: IUnknown); begin // weak reference, don't keep the controller alive FController := Pointer(AController); FConnectionPoints := TList.Create; end; destructor TConnectionPoints.Destroy; begin FreeObjectList(FConnectionPoints); inherited Destroy; end; function TConnectionPoints.CreateConnectionPoint(const IID: TGUID; Kind: TConnectionKind; OnConnect: TConnectEvent): TConnectionPoint; begin Result := TConnectionPoint.Create(Self, IID, Kind, OnConnect); end; { TConnectionPoints.IConnectionPointContainer } function TConnectionPoints.EnumConnectionPoints( out enumconn: IEnumConnectionPoints): HResult; begin try enumconn := TEnumConnectionPoints.Create(Self, 0); Result := S_OK; except Result := E_UNEXPECTED; end; end; function TConnectionPoints.FindConnectionPoint(const iid: TIID; out cp: IConnectionPoint): HResult; var I: Integer; ConnectionPoint: TConnectionPoint; begin for I := 0 to FConnectionPoints.Count - 1 do begin ConnectionPoint := FConnectionPoints[I]; if IsEqualGUID(ConnectionPoint.FIID, iid) then begin cp := ConnectionPoint; Result := S_OK; Exit; end; end; Result := CONNECT_E_NOCONNECTION; end; function TConnectionPoints.GetController: IUnknown; begin Result := IUnknown(FController); end; { TReflectorWindow } constructor TReflectorWindow.Create(ParentWindow: HWND; Control: TControl); begin inherited CreateParented(ParentWindow); FControl := Control; FInSize := True; try FControl.Parent := Self; FControl.SetBounds(0, 0, FControl.Width, FControl.Height); finally FInSize := False; end; SetBounds(Left, Top, FControl.Width, FControl.Height); end; procedure TReflectorWindow.CreateParams(var Params: TCreateParams); begin inherited CreateParams(Params); Params.Style := Params.Style or WS_CLIPCHILDREN; end; procedure TReflectorWindow.WMGetDlgCode(var Message: TMessage); begin TWinControlAccess(FControl).WndProc(Message); end; procedure TReflectorWindow.WMSetFocus(var Message: TWMSetFocus); begin if FControl is TWinControl then Windows.SetFocus(TWinControl(FControl).Handle) else inherited; end; procedure TReflectorWindow.WMSize(var Message: TWMSize); begin if not FInSize then begin FInSize := True; try FControl.SetBounds(0, 0, Message.Width, Message.Height); SetBounds(Left, Top, FControl.Width, FControl.Height); finally FInSize := False; end; end; inherited; end; { TOleLinkStub } type TOleLinkStub = class(TInterfacedObject, IUnknown, IOleLink) private Controller: IUnknown; public constructor Create(const AController: IUnknown); { IUnknown } function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall; { IOleLink } function SetUpdateOptions(dwUpdateOpt: Longint): HResult; stdcall; function GetUpdateOptions(out dwUpdateOpt: Longint): HResult; stdcall; function SetSourceMoniker(const mk: IMoniker; const clsid: TCLSID): HResult; stdcall; function GetSourceMoniker(out mk: IMoniker): HResult; stdcall; function SetSourceDisplayName(pszDisplayName: POleStr): HResult; stdcall; function GetSourceDisplayName(out pszDisplayName: POleStr): HResult; stdcall; function BindToSource(bindflags: Longint; const bc: IBindCtx): HResult; stdcall; function BindIfRunning: HResult; stdcall; function GetBoundSource(out unk: IUnknown): HResult; stdcall; function UnbindSource: HResult; stdcall; function Update(const bc: IBindCtx): HResult; stdcall; end; constructor TOleLinkStub.Create(const AController: IUnknown); begin inherited Create; Controller := AController; end; { TOleLinkStub.IUnknown } function TOleLinkStub.QueryInterface(const IID: TGUID; out Obj): HResult; begin Result := Controller.QueryInterface(IID, Obj); end; { TOleLinkStub.IOleLink } function TOleLinkStub.SetUpdateOptions(dwUpdateOpt: Longint): HResult; begin Result := E_NOTIMPL; end; function TOleLinkStub.GetUpdateOptions(out dwUpdateOpt: Longint): HResult; begin Result := E_NOTIMPL; end; function TOleLinkStub.SetSourceMoniker(const mk: IMoniker; const clsid: TCLSID): HResult; begin Result := E_NOTIMPL; end; function TOleLinkStub.GetSourceMoniker(out mk: IMoniker): HResult; begin Result := E_NOTIMPL; end; function TOleLinkStub.SetSourceDisplayName(pszDisplayName: POleStr): HResult; begin Result := E_NOTIMPL; end; function TOleLinkStub.GetSourceDisplayName(out pszDisplayName: POleStr): HResult; begin pszDisplayName := nil; Result := E_FAIL; end; function TOleLinkStub.BindToSource(bindflags: Longint; const bc: IBindCtx): HResult; begin Result := E_NOTIMPL; end; function TOleLinkStub.BindIfRunning: HResult; begin Result := S_OK; end; function TOleLinkStub.GetBoundSource(out unk: IUnknown): HResult; begin Result := E_NOTIMPL; end; function TOleLinkStub.UnbindSource: HResult; begin Result := E_NOTIMPL; end; function TOleLinkStub.Update(const bc: IBindCtx): HResult; begin Result := E_NOTIMPL; end; { TActiveXControl } procedure TActiveXControl.Initialize; begin inherited Initialize; FConnectionPoints := TConnectionPoints.Create(Self); FOleLinkStub := TOleLinkStub.Create(nil); FOleLinkStub._AddRef; FControlFactory := Factory as TActiveXControlFactory; if FControlFactory.EventTypeInfo <> nil then FConnectionPoints.CreateConnectionPoint(FControlFactory.EventIID, ckSingle, EventConnect); FPropertySinks := FConnectionPoints.CreateConnectionPoint(IPropertyNotifySink, ckMulti, nil); FControl := FControlFactory.WinControlClass.CreateParented(ParkingWindow); if csReflector in FControl.ControlStyle then FWinControl := TReflectorWindow.Create(ParkingWindow, FControl) else FWinControl := FControl; FControlWndProc := FControl.WindowProc; FControl.WindowProc := WndProc; InitializeControl; end; destructor TActiveXControl.Destroy; begin if Assigned(FControlWndProc) then FControl.WindowProc := FControlWndProc; FControl.Free; if FWinControl <> FControl then FWinControl.Free; FConnectionPoints.Free; FOleLinkStub := nil; inherited Destroy; end; function TActiveXControl.CreateAdviseHolder: HResult; begin if FOleAdviseHolder = nil then Result := CreateOleAdviseHolder(FOleAdviseHolder) else Result := S_OK; end; procedure TActiveXControl.DefinePropertyPages( DefinePropertyPage: TDefinePropertyPage); begin end; function TActiveXControl.GetPropertyString(DispID: Integer; var S: string): Boolean; begin Result := False; end; function TActiveXControl.GetPropertyStrings(DispID: Integer; Strings: TStrings): Boolean; begin Result := False; end; procedure TActiveXControl.GetPropFromBag(const PropName: WideString; DispatchID: Integer; PropBag: IPropertyBag; ErrorLog: IErrorLog); var PropValue: OleVariant; begin // Note: raise an EAbort exception here to stop properties from loading if PropBag.Read(PWideChar(PropName), PropValue, ErrorLog) = S_OK then ComObj.SetDispatchPropValue(Self as IDispatch, DispatchID, PropValue); end; procedure TActiveXControl.PutPropInBag(const PropName: WideString; DispatchID: Integer; PropBag: IPropertyBag); begin PropBag.Write(PWideChar(PropName), ComObj.GetDispatchPropValue(Self as IDispatch, DispatchID)); end; procedure TActiveXControl.GetPropertyValue(DispID, Cookie: Integer; var Value: OleVariant); begin end; procedure TActiveXControl.InitializeControl; begin end; function TActiveXControl.InPlaceActivate(ActivateUI: Boolean): HResult; var InPlaceActivateSent: Boolean; ParentWindow: HWND; PosRect, ClipRect: TRect; FrameInfo: TOleInPlaceFrameInfo; begin Result := S_OK; FWinControl.Visible := True; InPlaceActivateSent := False; if not FInPlaceActive then try if FOleClientSite = nil then OleError(E_FAIL); OleCheck(FOleClientSite.QueryInterface(IOleInPlaceSite, FOleInPlaceSite)); if FOleInPlaceSite.CanInPlaceActivate <> S_OK then OleError(E_FAIL); OleCheck(FOleInPlaceSite.OnInPlaceActivate); InPlaceActivateSent := True; OleCheck(FOleInPlaceSite.GetWindow(ParentWindow)); FrameInfo.cb := SizeOf(FrameInfo); OleCheck(FOleInPlaceSite.GetWindowContext(FOleInPlaceFrame, FOleInPlaceUIWindow, PosRect, ClipRect, FrameInfo)); if FOleInPlaceFrame = nil then OleError(E_FAIL); with PosRect do FWinControl.SetBounds(Left, Top, Right - Left, Bottom - Top); FWinControl.ParentWindow := ParentWindow; FWinControl.Visible := True; FInPlaceActive := True; FOleClientSite.ShowObject; except FInPlaceActive := False; FOleInPlaceUIWindow := nil; FOleInPlaceFrame := nil; if InPlaceActivateSent then FOleInPlaceSite.OnInPlaceDeactivate; FOleInPlaceSite := nil; Result := HandleException; Exit; end; if ActivateUI and not FUIActive then begin FUIActive := True; FOleInPlaceSite.OnUIActivate; SetFocus(FWinControl.Handle); FOleInPlaceFrame.SetActiveObject(Self as IOleInPlaceActiveObject, nil); if FOleInPlaceUIWindow <> nil then FOleInPlaceUIWindow.SetActiveObject(Self as IOleInPlaceActiveObject, nil); FOleInPlaceFrame.SetBorderSpace(nil); if FOleInPlaceUIWindow <> nil then FOleInPlaceUIWindow.SetBorderSpace(nil); end; end; procedure TActiveXControl.LoadFromStream(const Stream: IStream); var OleStream: TOleStream; begin OleStream := TOleStream.Create(Stream); try OleStream.ReadComponent(FControl); finally OleStream.Free; end; end; function TActiveXControl.ObjQueryInterface(const IID: TGUID; out Obj): HResult; begin if IsEqualGuid(IID, ISimpleFrameSite) and ((FControlFactory.MiscStatus and OLEMISC_SIMPLEFRAME) = 0) then Result := E_NOINTERFACE else begin Result := inherited ObjQueryInterface(IID, Obj); if Result <> 0 then if IsEqualGuid(IID, IOleLink) then begin // Work around for an MS Access 97 bug that requires IOleLink // to be stubbed. Pointer(Obj) := nil; IOleLink(Obj) := TOleLinkStub.Create(Self); end; end; end; procedure TActiveXControl.PerformVerb(Verb: Integer); begin end; function TActiveXControl.GetPropertyID(const PropertyName: WideString): Integer; var PName: PWideChar; begin PName := PWideChar(PropertyName); if PropertyName = '' then Result := DISPID_UNKNOWN else OleCheck(GetIDsOfNames(GUID_NULL, @PName, 1, GetThreadLocale, @Result)); end; procedure TActiveXControl.PropChanged(const PropertyName: WideString); var PropID: Integer; begin PropID := GetPropertyID(PropertyName); PropChanged(PropID); end; procedure TActiveXControl.PropChanged(DispID: TDispID); var Enum: IEnumConnections; ConnectData: TConnectData; Fetched: Longint; begin OleCheck(FPropertySinks.EnumConnections(Enum)); while Enum.Next(1, ConnectData, @Fetched) = S_OK do begin (ConnectData.pUnk as IPropertyNotifySink).OnChanged(DispID); ConnectData.pUnk := nil; end; end; function TActiveXControl.PropRequestEdit(const PropertyName: WideString): Boolean; var PropID: Integer; begin PropID := GetPropertyID(PropertyName); Result := PropRequestEdit(PropID); end; function TActiveXControl.PropRequestEdit(DispID: TDispID): Boolean; var Enum: IEnumConnections; ConnectData: TConnectData; Fetched: Longint; begin Result := True; OleCheck(FPropertySinks.EnumConnections(Enum)); while Enum.Next(1, ConnectData, @Fetched) = S_OK do begin Result := (ConnectData.pUnk as IPropertyNotifySink).OnRequestEdit(DispID) = S_OK; ConnectData.pUnk := nil; if not Result then Exit; end; end; procedure TActiveXControl.RecreateWnd; var WasUIActive: Boolean; PrevWnd: HWND; begin if FWinControl.HandleAllocated then begin WasUIActive := FUIActive; PrevWnd := Windows.GetWindow(FWinControl.Handle, GW_HWNDPREV); InPlaceDeactivate; TWinControlAccess(FWinControl).DestroyHandle; if InPlaceActivate(WasUIActive) = S_OK then SetWindowPos(FWinControl.Handle, PrevWnd, 0, 0, 0, 0, SWP_NOSIZE or SWP_NOMOVE or SWP_NOACTIVATE); end; end; procedure TActiveXControl.SaveToStream(const Stream: IStream); var OleStream: TOleStream; Writer: TWriter; begin OleStream := TOleStream.Create(Stream); try Writer := TWriter.Create(OleStream, 4096); try Writer.IgnoreChildren := True; Writer.WriteDescendent(FControl, nil); finally Writer.Free; end; finally OleStream.Free; end; end; procedure TActiveXControl.ShowPropertyDialog; var Unknown: IUnknown; Pages: TCAGUID; begin if (FOleControlSite <> nil) and (FOleControlSite.ShowPropertyFrame = S_OK) then Exit; OleCheck(GetPages(Pages)); try if Pages.cElems > 0 then begin if FOleInPlaceFrame <> nil then FOleInPlaceFrame.EnableModeless(False); try Unknown := Self; OleCheck(OleCreatePropertyFrame(GetActiveWindow, 16, 16, PWideChar(FAmbientDispatch.DisplayName), {+ !!} 1, @Unknown, Pages.cElems, Pages.pElems, GetSystemDefaultLCID, 0, nil)); finally if FOleInPlaceFrame <> nil then FOleInPlaceFrame.EnableModeless(True); end; end; finally CoFreeMem(pages.pElems); end; end; procedure TActiveXControl.SetInPlaceSite(const NewInPlaceSite: IOleInPlaceSite); begin FOleInPlaceSite := NewInPlaceSite; end; procedure TActiveXControl.StdClickEvent(Sender: TObject); begin if EventSink <> nil then IStdEvents(EventSink).Click; end; procedure TActiveXControl.StdDblClickEvent(Sender: TObject); begin if EventSink <> nil then IStdEvents(EventSink).DblClick; end; procedure TActiveXControl.StdKeyDownEvent(Sender: TObject; var Key: Word; Shift: TShiftState); begin if EventSink <> nil then IStdEvents(EventSink).KeyDown(Smallint(Key), GetEventShift(Shift)); end; procedure TActiveXControl.StdKeyPressEvent(Sender: TObject; var Key: Char); var KeyAscii: Smallint; begin if EventSink <> nil then begin KeyAscii := Ord(Key); IStdEvents(EventSink).KeyPress(KeyAscii); Key := Chr(KeyAscii); end; end; procedure TActiveXControl.StdKeyUpEvent(Sender: TObject; var Key: Word; Shift: TShiftState); begin if EventSink <> nil then IStdEvents(EventSink).KeyUp(Smallint(Key), GetEventShift(Shift)); end; procedure TActiveXControl.StdMouseDownEvent(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if EventSink <> nil then IStdEvents(EventSink).MouseDown(GetEventButton(Button), GetEventShift(Shift), X, Y); end; procedure TActiveXControl.StdMouseMoveEvent(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin if EventSink <> nil then IStdEvents(EventSink).MouseMove((Byte(Shift) shr 3) and 7, GetEventShift(Shift), X, Y); end; procedure TActiveXControl.StdMouseUpEvent(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if EventSink <> nil then IStdEvents(EventSink).MouseUp(GetEventButton(Button), GetEventShift(Shift), X, Y); end; procedure TActiveXControl.ViewChanged; begin if FAdviseSink <> nil then begin FAdviseSink.OnViewChange(DVASPECT_CONTENT, -1); if FAdviseFlags and ADVF_ONLYONCE <> 0 then FAdviseSink := nil; end; end; procedure TActiveXControl.WndProc(var Message: TMessage); var Handle: HWnd; FilterMessage: Boolean; Cookie: Longint; procedure ControlWndProc; begin with Message do if (Msg >= OCM_BASE) and (Msg < OCM_BASE + WM_USER) then Msg := Msg + (CN_BASE - OCM_BASE); FControlWndProc(Message); with Message do if (Msg >= CN_BASE) and (Msg < CN_BASE + WM_USER) then Msg := Msg - (CN_BASE - OCM_BASE); end; begin with Message do begin Handle := TWinControlAccess(FControl).WindowHandle; FilterMessage := ((Msg < CM_BASE) or (Msg >= $C000)) and (FSimpleFrameSite <> nil) and FInPlaceActive; if FilterMessage then if FSimpleFrameSite.PreMessageFilter(Handle, Msg, WParam, LParam, Integer(Result), Cookie) = S_FALSE then Exit; case Msg of WM_SETFOCUS, WM_KILLFOCUS: begin ControlWndProc; if FOleControlSite <> nil then FOleControlSite.OnFocus(Msg = WM_SETFOCUS); end; CM_VISIBLECHANGED: begin if FControl <> FWinControl then FWinControl.Visible := FControl.Visible; if not FWinControl.Visible then UIDeactivate; ControlWndProc; end; CM_RECREATEWND: begin if FInPlaceActive and (FControl = FWinControl) then RecreateWnd else begin ControlWndProc; ViewChanged; end; end; CM_INVALIDATE, WM_SETTEXT: begin ControlWndProc; if not FInPlaceActive then ViewChanged; end; WM_NCHITTEST: begin ControlWndProc; if Message.Result = HTTRANSPARENT then Message.Result := HTCLIENT; end; WM_MOUSEACTIVATE: begin ControlWndProc; if not FUIActive and ((Message.Result = MA_ACTIVATE) or (Message.Result = MA_ACTIVATEANDEAT)) and (FAmbientDispatch <> nil) and FAmbientDispatch.UserMode then InPlaceActivate(True); end; else ControlWndProc; end; if FilterMessage then FSimpleFrameSite.PostMessageFilter(Handle, Msg, WParam, LParam, Integer(Result), Cookie); end; end; { TActiveXControl standard properties } function TActiveXControl.Get_BackColor: Integer; begin Result := TWinControlAccess(FControl).Color; end; function TActiveXControl.Get_Caption: WideString; begin Result := TWinControlAccess(FControl).Caption; end; function TActiveXControl.Get_Enabled: WordBool; begin Result := FControl.Enabled; end; function TActiveXControl.Get_Font: Font; begin GetOleFont(TWinControlAccess(FControl).Font, Result); end; function TActiveXControl.Get_ForeColor: Integer; begin Result := TWinControlAccess(FControl).Font.Color; end; function TActiveXControl.Get_HWnd: Integer; begin Result := FControl.Handle; end; function TActiveXControl.Get_TabStop: WordBool; begin Result := FControl.TabStop; end; function TActiveXControl.Get_Text: WideString; begin Result := TWinControlAccess(FControl).Text; end; procedure TActiveXControl.Set_BackColor(Value: Integer); begin TWinControlAccess(FControl).Color := Value; end; procedure TActiveXControl.Set_Caption(const Value: WideString); begin TWinControlAccess(FControl).Caption := Value; end; procedure TActiveXControl.Set_Enabled(Value: WordBool); begin FControl.Enabled := Value; end; procedure TActiveXControl.Set_Font(const Value: Font); begin SetOleFont(TWinControlAccess(FControl).Font, Value); end; procedure TActiveXControl.Set_ForeColor(Value: Integer); begin TWinControlAccess(FControl).Font.Color := Value; end; procedure TActiveXControl.Set_TabStop(Value: WordBool); begin FControl.TabStop := Value; end; procedure TActiveXControl.Set_Text(const Value: WideString); begin TWinControlAccess(FControl).Text := Value; end; { TActiveXControl.IPersist } function TActiveXControl.GetClassID(out classID: TCLSID): HResult; begin classID := Factory.ClassID; Result := S_OK; end; { TActiveXControl.IPersistPropertyBag } function TActiveXControl.PersistPropBagInitNew: HResult; begin Result := S_OK; end; function TActiveXControl.PersistPropBagLoad(const pPropBag: IPropertyBag; const pErrorLog: IErrorLog): HResult; var PropList: TStringList; i: Integer; begin try if pPropBag = nil then begin Result := E_POINTER; Exit; end; PropList := TStringList.Create; try EnumDispatchProperties(Self as IDispatch, GUID_NULL, VT_EMPTY, PropList); for i := 0 to PropList.Count - 1 do try GetPropFromBag(PropList[i], Integer(PropList.Objects[i]), pPropBag, pErrorLog); except // Supress all exceptions except EAbort if ExceptObject is EAbort then begin Result := E_FAIL; Exit; end; end; finally PropList.Free; end; Result := S_OK; except Result := HandleException; end; end; function TActiveXControl.PersistPropBagSave(const pPropBag: IPropertyBag; fClearDirty: BOOL; fSaveAllProperties: BOOL): HResult; var PropList: TStringList; i: Integer; begin try if pPropBag = nil then begin Result := E_POINTER; Exit; end; PropList := TStringList.Create; try EnumDispatchProperties(Self as IDispatch, GUID_NULL, VT_EMPTY, PropList); for i := 0 to PropList.Count - 1 do PutPropInBag(PropList[i], Integer(PropList.Objects[i]), pPropBag); finally PropList.Free; end; if fClearDirty then FIsDirty := False; Result := S_OK; except Result := HandleException; end; end; { TActiveXControl.IPersistStreamInit } function TActiveXControl.IsDirty: HResult; begin if FIsDirty then Result := S_OK else Result := S_FALSE; end; function TActiveXControl.PersistStreamLoad(const stm: IStream): HResult; begin try LoadFromStream(stm); FIsDirty := False; Result := S_OK; except Result := HandleException; end; end; function TActiveXControl.PersistStreamSave(const stm: IStream; fClearDirty: BOOL): HResult; begin try SaveToStream(stm); if fClearDirty then FIsDirty := False; Result := S_OK; except Result := HandleException; end; end; function TActiveXControl.GetSizeMax(out cbSize: Largeint): HResult; begin Result := E_NOTIMPL; end; function TActiveXControl.InitNew: HResult; begin try FIsDirty := False; Result := S_OK; except Result := HandleException; end; end; { TActiveXControl.IPersistStorage } function TActiveXControl.PersistStorageInitNew(const stg: IStorage): HResult; begin Result := InitNew; end; function TActiveXControl.PersistStorageLoad(const stg: IStorage): HResult; var Stream: IStream; begin try OleCheck(stg.OpenStream('CONTROLSAVESTREAM'#0, nil, STGM_READ + STGM_SHARE_EXCLUSIVE, 0, Stream)); LoadFromStream(Stream); FIsDirty := False; Result := S_OK; except Result := HandleException; end; end; function TActiveXControl.PersistStorageSave(const stgSave: IStorage; fSameAsLoad: BOOL): HResult; var Stream: IStream; begin try OleCheck(stgSave.CreateStream('CONTROLSAVESTREAM'#0, STGM_WRITE + STGM_SHARE_EXCLUSIVE + STGM_CREATE, 0, 0, Stream)); SaveToStream(Stream); Result := S_OK; except Result := HandleException; end; end; function TActiveXControl.SaveCompleted(const stgNew: IStorage): HResult; begin FIsDirty := False; Result := S_OK; end; function TActiveXControl.HandsOffStorage: HResult; begin Result := S_OK; end; { TActiveXControl.IObjectSafety } function TActiveXControl.GetInterfaceSafetyOptions(const IID: TIID; pdwSupportedOptions, pdwEnabledOptions: PDWORD): HResult; var Unk: IUnknown; begin if (pdwSupportedOptions = nil) or (pdwEnabledOptions = nil) then begin Result := E_POINTER; Exit; end; Result := QueryInterface(IID, Unk); if Result = S_OK then begin pdwSupportedOptions^ := INTERFACESAFE_FOR_UNTRUSTED_CALLER or INTERFACESAFE_FOR_UNTRUSTED_DATA; pdwEnabledOptions^ := FObjectSafetyFlags and (INTERFACESAFE_FOR_UNTRUSTED_CALLER or INTERFACESAFE_FOR_UNTRUSTED_DATA); end else begin pdwSupportedOptions^ := 0; pdwEnabledOptions^ := 0; end; end; function TActiveXControl.SetInterfaceSafetyOptions(const IID: TIID; dwOptionSetMask, dwEnabledOptions: DWORD): HResult; var Unk: IUnknown; begin Result := QueryInterface(IID, Unk); if Result <> S_OK then Exit; FObjectSafetyFlags := dwEnabledOptions and dwOptionSetMask; end; { TActiveXControl.IOleObject } function TActiveXControl.SetClientSite(const ClientSite: IOleClientSite): HResult; begin if ClientSite <> nil then begin if FOleClientSite <> nil then begin Result := E_FAIL; Exit; end; FOleClientSite := ClientSite; ClientSite.QueryInterface(IOleControlSite, FOleControlSite); if FControlFactory.MiscStatus and OLEMISC_SIMPLEFRAME <> 0 then ClientSite.QueryInterface(ISimpleFrameSite, FSimpleFrameSite); ClientSite.QueryInterface(IDispatch, FAmbientDispatch); OnAmbientPropertyChange(0); end else begin FAmbientDispatch := nil; FSimpleFrameSite := nil; FOleControlSite := nil; FOleClientSite := nil; end; Result := S_OK; end; function TActiveXControl.GetClientSite(out clientSite: IOleClientSite): HResult; begin ClientSite := FOleClientSite; Result := S_OK; end; function TActiveXControl.SetHostNames(szContainerApp: POleStr; szContainerObj: POleStr): HResult; begin Result := S_OK; end; function TActiveXControl.Close(dwSaveOption: Longint): HResult; begin Application.CancelHint; if (dwSaveOption <> OLECLOSE_NOSAVE) and FIsDirty and (FOleClientSite <> nil) then FOleClientSite.SaveObject; if (self is TActiveFormControl) then if (TActiveFormControl(self).Control is TActiveForm) then TActiveForm(TActiveFormControl(self).Control).DoDestroy; Result := InPlaceDeactivate; end; function TActiveXControl.SetMoniker(dwWhichMoniker: Longint; const mk: IMoniker): HResult; begin Result := E_NOTIMPL; end; function TActiveXControl.GetMoniker(dwAssign: Longint; dwWhichMoniker: Longint; out mk: IMoniker): HResult; begin Result := E_NOTIMPL; end; function TActiveXControl.InitFromData(const dataObject: IDataObject; fCreation: BOOL; dwReserved: Longint): HResult; begin Result := E_NOTIMPL; end; function TActiveXControl.GetClipboardData(dwReserved: Longint; out dataObject: IDataObject): HResult; begin Result := E_NOTIMPL; end; function TActiveXControl.DoVerb(iVerb: Longint; msg: PMsg; const activeSite: IOleClientSite; lindex: Longint; hwndParent: HWND; const posRect: TRect): HResult; begin try case iVerb of OLEIVERB_SHOW, OLEIVERB_UIACTIVATE: Result := InPlaceActivate(True); OLEIVERB_INPLACEACTIVATE: Result := InPlaceActivate(False); OLEIVERB_HIDE: begin FWinControl.Visible := False; Result := S_OK; end; OLEIVERB_PRIMARY, OLEIVERB_PROPERTIES: begin ShowPropertyDialog; Result := S_OK; end; else if FControlFactory.FVerbs.IndexOfObject(TObject(iVerb)) >= 0 then begin PerformVerb(iVerb); Result := S_OK; end else Result := OLEOBJ_S_INVALIDVERB; end; except Result := HandleException; end; end; function TActiveXControl.EnumVerbs(out enumOleVerb: IEnumOleVerb): HResult; begin Result := OleRegEnumVerbs(Factory.ClassID, enumOleVerb); end; function TActiveXControl.Update: HResult; begin Result := S_OK; end; function TActiveXControl.IsUpToDate: HResult; begin Result := S_OK; end; function TActiveXControl.GetUserClassID(out clsid: TCLSID): HResult; begin clsid := Factory.ClassID; Result := S_OK; end; function TActiveXControl.GetUserType(dwFormOfType: Longint; out pszUserType: POleStr): HResult; begin Result := OleRegGetUserType(Factory.ClassID, dwFormOfType, pszUserType); end; function TActiveXControl.SetExtent(dwDrawAspect: Longint; const size: TPoint): HResult; var W, H: Integer; begin try if dwDrawAspect <> DVASPECT_CONTENT then OleError(DV_E_DVASPECT); W := MulDiv(Size.X, Screen.PixelsPerInch, 2540); H := MulDiv(Size.Y, Screen.PixelsPerInch, 2540); with FWinControl do SetBounds(Left, Top, W, H); Result := S_OK; except Result := HandleException; end; end; function TActiveXControl.GetExtent(dwDrawAspect: Longint; out size: TPoint): HResult; begin if dwDrawAspect <> DVASPECT_CONTENT then begin Result := DV_E_DVASPECT; Exit; end; Size.X := MulDiv(FWinControl.Width, 2540, Screen.PixelsPerInch); Size.Y := MulDiv(FWinControl.Height, 2540, Screen.PixelsPerInch); Result := S_OK; end; function TActiveXControl.Advise(const advSink: IAdviseSink; out dwConnection: Longint): HResult; begin Result := CreateAdviseHolder; if Result = S_OK then Result := FOleAdviseHolder.Advise(advSink, dwConnection); end; function TActiveXControl.Unadvise(dwConnection: Longint): HResult; begin Result := CreateAdviseHolder; if Result = S_OK then Result := FOleAdviseHolder.Unadvise(dwConnection); end; function TActiveXControl.EnumAdvise(out enumAdvise: IEnumStatData): HResult; begin Result := CreateAdviseHolder; if Result = S_OK then Result := FOleAdviseHolder.EnumAdvise(enumAdvise); end; function TActiveXControl.GetMiscStatus(dwAspect: Longint; out dwStatus: Longint): HResult; begin if dwAspect <> DVASPECT_CONTENT then begin Result := DV_E_DVASPECT; Exit; end; dwStatus := FControlFactory.FMiscStatus; Result := S_OK; end; function TActiveXControl.SetColorScheme(const logpal: TLogPalette): HResult; begin Result := E_NOTIMPL; end; { TActiveXControl.IOleControl } function TActiveXControl.GetControlInfo(var ci: TControlInfo): HResult; begin with ci do begin cb := SizeOf(ci); hAccel := 0; cAccel := 0; dwFlags := 0; end; Result := S_OK; end; function TActiveXControl.OnMnemonic(msg: PMsg): HResult; begin Result := InPlaceActivate(True); end; function TActiveXControl.OnAmbientPropertyChange(dispid: TDispID): HResult; var Font: TFont; begin if (FWinControl <> nil) and (FAmbientDispatch <> nil) then begin try FWinControl.Perform(CM_PARENTCOLORCHANGED, 1, FAmbientDispatch.BackColor); except end; FWinControl.Perform(CM_PARENTCTL3DCHANGED, 1, 1); Font := TFont.Create; try Font.Color := FAmbientDispatch.ForeColor; SetOleFont(Font, FAmbientDispatch.Font); FWinControl.Perform(CM_PARENTFONTCHANGED, 1, Integer(Font)); except end; Font.Free; end; Result := S_OK; //OnAmbientPropChange MUST return S_OK in all cases. end; function TActiveXControl.FreezeEvents(bFreeze: BOOL): HResult; begin FEventsFrozen := bFreeze; Result := S_OK; end; { TActiveXControl.IOleWindow } function TActiveXControl.GetWindow(out wnd: HWnd): HResult; begin if FWinControl.HandleAllocated then begin wnd := FWinControl.Handle; Result := S_OK; end else Result := E_FAIL; end; function TActiveXControl.ContextSensitiveHelp(fEnterMode: BOOL): HResult; begin Result := E_NOTIMPL; end; { TActiveXControl.IOleInPlaceObject } function TActiveXControl.InPlaceDeactivate: HResult; begin if FInPlaceActive then begin FInPlaceActive := False; UIDeactivate; FWinControl.Visible := False; FWinControl.ParentWindow := ParkingWindow; FOleInPlaceUIWindow := nil; FOleInPlaceFrame := nil; FOleInPlaceSite.OnInPlaceDeactivate; FOleInPlaceSite := nil; end; FWinControl.Visible := False; Result := S_OK; end; function TActiveXControl.UIDeactivate: HResult; begin if FUIActive then begin FUIActive := False; if FOleInPlaceUIWindow <> nil then FOleInPlaceUIWindow.SetActiveObject(nil, nil); FOleInPlaceFrame.SetActiveObject(nil, nil); FOleInPlaceSite.OnUIDeactivate(False); end; Result := S_OK; end; function TActiveXControl.SetObjectRects(const rcPosRect: TRect; const rcClipRect: TRect): HResult; var IntersectionRect: TRect; NewRegion: HRGN; begin try if (@rcPosRect = nil) or (@rcClipRect = nil) then begin Result := E_POINTER; Exit; end else if FWinControl.HandleAllocated then begin // The container thinks the control should clip, figure out if the control // really needs to clip. NewRegion := 0; if IntersectRect(IntersectionRect, rcPosRect, rcClipRect) and (not EqualRect(IntersectionRect, rcPosRect)) then begin OffsetRect(IntersectionRect, -rcPosRect.Left, -rcPosRect.Top); NewRegion := CreateRectRgnIndirect(IntersectionRect); end; // Set the control's location. SetWindowRgn(FWinControl.Handle, NewRegion, True); FWinControl.BoundsRect := rcPosRect; end; Result := S_OK; except Result := HandleException; end; end; function TActiveXControl.ReactivateAndUndo: HResult; begin Result := E_NOTIMPL; end; { TActiveXControl.IOleInPlaceActiveObject } function TActiveXControl.TranslateAccelerator(var msg: TMsg): HResult; var Control: TWinControl; Form: TCustomForm; HWindow: THandle; Mask: Integer; begin with Msg do if (Message >= WM_KEYFIRST) and (Message <= WM_KEYLAST) then begin Control := FindControl(HWnd); if Control = nil then begin HWindow := HWnd; repeat HWindow := GetParent(HWindow); if HWindow <> 0 then Control := FindControl(HWindow); until (HWindow = 0) or (Control <> nil); end; if Control <> nil then begin Result := S_OK; if (Message = WM_KEYDOWN) and (Control.Perform(CM_CHILDKEY, wParam, Integer(Control)) <> 0) then Exit; Mask := 0; case wParam of VK_TAB: Mask := DLGC_WANTTAB; VK_LEFT, VK_RIGHT, VK_UP, VK_DOWN, VK_PRIOR, VK_NEXT, VK_HOME, VK_END: Mask := DLGC_WANTARROWS; VK_RETURN, VK_EXECUTE, VK_ESCAPE, VK_CANCEL: Mask := DLGC_WANTALLKEYS; end; if (Mask <> 0) and ((Control.Perform(CM_WANTSPECIALKEY, wParam, 0) <> 0) or (Control.Perform(WM_GETDLGCODE, 0, 0) and Mask <> 0)) then begin TranslateMessage(msg); DispatchMessage(msg); Exit; end; if (Message = WM_KEYDOWN) and (Control.Parent <> nil) then Form := GetParentForm(Control) else Form := nil; if (Form <> nil) and (Form.Perform(CM_DIALOGKEY, wParam, lParam) = 1) then Exit; end; end; if FOleControlSite <> nil then Result := FOleControlSite.TranslateAccelerator(@msg, GetKeyModifiers) else Result := S_FALSE; end; function TActiveXControl.OnFrameWindowActivate(fActivate: BOOL): HResult; begin Result := InPlaceActivate(True); end; function TActiveXControl.OnDocWindowActivate(fActivate: BOOL): HResult; begin Result := InPlaceActivate(fActivate); end; function TActiveXControl.ResizeBorder(const rcBorder: TRect; const uiWindow: IOleInPlaceUIWindow; fFrameWindow: BOOL): HResult; begin Result := S_OK; end; function TActiveXControl.EnableModeless(fEnable: BOOL): HResult; begin Result := S_OK; end; { TActiveXControl.IViewObject } function TActiveXControl.Draw(dwDrawAspect: Longint; lindex: Longint; pvAspect: Pointer; ptd: PDVTargetDevice; hicTargetDev: HDC; hdcDraw: HDC; prcBounds: PRect; prcWBounds: PRect; fnContinue: TContinueFunc; dwContinue: Longint): HResult; var R: TRect; SaveIndex: Integer; WasVisible: Boolean; begin try if dwDrawAspect <> DVASPECT_CONTENT then OleError(DV_E_DVASPECT); WasVisible := FControl.Visible; try FControl.Visible := True; ShowWindow(FWinControl.Handle, 1); R := prcBounds^; LPToDP(hdcDraw, R, 2); SaveIndex := SaveDC(hdcDraw); try SetViewportOrgEx(hdcDraw, 0, 0, nil); SetWindowOrgEx(hdcDraw, 0, 0, nil); SetMapMode(hdcDraw, MM_TEXT); FControl.PaintTo(hdcDraw, R.Left, R.Top); finally RestoreDC(hdcDraw, SaveIndex); end; finally FControl.Visible := WasVisible; end; Result := S_OK; except Result := HandleException; end; end; function TActiveXControl.GetColorSet(dwDrawAspect: Longint; lindex: Longint; pvAspect: Pointer; ptd: PDVTargetDevice; hicTargetDev: HDC; out colorSet: PLogPalette): HResult; begin Result := E_NOTIMPL; end; function TActiveXControl.Freeze(dwDrawAspect: Longint; lindex: Longint; pvAspect: Pointer; out dwFreeze: Longint): HResult; begin Result := E_NOTIMPL; end; function TActiveXControl.Unfreeze(dwFreeze: Longint): HResult; begin Result := E_NOTIMPL; end; function TActiveXControl.SetAdvise(aspects: Longint; advf: Longint; const advSink: IAdviseSink): HResult; begin if aspects and DVASPECT_CONTENT = 0 then begin Result := DV_E_DVASPECT; Exit; end; FAdviseFlags := advf; FAdviseSink := advSink; if FAdviseFlags and ADVF_PRIMEFIRST <> 0 then ViewChanged; Result := S_OK; end; function TActiveXControl.GetAdvise(pAspects: PLongint; pAdvf: PLongint; out advSink: IAdviseSink): HResult; begin if pAspects <> nil then pAspects^ := DVASPECT_CONTENT; if pAdvf <> nil then pAdvf^ := FAdviseFlags; if @advSink <> nil then advSink := FAdviseSink; Result := S_OK; end; { TActiveXControl.IViewObject2 } function TActiveXControl.ViewObjectGetExtent(dwDrawAspect: Longint; lindex: Longint; ptd: PDVTargetDevice; out size: TPoint): HResult; begin Result := GetExtent(dwDrawAspect, size); end; { TActiveXControl.IPerPropertyBrowsing } function TActiveXControl.GetDisplayString(dispid: TDispID; out bstr: WideString): HResult; var S: string; begin Result := E_NOTIMPL; if GetPropertyString( dispid, S ) then begin bstr := S; Result := S_OK; end; end; function TActiveXControl.MapPropertyToPage(dispid: TDispID; out clsid: TCLSID): HResult; begin if @clsid <> nil then clsid := GUID_NULL; Result := E_NOTIMPL; {+ !!} end; function TActiveXControl.GetPredefinedStrings(dispid: TDispID; out caStringsOut: TCAPOleStr; out caCookiesOut: TCALongint): HResult; var StringList: POleStrList; CookieList: PLongintList; Strings: TStringList; Count, I: Integer; begin StringList := nil; CookieList := nil; Count := 0; if (@CaStringsOut = nil) or (@CaCookiesOut = nil) then begin Result := E_POINTER; Exit; end; caStringsOut.cElems := 0; caStringsOut.pElems := nil; caCookiesOut.cElems := 0; caCookiesOut.pElems := nil; try Strings := TStringList.Create; try if GetPropertyStrings(dispid, Strings) then begin Count := Strings.Count; StringList := CoAllocMem(Count * SizeOf(Pointer)); CookieList := CoAllocMem(Count * SizeOf(Longint)); for I := 0 to Count - 1 do begin StringList[I] := CoAllocString(Strings[I]); CookieList[I] := Longint(Strings.Objects[I]); end; caStringsOut.cElems := Count; caStringsOut.pElems := StringList; caCookiesOut.cElems := Count; caCookiesOut.pElems := CookieList; Result := S_OK; end else Result := E_NOTIMPL; finally Strings.Free; end; except if StringList <> nil then for I := 0 to Count - 1 do CoFreeMem(StringList[I]); CoFreeMem(CookieList); CoFreeMem(StringList); Result := HandleException; end; end; function TActiveXControl.GetPredefinedValue(dispid: TDispID; dwCookie: Longint; out varOut: OleVariant): HResult; var Temp: OleVariant; begin GetPropertyValue(dispid, dwCookie, Temp); varOut := Temp; Result := S_OK; end; { TActiveXControl.ISpecifyPropertyPages } type TPropPages = class private FGUIDList: PGUIDList; FCount: Integer; procedure ProcessPage(const GUID: TGUID); end; procedure TPropPages.ProcessPage(const GUID: TGUID); begin if FGUIDList <> nil then FGUIDList[FCount] := GUID; Inc(FCount); end; function TActiveXControl.GetPages(out pages: TCAGUID): HResult; var PropPages: TPropPages; begin try PropPages := TPropPages.Create; try DefinePropertyPages(PropPages.ProcessPage); PropPages.FGUIDList := CoAllocMem(PropPages.FCount * SizeOf(TGUID)); PropPages.FCount := 0; DefinePropertyPages(PropPages.ProcessPage); pages.cElems := PropPages.FCount; pages.pElems := PropPages.FGUIDList; PropPages.FGUIDList := nil; finally if PropPages.FGUIDList <> nil then CoFreeMem(PropPages.FGUIDList); PropPages.Free; end; Result := S_OK; except Result := HandleException; end; end; { ISimpleFrameSite } function TActiveXControl.PreMessageFilter(wnd: HWnd; msg, wp, lp: Integer; out res: Integer; out Cookie: Longint): HResult; begin if FSimpleFrameSite <> nil then Result := FSimpleFrameSite.PreMessageFilter(wnd, msg, wp, lp, res, Cookie) else Result := S_OK; end; function TActiveXControl.PostMessageFilter(wnd: HWnd; msg, wp, lp: Integer; out res: Integer; Cookie: Longint): HResult; begin if FSimpleFrameSite <> nil then Result := FSimpleFrameSite.PostMessageFilter(wnd, msg, wp, lp, res, Cookie) else Result := S_OK; end; { IQuickActivate } function TActiveXControl.QuickActivate(var qaCont: TQaContainer; var qaCtrl: TQaControl): HResult; stdcall; var Connections: IConnectionPointContainer; EventConnection: IConnectionPoint; PropConnection: IConnectionPoint; begin // Verify that caller allocated enough space if qaCtrl.cbSize < SizeOf(TQaControl) then begin Result := E_UNEXPECTED; Exit; end; // Initialize TQaControl structure FillChar(qaCtrl, SizeOf(TQaControl), 0); qaCtrl.cbSize := SizeOf(TQaControl); // Set ClientSite SetClientSite(qaCont.pClientSite); // Set Advise Sink if qaCont.pAdviseSink <> nil then SetAdvise(DVASPECT_CONTENT, 0, qaCont.pAdviseSink); // Grab ConnectionPointContainer Connections := Self as IConnectionPointContainer; // Hook up Property Notify Sink if qaCont.pPropertyNotifySink <> nil then begin if Connections.FindConnectionPoint(IPropertyNotifySink, EventConnection) = S_OK then EventConnection.Advise(qaCont.pPropertyNotifySink, qaCtrl.dwPropNotifyCookie); end; // Hook up default outgoing interface if qaCont.pUnkEventSink <> nil then begin if Connections.FindConnectionPoint(FControlFactory.EventIID, PropConnection) = S_OK then PropConnection.Advise(qaCont.pUnkEventSink, qaCtrl.dwEventCookie); end; // Give information to Container GetMiscStatus(DVASPECT_CONTENT, qaCtrl.dwMiscStatus); // Return SUCCESS Result := S_OK; end; function TActiveXControl.SetContentExtent(const sizel: TPoint): HResult; stdcall; begin Result := SetExtent(DVASPECT_CONTENT, sizel); end; function TActiveXControl.GetContentExtent(out sizel: TPoint): HResult; stdcall; begin Result := GetExtent(DVASPECT_CONTENT, sizel); end; { IDataObject } function TActiveXControl.GetData(const formatetcIn: TFormatEtc; out medium: TStgMedium): HResult; stdcall; var sizeMetric: TPoint; dc: HDC; hMF: HMetafile; hMem: THandle; pMFP: PMetafilePict; SaveVisible: Boolean; BM: TBitmap; begin // Handle only MetaFile if (formatetcin.tymed and TYMED_MFPICT) = 0 then begin Result := DV_E_FORMATETC; Exit; end; // Retrieve Extent GetExtent(DVASPECT_CONTENT, sizeMetric); // Create Metafile DC and set it up dc := CreateMetafile(nil); SetWindowOrgEx(dc, 0, 0, nil); SetWindowExtEx(dc, sizemetric.X, sizemetric.Y, nil); // Have Control paint to DC and get metafile handle SaveVisible := FControl.Visible; try FControl.Visible := True; BM := TBitmap.Create; try BM.Width := FControl.Width; BM.Height := FControl.Height; FControl.PaintTo(BM.Canvas.Handle, 0, 0); StretchBlt(dc, 0, 0, sizeMetric.X, sizeMetric.Y, BM.Canvas.Handle, 0, 0, BM.Width, BM.Height, SRCCOPY); finally BM.Free; end; finally FControl.Visible := SaveVisible; end; hMF := CloseMetaFile(dc); if hMF = 0 then begin Result := E_UNEXPECTED; Exit; end; // Get memory handle hMEM := GlobalAlloc(GMEM_SHARE or GMEM_MOVEABLE, sizeof(METAFILEPICT)); if hMEM = 0 then begin DeleteMetafile(hMF); Result := STG_E_MEDIUMFULL; Exit; end; pMFP := PMetaFilePict(GlobalLock(hMEM)); pMFP^.hMF := hMF; pMFP^.mm := MM_ANISOTROPIC; pMFP^.xExt := sizeMetric.X; pMFP^.yExt := sizeMetric.Y; GlobalUnlock(hMEM); medium.tymed := TYMED_MFPICT; medium.hGlobal := hMEM; medium.UnkForRelease := nil; Result := S_OK; end; function TActiveXControl.GetDataHere(const formatetc: TFormatEtc; out medium: TStgMedium): HResult; stdcall; begin Result := E_NOTIMPL; end; function TActiveXControl.QueryGetData(const formatetc: TFormatEtc): HResult; stdcall; begin Result := E_NOTIMPL; end; function TActiveXControl.GetCanonicalFormatEtc(const formatetc: TFormatEtc; out formatetcOut: TFormatEtc): HResult; stdcall; begin Result := E_NOTIMPL; end; function TActiveXControl.SetData(const formatetc: TFormatEtc; var medium: TStgMedium; fRelease: BOOL): HResult; stdcall; begin Result := E_NOTIMPL; end; function TActiveXControl.EnumFormatEtc(dwDirection: Longint; out enumFormatEtc: IEnumFormatEtc): HResult; stdcall; begin Result := E_NOTIMPL; end; function TActiveXControl.DAdvise(const formatetc: TFormatEtc; advf: Longint; const advSink: IAdviseSink; out dwConnection: Longint): HResult; stdcall; begin Result := S_OK; if FDataAdviseHolder = nil then Result := CreateDataAdviseHolder(FDataAdviseHolder); if Result = S_OK then Result := FDataAdviseHolder.Advise(Self, formatetc, advf, advSink, dwConnection); end; function TActiveXControl.DUnadvise(dwConnection: Longint): HResult; stdcall; begin if FDataAdviseHolder = nil then Result := OLE_E_NOCONNECTION else Result := FDataAdviseHolder.Unadvise(dwConnection); end; function TActiveXControl.EnumDAdvise(out enumAdvise: IEnumStatData): HResult; stdcall; begin if FDataAdviseHolder = nil then Result := E_FAIL else Result := FDataAdviseHolder.EnumAdvise(enumAdvise); end; { TActiveXControlFactory } constructor TActiveXControlFactory.Create(ComServer: TComServerObject; ActiveXControlClass: TActiveXControlClass; WinControlClass: TWinControlClass; const ClassID: TGUID; ToolboxBitmapID: Integer; const LicStr: string; MiscStatus: Integer; ThreadingModel: TThreadingModel); begin FWinControlClass := WinControlClass; inherited Create(ComServer, ActiveXControlClass, ClassID, ciMultiInstance, ThreadingModel); FMiscStatus := MiscStatus or OLEMISC_RECOMPOSEONRESIZE or OLEMISC_CANTLINKINSIDE or OLEMISC_INSIDEOUT or OLEMISC_ACTIVATEWHENVISIBLE or OLEMISC_SETCLIENTSITEFIRST; FToolboxBitmapID := ToolboxBitmapID; FVerbs := TStringList.Create; AddVerb(OLEIVERB_PRIMARY, SPropertiesVerb); LicString := LicStr; SupportsLicensing := LicStr <> ''; FLicFileStrings := TStringList.Create; end; destructor TActiveXControlFactory.Destroy; begin FVerbs.Free; FLicFileStrings.Free; inherited Destroy; end; procedure TActiveXControlFactory.AddVerb(Verb: Integer; const VerbName: string); begin FVerbs.AddObject(VerbName, TObject(Verb)); end; function TActiveXControlFactory.GetLicenseFileName: string; begin Result := ChangeFileExt(ComServer.ServerFileName, '.lic'); end; function TActiveXControlFactory.HasMachineLicense: Boolean; var i: Integer; begin Result := True; if not SupportsLicensing then Exit; if not FLicenseFileRead then begin try FLicFileStrings.LoadFromFile(GetLicenseFileName); FLicenseFileRead := True; except Result := False; end; end; if Result then begin i := 0; Result := False; while (i < FLicFileStrings.Count) and (not Result) do begin Result := ValidateUserLicense(FLicFileStrings[i]); inc(i); end; end; end; procedure TActiveXControlFactory.UpdateRegistry(Register: Boolean); var ClassKey: string; I: Integer; begin ClassKey := 'CLSID\' + GUIDToString(ClassID); if Register then begin inherited UpdateRegistry(Register); CreateRegKey(ClassKey + '\MiscStatus', '', '0'); CreateRegKey(ClassKey + '\MiscStatus\1', '', IntToStr(FMiscStatus)); CreateRegKey(ClassKey + '\ToolboxBitmap32', '', ComServer.ServerFileName + ',' + IntToStr(FToolboxBitmapID)); CreateRegKey(ClassKey + '\Control', '', ''); CreateRegKey(ClassKey + '\Verb', '', ''); for I := 0 to FVerbs.Count - 1 do CreateRegKey(ClassKey + '\Verb\' + IntToStr(Integer(FVerbs.Objects[I])), '', FVerbs[I] + ',0,2'); end else begin for I := 0 to FVerbs.Count - 1 do DeleteRegKey(ClassKey + '\Verb\' + IntToStr(Integer(FVerbs.Objects[I]))); DeleteRegKey(ClassKey + '\Verb'); DeleteRegKey(ClassKey + '\Control'); DeleteRegKey(ClassKey + '\ToolboxBitmap32'); DeleteRegKey(ClassKey + '\MiscStatus\1'); DeleteRegKey(ClassKey + '\MiscStatus'); inherited UpdateRegistry(Register); end; end; { TActiveFormControl } procedure TActiveFormControl.DefinePropertyPages(DefinePropertyPage: TDefinePropertyPage); begin if FControl is TActiveForm then TActiveForm(FControl).DefinePropertyPages(DefinePropertyPage); end; procedure TActiveFormControl.FreeOnRelease; begin end; procedure TActiveFormControl.InitializeControl; begin inherited InitializeControl; FControl.VCLComObject := Pointer(Self as IVCLComObject); if FControl is TActiveForm then begin TActiveForm(FControl).FActiveFormControl := Self; TActiveForm(FControl).Initialize; end; end; function TActiveFormControl.Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer; Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult; const INVOKE_PROPERTYSET = INVOKE_PROPERTYPUT or INVOKE_PROPERTYPUTREF; begin if Flags and INVOKE_PROPERTYSET <> 0 then Flags := INVOKE_PROPERTYSET; Result := TAutoObjectFactory(Factory).DispTypeInfo.Invoke(Pointer( Integer(Control) + TAutoObjectFactory(Factory).DispIntfEntry.IOffset), DispID, Flags, TDispParams(Params), VarResult, ExcepInfo, ArgErr); end; function TActiveFormControl.ObjQueryInterface(const IID: TGUID; out Obj): HResult; begin Result := S_OK; if IsEqualGUID(IID, IUnknown) or not Control.GetInterface(IID, Obj) then Result := inherited ObjQueryInterface(IID, Obj); end; procedure TActiveFormControl.EventSinkChanged(const EventSink: IUnknown); begin if (Control is TActiveForm) then TActiveForm(Control).EventSinkChanged(EventSink); end; { TActiveForm } procedure TActiveForm.DefinePropertyPages(DefinePropertyPage: TDefinePropertyPage); begin end; procedure TActiveForm.DoDestroy; begin if Assigned(OnDestroy) then try OnDestroy(Self); OnDestroy := nil; except Application.HandleException(Self); end; end; procedure TActiveForm.EventSinkChanged(const EventSink: IUnknown); begin if (FSinkChangeCount = 0) and (EventSink <> nil) then DoCreate; InterLockedIncrement(FSinkChangeCount); end; procedure TActiveForm.Initialize; begin end; { TActiveFormFactory } function TActiveFormFactory.GetIntfEntry(Guid: TGUID): PInterfaceEntry; begin Result := WinControlClass.GetInterfaceEntry(Guid); end; { TPropertyPage } constructor TPropertyPage.Create(AOwner: TComponent); begin inherited Create(AOwner); FOleObjects := TInterfaceList.Create; end; destructor TPropertyPage.Destroy; begin FOleObjects.Free; inherited Destroy; end; procedure TPropertyPage.CMChanged(var Msg: TCMChanged); begin Modified; end; procedure TPropertyPage.Modified; begin if Assigned(FActiveXPropertyPage) then FActiveXPropertyPage.Modified; end; procedure TPropertyPage.UpdateObject; begin end; procedure TPropertyPage.EnumCtlProps(PropType: TGUID; PropNames: TStrings); begin EnumDispatchProperties(IUnknown(FOleObject) as IDispatch, PropType, VT_EMPTY, PropNames); end; procedure TPropertyPage.UpdatePropertyPage; begin end; { TActiveXPropertyPage } destructor TActiveXPropertyPage.Destroy; begin FPropertyPageImpl.FPropertyPage.Free; FPropertyPageImpl.Free; end; procedure TActiveXPropertyPage.Initialize; begin FPropertyPageImpl := TPropertyPageImpl.Create(Self); FPropertyPageImpl.FPropertyPage := TPropertyPageClass(Factory.ComClass).Create(nil); FPropertyPageImpl.InitPropertyPage; end; { TPropertyPageImpl } procedure TPropertyPageImpl.InitPropertyPage; begin FPropertyPage.FActiveXPropertyPage := Self; FPropertyPage.BorderStyle := bsNone; FPropertyPage.Position := poDesigned; end; procedure TPropertyPageImpl.Modified; begin if FActive then begin FModified := True; if FPageSite <> nil then FPageSite.OnStatusChange(PROPPAGESTATUS_DIRTY or PROPPAGESTATUS_VALIDATE); end; end; { TPropertyPageImpl.IPropertyPage } function TPropertyPageImpl.SetPageSite(const pageSite: IPropertyPageSite): HResult; begin FPageSite := pageSite; Result := S_OK; end; function TPropertyPageImpl.Activate(hwndParent: HWnd; const rc: TRect; bModal: BOOL): HResult; begin try FPropertyPage.BoundsRect := rc; FPropertyPage.ParentWindow := hwndParent; FActive:= True; FModified := False; Result := S_OK; except Result := HandleException; end; end; function TPropertyPageImpl.Deactivate: HResult; begin try FActive := False; FPropertyPage.Hide; FPropertyPage.ParentWindow := 0; FPropertyPage.FOleObject := null; FPropertyPage.FOleObjects.Clear; Result := S_OK; except Result := HandleException; end; end; function TPropertyPageImpl.GetPageInfo(out pageInfo: TPropPageInfo): HResult; begin try FillChar(pageInfo.pszTitle, SizeOf(pageInfo) - 4, 0); pageInfo.pszTitle := CoAllocString(FPropertyPage.Caption); pageInfo.size.cx := FPropertyPage.Width; pageInfo.size.cy := FPropertyPage.Height; Result := S_OK; except Result := HandleException; end; end; function TPropertyPageImpl.SetObjects(cObjects: Longint; pUnkList: PUnknownList): HResult; var i: Integer; begin try FPropertyPage.FOleObject := Null; FPropertyPage.FOleObjects.Clear; if pUnkList = nil then begin Result := E_POINTER; Exit; end; if cObjects > 0 then begin for i := 0 to cObjects - 1 do FPropertyPage.FOleObjects.Add(pUnkList[i]); FPropertyPage.FOleObject := pUnkList[0] as IDispatch; end; Result := S_OK; except Result := HandleException; end; if not VarIsNull(FPropertyPage.FOleObject) then FPropertyPage.UpdatePropertyPage; end; function TPropertyPageImpl.Show(nCmdShow: Integer): HResult; begin try FPropertyPage.Visible := nCmdShow <> SW_HIDE; Result := S_OK; except Result := HandleException; end; end; function TPropertyPageImpl.Move(const rect: TRect): HResult; begin try FPropertyPage.BoundsRect := rect; Result := S_OK; except Result := HandleException; end; end; function TPropertyPageImpl.IsPageDirty: HResult; begin if FModified then Result := S_OK else Result := S_FALSE; end; function TPropertyPageImpl.Apply: HResult; procedure NotifyContainerOfApply; var OleObject: IUnknown; Connections: IConnectionPointContainer; Connection: IConnectionPoint; Enum: IEnumConnections; ConnectData: TConnectData; Fetched: Longint; begin { VB seems to wait for an OnChange call along a IPropetyNotifySink before it will update its property inspector. } OleObject := IUnknown(FPropertyPage.FOleObject); if OleObject.QueryInterface(IConnectionPointContainer, Connections) = S_OK then if Connections.FindConnectionPoint(IPropertyNotifySink, Connection) = S_OK then begin OleCheck(Connection.EnumConnections(Enum)); while Enum.Next(1, ConnectData, @Fetched) = S_OK do begin (ConnectData.pUnk as IPropertyNotifySink).OnChanged(DISPID_UNKNOWN); ConnectData.pUnk := nil; end; end; end; begin try FPropertyPage.UpdateObject; FModified := False; NotifyContainerOfApply; Result := S_OK; except Result := HandleException; end; end; function TPropertyPageImpl.Help(pszHelpDir: POleStr): HResult; begin Result := E_NOTIMPL; end; function TPropertyPageImpl.TranslateAccelerator(msg: PMsg): HResult; begin try { For some reason VB bashes WS_EX_CONTROLPARENT, set it back } if FPropertyPage.WindowHandle <> 0 then SetWindowLong(FPropertyPage.Handle, GWL_EXSTYLE, GetWindowLong(FPropertyPage.Handle, GWL_EXSTYLE) or WS_EX_CONTROLPARENT); {+ !!} Result := S_FALSE; except Result := HandleException; end; end; { TPropertyPageImpl.IPropertyPage2 } function TPropertyPageImpl.EditProperty(dispid: TDispID): HResult; begin Result := E_NOTIMPL; {+ !!} end; { TActiveXPropertyPageFactory } constructor TActiveXPropertyPageFactory.Create(ComServer: TComServerObject; PropertyPageClass: TPropertyPageClass; const ClassID: TGUID); begin inherited Create(ComServer, TComClass(PropertyPageClass), ClassID, '', Format('%s property page', [PropertyPageClass.ClassName]), ciMultiInstance); end; function TActiveXPropertyPageFactory.CreateComObject( const Controller: IUnknown): TComObject; begin Result := TActiveXPropertyPage.CreateFromFactory(Self, Controller); end; { TCustomAdapter } constructor TCustomAdapter.Create; begin inherited Create; FNotifier := TAdapterNotifier.Create(Self); end; destructor TCustomAdapter.Destroy; begin ReleaseOleObject; inherited Destroy; end; procedure TCustomAdapter.Changed; begin if not Updating then ReleaseOleObject; end; procedure TCustomAdapter.ConnectOleObject(OleObject: IUnknown); begin if FOleObject <> nil then ReleaseOleObject; if OleObject <> nil then InterfaceConnect(OleObject, IPropertyNotifySink, FNotifier, FConnection); FOleObject := OleObject; end; procedure TCustomAdapter.ReleaseOleObject; begin InterfaceDisconnect(FOleObject, IPropertyNotifySink, FConnection); FOleObject := nil; end; { TAdapterNotifier } constructor TAdapterNotifier.Create(Adapter: TCustomAdapter); begin inherited Create; FAdapter := Adapter; end; { TAdapterNotifier.IPropertyNotifySink } function TAdapterNotifier.OnChanged(dispid: TDispID): HResult; begin try FAdapter.Update; Result := S_OK; except Result := HandleException; end; end; function TAdapterNotifier.OnRequestEdit(dispid: TDispID): HResult; begin Result := S_OK; end; { TFontAdapter } constructor TFontAdapter.Create(Font: TFont); begin inherited Create; FFont := Font; end; procedure TFontAdapter.Update; var TempFont: TFont; Name: WideString; Size: Currency; Temp: Longbool; Charset: Smallint; Style: TFontStyles; FOleFont: IFont; begin if Updating then Exit; FOleFont := FOleObject as IFont; if FOleFont = nil then Exit; FOleFont.get_Name(Name); FOleFont.get_Size(Size); Style := []; FOleFont.get_Bold(Temp); if Temp then Include(Style, fsBold); FOleFont.get_Italic(Temp); if Temp then Include(Style, fsItalic); FOleFont.get_Underline(Temp); if Temp then Include(Style, fsUnderline); FOleFont.get_Strikethrough(Temp); if Temp then Include(Style, fsStrikeout); FOleFont.get_Charset(Charset); TempFont := TFont.Create; Updating := True; try TempFont.Assign(FFont); TempFont.Name := Name; TempFont.Size := Integer(Round(Size)); TempFont.Style := Style; TempFont.Charset := Charset; FFont.Assign(TempFont); finally Updating := False; TempFont.Free; end; end; procedure TFontAdapter.Changed; begin // TFont has changed. Need to update IFont if Updating then Exit; if FOleObject = nil then Exit; Updating := True; try with FOleObject as IFont do begin Put_Name(FFont.Name); Put_Size(FFont.Size); Put_Bold(fsBold in FFont.Style); Put_Italic(fsItalic in FFont.Style); Put_Underline(fsUnderline in FFont.Style); Put_Strikethrough(fsStrikeout in FFont.Style); Put_Charset(FFont.Charset); end; finally Updating := False; end; end; { TFontAdapter.IFontAccess } procedure TFontAdapter.GetOleFont(var OleFont: IFontDisp); var FontDesc: TFontDesc; FontName: WideString; Temp: IFont; begin if FOleObject = nil then begin FontName := FFont.Name; with FontDesc do begin cbSizeOfStruct := SizeOf(FontDesc); lpstrName := PWideChar(FontName); cySize := FFont.Size; if fsBold in FFont.Style then sWeight := 700 else sWeight := 400; sCharset := FFont.Charset; fItalic := fsItalic in FFont.Style; fUnderline := fsUnderline in FFont.Style; fStrikethrough := fsStrikeout in FFont.Style; end; OleCheck(OleCreateFontIndirect(FontDesc, IFont, Temp)); ConnectOleObject(Temp); end; OleFont := FOleObject as IFontDisp; end; procedure TFontAdapter.SetOleFont(const OleFont: IFontDisp); begin ConnectOleObject(OleFont as IFont); Update; end; { TPictureAdapter } constructor TPictureAdapter.Create(Picture: TPicture); begin inherited Create; FPicture := Picture; end; procedure TPictureAdapter.Update; var Temp: TOleGraphic; begin Updating := True; Temp := TOleGraphic.Create; try Temp.Picture := FOleObject as IPicture; FPicture.Graphic := Temp; finally Updating := False; Temp.Free; end; end; { TPictureAdapter.IPictureAccess } procedure TPictureAdapter.GetOlePicture(var OlePicture: IPictureDisp); var PictureDesc: TPictDesc; OwnHandle: Boolean; TempM: TMetafile; TempB: TBitmap; begin if FOleObject = nil then begin OwnHandle := False; with PictureDesc do begin cbSizeOfStruct := SizeOf(PictureDesc); if FPicture.Graphic is TBitmap then begin picType := PICTYPE_BITMAP; TempB := TBitmap.Create; try TempB.Assign(FPicture.Graphic); hbitmap := TempB.ReleaseHandle; hpal := TempB.ReleasePalette; OwnHandle := True; finally TempB.Free; end; end else if FPicture.Graphic is TIcon then begin picType := PICTYPE_ICON; hicon := FPicture.Icon.Handle; end else begin picType := PICTYPE_ENHMETAFILE; if not (FPicture.Graphic is TMetafile) then begin TempM := TMetafile.Create; try TempM.Width := FPicture.Width; TempM.Height := FPicture.Height; with TMetafileCanvas.Create(TempM,0) do try Draw(0,0,FPicture.Graphic); finally Free; end; hemf := TempM.ReleaseHandle; OwnHandle := True; // IPicture destroys temp metafile when released finally TempM.Free; end; end else hemf := FPicture.Metafile.Handle; end; end; OleCheck(OleCreatePictureIndirect(PictureDesc, IPicture, OwnHandle, OlePicture)); ConnectOleObject(OlePicture); end; OlePicture := FOleObject as IPictureDisp; end; procedure TPictureAdapter.SetOlePicture(const OlePicture: IPictureDisp); begin ConnectOleObject(OlePicture); Update; end; { TOleGraphic } procedure TOleGraphic.Assign(Source: TPersistent); begin if Source is TOleGraphic then FPicture := TOleGraphic(Source).Picture else inherited Assign(Source); end; procedure TOleGraphic.Changed(Sender: TObject); begin //!! end; procedure TOleGraphic.Draw(ACanvas: TCanvas; const Rect: TRect); var DC: HDC; Pal: HPalette; RestorePalette: Boolean; PicType: SmallInt; hemf: HENHMETAFILE; begin if FPicture = nil then Exit; ACanvas.Lock; // OLE calls might cycle the message loop try DC := ACanvas.Handle; Pal := Palette; RestorePalette := False; if Pal <> 0 then begin Pal := SelectPalette(DC, Pal, True); RealizePalette(DC); RestorePalette := True; end; FPicture.get_Type(PicType); if PicType = PICTYPE_ENHMETAFILE then begin FPicture.get_Handle(hemf); PlayEnhMetafile(DC, hemf, Rect); end else OleCheck(FPicture.Render(DC, Rect.Left, Rect.Top, Rect.Right - Rect.Left, Rect.Bottom - Rect.Top, 0, MMHeight - 1, MMWidth, -MMHeight, Rect)); if RestorePalette then SelectPalette(DC, Pal, True); finally ACanvas.Unlock; end; end; function TOleGraphic.GetEmpty: Boolean; var PicType: Smallint; begin Result := (FPicture = nil) or (FPicture.get_Type(PicType) <> 0) or (PicType <= 0); end; function HIMETRICtoDP(P: TPoint): TPoint; var DC: HDC; begin DC := GetDC(0); SetMapMode(DC, MM_HIMETRIC); Result := P; Result.Y := -Result.Y; LPTODP(DC, Result, 1); ReleaseDC(0,DC); end; function TOleGraphic.GetHeight: Integer; begin Result := HIMETRICtoDP(Point(0, MMHeight)).Y; end; function TOleGraphic.GetMMHeight: Integer; begin Result := 0; if FPicture <> nil then FPicture.get_Height(Result); end; function TOleGraphic.GetMMWidth: Integer; begin Result := 0; if FPicture <> nil then FPicture.get_Width(Result); end; function TOleGraphic.GetPalette: HPALETTE; var Handle: OLE_HANDLE; begin Result := 0; if FPicture <> nil then begin FPicture.Get_HPal(Handle); Result := HPALETTE(Handle); end; end; function TOleGraphic.GetTransparent: Boolean; var Attr: Integer; begin Result := False; if FPicture <> nil then begin FPicture.Get_Attributes(Attr); Result := (Attr and PICTURE_TRANSPARENT) <> 0; end; end; function TOleGraphic.GetWidth: Integer; begin Result := HIMETRICtoDP(Point(MMWidth,0)).X; end; procedure InvalidOperation(const Str: string); begin raise EInvalidGraphicOperation.Create(Str); end; procedure TOleGraphic.SetHeight(Value: Integer); begin InvalidOperation(sOleGraphic); end; procedure TOleGraphic.SetPalette(Value: HPALETTE); begin if FPicture <> nil then OleCheck(FPicture.Set_hpal(Value)); end; procedure TOleGraphic.SetWidth(Value: Integer); begin InvalidOperation(sOleGraphic); end; procedure TOleGraphic.LoadFromFile(const Filename: string); begin //!! end; procedure TOleGraphic.LoadFromStream(Stream: TStream); begin OleCheck(OleLoadPicture(TStreamAdapter.Create(Stream), 0, True, IPicture, FPicture)); end; procedure TOleGraphic.SaveToStream(Stream: TStream); begin OleCheck((FPicture as IPersistStream).Save(TStreamAdapter.Create(Stream), True)); end; procedure TOleGraphic.LoadFromClipboardFormat(AFormat: Word; AData: THandle; APalette: HPALETTE); begin InvalidOperation(sOleGraphic); end; procedure TOleGraphic.SaveToClipboardFormat(var AFormat: Word; var AData: THandle; var APalette: HPALETTE); begin InvalidOperation(sOleGraphic); end; type TStringsEnumerator = class(TContainedObject, IEnumString) private FIndex: Integer; // index of next unread string FStrings: IStrings; public constructor Create(const Strings: IStrings); function Next(celt: Longint; out elt; pceltFetched: PLongint): HResult; stdcall; function Skip(celt: Longint): HResult; stdcall; function Reset: HResult; stdcall; function Clone(out enm: IEnumString): HResult; stdcall; end; constructor TStringsEnumerator.Create(const Strings: IStrings); begin inherited Create(Strings); FStrings := Strings; end; function TStringsEnumerator.Next(celt: Longint; out elt; pceltFetched: PLongint): HResult; var I: Integer; begin I := 0; while (I < celt) and (FIndex < FStrings.Count) do begin TPointerList(elt)[I] := PWideChar(WideString(FStrings.Item[I])); Inc(I); Inc(FIndex); end; if pceltFetched <> nil then pceltFetched^ := I; if I = celt then Result := S_OK else Result := S_FALSE; end; function TStringsEnumerator.Skip(celt: Longint): HResult; begin if (FIndex + celt) <= FStrings.Count then begin Inc(FIndex, celt); Result := S_OK; end else begin FIndex := FStrings.Count; Result := S_FALSE; end; end; function TStringsEnumerator.Reset: HResult; begin FIndex := 0; Result := S_OK; end; function TStringsEnumerator.Clone(out enm: IEnumString): HResult; begin try enm := TStringsEnumerator.Create(FStrings); Result := S_OK; except Result := E_UNEXPECTED; end; end; { TStringsAdapter } constructor TStringsAdapter.Create(Strings: TStrings); var StdVcl: ITypeLib; begin OleCheck(LoadRegTypeLib(LIBID_STDVCL, 4, 0, 0, StdVcl)); inherited Create(StdVcl, IStrings); FStrings := Strings; end; procedure TStringsAdapter.ReferenceStrings(S: TStrings); begin FStrings := S; end; procedure TStringsAdapter.ReleaseStrings; begin FStrings := nil; end; function TStringsAdapter.Get_ControlDefault(Index: Integer): OleVariant; begin Result := Get_Item(Index); end; procedure TStringsAdapter.Set_ControlDefault(Index: Integer; Value: OleVariant); begin Set_Item(Index, Value); end; function TStringsAdapter.Count: Integer; begin Result := 0; if FStrings <> nil then Result := FStrings.Count; end; function TStringsAdapter.Get_Item(Index: Integer): OleVariant; begin Result := NULL; if (FStrings <> nil) then Result := WideString(FStrings[Index]); end; procedure TStringsAdapter.Set_Item(Index: Integer; Value: OleVariant); begin if (FStrings <> nil) then FStrings[Index] := Value; end; procedure TStringsAdapter.Remove(Index: Integer); begin if FStrings <> nil then FStrings.Delete(Index); end; procedure TStringsAdapter.Clear; begin if FStrings <> nil then FStrings.Clear; end; function TStringsAdapter.Add(Item: OleVariant): Integer; begin Result := -1; if FStrings <> nil then Result := FStrings.Add(Item); end; function TStringsAdapter._NewEnum: IUnknown; begin Result := TStringsEnumerator.Create(Self); end; procedure GetOleStrings(Strings: TStrings; var OleStrings: IStrings); begin OleStrings := nil; if Strings = nil then Exit; if Strings.StringsAdapter = nil then Strings.StringsAdapter := TStringsAdapter.Create(Strings); OleStrings := Strings.StringsAdapter as IStrings; end; procedure SetOleStrings(Strings: TStrings; OleStrings: IStrings); var I: Integer; begin if Strings = nil then Exit; Strings.BeginUpdate; try Strings.Clear; for I := 0 to OleStrings.Count-1 do Strings.Add(OleStrings.Item[I]); finally Strings.EndUpdate; end; end; { Dynamically load functions used in OLEPRO32.DLL } var OlePro32DLL: THandle; _OleCreatePropertyFrame: function(hwndOwner: HWnd; x, y: Integer; lpszCaption: POleStr; cObjects: Integer; pObjects: Pointer; cPages: Integer; pPageCLSIDs: Pointer; lcid: TLCID; dwReserved: Longint; pvReserved: Pointer): HResult stdcall; _OleCreateFontIndirect: function(const FontDesc: TFontDesc; const iid: TIID; out vObject): HResult stdcall; _OleCreatePictureIndirect: function(const PictDesc: TPictDesc; const iid: TIID; fOwn: BOOL; out vObject): HResult stdcall; _OleLoadPicture: function(stream: IStream; lSize: Longint; fRunmode: BOOL; const iid: TIID; out vObject): HResult; stdcall; procedure InitOlePro32; begin if OlePro32Dll <> 0 then Exit; {$IFDEF MSWINDOWS} OlePro32Dll := SafeLoadLibrary('olepro32.dll'); {$ENDIF} if OlePro32DLL <> 0 then begin @_OleCreatePropertyFrame := GetProcAddress(OlePro32DLL, 'OleCreatePropertyFrame'); @_OleCreateFontIndirect := GetProcAddress(OlePro32DLL, 'OleCreateFontIndirect'); @_OleCreatePictureIndirect := GetProcAddress(OlePro32DLL, 'OleCreatePictureIndirect'); @_OleLoadPicture := GetProcAddress(OlePro32DLL, 'OleLoadPicture'); end; end; function OleCreatePropertyFrame(hwndOwner: HWnd; x, y: Integer; lpszCaption: POleStr; cObjects: Integer; pObjects: Pointer; cPages: Integer; pPageCLSIDs: Pointer; lcid: TLCID; dwReserved: Longint; pvReserved: Pointer): HResult; begin if Assigned(_OleCreatePropertyFrame) then Result := _OleCreatePropertyFrame(hwndOwner, x, y, lpszCaption, cObjects, pObjects, cPages, pPageCLSIDs, lcid, dwReserved, pvReserved) else Result := E_UNEXPECTED; end; function OleCreateFontIndirect(const FontDesc: TFontDesc; const iid: TIID; out vObject): HResult; begin if Assigned(_OleCreateFontIndirect) then Result := _OleCreateFontIndirect(FontDesc, iid, vObject) else Result := E_UNEXPECTED; end; function OleCreatePictureIndirect(const PictDesc: TPictDesc; const iid: TIID; fOwn: BOOL; out vObject): HResult; begin if Assigned(_OleCreatePictureIndirect) then Result := _OleCreatePictureIndirect(PictDesc, iid, fOwn, vObject) else Result := E_UNEXPECTED; end; function OleLoadPicture(stream: IStream; lSize: Longint; fRunmode: BOOL; const iid: TIID; out vObject): HResult; begin if Assigned(_OleLoadPicture) then Result := _OleLoadPicture(stream, lSize, fRunmode, iid, vObject) else Result := E_UNEXPECTED; end; initialization TPicture.RegisterFileFormat('', '', TOleGraphic); InitOlePro32; finalization if xParkingWindow <> 0 then begin SendMessage(xParkingWindow, WM_CLOSE, 0, 0); Windows.UnregisterClass('DAXParkingWindow', HInstance); end; if OlePro32DLL <> 0 then FreeLibrary(OlePro32DLL); end.