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