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.*;
013: import org.eclipse.swt.internal.win32.*;
014: import org.eclipse.swt.internal.ole.win32.*;
015:
016: final class OleEventSink {
017: private OleControlSite widget;
018:
019: private COMObject iDispatch;
020: private int refCount;
021:
022: private IUnknown objIUnknown;
023: private int eventCookie;
024: private GUID eventGuid;
025:
026: private OleEventTable eventTable;
027:
028: OleEventSink(OleControlSite widget, int /*long*/iUnknown, GUID riid) {
029:
030: this .widget = widget;
031: this .eventGuid = riid;
032: this .objIUnknown = new IUnknown(iUnknown);
033:
034: createCOMInterfaces();
035: }
036:
037: void connect() {
038: int /*long*/[] ppvObject = new int /*long*/[1];
039: if (objIUnknown.QueryInterface(
040: COM.IIDIConnectionPointContainer, ppvObject) == COM.S_OK) {
041: IConnectionPointContainer cpc = new IConnectionPointContainer(
042: ppvObject[0]);
043: int /*long*/[] ppCP = new int /*long*/[1];
044: if (cpc.FindConnectionPoint(eventGuid, ppCP) == COM.S_OK) {
045: IConnectionPoint cp = new IConnectionPoint(ppCP[0]);
046: int[] pCookie = new int[1];
047: if (cp.Advise(iDispatch.getAddress(), pCookie) == COM.S_OK)
048: eventCookie = pCookie[0];
049: cp.Release();
050: }
051: cpc.Release();
052: }
053: }
054:
055: void addListener(int eventID, OleListener listener) {
056: if (listener == null)
057: OLE.error(SWT.ERROR_NULL_ARGUMENT);
058: if (eventTable == null)
059: eventTable = new OleEventTable();
060: eventTable.hook(eventID, listener);
061: }
062:
063: int AddRef() {
064: refCount++;
065: return refCount;
066: }
067:
068: private void createCOMInterfaces() {
069: iDispatch = new COMObject(new int[] { 2, 0, 0, 1, 3, 4, 8 }) {
070: public int /*long*/method0(int /*long*/[] args) {
071: return QueryInterface(args[0], args[1]);
072: }
073:
074: public int /*long*/method1(int /*long*/[] args) {
075: return AddRef();
076: }
077:
078: public int /*long*/method2(int /*long*/[] args) {
079: return Release();
080: }
081:
082: // method3 GetTypeInfoCount - not implemented
083: // method4 GetTypeInfo - not implemented
084: // method5 GetIDsOfNames - not implemented
085: public int /*long*/method6(int /*long*/[] args) {
086: return Invoke((int) /*64*/args[0], args[1],
087: (int) /*64*/args[2], (int) /*64*/args[3],
088: args[4], args[5], args[6], args[7]);
089: }
090: };
091: }
092:
093: void disconnect() {
094: // disconnect event sink
095: if (eventCookie != 0 && objIUnknown != null) {
096: int /*long*/[] ppvObject = new int /*long*/[1];
097: if (objIUnknown.QueryInterface(
098: COM.IIDIConnectionPointContainer, ppvObject) == COM.S_OK) {
099: IConnectionPointContainer cpc = new IConnectionPointContainer(
100: ppvObject[0]);
101: if (cpc.FindConnectionPoint(eventGuid, ppvObject) == COM.S_OK) {
102: IConnectionPoint cp = new IConnectionPoint(
103: ppvObject[0]);
104: if (cp.Unadvise(eventCookie) == COM.S_OK) {
105: eventCookie = 0;
106: }
107: cp.Release();
108: }
109: cpc.Release();
110: }
111: }
112: }
113:
114: private void disposeCOMInterfaces() {
115: if (iDispatch != null)
116: iDispatch.dispose();
117: iDispatch = null;
118:
119: }
120:
121: private int Invoke(int dispIdMember, int /*long*/riid, int lcid,
122: int dwFlags, int /*long*/pDispParams,
123: int /*long*/pVarResult, int /*long*/pExcepInfo,
124: int /*long*/pArgErr) {
125: if (eventTable == null || !eventTable.hooks(dispIdMember))
126: return COM.S_OK;
127:
128: // Construct an array of the parameters that are passed in
129: // Note: parameters are passed in reverse order - here we will correct the order
130: Variant[] eventInfo = null;
131: if (pDispParams != 0) {
132: DISPPARAMS dispParams = new DISPPARAMS();
133: COM.MoveMemory(dispParams, pDispParams, DISPPARAMS.sizeof);
134: eventInfo = new Variant[dispParams.cArgs];
135: int size = VARIANT.sizeof;
136: int /*long*/offset = (dispParams.cArgs - 1) * size;
137:
138: for (int j = 0; j < dispParams.cArgs; j++) {
139: eventInfo[j] = new Variant();
140: eventInfo[j].setData(dispParams.rgvarg + offset);
141: offset = offset - size;
142: }
143: }
144:
145: OleEvent event = new OleEvent();
146: event.arguments = eventInfo;
147: notifyListener(dispIdMember, event);
148: return COM.S_OK;
149: }
150:
151: /**
152: * Notify listeners of an event.
153: * <p>
154: * This method notifies all listeners that an event
155: * has occurred.
156: *
157: * @param eventType the desired SWT event
158: * @param event the event data
159: *
160: * @exception IllegalArgumentException <ul>
161: * <li>ERROR_NULL_ARGUMENT when handler is null</li>
162: * </ul>
163: * @exception SWTException <ul>
164: * <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
165: * <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
166: * </ul>
167: */
168: private void notifyListener(int eventType, OleEvent event) {
169: if (event == null)
170: OLE.error(SWT.ERROR_NULL_ARGUMENT);
171: if (eventTable == null)
172: return;
173: event.type = eventType;
174: event.widget = widget;
175: eventTable.sendEvent(event);
176: }
177:
178: private int QueryInterface(int /*long*/riid,
179: int /*long*/ppvObject) {
180:
181: if (riid == 0 || ppvObject == 0)
182: return COM.E_INVALIDARG;
183: GUID guid = new GUID();
184: COM.MoveMemory(guid, riid, GUID.sizeof);
185:
186: if (COM.IsEqualGUID(guid, COM.IIDIUnknown)
187: || COM.IsEqualGUID(guid, COM.IIDIDispatch)
188: || COM.IsEqualGUID(guid, eventGuid)) {
189: COM.MoveMemory(ppvObject, new int /*long*/[] { iDispatch
190: .getAddress() }, OS.PTR_SIZEOF);
191: AddRef();
192: return OLE.S_OK;
193: }
194:
195: COM.MoveMemory(ppvObject, new int /*long*/[] { 0 },
196: OS.PTR_SIZEOF);
197: return COM.E_NOINTERFACE;
198: }
199:
200: int Release() {
201: refCount--;
202: if (refCount == 0) {
203: disposeCOMInterfaces();
204: }
205:
206: return refCount;
207: }
208:
209: void removeListener(int eventID, OleListener listener) {
210: if (listener == null)
211: OLE.error(SWT.ERROR_NULL_ARGUMENT);
212: if (eventTable == null)
213: return;
214: eventTable.unhook(eventID, listener);
215: }
216:
217: boolean hasListeners() {
218: return eventTable.hasEntries();
219: }
220: }
|