HMONITOR MonitorFromWindow( IN HWND hwnd, IN DWORD dwFlags) { PMONITOR pMonitor; PWND pwnd; if (dwFlags > MONITOR_DEFAULTTONEAREST) { RIPERR1(ERROR_INVALID_FLAGS, RIP_WARNING, "Invalid flags to MonitorFromWindow, %x", dwFlags); return NULL; } if (hwnd) { pwnd = ValidateHwnd(hwnd); if (!pwnd) { return NULL; } } else { pwnd = NULL; } pMonitor = _MonitorFromWindow(pwnd, dwFlags); try { return PtoH(pMonitor); } except(W32ExceptionHandler(TRUE, RIP_WARNING)) { return NULL; } }
/***************************************************************************\ * * _GetListBoxInfo() * * Currently returns back the # of items per column. There is no way to get * or calculate this info any other way in a multicolumn list. * * For now, no structure is returned. If we ever need one more thing, make one. * * Since I have to run on multiple platforms, I can't define a message. * To do so would require that * * I make changes to the thunk table * * I make sure the 32-bit define doesn't collide with some NT new msg * * I use a different value on Win '95 vs Memphis due to additions * * I test apps extensively since many of them pass on bogus valued * messages to the listbox handler which checks to see if they * are in range. In other words, any value I pick is probably * going to flake out MSVC++ 4.0. * * Ergo an API instead. * \***************************************************************************/ DWORD WINAPI _GetListBoxInfo(PWND pwnd) { PCLS pcls; DWORD dwRet = 0; BOOL fOtherProcess; /* * Make sure it is a combobox or a dropdown */ pcls = pwnd->pcls; if ((pcls->atomClassName != gpsi->atomSysClass[ICLS_LISTBOX]) && (GETFNID(pwnd) != FNID_LISTBOX)) { RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING, "pwnd %#p is not a listbox", pwnd); return 0; } if (fOtherProcess = (GETPTI(pwnd)->ppi != PpiCurrent())) { KeAttachProcess(&GETPTI(pwnd)->ppi->Process->Pcb); } try { PLBIV ccxPlbSnap; /* * Snap and probe the pointer to the LBIV, since it is client-side. */ ccxPlbSnap = ((PLBWND)pwnd)->pLBIV; if (!ccxPlbSnap) { goto errorexit; } ProbeForRead(ccxPlbSnap, sizeof(LBIV), DATAALIGN); if (ccxPlbSnap->fMultiColumn) { dwRet = ccxPlbSnap->itemsPerColumn; } else { dwRet = ccxPlbSnap->cMac; } } except (W32ExceptionHandler(FALSE, RIP_WARNING)) { dwRet = 0; } errorexit: if (fOtherProcess) { KeDetachProcess(); } return dwRet; }
SHORT _GetKeyState( int vk) { UINT wKeyState; PTHREADINFO pti; if ((UINT)vk >= CVKKEYSTATE) { RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING, "Invalid parameter \"vk\" (%ld) to _GetKeyState", vk); return 0; } pti = PtiCurrentShared(); #ifdef LATER // // note - anything that accesses the pq structure is a bad idea since it // can be changed between any two instructions. // #endif wKeyState = 0; /* * Set the toggle bit. */ if (TestKeyStateToggle(pti->pq, vk)) wKeyState = 0x0001; /* * Set the keyup/down bit. */ if (TestKeyStateDown(pti->pq, vk)) { /* * Used to be wKeyState|= 0x8000.Fix for bug 28820; Ctrl-Enter * accelerator doesn't work on Nestscape Navigator Mail 2.0 */ wKeyState |= 0xff80; // This is what 3.1 returned!!!! } return (SHORT)wKeyState; }
HMONITOR MonitorFromRect( IN LPCRECT lprc, IN DWORD dwFlags) { PMONITOR pMonitor; if (dwFlags > MONITOR_DEFAULTTONEAREST) { RIPERR1(ERROR_INVALID_FLAGS, RIP_WARNING, "Invalid flags to MonitorFromRect, %x", dwFlags); return NULL; } pMonitor = _MonitorFromRect(lprc, dwFlags); try { return PtoH(pMonitor); } except(W32ExceptionHandler(TRUE, RIP_WARNING)) { return NULL; } }
DWORD _GetClassLong( PWND pwnd, int index, BOOL bAnsi) { PCLS pcls = REBASEALWAYS(pwnd, pcls); if (index < 0) { if (index < INDEX_OFFSET || afClassDWord[index - INDEX_OFFSET] > sizeof(DWORD)) { RIPERR1(ERROR_INVALID_INDEX, RIP_WARNING, "GetClassLong: invalid index %d", index); return 0; } return (DWORD)_GetClassData(pcls, pwnd, index, bAnsi); } else { if (index + (int)sizeof(DWORD) > pcls->cbclsExtra) { RIPERR0(ERROR_INVALID_INDEX, RIP_VERBOSE, ""); return 0; } else { DWORD UNALIGNED *pudw; pudw = (DWORD UNALIGNED *)((BYTE *)(pcls + 1) + index); return *pudw; } } }
SHORT _GetAsyncKeyState( int vk) { SHORT sKeyState; if ((UINT)vk >= CVKKEYSTATE) { RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING, "Invalid parameter \"vk\" (%ld) to _GetAsyncKeyState", vk); return 0; } /* * See if this key went down since the last time state for it was * read. Clear the flag if so. */ sKeyState = 0; if (TestAsyncKeyStateRecentDown(vk)) { ClearAsyncKeyStateRecentDown(vk); sKeyState = 1; } /* * Set the keyup/down bit. */ if (TestAsyncKeyStateDown(vk)) sKeyState |= 0x8000; /* * Don't return the toggle bit since it's a new bit and might * cause compatibility problems. */ return sKeyState; }
LPWSTR GetLpszItem( PLBIV pLBIV, INT sItem) { LONG offsz; lpLBItem plbi; if (sItem < 0 || sItem >= pLBIV->cMac) { RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING, "Invalid parameter \"sItem\" (%ld) to GetLpszItem", sItem); return NULL; } /* * get pointer to item index array * NOTE: NOT OWNERDRAW */ plbi = (lpLBItem)(pLBIV->rgpch); offsz = plbi[sItem].offsz; return (LPWSTR)((PBYTE)(pLBIV->hStrings) + offsz); }
/***************************************************************************\ * * _GetComboBoxInfo() * * This returns combobox information for either a combo or its dropdown * list. * \***************************************************************************/ BOOL WINAPI _GetComboBoxInfo(PWND pwnd, PCOMBOBOXINFO pcbi) { PCLS pcls; COMBOBOXINFO cbi = { sizeof cbi, }; BOOL fOtherProcess; BOOL bRetval = FALSE; WORD wWindowType = 0; /* * Make sure it is a combobox or a dropdown */ pcls = pwnd->pcls; if ((GETFNID(pwnd) == FNID_COMBOBOX) || (pcls->atomClassName == gpsi->atomSysClass[ICLS_COMBOBOX])) { wWindowType = FNID_COMBOBOX; } else if ((GETFNID(pwnd) == FNID_COMBOLISTBOX) || (pcls->atomClassName == gpsi->atomSysClass[ICLS_COMBOLISTBOX])) { wWindowType = FNID_COMBOLISTBOX; } else { RIPERR1(ERROR_WINDOW_NOT_COMBOBOX, RIP_WARNING, "pwnd %#p not a combobox or dropdown", pwnd); return FALSE; } /* * Validate combo structure */ if (pcbi->cbSize != sizeof(COMBOBOXINFO)) { RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING, "COMBOBOXINFO.cbSize %d is wrong", pcbi->cbSize); return FALSE; } if (fOtherProcess = (GETPTI(pwnd)->ppi != PpiCurrent())) { KeAttachProcess(&GETPTI(pwnd)->ppi->Process->Pcb); } try { PCBOX ccxPcboxSnap; PWND ccxPwndSnap; HWND ccxHwndSnap; /* * Snap and probe the CBOX structure, since it is client side. */ if (wWindowType == FNID_COMBOBOX) { ccxPcboxSnap = ((PCOMBOWND)pwnd)->pcbox; } else { PLBIV ccxPlbSnap; /* * If this is a listbox, we must snap and probe the LBIV structure * in order to get to the CBOX structure. */ ccxPlbSnap = ((PLBWND)pwnd)->pLBIV; if (!ccxPlbSnap) { goto errorexit; } ProbeForRead(ccxPlbSnap, sizeof(LBIV), DATAALIGN); ccxPcboxSnap = ccxPlbSnap->pcbox; } if (!ccxPcboxSnap) { goto errorexit; } ProbeForRead(ccxPcboxSnap, sizeof(CBOX), DATAALIGN); /* * Get the combo information now */ /* * Snap and probe the client side pointer to the Combo window */ ccxPwndSnap = ccxPcboxSnap->spwnd; ProbeForRead(ccxPwndSnap, sizeof(HEAD), DATAALIGN); cbi.hwndCombo = HWCCX(ccxPwndSnap); /* * Snap & probe the client side pointer to the Edit window. * To compare spwndEdit and pwnd, we should compare handles * since spwndEdit is a client-side address and pwnd is a * kernel-mode address, */ ccxPwndSnap = ccxPcboxSnap->spwndEdit; /* * If combobox is not fully initialized and spwndEdit is NULL, * we should fail. */ ProbeForRead(ccxPwndSnap, sizeof(HEAD), DATAALIGN); ccxHwndSnap = HWCCX(ccxPwndSnap); if (ccxHwndSnap == HW(pwnd)) { /* * ComboBox doesn't have Edit control. */ cbi.hwndItem = NULL; } else { cbi.hwndItem = HWCCX(ccxPwndSnap); } /* * Snap and probe the client side pointer to the List window */ ccxPwndSnap = ccxPcboxSnap->spwndList; /* * If combobox is not fully initialized and spwndList is NULL, * we should fail. */ ProbeForRead(ccxPwndSnap, sizeof(HEAD), DATAALIGN); cbi.hwndList = HWCCX(ccxPwndSnap); /* * Snap the rest of the combo information. * We don't need to probe any of these, since there are no more indirections. */ cbi.rcItem = ccxPcboxSnap->editrc; cbi.rcButton = ccxPcboxSnap->buttonrc; /* * Button state */ cbi.stateButton = 0; if (ccxPcboxSnap->CBoxStyle == CBS_SIMPLE) { cbi.stateButton |= STATE_SYSTEM_INVISIBLE; } if (ccxPcboxSnap->fButtonPressed) { cbi.stateButton |= STATE_SYSTEM_PRESSED; } } except (W32ExceptionHandler(FALSE, RIP_WARNING)) { goto errorexit; } *pcbi = cbi; bRetval = TRUE; errorexit: if (fOtherProcess) { KeDetachProcess(); } return bRetval; }
/*****************************************************************************\ * 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; }
/*****************************************************************************\ * * GetGUIThreadInfo() * * This gets GUI information out of context. If you pass in a NULL thread ID, * we will get the 'global' information, using the foreground thread. This * is guaranteed to be the real active window, focus window, etc. Yes, you * could do it yourself by calling GetForegroundWindow, getting the thread ID * of that window via GetWindowThreadProcessId, then passing the ID into * GetGUIThreadInfo(). However, that takes three calls and aside from being * a pain, anything could happen in the middle. So passing in NULL gets * you stuff in one call and hence also works right. * * This function returns FALSE if the thread doesn't have a queue or the * thread ID is bogus. * \*****************************************************************************/ BOOL WINAPI _GetGUIThreadInfo(PTHREADINFO pti, PGUITHREADINFO pgui) { PQ pq; /* * Validate threadinfo structure */ if (pgui->cbSize != sizeof(GUITHREADINFO)) { RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING, "GUITHREADINFO.cbSize %d is wrong", pgui->cbSize); return FALSE; } /* * Is this a valid initialized GUI thread? */ if (pti != NULL) { if ((pq = pti->pq) == NULL) { // does this ever happen? RIPMSG1(RIP_ERROR, "GetGUIThreadInfo: No queue for pti %lx", pti); return FALSE; } } else { /* * Use the foreground queue. To get menu state information we must also * figure out the right pti. This matches _GetForegroundWindow() logic. */ if ((pq = gpqForeground) == NULL) { // this does sometimes happen... RIPMSG0(RIP_WARNING, "GetGUIThreadInfo: No foreground queue"); return FALSE; } if (pq->spwndActive && (GETPTI(pq->spwndActive)->pq == pq)) { pti = GETPTI(pq->spwndActive); if (PtiCurrentShared()->rpdesk != pti->rpdesk) { RIPERR0(ERROR_ACCESS_DENIED, RIP_VERBOSE, "Foreground window on different desktop"); return FALSE; } } } UserAssert(pq != NULL); /* * For C2 security, verify that pq and pti are on the current thread's desktop. * We can't directly determine which desktop pq belongs to, but we can at * least ensure that any caret info we return is not from another desktop */ if (pq->caret.spwnd && (GETPTI(pq->caret.spwnd)->rpdesk != PtiCurrentShared()->rpdesk)) { RIPERR0(ERROR_ACCESS_DENIED, RIP_VERBOSE, "Foreground caret on different desktop"); return FALSE; } if (pti && (pti->rpdesk != PtiCurrentShared()->rpdesk)) { RIPERR0(ERROR_ACCESS_DENIED, RIP_VERBOSE, "Foreground thread on different desktop"); return FALSE; } pgui->flags = 0; pgui->hwndMoveSize = NULL; pgui->hwndMenuOwner = NULL; /* * Get Menu information from the THREADINFO */ if (pti != NULL) { if (pti->pmsd && !pti->pmsd->fTrackCancelled && pti->pmsd->spwnd) { pgui->flags |= GUI_INMOVESIZE; pgui->hwndMoveSize = HWq(pti->pmsd->spwnd); } if (pti->pMenuState && pti->pMenuState->pGlobalPopupMenu) { pgui->flags |= GUI_INMENUMODE; if (pti->pMenuState->pGlobalPopupMenu->fHasMenuBar) { if (pti->pMenuState->pGlobalPopupMenu->fIsSysMenu) { pgui->flags |= GUI_SYSTEMMENUMODE; } } else { pgui->flags |= GUI_POPUPMENUMODE; } if (pti->pMenuState->pGlobalPopupMenu->spwndNotify) pgui->hwndMenuOwner = HWq(pti->pMenuState->pGlobalPopupMenu->spwndNotify); } } /* * Get the rest of the information from the queue */ pgui->hwndActive = HW(pq->spwndActive); pgui->hwndFocus = HW(pq->spwndFocus); pgui->hwndCapture = HW(pq->spwndCapture); pgui->hwndCaret = NULL; if (pq->caret.spwnd) { pgui->hwndCaret = HWq(pq->caret.spwnd); /* * These coords are always relative to the client of hwndCaret * of course. */ pgui->rcCaret.left = pq->caret.x; pgui->rcCaret.right = pgui->rcCaret.left + pq->caret.cx; pgui->rcCaret.top = pq->caret.y; pgui->rcCaret.bottom = pgui->rcCaret.top + pq->caret.cy; if (pq->caret.iHideLevel == 0) pgui->flags |= GUI_CARETBLINKING; } else if (pti && (pti->ppi->W32PF_Flags & W32PF_CONSOLEHASFOCUS)) { /* * The thread is running in the console window with focus. Pull * out the info from the console pseudo caret. */ pgui->hwndCaret = pti->rpdesk->cciConsole.hwnd; pgui->rcCaret = pti->rpdesk->cciConsole.rc; } else { SetRectEmpty(&pgui->rcCaret); } return TRUE; }
/*****************************************************************************\ * * _GetScrollBarInfo() * * Gets state & location information about a scrollbar. * * Note we fill in the minimal amount of useful info. OLEACC is responsible * for extrapolation. I.E., if both the line up and line down buttons are * disabled, the whole scrollbar is, and the thumb is invisible. * \*****************************************************************************/ BOOL WINAPI _GetScrollBarInfo(PWND pwnd, LONG idObject, PSCROLLBARINFO psbi) { UINT wDisable; BOOL fVertical; SBCALC SBCalc; /* * Validate scrollbarinfo structure */ if (psbi->cbSize != sizeof(SCROLLBARINFO)) { RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING, "SCROLLBARINFO.cbSize %d is wrong", psbi->cbSize); return FALSE; } RtlZeroMemory(&psbi->rgstate, sizeof(psbi->rgstate)); /* * Calculate where everything is. */ if (idObject == OBJID_CLIENT) { RECT rc; wDisable = ((PSBWND)pwnd)->wDisableFlags; fVertical = ((PSBWND)pwnd)->fVert; GetRect(pwnd, &rc, GRECT_CLIENT | GRECT_CLIENTCOORDS); CalcSBStuff2(&SBCalc, &rc, (PSBDATA)&((PSBWND)pwnd)->SBCalc, ((PSBWND)pwnd)->fVert); } else { /* * Is this window scrollbar here? */ if (idObject == OBJID_VSCROLL) { fVertical = TRUE; if (! TestWF(pwnd, WFVSCROLL)) { // No scrollbar. psbi->rgstate[INDEX_SCROLLBAR_SELF] |= STATE_SYSTEM_INVISIBLE; } else if (! TestWF(pwnd, WFVPRESENT)) { // Window too short to display it. psbi->rgstate[INDEX_SCROLLBAR_SELF] |= STATE_SYSTEM_OFFSCREEN; } } else if (idObject == OBJID_HSCROLL) { fVertical = FALSE; if (! TestWF(pwnd, WFHSCROLL)) { // No scrollbar. psbi->rgstate[INDEX_SCROLLBAR_SELF] |= STATE_SYSTEM_INVISIBLE; } else if (! TestWF(pwnd, WFHPRESENT)) { psbi->rgstate[INDEX_SCROLLBAR_SELF] |= STATE_SYSTEM_OFFSCREEN; } } else { RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING, "invalid idObject %d", idObject); return FALSE; } if (psbi->rgstate[INDEX_SCROLLBAR_SELF] & STATE_SYSTEM_INVISIBLE) return TRUE; wDisable = GetWndSBDisableFlags(pwnd, fVertical); if (!(psbi->rgstate[INDEX_SCROLLBAR_SELF] & STATE_SYSTEM_OFFSCREEN)) CalcSBStuff(pwnd, &SBCalc, fVertical); } /* * Setup button states. */ if (wDisable & LTUPFLAG) { psbi->rgstate[INDEX_SCROLLBAR_UP] |= STATE_SYSTEM_UNAVAILABLE; psbi->rgstate[INDEX_SCROLLBAR_UPPAGE] |= STATE_SYSTEM_UNAVAILABLE; } if (wDisable & RTDNFLAG) { psbi->rgstate[INDEX_SCROLLBAR_DOWN] |= STATE_SYSTEM_UNAVAILABLE; psbi->rgstate[INDEX_SCROLLBAR_DOWNPAGE] |= STATE_SYSTEM_UNAVAILABLE; } if ((wDisable & (LTUPFLAG | RTDNFLAG)) == (LTUPFLAG | RTDNFLAG)) psbi->rgstate[INDEX_SCROLLBAR_SELF] |= STATE_SYSTEM_UNAVAILABLE; /* * Button pressed? */ if (TestWF(pwnd, WFSCROLLBUTTONDOWN) && ((idObject != OBJID_VSCROLL) || TestWF(pwnd, WFVERTSCROLLTRACK))) { if (TestWF(pwnd, WFLINEUPBUTTONDOWN)) psbi->rgstate[INDEX_SCROLLBAR_UP] |= STATE_SYSTEM_PRESSED; if (TestWF(pwnd, WFPAGEUPBUTTONDOWN)) psbi->rgstate[INDEX_SCROLLBAR_UPPAGE] |= STATE_SYSTEM_PRESSED; if (TestWF(pwnd, WFPAGEDNBUTTONDOWN)) psbi->rgstate[INDEX_SCROLLBAR_DOWNPAGE] |= STATE_SYSTEM_PRESSED; if (TestWF(pwnd, WFLINEDNBUTTONDOWN)) psbi->rgstate[INDEX_SCROLLBAR_DOWN] |= STATE_SYSTEM_PRESSED; } /* * Fill in area locations. */ if (!(psbi->rgstate[INDEX_SCROLLBAR_SELF] & STATE_SYSTEM_OFFSCREEN)) { if (fVertical) { psbi->rcScrollBar.left = SBCalc.pxLeft; psbi->rcScrollBar.top = SBCalc.pxTop; psbi->rcScrollBar.right = SBCalc.pxRight; psbi->rcScrollBar.bottom = SBCalc.pxBottom; } else { psbi->rcScrollBar.left = SBCalc.pxTop; psbi->rcScrollBar.top = SBCalc.pxLeft; psbi->rcScrollBar.right = SBCalc.pxBottom; psbi->rcScrollBar.bottom = SBCalc.pxRight; } if (idObject == OBJID_CLIENT) { OffsetRect(&psbi->rcScrollBar, pwnd->rcClient.left, pwnd->rcClient.top); } else { OffsetRect(&psbi->rcScrollBar, pwnd->rcWindow.left, pwnd->rcWindow.top); } psbi->dxyLineButton = (SBCalc.pxUpArrow - SBCalc.pxTop); psbi->xyThumbTop = (SBCalc.pxThumbTop - SBCalc.pxTop); psbi->xyThumbBottom = (SBCalc.pxThumbBottom - SBCalc.pxTop); /* * Is the thumb all the way to the left/top? If so, page up is * not visible. */ if (SBCalc.pxThumbTop == SBCalc.pxUpArrow) psbi->rgstate[INDEX_SCROLLBAR_UPPAGE] |= STATE_SYSTEM_INVISIBLE; /* * Is the thumb all the way to the right/down? If so, page down * is not visible. */ if (SBCalc.pxThumbBottom == SBCalc.pxDownArrow) psbi->rgstate[INDEX_SCROLLBAR_DOWNPAGE] |= STATE_SYSTEM_INVISIBLE; } return TRUE; }
/****************************************************************************\ * * _GetTitleBarInfo() * * Gets info about a window's title bar. If the window is bogus or * doesn't have a titlebar, this will fail. * \****************************************************************************/ BOOL WINAPI xxxGetTitleBarInfo(PWND pwnd, PTITLEBARINFO ptbi) { int cxB; CheckLock(pwnd); /* * Validate titlebarinfo structure */ if (ptbi->cbSize != sizeof(TITLEBARINFO)) { RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING, "TITLEBARINFO.cbSize %d is wrong", ptbi->cbSize); return FALSE; } RtlZeroMemory(&ptbi->rgstate, sizeof(ptbi->rgstate)); ptbi->rgstate[INDEX_TITLEBAR_SELF] |= STATE_SYSTEM_FOCUSABLE; if (TestWF(pwnd, WFBORDERMASK) != LOBYTE(WFCAPTION)) { // No titlebar. ptbi->rgstate[INDEX_TITLEBAR_SELF] |= STATE_SYSTEM_INVISIBLE; return TRUE; } if (!TestWF(pwnd, WFMINIMIZED) && !TestWF(pwnd, WFCPRESENT)) { // Off screen (didn't fit) ptbi->rgstate[INDEX_TITLEBAR_SELF] |= STATE_SYSTEM_OFFSCREEN; SetRectEmpty(&ptbi->rcTitleBar); return TRUE; } /* * Get titlebar rect */ ptbi->rcTitleBar = pwnd->rcWindow; cxB = GetWindowBorders(pwnd->style, pwnd->ExStyle, TRUE, FALSE); InflateRect(&ptbi->rcTitleBar, -cxB * SYSMET(CXBORDER), -cxB * SYSMET(CYBORDER)); if (TestWF(pwnd, WEFTOOLWINDOW)) { ptbi->rcTitleBar.bottom = ptbi->rcTitleBar.top + SYSMET(CYSMCAPTION); } else { ptbi->rcTitleBar.bottom = ptbi->rcTitleBar.top + SYSMET(CYCAPTION); } /* * Don't include the system menu area! */ if (TestWF(pwnd, WFSYSMENU) && _HasCaptionIcon(pwnd)) ptbi->rcTitleBar.left += (ptbi->rcTitleBar.bottom - ptbi->rcTitleBar.top - SYSMET(CYBORDER)); /* * Close button */ if (!TestWF(pwnd, WFSYSMENU) && TestWF(pwnd, WFWIN40COMPAT)) { ptbi->rgstate[INDEX_TITLEBAR_CLOSEBUTTON] |= STATE_SYSTEM_INVISIBLE; } else { if (!xxxMNCanClose(pwnd)) ptbi->rgstate[INDEX_TITLEBAR_CLOSEBUTTON] |= STATE_SYSTEM_UNAVAILABLE; if (TestWF(pwnd, WFCLOSEBUTTONDOWN)) ptbi->rgstate[INDEX_TITLEBAR_CLOSEBUTTON] |= STATE_SYSTEM_PRESSED; } /* * Max button */ if (! TestWF(pwnd, WFSYSMENU) && TestWF(pwnd, WFWIN40COMPAT)) { ptbi->rgstate[INDEX_TITLEBAR_MAXBUTTON] |= STATE_SYSTEM_INVISIBLE; } else { if (! TestWF(pwnd, WFMAXBOX)) { if (! TestWF(pwnd, WFMINBOX)) { ptbi->rgstate[INDEX_TITLEBAR_MAXBUTTON] |= STATE_SYSTEM_INVISIBLE; } else { ptbi->rgstate[INDEX_TITLEBAR_MAXBUTTON] |= STATE_SYSTEM_UNAVAILABLE; } } if (TestWF(pwnd, WFZOOMBUTTONDOWN)) ptbi->rgstate[INDEX_TITLEBAR_MAXBUTTON] |= STATE_SYSTEM_PRESSED; } /* * Min button */ if (! TestWF(pwnd, WFSYSMENU) && TestWF(pwnd, WFWIN40COMPAT)) { ptbi->rgstate[INDEX_TITLEBAR_MINBUTTON] |= STATE_SYSTEM_INVISIBLE; } else { if (! TestWF(pwnd, WFMINBOX)) { if (! TestWF(pwnd, WFMAXBOX)) { ptbi->rgstate[INDEX_TITLEBAR_MINBUTTON] |= STATE_SYSTEM_INVISIBLE; } else { ptbi->rgstate[INDEX_TITLEBAR_MINBUTTON] |= STATE_SYSTEM_UNAVAILABLE; } } if (TestWF(pwnd, WFREDUCEBUTTONDOWN)) ptbi->rgstate[INDEX_TITLEBAR_MINBUTTON] |= STATE_SYSTEM_PRESSED; } /* * Help button */ if (!TestWF(pwnd, WEFCONTEXTHELP) || TestWF(pwnd, WFMINBOX) || TestWF(pwnd, WFMAXBOX)) { ptbi->rgstate[INDEX_TITLEBAR_HELPBUTTON] |= STATE_SYSTEM_INVISIBLE; } else { if (TestWF(pwnd, WFHELPBUTTONDOWN)) ptbi->rgstate[INDEX_TITLEBAR_HELPBUTTON] |= STATE_SYSTEM_PRESSED; } // IME button BOGUS! ptbi->rgstate[INDEX_TITLEBAR_IMEBUTTON] = STATE_SYSTEM_INVISIBLE; #if 0 /* * System menu */ if (!TestWF(pwnd, WFSYSMENU) || !_HasCaptionIcon(pwnd)) ptbi->stateSysMenu |= STATE_SYSTEM_INVISIBLE; #endif return TRUE; }
PVOID FASTCALL HMValidateHandle( HANDLE h, BYTE bType) { DWORD dwError; #if defined(DEBUG) && !defined(_USERK_) && !defined(WOW) /* * We don't want 32 bit apps passing 16 bit handles * we should consider failing this before we get * stuck supporting it (Some VB apps do this). */ if ((h != NULL) && (HMUniqFromHandle(h) == 0) && !(GetClientInfo()->dwTIFlags & TIF_16BIT)) { //RIPMSG3(RIP_WARNING, "HMValidateHandle: 32bit process [%d] using 16 bit handle [%#lx]. bType:%#lx", //((DWORD)NtCurrentTeb()->ClientId.UniqueProcess), h, (DWORD)bType); } #endif /* * Include this macro, which does validation - this is the fastest * way to do validation, without the need to pass a third parameter * into a general rip routine, and we don't have two sets of * validation to maintain. */ ValidateHandleMacro(h, bType) switch (bType) { case TYPE_WINDOW: dwError = ERROR_INVALID_WINDOW_HANDLE; break; case TYPE_MENU: dwError = ERROR_INVALID_MENU_HANDLE; break; case TYPE_CURSOR: dwError = ERROR_INVALID_CURSOR_HANDLE; break; case TYPE_ACCELTABLE: dwError = ERROR_INVALID_ACCEL_HANDLE; break; case TYPE_HOOK: dwError = ERROR_INVALID_HOOK_HANDLE; break; case TYPE_SETWINDOWPOS: dwError = ERROR_INVALID_DWP_HANDLE; break; default: dwError = ERROR_INVALID_HANDLE; break; } RIPERR1(dwError, RIP_WARNING, "HMValidateHandle: Invalid handle (0x%08lx)", h); /* * If we get here, it's an error. */ return NULL; }
BOOL CliSaveImeHotKeyWorker(DWORD id, UINT mod, UINT vk, HKL hkl, BOOL fDelete, ADVAPI_FN* fn) { HKEY hKey, hKeyParent; INT i; LONG lResult; TCHAR szHex[16]; if (fDelete) { TCHAR szRegTmp[(sizeof(szRegImeHotKey) / sizeof(TCHAR) + 1 + 8 + 1)]; lstrcpy(szRegTmp, szRegImeHotKey); lstrcat(szRegTmp, TEXT("\\")); NumToHexAscii(id, szHex); lstrcat(szRegTmp, szHex); lResult = fn->RegDeleteKey(HKEY_CURRENT_USER, szRegTmp); if (lResult != ERROR_SUCCESS) { RIPERR1(lResult, RIP_WARNING, "CliSaveImeHotKeyWorker: deleting %s failed", szRegTmp); return FALSE; } return TRUE; } hKeyParent = HKEY_CURRENT_USER; for (i = 0; szaRegImmHotKeys[i] != NULL; i++) { lResult = fn->RegCreateKeyEx(hKeyParent, szaRegImmHotKeys[i], 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE|KEY_READ, NULL, &hKey, NULL ); fn->RegCloseKey(hKeyParent); if (lResult == ERROR_SUCCESS) { hKeyParent = hKey; } else { RIPERR1(lResult, RIP_WARNING, "CliSaveImeHotKeyWorker: creating %s failed", szaRegImmHotKeys[i]); return FALSE; } } NumToHexAscii(id, szHex); lResult = fn->RegCreateKeyEx(hKeyParent, szHex, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE|KEY_READ, NULL, &hKey, NULL ); fn->RegCloseKey(hKeyParent); if (lResult != ERROR_SUCCESS) { RIPERR1(lResult, RIP_WARNING, "CliSaveImeHotKeyWorker: creating %s failed", szHex ); return FALSE; } lResult = fn->RegSetValueExW(hKey, szRegVK, 0, REG_BINARY, (LPBYTE)&vk, sizeof(DWORD)); if (lResult != ERROR_SUCCESS) { fn->RegCloseKey(hKey); CliSaveImeHotKey(id, vk, mod, hkl, TRUE); RIPERR1( lResult, RIP_WARNING, "SaveImeHotKey:setting value on %s failed", szRegVK ); return ( FALSE ); } lResult = fn->RegSetValueExW(hKey, szRegMOD, 0, REG_BINARY, (LPBYTE)&mod, sizeof(DWORD)); if (lResult != ERROR_SUCCESS) { fn->RegCloseKey(hKey); CliSaveImeHotKey(id, vk, mod, hkl, TRUE); RIPERR1(lResult, RIP_WARNING, "CliSaveImeHotKeyWorker: setting value on %s failed", szRegMOD); return FALSE; } lResult = fn->RegSetValueExW(hKey, szRegHKL, 0, REG_BINARY, (LPBYTE)&hkl, sizeof(DWORD) ); if (lResult != ERROR_SUCCESS) { fn->RegCloseKey(hKey); CliSaveImeHotKey(id, vk, mod, hkl, TRUE); RIPERR1(lResult, RIP_WARNING, "CliSaveImeHotKeyWorker: setting value on %s failed", szRegHKL); return FALSE; } fn->RegCloseKey(hKey); return TRUE; }