view dwt/dnd/OleEnumFORMATETC.d @ 213:36f5cb12e1a2

Update to SWT 3.4M7
author Frank Benoit <benoit@tionex.de>
date Sat, 17 May 2008 17:34:28 +0200
parents 18847a0560e9
children fd9c62a2998e
line wrap: on
line source

/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 * Port to the D programming language:
 *     Frank Benoit <benoit@tionex.de>
 *******************************************************************************/
module dwt.dnd.OleEnumFORMATETC;

import dwt.internal.ole.win32.COM;
import dwt.internal.ole.win32.OBJIDL;
import dwt.internal.ole.win32.extras;
import dwt.internal.win32.OS;

final class OleEnumFORMATETC {

    private _IEnumFORMATETCImpl iEnumFORMATETC;

    private int refCount;
    private int index;

    private FORMATETC*[] formats;

this() {

    createCOMInterfaces();

}
int AddRef() {
    refCount++;
    return refCount;
}
private void createCOMInterfaces() {
    // register each of the interfaces that this object implements
    iEnumFORMATETC = new _IEnumFORMATETCImpl( this );
}
private void disposeCOMInterfaces() {
    iEnumFORMATETC = null;
}
IEnumFORMATETC getAddress() {
    return iEnumFORMATETC;
}
private FORMATETC*[] getNextItems(int numItems){

    if (formats is null || numItems < 1) return null;

    int endIndex = index + numItems - 1;
    if (endIndex > (formats.length - 1)) endIndex = formats.length - 1;
    if (index > endIndex) return null;

    FORMATETC*[] items =  new FORMATETC*[endIndex - index + 1];
    for (int i = 0; i < items.length; i++){
        items[i] = formats[index];
        index++;
    }

    return items;
}

package HRESULT Next(ULONG celt, FORMATETC *rgelt, ULONG *pceltFetched) {
    /* Retrieves the next celt items in the enumeration sequence.
       If there are fewer than the requested number of elements left in the sequence,
       it retrieves the remaining elements.
       The number of elements actually retrieved is returned through pceltFetched
       (unless the caller passed in NULL for that parameter).
    */

    if (rgelt is null) return COM.E_INVALIDARG;
    if (pceltFetched is null && celt !is 1) return COM.E_INVALIDARG;

    FORMATETC*[] nextItems = getNextItems(celt);
    if (nextItems !is null) {
        for (int i = 0; i < nextItems.length; i++) {
            rgelt[i] = *nextItems[i];
        }

        if (pceltFetched !is null)
            *pceltFetched = nextItems.length;

        if (nextItems.length is celt) return COM.S_OK;

    } else {
        if (pceltFetched !is null)
            *pceltFetched = 0;
        COM.MoveMemory(rgelt, & FORMATETC.init, FORMATETC.sizeof);

    }
    return COM.S_FALSE;
}
private HRESULT QueryInterface(REFIID riid, void** ppvObject) {

    if (riid is null || ppvObject is null) return COM.E_NOINTERFACE;

    if (COM.IsEqualGUID(riid, &COM.IIDIUnknown)) {
        *ppvObject = cast(void*)cast(IUnknown)iEnumFORMATETC;
        AddRef();
        return COM.S_OK;
    }
    if (COM.IsEqualGUID(riid, &COM.IIDIEnumFORMATETC)) {
        *ppvObject = cast(void*)cast(IEnumFORMATETC)iEnumFORMATETC;
        AddRef();
        return COM.S_OK;
    }
    *ppvObject = null;
    return COM.E_NOINTERFACE;
}
int Release() {
    refCount--;

    if (refCount is 0) {
        disposeCOMInterfaces();
        COM.CoFreeUnusedLibraries();
    }

    return refCount;
}
private int Reset() {
    //Resets the enumeration sequence to the beginning.
    index = 0;
    return COM.S_OK;
}
void setFormats(FORMATETC*[] newFormats) {
    formats = newFormats;
    index = 0;
}
private int Skip(int celt) {
    //Skips over the next specified number of elements in the enumeration sequence.
    if (celt < 1 ) return COM.E_INVALIDARG;

    index += celt;
    if (index > (formats.length - 1)){
        index = formats.length - 1;
        return COM.S_FALSE;
    }
    return COM.S_OK;
}
}

class _IEnumFORMATETCImpl : IEnumFORMATETC {


    OleEnumFORMATETC    parent;
    this(OleEnumFORMATETC   p) { parent = p; }
extern (Windows):
    // interface of IUnknown
    HRESULT QueryInterface(REFIID riid, void ** ppvObject) { return parent.QueryInterface(riid, ppvObject); }
    ULONG AddRef()  { return parent.AddRef(); }
    ULONG Release() { return parent.Release(); }

    // interface of IEnumFORMATETC
    HRESULT Next(ULONG celt, FORMATETC *rgelt, ULONG *pceltFetched) {
        return parent.Next(celt, rgelt, pceltFetched);
    }
    HRESULT Skip(ULONG celt) { return parent.Skip(celt); }
    HRESULT Reset() { return parent.Reset(); }
    HRESULT Clone(IEnumFORMATETC * ppenum) { return COM.E_NOTIMPL;}
}