mirror of
https://github.com/glfw/glfw.git
synced 2024-12-02 06:47:10 +00:00
Win32: Implement extended drag & drop API
This commit is contained in:
parent
d2763ec2a1
commit
2933c00e54
@ -458,12 +458,12 @@ static GLFWbool initDragDrop()
|
|||||||
}
|
}
|
||||||
|
|
||||||
//_glfw.win32.dropTargetVtbl.QueryInterface = _glfwDropTarget_QueryInterface;
|
//_glfw.win32.dropTargetVtbl.QueryInterface = _glfwDropTarget_QueryInterface;
|
||||||
_glfw.win32.dropTargetVtbl.AddRef = (PFN_IDropTarget_AddRef)_glfwDropTarget_AddRef;
|
_glfw.win32.dropTargetVtbl.AddRef = _glfwDropTarget_AddRef;
|
||||||
_glfw.win32.dropTargetVtbl.Release = (PFN_IDropTarget_Release)_glfwDropTarget_Release;
|
_glfw.win32.dropTargetVtbl.Release = _glfwDropTarget_Release;
|
||||||
_glfw.win32.dropTargetVtbl.DragEnter = (PFN_IDropTarget_DragEnter)_glfwDropTarget_DragEnter;
|
_glfw.win32.dropTargetVtbl.DragEnter = _glfwDropTarget_DragEnter;
|
||||||
_glfw.win32.dropTargetVtbl.DragOver = (PFN_IDropTarget_DragOver)_glfwDropTarget_DragOver;
|
_glfw.win32.dropTargetVtbl.DragOver = _glfwDropTarget_DragOver;
|
||||||
_glfw.win32.dropTargetVtbl.DragLeave = (PFN_IDropTarget_DragLeave)_glfwDropTarget_DragLeave;
|
_glfw.win32.dropTargetVtbl.DragLeave = _glfwDropTarget_DragLeave;
|
||||||
_glfw.win32.dropTargetVtbl.Drop = (PFN_IDropTarget_Drop)_glfwDropTarget_Drop;
|
_glfw.win32.dropTargetVtbl.Drop = _glfwDropTarget_Drop;
|
||||||
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
@ -325,12 +325,6 @@ typedef HRESULT (WINAPI * PFN_OleInitialize)(LPVOID);
|
|||||||
typedef VOID (WINAPI * PFN_OleUninitialize)(VOID);
|
typedef VOID (WINAPI * PFN_OleUninitialize)(VOID);
|
||||||
typedef HRESULT (WINAPI * PFN_RegisterDragDrop)(HWND,LPDROPTARGET);
|
typedef HRESULT (WINAPI * PFN_RegisterDragDrop)(HWND,LPDROPTARGET);
|
||||||
typedef HRESULT (WINAPI * PFN_RevokeDragDrop)(HWND);
|
typedef HRESULT (WINAPI * PFN_RevokeDragDrop)(HWND);
|
||||||
typedef ULONG (STDMETHODCALLTYPE * PFN_IDropTarget_AddRef)(LPDROPTARGET);
|
|
||||||
typedef ULONG (STDMETHODCALLTYPE * PFN_IDropTarget_Release)(LPDROPTARGET);
|
|
||||||
typedef HRESULT (STDMETHODCALLTYPE * PFN_IDropTarget_DragEnter)(LPDROPTARGET,IDataObject*,DWORD,POINTL,DWORD*);
|
|
||||||
typedef HRESULT (STDMETHODCALLTYPE * PFN_IDropTarget_DragOver)(LPDROPTARGET,DWORD,POINTL,DWORD*);
|
|
||||||
typedef HRESULT (STDMETHODCALLTYPE * PFN_IDropTarget_DragLeave)(LPDROPTARGET);
|
|
||||||
typedef HRESULT (STDMETHODCALLTYPE * PFN_IDropTarget_Drop)(LPDROPTARGET,IDataObject*,DWORD,POINTL,DWORD*);
|
|
||||||
#define OleInitialize _glfw.win32.ole32.OleInitialize_
|
#define OleInitialize _glfw.win32.ole32.OleInitialize_
|
||||||
#define OleUninitialize _glfw.win32.ole32.OleUninitialize_
|
#define OleUninitialize _glfw.win32.ole32.OleUninitialize_
|
||||||
#define RegisterDragDrop _glfw.win32.ole32.RegisterDragDrop_
|
#define RegisterDragDrop _glfw.win32.ole32.RegisterDragDrop_
|
||||||
@ -428,12 +422,17 @@ typedef struct _GLFWlibraryWGL
|
|||||||
GLFWbool ARB_context_flush_control;
|
GLFWbool ARB_context_flush_control;
|
||||||
} _GLFWlibraryWGL;
|
} _GLFWlibraryWGL;
|
||||||
|
|
||||||
typedef struct _GLFWdropTarget
|
typedef struct _GLFWdroptarget
|
||||||
{
|
{
|
||||||
IDropTargetVtbl* lpVtbl;
|
IDropTargetVtbl* lpVtbl;
|
||||||
ULONG cRefCount;
|
ULONG cRefCount;
|
||||||
_GLFWwindow* window;
|
_GLFWwindow* window;
|
||||||
} _GLFWdropTarget;
|
int availableFormats;
|
||||||
|
int chosenFormat;
|
||||||
|
int availableActions;
|
||||||
|
int proposedAction;
|
||||||
|
int chosenAction;
|
||||||
|
} _GLFWdroptarget;
|
||||||
|
|
||||||
// Win32-specific per-window data
|
// Win32-specific per-window data
|
||||||
//
|
//
|
||||||
@ -460,7 +459,7 @@ typedef struct _GLFWwindowWin32
|
|||||||
// The last received high surrogate when decoding pairs of UTF-16 messages
|
// The last received high surrogate when decoding pairs of UTF-16 messages
|
||||||
WCHAR highSurrogate;
|
WCHAR highSurrogate;
|
||||||
|
|
||||||
_GLFWdropTarget dropTarget;
|
_GLFWdroptarget dropTarget;
|
||||||
} _GLFWwindowWin32;
|
} _GLFWwindowWin32;
|
||||||
|
|
||||||
// Win32-specific global data
|
// Win32-specific global data
|
||||||
@ -660,10 +659,10 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
|||||||
const _GLFWfbconfig* fbconfig);
|
const _GLFWfbconfig* fbconfig);
|
||||||
|
|
||||||
// IDropTarget vtable functions
|
// IDropTarget vtable functions
|
||||||
//HRESULT STDMETHODCALLTYPE _glfwDropTarget_QueryInterface(_GLFWdropTarget *This, REFIID riid, void **ppvObject);
|
//HRESULT STDMETHODCALLTYPE _glfwDropTarget_QueryInterface(IDropTarget *_This, REFIID riid, void **ppvObject);
|
||||||
ULONG STDMETHODCALLTYPE _glfwDropTarget_AddRef(_GLFWdropTarget *This);
|
ULONG STDMETHODCALLTYPE _glfwDropTarget_AddRef(IDropTarget *_This);
|
||||||
ULONG STDMETHODCALLTYPE _glfwDropTarget_Release(_GLFWdropTarget *This);
|
ULONG STDMETHODCALLTYPE _glfwDropTarget_Release(IDropTarget *_This);
|
||||||
HRESULT STDMETHODCALLTYPE _glfwDropTarget_DragEnter(_GLFWdropTarget *This, IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
|
HRESULT STDMETHODCALLTYPE _glfwDropTarget_DragEnter(IDropTarget *_This, IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
|
||||||
HRESULT STDMETHODCALLTYPE _glfwDropTarget_DragOver(_GLFWdropTarget *This, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
|
HRESULT STDMETHODCALLTYPE _glfwDropTarget_DragOver(IDropTarget *_This, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
|
||||||
HRESULT STDMETHODCALLTYPE _glfwDropTarget_DragLeave(_GLFWdropTarget *This);
|
HRESULT STDMETHODCALLTYPE _glfwDropTarget_DragLeave(IDropTarget *_This);
|
||||||
HRESULT STDMETHODCALLTYPE _glfwDropTarget_Drop(_GLFWdropTarget *This, IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
|
HRESULT STDMETHODCALLTYPE _glfwDropTarget_Drop(IDropTarget *_This, IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
|
||||||
|
@ -2472,8 +2472,9 @@ GLFWAPI HWND glfwGetWin32Window(GLFWwindow* handle)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// IDropTarget vtable functions
|
// IDropTarget vtable functions
|
||||||
HRESULT STDMETHODCALLTYPE _glfwDropTarget_QueryInterface(_GLFWdropTarget *This, REFIID riid, void **ppvObject)
|
HRESULT STDMETHODCALLTYPE _glfwDropTarget_QueryInterface(IDropTarget *_This, REFIID riid, void **ppvObject)
|
||||||
{
|
{
|
||||||
|
_GLFWdroptarget *This = (_GLFWdroptarget*) _This;
|
||||||
printf("DropTarget_QueryInterface\n");
|
printf("DropTarget_QueryInterface\n");
|
||||||
if(!ppvObject)
|
if(!ppvObject)
|
||||||
return E_POINTER;
|
return E_POINTER;
|
||||||
@ -2489,93 +2490,205 @@ HRESULT STDMETHODCALLTYPE _glfwDropTarget_QueryInterface(_GLFWdropTarget *This,
|
|||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
// IDropTarget vtable functions
|
// IDropTarget utility functions
|
||||||
ULONG STDMETHODCALLTYPE _glfwDropTarget_AddRef(_GLFWdropTarget *This)
|
static void getActions(_GLFWdroptarget *This, DWORD dwEffect)
|
||||||
{
|
{
|
||||||
|
This->availableActions = GLFW_DND_NONE;
|
||||||
|
This->proposedAction = GLFW_DND_NONE;
|
||||||
|
if ((dwEffect & DROPEFFECT_COPY) == DROPEFFECT_COPY)
|
||||||
|
{
|
||||||
|
This->availableActions |= GLFW_DND_COPY;
|
||||||
|
if (!This->proposedAction)
|
||||||
|
This->proposedAction = GLFW_DND_COPY;
|
||||||
|
}
|
||||||
|
if ((dwEffect & DROPEFFECT_LINK) == DROPEFFECT_LINK)
|
||||||
|
{
|
||||||
|
This->availableActions |= GLFW_DND_LINK;
|
||||||
|
if (!This->proposedAction)
|
||||||
|
This->proposedAction = GLFW_DND_LINK;
|
||||||
|
}
|
||||||
|
if ((dwEffect & DROPEFFECT_MOVE) == DROPEFFECT_MOVE)
|
||||||
|
{
|
||||||
|
This->availableActions |= GLFW_DND_MOVE;
|
||||||
|
if (!This->proposedAction)
|
||||||
|
This->proposedAction = GLFW_DND_MOVE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setActions(_GLFWdroptarget *This, DWORD *pdwEffect)
|
||||||
|
{
|
||||||
|
if((This->chosenAction & GLFW_DND_COPY) == GLFW_DND_COPY)
|
||||||
|
*pdwEffect = DROPEFFECT_COPY;
|
||||||
|
else if((This->chosenAction & GLFW_DND_LINK) == GLFW_DND_LINK)
|
||||||
|
*pdwEffect = DROPEFFECT_LINK;
|
||||||
|
else if((This->chosenAction & GLFW_DND_MOVE) == GLFW_DND_MOVE)
|
||||||
|
*pdwEffect = DROPEFFECT_MOVE;
|
||||||
|
else
|
||||||
|
*pdwEffect = DROPEFFECT_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static FORMATETC *withClipFormat(FORMATETC *pFmt, CLIPFORMAT cf)
|
||||||
|
{
|
||||||
|
pFmt->cfFormat = cf;
|
||||||
|
return pFmt;
|
||||||
|
}
|
||||||
|
|
||||||
|
// IDropTarget vtable functions
|
||||||
|
ULONG STDMETHODCALLTYPE _glfwDropTarget_AddRef(IDropTarget *_This)
|
||||||
|
{
|
||||||
|
_GLFWdroptarget *This = (_GLFWdroptarget*) _This;
|
||||||
printf("DropTarget_AddRef\n");
|
printf("DropTarget_AddRef\n");
|
||||||
return ++This->cRefCount;
|
return ++This->cRefCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG STDMETHODCALLTYPE _glfwDropTarget_Release(_GLFWdropTarget *This)
|
ULONG STDMETHODCALLTYPE _glfwDropTarget_Release(IDropTarget *_This)
|
||||||
{
|
{
|
||||||
|
_GLFWdroptarget *This = (_GLFWdroptarget*) _This;
|
||||||
printf("DropTarget_Release\n");
|
printf("DropTarget_Release\n");
|
||||||
return --This->cRefCount;
|
return --This->cRefCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE _glfwDropTarget_DragEnter(_GLFWdropTarget *This, IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
|
HRESULT STDMETHODCALLTYPE _glfwDropTarget_DragEnter(IDropTarget *_This, IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
|
||||||
{
|
{
|
||||||
FORMATETC fmt = { CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
|
_GLFWdroptarget *This = (_GLFWdroptarget*) _This;
|
||||||
|
FORMATETC fmt = { 0, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
|
||||||
|
STGMEDIUM stgmed;
|
||||||
|
|
||||||
printf("DropTarget_DragEnter\n");
|
printf("DropTarget_DragEnter\n");
|
||||||
if(SUCCEEDED(IDataObject_QueryGetData(pDataObj, &fmt)))
|
|
||||||
|
getActions(This, *pdwEffect);
|
||||||
|
|
||||||
|
This->availableFormats = GLFW_DND_NONE;
|
||||||
|
|
||||||
|
if (SUCCEEDED(IDataObject_QueryGetData(pDataObj, withClipFormat(&fmt, CF_HDROP)))
|
||||||
|
&& SUCCEEDED(IDataObject_GetData(pDataObj, &fmt, &stgmed)))
|
||||||
{
|
{
|
||||||
printf("QueryGetData OK\n");
|
This->availableFormats |= GLFW_DND_PATHS;
|
||||||
*pdwEffect = DROPEFFECT_COPY;
|
printf("paths\n");
|
||||||
}
|
}
|
||||||
else
|
if (SUCCEEDED(IDataObject_QueryGetData(pDataObj, withClipFormat(&fmt, CF_TEXT)))
|
||||||
*pdwEffect = DROPEFFECT_NONE;
|
&& SUCCEEDED(IDataObject_GetData(pDataObj, &fmt, &stgmed)))
|
||||||
|
{
|
||||||
|
This->availableFormats |= GLFW_DND_TEXT;
|
||||||
|
printf("text\n");
|
||||||
|
ReleaseStgMedium(&stgmed);
|
||||||
|
}
|
||||||
|
|
||||||
|
This->window->dndDragging = GLFW_TRUE;
|
||||||
|
|
||||||
|
This->chosenFormat = This->availableFormats;
|
||||||
|
This->chosenAction = This->proposedAction;
|
||||||
|
_glfwInputDrag(This->window, GLFW_DND_ENTER, pt.x, pt.y,
|
||||||
|
This->availableFormats,
|
||||||
|
&This->chosenFormat,
|
||||||
|
This->availableActions,
|
||||||
|
&This->chosenAction);
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE _glfwDropTarget_DragOver(_GLFWdropTarget *This, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
|
HRESULT STDMETHODCALLTYPE _glfwDropTarget_DragOver(IDropTarget *_This, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
|
||||||
{
|
{
|
||||||
|
_GLFWdroptarget *This = (_GLFWdroptarget*) _This;
|
||||||
printf("DropTarget_DragOver\n");
|
printf("DropTarget_DragOver\n");
|
||||||
*pdwEffect = DROPEFFECT_COPY;
|
|
||||||
|
getActions(This, *pdwEffect);
|
||||||
|
|
||||||
|
_glfwInputCursorPos(This->window, pt.x, pt.y);
|
||||||
|
|
||||||
|
This->chosenAction = This->proposedAction;
|
||||||
|
_glfwInputDrag(This->window, GLFW_DND_DRAG, pt.x, pt.y,
|
||||||
|
This->availableFormats,
|
||||||
|
&This->chosenFormat,
|
||||||
|
This->availableActions,
|
||||||
|
&This->chosenAction);
|
||||||
|
|
||||||
|
setActions(This, pdwEffect);
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE _glfwDropTarget_DragLeave(_GLFWdropTarget *This)
|
HRESULT STDMETHODCALLTYPE _glfwDropTarget_DragLeave(IDropTarget *_This)
|
||||||
{
|
{
|
||||||
|
_GLFWdroptarget *This = (_GLFWdroptarget*) _This;
|
||||||
printf("DropTarget_DragLeave\n");
|
printf("DropTarget_DragLeave\n");
|
||||||
|
|
||||||
|
This->window->dndDragging = GLFW_FALSE;
|
||||||
|
|
||||||
|
This->chosenFormat =
|
||||||
|
This->availableFormats = GLFW_DND_NONE;
|
||||||
|
This->chosenAction =
|
||||||
|
This->proposedAction =
|
||||||
|
This->availableActions = GLFW_DND_NONE;
|
||||||
|
_glfwInputDrag(This->window, GLFW_DND_LEAVE, 0.0, 0.0,
|
||||||
|
This->availableFormats,
|
||||||
|
&This->chosenFormat,
|
||||||
|
This->availableActions,
|
||||||
|
&This->chosenAction);
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE _glfwDropTarget_Drop(_GLFWdropTarget *This, IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
|
HRESULT STDMETHODCALLTYPE _glfwDropTarget_Drop(IDropTarget *_This, IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
|
||||||
{
|
{
|
||||||
FORMATETC fmt = { CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
|
_GLFWdroptarget *This = (_GLFWdroptarget*) _This;
|
||||||
|
FORMATETC fmt = { 0, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
|
||||||
STGMEDIUM stgmed;
|
STGMEDIUM stgmed;
|
||||||
|
|
||||||
printf("DropTarget_Drop\n");
|
printf("DropTarget_Drop\n");
|
||||||
*pdwEffect = DROPEFFECT_NONE;
|
*pdwEffect = DROPEFFECT_NONE;
|
||||||
|
|
||||||
if(SUCCEEDED(IDataObject_QueryGetData(pDataObj, &fmt)))
|
This->window->dndDragging = GLFW_FALSE;
|
||||||
{
|
|
||||||
printf("QueryGetData OK\n");
|
|
||||||
if(SUCCEEDED(IDataObject_GetData(pDataObj, &fmt, &stgmed)))
|
|
||||||
{
|
|
||||||
HDROP drop = (HDROP) GlobalLock(stgmed.hGlobal);
|
|
||||||
const int count = DragQueryFileW(drop, 0xffffffff, NULL, 0);
|
|
||||||
char** paths = _glfw_calloc(count, sizeof(char*));
|
|
||||||
int i;
|
|
||||||
|
|
||||||
printf("GetData OK\n");
|
if ((This->chosenFormat & GLFW_DND_PATHS) == GLFW_DND_PATHS
|
||||||
_glfwInputCursorPos(This->window, pt.x, pt.y);
|
&& SUCCEEDED(IDataObject_GetData(pDataObj, withClipFormat(&fmt, CF_HDROP), &stgmed)))
|
||||||
|
{
|
||||||
|
HDROP drop = (HDROP) GlobalLock(stgmed.hGlobal);
|
||||||
|
const int count = DragQueryFileW(drop, 0xffffffff, NULL, 0);
|
||||||
|
char** paths = _glfw_calloc(count, sizeof(char*));
|
||||||
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < count; ++i)
|
printf("GetData OK (paths)\n");
|
||||||
{
|
_glfwInputCursorPos(This->window, pt.x, pt.y);
|
||||||
const UINT length = DragQueryFileW(drop, i, NULL, 0);
|
|
||||||
WCHAR* buffer = _glfw_calloc((size_t) length + 1, sizeof(WCHAR));
|
|
||||||
|
|
||||||
DragQueryFileW(drop, i, buffer, length + 1);
|
for (i = 0; i < count; ++i)
|
||||||
paths[i] = _glfwCreateUTF8FromWideStringWin32(buffer);
|
{
|
||||||
|
const UINT length = DragQueryFileW(drop, i, NULL, 0);
|
||||||
|
WCHAR* buffer = _glfw_calloc((size_t) length + 1, sizeof(WCHAR));
|
||||||
|
|
||||||
_glfw_free(buffer);
|
DragQueryFileW(drop, i, buffer, length + 1);
|
||||||
}
|
paths[i] = _glfwCreateUTF8FromWideStringWin32(buffer);
|
||||||
|
|
||||||
_glfwInputDrop(This->window, count, (const char**) paths);
|
_glfw_free(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < count; ++i)
|
_glfwInputDrop(This->window, count, (const char**) paths);
|
||||||
_glfw_free(paths[i]);
|
|
||||||
_glfw_free(paths);
|
|
||||||
|
|
||||||
GlobalUnlock(stgmed.hGlobal);
|
_glfwInputDropEx(This->window, GLFW_DND_PATHS, count, paths,
|
||||||
ReleaseStgMedium(&stgmed);
|
&This->chosenAction);
|
||||||
|
|
||||||
*pdwEffect = DROPEFFECT_COPY;
|
for (i = 0; i < count; ++i)
|
||||||
}
|
_glfw_free(paths[i]);
|
||||||
}
|
_glfw_free(paths);
|
||||||
|
}
|
||||||
|
else if ((This->chosenFormat & GLFW_DND_TEXT) == GLFW_DND_TEXT
|
||||||
|
&& SUCCEEDED(IDataObject_GetData(pDataObj, withClipFormat(&fmt, CF_TEXT), &stgmed)))
|
||||||
|
{
|
||||||
|
char *text = (char*) GlobalLock(stgmed.hGlobal);
|
||||||
|
|
||||||
|
printf("GetData OK (text)\n");
|
||||||
|
_glfwInputCursorPos(This->window, pt.x, pt.y);
|
||||||
|
|
||||||
|
_glfwInputDropEx(This->window, GLFW_DND_TEXT, -1, text,
|
||||||
|
&This->chosenAction);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return S_OK;
|
||||||
|
|
||||||
|
GlobalUnlock(stgmed.hGlobal);
|
||||||
|
ReleaseStgMedium(&stgmed);
|
||||||
|
|
||||||
|
setActions(This, pdwEffect);
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user