5
{ Visual ActiveX container.
7
Copyright (C) 2011 Ludo Brands
9
This library is free software; you can redistribute it and/or modify it
10
under the terms of the GNU Library General Public License as published by
11
the Free Software Foundation; either version 2 of the License, or (at your
12
option) any later version with the following modification:
14
As a special exception, the copyright holders of this library give you
15
permission to link this library with independent modules to produce an
16
executable, regardless of the license terms of these independent modules,and
17
to copy and distribute the resulting executable under terms of your choice,
18
provided that you also meet, for each linked independent module, the terms
19
and conditions of the license of that module. An independent module is a
20
module which is not derived from or based on this library. If you modify
21
this library, you may extend this exception to your version of the library,
22
but you are not obligated to do so. If you do not wish to do so, delete this
23
exception statement from your version.
25
This program is distributed in the hope that it will be useful, but WITHOUT
26
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
27
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
30
You should have received a copy of the GNU Library General Public License
31
along with this library; if not, write to the Free Software Foundation,
32
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
38
Classes, SysUtils, Controls, Windows, ActiveX, ComObj, Forms, Graphics;
51
IOleControlSite = interface
52
['{B196B289-BAB4-101A-B69C-00AA00341D07}']
53
function OnControlInfoChanged: HResult; stdcall;
54
function LockInPlaceActive(fLock: BOOL): HResult; stdcall;
55
function GetExtendedControl(out disp: IDispatch): HResult; stdcall;
56
function TransformCoords(var ptlHimetric: TPoint; var ptfContainer: TPointF;
57
flags: Longint): HResult; stdcall;
58
function TranslateAccelerator(msg: PMsg; grfModifiers: Longint): HResult;
60
function OnFocus(fGotFocus: BOOL): HResult; stdcall;
61
function ShowPropertyFrame: HResult; stdcall;
64
IPropertyNotifySink = interface
65
['{9BFBBC02-EFF1-101A-84ED-00AA00341D07}']
66
function OnChanged(dispid: TDispID): HResult; stdcall;
67
function OnRequestEdit(dispid: TDispID): HResult; stdcall;
70
ISimpleFrameSite = interface
71
['{742B0E01-14E6-101B-914E-00AA00300CAB}']
72
function PreMessageFilter(wnd: HWnd; msg, wp, lp: Integer;
73
out res: Integer; out Cookie: Longint): HResult;
75
function PostMessageFilter(wnd: HWnd; msg, wp, lp: Integer;
76
out res: Integer; Cookie: Longint): HResult;
81
TStatusTextEvent = procedure(Sender: TObject; Status:string) of object;
85
TActiveXContainer = class(TWinControl, IUnknown, IOleClientSite,
86
IOleControlSite, IOleInPlaceSite, IOleInPlaceFrame, IDispatch)
91
FOleObject: IDispatch;
92
FOnStatusText: TStatusTextEvent;
93
FPrevWndProc:windows.WNDPROC;
94
Function GetvObject:variant;
96
Function SaveObject: HResult;StdCall;
97
Function GetMoniker(dwAssign: Longint; dwWhichMoniker: Longint;OUT mk: IMoniker):HResult;StdCall;
98
Function GetContainer(OUT container: IOleContainer):HResult;StdCall;
99
procedure SetActive(AValue: boolean);
100
procedure SetClassName(AValue: string);
101
procedure SetOleObject(AValue: IDispatch);
102
Function ShowObject:HResult;StdCall;
103
Function OnShowWindow(fShow: BOOL):HResult;StdCall;
104
Function RequestNewObjectLayout:HResult;StdCall;
106
function OnControlInfoChanged: HResult; stdcall;
107
function LockInPlaceActive(fLock: BOOL): HResult; stdcall;
108
function GetExtendedControl(out disp: IDispatch): HResult; stdcall;
109
function TransformCoords(var ptlHimetric: TPoint; var ptfContainer: TPointF;
110
flags: Longint): HResult; stdcall;
111
function TranslateAccelerator(msg: PMsg; grfModifiers: Longint): HResult;overload;
113
function OnFocus(fGotFocus: BOOL): HResult; stdcall;
114
function ShowPropertyFrame: HResult; stdcall;
116
function CanInPlaceActivate : HResult;stdcall;
117
function OnInPlaceActivate : HResult;stdcall;
118
function OnUIActivate : HResult;stdcall;
119
function GetWindowContext(out ppframe:IOleInPlaceFrame;out ppdoc:IOleInPlaceUIWindow;lprcposrect:LPRECT;lprccliprect:LPRECT;lpframeinfo:LPOLEINPLACEFRAMEINFO):hresult; stdcall;
120
function Scroll(scrollExtant:TSIZE):hresult; stdcall;
121
function OnUIDeactivate(fUndoable:BOOL):hresult; stdcall;
122
function OnInPlaceDeactivate :hresult; stdcall;
123
function DiscardUndoState :hresult; stdcall;
124
function DeactivateAndUndo :hresult; stdcall;
125
function OnPosRectChange(lprcPosRect:LPRect):hresult; stdcall;
127
function GetWindow(out wnd: HWnd): HResult; stdcall;
128
function ContextSensitiveHelp(fEnterMode: BOOL): HResult; stdcall;
130
function InsertMenus(hmenuShared: HMenu; var menuWidths: TOleMenuGroupWidths): HResult;StdCall;
131
function SetMenu(hmenuShared: HMenu; holemenu: HMenu; hwndActiveObject: HWnd): HResult;StdCall;
132
function RemoveMenus(hmenuShared: HMenu): HResult;StdCall;
133
function SetStatusText(pszStatusText: POleStr): HResult;StdCall;
134
function EnableModeless(fEnable: BOOL): HResult;StdCall;
135
function TranslateAccelerator(var msg: TMsg; wID: Word): HResult;StdCall;overload;
136
//IOleInPlaceUIWindow
137
function GetBorder(out rectBorder: TRect):HResult;StdCall;
138
function RequestBorderSpace(const borderwidths: TRect):HResult;StdCall;
139
function SetBorderSpace(const borderwidths: TRect):HResult;StdCall;
140
function SetActiveObject(const activeObject: IOleInPlaceActiveObject;pszObjName: POleStr):HResult;StdCall;
142
function GetTypeInfoCount(out count : longint) : HResult;stdcall;
143
function GetTypeInfo(Index,LocaleID : longint;
144
out TypeInfo): HResult;stdcall;
145
function GetIDsOfNames(const iid: TGUID; names: Pointer;
146
NameCount, LocaleID: LongInt; DispIDs: Pointer) : HResult;stdcall;
147
function Invoke(DispID: LongInt;const iid : TGUID;
148
LocaleID : longint; Flags: Word;var params;
149
VarResult,ExcepInfo,ArgErr : pointer) : HResult;stdcall;
154
constructor Create(TheOwner: TComponent); override;
155
destructor Destroy; override;
156
//VT_DISPATCH variant used for late binding
157
property vObject:Variant read GetvObject;
162
property BorderSpacing;
163
property ChildSizing;
164
//ActiveX object is automatically created from classname and destroyed when set
165
property OleClassName:string read FClassName write SetClassName;
166
property ClientHeight;
167
property ClientWidth;
168
property Constraints;
174
{IDispatch interface for ActiveX object. Overrides classname. Set ComServer
175
when you create and destroy the object yourself, fe. using CoClass.
176
When Active, returns the IDispatch for the object.
178
property ComServer:IDispatch read FOleObject write SetOleObject;
179
property ParentShowHint;
184
property UseDockManager default True;
194
property OnGetSiteInfo;
195
property OnGetDockCaption;
197
property OnStartDock;
198
property OnStartDrag;
199
property OnStatusText:TStatusTextEvent read FOnStatusText write FOnStatusText;
201
{When set, binds ActiveX component to control.
202
When cleared, detaches the component from the control
203
If Classname is provided the ActiveX component will also be created and destroyed
205
property Active:boolean read FActive write SetActive;
212
GWLP_USERDATA=GWL_USERDATA;
214
function GetWindowLongPtrW(hWnd:HWND; nIndex:longint):LONG;
216
result:=GetWindowLongW(hWnd, nIndex);
219
function SetWindowLongPtrW(hWnd:HWND; nIndex:longint; dwNewLong:LONG):LONG;
221
result:=SetWindowLongW(hWnd, nIndex, dwNewLong);
224
function SetWindowLongPtr(hWnd:HWND; nIndex:longint; dwNewLong:LONG):LONG;
226
result:=SetWindowLongW(hWnd, nIndex, dwNewLong);
230
function WndCallback(Ahwnd: HWND; uMsg: UINT; wParam: WParam;
231
lParam: LParam): LRESULT; stdcall;
236
AXC:TActiveXContainer;
238
AXC:=TActiveXContainer(GetWindowLongPtrW( Ahwnd, GWLP_USERDATA));
240
WM_DESTROY:AXC.Detach;
243
size.x:=(LOWORD(lparam)*2540) div Screen.PixelsPerInch;
244
size.y:=(HIWORD(lparam)*2540) div Screen.PixelsPerInch;
245
AXC.Width:=LOWORD(lparam);
246
AXC.Height:=HIWORD(lparam);
247
olecheck((AXC.ComServer as IOleObject).SetExtent(DVASPECT_CONTENT,size));
248
bounds:=AXC.ClientRect;
249
olecheck((AXC.ComServer as IOleInPlaceObject).SetObjectRects(@bounds,@bounds));
253
DC:=GetDC(AXC.handle);
254
bounds:=AXC.ClientRect;
255
olecheck((AXC.ComServer as IViewObject).Draw(DVASPECT_CONTENT,0,nil,nil,0,DC,@bounds,@bounds,nil,0));
256
ReleaseDC(AXC.handle,DC);
259
result:=CallWindowProc(AXC.FPrevWndProc,Ahwnd, uMsg, WParam, LParam);
262
{ TActiveXContainer }
264
function TActiveXContainer.GetvObject: variant;
269
function TActiveXContainer.SaveObject: HResult; StdCall;
274
function TActiveXContainer.GetMoniker(dwAssign: Longint; dwWhichMoniker: Longint; out
275
mk: IMoniker): HResult; StdCall;
281
function TActiveXContainer.GetContainer(out container: IOleContainer): HResult;
285
Result := E_NOINTERFACE;
288
procedure TActiveXContainer.SetActive(AValue: boolean);
290
if FActive=AValue then Exit;
293
if (FClassName='') and not assigned(ComServer) then
294
raise exception.Create('OleClassName and ComServer not assigned.');
295
if not assigned(FOleObject) then
296
FOleObject:=CreateOleObject(FClassName);
302
if FClassName<>'' then //destroy com object
308
procedure TActiveXContainer.SetClassName(AValue: string);
310
if (FClassName=AValue) or FActive then Exit;
314
procedure TActiveXContainer.SetOleObject(AValue: IDispatch);
316
if (FOleObject=AValue) or FActive then Exit;
320
function TActiveXContainer.ShowObject: HResult; StdCall;
325
function TActiveXContainer.OnShowWindow(fShow: BOOL): HResult; StdCall;
330
function TActiveXContainer.RequestNewObjectLayout: HResult; StdCall;
335
function TActiveXContainer.OnControlInfoChanged: HResult; stdcall;
340
function TActiveXContainer.LockInPlaceActive(fLock: BOOL): HResult; stdcall;
345
function TActiveXContainer.GetExtendedControl(out disp: IDispatch): HResult; stdcall;
350
function TActiveXContainer.TransformCoords(var ptlHimetric: TPoint;
351
var ptfContainer: TPointF; flags: Longint): HResult; stdcall;
353
if flags and 4 <> 0 then //XFORMCOORDS_HIMETRICTOCONTAINER=4
355
ptfContainer.X := (ptlHimetric.X * Screen.PixelsPerInch) div 2540;
356
ptfContainer.Y := (ptlHimetric.Y * Screen.PixelsPerInch) div 2540;
358
else if assigned(@ptlHimetric) and (flags and 8 <> 0) then //XFORMCOORDS_CONTAINERTOHIMETRIC = 8
360
ptlHimetric.X := Integer(Round(ptfContainer.X * 2540 / Screen.PixelsPerInch));
361
ptlHimetric.Y := Integer(Round(ptfContainer.Y * 2540 / Screen.PixelsPerInch));
366
function TActiveXContainer.TranslateAccelerator(msg: PMsg; grfModifiers: Longint
372
function TActiveXContainer.OnFocus(fGotFocus: BOOL): HResult; stdcall;
377
function TActiveXContainer.ShowPropertyFrame: HResult; stdcall;
382
function TActiveXContainer.CanInPlaceActivate: HResult;stdcall;
387
function TActiveXContainer.OnInPlaceActivate: HResult;stdcall;
392
function TActiveXContainer.OnUIActivate: HResult; stdcall;
397
function TActiveXContainer.GetWindowContext(out ppframe: IOleInPlaceFrame; out
398
ppdoc: IOleInPlaceUIWindow; lprcposrect: LPRECT; lprccliprect: LPRECT;
399
lpframeinfo: LPOLEINPLACEFRAMEINFO): hresult; stdcall;
401
if assigned (ppframe) then
402
ppframe := Self as IOleInPlaceFrame;
403
if assigned(ppdoc) then
405
if assigned(lpframeinfo) then
407
lpframeinfo.fMDIApp := False;
408
lpframeinfo.cAccelEntries := 0;
409
lpframeinfo.haccel := 0;
410
lpframeinfo.hwndFrame := Handle;
413
if assigned (lprcPosRect) then
414
lprcPosRect^:=GetClientRect;
415
if assigned (lprcClipRect) then
416
lprcClipRect^:=GetClientRect;
421
function TActiveXContainer.Scroll(scrollExtant: TSIZE): hresult; stdcall;
426
function TActiveXContainer.OnUIDeactivate(fUndoable: BOOL): hresult; stdcall;
431
function TActiveXContainer.OnInPlaceDeactivate: hresult; stdcall;
436
function TActiveXContainer.DiscardUndoState: hresult; stdcall;
441
function TActiveXContainer.DeactivateAndUndo: hresult; stdcall;
446
function TActiveXContainer.OnPosRectChange(lprcPosRect: LPRect): hresult; stdcall;
451
function TActiveXContainer.GetWindow(out wnd: HWnd): HResult; stdcall;
457
function TActiveXContainer.ContextSensitiveHelp(fEnterMode: BOOL): HResult; stdcall;
462
function TActiveXContainer.InsertMenus(hmenuShared: HMenu;
463
var menuWidths: TOleMenuGroupWidths): HResult; StdCall;
468
function TActiveXContainer.SetMenu(hmenuShared: HMenu; holemenu: HMenu;
469
hwndActiveObject: HWnd): HResult; StdCall;
474
function TActiveXContainer.RemoveMenus(hmenuShared: HMenu): HResult; StdCall;
479
function TActiveXContainer.SetStatusText(pszStatusText: POleStr): HResult; StdCall;
481
if assigned(FOnStatusText) then
482
FOnStatusText(Self,utf8encode(WideString(pszStatusText)));
486
function TActiveXContainer.EnableModeless(fEnable: BOOL): HResult; StdCall;
491
function TActiveXContainer.TranslateAccelerator(var msg: TMsg; wID: Word): HResult;
497
function TActiveXContainer.GetBorder(out rectBorder: TRect): HResult; StdCall;
499
Result := INPLACE_E_NOTOOLSPACE;
502
function TActiveXContainer.RequestBorderSpace(const borderwidths: TRect): HResult;
505
Result := INPLACE_E_NOTOOLSPACE;
508
function TActiveXContainer.SetBorderSpace(const borderwidths: TRect): HResult;
514
function TActiveXContainer.SetActiveObject(
515
const activeObject: IOleInPlaceActiveObject; pszObjName: POleStr): HResult;
521
function TActiveXContainer.GetTypeInfoCount(out count: longint): HResult;
528
function TActiveXContainer.GetTypeInfo(Index, LocaleID: longint; out TypeInfo
531
Pointer(TypeInfo) := nil;
535
function TActiveXContainer.GetIDsOfNames(const iid: TGUID; names: Pointer;
536
NameCount, LocaleID: LongInt; DispIDs: Pointer): HResult; stdcall;
541
function TActiveXContainer.Invoke(DispID: LongInt; const iid: TGUID;
542
LocaleID: longint; Flags: Word; var params; VarResult, ExcepInfo,
543
ArgErr: pointer): HResult; stdcall;
545
DISPID_AMBIENT_BACKCOLOR = -701;
546
DISPID_AMBIENT_DISPLAYNAME = -702;
547
DISPID_AMBIENT_FONT = -703;
548
DISPID_AMBIENT_FORECOLOR = -704;
549
DISPID_AMBIENT_LOCALEID = -705;
550
DISPID_AMBIENT_MESSAGEREFLECT = -706;
551
DISPID_AMBIENT_USERMODE = -709;
552
DISPID_AMBIENT_UIDEAD = -710;
553
DISPID_AMBIENT_SHOWGRABHANDLES = -711;
554
DISPID_AMBIENT_SHOWHATCHING = -712;
555
DISPID_AMBIENT_SUPPORTSMNEMONICS = -714;
556
DISPID_AMBIENT_AUTOCLIP = -715;
558
if (Flags and DISPATCH_PROPERTYGET <> 0) and (VarResult <> nil) then
562
DISPID_AMBIENT_BACKCOLOR:
563
PVariant(VarResult)^ := Color;
564
DISPID_AMBIENT_DISPLAYNAME:
565
PVariant(VarResult)^ := OleVariant(Name);
567
PVariant(VarResult)^ :=nil;
568
DISPID_AMBIENT_FORECOLOR:
569
PVariant(VarResult)^ := Font.Color;
570
DISPID_AMBIENT_LOCALEID:
571
PVariant(VarResult)^ := Integer(GetUserDefaultLCID);
572
DISPID_AMBIENT_MESSAGEREFLECT:
573
PVariant(VarResult)^ := False;
574
DISPID_AMBIENT_USERMODE:
575
PVariant(VarResult)^ := not (csDesigning in ComponentState);
576
DISPID_AMBIENT_UIDEAD:
577
PVariant(VarResult)^ := csDesigning in ComponentState;
578
DISPID_AMBIENT_SHOWGRABHANDLES:
579
PVariant(VarResult)^ := False;
580
DISPID_AMBIENT_SHOWHATCHING:
581
PVariant(VarResult)^ := False;
582
DISPID_AMBIENT_SUPPORTSMNEMONICS:
583
PVariant(VarResult)^ := True;
584
DISPID_AMBIENT_AUTOCLIP:
585
PVariant(VarResult)^ := True;
587
Result := DISP_E_MEMBERNOTFOUND;
590
Result := DISP_E_MEMBERNOTFOUND;
593
procedure TActiveXContainer.Attach;
597
SetWindowLongPtr(Handle,GWLP_USERDATA, PtrInt(Self));
598
FPrevWndProc:=Windows.WNDPROC(SetWindowLongPtr(Handle,GWL_WNDPROC,PtrInt(@WndCallback)));
600
olecheck((FOleObject as IOleObject).SetClientSite(Self as IOleClientSite));
601
olecheck((FOleObject as IOleObject).SetHostNames(PWideChar(name),PWideChar(name)));
602
size.x:=(Width*2540) div Screen.PixelsPerInch;
603
size.y:=(Height*2540) div Screen.PixelsPerInch;
604
olecheck((FOleObject as IOleObject).SetExtent(DVASPECT_CONTENT,size));
605
olecheck((FOleObject as IOleObject).DoVerb(OLEIVERB_INPLACEACTIVATE,nil,Self as IOleClientSite,0,Handle,ClientRect));
608
procedure TActiveXContainer.Detach;
614
SetWindowLongPtr(Handle,GWL_WNDPROC,PtrInt(@FPrevWndProc));
615
SetWindowLongPtr(Handle,GWLP_USERDATA, 0);
617
if assigned(FOleObject) then
619
olecheck((FOleObject as IOleObject).SetClientSite(nil));
620
olecheck((FOleObject as IOleObject).Close(OLECLOSE_NOSAVE));
624
constructor TActiveXContainer.Create(TheOwner: TComponent);
626
inherited Create(TheOwner);
627
parent:=TWinControl(TheOwner);
632
destructor TActiveXContainer.Destroy;
634
Active:=false; //destroys com object if created by Self