98
|
1 /*******************************************************************************
|
|
2 * Copyright (c) 2000, 2004 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 dwt.ole.win32.OlePropertyChangeSink;
|
|
14
|
|
15
|
|
16 import dwt.DWT;
|
|
17 import dwt.DWTException;
|
|
18 import dwt.internal.ole.win32.COM;
|
|
19 import dwt.internal.ole.win32.extras;
|
|
20 import dwt.internal.ole.win32.ifs;
|
|
21
|
|
22 import dwt.ole.win32.OleControlSite;
|
|
23 import dwt.ole.win32.OleEventTable;
|
|
24 import dwt.ole.win32.OleListener;
|
|
25 import dwt.ole.win32.OleEvent;
|
|
26 import dwt.ole.win32.OleEventTable;
|
|
27 import dwt.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__, DWT.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 DWT 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 DWTException <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__, DWT.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(REFIID 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*)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__, DWT.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(REFIID 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
|