001: /*******************************************************************************
002: * Copyright (c) 2000, 2004 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.swt.ole.win32;
011:
012: import org.eclipse.swt.internal.ole.win32.*;
013: import org.eclipse.swt.internal.win32.*;
014: import org.eclipse.swt.*;
015:
016: final class OlePropertyChangeSink {
017:
018: private OleControlSite controlSite;
019: //private IUnknown objIUnknown;
020:
021: private COMObject iUnknown;
022: private COMObject iPropertyNotifySink;
023:
024: private int refCount;
025:
026: private int propertyCookie;
027:
028: private OleEventTable eventTable;
029:
030: OlePropertyChangeSink(OleControlSite controlSite) {
031:
032: this .controlSite = controlSite;
033:
034: createCOMInterfaces();
035: }
036:
037: void addListener(int propertyID, OleListener listener) {
038: if (listener == null)
039: OLE.error(SWT.ERROR_NULL_ARGUMENT);
040: if (eventTable == null)
041: eventTable = new OleEventTable();
042: eventTable.hook(propertyID, listener);
043: }
044:
045: int AddRef() {
046: refCount++;
047: return refCount;
048: }
049:
050: void connect(IUnknown objIUnknown) {
051:
052: // Set up property change notification sink
053: int /*long*/[] ppvObject = new int /*long*/[1];
054: if (objIUnknown.QueryInterface(
055: COM.IIDIConnectionPointContainer, ppvObject) == COM.S_OK) {
056: IConnectionPointContainer cpc = new IConnectionPointContainer(
057: ppvObject[0]);
058: if (cpc.FindConnectionPoint(COM.IIDIPropertyNotifySink,
059: ppvObject) == COM.S_OK) {
060: IConnectionPoint cp = new IConnectionPoint(ppvObject[0]);
061: int[] cookie = new int[1];
062: if (cp.Advise(iPropertyNotifySink.getAddress(), cookie) == COM.S_OK) {
063: propertyCookie = cookie[0];
064: }
065: cp.Release();
066: }
067: cpc.Release();
068: }
069: }
070:
071: private void createCOMInterfaces() {
072: // register each of the interfaces that this object implements
073: iUnknown = new COMObject(new int[] { 2, 0, 0 }) {
074: public int /*long*/method0(int /*long*/[] args) {
075: return QueryInterface(args[0], args[1]);
076: }
077:
078: public int /*long*/method1(int /*long*/[] args) {
079: return AddRef();
080: }
081:
082: public int /*long*/method2(int /*long*/[] args) {
083: return Release();
084: }
085: };
086:
087: iPropertyNotifySink = new COMObject(new int[] { 2, 0, 0, 1, 1 }) {
088: public int /*long*/method0(int /*long*/[] args) {
089: return QueryInterface(args[0], args[1]);
090: }
091:
092: public int /*long*/method1(int /*long*/[] args) {
093: return AddRef();
094: }
095:
096: public int /*long*/method2(int /*long*/[] args) {
097: return Release();
098: }
099:
100: public int /*long*/method3(int /*long*/[] args) {
101: return OnChanged((int) /*64*/args[0]);
102: }
103:
104: public int /*long*/method4(int /*long*/[] args) {
105: return OnRequestEdit((int) /*64*/args[0]);
106: }
107: };
108: }
109:
110: void disconnect(IUnknown objIUnknown) {
111:
112: // disconnect property notification sink
113: if (propertyCookie != 0 && objIUnknown != null) {
114: int /*long*/[] ppvObject = new int /*long*/[1];
115: if (objIUnknown.QueryInterface(
116: COM.IIDIConnectionPointContainer, ppvObject) == COM.S_OK) {
117: IConnectionPointContainer cpc = new IConnectionPointContainer(
118: ppvObject[0]);
119: if (cpc.FindConnectionPoint(COM.IIDIPropertyNotifySink,
120: ppvObject) == COM.S_OK) {
121: IConnectionPoint cp = new IConnectionPoint(
122: ppvObject[0]);
123: if (cp.Unadvise(propertyCookie) == COM.S_OK) {
124: propertyCookie = 0;
125: }
126: cp.Release();
127: }
128: cpc.Release();
129: }
130: }
131: }
132:
133: private void disposeCOMInterfaces() {
134: if (iUnknown != null)
135: iUnknown.dispose();
136: iUnknown = null;
137: if (iPropertyNotifySink != null)
138: iPropertyNotifySink.dispose();
139: iPropertyNotifySink = null;
140: }
141:
142: /**
143: * Notify listeners of an event.
144: * <p>
145: * This method notifies all listeners that an event
146: * has occurred.
147: *
148: * @param eventType the desired SWT event
149: * @param event the event data
150: *
151: * @exception IllegalArgumentException <ul>
152: * <li>ERROR_NULL_ARGUMENT when handler is null</li>
153: * </ul>
154: * @exception SWTException <ul>
155: * <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
156: * <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
157: * </ul>
158: */
159: private void notifyListener(int eventType, OleEvent event) {
160: if (event == null)
161: OLE.error(SWT.ERROR_NULL_ARGUMENT);
162: if (eventTable == null)
163: return;
164: event.type = eventType;
165: event.widget = controlSite;
166: eventTable.sendEvent(event);
167: }
168:
169: private int OnChanged(int dispID) {
170: if (eventTable == null || !eventTable.hooks(dispID))
171: return COM.S_OK;
172: OleEvent event = new OleEvent();
173: event.detail = OLE.PROPERTY_CHANGED;
174: notifyListener(dispID, event);
175: return COM.S_OK;
176: }
177:
178: private int OnRequestEdit(int dispID) {
179: if (eventTable == null || !eventTable.hooks(dispID))
180: return COM.S_OK;
181: OleEvent event = new OleEvent();
182: event.doit = true;
183: event.detail = OLE.PROPERTY_CHANGING;
184: notifyListener(dispID, event);
185: return (event.doit) ? COM.S_OK : COM.S_FALSE;
186: }
187:
188: private int QueryInterface(int /*long*/riid,
189: int /*long*/ppvObject) {
190: if (riid == 0 || ppvObject == 0)
191: return COM.E_INVALIDARG;
192: GUID guid = new GUID();
193: COM.MoveMemory(guid, riid, GUID.sizeof);
194: if (COM.IsEqualGUID(guid, COM.IIDIUnknown)) {
195: COM.MoveMemory(ppvObject, new int /*long*/[] { iUnknown
196: .getAddress() }, OS.PTR_SIZEOF);
197: AddRef();
198: return COM.S_OK;
199: }
200: if (COM.IsEqualGUID(guid, COM.IIDIPropertyNotifySink)) {
201: COM.MoveMemory(ppvObject,
202: new int /*long*/[] { iPropertyNotifySink
203: .getAddress() }, OS.PTR_SIZEOF);
204: AddRef();
205: return COM.S_OK;
206: }
207: COM.MoveMemory(ppvObject, new int /*long*/[] { 0 },
208: OS.PTR_SIZEOF);
209: return COM.E_NOINTERFACE;
210: }
211:
212: int Release() {
213: refCount--;
214: if (refCount == 0) {
215: disposeCOMInterfaces();
216: }
217: return refCount;
218: }
219:
220: void removeListener(int propertyID, OleListener listener) {
221: if (listener == null)
222: OLE.error(SWT.ERROR_NULL_ARGUMENT);
223: if (eventTable == null)
224: return;
225: eventTable.unhook(propertyID, listener);
226: }
227: }
|