00032 {
00033 MSG
msg, msgKey;
00034
DWORD result = 0;
00035
BOOL fDrag =
TRUE;
00036 LPDROPSTRUCT lpds;
00037
PWND pwndDragging =
NULL;
00038
PWND pwndTop;
00039
PCURSOR pcurOld, pcurT;
00040
PWND pwndT;
00041
TL tlpwndT;
00042
TL tlpwndTop;
00043
TL tlpwndDragging;
00044
TL tlPool;
00045
PTHREADINFO pti =
PtiCurrent();
00046
00047
CheckLock(pwndParent);
00048
CheckLock(pwndFrom);
00049
CheckLock(pcur);
00050 UserAssert(
IsWinEventNotifyDeferredOK());
00051
00052 lpds = (LPDROPSTRUCT)UserAllocPoolWithQuota(2 *
sizeof(DROPSTRUCT), TAG_DRAGDROP);
00053
if (lpds ==
NULL)
00054
return 0;
00055
00056
ThreadLockPool(pti, lpds, &tlPool);
00057 lpds->hwndSource =
HW(pwndFrom);
00058 lpds->wFmt = wFmt;
00059 lpds->dwData = dwData;
00060
00061
if (pcur !=
NULL) {
00062
00063
00064
00065 pcurOld =
zzzSetCursor(pcur);
00066 }
else {
00067 pcurOld = pti->
pq->
spcurCurrent;
00068 }
00069
00070
if (pwndFrom) {
00071
for (pwndTop = pwndFrom;
TestwndChild(pwndTop);
00072 pwndTop = pwndTop->
spwndParent) ;
00073
00074
ThreadLockWithPti(pti, pwndTop, &tlpwndTop);
00075
xxxUpdateWindow(pwndTop);
00076
ThreadUnlock(&tlpwndTop);
00077 }
00078
00079
if (
FWINABLE()) {
00080
xxxWindowEvent(EVENT_SYSTEM_DRAGDROPSTART, pwndFrom, OBJID_WINDOW, INDEXID_CONTAINER, 0);
00081 }
00082
00083
xxxSetCapture(pwndFrom);
00084
zzzShowCursor(TRUE);
00085
00086
ThreadLockWithPti(pti, pwndDragging, &tlpwndDragging);
00087
00088
while (fDrag && pti->
pq->
spwndCapture == pwndFrom) {
00089
while (!(
xxxPeekMessage(&msg, NULL, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE) ||
00090
xxxPeekMessage(&msg, NULL, WM_QUEUESYNC, WM_QUEUESYNC, PM_REMOVE) ||
00091
xxxPeekMessage(&msg, NULL, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE))) {
00092
if (!
xxxSleepThread(QS_MOUSE | QS_KEY, 0, TRUE)) {
00093
ThreadUnlock(&tlpwndDragging);
00094
ThreadUnlockAndFreePool(pti, &tlPool);
00095
return 0;
00096 }
00097 }
00098
00099
00100
00101
00102
00103
00104
while (
xxxPeekMessage(&msgKey, NULL, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE))
00105 ;
00106
00107
if ( (pti->
pq->
spwndCapture != pwndFrom) ||
00108 (
msg.message == WM_KEYDOWN &&
msg.wParam == VK_ESCAPE) )
00109 {
00110
if (pcurT =
SYSCUR(NO))
00111
zzzSetCursor(pcurT);
00112
break;
00113 }
00114
00115 RtlCopyMemory(lpds + 1, lpds,
sizeof(DROPSTRUCT));
00116
00117
00118
00119
00120 lpds->ptDrop =
msg.pt;
00121
00122 pcurT =
xxxQueryDropObject(pwndParent, lpds);
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
if (pcurT == (
PCURSOR)
FALSE) {
00133 pcurT =
SYSCUR(NO);
00134 lpds->hwndSink =
NULL;
00135 }
else if (pcurT == (
PCURSOR)
TRUE) {
00136 pcurT = pcur;
00137 }
00138
00139
if (pcurT !=
NULL)
00140
zzzSetCursor(pcurT);
00141
00142
00143
00144
00145
00146
if (pwndFrom) {
00147
xxxSendMessage(pwndFrom, WM_DRAGLOOP, (pcurT !=
SYSCUR(NO)),
00148 (LPARAM)lpds);
00149 }
00150
00151
00152
00153
00154
if (pwndDragging !=
RevalidateHwnd(lpds->hwndSink)) {
00155
if (pwndDragging !=
NULL) {
00156
xxxSendMessage(pwndDragging, WM_DRAGSELECT, FALSE,
00157 (LPARAM)(lpds + 1));
00158 }
00159 pwndDragging =
RevalidateHwnd(lpds->hwndSink);
00160
ThreadUnlock(&tlpwndDragging);
00161
ThreadLockWithPti(pti, pwndDragging, &tlpwndDragging);
00162
00163
if (pwndDragging !=
NULL) {
00164
xxxSendMessage(pwndDragging, WM_DRAGSELECT, TRUE, (LPARAM)lpds);
00165 }
00166 }
else {
00167
if (pwndDragging !=
NULL) {
00168
xxxSendMessage(pwndDragging, WM_DRAGMOVE, 0, (LPARAM)lpds);
00169 }
00170 }
00171
00172
switch (
msg.message) {
00173
case WM_LBUTTONUP:
00174
case WM_NCLBUTTONUP:
00175 fDrag =
FALSE;
00176
break;
00177 }
00178 }
00179
00180
ThreadUnlock(&tlpwndDragging);
00181
00182
00183
00184
00185
if (fDrag)
00186 pcurT =
SYSCUR(NO);
00187
00188
00189
00190
00191
00192
xxxReleaseCapture();
00193
zzzShowCursor(FALSE);
00194
00195
zzzSetCursor(pcurOld);
00196
00197
00198
00199
00200
if (pcurT !=
SYSCUR(NO)) {
00201
00202
00203
00204
00205 pwndT =
ValidateHwnd(lpds->hwndSink);
00206
if (pwndT !=
NULL) {
00207
00208
ThreadLockAlwaysWithPti(pti, pwndT, &tlpwndT);
00209
00210
00211
00212
00213
GETPTI(pwndT)->TIF_flags |=
TIF_ALLOWFOREGROUNDACTIVATE;
00214 TAGMSG1(DBGTAG_FOREGROUND,
"xxxDragObject set TIF %#p",
GETPTI(pwndT));
00215 result = (
DWORD)
xxxSendMessage(pwndT, WM_DROPOBJECT,
00216 (WPARAM)
HW(pwndFrom), (LPARAM)lpds);
00217
00218
ThreadUnlock(&tlpwndT);
00219 }
00220 }
00221
00222
if (
FWINABLE()) {
00223
xxxWindowEvent(EVENT_SYSTEM_DRAGDROPEND, pwndFrom, OBJID_WINDOW, INDEXID_CONTAINER, 0);
00224 }
00225
00226
ThreadUnlockAndFreePool(pti, &tlPool);
00227
return result;
00228 }