efl/legacy/ecore/src/lib/ecore_win32/ecore_win32_dnd.c

222 lines
6.1 KiB
C
Executable File

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <windows.h>
#include "Ecore_Win32.h"
#include "ecore_win32_private.h"
/*============================================================================*
* Local *
*============================================================================*/
/**
* @cond LOCAL
*/
static int _ecore_win32_dnd_init_count = 0;
static HANDLE DataToHandle(const char *data, int size)
{
char *ptr;
ptr = (char *)GlobalAlloc(GMEM_FIXED, size);
memcpy(ptr, data, size);
return ptr;
}
/**
* @endcond
*/
/*============================================================================*
* Global *
*============================================================================*/
/*============================================================================*
* API *
*============================================================================*/
/**
* @addtogroup Ecore_Win32_Group Ecore_Win32 library
*
* @{
*/
/**
* @brief Initialize the Ecore_Win32 Drag and Drop module.
*
* @return 1 or greater on success, 0 on error.
*
* This function initialize the Drag and Drop module. It returns 0 on
* failure, otherwise it returns the number of times it has already
* been called.
*
* When the Drag and Drop module is not used anymore, call
* ecore_win32_dnd_shutdown() to shut down the module.
*/
EAPI int
ecore_win32_dnd_init()
{
if (_ecore_win32_dnd_init_count > 0)
{
_ecore_win32_dnd_init_count++;
return _ecore_win32_dnd_init_count;
}
if (OleInitialize(NULL) != S_OK)
return 0;
_ecore_win32_dnd_init_count++;
return _ecore_win32_dnd_init_count;
}
/**
* @brief Shut down the Ecore_Win32 Drag and Drop module.
*
* @return 0 when the module is completely shut down, 1 or
* greater otherwise.
*
* This function shuts down the Drag and Drop module. It returns 0 when it has
* been called the same number of times than ecore_win32_dnd_init(). In that case
* it shut down the module.
*/
EAPI int
ecore_win32_dnd_shutdown()
{
_ecore_win32_dnd_init_count--;
if (_ecore_win32_dnd_init_count > 0) return _ecore_win32_dnd_init_count;
OleUninitialize();
if (_ecore_win32_dnd_init_count < 0) _ecore_win32_dnd_init_count = 0;
return _ecore_win32_dnd_init_count;
}
/**
* @brief Begin a DnD operation.
*
* @param data The name pf the Drag operation.
* @param size The size of the name.
* @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
*
* This function start a Drag operation with the name @p data. If
* @p data is @c NULL, @c EINA_FALSE is returned. if @p size is less than
* @c 0, it is set to the length (as strlen()) of @p data. On success the
* function returns @c EINA_TRUE, otherwise it returns @c EINA_FALSE.
*/
EAPI Eina_Bool
ecore_win32_dnd_begin(const char *data,
int size)
{
IDataObject *pDataObject = NULL;
IDropSource *pDropSource = NULL;
FORMATETC fmtetc = { CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
STGMEDIUM stgmed = { TYMED_HGLOBAL, { 0 }, 0 };
Eina_Bool res = EINA_FALSE;
if (!data)
return EINA_FALSE;
if (size < 0)
size = strlen(data) + 1;
stgmed.hGlobal = DataToHandle(data, size);
// create the data object
pDataObject = (IDataObject *)_ecore_win32_dnd_data_object_new((void *)&fmtetc,
(void *)&stgmed,
1);
pDropSource = (IDropSource *)_ecore_win32_dnd_drop_source_new();
if (pDataObject && pDropSource)
{
DWORD dwResult;
DWORD dwEffect = DROPEFFECT_COPY;
// do the drag-drop!
dwResult = DoDragDrop(pDataObject, pDropSource, DROPEFFECT_COPY, &dwEffect);
// finished. Check the return values to see if we need to do anything else
if (dwResult == DRAGDROP_S_DROP)
{
//printf(">>> \"%s\" Dropped <<<\n", str);
if(dwEffect == DROPEFFECT_MOVE)
{
// remove the data we just dropped from active document
}
}
//else if (dwResult == DRAGDROP_S_CANCEL)
// printf("DND cancelled\n");
//else
// printf("DND error\n");
res = EINA_TRUE;
}
_ecore_win32_dnd_data_object_free(pDataObject);
_ecore_win32_dnd_drop_source_free(pDropSource);
// cleanup
ReleaseStgMedium(&stgmed);
return res;
}
/**
* @brief Register a Drop operation.
*
* @param window The destination of the Drop operation.
* @param callback The callback called when the Drop operation
* finishes.
* @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
*
* This function register a Drop operation on @p window. Once the Drop
* operation finishes, @p callback is called. If @p window is @c NULL,
* the function returns @c EINA_FALSE. On success, it returns @c EINA_TRUE,
* otherwise it returns @c EINA_FALSE.
*/
EAPI Eina_Bool
ecore_win32_dnd_register_drop_target(Ecore_Win32_Window *window,
Ecore_Win32_Dnd_DropTarget_Callback callback)
{
Ecore_Win32_Window *wnd = (Ecore_Win32_Window *)window;
if (!window)
return EINA_FALSE;
wnd->dnd_drop_target = _ecore_win32_dnd_register_drop_window(wnd->window,
callback,
(void *)wnd);
return wnd->dnd_drop_target ? EINA_TRUE : EINA_FALSE;
}
/**
* @brief Unregister a Drop operation.
*
* @param window The destination of the Drop operation.
*
* This function unregister a Drop operation on @p window. If
* @p window is @c NULL, the function does nothing.
*/
EAPI void
ecore_win32_dnd_unregister_drop_target(Ecore_Win32_Window *window)
{
Ecore_Win32_Window *wnd = (Ecore_Win32_Window *)window;
if (!window)
return;
if (wnd->dnd_drop_target)
_ecore_win32_dnd_unregister_drop_window(wnd->window, wnd->dnd_drop_target);
}
/**
* @}
*/