VOID xxxSendNCPaint( PWND pwnd, HRGN hrgnUpdate) { CheckLock(pwnd); /* * Clear the WFSENDNCPAINT bit... */ ClrWF(pwnd, WFSENDNCPAINT); /* * If the window is active, but its FRAMEON bit hasn't * been set yet, set it and make sure that the entire frame * gets redrawn when we send the NCPAINT. */ if ((pwnd == PtiCurrent()->pq->spwndActive) && !TestWF(pwnd, WFFRAMEON)) { SetWF(pwnd, WFFRAMEON); hrgnUpdate = HRGN_FULL; ClrWF(pwnd, WFNONCPAINT); } /* * If PixieHack() has set the WM_NCPAINT bit, we must be sure * to send with hrgnClip == HRGN_FULL. (see PixieHack() in wmupdate.c) */ if (TestWF(pwnd, WFPIXIEHACK)) { ClrWF(pwnd, WFPIXIEHACK); hrgnUpdate = HRGN_FULL; } if (hrgnUpdate) xxxSendMessage(pwnd, WM_NCPAINT, (WPARAM)hrgnUpdate, 0L); }
/***************************************************************************\ * xxxMNGetBitmapSize * * returns TRUE if measureitem was sent and FALSE if not * * History: * 07-23-96 GerardoB - Added header & fixed up for 5.0 \***************************************************************************/ BOOL xxxMNGetBitmapSize(LPITEM pItem, PWND pwndNotify) { MEASUREITEMSTRUCT mis; if (pItem->cxBmp != MNIS_MEASUREBMP) { return FALSE; } // Send a measure item message to the owner mis.CtlType = ODT_MENU; mis.CtlID = 0; mis.itemID = pItem->wID; mis.itemWidth = 0; // After scrollable menus // mis32.itemHeight= gcyMenuFontChar; mis.itemHeight= (UINT)gpsi->cySysFontChar; mis.itemData = pItem->dwItemData; xxxSendMessage(pwndNotify, WM_MEASUREITEM, 0, (LPARAM)&mis); pItem->cxBmp = mis.itemWidth; pItem->cyBmp = mis.itemHeight; return TRUE; }
void xxxSendHelpMessage( PWND pwnd, int iType, int iCtrlId, HANDLE hItemHandle, DWORD dwContextId) { HELPINFO HelpInfo; long lValue; CheckLock(pwnd); HelpInfo.cbSize = sizeof(HELPINFO); HelpInfo.iContextType = iType; HelpInfo.iCtrlId = iCtrlId; HelpInfo.hItemHandle = hItemHandle; HelpInfo.dwContextId = dwContextId; lValue = _GetMessagePos(); HelpInfo.MousePos.x = GET_X_LPARAM(lValue); HelpInfo.MousePos.y = GET_Y_LPARAM(lValue); xxxSendMessage(pwnd, WM_HELP, 0, (LPARAM)(LPHELPINFO)&HelpInfo); }
BOOL xxxShowWindow( PWND pwnd, DWORD cmdShowAnimate) { BOOL fVisOld, fVisNew; UINT swpFlags = SWP_NOMOVE | SWP_NOSIZE; PTHREADINFO pti; BOOL bFirstMain = FALSE; int cmdShow = LOWORD(cmdShowAnimate); CheckLock(pwnd); fVisOld = TestWF(pwnd, WFVISIBLE); pti = PtiCurrent(); /* * See if this is the first "main" top level * window being created by this application - if show, assume it * is showing with the SW_SHOWDEFAULT command. * * Checks for: * - cmdShow is a "default" show command * - we haven't done startupinfo yet (we only use it once) * - this is not a child (it is a top level window) * - this has a titlebar (indicator of the main window) * - it isn't owned (indicator of the main window) */ if ((pti->ppi->usi.dwFlags & STARTF_USESHOWWINDOW) && !TestwndChild(pwnd) && (TestWF(pwnd, WFBORDERMASK) == (BYTE)LOBYTE(WFCAPTION)) && (pwnd->spwndOwner == NULL)) { bFirstMain = TRUE; switch (cmdShow) { case SW_SHOWNORMAL: case SW_SHOW: /* * Then assume default! */ cmdShow = SW_SHOWDEFAULT; break; } } /* * If this application specified SW_SHOWDEFAULT, then we get the * real SW_* command from the application's STARTUPINFO structure * (STARTUPINFO is passed to CreateProcess() when this application * was launched). */ if (cmdShow == SW_SHOWDEFAULT) { /* * Call the client to get the SW_* command from the STARTUPINFO * for this process. */ if (pti->ppi->usi.dwFlags & STARTF_USESHOWWINDOW) { bFirstMain = TRUE; cmdShow = pti->ppi->usi.wShowWindow; #if 0 switch (cmdShow) { case SW_SHOWMINIMIZED: case SW_MINIMIZE: /* * If the default show was "minimized", then make sure it doesn't * become active. Minimized is effectively "background". */ cmdShow = SW_SHOWMINNOACTIVE; break; } #endif } } // // This is in case someone said SW_SHOWDEFAULT but has no startupinfo. // Or in case cmdShow inside of STARTUPINFO is SW_SHOWDEFAULT. // if (cmdShow == SW_SHOWDEFAULT) cmdShow = SW_SHOWNORMAL; /* * Turn off startup info. We turn this off after the first call to * ShowWindow. If we don't apps can be started by progman with * the start info being minimized and then be restored and then * call ShowWindow(SW_SHOW) and the app would minimize again. * Notepad had that problem 2985. */ if (bFirstMain) { pti->ppi->usi.dwFlags &= ~(STARTF_USESHOWWINDOW|STARTF_USESIZE \ | STARTF_USEPOSITION); } /* * Take care of all the OLD show commands with columns & iconslot. */ if (cmdShow & 0xFF00) { if ((cmdShow & 0xFF80) == (int)0xFF80) cmdShow = SW_SHOWMINNOACTIVE; else cmdShow = SW_SHOW; } /* * Change to new fullscreen if needed and in same desktop */ if ((pwnd->bFullScreen != WINDOWED) && (pwnd->head.rpdesk == grpdeskRitInput)) { if ((cmdShow == SW_SHOWNORMAL) || (cmdShow == SW_RESTORE) || (cmdShow == SW_MAXIMIZE) || (cmdShow == SW_SHOWMAXIMIZED)) { cmdShow = SW_SHOWMINIMIZED; if (pwnd->bFullScreen == FULLSCREENMIN) { pwnd->bFullScreen = FULLSCREEN; } if (gpqForeground != NULL && gpqForeground->spwndActive == pwnd) { xxxMakeWindowForegroundWithState(NULL, 0); } } } switch (cmdShow) { case SW_SHOWNOACTIVATE: case SW_SHOWNORMAL: case SW_RESTORE: /* * If min/max, let xxxMinMaximize() do all the work. */ if (TestWF(pwnd, WFMINIMIZED) || TestWF(pwnd, WFMAXIMIZED)) { xxxMinMaximize(pwnd, (UINT)cmdShow, cmdShowAnimate & MINMAX_ANIMATE); return fVisOld; } else { /* * Ignore if the window is already visible. */ if (fVisOld) { return fVisOld; } swpFlags |= SWP_SHOWWINDOW; if ( cmdShow == SW_SHOWNOACTIVATE) { swpFlags |= SWP_NOZORDER; #ifdef NEVER /* * This is what win3.1 does. On NT, since each "queue" has * its own active window, there is often no active window. * In this case, win3.1 turns a SHOWNOACTIVATE into a "SHOW * with activate". Since win3.1 almost always has an active * window, this almost never happens. So on NT, we're not * going to do this check - that way we'll be more compatible * with win3.1 because we'll usally not activate (like win3.1). * With this check, this causes FoxPro 2.5 for Windows to not * properly activate its command window when first coming up. */ if (pti->pq->spwndActive != NULL) swpFlags |= SWP_NOACTIVATE; #else swpFlags |= SWP_NOACTIVATE; #endif } } break; case SW_SHOWMINNOACTIVE: case SW_SHOWMINIMIZED: case SW_SHOWMAXIMIZED: case SW_MINIMIZE: xxxMinMaximize(pwnd, (UINT)cmdShow, cmdShowAnimate & MINMAX_ANIMATE); return fVisOld; case SW_SHOWNA: swpFlags |= SWP_SHOWWINDOW | SWP_NOACTIVATE; // LATER removed this to be compatible with SHOWNOACTIVATE //if (pti->pq->spwndActive != NULL) // swpFlags |= SWP_NOACTIVATE; break; case SW_SHOW: /* * Don't bother if it is already visible. */ if (fVisOld) return fVisOld; swpFlags |= SWP_SHOWWINDOW; if (cmdShow == SW_SHOWNOACTIVATE) { swpFlags |= SWP_NOZORDER | SWP_NOACTIVATE; } break; case SW_HIDE: /* * Don't bother if it is already hidden. */ if (!fVisOld) return fVisOld; swpFlags |= SWP_HIDEWINDOW; if (pwnd != pti->pq->spwndActive) swpFlags |= (SWP_NOACTIVATE | SWP_NOZORDER); break; default: RIPERR0(ERROR_INVALID_SHOWWIN_COMMAND, RIP_VERBOSE, ""); return fVisOld; } /* * If we're changing from visible to hidden or vise-versa, send * WM_SHOWWINDOW. */ fVisNew = !(cmdShow == SW_HIDE); if (fVisNew != fVisOld) { xxxSendMessage(pwnd, WM_SHOWWINDOW, fVisNew, 0L); if (!TestWF(pwnd, WFWIN31COMPAT)) { xxxSendMessage(pwnd, WM_SETVISIBLE, fVisNew, 0L); } } if (!TestwndChild(pwnd)) { if (TestCF(pwnd, CFSAVEBITS)) { /* * Activate to prevent discarding saved bits??? */ if (cmdShow == SW_SHOW || cmdShow == SW_SHOWNORMAL) { xxxActivateWindow(pwnd, AW_USE); swpFlags |= SWP_NOZORDER | SWP_NOACTIVATE; } } } else { /* * Children can't get activation... */ swpFlags |= (SWP_NOACTIVATE | SWP_NOZORDER); } /* * If our parent is hidden, don't bother to call xxxSetWindowPos. */ if (_FChildVisible(pwnd)) { xxxSetWindowPos(pwnd, (PWND)NULL, 0, 0, 0, 0, swpFlags); } else { if (cmdShow == SW_HIDE) ClrWF(pwnd, WFVISIBLE); else SetWF(pwnd, WFVISIBLE); } /* * Send size and move messages AFTER repainting */ if (TestWF(pwnd, WFSENDSIZEMOVE)) { ClrWF(pwnd, WFSENDSIZEMOVE); if (TestWF(pwnd, WFMINIMIZED)) { xxxSendSizeMessage(pwnd, SIZEICONIC); } else if (TestWF(pwnd, WFMAXIMIZED)) { xxxSendSizeMessage(pwnd, SIZEFULLSCREEN); } else { xxxSendSizeMessage(pwnd, SIZENORMAL); } if (pwnd->spwndParent) { xxxSendMessage(pwnd, WM_MOVE, 0, MAKELONG( pwnd->rcClient.left - pwnd->spwndParent->rcClient.left, pwnd->rcClient.top - pwnd->spwndParent->rcClient. top)); } else { /* * NULL parent implies this window is a zombie */ xxxSendMessage(pwnd, WM_MOVE, 0, MAKELONG( pwnd->rcClient.left, pwnd->rcClient.top)); } } /* * If hiding and is active-foreground window, activate someone else. * If hiding a active window make someone active. */ if (cmdShow == SW_HIDE) { if ((pwnd == pti->pq->spwndActive) && (pti->pq == gpqForeground)) { xxxActivateWindow(pwnd, AW_SKIP); } else { xxxCheckFocus(pwnd); } } return fVisOld; }
void xxxShowOwnedWindows( PWND pwndOwner, UINT cmdShow) { BOOL fShow; int cmdZoom; HWND *phwnd; PBWL pbwl; PWND pwnd, pwndTopOwner; TL tlpwnd; CheckLock(pwndOwner); /* * Not interested in child windows */ if (TestwndChild(pwndOwner)) return; if ((pbwl = BuildHwndList(PWNDDESKTOP(pwndOwner)->spwndChild, BWL_ENUMLIST, NULL)) == NULL) return; /* * NOTE: The following code assumes the values of SW_* are 1, 2, 3, and 4 */ fShow = (cmdShow >= SW_PARENTOPENING); cmdZoom = 0; if (cmdShow == SW_OTHERZOOM) cmdZoom = SIZEZOOMHIDE; if (cmdShow == SW_OTHERUNZOOM) cmdZoom = SIZEZOOMSHOW; /* * If zoom/unzoom, then open/close all popups owned by all other * windows. Otherwise, open/close popups owned by pwndOwner. */ for (phwnd = pbwl->rghwnd; *phwnd != (HWND)1; phwnd++) { /* * Lock the window before we play with it. * If the window handle is invalid, skip it */ if ((pwnd = RevalidateHwnd(*phwnd)) == NULL) continue; /* * Kanji windows can't be owned, so skip it. */ if (TestCF(pwnd, CFKANJIWINDOW)) continue; /* * If same as window passed in, skip it. */ if (pwnd == pwndOwner) continue; /* * Find ultimate owner of popup, but only go up as far as pwndOwner. */ if ((pwndTopOwner = pwnd->spwndOwner) != NULL) { /* * The TestwndHI is needed since if it has an icon, pwndOwner * is invalid. */ while (!TestwndHI(pwndTopOwner) && pwndTopOwner != pwndOwner && pwndTopOwner->spwndOwner != NULL) pwndTopOwner = pwndTopOwner->spwndOwner; } /* * Zoom/Unzoom case. */ if (cmdZoom != 0) { /* * If no parent, or parents are the same, skip. */ if (pwndTopOwner == NULL || pwndTopOwner == pwndOwner) continue; /* * If owner is iconic, then this window should stay hidden, * UNLESS the minimized window is disabled, in which case we'd * better show the window. */ if ( cmdShow == SW_OTHERUNZOOM && pwndTopOwner != NULL && TestWF(pwndTopOwner, WFMINIMIZED) && !TestWF(pwndTopOwner, WFDISABLED) ) continue; } else { /* * Hide/Iconize/Show/Open case. */ /* * If parents aren't the same, skip. */ if (pwndTopOwner != pwndOwner) continue; } /* * Hide or show if: * Showing & this is a hidden popup * OR * Hiding & this is a visible window */ if ((fShow && TestWF(pwnd, WFHIDDENPOPUP)) || (!fShow && TestWF(pwnd, WFVISIBLE))) { ThreadLockAlways(pwnd, &tlpwnd); xxxSendMessage(pwnd, WM_SHOWWINDOW, fShow, (LONG)cmdShow); ThreadUnlock(&tlpwnd); } } /* * Free the window list. */ FreeHwndList(pbwl); }
BOOL xxxSendEraseBkgnd( PWND pwnd, HDC hdcBeginPaint, HRGN hrgnUpdate) { PTHREADINFO ptiCurrent; BOOL fErased; HDC hdc; CheckLock(pwnd); /* * For minimized dudes in win3.1, we would've sent an * WM_ICONERASEBKGND and cleared the erase bit. Now that min * windows in 4.0 are all nonclient, don't bother erasing at * all. Pretend like we did. * * NOTE: * For < 4.0 windows, we may have to send a fake WM_ICONERASEKBGND * to keep 'em happy. Saves time not to though. Getting a DC and * sending the message ain't speedy. */ if ((hrgnUpdate == NULL) || TestWF(pwnd, WFMINIMIZED)) return FALSE; /* * If a DC to use was not passed in, get one. * We want one clipped to this window's update region. */ if (hdcBeginPaint == NULL) { hdc = _GetDCEx(pwnd, hrgnUpdate, DCX_USESTYLE | DCX_INTERSECTRGN | DCX_NODELETERGN); } else { hdc = hdcBeginPaint; } /* * If we're send the WM_ERASEBKGND to another process * we need to change the DC owner. * * We'd like to change the owner to pwnd->pti->idProcess, but * GDI won't let us assign ownership back to ourselves later. */ ptiCurrent = PtiCurrent(); if (GETPTI(pwnd)->ppi != ptiCurrent->ppi) GreSetDCOwner(hdc, OBJECT_OWNER_PUBLIC); /* * Send the event to the window. This contains the DC clipped to * the update-region. */ fErased = (BOOL)xxxSendMessage(pwnd, WM_ERASEBKGND, (WPARAM)hdc, 0L); /* * If we've changed the DC owner, change it back to * the current process. */ if (GETPTI(pwnd)->ppi != ptiCurrent->ppi) GreSetDCOwner(hdc, OBJECT_OWNER_CURRENT); /* * If the WM_ERASEBKGND message did not erase the * background, then set this flag to let BeginPaint() * know to ask the caller to do it via the fErase * flag in the PAINTSTRUCT. */ if (!fErased) { SetWF(pwnd, WFERASEBKGND); if (!TestWF(pwnd, WFWIN31COMPAT)) SetWF(pwnd, WFSENDERASEBKGND); } /* * If we got a cache DC in this routine, release it. */ if (hdcBeginPaint == NULL) { ReleaseCacheDC(hdc, TRUE); } return fErased; }
LRESULT xxxTooltipWndProc(PWND pwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; PTOOLTIPWND pttwnd; CheckLock(pwnd); VALIDATECLASSANDSIZE(pwnd, uMsg, wParam, lParam, FNID_TOOLTIP, WM_NCCREATE); pttwnd = (PTOOLTIPWND)pwnd; switch(uMsg) { case WM_TIMER: xxxTooltipHandleTimer(pttwnd, (UINT)wParam); break; case WM_PAINT: xxxBeginPaint(pwnd, &ps); TooltipRender(pttwnd, ps.hdc); xxxEndPaint(pwnd, &ps); break; case WM_PRINTCLIENT: TooltipRender(pttwnd, (HDC)wParam); break; case WM_ERASEBKGND: break; case WM_NCCREATE: InitTooltipDelay(pttwnd); InitTooltipAnimation(pttwnd); goto CallDWP; case WM_NCDESTROY: CleanupTooltipAnimation(pttwnd); GETPDESK(pttwnd)->dwDTFlags &= ~DF_TOOLTIP; goto CallDWP; case WM_WINDOWPOSCHANGED: if (((LPWINDOWPOS)lParam)->flags & SWP_SHOWWINDOW) { HDC hdc; int cx; int cy; if (!TestEffectUP(TOOLTIPANIMATION)) { SetTooltipTimer(pttwnd, TTT_HIDE, pttwnd->dwHideDelay); goto CallDWP; } hdc = NULL; cx = pttwnd->rcWindow.right - pttwnd->rcWindow.left; cy = pttwnd->rcWindow.bottom - pttwnd->rcWindow.top; /* * At this point we're sure that the window is showing and the size * has been changed and we're in the context of the desktop thread. */ if (TestALPHA(TOOLTIPFADE)) { hdc = CreateFade((PWND)pttwnd, NULL, CMS_TOOLTIP, FADE_SHOW | FADE_TOOLTIP); } else { if (CreateTooltipBitmap(pttwnd, cx, cy)) { hdc = pttwnd->hdcMem; } } if (hdc == NULL) { SetTooltipTimer(pttwnd, TTT_HIDE, 0); goto CallDWP; } xxxSendMessage((PWND)pttwnd, WM_PRINT, (WPARAM)hdc, PRF_CLIENT | PRF_NONCLIENT | PRF_CHILDREN | PRF_ERASEBKGND); /* * Start animation timer */ if (TestFadeFlags(FADE_TOOLTIP)) { StartFade(); SetTooltipTimer(pttwnd, TTT_HIDE, pttwnd->dwHideDelay); } else { pttwnd->dwAnimStart = NtGetTickCount(); SetTooltipTimer(pttwnd, TTT_ANIMATE, TT_ANIMATEDELAY); } } else if (((LPWINDOWPOS)lParam)->flags & SWP_HIDEWINDOW) { if (TestFadeFlags(FADE_TOOLTIP)) { StopFade(); } else { DestroyTooltipBitmap(pttwnd); } } goto CallDWP; default: CallDWP: return xxxDefWindowProc(pwnd, uMsg, wParam, lParam); } return 0; }
/*****************************************************************************\ * xxxGetMenuBarInfo() * * This succeeds if the menu/menu item exists. * * Parameters: * pwnd window * idObject this can be OBJID_MENU, OBJID_SYSMENU, or OBJID_CLIENT * idItem which thing do we need info on? 0..cItems. 0 indicates * the menu itself, 1 is the first item on the menu... * pmbi Pointer to a MENUBARINFO structure that gets filled in * \*****************************************************************************/ BOOL WINAPI xxxGetMenuBarInfo(PWND pwnd, long idObject, long idItem, PMENUBARINFO pmbi) { PMENU pMenu; int cBorders; PITEM pItem; PPOPUPMENU ppopup; CheckLock(pwnd); /* * Validate menubarinfo structure */ if (pmbi->cbSize != sizeof(MENUBARINFO)) { RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING, "MENUBARINFO.cbSize %d is wrong", pmbi->cbSize); return FALSE; } /* * Initialize the fields */ SetRectEmpty(&pmbi->rcBar); pmbi->hMenu = NULL; pmbi->hwndMenu = NULL; pmbi->fBarFocused = FALSE; pmbi->fFocused = FALSE; /* * Get the menu handle we will deal with. */ if (idObject == OBJID_MENU) { int cBorders; if (TestWF(pwnd, WFCHILD) || !pwnd->spmenu) return FALSE; pMenu = pwnd->spmenu; if (!pMenu) return FALSE; // If we have an item, is it in the valid range? if ((idItem < 0) || ((DWORD)idItem > pMenu->cItems)) return FALSE; /* * Menu handle */ pmbi->hMenu = PtoHq(pMenu); /* * Menu rect */ if (pMenu->cxMenu && pMenu->cyMenu) { if (!idItem) { cBorders = GetWindowBorders(pwnd->style, pwnd->ExStyle, TRUE, FALSE); pmbi->rcBar.left = pwnd->rcWindow.left + cBorders * SYSMET(CXBORDER); pmbi->rcBar.top = pwnd->rcWindow.top + cBorders * SYSMET(CYBORDER); if (TestWF(pwnd, WFCPRESENT)) { pmbi->rcBar.top += (TestWF(pwnd, WEFTOOLWINDOW) ? SYSMET(CYSMCAPTION) : SYSMET(CYCAPTION)); } pmbi->rcBar.right = pmbi->rcBar.left + pMenu->cxMenu; pmbi->rcBar.bottom = pmbi->rcBar.top + pMenu->cyMenu; } else { pItem = pMenu->rgItems + idItem - 1; pmbi->rcBar.left = pwnd->rcWindow.left + pItem->xItem; pmbi->rcBar.top = pwnd->rcWindow.top + pItem->yItem; pmbi->rcBar.right = pmbi->rcBar.left + pItem->cxItem; pmbi->rcBar.bottom = pmbi->rcBar.top + pItem->cyItem; } } /* * Are we currently in app menu bar mode? */ ppopup = GetpGlobalPopupMenu(pwnd); if (ppopup && ppopup->fHasMenuBar && !ppopup->fIsSysMenu && (ppopup->spwndNotify == pwnd)) { // Yes, we are. pmbi->fBarFocused = TRUE; if (!idItem) { pmbi->fFocused = TRUE; } else if (ppopup->ppopupmenuRoot->posSelectedItem == (UINT)idItem-1) { pmbi->fFocused = TRUE; UserAssert(ppopup->ppopupmenuRoot); pmbi->hwndMenu = HW(ppopup->ppopupmenuRoot->spwndNextPopup); } } } else if (idObject == OBJID_SYSMENU) { if (!TestWF(pwnd, WFSYSMENU)) return FALSE; pMenu = xxxGetSysMenu(pwnd, FALSE); if (!pMenu) return FALSE; // If we have an item, is it in the valid range? if ((idItem < 0) || ((DWORD)idItem > pMenu->cItems)) return FALSE; pmbi->hMenu = PtoHq(pMenu); /* * Menu rect */ if (_HasCaptionIcon(pwnd)) { // The menu and single item take up the same space cBorders = GetWindowBorders(pwnd->style, pwnd->ExStyle, TRUE, FALSE); pmbi->rcBar.left = pwnd->rcWindow.left + cBorders * SYSMET(CXBORDER); pmbi->rcBar.top = pwnd->rcWindow.top + cBorders * SYSMET(CYBORDER); pmbi->rcBar.right = pmbi->rcBar.left + (TestWF(pwnd, WEFTOOLWINDOW) ? SYSMET(CXSMSIZE) : SYSMET(CXSIZE)); pmbi->rcBar.bottom = pmbi->rcBar.top + (TestWF(pwnd, WEFTOOLWINDOW) ? SYSMET(CYSMSIZE) : SYSMET(CYSIZE)); } /* * Are we currently in system menu bar mode? */ ppopup = GetpGlobalPopupMenu(pwnd); if (ppopup && ppopup->fHasMenuBar && ppopup->fIsSysMenu && (ppopup->spwndNotify == pwnd)) { // Yes, we are. pmbi->fBarFocused = TRUE; if (!idItem) { pmbi->fFocused = TRUE; } else if (ppopup->ppopupmenuRoot->posSelectedItem == (UINT)idItem - 1) { pmbi->fFocused = TRUE; UserAssert(ppopup->ppopupmenuRoot); pmbi->hwndMenu = HW(ppopup->ppopupmenuRoot->spwndNextPopup); } } } else if (idObject == OBJID_CLIENT) { HMENU hMenu; hMenu = (HMENU)xxxSendMessage(pwnd, MN_GETHMENU, 0, 0); pMenu = HtoP(hMenu); if (!pMenu) return FALSE; // If we have an item, is it in the valid range? if ((idItem < 0) || ((DWORD)idItem > pMenu->cItems)) return FALSE; pmbi->hMenu = hMenu; if (!idItem) { pmbi->rcBar = pwnd->rcClient; } else { pItem = pMenu->rgItems + idItem - 1; pmbi->rcBar.left = pwnd->rcClient.left + pItem->xItem; pmbi->rcBar.top = pwnd->rcClient.top + pItem->yItem; pmbi->rcBar.right = pmbi->rcBar.left + pItem->cxItem; pmbi->rcBar.bottom = pmbi->rcBar.top + pItem->cyItem; } /* * Are we currently in popup mode with us as one of the popups * showing? */ ppopup = ((PMENUWND)pwnd)->ppopupmenu; if (ppopup && (ppopup->ppopupmenuRoot == GetpGlobalPopupMenu(pwnd))) { pmbi->fBarFocused = TRUE; if (!idItem) { pmbi->fFocused = TRUE; } else if ((UINT)idItem == ppopup->posSelectedItem + 1) { pmbi->fFocused = TRUE; pmbi->hwndMenu = HW(ppopup->spwndNextPopup); } } } else { return FALSE; } return TRUE; }
/***************************************************************************\ * xxxCsEvent * * Description: * Handles broadcasting of all types of DDEML events. * * History: * 11-1-91 sanfords Created. * 10-28-97 FritzS added cbEventData as a passed-in parameter. This was done because the EVENT_PACKET may be client-side and we capture the count to keep a hostile app from changing the size after data probing. \***************************************************************************/ DWORD xxxCsEvent( PEVENT_PACKET pep, WORD cbEventData) { PSVR_INSTANCE_INFO psiiT; PEVENT_PACKET pep2; HWND *ahwndEvent = NULL; PWND pwnd; int cHwndAllocated, i, cTargets; TL tlpwnd; TL tlpep2; TL tlahwndEvent; ULONG cbEventPacket; PTHREADINFO pti = PtiCurrent(); CheckCritIn(); /* * Copy pep info to a server side stable area */ cbEventPacket = cbEventData + sizeof(EVENT_PACKET) - sizeof(DWORD); pep2 = (PEVENT_PACKET)UserAllocPoolWithQuota(cbEventPacket, TAG_DDE5); if (pep2 == NULL) { return DMLERR_MEMORY_ERROR; } try { RtlCopyMemory((LPSTR)pep2, (LPSTR)pep, cbEventPacket); } except (W32ExceptionHandler(FALSE, RIP_WARNING)) { UserFreePool(pep2); return DMLERR_INVALIDPARAMETER; } pep2->cbEventData = cbEventData; cTargets = 0; cHwndAllocated = 0; for (psiiT = psiiList; psiiT != NULL; psiiT = psiiT->next) { // // Don't bother with event windows for instances who's flags // indicate they're not interrested in the event. // if (((psiiT->afCmd & pep2->EventType) && !pep2->fSense) || (!(psiiT->afCmd & pep2->EventType) && pep2->fSense)) { continue; } if (cTargets >= cHwndAllocated) { if (ahwndEvent == NULL) { cHwndAllocated = 8; ahwndEvent = (HWND *)UserAllocPoolWithQuota( sizeof(HWND) * cHwndAllocated, TAG_DDE6); } else { DWORD dwSize = cHwndAllocated * sizeof(HWND); HWND *ahwndEventT = ahwndEvent; cHwndAllocated += 8; ahwndEvent = (HWND *)UserReAllocPoolWithQuota(ahwndEvent, dwSize, sizeof(HWND) * cHwndAllocated, TAG_DDE7); if (ahwndEvent == NULL) { UserFreePool(ahwndEventT); } } if (ahwndEvent == NULL) { UserFreePool(pep2); return DMLERR_MEMORY_ERROR; } } ahwndEvent[cTargets++] = PtoH(psiiT->spwndEvent); } ThreadLockPool(pti, pep2, &tlpep2); if (ahwndEvent != NULL) { ThreadLockPool(pti, ahwndEvent, &tlahwndEvent); for (i = 0; i < cTargets; i++) { /* * We need to change contexts for the callback */ pwnd = ValidateHwnd(ahwndEvent[i]); if (pwnd != NULL) { ThreadLockAlwaysWithPti(pti, pwnd, &tlpwnd); xxxSendMessage(pwnd, WM_DDEMLEVENT, 0, (LPARAM)pep2); ThreadUnlock(&tlpwnd); } } ThreadUnlockAndFreePool(pti, &tlahwndEvent); } ThreadUnlockAndFreePool(pti, &tlpep2); return DMLERR_NO_ERROR; }
BOOL xxxMNStartState( PPOPUPMENU ppopupmenu, int mn) { PWND pwndMenu; PMENUSTATE pMenuState; TL tlpwndMenu; TL tlpmenu; UserAssert(IsRootPopupMenu(ppopupmenu)); if (ppopupmenu->fDestroyed) { return FALSE; } pwndMenu = ppopupmenu->spwndNotify; ThreadLock(pwndMenu, &tlpwndMenu); pMenuState = GetpMenuState(pwndMenu); if (pMenuState == NULL) { RIPMSG0(RIP_ERROR, "xxxMNStartState: pMenuState == NULL"); return FALSE; } pMenuState->mnFocus = mn; pMenuState->fMenuStarted = TRUE; pMenuState->fButtonDown = FALSE; /* * Lotus Freelance demo programs depend on GetCapture returning their hwnd * when in menumode. */ xxxCapture(PtiCurrent(), ppopupmenu->spwndNotify, SCREEN_CAPTURE); xxxSendMessage(pwndMenu, WM_SETCURSOR, (DWORD)HWq(pwndMenu), MAKELONG(MSGF_MENU, 0)); if (ppopupmenu->fIsMenuBar) { BOOL fSystemMenu; PMENU pMenu; pMenu = GetInitMenuParam(pwndMenu, &fSystemMenu); if (pMenu == NULL) { pMenuState->fMenuStarted = FALSE; xxxSetCapture(NULL); ThreadUnlock(&tlpwndMenu); return(FALSE); } Lock(&(ppopupmenu->spmenu), pMenu); ppopupmenu->fIsSysMenu = (fSystemMenu != 0); if (!fSystemMenu) Lock(&(ppopupmenu->spmenuAlternate), GetSysMenu(pwndMenu, FALSE)); } pMenuState->fIsSysMenu = (ppopupmenu->fIsSysMenu != 0); if (!ppopupmenu->fNoNotify) { PMENU pMenu; if (ppopupmenu->fIsTrackPopup && ppopupmenu->fIsSysMenu) pMenu = GetInitMenuParam(pwndMenu, NULL); else pMenu = ppopupmenu->spmenu; xxxSendMessage(pwndMenu, WM_INITMENU, (DWORD)PtoH(pMenu), 0L); } if (!ppopupmenu->fIsTrackPopup) { if (ppopupmenu->fIsSysMenu) { MNPositionSysMenu(pwndMenu, ppopupmenu->spmenu); } else if (ppopupmenu->fIsMenuBar) { ThreadLock(ppopupmenu->spmenu, &tlpmenu); xxxMNRecomputeBarIfNeeded(pwndMenu, ppopupmenu->spmenu); ThreadUnlock(&tlpmenu); MNPositionSysMenu(pwndMenu, ppopupmenu->spmenuAlternate); } } ThreadUnlock(&tlpwndMenu); return !ppopupmenu->fDestroyed; }
/***************************************************************************\ * xxxMNStartMenuState * * This function is called when the menu bar is about to be activated (the * app's main menu). It makes sure that the threads involved are not in * menu mode already, finds the owner/notification window, initializes * pMenuState and sends the WM_ENTERMENULOOP message. * It successful, it returns a pointer to a pMenuState. If so, the caller * must call MNEndMenuState when done. * * History: * 4-25-91 Mikehar Port for 3.1 merge * 5-20-96 GerardoB Renamed and changed (Old name: xxxMNGetPopup) \***************************************************************************/ PMENUSTATE xxxMNStartMenuState(PWND pwnd) { PPOPUPMENU ppopupmenu; PTHREADINFO ptiCurrent, ptiNotify; PMENUSTATE pMenuState; TL tlpwnd; CheckLock(pwnd); /* * Bail if the current thread is already in menu mode */ ptiCurrent = PtiCurrent(); if (ptiCurrent->pMenuState != NULL) { return NULL; } /* * If the window doesn't have any children, return pwndActive. */ if (!TestwndChild(pwnd)) { pwnd = GETPTI(pwnd)->pq->spwndActive; } else { /* * Search up the parents for a window with a System Menu. */ while (TestwndChild(pwnd)) { if (TestWF(pwnd, WFSYSMENU)) break; pwnd = pwnd->spwndParent; } } if (pwnd == NULL) { return NULL; } if (!TestwndChild(pwnd) && (pwnd->spmenu != NULL)) { goto hasmenu; } if (!TestWF(pwnd, WFSYSMENU)) { return NULL; } hasmenu: /* * If the owner/notification window was created by another thread, * make sure that it's not in menu mode already * This can happen if PtiCurrent() is attached to other threads, one of * which created pwnd. */ ptiNotify = GETPTI(pwnd); if (ptiNotify->pMenuState != NULL) { return NULL; } /* * Allocate ppoupmenu and pMenuState */ ppopupmenu = MNAllocPopup(FALSE); if (ppopupmenu == NULL) { return NULL; } pMenuState = MNAllocMenuState(ptiCurrent, ptiNotify, ppopupmenu); if (pMenuState == NULL) { MNFreePopup(ppopupmenu); return NULL; } ppopupmenu->fIsMenuBar = TRUE; ppopupmenu->fHasMenuBar = TRUE; Lock(&(ppopupmenu->spwndNotify), pwnd); ppopupmenu->posSelectedItem = MFMWFP_NOITEM; Lock(&(ppopupmenu->spwndPopupMenu), pwnd); ppopupmenu->ppopupmenuRoot = ppopupmenu; /* * Notify the app we are entering menu mode. wParam is always 0 since this * procedure will only be called for menu bar menus not TrackPopupMenu * menus. */ ThreadLockAlways(pwnd, &tlpwnd); xxxSendMessage(pwnd, WM_ENTERMENULOOP, 0, 0L); ThreadUnlock(&tlpwnd); return pMenuState; }
BOOL xxxClientShutdown2( PBWL pbwl, UINT msg, DWORD wParam) { HWND *phwnd; PWND pwnd; TL tlpwnd; BOOL fEnd; PTHREADINFO ptiCurrent; BOOL fDestroyTimers; LPARAM lParam; ptiCurrent = PtiCurrent(); /* * Make sure we don't send this window any more WM_TIMER * messages if the session is ending. This was causing * AfterDark to fault when it freed some memory on the * WM_ENDSESSION and then tried to reference it on the * WM_TIMER. * LATER GerardoB: Do we still need to do this?? * Do this horrible thing only if the process is in the * context being logged off. * Perhaps someday we should post a WM_CLOSE so the app * gets a better chance to clean up (if this process is in * the context being logged off, winsrv is going to call * TerminateProcess soon after this). */ fDestroyTimers = (wParam & WMCS_EXIT) && (wParam & WMCS_CONTEXTLOGOFF); /* * fLogOff and fEndSession parameters (WM_ENDSESSION only) */ lParam = wParam & ENDSESSION_LOGOFF; wParam &= WMCS_EXIT; /* * Now enumerate these windows and send the WM_QUERYENDSESSION or * WM_ENDSESSION messages. */ for (phwnd = pbwl->rghwnd; *phwnd != (HWND)1; phwnd++) { if ((pwnd = RevalidateHwnd(*phwnd)) == NULL) continue; ThreadLockAlways(pwnd, &tlpwnd); /* * Send the message. */ switch (msg) { case WM_QUERYENDSESSION: /* * Windows does not send the WM_QUERYENDSESSION to the app * that called ExitWindows */ if (ptiCurrent == gptiShutdownNotify) { fEnd = TRUE; } else { fEnd = xxxSendMessage(pwnd, WM_QUERYENDSESSION, FALSE, lParam); } break; case WM_ENDSESSION: xxxSendMessage(pwnd, WM_ENDSESSION, wParam, lParam); fEnd = TRUE; if (fDestroyTimers) { DestroyWindowsTimers(pwnd); } break; } ThreadUnlock(&tlpwnd); if (!fEnd) return FALSE; } return TRUE; }