Mercurial > projects > dwt-win
view dwt/ole/win32/OleEventSink.d @ 301:244e3774d515
Fixed missing casts to interface types.
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Thu, 28 Aug 2008 15:57:57 +0200 |
parents | fd9c62a2998e |
children |
line wrap: on
line source
/******************************************************************************* * Copyright (c) 2000, 2007 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 dwt.ole.win32.OleEventSink; import dwt.DWT; import dwt.DWTException; import dwt.internal.ole.win32.COM; import dwt.internal.ole.win32.extras; import dwt.internal.ole.win32.OAIDL; import dwt.internal.ole.win32.ifs; import dwt.ole.win32.OleControlSite; import dwt.ole.win32.OleEventTable; import dwt.ole.win32.OleListener; import dwt.ole.win32.OleEvent; import dwt.ole.win32.OLE; import dwt.ole.win32.Variant; final class OleEventSink { private OleControlSite widget; private _DispatchImpl iDispatch; private int refCount; private IUnknown objIUnknown; private int eventCookie; private GUID* eventGuid; private OleEventTable eventTable; this(OleControlSite widget, IUnknown iUnknown, GUID* riid) { this.widget = widget; this.eventGuid = riid; this.objIUnknown = iUnknown; createCOMInterfaces(); } void connect () { IConnectionPointContainer cpc; if (objIUnknown.QueryInterface(&COM.IIDIConnectionPointContainer, cast(void**)&cpc) is COM.S_OK) { IConnectionPoint cp; if (cpc.FindConnectionPoint(eventGuid, &cp) is COM.S_OK) { uint pCookie; if (cp.Advise(iDispatch, &pCookie) is COM.S_OK) eventCookie = pCookie; cp.Release(); } cpc.Release(); } } void addListener(int eventID, OleListener listener) { if (listener is null) OLE.error (DWT.ERROR_NULL_ARGUMENT); if (eventTable is null) eventTable = new OleEventTable (); eventTable.hook(eventID, listener); } int AddRef() { refCount++; return refCount; } private void createCOMInterfaces() { iDispatch = new _DispatchImpl(this); } void disconnect() { // disconnect event sink if (eventCookie !is 0 && objIUnknown !is null) { IConnectionPointContainer cpc; if (objIUnknown.QueryInterface(&COM.IIDIConnectionPointContainer, cast(void**)&cpc) is COM.S_OK) { IConnectionPoint cp; if (cpc.FindConnectionPoint(eventGuid, &cp) is COM.S_OK) { if (cp.Unadvise(eventCookie) is COM.S_OK) { eventCookie = 0; } cp.Release(); } cpc.Release(); } } } private void disposeCOMInterfaces() { iDispatch = null; } private HRESULT Invoke(DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS* pDispParams,VARIANT* pVarResult,EXCEPINFO* pExcepInfo,UINT* puArgErr) { if (eventTable is null || !eventTable.hooks(dispIdMember)) return COM.S_OK; // Construct an array of the parameters that are passed in // Note: parameters are passed in reverse order - here we will correct the order Variant[] eventInfo = null; if (pDispParams !is null) { DISPPARAMS* dispParams = new DISPPARAMS(); COM.MoveMemory(dispParams, pDispParams, DISPPARAMS.sizeof); eventInfo = new Variant[dispParams.cArgs]; int size = Variant.sizeof; int offset = (dispParams.cArgs - 1) * size; for (int j = 0; j < dispParams.cArgs; j++){ eventInfo[j] = new Variant(); eventInfo[j].setData(dispParams.rgvarg + offset); offset = offset - size; } } OleEvent event = new OleEvent(); event.arguments = eventInfo; notifyListener(dispIdMember,event); return COM.S_OK; } /** * Notify listeners of an event. * <p> * This method notifies all listeners that an event * has occurred. * * @param eventType the desired DWT event * @param event the event data * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT when handler is null</li> * </ul> * @exception DWTException <ul> * <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li> * <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li> * </ul> */ private void notifyListener (int eventType, OleEvent event) { if (event is null) OLE.error (DWT.ERROR_NULL_ARGUMENT); if (eventTable is null) return; event.type = eventType; event.widget = widget; eventTable.sendEvent (event); } private HRESULT QueryInterface(REFIID riid, void ** ppvObject) { if (riid is null || ppvObject is null) return COM.E_INVALIDARG; if ( COM.IsEqualGUID(riid, &COM.IIDIUnknown) || COM.IsEqualGUID(riid, &COM.IIDIDispatch) || COM.IsEqualGUID(riid, eventGuid)) { *ppvObject = cast(void*)cast(IDispatch)iDispatch; AddRef(); return OLE.S_OK; } *ppvObject = null; return COM.E_NOINTERFACE; } int Release() { refCount--; if (refCount is 0) { disposeCOMInterfaces(); } return refCount; } void removeListener(int eventID, OleListener listener) { if (listener is null) OLE.error (DWT.ERROR_NULL_ARGUMENT); if (eventTable is null) return; eventTable.unhook (eventID, listener); } bool hasListeners() { return eventTable.hasEntries(); } } private class _DispatchImpl : IDispatch { OleEventSink parent; this(OleEventSink sink) { parent = sink;} extern (Windows) : HRESULT QueryInterface(REFIID riid, void ** ppvObject){ return parent.QueryInterface(riid, ppvObject); } ULONG AddRef() { return parent.AddRef(); } ULONG Release() { return parent.Release(); } 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; } 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); } }