]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.eclipse.swt.win32.win32.x86_64/src/org/eclipse/swt/ole/win32/OlePropertyChangeSink.java
Merge branch 'bug-623' into release/1.43.0
[simantics/platform.git] / bundles / org.eclipse.swt.win32.win32.x86_64 / src / org / eclipse / swt / ole / win32 / OlePropertyChangeSink.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2017 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *******************************************************************************/
14 package org.eclipse.swt.ole.win32;
15
16
17 import org.eclipse.swt.*;
18 import org.eclipse.swt.internal.*;
19 import org.eclipse.swt.internal.ole.win32.*;
20 import org.eclipse.swt.internal.win32.*;
21
22 final class OlePropertyChangeSink {
23
24         private OleControlSite controlSite;
25         //private IUnknown objIUnknown;
26
27         private COMObject iPropertyNotifySink;
28
29         private int refCount;
30
31         private int propertyCookie;
32
33         private OleEventTable eventTable;
34
35 OlePropertyChangeSink(OleControlSite controlSite) {
36
37         this.controlSite = controlSite;
38
39         createCOMInterfaces();
40 }
41 void addListener(int propertyID, OleListener listener) {
42         if (listener == null) OLE.error (SWT.ERROR_NULL_ARGUMENT);
43         if (eventTable == null) eventTable = new OleEventTable ();
44         eventTable.hook(propertyID, listener);
45 }
46 int AddRef() {
47         refCount++;
48         return refCount;
49 }
50 void connect(IUnknown objIUnknown) {
51
52         // Set up property change notification sink
53         long[] ppvObject = new long[1];
54         if (objIUnknown.QueryInterface(COM.IIDIConnectionPointContainer, ppvObject) == COM.S_OK) {
55                 IConnectionPointContainer cpc = new IConnectionPointContainer(ppvObject[0]);
56                 if (cpc.FindConnectionPoint(COM.IIDIPropertyNotifySink, ppvObject) == COM.S_OK) {
57                         IConnectionPoint cp = new IConnectionPoint(ppvObject[0]);
58                         int[] cookie = new int[1];
59                         if (cp.Advise(iPropertyNotifySink.getAddress(), cookie) == COM.S_OK) {
60                                 propertyCookie = cookie[0];
61                         }
62                         cp.Release();
63                 }
64                 cpc.Release();
65         }
66 }
67 private void createCOMInterfaces() {
68         iPropertyNotifySink = new COMObject(new int[]{2, 0, 0, 1, 1}){
69                 @Override
70                 public long method0(long[] args) {return QueryInterface(args[0], args[1]);}
71                 @Override
72                 public long method1(long[] args) {return AddRef();}
73                 @Override
74                 public long method2(long[] args) {return Release();}
75                 @Override
76                 public long method3(long[] args) {return OnChanged((int)args[0]);}
77                 @Override
78                 public long method4(long[] args) {return OnRequestEdit((int)args[0]);}
79         };
80 }
81 void disconnect(IUnknown objIUnknown) {
82
83         // disconnect property notification sink
84         if (propertyCookie != 0 && objIUnknown != null) {
85                 long[] ppvObject = new long[1];
86                 if (objIUnknown.QueryInterface(COM.IIDIConnectionPointContainer, ppvObject) == COM.S_OK) {
87                         IConnectionPointContainer cpc = new IConnectionPointContainer(ppvObject[0]);
88                         if (cpc.FindConnectionPoint(COM.IIDIPropertyNotifySink, ppvObject) == COM.S_OK) {
89                                 IConnectionPoint cp = new IConnectionPoint(ppvObject[0]);
90                                 if (cp.Unadvise(propertyCookie) == COM.S_OK) {
91                                         propertyCookie = 0;
92                                 }
93                                 cp.Release();
94                         }
95                         cpc.Release();
96                 }
97         }
98 }
99 private void disposeCOMInterfaces() {
100         if (iPropertyNotifySink != null) iPropertyNotifySink.dispose();
101         iPropertyNotifySink = null;
102 }
103 /**
104 * Notify listeners of an event.
105 * <p>
106 *       This method notifies all listeners that an event
107 * has occurred.
108 *
109 * @param eventType the desired SWT event
110 * @param event the event data
111 *
112 * @exception IllegalArgumentException <ul>
113 *               <li>ERROR_NULL_ARGUMENT when handler is null</li>
114 * </ul>
115 * @exception SWTException <ul>
116 *               <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li>
117 *               <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
118 *       </ul>
119 */
120 private void notifyListener (int eventType, OleEvent event) {
121         if (event == null) OLE.error (SWT.ERROR_NULL_ARGUMENT);
122         if (eventTable == null) return;
123         event.type = eventType;
124         event.widget = controlSite;
125         eventTable.sendEvent (event);
126 }
127 private int OnChanged(int dispID) {
128         if (eventTable == null || !eventTable.hooks(dispID)) return COM.S_OK;
129         OleEvent event = new OleEvent();
130         event.detail = OLE.PROPERTY_CHANGED;
131         notifyListener(dispID,event);
132         return COM.S_OK;
133 }
134 private int OnRequestEdit(int dispID) {
135         if (eventTable == null || !eventTable.hooks(dispID)) return COM.S_OK;
136         OleEvent event = new OleEvent();
137         event.doit = true;
138         event.detail = OLE.PROPERTY_CHANGING;
139         notifyListener(dispID,event);
140         return (event.doit) ? COM.S_OK : COM.S_FALSE;
141 }
142 private int QueryInterface(long riid, long ppvObject) {
143         if (riid == 0 || ppvObject == 0)
144                 return COM.E_INVALIDARG;
145         GUID guid = new GUID();
146         COM.MoveMemory(guid, riid, GUID.sizeof);
147         if (COM.IsEqualGUID(guid, COM.IIDIUnknown) || COM.IsEqualGUID(guid, COM.IIDIPropertyNotifySink)) {
148                 OS.MoveMemory(ppvObject, new long[] {iPropertyNotifySink.getAddress()}, C.PTR_SIZEOF);
149                 AddRef();
150                 return COM.S_OK;
151         }
152         OS.MoveMemory(ppvObject, new long[] {0}, C.PTR_SIZEOF);
153         return COM.E_NOINTERFACE;
154 }
155 int Release() {
156         refCount--;
157         if (refCount == 0) {
158                 disposeCOMInterfaces();
159         }
160         return refCount;
161 }
162 void removeListener(int propertyID, OleListener listener) {
163         if (listener == null) OLE.error (SWT.ERROR_NULL_ARGUMENT);
164         if (eventTable == null) return;
165         eventTable.unhook (propertyID, listener);
166 }
167 }