Mercurial > projects > dwt2
diff org.eclipse.swt.win32.win32.x86/src/org/eclipse/swt/ole/win32/OleControlSite.d @ 0:6dd524f61e62
add dwt win and basic java stuff
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Mon, 02 Mar 2009 14:44:16 +0100 |
parents | |
children | 2e09b0e6857a |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/org.eclipse.swt.win32.win32.x86/src/org/eclipse/swt/ole/win32/OleControlSite.d Mon Mar 02 14:44:16 2009 +0100 @@ -0,0 +1,915 @@ +/******************************************************************************* + * Copyright (c) 2000, 2008 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Port to the D programming language: + * Frank Benoit <benoit@tionex.de> + *******************************************************************************/ +module org.eclipse.swt.ole.win32.OleControlSite; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTError; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.internal.ole.win32.COM; +import org.eclipse.swt.internal.ole.win32.COMTYPES; +import org.eclipse.swt.internal.ole.win32.extras; +import org.eclipse.swt.internal.ole.win32.ifs; +import org.eclipse.swt.internal.ole.win32.OAIDL; +import org.eclipse.swt.internal.ole.win32.OBJIDL; +import org.eclipse.swt.internal.win32.OS; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; + +import org.eclipse.swt.ole.win32.OleClientSite; +import org.eclipse.swt.ole.win32.OleEventSink; +import org.eclipse.swt.ole.win32.OlePropertyChangeSink; +import org.eclipse.swt.ole.win32.OleListener; +import org.eclipse.swt.ole.win32.OleAutomation; +import org.eclipse.swt.ole.win32.Variant; +import org.eclipse.swt.ole.win32.OLE; + +import java.lang.all; + +/** + * OleControlSite provides a site to manage an embedded ActiveX Control within a container. + * + * <p>In addition to the behaviour provided by OleClientSite, this object provides the following: + * <ul> + * <li>events from the ActiveX control + * <li>notification of property changes from the ActiveX control + * <li>simplified access to well known properties of the ActiveX Control (e.g. font, background color) + * <li>expose ambient properties of the container to the ActiveX Control + * </ul> + * + * <p>This object implements the OLE Interfaces IOleControlSite, IDispatch, and IPropertyNotifySink. + * + * <p>Note that although this class is a subclass of <code>Composite</code>, + * it does not make sense to add <code>Control</code> children to it, + * or set a layout on it. + * </p><p> + * <dl> + * <dt><b>Styles</b> <dd>BORDER + * <dt><b>Events</b> <dd>Dispose, Move, Resize + * </dl> + * + * @see <a href="http://www.eclipse.org/swt/snippets/#ole">OLE and ActiveX snippets</a> + * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Examples: OLEExample, OleWebBrowser</a> + */ +public class OleControlSite : OleClientSite +{ + // interfaces for this container + private _IOleControlSiteImpl iOleControlSite; + private _IDispatchImpl iDispatch; + + // supporting Property Change attributes + private OlePropertyChangeSink olePropertyChangeSink; + + // supporting Event Sink attributes + private OleEventSink[] oleEventSink; + private GUID*[] oleEventSinkGUID; + private IUnknown[] oleEventSinkIUnknown; + + // supporting information for the Control COM object + private CONTROLINFO* currentControlInfo; + private int[] sitePropertyIds; + private Variant[] sitePropertyValues; + + // work around for IE destroying the caret + static int SWT_RESTORECARET; + +/** + * Create an OleControlSite child widget using style bits + * to select a particular look or set of properties. + * + * @param parent a composite widget; must be an OleFrame + * @param style the bitwise OR'ing of widget styles + * @param progId the unique program identifier which has been registered for this ActiveX Control; + * the value of the ProgID key or the value of the VersionIndependentProgID key specified + * in the registry for this Control (for example, the VersionIndependentProgID for + * Internet Explorer is Shell.Explorer) + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT when the parent is null + *</ul> + * @exception SWTException <ul> + * <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread + * <li>ERROR_INVALID_CLASSID when the progId does not map to a registered CLSID + * <li>ERROR_CANNOT_CREATE_OBJECT when failed to create OLE Object + * <li>ERROR_CANNOT_ACCESS_CLASSFACTORY when Class Factory could not be found + * <li>ERROR_CANNOT_CREATE_LICENSED_OBJECT when failed to create a licensed OLE Object + * </ul> + */ +public this(Composite parent, int style, String progId) { + super(parent, style); + try { + + // check for licensing + appClsid = getClassID(progId); + if (appClsid is null) OLE.error(__FILE__, __LINE__, OLE.ERROR_INVALID_CLASSID); + + BSTR licinfo = getLicenseInfo(appClsid); + if (licinfo is null) { + + // Open a storage object + tempStorage = createTempStorage(); + + // Create ole object with storage object + HRESULT result = COM.OleCreate(appClsid, &COM.IIDIUnknown, COM.OLERENDER_DRAW, null, null, tempStorage, cast(void**)&objIUnknown); + if (result !is COM.S_OK) + OLE.error(__FILE__, __LINE__, OLE.ERROR_CANNOT_CREATE_OBJECT, result); + + } else { + // Prepare the ClassFactory + try { + IClassFactory2 classFactory; + HRESULT result = COM.CoGetClassObject(appClsid, COM.CLSCTX_INPROC_HANDLER | COM.CLSCTX_INPROC_SERVER, null, &COM.IIDIClassFactory2, cast(void**)&classFactory); + if (result !is COM.S_OK) { + OLE.error(__FILE__, __LINE__, OLE.ERROR_CANNOT_ACCESS_CLASSFACTORY, result); + } + // Create Com Object + result = classFactory.CreateInstanceLic(null, null, &COM.IIDIUnknown, licinfo, cast(void**)&objIUnknown); + classFactory.Release(); + if (result !is COM.S_OK) + OLE.error(__FILE__, __LINE__, OLE.ERROR_CANNOT_CREATE_LICENSED_OBJECT, result); + } finally { + COM.SysFreeString(licinfo); + } + + // Prepare a storage medium + IPersistStorage persist; + if (objIUnknown.QueryInterface(&COM.IIDIPersistStorage, cast(void**)&persist) is COM.S_OK) { + tempStorage = createTempStorage(); + persist.InitNew(tempStorage); + persist.Release(); + } + } + + // Init sinks + addObjectReferences(); + + // Init site properties + setSiteProperty(COM.DISPID_AMBIENT_USERMODE, new Variant(true)); + setSiteProperty(COM.DISPID_AMBIENT_UIDEAD, new Variant(false)); + + if (COM.OleRun(objIUnknown) is OLE.S_OK) state= STATE_RUNNING; + + } catch (SWTError e) { + dispose(); + disposeCOMInterfaces(); + throw e; + } +} +/** + * Adds the listener to receive events. + * + * @param eventID the id of the event + * + * @param listener the listener + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT when listener is null</li> + * </ul> + */ +public void addEventListener(int eventID, OleListener listener) { + if (listener is null) OLE.error (__FILE__, __LINE__, SWT.ERROR_NULL_ARGUMENT); + GUID* riid = getDefaultEventSinkGUID(objIUnknown); + if (riid !is null) { + addEventListener(objIUnknown, riid, eventID, listener); + } +} + + +static GUID* getDefaultEventSinkGUID(IUnknown unknown) { + // get Event Sink I/F from IProvideClassInfo2 + IProvideClassInfo2 pci2; + if (unknown.QueryInterface(&COM.IIDIProvideClassInfo2, cast(void**)&pci2) is COM.S_OK) { + GUID* riid = new GUID(); + HRESULT result = pci2.GetGUID(COM.GUIDKIND_DEFAULT_SOURCE_DISP_IID, riid); + pci2.Release(); + if (result is COM.S_OK) return riid; + } + + // get Event Sink I/F from IProvideClassInfo + IProvideClassInfo pci; + if (unknown.QueryInterface(&COM.IIDIProvideClassInfo, cast(void**)&pci) is COM.S_OK) { + ITypeInfo classInfo; + ITypeInfo eventInfo; + HRESULT result = pci.GetClassInfo(&classInfo); + pci.Release(); + + if (result is COM.S_OK && classInfo !is null) { + TYPEATTR* typeAttribute; + result = classInfo.GetTypeAttr(&typeAttribute); + if (result is COM.S_OK && typeAttribute !is null) { + int implMask = COM.IMPLTYPEFLAG_FDEFAULT | COM.IMPLTYPEFLAG_FSOURCE | COM.IMPLTYPEFLAG_FRESTRICTED; + int implBits = COM.IMPLTYPEFLAG_FDEFAULT | COM.IMPLTYPEFLAG_FSOURCE; + + for (uint i = 0; i < typeAttribute.cImplTypes; i++) { + int pImplTypeFlags; + if (classInfo.GetImplTypeFlags(i, &pImplTypeFlags) is COM.S_OK) { + if ((pImplTypeFlags & implMask) is implBits) { + uint pRefType; + if (classInfo.GetRefTypeOfImplType(i, &pRefType) is COM.S_OK) { + classInfo.GetRefTypeInfo(pRefType, &eventInfo); + } + } + } + } + classInfo.ReleaseTypeAttr(typeAttribute); + } + classInfo.Release(); + + if (eventInfo !is null) { + TYPEATTR* ppTypeAttr; + result = eventInfo.GetTypeAttr(&ppTypeAttr); + GUID* riid = null; + if (result is COM.S_OK && ppTypeAttr !is null) { + riid = new GUID(); + *riid = ppTypeAttr.guid; + eventInfo.ReleaseTypeAttr(ppTypeAttr); + } + eventInfo.Release(); + return riid; + } + } + } + return null; +} + +/** + * Adds the listener to receive events. + * + * @since 2.0 + * + * @param automation the automation object that provides the event notification + * @param eventID the id of the event + * @param listener the listener + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT when listener is null</li> + * </ul> + */ +public void addEventListener(OleAutomation automation, int eventID, OleListener listener) { + if (listener is null || automation is null) OLE.error (__FILE__, __LINE__, SWT.ERROR_NULL_ARGUMENT); + IUnknown unknown = automation.getAddress(); + GUID* riid = getDefaultEventSinkGUID(unknown); + if (riid !is null) { + addEventListener(unknown, riid, eventID, listener); + } + +} +/** + * Adds the listener to receive events. + * + * @since 3.2 + * + * @param automation the automation object that provides the event notification + * @param eventSinkId the GUID of the event sink + * @param eventID the id of the event + * @param listener the listener + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT when listener is null</li> + * </ul> + */ +public void addEventListener(OleAutomation automation, String eventSinkId, int eventID, OleListener listener) { + if (listener is null || automation is null || eventSinkId is null) OLE.error (__FILE__, __LINE__, SWT.ERROR_NULL_ARGUMENT); + auto address = automation.getAddress(); + if (address is null) return; + wchar[] buffer = StrToWCHARs(0,eventSinkId,true); + GUID* guid = new GUID(); + if (COM.IIDFromString(buffer.ptr, guid) !is COM.S_OK) return; + addEventListener(address, guid, eventID, listener); +} + +void addEventListener(IUnknown iunknown, GUID* guid, int eventID, OleListener listener) { + if (listener is null || iunknown is null || guid is null) OLE.error (__FILE__, __LINE__, SWT.ERROR_NULL_ARGUMENT); + // have we connected to this kind of event sink before? + int index = -1; + for (int i = 0; i < oleEventSinkGUID.length; i++) { + if (COM.IsEqualGUID(oleEventSinkGUID[i], guid)) { + if (iunknown is oleEventSinkIUnknown[i]) { + index = i; + break; + } + } + } + if (index !is -1) { + oleEventSink[index].addListener(eventID, listener); + } else { + int oldLength = oleEventSink.length; + + oleEventSink ~= new OleEventSink(this, iunknown, guid); + oleEventSinkGUID ~= guid; + oleEventSinkIUnknown ~= iunknown; + + oleEventSink[oldLength].AddRef(); + oleEventSink[oldLength].connect(); + oleEventSink[oldLength].addListener(eventID, listener); + + } +} +protected void addObjectReferences() { + + super.addObjectReferences(); + + // Get property change notification from control + connectPropertyChangeSink(); + + // Get access to the Control object + IOleControl objIOleControl; + if (objIUnknown.QueryInterface(&COM.IIDIOleControl, cast(void**)&objIOleControl) is COM.S_OK) { + // ask the control for its info in case users + // need to act on it + currentControlInfo = new CONTROLINFO(); + objIOleControl.GetControlInfo(currentControlInfo); + objIOleControl.Release(); + } +} +/** + * Adds the listener to receive events. + * + * @param propertyID the identifier of the property + * @param listener the listener + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT when listener is null</li> + * </ul> + */ +public void addPropertyListener(int propertyID, OleListener listener) { + if (listener is null) SWT.error (__FILE__, __LINE__, SWT.ERROR_NULL_ARGUMENT); + olePropertyChangeSink.addListener(propertyID, listener); +} + +private void connectPropertyChangeSink() { + olePropertyChangeSink = new OlePropertyChangeSink(this); + olePropertyChangeSink.AddRef(); + olePropertyChangeSink.connect(objIUnknown); +} +protected void createCOMInterfaces () { + super.createCOMInterfaces(); + iOleControlSite = new _IOleControlSiteImpl(this); + iDispatch = new _IDispatchImpl(this); +} +private void disconnectEventSinks() { + + for (int i = 0; i < oleEventSink.length; i++) { + OleEventSink sink = oleEventSink[i]; + sink.disconnect(); + sink.Release(); + } + oleEventSink = null; + oleEventSinkGUID = null; + oleEventSinkIUnknown = null; +} +private void disconnectPropertyChangeSink() { + + if (olePropertyChangeSink !is null) { + olePropertyChangeSink.disconnect(objIUnknown); + olePropertyChangeSink.Release(); + } + olePropertyChangeSink = null; +} +protected void disposeCOMInterfaces() { + super.disposeCOMInterfaces(); + iOleControlSite = null; + iDispatch = null; +} +public Color getBackground () { + + if (objIUnknown !is null) { + // !! We are getting the OLE_COLOR - should we change this to the COLORREF value? + OleAutomation oleObject= new OleAutomation(this); + Variant varBackColor = oleObject.getProperty(COM.DISPID_BACKCOLOR); + oleObject.dispose(); + + if (varBackColor !is null){ + COLORREF colorRef; + if (COM.OleTranslateColor(varBackColor.getInt(), getDisplay().hPalette, &colorRef) is COM.S_OK) + return Color.win32_new(getDisplay(), colorRef); + } + } + + return super.getBackground(); +} +public Font getFont () { + + if (objIUnknown !is null) { + OleAutomation oleObject= new OleAutomation(this); + Variant varDispFont = oleObject.getProperty(COM.DISPID_FONT); + oleObject.dispose(); + + if (varDispFont !is null){ + OleAutomation iDispFont = varDispFont.getAutomation(); + Variant lfFaceName = iDispFont.getProperty(COM.DISPID_FONT_NAME); + Variant lfHeight = iDispFont.getProperty(COM.DISPID_FONT_SIZE); + Variant lfItalic = iDispFont.getProperty(COM.DISPID_FONT_ITALIC); + //Variant lfCharSet = iDispFont.getProperty(COM.DISPID_FONT_CHARSET); + Variant lfBold = iDispFont.getProperty(COM.DISPID_FONT_BOLD); + iDispFont.dispose(); + + if (lfFaceName !is null && + lfHeight !is null && + lfItalic !is null && + lfBold !is null){ + int style = 3 * lfBold.getInt() + 2 * lfItalic.getInt(); + Device dev = getShell().getDisplay(); + Font font = new Font(dev, lfFaceName.getString(), lfHeight.getInt(), style); + return font; + } + } + } + + return super.getFont(); +} +public Color getForeground () { + + if (objIUnknown !is null) { + // !! We are getting the OLE_COLOR - should we change this to the COLORREF value? + OleAutomation oleObject= new OleAutomation(this); + Variant varForeColor = oleObject.getProperty(COM.DISPID_FORECOLOR); + oleObject.dispose(); + + if (varForeColor !is null){ + COLORREF colorRef; + if (COM.OleTranslateColor(varForeColor.getInt(), getDisplay().hPalette, &colorRef) is COM.S_OK) + return Color.win32_new(getDisplay(), colorRef); + } + } + + return super.getForeground(); +} +protected BSTR getLicenseInfo(GUID* clsid) { + IClassFactory2 classFactory; + if (COM.CoGetClassObject(clsid, COM.CLSCTX_INPROC_HANDLER | COM.CLSCTX_INPROC_SERVER, null, &COM.IIDIClassFactory2, cast(void**)&classFactory) !is COM.S_OK) { + return null; + } + LICINFO licinfo; + if (classFactory.GetLicInfo(&licinfo) !is COM.S_OK) { + classFactory.Release(); + return null; + } + BSTR pBstrKey; + if (licinfo.fRuntimeKeyAvail) { + if (classFactory.RequestLicKey(0, &pBstrKey) is COM.S_OK) { + classFactory.Release(); + return pBstrKey; + } + } + classFactory.Release(); + return null; +} +/** + * + * Get the control site property specified by the dispIdMember, or + * <code>null</code> if the dispId is not recognised. + * + * @param dispId the dispId + * + * @return the property value or <code>null</code> + * + * @since 2.1 + */ +public Variant getSiteProperty(int dispId){ + for (int i = 0; i < sitePropertyIds.length; i++) { + if (sitePropertyIds[i] is dispId) { + return sitePropertyValues[i]; + } + } + return null; +} +protected HRESULT GetWindow(HWND* phwnd) { + + if (phwnd is null) + return COM.E_INVALIDARG; + if (frame is null) { + *phwnd = null; + return COM.E_NOTIMPL; + } + + // Copy the Window's handle into the memory passed in + *phwnd = handle; + return COM.S_OK; +} + +private HRESULT Invoke(DISPID dispIdMember,REFIID riid,LCID lcid,WORD dwFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult,EXCEPINFO* pExcepInfo,UINT* pArgErr) { + int nullv = 0; + if (pVarResult is null || dwFlags !is COM.DISPATCH_PROPERTYGET) { + if (pExcepInfo !is null) COM.MoveMemory(pExcepInfo, &nullv, 4); + if (pArgErr !is null) COM.MoveMemory(pArgErr, &nullv, 4); + return COM.DISP_E_MEMBERNOTFOUND; + } + Variant result = getSiteProperty(dispIdMember); + if (result !is null) { + if (pVarResult !is null) result.getData(pVarResult); + return COM.S_OK; + } + switch (dispIdMember) { + // indicate a false result + case COM.DISPID_AMBIENT_SUPPORTSMNEMONICS : + case COM.DISPID_AMBIENT_SHOWGRABHANDLES : + case COM.DISPID_AMBIENT_SHOWHATCHING : + if (pVarResult !is null) COM.MoveMemory(pVarResult, &nullv, 4); + if (pExcepInfo !is null) COM.MoveMemory(pExcepInfo, &nullv, 4); + if (pArgErr !is null) COM.MoveMemory(pArgErr, &nullv, 4); + return COM.S_FALSE; + + // not implemented + case COM.DISPID_AMBIENT_OFFLINEIFNOTCONNECTED : + case COM.DISPID_AMBIENT_BACKCOLOR : + case COM.DISPID_AMBIENT_FORECOLOR : + case COM.DISPID_AMBIENT_FONT : + case COM.DISPID_AMBIENT_LOCALEID : + case COM.DISPID_AMBIENT_SILENT : + case COM.DISPID_AMBIENT_MESSAGEREFLECT : + if (pVarResult !is null) COM.MoveMemory(pVarResult, &nullv, 4); + if (pExcepInfo !is null) COM.MoveMemory(pExcepInfo, &nullv, 4); + if (pArgErr !is null) COM.MoveMemory(pArgErr, &nullv, 4); + return COM.E_NOTIMPL; + + default : + if (pVarResult !is null) COM.MoveMemory(pVarResult, &nullv, 4); + if (pExcepInfo !is null) COM.MoveMemory(pExcepInfo, &nullv, 4); + if (pArgErr !is null) COM.MoveMemory(pArgErr, &nullv, 4); + return COM.DISP_E_MEMBERNOTFOUND; + } +} +private int OnControlInfoChanged() { + IOleControl objIOleControl; + if (objIUnknown.QueryInterface(&COM.IIDIOleControl, cast(void**)&objIOleControl ) is COM.S_OK) { + // ask the control for its info in case users + // need to act on it + currentControlInfo = new CONTROLINFO(); + objIOleControl.GetControlInfo(currentControlInfo); + objIOleControl.Release(); + } + return COM.S_OK; +} +void onFocusIn(Event e) { + if (objIOleInPlaceObject is null) return; + doVerb(OLE.OLEIVERB_UIACTIVATE); + if (isFocusControl()) return; + HWND phwnd; + objIOleInPlaceObject.GetWindow(&phwnd); + if (phwnd is null) return; + OS.SetFocus(phwnd); +} +void onFocusOut(Event e) { + if (objIOleInPlaceObject !is null) { + /* + * Bug in Windows. When IE7 loses focus and UIDeactivate() + * is called, IE destroys the caret even though it is + * no longer owned by IE. If focus has moved to a control + * that shows a caret then the caret disappears. The fix + * is to detect this case and restore the caret. + */ + auto threadId = OS.GetCurrentThreadId(); + GUITHREADINFO* lpgui1 = new GUITHREADINFO(); + lpgui1.cbSize = GUITHREADINFO.sizeof; + OS.GetGUIThreadInfo(threadId, lpgui1); + objIOleInPlaceObject.UIDeactivate(); + if (lpgui1.hwndCaret !is null) { + GUITHREADINFO* lpgui2 = new GUITHREADINFO(); + lpgui2.cbSize = GUITHREADINFO.sizeof; + OS.GetGUIThreadInfo(threadId, lpgui2); + if (lpgui2.hwndCaret is null && lpgui1.hwndCaret is OS.GetFocus()) { + if (SWT_RESTORECARET is 0) { + SWT_RESTORECARET = OS.RegisterWindowMessage (StrToTCHARz (0, "SWT_RESTORECARET")); + } + /* + * If the caret was not restored by SWT, put it back using + * the information from GUITHREADINFO. Note that this will + * not be correct when the caret has a bitmap. There is no + * API to query the bitmap that the caret is using. + */ + if (OS.SendMessage (lpgui1.hwndCaret, SWT_RESTORECARET, 0, 0) is 0) { + int width = lpgui1.rcCaret.right - lpgui1.rcCaret.left; + int height = lpgui1.rcCaret.bottom - lpgui1.rcCaret.top; + OS.CreateCaret (lpgui1.hwndCaret, null, width, height); + OS.SetCaretPos (lpgui1.rcCaret.left, lpgui1.rcCaret.top); + OS.ShowCaret (lpgui1.hwndCaret); + } + } + } + } +} +private int OnFocus(int fGotFocus) { + return COM.S_OK; +} +protected int OnUIDeactivate(int fUndoable) { + // controls don't need to do anything for + // border space or menubars + state = STATE_INPLACEACTIVE; + return COM.S_OK; +} +override protected HRESULT QueryInterface(REFIID riid, void ** ppvObject) { + int nullv = 0; + int result = super.QueryInterface(riid, ppvObject); + if (result is COM.S_OK) + return result; + if (riid is null || ppvObject is null) + return COM.E_INVALIDARG; + GUID oGuid = *riid; + GUID* guid = &oGuid; + //COM.MoveMemory(&guid, riid, GUID.sizeof); + if (COM.IsEqualGUID(guid, &COM.IIDIOleControlSite)) { + *ppvObject = cast(void*)cast(IOleControlSite)iOleControlSite; + AddRef(); + return COM.S_OK; + } + if (COM.IsEqualGUID(guid, &COM.IIDIDispatch)) { + *ppvObject = cast(void*)cast(IDispatch)iDispatch; + AddRef(); + return COM.S_OK; + } + *ppvObject = null; + return COM.E_NOINTERFACE; +} +protected int Release() { + int result = super.Release(); + if (result is 0) { + for (int i = 0; i < sitePropertyIds.length; i++) { + sitePropertyValues[i].dispose(); + } + sitePropertyIds = null; + sitePropertyValues = null; + } + return result; +} +protected void releaseObjectInterfaces() { + + disconnectEventSinks(); + + disconnectPropertyChangeSink(); + + super.releaseObjectInterfaces(); +} +/** + * Removes the listener. + * + * @param eventID the event identifier + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT when listener is null</li> + * </ul> + */ +public void removeEventListener(int eventID, OleListener listener) { + checkWidget(); + if (listener is null) SWT.error (__FILE__, __LINE__, SWT.ERROR_NULL_ARGUMENT); + + GUID* riid = getDefaultEventSinkGUID(objIUnknown); + if (riid !is null) { + removeEventListener(objIUnknown, riid, eventID, listener); + } +} +/** + * Removes the listener. + * + * @since 2.0 + * @deprecated - use OleControlSite.removeEventListener(OleAutomation, int, OleListener) + * + * @param automation the automation object that provides the event notification + * + * @param guid the identifier of the events COM interface + * + * @param eventID the event identifier + * + * @param listener the listener + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT when listener is null</li> + * </ul> + */ +public void removeEventListener(OleAutomation automation, GUID* guid, int eventID, OleListener listener) { + checkWidget(); + if (automation is null || listener is null || guid is null) SWT.error ( __FILE__, __LINE__, SWT.ERROR_NULL_ARGUMENT); + removeEventListener(automation.getAddress(), guid, eventID, listener); +} +/** + * Removes the listener. + * + * @param automation the automation object that provides the event notification + * @param eventID the event identifier + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT when listener is null</li> + * </ul> + * + * @since 2.0 + */ +public void removeEventListener(OleAutomation automation, int eventID, OleListener listener) { + checkWidget(); + if (automation is null || listener is null) SWT.error ( __FILE__, __LINE__, SWT.ERROR_NULL_ARGUMENT); + auto unknown = automation.getAddress(); + GUID* riid = getDefaultEventSinkGUID(unknown); + if (riid !is null) { + removeEventListener(unknown, riid, eventID, listener); + } +} +void removeEventListener(IUnknown iunknown, GUID* guid, int eventID, OleListener listener) { + if (listener is null || guid is null) SWT.error ( __FILE__, __LINE__, SWT.ERROR_NULL_ARGUMENT); + for (int i = 0; i < oleEventSink.length; i++) { + if (COM.IsEqualGUID(oleEventSinkGUID[i], guid)) { + if (iunknown is oleEventSinkIUnknown[i]) { + oleEventSink[i].removeListener(eventID, listener); + if (!oleEventSink[i].hasListeners()) { + //free resources associated with event sink + oleEventSink[i].disconnect(); + oleEventSink[i].Release(); + int oldLength = oleEventSink.length; + if (oldLength is 1) { + oleEventSink = null; + oleEventSinkGUID = null; + oleEventSinkIUnknown = null; + } else { + OleEventSink[] newOleEventSink = new OleEventSink[oldLength - 1]; + System.arraycopy(oleEventSink, 0, newOleEventSink, 0, i); + System.arraycopy(oleEventSink, i + 1, newOleEventSink, i, oldLength - i - 1); + oleEventSink = newOleEventSink; + + GUID*[] newOleEventSinkGUID = new GUID*[oldLength - 1]; + SimpleType!(GUID*).arraycopy(oleEventSinkGUID, 0, newOleEventSinkGUID, 0, i); + SimpleType!(GUID*).arraycopy(oleEventSinkGUID, i + 1, newOleEventSinkGUID, i, oldLength - i - 1); + oleEventSinkGUID = newOleEventSinkGUID; + + IUnknown[] newOleEventSinkIUnknown = new IUnknown[oldLength - 1]; + SimpleType!(IUnknown).arraycopy(oleEventSinkIUnknown, 0, newOleEventSinkIUnknown, 0, i); + SimpleType!(IUnknown).arraycopy(oleEventSinkIUnknown, i + 1, newOleEventSinkIUnknown, i, oldLength - i - 1); + oleEventSinkIUnknown = newOleEventSinkIUnknown; + } + } + return; + } + } + } +} +/** + * Removes the listener. + * + * @param propertyID the identifier of the property + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT when listener is null</li> + * </ul> + */ +public void removePropertyListener(int propertyID, OleListener listener) { + if (listener is null) SWT.error (__FILE__, __LINE__, SWT.ERROR_NULL_ARGUMENT); + olePropertyChangeSink.removeListener(propertyID, listener); +} +public void setBackground (Color color) { + + super.setBackground(color); + + //set the background of the ActiveX Control + if (objIUnknown !is null) { + OleAutomation oleObject= new OleAutomation(this); + oleObject.setProperty(COM.DISPID_BACKCOLOR, new Variant(cast(int)color.handle)); + oleObject.dispose(); + } +} +public void setFont (Font font) { + + super.setFont(font); + + //set the font of the ActiveX Control + if (objIUnknown !is null) { + + OleAutomation oleObject= new OleAutomation(this); + Variant varDispFont = oleObject.getProperty(COM.DISPID_FONT); + oleObject.dispose(); + + if (varDispFont !is null){ + OleAutomation iDispFont = varDispFont.getAutomation(); + FontData[] fdata = font.getFontData(); + iDispFont.setProperty(COM.DISPID_FONT_NAME, new Variant(fdata[0].getName())); + iDispFont.setProperty(COM.DISPID_FONT_SIZE, new Variant(fdata[0].getHeight())); + iDispFont.setProperty(COM.DISPID_FONT_ITALIC, new Variant(fdata[0].getStyle() & SWT.ITALIC)); + //iDispFont.setProperty(COM.DISPID_FONT_CHARSET, new Variant(fdata[0].getCharset)); + iDispFont.setProperty(COM.DISPID_FONT_BOLD, new Variant((fdata[0].getStyle() & SWT.BOLD))); + iDispFont.dispose(); + } + } + + return; +} +public void setForeground (Color color) { + + super.setForeground(color); + + //set the foreground of the ActiveX Control + if (objIUnknown !is null) { + OleAutomation oleObject= new OleAutomation(this); + oleObject.setProperty(COM.DISPID_FORECOLOR, new Variant(cast(int)color.handle)); + oleObject.dispose(); + } +} +/** + * Sets the control site property specified by the dispIdMember to a new value. + * The value will be disposed by the control site when it is no longer required + * using Variant.dispose. Passing a value of null will clear the dispId value. + * + * @param dispId the ID of the property as specified by the IDL of the ActiveX Control + * @param value The new value for the property as expressed in a Variant. + * + * @since 2.1 + */ +public void setSiteProperty(int dispId, Variant value){ + for (int i = 0; i < sitePropertyIds.length; i++) { + if (sitePropertyIds[i] is dispId) { + if (sitePropertyValues[i] !is null) { + sitePropertyValues[i].dispose(); + } + if (value !is null) { + sitePropertyValues[i] = value; + } else { + int oldLength = sitePropertyIds.length; + int[] newSitePropertyIds = new int[oldLength - 1]; + Variant[] newSitePropertyValues = new Variant[oldLength - 1]; + System.arraycopy(sitePropertyIds, 0, newSitePropertyIds, 0, i); + System.arraycopy(sitePropertyIds, i + 1, newSitePropertyIds, i, oldLength - i - 1); + System.arraycopy(sitePropertyValues, 0, newSitePropertyValues, 0, i); + System.arraycopy(sitePropertyValues, i + 1, newSitePropertyValues, i, oldLength - i - 1); + sitePropertyIds = newSitePropertyIds; + sitePropertyValues = newSitePropertyValues; + } + return; + } + } + int oldLength = sitePropertyIds.length; + int[] newSitePropertyIds = new int[oldLength + 1]; + Variant[] newSitePropertyValues = new Variant[oldLength + 1]; + System.arraycopy(sitePropertyIds, 0, newSitePropertyIds, 0, oldLength); + System.arraycopy(sitePropertyValues, 0, newSitePropertyValues, 0, oldLength); + newSitePropertyIds[oldLength] = dispId; + newSitePropertyValues[oldLength] = value; + sitePropertyIds = newSitePropertyIds; + sitePropertyValues = newSitePropertyValues; +} +} + +class _IDispatchImpl : IDispatch { + + OleControlSite parent; + this(OleControlSite p) { parent = p; } +extern (Windows): + // interface of IUnknown + HRESULT QueryInterface(REFIID riid, void ** ppvObject) { return parent.QueryInterface(riid, ppvObject); } + ULONG AddRef() { return parent.AddRef(); } + ULONG Release() { return parent.Release(); } + + // interface of IDispatch : IUnknown + HRESULT GetTypeInfoCount(UINT * pctinfo) { return COM.E_NOTIMPL; } + HRESULT GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo * ppTInfo) { return COM.E_NOTIMPL; } + HRESULT GetIDsOfNames(REFIID riid, LPOLESTR * rgszNames, UINT cNames, LCID lcid, DISPID * rgDispId) { return COM.E_NOTIMPL; } + // Note : <Shawn> one argument is short !!! + HRESULT Invoke(DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS* pDispParams,VARIANT* pVarResult,EXCEPINFO* pExcepInfo,UINT* puArgErr) { + return parent.Invoke(dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + } +} + +class _IOleControlSiteImpl : IOleControlSite { + + OleControlSite parent; + this(OleControlSite p) { parent = p; } +extern (Windows): + // interface of IUnknown + HRESULT QueryInterface(REFIID riid, void ** ppvObject) { return parent.QueryInterface(riid, ppvObject); } + ULONG AddRef() { return parent.AddRef(); } + ULONG Release() { return parent.Release(); } + + // interface IOleControlSite : IUnknown + HRESULT OnControlInfoChanged() { return parent.OnControlInfoChanged();} + HRESULT LockInPlaceActive(BOOL fLock) { return COM.E_NOTIMPL; } + HRESULT GetExtendedControl(LPDISPATCH* ppDisp) { return COM.E_NOTIMPL; } + HRESULT TransformCoords( + POINTL* pPtlHimetric , //Address of POINTL structure + POINTF* pPtfContainer , //Address of POINTF structure + DWORD dwFlags //Flags indicating the exact conversion + ) { return COM.E_NOTIMPL; } + HRESULT TranslateAccelerator( + LPMSG pMsg , //Pointer to the structure + DWORD grfModifiers //Flags describing the state of the keys + ) + { return COM.E_NOTIMPL; } + HRESULT OnFocus( + BOOL fGotFocus //Indicates whether the control gained focus + ) + { return COM.S_OK; } + HRESULT ShowPropertyFrame() { return COM.E_NOTIMPL; } +} + + +