00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
#include "precomp.h"
00012
#pragma hdrstop
00013
00014
#include "callback.h"
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 NTSTATUS xxxClientLoadOLE (
void)
00025 {
00026
NTSTATUS Status;
00027
PPROCESSINFO ppiCurrent =
PpiCurrent();
00028
00029
if (ppiCurrent->W32PF_Flags & W32PF_OLELOADED) {
00030
return STATUS_SUCCESS;
00031 }
00032
00033
Status =
xxxUserModeCallback(FI_CLIENTLOADOLE,
NULL, 0,
NULL, 0);
00034
if (
NT_SUCCESS(
Status)) {
00035 ppiCurrent->W32PF_Flags |= W32PF_OLELOADED;
00036 }
00037
return Status;
00038 }
00039
00040
00041
00042
00043
00044 NTSTATUS xxxClientRegisterDragDrop (HWND hwnd)
00045 {
00046
return xxxUserModeCallback(FI_CLIENTREGISTERDRAGDROP, &hwnd,
sizeof(&hwnd),
NULL, 0);
00047 }
00048
00049
00050
00051
00052
00053 NTSTATUS xxxClientRevokeDragDrop (HWND hwnd)
00054 {
00055
return xxxUserModeCallback(FI_CLIENTREVOKEDRAGDROP, &hwnd,
sizeof(&hwnd),
NULL, 0);
00056
00057 }
00058
00059
00060
00061
00062
00063 void xxxMNSetGapState (ULONG_PTR uHitArea, UINT uIndex, UINT uFlags, BOOL fSet)
00064 {
00065
int yTop;
00066
PITEM pItem, pItemGap;
00067
PPOPUPMENU ppopup;
00068 RECT rc;
00069
TL tlHitArea;
00070
00071
00072
00073
00074
if (!(uFlags & MNGOF_GAP) || !
IsMFMWFPWindow(uHitArea)) {
00075
return;
00076 }
00077
00078 ppopup = ((
PMENUWND)uHitArea)->ppopupmenu;
00079 pItem =
MNGetpItem(ppopup, uIndex);
00080
00081
00082
00083
00084
if (pItem ==
NULL) {
00085
return;
00086 }
00087
00088
00089
00090
00091
00092
00093
00094 rc.left = pItem->
xItem;
00095 rc.right = pItem->
xItem + pItem->
cxItem;
00096 rc.top = pItem->
yItem;
00097 rc.bottom = pItem->
yItem + pItem->
cyItem;
00098
00099
if (uFlags & MNGOF_TOPGAP) {
00100 pItemGap =
MNGetpItem(ppopup, uIndex - 1);
00101
if (fSet) {
00102
SetMFS(pItem, MFS_TOPGAPDROP);
00103
if (pItemGap !=
NULL) {
00104
SetMFS(pItemGap, MFS_BOTTOMGAPDROP);
00105 }
00106 }
else {
00107
ClearMFS(pItem, MFS_TOPGAPDROP);
00108
if (pItemGap !=
NULL) {
00109
ClearMFS(pItemGap, MFS_BOTTOMGAPDROP);
00110 }
00111 }
00112
if (pItemGap !=
NULL) {
00113 rc.top -=
SYSMET(CYDRAG);
00114 }
00115 }
else {
00116 pItemGap =
MNGetpItem(ppopup, uIndex + 1);
00117
if (fSet) {
00118
SetMFS(pItem, MFS_BOTTOMGAPDROP);
00119
if (pItemGap !=
NULL) {
00120
SetMFS(pItemGap, MFS_TOPGAPDROP);
00121 }
00122 }
else {
00123
ClearMFS(pItem, MFS_BOTTOMGAPDROP);
00124
if (pItemGap !=
NULL) {
00125
ClearMFS(pItemGap, MFS_TOPGAPDROP);
00126 }
00127 }
00128
if (pItemGap !=
NULL) {
00129 rc.bottom +=
SYSMET(CYDRAG);
00130 }
00131 }
00132
00133
00134
00135
00136 yTop =
MNGetToppItem(ppopup->
spmenu)->
yItem;
00137 rc.top -= yTop;
00138 rc.bottom -= yTop;
00139
00140
00141
00142
00143
ThreadLockAlways((
PWND)uHitArea, &tlHitArea);
00144
xxxInvalidateRect((
PWND)uHitArea, &rc,
TRUE);
00145
ThreadUnlock(&tlHitArea);
00146 }
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 BOOL xxxMNDragOver(POINT * ppt,
PMNDRAGOVERINFO pmndoi)
00157 {
00158
BOOL fRet;
00159
PMENUSTATE pMenuState;
00160
PWND pwnd;
00161
PPOPUPMENU ppopup;
00162
TL tlpwnd;
00163
00164
00165
00166
00167
00168 pMenuState =
PtiCurrent()->pMenuState;
00169
if (pMenuState ==
NULL) {
00170 RIPMSG0(RIP_WARNING,
"xxxMNDragOver: Not in menu mode");
00171
return FALSE;
00172 }
00173
00174
00175
00176
00177 UserAssert(pMenuState->
fDragAndDrop);
00178
00179
00180
00181
00182
00183 pMenuState->
fInDoDragDrop =
TRUE;
00184
00185
00186
00187
00188 pwnd =
GetMenuStateWindow(pMenuState);
00189
if (pwnd ==
NULL) {
00190 RIPMSG0(RIP_WARNING,
"xxxMNDragOver: Failed to get MenuStateWindow");
00191
return FALSE;
00192 }
00193
00194
00195
00196
00197
LockMenuState(pMenuState);
00198
00199
00200
00201
00202
00203
ThreadLockAlways(pwnd, &tlpwnd);
00204
xxxCallHandleMenuMessages(pMenuState, pwnd, WM_NCMOUSEMOVE, 0, MAKELONG(ppt->x, ppt->y));
00205
ThreadUnlock(&tlpwnd);
00206
00207
00208
00209
00210
if (pMenuState->
uDraggingHitArea !=
MFMWFP_OFFMENU) {
00211 ppopup = ((
PMENUWND)pMenuState->
uDraggingHitArea)->ppopupmenu;
00212 pmndoi->
hmenu =
PtoH(ppopup->
spmenu);
00213 pmndoi->
uItemIndex = pMenuState->
uDraggingIndex;
00214 pmndoi->
hwndNotify =
PtoH(ppopup->
spwndNotify);
00215 pmndoi->
dwFlags = pMenuState->
uDraggingFlags;
00216
00217
00218
00219
if (pmndoi->
dwFlags & MNGOF_BOTTOMGAP) {
00220 UserAssert(pmndoi->
uItemIndex !=
MFMWFP_NOITEM);
00221 (pmndoi->
uItemIndex)++;
00222 }
00223 fRet =
TRUE;
00224 }
else {
00225 fRet =
FALSE;
00226 }
00227
00228
xxxUnlockMenuState(pMenuState);
00229
return fRet;;
00230
00231 }
00232
00233
00234
00235
00236
00237 BOOL xxxMNDragLeave (VOID)
00238 {
00239
PMENUSTATE pMenuState;
00240
00241 pMenuState =
PtiCurrent()->pMenuState;
00242
if (pMenuState ==
NULL) {
00243 RIPMSG0(RIP_WARNING,
"xxxMNDragLeave: Not in menu mode");
00244
return FALSE;
00245 }
00246
00247
LockMenuState(pMenuState);
00248
00249
00250
00251
00252
xxxMNSetGapState(pMenuState->
uDraggingHitArea,
00253 pMenuState->
uDraggingIndex,
00254 pMenuState->
uDraggingFlags,
00255
FALSE);
00256
00257
00258
00259
00260
UnlockMFMWFPWindow(&pMenuState->
uDraggingHitArea);
00261 pMenuState->
uDraggingIndex =
MFMWFP_NOITEM;
00262 pMenuState->
uDraggingFlags = 0;
00263
00264
00265
00266
00267
00268 pMenuState->
fInDoDragDrop =
FALSE;
00269
00270
xxxUnlockMenuState(pMenuState);
00271
00272
return TRUE;
00273 }
00274
00275
00276
00277
00278
00279 void xxxMNUpdateDraggingInfo (
PMENUSTATE pMenuState, ULONG_PTR uHitArea, UINT uIndex)
00280 {
00281
BOOL fCross;
00282
int y, iIndexDelta;
00283
PITEM pItem;
00284
PPOPUPMENU ppopup;
00285
TL tlLastHitArea;
00286 ULONG_PTR uLastHitArea;
00287
UINT uLastIndex, uLastFlags;
00288
00289
00290
00291
00292
00293 UserAssert((pMenuState->
uDraggingHitArea == 0) ||
IsMFMWFPWindow(pMenuState->
uDraggingHitArea));
00294
ThreadLock((
PWND)pMenuState->
uDraggingHitArea, &tlLastHitArea);
00295 uLastHitArea = pMenuState->
uDraggingHitArea;
00296 uLastIndex = pMenuState->
uDraggingIndex;
00297 uLastFlags = pMenuState->
uDraggingFlags & MNGOF_GAP;
00298
00299
00300
00301
00302
LockMFMWFPWindow(&pMenuState->
uDraggingHitArea, uHitArea);
00303 pMenuState->
uDraggingIndex = uIndex;
00304
00305
00306
00307
00308
if (!
IsMFMWFPWindow(pMenuState->
uDraggingHitArea)) {
00309 pMenuState->
uDraggingHitArea =
MFMWFP_OFFMENU;
00310 pMenuState->
uDraggingIndex =
MFMWFP_NOITEM;
00311
ThreadUnlock(&tlLastHitArea);
00312
return;
00313 }
00314
00315
00316
00317
00318 ppopup = ((
PMENUWND)pMenuState->
uDraggingHitArea)->ppopupmenu;
00319 pItem =
MNGetpItem(ppopup, pMenuState->
uDraggingIndex);
00320
00321
00322
00323
00324
00325
00326
00327
00328 pMenuState->
uDraggingFlags = 0;
00329
if (pItem !=
NULL) {
00330
00331
00332
00333
00334 y = pMenuState->
ptMouseLast.y;
00335 y -= ((
PWND)pMenuState->
uDraggingHitArea)->rcClient.top;
00336 y +=
MNGetToppItem(ppopup->
spmenu)->
yItem;
00337
#if DBG
00338
if ((y < (
int)pItem->
yItem)
00339 || (y > (
int)(pItem->
yItem + pItem->
cyItem))) {
00340 RIPMSG4(RIP_ERROR,
"xxxMNUpdateDraggingInfo: y Point not in selected item. "
00341
"pwnd:%#lx ppopup:%#lx Index:%#lx pItem:%#lx",
00342 pMenuState->
uDraggingHitArea, ppopup, pMenuState->
uDraggingIndex, pItem);
00343 }
00344
#endif
00345
00346
00347
00348
00349
if (y <= (
int)(pItem->
yItem +
SYSMET(CYDRAG))) {
00350 pMenuState->
uDraggingFlags = MNGOF_TOPGAP;
00351 }
else if (y >= (
int)(pItem->
yItem + pItem->
cyItem -
SYSMET(CYDRAG))) {
00352 pMenuState->
uDraggingFlags = MNGOF_BOTTOMGAP;
00353 }
00354 }
00355
00356
00357
00358
00359
00360
00361
00362
00363 fCross = (uLastHitArea != pMenuState->
uDraggingHitArea);
00364
if (!fCross) {
00365 iIndexDelta = (
int)pMenuState->
uDraggingIndex - (
int)uLastIndex;
00366
switch (iIndexDelta) {
00367
case 0:
00368
00369
00370
00371 fCross = (uLastFlags != pMenuState->
uDraggingFlags);
00372
break;
00373
00374
case 1:
00375
00376
00377
00378 fCross = !((pMenuState->
uDraggingFlags == MNGOF_TOPGAP)
00379 && (uLastFlags == MNGOF_BOTTOMGAP));
00380
break;
00381
00382
case -1:
00383
00384
00385
00386 fCross = !((pMenuState->
uDraggingFlags == MNGOF_BOTTOMGAP)
00387 && (uLastFlags == MNGOF_TOPGAP));
00388
break;
00389
00390
default:
00391
00392
00393
00394 fCross =
TRUE;
00395 }
00396 }
00397
00398
if (fCross) {
00399 pMenuState->
uDraggingFlags |= MNGOF_CROSSBOUNDARY;
00400
00401
00402
00403
00404
xxxMNSetGapState(uLastHitArea, uLastIndex, uLastFlags,
FALSE);
00405
xxxMNSetGapState(pMenuState->
uDraggingHitArea,
00406 pMenuState->
uDraggingIndex,
00407 pMenuState->
uDraggingFlags,
00408
TRUE);
00409 }
00410
00411
ThreadUnlock(&tlLastHitArea);
00412 }
00413