Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

menudd.c File Reference

#include "precomp.h"
#include "callback.h"

Go to the source code of this file.

Functions

NTSTATUS xxxClientLoadOLE (void)
NTSTATUS xxxClientRegisterDragDrop (HWND hwnd)
NTSTATUS xxxClientRevokeDragDrop (HWND hwnd)
void xxxMNSetGapState (ULONG_PTR uHitArea, UINT uIndex, UINT uFlags, BOOL fSet)
BOOL xxxMNDragOver (POINT *ppt, PMNDRAGOVERINFO pmndoi)
BOOL xxxMNDragLeave (VOID)
void xxxMNUpdateDraggingInfo (PMENUSTATE pMenuState, ULONG_PTR uHitArea, UINT uIndex)


Function Documentation

NTSTATUS xxxClientLoadOLE void   ) 
 

Definition at line 24 of file menudd.c.

References NT_SUCCESS, NTSTATUS(), NULL, PpiCurrent, Status, and xxxUserModeCallback().

Referenced by xxxMNStartMenu().

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 }

NTSTATUS xxxClientRegisterDragDrop HWND  hwnd  ) 
 

Definition at line 44 of file menudd.c.

References NTSTATUS(), NULL, and xxxUserModeCallback().

Referenced by xxxMNOpenHierarchy(), and xxxTrackPopupMenuEx().

00045 { 00046 return xxxUserModeCallback(FI_CLIENTREGISTERDRAGDROP, &hwnd, sizeof(&hwnd), NULL, 0); 00047 }

NTSTATUS xxxClientRevokeDragDrop HWND  hwnd  ) 
 

Definition at line 53 of file menudd.c.

References NTSTATUS(), NULL, and xxxUserModeCallback().

Referenced by xxxMenuWindowProc(), and xxxMNCloseHierarchy().

00054 { 00055 return xxxUserModeCallback(FI_CLIENTREVOKEDRAGDROP, &hwnd, sizeof(&hwnd), NULL, 0); 00056 00057 }

BOOL xxxMNDragLeave VOID   ) 
 

Definition at line 237 of file menudd.c.

References BOOL, FALSE, tagMENUSTATE::fInDoDragDrop, LockMenuState(), MFMWFP_NOITEM, NULL, PtiCurrent, TRUE, tagMENUSTATE::uDraggingFlags, tagMENUSTATE::uDraggingHitArea, tagMENUSTATE::uDraggingIndex, UnlockMFMWFPWindow(), xxxMNSetGapState(), and xxxUnlockMenuState().

Referenced by NtUserMNDragLeave().

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 * Clean up any present insertion bar state 00251 */ 00252 xxxMNSetGapState(pMenuState->uDraggingHitArea, 00253 pMenuState->uDraggingIndex, 00254 pMenuState->uDraggingFlags, 00255 FALSE); 00256 00257 /* 00258 * Forget the last dragging area 00259 */ 00260 UnlockMFMWFPWindow(&pMenuState->uDraggingHitArea); 00261 pMenuState->uDraggingIndex = MFMWFP_NOITEM; 00262 pMenuState->uDraggingFlags = 0; 00263 00264 00265 /* 00266 * The DoDragDrop loop has left our window. 00267 */ 00268 pMenuState->fInDoDragDrop = FALSE; 00269 00270 xxxUnlockMenuState(pMenuState); 00271 00272 return TRUE; 00273 }

BOOL xxxMNDragOver POINT *  ppt,
PMNDRAGOVERINFO  pmndoi
 

Definition at line 156 of file menudd.c.

References BOOL, tagMNDRAGOVERINFO::dwFlags, FALSE, tagMENUSTATE::fDragAndDrop, tagMENUSTATE::fInDoDragDrop, GetMenuStateWindow(), tagMNDRAGOVERINFO::hmenu, tagMNDRAGOVERINFO::hwndNotify, LockMenuState(), MFMWFP_NOITEM, MFMWFP_OFFMENU, NULL, PMNDRAGOVERINFO, PtiCurrent, PtoH, tagPOPUPMENU::spmenu, tagPOPUPMENU::spwndNotify, ThreadLockAlways, ThreadUnlock, TRUE, tagMENUSTATE::uDraggingFlags, tagMENUSTATE::uDraggingHitArea, tagMENUSTATE::uDraggingIndex, tagMNDRAGOVERINFO::uItemIndex, xxxCallHandleMenuMessages(), and xxxUnlockMenuState().

Referenced by NtUserMNDragOver().

00157 { 00158 BOOL fRet; 00159 PMENUSTATE pMenuState; 00160 PWND pwnd; 00161 PPOPUPMENU ppopup; 00162 TL tlpwnd; 00163 00164 /* 00165 * OLE always calls us in context (proxy/marshall stuff). So the 00166 * current thread must be in menu mode 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 * This must be a drag and drop menu 00176 */ 00177 UserAssert(pMenuState->fDragAndDrop); 00178 00179 /* 00180 * We might have not initiated this DoDragDrop so make sure 00181 * the internal flag is set. 00182 */ 00183 pMenuState->fInDoDragDrop = TRUE; 00184 00185 /* 00186 * Get a window to call xxxCallHandleMenuMessages 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 * We need this after calling back, so lock it 00196 */ 00197 LockMenuState(pMenuState); 00198 00199 /* 00200 * Update the selection and the dragging info 00201 * Use WM_NCMOUSEMOVE because the point is in screen coordinates already. 00202 */ 00203 ThreadLockAlways(pwnd, &tlpwnd); 00204 xxxCallHandleMenuMessages(pMenuState, pwnd, WM_NCMOUSEMOVE, 0, MAKELONG(ppt->x, ppt->y)); 00205 ThreadUnlock(&tlpwnd); 00206 00207 /* 00208 * If we're on a popup, propagate the hit test info 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 * Bottom gap of item N corresponds to N+1 gap 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 }

void xxxMNSetGapState ULONG_PTR  uHitArea,
UINT  uIndex,
UINT  uFlags,
BOOL  fSet
 

Definition at line 63 of file menudd.c.

References ClearMFS, tagITEM::cxItem, tagITEM::cyItem, IsMFMWFPWindow(), MNGetpItem(), MNGetToppItem(), NULL, SetMFS, tagPOPUPMENU::spmenu, SYSMET, ThreadLockAlways, ThreadUnlock, TRUE, tagITEM::xItem, xxxInvalidateRect(), and tagITEM::yItem.

Referenced by xxxInsertMenuItem(), xxxMNDragLeave(), and xxxMNUpdateDraggingInfo().

00064 { 00065 int yTop; 00066 PITEM pItem, pItemGap; 00067 PPOPUPMENU ppopup; 00068 RECT rc; 00069 TL tlHitArea; 00070 00071 /* 00072 * Bail if there is nothing to do. 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 * The menu window might be destroyed by now so pItem could be NULL. 00083 */ 00084 if (pItem == NULL) { 00085 return; 00086 } 00087 00088 /* 00089 * Mark the item and set the rectangle we need to redraw. 00090 * Drawing/erasing the insertion bar unhilites/hiltes the 00091 * item, so pItem needs to be redrawn completely. In additon, 00092 * we need to draw the insertion bar in the next/previous item. 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 * Adjust to "menu" coordinates (for scrollable menus) 00135 */ 00136 yTop = MNGetToppItem(ppopup->spmenu)->yItem; 00137 rc.top -= yTop; 00138 rc.bottom -= yTop; 00139 00140 /* 00141 * Invalidate this rect to repaint it later 00142 */ 00143 ThreadLockAlways((PWND)uHitArea, &tlHitArea); 00144 xxxInvalidateRect((PWND)uHitArea, &rc, TRUE); 00145 ThreadUnlock(&tlHitArea); 00146 }

void xxxMNUpdateDraggingInfo PMENUSTATE  pMenuState,
ULONG_PTR  uHitArea,
UINT  uIndex
 

Definition at line 279 of file menudd.c.

References BOOL, tagITEM::cyItem, FALSE, IsMFMWFPWindow(), LockMFMWFPWindow(), MFMWFP_NOITEM, MFMWFP_OFFMENU, MNGetpItem(), MNGetToppItem(), NULL, tagMENUSTATE::ptMouseLast, tagPOPUPMENU::spmenu, SYSMET, ThreadLock, ThreadUnlock, TRUE, tagMENUSTATE::uDraggingFlags, tagMENUSTATE::uDraggingHitArea, tagMENUSTATE::uDraggingIndex, UINT, xxxMNSetGapState(), and tagITEM::yItem.

Referenced by xxxMNMouseMove().

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 * Remember current dragging area so we can detected when 00291 * crossing item/gap boundries. 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 * Store new dragging area. 00301 */ 00302 LockMFMWFPWindow(&pMenuState->uDraggingHitArea, uHitArea); 00303 pMenuState->uDraggingIndex = uIndex; 00304 00305 /* 00306 * If we're not on a popup, done. 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 * Get the popup and item we're on 00317 */ 00318 ppopup = ((PMENUWND)pMenuState->uDraggingHitArea)->ppopupmenu; 00319 pItem = MNGetpItem(ppopup, pMenuState->uDraggingIndex); 00320 00321 /* 00322 * Find out if we're on the gap, that is, the "virtual" space 00323 * between items. Some apps want to distinguish between a drop 00324 * ON the item and a drop BEFORE/AFTER the item; there is no 00325 * actual space between items so we define a virtual gap 00326 * 00327 */ 00328 pMenuState->uDraggingFlags = 0; 00329 if (pItem != NULL) { 00330 /* 00331 * Map the point to client coordinates and then to "menu" 00332 * coordinates (to take care of scrollable menus) 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 * Top/bottom gap check 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 * Have we crossed an item/gap boundary? 00358 * We don't cross a boundary when we move from the bottom 00359 * of an item to the top of the next, or, from the top 00360 * of an item to the bottom of the previous. 00361 * (Item N is on top of and previous to item N+1). 00362 */ 00363 fCross = (uLastHitArea != pMenuState->uDraggingHitArea); 00364 if (!fCross) { 00365 iIndexDelta = (int)pMenuState->uDraggingIndex - (int)uLastIndex; 00366 switch (iIndexDelta) { 00367 case 0: 00368 /* 00369 * We're on the same item. 00370 */ 00371 fCross = (uLastFlags != pMenuState->uDraggingFlags); 00372 break; 00373 00374 case 1: 00375 /* 00376 * We've moved to the next item 00377 */ 00378 fCross = !((pMenuState->uDraggingFlags == MNGOF_TOPGAP) 00379 && (uLastFlags == MNGOF_BOTTOMGAP)); 00380 break; 00381 00382 case -1: 00383 /* 00384 * We've moved to the previous item 00385 */ 00386 fCross = !((pMenuState->uDraggingFlags == MNGOF_BOTTOMGAP) 00387 && (uLastFlags == MNGOF_TOPGAP)); 00388 break; 00389 00390 default: 00391 /* 00392 * We've skipped more than one item. 00393 */ 00394 fCross = TRUE; 00395 } 00396 } 00397 00398 if (fCross) { 00399 pMenuState->uDraggingFlags |= MNGOF_CROSSBOUNDARY; 00400 00401 /* 00402 * Update the insertion bar state. 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 }


Generated on Sat May 15 19:44:38 2004 for test by doxygen 1.3.7