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.dnd.OleEnumFORMATETC; 14 15 import org.eclipse.swt.internal.ole.win32.COM; 16 import org.eclipse.swt.internal.ole.win32.OBJIDL; 17 import org.eclipse.swt.internal.ole.win32.extras; 18 import org.eclipse.swt.internal.win32.OS; 19 20 final class OleEnumFORMATETC { 21 22 private _IEnumFORMATETCImpl iEnumFORMATETC; 23 24 private int refCount; 25 private int index; 26 27 private FORMATETC*[] formats; 28 29 this() { 30 31 createCOMInterfaces(); 32 33 } 34 int AddRef() { 35 refCount++; 36 return refCount; 37 } 38 private void createCOMInterfaces() { 39 // register each of the interfaces that this object implements 40 iEnumFORMATETC = new _IEnumFORMATETCImpl( this ); 41 } 42 private void disposeCOMInterfaces() { 43 iEnumFORMATETC = null; 44 } 45 IEnumFORMATETC getAddress() { 46 return iEnumFORMATETC; 47 } 48 private FORMATETC*[] getNextItems(int numItems){ 49 50 if (formats is null || numItems < 1) return null; 51 52 int endIndex = index + numItems - 1; 53 if (endIndex > (formats.length - 1)) endIndex = cast(int)/*64bit*/formats.length - 1; 54 if (index > endIndex) return null; 55 56 FORMATETC*[] items = new FORMATETC*[endIndex - index + 1]; 57 for (int i = 0; i < items.length; i++){ 58 items[i] = formats[index]; 59 index++; 60 } 61 62 return items; 63 } 64 65 package HRESULT Next(ULONG celt, FORMATETC *rgelt, ULONG *pceltFetched) { 66 /* Retrieves the next celt items in the enumeration sequence. 67 If there are fewer than the requested number of elements left in the sequence, 68 it retrieves the remaining elements. 69 The number of elements actually retrieved is returned through pceltFetched 70 (unless the caller passed in NULL for that parameter). 71 */ 72 73 if (rgelt is null) return COM.E_INVALIDARG; 74 if (pceltFetched is null && celt !is 1) return COM.E_INVALIDARG; 75 76 FORMATETC*[] nextItems = getNextItems(celt); 77 if (nextItems !is null) { 78 for (int i = 0; i < nextItems.length; i++) { 79 rgelt[i] = *nextItems[i]; 80 } 81 82 if (pceltFetched !is null) 83 *pceltFetched = cast(int)/*64bit*/nextItems.length; 84 85 if (nextItems.length is celt) return COM.S_OK; 86 87 } else { 88 if (pceltFetched !is null) 89 *pceltFetched = 0; 90 FORMATETC fInit; 91 COM.MoveMemory(rgelt, & fInit, FORMATETC.sizeof); 92 93 } 94 return COM.S_FALSE; 95 } 96 private HRESULT QueryInterface(REFCIID riid, void** ppvObject) { 97 98 if (riid is null || ppvObject is null) return COM.E_NOINTERFACE; 99 100 if (COM.IsEqualGUID(riid, &COM.IIDIUnknown)) { 101 *ppvObject = cast(void*)cast(IUnknown)iEnumFORMATETC; 102 AddRef(); 103 return COM.S_OK; 104 } 105 if (COM.IsEqualGUID(riid, &COM.IIDIEnumFORMATETC)) { 106 *ppvObject = cast(void*)cast(IEnumFORMATETC)iEnumFORMATETC; 107 AddRef(); 108 return COM.S_OK; 109 } 110 *ppvObject = null; 111 return COM.E_NOINTERFACE; 112 } 113 int Release() { 114 refCount--; 115 116 if (refCount is 0) { 117 disposeCOMInterfaces(); 118 COM.CoFreeUnusedLibraries(); 119 } 120 121 return refCount; 122 } 123 private int Reset() { 124 //Resets the enumeration sequence to the beginning. 125 index = 0; 126 return COM.S_OK; 127 } 128 void setFormats(FORMATETC*[] newFormats) { 129 formats = newFormats; 130 index = 0; 131 } 132 private int Skip(int celt) { 133 //Skips over the next specified number of elements in the enumeration sequence. 134 if (celt < 1 ) return COM.E_INVALIDARG; 135 136 index += celt; 137 if (index > (formats.length - 1)){ 138 index = cast(int)/*64bit*/formats.length - 1; 139 return COM.S_FALSE; 140 } 141 return COM.S_OK; 142 } 143 } 144 145 class _IEnumFORMATETCImpl : IEnumFORMATETC { 146 147 148 OleEnumFORMATETC parent; 149 this(OleEnumFORMATETC p) { parent = p; } 150 extern (Windows): 151 // interface of IUnknown 152 HRESULT QueryInterface(REFCIID riid, void ** ppvObject) { return parent.QueryInterface(riid, ppvObject); } 153 ULONG AddRef() { return parent.AddRef(); } 154 ULONG Release() { return parent.Release(); } 155 156 // interface of IEnumFORMATETC 157 HRESULT Next(ULONG celt, FORMATETC *rgelt, ULONG *pceltFetched) { 158 return parent.Next(celt, rgelt, pceltFetched); 159 } 160 HRESULT Skip(ULONG celt) { return parent.Skip(celt); } 161 HRESULT Reset() { return parent.Reset(); } 162 HRESULT Clone(IEnumFORMATETC * ppenum) { return COM.E_NOTIMPL;} 163 } 164 165