Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[OLE32] Implement WS_EX_ACCEPTFILES #1403

Merged
merged 5 commits into from
Mar 15, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
143 changes: 143 additions & 0 deletions dll/win32/ole32/ole2.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ typedef struct tagTrackerWindowInfo
BOOL escPressed;
HWND curTargetHWND; /* window the mouse is hovering over */
IDropTarget* curDragTarget;
#ifdef __REACTOS__
HWND accepterHWND;
#endif
POINTL curMousePos; /* current position of the mouse in screen coordinates */
DWORD dwKeyState; /* current state of the shift and ctrl keys and the mouse buttons */
} TrackerWindowInfo;
Expand Down Expand Up @@ -293,6 +296,12 @@ static inline BOOL is_droptarget(HWND hwnd)
return get_droptarget_handle(hwnd) != 0;
}

#ifdef __REACTOS__
static inline BOOL is_acceptfiles(HWND hwnd)
{
return !!(GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_ACCEPTFILES);
}
#endif
/*************************************************************
* get_droptarget_local_handle
*
Expand Down Expand Up @@ -772,6 +781,9 @@ HRESULT WINAPI DoDragDrop (
trackerInfo.escPressed = FALSE;
trackerInfo.curTargetHWND = 0;
trackerInfo.curDragTarget = 0;
#ifdef __REACTOS__
trackerInfo.accepterHWND = NULL;
#endif

hwndTrackWindow = CreateWindowW(OLEDD_DRAGTRACKERCLASS, trackerW,
WS_POPUP, CW_USEDEFAULT, CW_USEDEFAULT,
Expand Down Expand Up @@ -2182,14 +2194,107 @@ static LRESULT WINAPI OLEDD_DragTrackerWindowProc(
return DefWindowProcW (hwnd, uMsg, wParam, lParam);
}

#ifdef __REACTOS__
static HRESULT WINAPI DefaultDragEnter(HWND hwndTarget,
IDataObject* pDataObj,
DWORD grfKeyState,
POINTL pt,
DWORD* pdwEffect)
{
HRESULT hr;
FORMATETC fme;

ZeroMemory(&fme, sizeof(fme));
fme.cfFormat = CF_HDROP;
fme.ptd = NULL;
fme.dwAspect = DVASPECT_CONTENT;
fme.lindex = -1;
fme.tymed = TYMED_HGLOBAL;
hr = pDataObj->lpVtbl->QueryGetData(pDataObj, &fme);

*pdwEffect = SUCCEEDED(hr) ? DROPEFFECT_COPY : DROPEFFECT_NONE;

if (*pdwEffect == DROPEFFECT_NONE)
return DRAGDROP_S_CANCEL;

return S_OK;
}

static HRESULT WINAPI DefaultDrop(HWND hwndAccepter,
IDataObject* pDataObj,
DWORD grfKeyState,
POINTL pt,
DWORD* pdwEffect)
{
FORMATETC fme;
STGMEDIUM stgm;
HRESULT hr;
HGLOBAL hGlobal = NULL;

ZeroMemory(&fme, sizeof(fme));
fme.cfFormat = CF_HDROP;
fme.ptd = NULL;
fme.dwAspect = DVASPECT_CONTENT;
fme.lindex = -1;
fme.tymed = TYMED_HGLOBAL;
hr = pDataObj->lpVtbl->QueryGetData(pDataObj, &fme);
if (FAILED(hr))
return hr;

ZeroMemory(&stgm, sizeof(stgm));
hr = pDataObj->lpVtbl->GetData(pDataObj, &fme, &stgm);
if (SUCCEEDED(hr))
{
hGlobal = stgm.DUMMYUNIONNAME.hGlobal;
if (hGlobal)
{
if (IsWindowUnicode(hwndAccepter))
PostMessageW(hwndAccepter, WM_DROPFILES, (WPARAM)hGlobal, 0);
else
PostMessageA(hwndAccepter, WM_DROPFILES, (WPARAM)hGlobal, 0);
}
ReleaseStgMedium(&stgm);
}

return hr;
}
#endif

static void drag_enter( TrackerWindowInfo *info, HWND new_target )
{
HRESULT hr;
#ifdef __REACTOS__
DWORD dwEffect = *info->pdwEffect;
#endif

info->curTargetHWND = new_target;

#ifdef __REACTOS__
info->accepterHWND = NULL;
while (new_target && !is_droptarget( new_target ))
{
if (is_acceptfiles(new_target))
{
dwEffect = info->dwOKEffect;
hr = DefaultDragEnter(new_target, info->dataObject,
info->dwKeyState, info->curMousePos,
&dwEffect);
dwEffect &= info->dwOKEffect;

if (hr == S_OK)
{
info->accepterHWND = new_target;
info->curDragTarget = NULL;
*info->pdwEffect = dwEffect;
return;
}
}
new_target = GetParent( new_target );
}
#else
while (new_target && !is_droptarget( new_target ))
new_target = GetParent( new_target );
#endif

info->curDragTarget = get_droptarget_pointer( new_target );

Expand All @@ -2207,6 +2312,9 @@ static void drag_enter( TrackerWindowInfo *info, HWND new_target )
IDropTarget_Release( info->curDragTarget );
info->curDragTarget = NULL;
info->curTargetHWND = NULL;
#ifdef __REACTOS__
info->accepterHWND = NULL;
#endif
}
}
}
Expand Down Expand Up @@ -2239,6 +2347,27 @@ static void drag_end( TrackerWindowInfo *info )
IDropTarget_Release( info->curDragTarget );
info->curDragTarget = NULL;
}
#ifdef __REACTOS__
else if (info->accepterHWND)
{
if (info->returnValue == DRAGDROP_S_DROP &&
*info->pdwEffect != DROPEFFECT_NONE)
{
*info->pdwEffect = info->dwOKEffect;
hr = DefaultDrop(info->accepterHWND, info->dataObject, info->dwKeyState,
info->curMousePos, info->pdwEffect);
*info->pdwEffect &= info->dwOKEffect;

if (FAILED( hr ))
info->returnValue = hr;
}
else
{
*info->pdwEffect = DROPEFFECT_NONE;
}
info->accepterHWND = NULL;
}
#endif
else
*info->pdwEffect = DROPEFFECT_NONE;
}
Expand All @@ -2249,8 +2378,13 @@ static HRESULT give_feedback( TrackerWindowInfo *info )
int res;
HCURSOR cur;

#ifdef __REACTOS__
if (info->curDragTarget == NULL && info->accepterHWND == NULL)
*info->pdwEffect = DROPEFFECT_NONE;
#else
if (info->curDragTarget == NULL)
*info->pdwEffect = DROPEFFECT_NONE;
#endif

hr = IDropSource_GiveFeedback( info->dropSource, *info->pdwEffect );

Expand Down Expand Up @@ -2309,6 +2443,9 @@ static void OLEDD_TrackStateChange(TrackerWindowInfo* trackerInfo)
trackerInfo->curDragTarget = NULL;
trackerInfo->curTargetHWND = NULL;
}
#ifdef __REACTOS__
trackerInfo->accepterHWND = NULL;
#endif

if (hwndNewTarget)
drag_enter( trackerInfo, hwndNewTarget );
Expand All @@ -2328,6 +2465,12 @@ static void OLEDD_TrackStateChange(TrackerWindowInfo* trackerInfo)
trackerInfo->pdwEffect);
*trackerInfo->pdwEffect &= trackerInfo->dwOKEffect;
}
#ifdef __REACTOS__
else if (trackerInfo->accepterHWND)
{
*trackerInfo->pdwEffect = trackerInfo->dwOKEffect;
}
#endif
give_feedback( trackerInfo );
}
else
Expand Down