HRESULT STDMETHODCALLTYPE DataObjectImpl::GetData(FORMATETC *pformatetcIn, STGMEDIUM *pmedium)
{
    if (!pformatetcIn) return E_INVALIDARG;
    if (!pmedium) return E_POINTER;

    unsigned count = m_contents.get_count();

    for (unsigned i = 0; i < count; i++)
    {
        StoredDataInfo *pInfo = m_contents[i];

        if (pInfo->formatEtc.cfFormat == pformatetcIn->cfFormat &&
            pInfo->formatEtc.lindex == pformatetcIn->lindex &&
            (pInfo->formatEtc.tymed & pformatetcIn->tymed)) 
        {
            // If medium is NULL, delay-rendering will be used.
            if (pInfo->pMedium) {
                DuplicateMedium(pInfo->formatEtc.cfFormat, pInfo->pMedium, pmedium);
            } else {
                // Check if the left button is down.
                bool isLeftButtonDown = (GetKeyState(VK_LBUTTON) & 0x8000) != 0;
                bool waitForData = false;

                if (pInfo->isInDelayRendering) 
                {
                    // Make sure the left button is up. Sometimes the drop target, like
                    // Shell, might be too aggresive in calling GetData when the left
                    // button is not released.
                    if (isLeftButtonDown) return DV_E_FORMATETC;

                    // In async mode, we do not want to start waiting for the data before
                    // the async operation is started. This is because we want to postpone
                    // until Shell kicks off a background thread to do the work so that
                    // we do not block the UI thread.
                    if (!m_isInAsyncMode || m_isAsyncOperationStarted)
                        waitForData = true;
                } else {
                    // If the left button is up and the target has not requested the data
                    // yet, it probably means that the target does not support delay-
                    // rendering. So instead, we wait for the data.
                    if (isLeftButtonDown) {
                        pInfo->isInDelayRendering = true;
                        memset(pmedium, 0, sizeof(STGMEDIUM));
                    } else {
                        waitForData = true;
                    }
                }

                if (!waitForData) return DV_E_FORMATETC;

                // The stored data should have been updated with the final version.
                // So we just need to call this function again to retrieve it.
                return GetData(pformatetcIn, pmedium);
            }
            return S_OK;
        }
    }

    return DV_E_FORMATETC;
}
Ejemplo n.º 2
0
HRESULT DataObjectWin::SetData(FORMATETC* pFormatEtc,
                               STGMEDIUM* pMedium,
                               BOOL fRelease) {

	RemoveData(*pFormatEtc);

	STGMEDIUM* local_medium = new STGMEDIUM;
	if (fRelease) {
		*local_medium = *pMedium;
	}
	else {
		DuplicateMedium(pFormatEtc->cfFormat, pMedium, local_medium);
	}

	StoredDataInfo* info =
		new StoredDataInfo(*pFormatEtc, local_medium);
	info->medium->tymed = pFormatEtc->tymed;
	info->owns_medium = !!fRelease;
	// Make newly added data appear first.
	// TODO(dcheng): Make various setters agree whether elements should be
	// prioritized from front to back or back to front.
	contents_.insert(contents_.begin(), info);
	return S_OK;
  //return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE DataObjectImpl::SetData(FORMATETC *pformatetc, STGMEDIUM *pmedium, BOOL fRelease)
{
    // Remove data of the same type first
    if (!pformatetc->ptd)
    {
        unsigned count = m_contents.get_count();
        for (unsigned i = 0; i < count; i++)
        {
            StoredDataInfo* ptr = m_contents[i];
            if (pformatetc->ptd == NULL && 
                pformatetc->cfFormat == ptr->formatEtc.cfFormat &&
                pformatetc->dwAspect == ptr->formatEtc.dwAspect &&
                pformatetc->lindex == ptr->formatEtc.lindex &&
                pformatetc->tymed == ptr->formatEtc.tymed)
            {
                delete ptr;
                m_contents.remove_by_idx(i);
                break;
            }
        }
    }

    STGMEDIUM *pLocalMedium = new STGMEDIUM;
    if (fRelease)
    {
        *pLocalMedium = *pmedium;
    }
    else
    {
        DuplicateMedium(pformatetc->cfFormat, pmedium, pLocalMedium);
    }

    StoredDataInfo *pInfo = new StoredDataInfo(pformatetc->cfFormat, pLocalMedium);
    pInfo->pMedium->tymed = pformatetc->tymed;
    pInfo->isManaged = !!fRelease;
    m_contents.add_item(pInfo);
    return S_OK;
}
    HRESULT DataObjectImpl::SetData(FORMATETC* format_etc, STGMEDIUM* medium,
        BOOL should_release)
    {
        RemoveData(*format_etc);

        STGMEDIUM* local_medium = new STGMEDIUM;
        if(should_release)
        {
            *local_medium = *medium;
        }
        else
        {
            DuplicateMedium(format_etc->cfFormat, medium, local_medium);
        }

        DataObjectImpl::StoredDataInfo* info =
            new DataObjectImpl::StoredDataInfo(format_etc->cfFormat, local_medium);
        info->medium->tymed = format_etc->tymed;
        info->owns_medium = !!should_release;
        // Make newly added data appear first.
        contents_.insert(contents_.begin(), info);

        return S_OK;
    }
    HRESULT DataObjectImpl::GetData(FORMATETC* format_etc, STGMEDIUM* medium)
    {
        StoredData::iterator iter = contents_.begin();
        while(iter != contents_.end())
        {
            if((*iter)->format_etc.cfFormat==format_etc->cfFormat &&
                (*iter)->format_etc.lindex==format_etc->lindex &&
                ((*iter)->format_etc.tymed&format_etc->tymed))
            {
                // If medium is NULL, delay-rendering will be used.
                if((*iter)->medium)
                {
                    DuplicateMedium((*iter)->format_etc.cfFormat, (*iter)->medium, medium);
                }
                else
                {
                    // Check if the left button is down.
                    bool is_left_button_down = (GetKeyState(VK_LBUTTON) & 0x8000) != 0;

                    bool wait_for_data = false;
                    if((*iter)->in_delay_rendering)
                    {
                        // Make sure the left button is up. Sometimes the drop target, like
                        // Shell, might be too aggresive in calling GetData when the left
                        // button is not released.
                        if(is_left_button_down)
                        {
                            return DV_E_FORMATETC;
                        }

                        wait_for_data = true;
                    }
                    else
                    {
                        // If the left button is up and the target has not requested the data
                        // yet, it probably means that the target does not support delay-
                        // rendering. So instead, we wait for the data.
                        if(is_left_button_down)
                        {
                            (*iter)->in_delay_rendering = true;
                            memset(medium, 0, sizeof(STGMEDIUM));
                        }
                        else
                        {
                            wait_for_data = true;
                        }
                    }

                    if(!wait_for_data)
                    {
                        return DV_E_FORMATETC;
                    }

                    // The stored data should have been updated with the final version.
                    // So we just need to call this function again to retrieve it.
                    return GetData(format_etc, medium);
                }
                return S_OK;
            }
            ++iter;
        }

        return DV_E_FORMATETC;
    }