1 /******************************************************************************* 2 * Copyright (c) 2000, 2007 IBM Corporation and others. 3 * All rights reserved. This program and the accompanying materials 4 * are made available under the terms of the Eclipse Public License v1.0 5 * which accompanies this distribution, and is available at 6 * http://www.eclipse.org/legal/epl-v10.html 7 * 8 * Contributors: 9 * IBM Corporation - initial API and implementation 10 * Port to the D programming language: 11 * Frank Benoit <benoit@tionex.de> 12 *******************************************************************************/ 13 module org.eclipse.swt.ole.win32.OlePropertyChangeSink; 14 15 16 import org.eclipse.swt.SWT; 17 import org.eclipse.swt.SWTException; 18 import org.eclipse.swt.internal.ole.win32.COM; 19 import org.eclipse.swt.internal.ole.win32.extras; 20 import org.eclipse.swt.internal.ole.win32.ifs; 21 22 import org.eclipse.swt.ole.win32.OleControlSite; 23 import org.eclipse.swt.ole.win32.OleEventTable; 24 import org.eclipse.swt.ole.win32.OleListener; 25 import org.eclipse.swt.ole.win32.OleEvent; 26 import org.eclipse.swt.ole.win32.OleEventTable; 27 import org.eclipse.swt.ole.win32.OLE; 28 29 final class OlePropertyChangeSink { 30 31 private OleControlSite controlSite; 32 //private IUnknown objIUnknown; 33 34 //private COMObject iUnknown; 35 private _IPropertyNotifySinkImpl iPropertyNotifySink; 36 37 private int refCount; 38 39 private int propertyCookie; 40 41 private OleEventTable eventTable; 42 43 this(OleControlSite controlSite) { 44 45 this.controlSite = controlSite; 46 47 createCOMInterfaces(); 48 } 49 void addListener(int propertyID, OleListener listener) { 50 if (listener is null) OLE.error (__FILE__, __LINE__, SWT.ERROR_NULL_ARGUMENT); 51 if (eventTable is null) eventTable = new OleEventTable (); 52 eventTable.hook(propertyID, listener); 53 } 54 int AddRef() { 55 refCount++; 56 return refCount; 57 } 58 void connect(IUnknown objIUnknown) { 59 60 // Set up property change notification sink 61 IConnectionPointContainer cpc; 62 if (objIUnknown.QueryInterface(&COM.IIDIConnectionPointContainer, cast(void**)&cpc) is COM.S_OK) { 63 IConnectionPoint cp; 64 if (cpc.FindConnectionPoint(&COM.IIDIPropertyNotifySink, &cp) is COM.S_OK) { 65 uint cookie; 66 if (cp.Advise(iPropertyNotifySink, &cookie) is COM.S_OK) { 67 propertyCookie = cookie; 68 } 69 cp.Release(); 70 } 71 cpc.Release(); 72 } 73 } 74 protected void createCOMInterfaces() { 75 // register each of the interfaces that this object implements 76 iPropertyNotifySink = new _IPropertyNotifySinkImpl(this); 77 } 78 void disconnect(IUnknown objIUnknown) { 79 80 // disconnect property notification sink 81 if (propertyCookie !is 0 && objIUnknown !is null) { 82 IConnectionPointContainer cpc; 83 if (objIUnknown.QueryInterface(&COM.IIDIConnectionPointContainer, cast(void**)&cpc) is COM.S_OK) { 84 IConnectionPoint cp; 85 if (cpc.FindConnectionPoint(&COM.IIDIPropertyNotifySink, &cp) is COM.S_OK) { 86 if (cp.Unadvise(propertyCookie) is COM.S_OK) { 87 propertyCookie = 0; 88 } 89 cp.Release(); 90 } 91 cpc.Release(); 92 } 93 } 94 } 95 private void disposeCOMInterfaces() { 96 iPropertyNotifySink = null; 97 } 98 /** 99 * Notify listeners of an event. 100 * <p> 101 * This method notifies all listeners that an event 102 * has occurred. 103 * 104 * @param eventType the desired SWT event 105 * @param event the event data 106 * 107 * @exception IllegalArgumentException <ul> 108 * <li>ERROR_NULL_ARGUMENT when handler is null</li> 109 * </ul> 110 * @exception SWTException <ul> 111 * <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li> 112 * <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li> 113 * </ul> 114 */ 115 private void notifyListener (int eventType, OleEvent event) { 116 if (event is null) OLE.error (__FILE__, __LINE__, SWT.ERROR_NULL_ARGUMENT); 117 if (eventTable is null) return; 118 event.type = eventType; 119 event.widget = controlSite; 120 eventTable.sendEvent (event); 121 } 122 package int OnChanged(int dispID) { 123 if (eventTable is null || !eventTable.hooks(dispID)) return COM.S_OK; 124 OleEvent event = new OleEvent(); 125 event.detail = OLE.PROPERTY_CHANGED; 126 notifyListener(dispID,event); 127 return COM.S_OK; 128 } 129 package int OnRequestEdit(int dispID) { 130 if (eventTable is null || !eventTable.hooks(dispID)) return COM.S_OK; 131 OleEvent event = new OleEvent(); 132 event.doit = true; 133 event.detail = OLE.PROPERTY_CHANGING; 134 notifyListener(dispID,event); 135 return (event.doit) ? COM.S_OK : COM.S_FALSE; 136 } 137 protected HRESULT QueryInterface(REFCIID riid, void ** ppvObject) { 138 if (riid is null || ppvObject is null) 139 return COM.E_INVALIDARG; 140 141 if (COM.IsEqualGUID(riid, &COM.IIDIPropertyNotifySink)) { 142 *ppvObject = cast(void*)cast(IPropertyNotifySink)iPropertyNotifySink; 143 AddRef(); 144 return COM.S_OK; 145 } 146 *ppvObject = null; 147 return COM.E_NOINTERFACE; 148 } 149 int Release() { 150 refCount--; 151 if (refCount is 0) { 152 disposeCOMInterfaces(); 153 } 154 return refCount; 155 } 156 void removeListener(int propertyID, OleListener listener) { 157 if (listener is null) OLE.error (__FILE__, __LINE__, SWT.ERROR_NULL_ARGUMENT); 158 if (eventTable is null) return; 159 eventTable.unhook (propertyID, listener); 160 } 161 } 162 163 164 private class _IPropertyNotifySinkImpl : IPropertyNotifySink { 165 166 OlePropertyChangeSink parent; 167 this(OlePropertyChangeSink p) { parent = p; } 168 extern (Windows): 169 // interface of IUnknown 170 HRESULT QueryInterface(REFCIID riid, void ** ppvObject) { return parent.QueryInterface(riid, ppvObject); } 171 ULONG AddRef() { return parent.AddRef(); } 172 ULONG Release() { return parent.Release(); } 173 174 // interface of IPropertyNotifySink 175 int OnChanged(int dispID) { return parent.OnChanged(dispID); } 176 int OnRequestEdit(int dispID) { return parent.OnRequestEdit(dispID); } 177 } 178 179 180 181