forked from Mirrors/wine-wine
Implemented the OLE Drag and Drop target registration mechanism and
the DoDragDrop loop to perform the DnD operation.oldstable
parent
197a8e163e
commit
3f7ad7aa98
|
@ -198,7 +198,7 @@ static char **OBM_Icons_Data[OIC_LAST-OIC_FIRST+1] =
|
|||
#define OCR_BASE1 (OCR_BASE0 + OCR_LAST0 - OCR_FIRST0 + 1)
|
||||
|
||||
#define OCR_FIRST2 OCR_SIZE
|
||||
#define OCR_LAST2 OCR_SIZENS
|
||||
#define OCR_LAST2 OCR_SIZEALL
|
||||
#define OCR_BASE2 (OCR_BASE1 + OCR_LAST1 - OCR_FIRST1 + 1)
|
||||
|
||||
#define OCR_FIRST3 OCR_NO
|
||||
|
@ -229,8 +229,8 @@ static char **OBM_Cursors_Data[NB_CURSORS] =
|
|||
ocr_sizenesw, /* OCR_SIZENESW */
|
||||
ocr_sizewe, /* OCR_SIZEWE */
|
||||
ocr_sizens, /* OCR_SIZENS */
|
||||
ocr_size, /* OCR_SIZEALL */ /* Re-used the same one as OCR_SIZE for now */
|
||||
#if 0
|
||||
ocr_sizeall, /* OCR_SIZEALL */
|
||||
ocr_icocur /* OCR_ICOCUR */
|
||||
#endif
|
||||
ocr_no, /* OCR_NO */
|
||||
|
|
|
@ -5,13 +5,9 @@
|
|||
#ifndef __WINE_OLE2_H
|
||||
#define __WINE_OLE2_H
|
||||
|
||||
#include "oleidl.h"
|
||||
#include "wintypes.h"
|
||||
|
||||
/* to be implemented */
|
||||
/* FIXME: this should be defined somewhere in oleidl.h instead, should it be repeated here ? */
|
||||
typedef LPVOID LPDROPTARGET;
|
||||
|
||||
|
||||
/* OLE version */
|
||||
#define rmm 23
|
||||
#define rup 639
|
||||
|
@ -27,11 +23,23 @@ typedef struct tagOleMenuGroupWidths *LPOLEMENUGROUPWIDTHS32;
|
|||
|
||||
typedef HGLOBAL32 HOLEMENU32;
|
||||
|
||||
HRESULT WINAPI RegisterDragDrop16(HWND16,LPVOID);
|
||||
HRESULT WINAPI RegisterDragDrop32(HWND32,LPVOID);
|
||||
/*
|
||||
* API declarations
|
||||
*/
|
||||
HRESULT WINAPI RegisterDragDrop16(HWND16,LPDROPTARGET);
|
||||
HRESULT WINAPI RegisterDragDrop32(HWND32,LPDROPTARGET);
|
||||
#define RegisterDragDrop WINELIB_NAME(RegisterDragDrop)
|
||||
HRESULT WINAPI RevokeDragDrop16(HWND16);
|
||||
HRESULT WINAPI RevokeDragDrop32(HWND32);
|
||||
#define RevokeDragDrop WINELIB_NAME(RevokeDragDrop)
|
||||
HRESULT WINAPI DoDragDrop16(LPDATAOBJECT,
|
||||
LPDROPSOURCE,
|
||||
DWORD,
|
||||
DWORD*);
|
||||
HRESULT WINAPI DoDragDrop32(LPDATAOBJECT,
|
||||
LPDROPSOURCE,
|
||||
DWORD,
|
||||
DWORD*);
|
||||
#define DoDragDrop WINELIB_NAME(DoDragDrop)
|
||||
|
||||
#endif /* __WINE_OLE2_H */
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
#ifndef __WINE_OLEIDL_H
|
||||
#define __WINE_OLEIDL_H
|
||||
|
||||
|
||||
#include "wine/obj_base.h"
|
||||
|
||||
/* the following depend only on obj_base.h */
|
||||
#include "wine/obj_storage.h"
|
||||
|
||||
/* the following depend on obj_storage.h */
|
||||
#include "wine/obj_moniker.h"
|
||||
|
||||
/* the following depend on obj_moniker */
|
||||
#include "wine/obj_dataobject.h"
|
||||
|
||||
/* the following depend on obj_dataobject.h */
|
||||
#include "wine/obj_dragdrop.h"
|
||||
|
||||
|
||||
#endif /* __WINE_OLEIDL_H */
|
||||
|
|
@ -50,7 +50,5 @@ DEFINE_GUID (IID_IDockingWindowFrame, 0x47D2657AL, 0x7B27, 0x11D0, 0x8C, 0xA9, 0
|
|||
DEFINE_GUID (IID_MyComputer, 0x20D04FE0L, 0x3AEA, 0x1069, 0xA2, 0xD8, 0x08, 0x00, 0x2B, 0x30, 0x30, 0x9D);
|
||||
DEFINE_SHLGUID(IID_IEnumOLEVERB, 0x00000104L, 0, 0);
|
||||
DEFINE_SHLGUID(IID_IViewObject, 0x0000010DL, 0, 0);
|
||||
DEFINE_SHLGUID(IID_IDropSource, 0x00000121L, 0, 0);
|
||||
DEFINE_SHLGUID(IID_IDropTarget, 0x00000122L, 0, 0);
|
||||
|
||||
#endif /* __WINE_SHLGUID_H */
|
||||
|
|
|
@ -389,13 +389,6 @@ typedef enum tagSHCONTF
|
|||
SHCONTF_INCLUDEHIDDEN = 128 /* for hidden/system objects */
|
||||
} SHCONTF;
|
||||
|
||||
/* from oleidl.h */
|
||||
#define DROPEFFECT_NONE 0
|
||||
#define DROPEFFECT_COPY 1
|
||||
#define DROPEFFECT_MOVE 2
|
||||
#define DROPEFFECT_LINK 4
|
||||
#define DROPEFFECT_SCROLL 0x80000000
|
||||
|
||||
/* IShellFolder::GetAttributesOf flags */
|
||||
#define SFGAO_CANCOPY DROPEFFECT_COPY /* Objects can be copied */
|
||||
#define SFGAO_CANMOVE DROPEFFECT_MOVE /* Objects can be moved */
|
||||
|
|
|
@ -28,4 +28,15 @@
|
|||
|
||||
#pragma pack(4)
|
||||
|
||||
|
||||
/*
|
||||
* POINTL structure. Used in some OLE calls.
|
||||
*/
|
||||
typedef struct _POINTL
|
||||
{
|
||||
LONG x;
|
||||
LONG y;
|
||||
} POINTL;
|
||||
|
||||
|
||||
#endif /* __INCLUDE_WINDEF_H */
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Defines the COM interfaces and APIs related to OLE Drag and Drop.
|
||||
*
|
||||
* Depends on 'obj_base.h'.
|
||||
*/
|
||||
|
||||
#ifndef __WINE_WINE_OBJ_DRAGDROP_H
|
||||
#define __WINE_WINE_OBJ_DRAGDROP_H
|
||||
|
||||
#include "winnt.h"
|
||||
#include "windef.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* Predeclare the interfaces
|
||||
*/
|
||||
DEFINE_OLEGUID(IID_IDropSource, 0x00000121L, 0, 0);
|
||||
typedef struct IDropSource IDropSource,*LPDROPSOURCE;
|
||||
|
||||
DEFINE_OLEGUID(IID_IDropTarget, 0x00000122L, 0, 0);
|
||||
typedef struct IDropTarget IDropTarget,*LPDROPTARGET;
|
||||
|
||||
/*****************************************************************************
|
||||
* DROPEFFECT enumeration
|
||||
*/
|
||||
#define DROPEFFECT_NONE 0
|
||||
#define DROPEFFECT_COPY 1
|
||||
#define DROPEFFECT_MOVE 2
|
||||
#define DROPEFFECT_LINK 4
|
||||
#define DROPEFFECT_SCROLL 0x80000000
|
||||
|
||||
/*****************************************************************************
|
||||
* IDropSource interface
|
||||
*/
|
||||
#define ICOM_INTERFACE IDropSource
|
||||
ICOM_BEGIN(IDropSource,IUnknown)
|
||||
ICOM_METHOD2(HRESULT, QueryContinueDrag, BOOL32, fEscapePressed, DWORD, grfKeyState);
|
||||
ICOM_METHOD1(HRESULT, GiveFeedback, DWORD, dwEffect);
|
||||
ICOM_END(IDropSource)
|
||||
#undef ICOM_INTERFACE
|
||||
|
||||
#if !defined(__cplusplus) || defined(CINTERFACE)
|
||||
/*** IUnknown methods ***/
|
||||
#define IDropSource_QueryInterface(p,a,b) ICOM_ICALL2(IUnknown,QueryInterface,p,a,b)
|
||||
#define IDropSource_AddRef(p) ICOM_ICALL (IUnknown,AddRef,p)
|
||||
#define IDropSource_Release(p) ICOM_ICALL (IUnknown,Release,p)
|
||||
/*** IDropTarget methods ***/
|
||||
#define IDropSource_QueryContinueDrag(p,a,b) ICOM_CALL2(QueryContinueDrag,p,a,b)
|
||||
#define IDropSource_GiveFeedback(p,a) ICOM_CALL1(GiveFeedback,p,a)
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
* IDropTarget interface
|
||||
*/
|
||||
#define ICOM_INTERFACE IDropTarget
|
||||
ICOM_BEGIN(IDropTarget,IUnknown)
|
||||
ICOM_METHOD4(HRESULT, DragEnter, IDataObject*, pDataObjhect, DWORD, grfKeyState, POINTL, pt, DWORD*, pdwEffect);
|
||||
ICOM_METHOD3(HRESULT, DragOver, DWORD, grfKeyState, POINTL, pt, DWORD*, pdwEffect);
|
||||
ICOM_METHOD(HRESULT, DragLeave);
|
||||
ICOM_METHOD4(HRESULT, Drop, IDataObject*, pDataObjhect, DWORD, grfKeyState, POINTL, pt, DWORD*, pdwEffect);
|
||||
ICOM_END(IDropTarget)
|
||||
#undef ICOM_INTERFACE
|
||||
|
||||
#if !defined(__cplusplus) || defined(CINTERFACE)
|
||||
/*** IUnknown methods ***/
|
||||
#define IDropTarget_QueryInterface(p,a,b) ICOM_ICALL2(IUnknown,QueryInterface,p,a,b)
|
||||
#define IDropTarget_AddRef(p) ICOM_ICALL (IUnknown,AddRef,p)
|
||||
#define IDropTarget_Release(p) ICOM_ICALL (IUnknown,Release,p)
|
||||
/*** IDropTarget methods ***/
|
||||
#define IDropTarget_DragEnter(p,a,b,c,d) ICOM_CALL4(DragEnter,p,a,b,c,d)
|
||||
#define IDropTarget_DragOver(p,a,b,c) ICOM_CALL3(DragOver,p,a,b,c)
|
||||
#define IDropTarget_DragLeave(p) ICOM_CALL(DragLeave,p)
|
||||
#define IDropTarget_Drop(p,a,b,c,d) ICOM_CALL4(Drop,p,a,b,c,d)
|
||||
#endif
|
||||
|
||||
#endif /* __WINE_WINE_OBJ_DRAGDROP_H */
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -264,6 +264,9 @@ extern int WIN32_LastError;
|
|||
/* Drag and Drop */
|
||||
#define DRAGDROP_S_DROP 0x00040100L
|
||||
#define DRAGDROP_S_CANCEL 0x00040101L
|
||||
#define DRAGDROP_E_NOTREGISTERED 0x80040100L
|
||||
#define DRAGDROP_E_ALREADYREGISTERED 0x80040101L
|
||||
#define DRAGDROP_S_USEDEFAULTCURSORS 0x00040102L
|
||||
|
||||
#define E_UNEXPECTED 0x8000FFFF
|
||||
|
||||
|
@ -290,6 +293,7 @@ extern int WIN32_LastError;
|
|||
|
||||
#define CO_E_OBJISREG 0x800401FB
|
||||
#define OLE_E_ENUM_NOMORE 0x80040002
|
||||
#define OLE_S_USEREG 0x00040000
|
||||
#define CLASS_E_NOAGGREGATION 0x80040110
|
||||
#define CLASS_E_CLASSNOTAVAILABLE 0x80040111
|
||||
#define E_ACCESSDENIED 0x80070005
|
||||
|
|
|
@ -485,13 +485,6 @@ DECL_WINELIB_TYPE(POINT)
|
|||
DECL_WINELIB_TYPE(PPOINT)
|
||||
DECL_WINELIB_TYPE(LPPOINT)
|
||||
|
||||
typedef struct tagPOINTL
|
||||
{
|
||||
LONG x;
|
||||
LONG y;
|
||||
} POINTL, *PPOINTL, *LPPOINTL;
|
||||
|
||||
|
||||
#define CONV_POINT16TO32(p16,p32) \
|
||||
((p32)->x = (INT32)(p16)->x, (p32)->y = (INT32)(p16)->y)
|
||||
#define CONV_POINT32TO16(p32,p16) \
|
||||
|
|
825
ole/ole2.c
825
ole/ole2.c
|
@ -2,8 +2,11 @@
|
|||
* OLE2 library
|
||||
*
|
||||
* Copyright 1995 Martin von Loewis
|
||||
* Copyright 1999 Francis Beaudet
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "windows.h"
|
||||
#include "winerror.h"
|
||||
#include "ole2.h"
|
||||
|
@ -17,15 +20,73 @@
|
|||
#include "wine/obj_moniker.h"
|
||||
|
||||
/******************************************************************************
|
||||
* These are static/global variables that the OLE module uses to maintain
|
||||
* it's state.
|
||||
* These are static/global variables and internal data structures that the
|
||||
* OLE module uses to maintain it's state.
|
||||
*/
|
||||
typedef struct tagDropTargetNode
|
||||
{
|
||||
HWND32 hwndTarget;
|
||||
IDropTarget* dropTarget;
|
||||
struct tagDropTargetNode* prevDropTarget;
|
||||
struct tagDropTargetNode* nextDropTarget;
|
||||
} DropTargetNode;
|
||||
|
||||
typedef struct tagTrackerWindowInfo
|
||||
{
|
||||
IDataObject* dataObject;
|
||||
IDropSource* dropSource;
|
||||
DWORD dwOKEffect;
|
||||
DWORD* pdwEffect;
|
||||
BOOL32 trackingDone;
|
||||
HRESULT returnValue;
|
||||
|
||||
BOOL32 escPressed;
|
||||
HWND32 curDragTargetHWND;
|
||||
IDropTarget* curDragTarget;
|
||||
} TrackerWindowInfo;
|
||||
|
||||
/*
|
||||
* This is the lock count on the OLE library. It is controlled by the
|
||||
* OLEInitialize/OLEUninitialize methods.
|
||||
*/
|
||||
static ULONG s_OLEModuleLockCount = 0;
|
||||
static ULONG OLE_moduleLockCount = 0;
|
||||
|
||||
/*
|
||||
* Name of our registered window class.
|
||||
*/
|
||||
static const char OLEDD_DRAGTRACKERCLASS[] = "WineDragDropTracker32";
|
||||
|
||||
/*
|
||||
* This is the head of the Drop target container.
|
||||
*/
|
||||
static DropTargetNode* targetListHead = NULL;
|
||||
|
||||
/******************************************************************************
|
||||
* These are the prototypes of the utility methods used for OLE Drag n Drop
|
||||
*/
|
||||
static void OLEDD_Initialize();
|
||||
static void OLEDD_UnInitialize();
|
||||
static void OLEDD_InsertDropTarget(
|
||||
DropTargetNode* nodeToAdd);
|
||||
static DropTargetNode* OLEDD_ExtractDropTarget(
|
||||
HWND32 hwndOfTarget);
|
||||
static DropTargetNode* OLEDD_FindDropTarget(
|
||||
HWND32 hwndOfTarget);
|
||||
static LRESULT WINAPI OLEDD_DragTrackerWindowProc(
|
||||
HWND32 hwnd,
|
||||
UINT32 uMsg,
|
||||
WPARAM32 wParam,
|
||||
LPARAM lParam);
|
||||
static void OLEDD_TrackMouseMove(
|
||||
TrackerWindowInfo* trackerInfo,
|
||||
POINT32 mousePos,
|
||||
DWORD keyState);
|
||||
static void OLEDD_TrackStateChange(
|
||||
TrackerWindowInfo* trackerInfo,
|
||||
POINT32 mousePos,
|
||||
DWORD keyState);
|
||||
static DWORD OLEDD_GetButtonState();
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* OleBuildVersion [OLE2.1]
|
||||
|
@ -65,18 +126,23 @@ HRESULT WINAPI OleInitialize(LPVOID reserved)
|
|||
* Object linking and Embedding
|
||||
* In-place activation
|
||||
*/
|
||||
if (s_OLEModuleLockCount==0)
|
||||
if (OLE_moduleLockCount==0)
|
||||
{
|
||||
/*
|
||||
* Initialize the libraries.
|
||||
*/
|
||||
TRACE(ole, "() - Initializing the OLE libraries\n");
|
||||
|
||||
/*
|
||||
* Drag and Drop
|
||||
*/
|
||||
OLEDD_Initialize();
|
||||
}
|
||||
|
||||
/*
|
||||
* Then, we increase the lock count on the OLE module.
|
||||
*/
|
||||
s_OLEModuleLockCount++;
|
||||
OLE_moduleLockCount++;
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
@ -101,17 +167,22 @@ void WINAPI OleUninitialize(void)
|
|||
/*
|
||||
* Decrease the lock count on the OLE module.
|
||||
*/
|
||||
s_OLEModuleLockCount--;
|
||||
OLE_moduleLockCount--;
|
||||
|
||||
/*
|
||||
* If we hit the bottom of the lock stack, free the libraries.
|
||||
*/
|
||||
if (s_OLEModuleLockCount==0)
|
||||
if (OLE_moduleLockCount==0)
|
||||
{
|
||||
/*
|
||||
* Actually free the libraries.
|
||||
*/
|
||||
TRACE(ole, "() - Freeing the last reference count\n");
|
||||
|
||||
/*
|
||||
* Drag and Drop
|
||||
*/
|
||||
OLEDD_UnInitialize();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -175,9 +246,41 @@ HRESULT WINAPI RegisterDragDrop16(
|
|||
*/
|
||||
HRESULT WINAPI RegisterDragDrop32(
|
||||
HWND32 hwnd,
|
||||
LPDROPTARGET pDropTarget
|
||||
) {
|
||||
FIXME(ole,"(0x%04x,%p),stub!\n",hwnd,pDropTarget);
|
||||
LPDROPTARGET pDropTarget)
|
||||
{
|
||||
DropTargetNode* dropTargetInfo;
|
||||
|
||||
TRACE(ole,"(0x%x,%p)\n", hwnd, pDropTarget);
|
||||
|
||||
/*
|
||||
* First, check if the window is already registered.
|
||||
*/
|
||||
dropTargetInfo = OLEDD_FindDropTarget(hwnd);
|
||||
|
||||
if (dropTargetInfo!=NULL)
|
||||
return DRAGDROP_E_ALREADYREGISTERED;
|
||||
|
||||
/*
|
||||
* If it's not there, we can add it. We first create a node for it.
|
||||
*/
|
||||
dropTargetInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(DropTargetNode));
|
||||
|
||||
if (dropTargetInfo==NULL)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
dropTargetInfo->hwndTarget = hwnd;
|
||||
dropTargetInfo->prevDropTarget = NULL;
|
||||
dropTargetInfo->nextDropTarget = NULL;
|
||||
|
||||
/*
|
||||
* Don't forget that this is an interface pointer, need to nail it down since
|
||||
* we keep a copy of it.
|
||||
*/
|
||||
dropTargetInfo->dropTarget = pDropTarget;
|
||||
IDropTarget_AddRef(dropTargetInfo->dropTarget);
|
||||
|
||||
OLEDD_InsertDropTarget(dropTargetInfo);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -195,9 +298,30 @@ HRESULT WINAPI RevokeDragDrop16(
|
|||
* RevokeDragDrop32 (OLE32.141)
|
||||
*/
|
||||
HRESULT WINAPI RevokeDragDrop32(
|
||||
HWND32 hwnd
|
||||
) {
|
||||
FIXME(ole,"(0x%04x),stub!\n",hwnd);
|
||||
HWND32 hwnd)
|
||||
{
|
||||
DropTargetNode* dropTargetInfo;
|
||||
|
||||
TRACE(ole,"(0x%x)\n", hwnd);
|
||||
|
||||
/*
|
||||
* First, check if the window is already registered.
|
||||
*/
|
||||
dropTargetInfo = OLEDD_ExtractDropTarget(hwnd);
|
||||
|
||||
/*
|
||||
* If it ain't in there, it's an error.
|
||||
*/
|
||||
if (dropTargetInfo==NULL)
|
||||
return DRAGDROP_E_NOTREGISTERED;
|
||||
|
||||
/*
|
||||
* If it's in there, clean-up it's used memory and
|
||||
* references
|
||||
*/
|
||||
IDropTarget_Release(dropTargetInfo->dropTarget);
|
||||
HeapFree(GetProcessHeap(), 0, dropTargetInfo);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -218,10 +342,679 @@ HRESULT WINAPI OleRegGetUserType32(
|
|||
*/
|
||||
HRESULT WINAPI DoDragDrop32 (
|
||||
IDataObject *pDataObject, /* ptr to the data obj */
|
||||
IDataObject *pDropSource, /* ptr to the source obj */
|
||||
IDropSource* pDropSource, /* ptr to the source obj */
|
||||
DWORD dwOKEffect, /* effects allowed by the source */
|
||||
DWORD *pdwEffect) /* ptr to effects of the source */
|
||||
{
|
||||
FIXME(ole,"(DataObject %p, DropSource %p): stub!\n", pDataObject, pDropSource);
|
||||
return DRAGDROP_S_DROP;
|
||||
TrackerWindowInfo trackerInfo;
|
||||
HWND32 hwndTrackWindow;
|
||||
MSG32 msg;
|
||||
|
||||
TRACE(ole,"(DataObject %p, DropSource %p)\n", pDataObject, pDropSource);
|
||||
|
||||
/*
|
||||
* Setup the drag n drop tracking window.
|
||||
*/
|
||||
trackerInfo.dataObject = pDataObject;
|
||||
trackerInfo.dropSource = pDropSource;
|
||||
trackerInfo.dwOKEffect = dwOKEffect;
|
||||
trackerInfo.pdwEffect = pdwEffect;
|
||||
trackerInfo.trackingDone = FALSE;
|
||||
trackerInfo.escPressed = FALSE;
|
||||
trackerInfo.curDragTargetHWND = 0;
|
||||
trackerInfo.curDragTarget = 0;
|
||||
|
||||
hwndTrackWindow = CreateWindow32A(OLEDD_DRAGTRACKERCLASS,
|
||||
"TrackerWindow",
|
||||
WS_POPUP,
|
||||
CW_USEDEFAULT32, CW_USEDEFAULT32,
|
||||
CW_USEDEFAULT32, CW_USEDEFAULT32,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
(LPVOID)&trackerInfo);
|
||||
|
||||
if (hwndTrackWindow!=0)
|
||||
{
|
||||
/*
|
||||
* Capture the mouse input
|
||||
*/
|
||||
SetCapture32(hwndTrackWindow);
|
||||
|
||||
/*
|
||||
* Pump messages. All mouse input should go the the capture window.
|
||||
*/
|
||||
while (!trackerInfo.trackingDone && GetMessage32A(&msg, 0, 0, 0) )
|
||||
{
|
||||
if ( (msg.message >= WM_KEYFIRST) &&
|
||||
(msg.message <= WM_KEYFIRST) )
|
||||
{
|
||||
/*
|
||||
* When keyboard messages are sent to windows on this thread, we
|
||||
* want to ignore notify the drop source that the state changed.
|
||||
* in the case of the Escape key, we also notify the drop source
|
||||
* we give it a special meaning.
|
||||
*/
|
||||
if ( (msg.message==WM_KEYDOWN) &&
|
||||
(msg.wParam==VK_ESCAPE) )
|
||||
{
|
||||
trackerInfo.escPressed = TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Notify the drop source.
|
||||
*/
|
||||
OLEDD_TrackStateChange(&trackerInfo,
|
||||
msg.pt,
|
||||
OLEDD_GetButtonState());
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Dispatch the messages only when it's not a keyboard message.
|
||||
*/
|
||||
DispatchMessage32A(&msg);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Destroy the temporary window.
|
||||
*/
|
||||
DestroyWindow32(hwndTrackWindow);
|
||||
|
||||
return trackerInfo.returnValue;
|
||||
}
|
||||
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* OleQueryLinkFromData32 [OLE32.118]
|
||||
*/
|
||||
HRESULT WINAPI OleQueryLinkFromData32(
|
||||
IDataObject* pSrcDataObject)
|
||||
{
|
||||
FIXME(ole,"(%p),stub!\n", pSrcDataObject);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* OleRegGetMiscStatus32 [OLE32.121]
|
||||
*/
|
||||
HRESULT WINAPI OleRegGetMiscStatus32(
|
||||
REFCLSID clsid,
|
||||
DWORD dwAspect,
|
||||
DWORD* pdwStatus)
|
||||
{
|
||||
FIXME(ole,"(),stub!\n");
|
||||
return REGDB_E_CLASSNOTREG;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* OleGetClipboard32 [OLE32.105]
|
||||
*/
|
||||
HRESULT WINAPI OleGetClipboard32(
|
||||
IDataObject** ppDataObj)
|
||||
{
|
||||
FIXME(ole,"(%p),stub!\n", ppDataObj);
|
||||
|
||||
if (ppDataObj)
|
||||
*ppDataObj=0;
|
||||
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
/***
|
||||
* OLEDD_Initialize()
|
||||
*
|
||||
* Initializes the OLE drag and drop data structures.
|
||||
*/
|
||||
static void OLEDD_Initialize()
|
||||
{
|
||||
WNDCLASS32A wndClass;
|
||||
|
||||
ZeroMemory (&wndClass, sizeof(WNDCLASS32A));
|
||||
wndClass.style = CS_GLOBALCLASS;
|
||||
wndClass.lpfnWndProc = (WNDPROC32)OLEDD_DragTrackerWindowProc;
|
||||
wndClass.cbClsExtra = 0;
|
||||
wndClass.cbWndExtra = sizeof(TrackerWindowInfo*);
|
||||
wndClass.hCursor = 0;
|
||||
wndClass.hbrBackground = 0;
|
||||
wndClass.lpszClassName = OLEDD_DRAGTRACKERCLASS;
|
||||
|
||||
RegisterClass32A (&wndClass);
|
||||
}
|
||||
|
||||
/***
|
||||
* OLEDD_UnInitialize()
|
||||
*
|
||||
* Releases the OLE drag and drop data structures.
|
||||
*/
|
||||
static void OLEDD_UnInitialize()
|
||||
{
|
||||
/*
|
||||
* Simply empty the list.
|
||||
*/
|
||||
while (targetListHead!=NULL)
|
||||
{
|
||||
RevokeDragDrop32(targetListHead->hwndTarget);
|
||||
}
|
||||
}
|
||||
|
||||
/***
|
||||
* OLEDD_InsertDropTarget()
|
||||
*
|
||||
* Insert the target node in the tree.
|
||||
*/
|
||||
static void OLEDD_InsertDropTarget(DropTargetNode* nodeToAdd)
|
||||
{
|
||||
DropTargetNode* curNode;
|
||||
DropTargetNode** parentNodeLink;
|
||||
|
||||
/*
|
||||
* Iterate the tree to find the insertion point.
|
||||
*/
|
||||
curNode = targetListHead;
|
||||
parentNodeLink = &targetListHead;
|
||||
|
||||
while (curNode!=NULL)
|
||||
{
|
||||
if (nodeToAdd->hwndTarget<curNode->hwndTarget)
|
||||
{
|
||||
/*
|
||||
* If the node we want to add has a smaller HWND, go left
|
||||
*/
|
||||
parentNodeLink = &curNode->prevDropTarget;
|
||||
curNode = curNode->prevDropTarget;
|
||||
}
|
||||
else if (nodeToAdd->hwndTarget>curNode->hwndTarget)
|
||||
{
|
||||
/*
|
||||
* If the node we want to add has a larger HWND, go right
|
||||
*/
|
||||
parentNodeLink = &curNode->nextDropTarget;
|
||||
curNode = curNode->nextDropTarget;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* The item was found in the list. It shouldn't have been there
|
||||
*/
|
||||
assert(FALSE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If we get here, we have found a spot for our item. The parentNodeLink
|
||||
* pointer points to the pointer that we have to modify.
|
||||
* The curNode should be NULL. We just have to establish the link and Voila!
|
||||
*/
|
||||
assert(curNode==NULL);
|
||||
assert(parentNodeLink!=NULL);
|
||||
assert(*parentNodeLink==NULL);
|
||||
|
||||
*parentNodeLink=nodeToAdd;
|
||||
}
|
||||
|
||||
/***
|
||||
* OLEDD_ExtractDropTarget()
|
||||
*
|
||||
* Removes the target node from the tree.
|
||||
*/
|
||||
static DropTargetNode* OLEDD_ExtractDropTarget(HWND32 hwndOfTarget)
|
||||
{
|
||||
DropTargetNode* curNode;
|
||||
DropTargetNode** parentNodeLink;
|
||||
|
||||
/*
|
||||
* Iterate the tree to find the insertion point.
|
||||
*/
|
||||
curNode = targetListHead;
|
||||
parentNodeLink = &targetListHead;
|
||||
|
||||
while (curNode!=NULL)
|
||||
{
|
||||
if (hwndOfTarget<curNode->hwndTarget)
|
||||
{
|
||||
/*
|
||||
* If the node we want to add has a smaller HWND, go left
|
||||
*/
|
||||
parentNodeLink = &curNode->prevDropTarget;
|
||||
curNode = curNode->prevDropTarget;
|
||||
}
|
||||
else if (hwndOfTarget>curNode->hwndTarget)
|
||||
{
|
||||
/*
|
||||
* If the node we want to add has a larger HWND, go right
|
||||
*/
|
||||
parentNodeLink = &curNode->nextDropTarget;
|
||||
curNode = curNode->nextDropTarget;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* The item was found in the list. Detach it from it's parent and
|
||||
* re-insert it's kids in the tree.
|
||||
*/
|
||||
assert(parentNodeLink!=NULL);
|
||||
assert(*parentNodeLink==curNode);
|
||||
|
||||
/*
|
||||
* We arbitrately re-attach the left sub-tree to the parent.
|
||||
*/
|
||||
*parentNodeLink = curNode->prevDropTarget;
|
||||
|
||||
/*
|
||||
* And we re-insert the right subtree
|
||||
*/
|
||||
if (curNode->nextDropTarget!=NULL)
|
||||
{
|
||||
OLEDD_InsertDropTarget(curNode->nextDropTarget);
|
||||
}
|
||||
|
||||
/*
|
||||
* The node we found is still a valid node once we complete
|
||||
* the unlinking of the kids.
|
||||
*/
|
||||
curNode->nextDropTarget=NULL;
|
||||
curNode->prevDropTarget=NULL;
|
||||
|
||||
return curNode;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If we get here, the node is not in the tree
|
||||
*/
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/***
|
||||
* OLEDD_FindDropTarget()
|
||||
*
|
||||
* Finds information about the drop target.
|
||||
*/
|
||||
static DropTargetNode* OLEDD_FindDropTarget(HWND32 hwndOfTarget)
|
||||
{
|
||||
DropTargetNode* curNode;
|
||||
|
||||
/*
|
||||
* Iterate the tree to find the HWND value.
|
||||
*/
|
||||
curNode = targetListHead;
|
||||
|
||||
while (curNode!=NULL)
|
||||
{
|
||||
if (hwndOfTarget<curNode->hwndTarget)
|
||||
{
|
||||
/*
|
||||
* If the node we want to add has a smaller HWND, go left
|
||||
*/
|
||||
curNode = curNode->prevDropTarget;
|
||||
}
|
||||
else if (hwndOfTarget>curNode->hwndTarget)
|
||||
{
|
||||
/*
|
||||
* If the node we want to add has a larger HWND, go right
|
||||
*/
|
||||
curNode = curNode->nextDropTarget;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* The item was found in the list.
|
||||
*/
|
||||
return curNode;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If we get here, the item is not in the list
|
||||
*/
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/***
|
||||
* OLEDD_DragTrackerWindowProc()
|
||||
*
|
||||
* This method is the WindowProcedure of the drag n drop tracking
|
||||
* window. During a drag n Drop operation, an invisible window is created
|
||||
* to receive the user input and act upon it. This procedure is in charge
|
||||
* of this behavior.
|
||||
*/
|
||||
static LRESULT WINAPI OLEDD_DragTrackerWindowProc(
|
||||
HWND32 hwnd,
|
||||
UINT32 uMsg,
|
||||
WPARAM32 wParam,
|
||||
LPARAM lParam)
|
||||
{
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_CREATE:
|
||||
{
|
||||
LPCREATESTRUCT32A createStruct = (LPCREATESTRUCT32A)lParam;
|
||||
|
||||
SetWindowLong32A(hwnd, 0, (LONG)createStruct->lpCreateParams);
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
case WM_MOUSEMOVE:
|
||||
{
|
||||
TrackerWindowInfo* trackerInfo = (TrackerWindowInfo*)GetWindowLong32A(hwnd, 0);
|
||||
POINT32 mousePos;
|
||||
|
||||
/*
|
||||
* Get the current mouse position in screen coordinates.
|
||||
*/
|
||||
mousePos.x = LOWORD(lParam);
|
||||
mousePos.y = HIWORD(lParam);
|
||||
ClientToScreen32(hwnd, &mousePos);
|
||||
|
||||
/*
|
||||
* Track the movement of the mouse.
|
||||
*/
|
||||
OLEDD_TrackMouseMove(trackerInfo, mousePos, wParam);
|
||||
|
||||
break;
|
||||
}
|
||||
case WM_LBUTTONUP:
|
||||
case WM_MBUTTONUP:
|
||||
case WM_RBUTTONUP:
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_MBUTTONDOWN:
|
||||
case WM_RBUTTONDOWN:
|
||||
{
|
||||
TrackerWindowInfo* trackerInfo = (TrackerWindowInfo*)GetWindowLong32A(hwnd, 0);
|
||||
POINT32 mousePos;
|
||||
|
||||
/*
|
||||
* Get the current mouse position in screen coordinates.
|
||||
*/
|
||||
mousePos.x = LOWORD(lParam);
|
||||
mousePos.y = HIWORD(lParam);
|
||||
ClientToScreen32(hwnd, &mousePos);
|
||||
|
||||
/*
|
||||
* Notify everyone that the button state changed
|
||||
* TODO: Check if the "escape" key was pressed.
|
||||
*/
|
||||
OLEDD_TrackStateChange(trackerInfo, mousePos, wParam);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a window proc after all. Let's call the default.
|
||||
*/
|
||||
return DefWindowProc32A (hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
/***
|
||||
* OLEDD_TrackMouseMove()
|
||||
*
|
||||
* This method is invoked while a drag and drop operation is in effect.
|
||||
* it will generate the appropriate callbacks in the drop source
|
||||
* and drop target. It will also provide the expected feedback to
|
||||
* the user.
|
||||
*
|
||||
* params:
|
||||
* trackerInfo - Pointer to the structure identifying the
|
||||
* drag & drop operation that is currently
|
||||
* active.
|
||||
* mousePos - Current position of the mouse in screen
|
||||
* coordinates.
|
||||
* keyState - Contains the state of the shift keys and the
|
||||
* mouse buttons (MK_LBUTTON and the like)
|
||||
*/
|
||||
static void OLEDD_TrackMouseMove(
|
||||
TrackerWindowInfo* trackerInfo,
|
||||
POINT32 mousePos,
|
||||
DWORD keyState)
|
||||
{
|
||||
HWND32 hwndNewTarget = 0;
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
/*
|
||||
* Get the handle of the window under the mouse
|
||||
*/
|
||||
hwndNewTarget = WindowFromPoint32(mousePos);
|
||||
|
||||
/*
|
||||
* If we are hovering over the same target as before, send the
|
||||
* DragOver notification
|
||||
*/
|
||||
if ( (trackerInfo->curDragTarget != 0) &&
|
||||
(trackerInfo->curDragTargetHWND==hwndNewTarget) )
|
||||
{
|
||||
POINTL mousePosParam;
|
||||
|
||||
/*
|
||||
* The documentation tells me that the coordinate should be in the target
|
||||
* window's coordinate space. However, the tests I made tell me the
|
||||
* coordinates should be in screen coordinates.
|
||||
*/
|
||||
mousePosParam.x = mousePos.x;
|
||||
mousePosParam.y = mousePos.y;
|
||||
|
||||
IDropTarget_DragOver(trackerInfo->curDragTarget,
|
||||
keyState,
|
||||
mousePosParam,
|
||||
trackerInfo->pdwEffect);
|
||||
}
|
||||
else
|
||||
{
|
||||
DropTargetNode* newDropTargetNode = 0;
|
||||
|
||||
/*
|
||||
* If we changed window, we have to notify our old target and check for
|
||||
* the new one.
|
||||
*/
|
||||
if (trackerInfo->curDragTarget!=0)
|
||||
{
|
||||
IDropTarget_DragLeave(trackerInfo->curDragTarget);
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure we're hovering over a window.
|
||||
*/
|
||||
if (hwndNewTarget!=0)
|
||||
{
|
||||
/*
|
||||
* Find-out if there is a drag target under the mouse
|
||||
*/
|
||||
newDropTargetNode = OLEDD_FindDropTarget(hwndNewTarget);
|
||||
|
||||
trackerInfo->curDragTargetHWND = hwndNewTarget;
|
||||
trackerInfo->curDragTarget = newDropTargetNode ? newDropTargetNode->dropTarget : 0;
|
||||
|
||||
/*
|
||||
* If there is, notify it that we just dragged-in
|
||||
*/
|
||||
if (trackerInfo->curDragTarget!=0)
|
||||
{
|
||||
POINTL mousePosParam;
|
||||
|
||||
/*
|
||||
* The documentation tells me that the coordinate should be in the target
|
||||
* window's coordinate space. However, the tests I made tell me the
|
||||
* coordinates should be in screen coordinates.
|
||||
*/
|
||||
mousePosParam.x = mousePos.x;
|
||||
mousePosParam.y = mousePos.y;
|
||||
|
||||
IDropTarget_DragEnter(trackerInfo->curDragTarget,
|
||||
trackerInfo->dataObject,
|
||||
keyState,
|
||||
mousePosParam,
|
||||
trackerInfo->pdwEffect);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* The mouse is not over a window so we don't track anything.
|
||||
*/
|
||||
trackerInfo->curDragTargetHWND = 0;
|
||||
trackerInfo->curDragTarget = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Now that we have done that, we have to tell the source to give
|
||||
* us feedback on the work being done by the target. If we don't
|
||||
* have a target, simulate no effect.
|
||||
*/
|
||||
if (trackerInfo->curDragTarget==0)
|
||||
{
|
||||
*trackerInfo->pdwEffect = DROPEFFECT_NONE;
|
||||
}
|
||||
|
||||
hr = IDropSource_GiveFeedback(trackerInfo->dropSource,
|
||||
*trackerInfo->pdwEffect);
|
||||
|
||||
/*
|
||||
* When we ask for feedback from the drop source, sometimes it will
|
||||
* do all the necessary work and sometimes it will not handle it
|
||||
* when that's the case, we must display the standard drag and drop
|
||||
* cursors.
|
||||
*/
|
||||
if (hr==DRAGDROP_S_USEDEFAULTCURSORS)
|
||||
{
|
||||
if ( (*trackerInfo->pdwEffect & DROPEFFECT_MOVE) ||
|
||||
(*trackerInfo->pdwEffect & DROPEFFECT_COPY) ||
|
||||
(*trackerInfo->pdwEffect & DROPEFFECT_LINK) )
|
||||
{
|
||||
SetCursor32(LoadCursor32A(0, IDC_SIZEALL32A));
|
||||
}
|
||||
else
|
||||
{
|
||||
SetCursor32(LoadCursor32A(0, IDC_NO32A));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***
|
||||
* OLEDD_TrackStateChange()
|
||||
*
|
||||
* This method is invoked while a drag and drop operation is in effect.
|
||||
* It is used to notify the drop target/drop source callbacks when
|
||||
* the state of the keyboard or mouse button change.
|
||||
*
|
||||
* params:
|
||||
* trackerInfo - Pointer to the structure identifying the
|
||||
* drag & drop operation that is currently
|
||||
* active.
|
||||
* mousePos - Current position of the mouse in screen
|
||||
* coordinates.
|
||||
* keyState - Contains the state of the shift keys and the
|
||||
* mouse buttons (MK_LBUTTON and the like)
|
||||
*/
|
||||
static void OLEDD_TrackStateChange(
|
||||
TrackerWindowInfo* trackerInfo,
|
||||
POINT32 mousePos,
|
||||
DWORD keyState)
|
||||
{
|
||||
/*
|
||||
* Ask the drop source what to do with the operation.
|
||||
*/
|
||||
trackerInfo->returnValue = IDropSource_QueryContinueDrag(
|
||||
trackerInfo->dropSource,
|
||||
trackerInfo->escPressed,
|
||||
keyState);
|
||||
|
||||
/*
|
||||
* All the return valued will stop the operation except the S_OK
|
||||
* return value.
|
||||
*/
|
||||
if (trackerInfo->returnValue!=S_OK)
|
||||
{
|
||||
/*
|
||||
* Make sure the message loop in DoDragDrop stops
|
||||
*/
|
||||
trackerInfo->trackingDone = TRUE;
|
||||
|
||||
/*
|
||||
* Release the mouse in case the drop target decides to show a popup
|
||||
* or a menu or something.
|
||||
*/
|
||||
ReleaseCapture();
|
||||
|
||||
/*
|
||||
* If we end-up over a target, drop the object in the target or
|
||||
* inform the target that the operation was cancelled.
|
||||
*/
|
||||
if (trackerInfo->curDragTarget!=0)
|
||||
{
|
||||
switch (trackerInfo->returnValue)
|
||||
{
|
||||
/*
|
||||
* If the source wants us to complete the operation, we tell
|
||||
* the drop target that we just dropped the object in it.
|
||||
*/
|
||||
case DRAGDROP_S_DROP:
|
||||
{
|
||||
POINTL mousePosParam;
|
||||
|
||||
/*
|
||||
* The documentation tells me that the coordinate should be
|
||||
* in the target window's coordinate space. However, the tests
|
||||
* I made tell me the coordinates should be in screen coordinates.
|
||||
*/
|
||||
mousePosParam.x = mousePos.x;
|
||||
mousePosParam.y = mousePos.y;
|
||||
|
||||
IDropTarget_Drop(trackerInfo->curDragTarget,
|
||||
trackerInfo->dataObject,
|
||||
keyState,
|
||||
mousePosParam,
|
||||
trackerInfo->pdwEffect);
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* If the source told us that we should cancel, fool the drop
|
||||
* target by telling it that the mouse left it's window.
|
||||
*/
|
||||
case DRAGDROP_S_CANCEL:
|
||||
IDropTarget_DragLeave(trackerInfo->curDragTarget);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***
|
||||
* OLEDD_GetButtonState()
|
||||
*
|
||||
* This method will use the current state of the keyboard to build
|
||||
* a button state mask equivalent to the one passed in the
|
||||
* WM_MOUSEMOVE wParam.
|
||||
*/
|
||||
static DWORD OLEDD_GetButtonState()
|
||||
{
|
||||
BYTE keyboardState[256];
|
||||
DWORD keyMask = 0;
|
||||
|
||||
GetKeyboardState(keyboardState);
|
||||
|
||||
if ( (keyboardState[VK_SHIFT] & 0x80) !=0)
|
||||
keyMask |= MK_SHIFT;
|
||||
|
||||
if ( (keyboardState[VK_CONTROL] & 0x80) !=0)
|
||||
keyMask |= MK_CONTROL;
|
||||
|
||||
if ( (keyboardState[VK_LBUTTON] & 0x80) !=0)
|
||||
keyMask |= MK_LBUTTON;
|
||||
|
||||
if ( (keyboardState[VK_RBUTTON] & 0x80) !=0)
|
||||
keyMask |= MK_RBUTTON;
|
||||
|
||||
if ( (keyboardState[VK_MBUTTON] & 0x80) !=0)
|
||||
keyMask |= MK_MBUTTON;
|
||||
|
||||
return keyMask;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -105,7 +105,7 @@ type win32
|
|||
102 stub OleDuplicateData
|
||||
103 stub OleFlushClipboard
|
||||
104 stub OleGetAutoConvert
|
||||
105 stub OleGetClipboard
|
||||
105 stdcall OleGetClipboard(ptr) OleGetClipboard32
|
||||
106 stub OleGetIconOfClass
|
||||
107 stub OleGetIconOfFile
|
||||
108 stdcall OleInitialize(ptr) OleInitialize
|
||||
|
@ -118,10 +118,10 @@ type win32
|
|||
115 stub OleMetafilePictFromIconAndLabel
|
||||
116 stub OleNoteObjectVisible
|
||||
117 stub OleQueryCreateFromData
|
||||
118 stub OleQueryLinkFromData
|
||||
118 stdcall OleQueryLinkFromData(ptr) OleQueryLinkFromData32
|
||||
119 stub OleRegEnumFormatEtc
|
||||
120 stub OleRegEnumVerbs
|
||||
121 stub OleRegGetMiscStatus
|
||||
121 stdcall OleRegGetMiscStatus(ptr long ptr) OleRegGetMiscStatus32
|
||||
122 stdcall OleRegGetUserType(long long ptr) OleRegGetUserType32
|
||||
123 stub OleRun
|
||||
124 stub OleSave
|
||||
|
|
Loading…
Reference in New Issue