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

rare.c

Go to the documentation of this file.
00001 /****************************** Module Header ******************************\ 00002 * Module Name: rare.c 00003 * 00004 * Copyright (c) 1985 - 1999, Microsoft Corporation 00005 * 00006 * History: 00007 * 06-28-91 MikeHar Created. 00008 \***************************************************************************/ 00009 00010 #include "precomp.h" 00011 #pragma hdrstop 00012 00013 /* 00014 * MetricsRecalc flags 00015 */ 00016 #define CALC_RESIZE 0x0001 00017 #define CALC_FRAME 0x0002 00018 #define CALC_MINIMIZE 0x0004 00019 00020 /* 00021 * NormalizeRect flags 00022 */ 00023 #define NORMALIZERECT_NORMAL 0 00024 #define NORMALIZERECT_MAXIMIZED 1 00025 #define NORMALIZERECT_FULLSCREEN 2 00026 00027 /***************************************************************************\ 00028 * SnapshotMonitorRects 00029 * 00030 * This is called from ResetDisplay to memorize the monitor positions so 00031 * DesktopRecalcEx will know where to move stuff. 00032 * 00033 * Returns the MONITORRECTS if succeeded, NULL otherwise. 00034 * 00035 * History: 00036 * 09-Dec-1996 adams Created. 00037 \***************************************************************************/ 00038 00039 PMONITORRECTS 00040 SnapshotMonitorRects(void) 00041 { 00042 PMONITOR pMonitor; 00043 PMONITORRECTS pmr; 00044 PMONITORPOS pmp; 00045 #if DBG 00046 ULONG cVisMon = 0; 00047 #endif 00048 00049 pmr = UserAllocPool( 00050 sizeof(MONITORRECTS) + sizeof(MONITORPOS) * (gpDispInfo->cMonitors - 1), 00051 TAG_MONITORRECTS); 00052 00053 if (!pmr) { 00054 RIPERR0(ERROR_OUTOFMEMORY, RIP_WARNING, "Out of memory in SnapshotMonitorRects"); 00055 return NULL; 00056 } 00057 00058 pmp = pmr->amp; 00059 for ( pMonitor = gpDispInfo->pMonitorFirst; 00060 pMonitor; 00061 pMonitor = pMonitor->pMonitorNext) { 00062 00063 if (!(pMonitor->dwMONFlags & MONF_VISIBLE)) 00064 continue; 00065 #if DBG 00066 cVisMon++; 00067 #endif 00068 00069 CopyRect(&pmp->rcMonitor, &pMonitor->rcMonitor); 00070 CopyRect(&pmp->rcWork, &pMonitor->rcWork); 00071 00072 /* 00073 * If the device for this monitor object is not active, don't store 00074 * the pointer to it in the list. This way the windows on the inactive 00075 * monitor will be later moved to the default one. 00076 */ 00077 if (HdevFromMonitor(pMonitor) == -1) { 00078 pmp->pMonitor = NULL; 00079 } else { 00080 pmp->pMonitor = pMonitor; 00081 } 00082 00083 pmp++; 00084 } 00085 UserAssert(cVisMon == gpDispInfo->cMonitors); 00086 00087 pmr->cMonitor = (int)(pmp - pmr->amp); 00088 00089 return pmr; 00090 } 00091 00092 /***************************************************************************\ 00093 * NormalizeRect 00094 * 00095 * Adjusts a window rectangle when the working area changes. This can be 00096 * because of a tray move, with the resolution staying the same, or 00097 * because of a dynamic resolution change, with the tray staying the same 00098 * relatively. 00099 * 00100 * History: 00101 \***************************************************************************/ 00102 00103 PMONITOR NormalizeRect( 00104 LPRECT lprcDest, 00105 LPRECT lprcSrc, 00106 PMONITORRECTS pmrOld, 00107 int iOldMonitor, 00108 int codeFullScreen, 00109 DWORD style) 00110 { 00111 LPCRECT lprcOldMonitor; 00112 LPCRECT lprcOldWork; 00113 LPRECT lprcNewWork; 00114 PMONITOR pMonitor; 00115 int cxOldMonitor; 00116 int cyOldMonitor; 00117 int cxNewMonitor; 00118 int cyNewMonitor; 00119 int dxOrg, dyOrg; 00120 00121 /* 00122 * Track the window so it stays in the same place on the same monitor. 00123 * If the old monitor is no longer active then pick a default. 00124 */ 00125 if ((pMonitor = pmrOld->amp[iOldMonitor].pMonitor) == NULL) { 00126 pMonitor = GetPrimaryMonitor(); 00127 } 00128 00129 lprcOldMonitor = &pmrOld->amp[iOldMonitor].rcMonitor; 00130 lprcOldWork = &pmrOld->amp[iOldMonitor].rcWork; 00131 00132 /* 00133 * If is a fullscreen app just make it fullscreen at the new location. 00134 */ 00135 if (codeFullScreen != NORMALIZERECT_NORMAL) { 00136 LPCRECT lprcOldSnap, lprcNewSnap; 00137 00138 /* 00139 * If it is a maximized window snap it to the work area. 00140 * Otherwise it is a rude app so snap it to the screen. 00141 */ 00142 if (codeFullScreen == NORMALIZERECT_MAXIMIZED) { 00143 lprcOldSnap = lprcOldWork; 00144 lprcNewSnap = &pMonitor->rcWork; 00145 } else { 00146 lprcOldSnap = lprcOldMonitor; 00147 lprcNewSnap = &pMonitor->rcMonitor; 00148 } 00149 00150 lprcDest->left = lprcSrc->left + 00151 lprcNewSnap->left - lprcOldSnap->left; 00152 00153 lprcDest->top = lprcSrc->top + 00154 lprcNewSnap->top - lprcOldSnap->top; 00155 00156 lprcDest->right = lprcSrc->right + 00157 lprcNewSnap->right - lprcOldSnap->right; 00158 00159 lprcDest->bottom = lprcSrc->bottom + 00160 lprcNewSnap->bottom - lprcOldSnap->bottom; 00161 00162 goto AllDone; 00163 } 00164 00165 /* 00166 * Offset the window by the change in desktop origin. 00167 */ 00168 dxOrg = pMonitor->rcMonitor.left - lprcOldMonitor->left; 00169 dyOrg = pMonitor->rcMonitor.top - lprcOldMonitor->top; 00170 00171 /* 00172 * Calculate the change in screen size (we need it in more than one place). 00173 */ 00174 cxOldMonitor = lprcOldMonitor->right - lprcOldMonitor->left; 00175 cyOldMonitor = lprcOldMonitor->bottom - lprcOldMonitor->top; 00176 cxNewMonitor = pMonitor->rcMonitor.right - pMonitor->rcMonitor.left; 00177 cyNewMonitor = pMonitor->rcMonitor.bottom - pMonitor->rcMonitor.top; 00178 00179 /* 00180 * If the monitor resolution has changed (or we moved to a new monitor) 00181 * then factor in the size change. 00182 */ 00183 if (cxNewMonitor != cxOldMonitor || cyNewMonitor != cyOldMonitor) { 00184 int xWnd = lprcSrc->left - lprcOldMonitor->left; 00185 int yWnd = lprcSrc->top - lprcOldMonitor->top; 00186 00187 dxOrg += MultDiv(xWnd, cxNewMonitor - cxOldMonitor, cxOldMonitor); 00188 dyOrg += MultDiv(yWnd, cyNewMonitor - cyOldMonitor, cyOldMonitor); 00189 } 00190 00191 /* 00192 * Compute the initial new position. 00193 */ 00194 CopyOffsetRect(lprcDest, lprcSrc, dxOrg, dyOrg); 00195 lprcNewWork = &pMonitor->rcWork; 00196 00197 /* 00198 * Fit horizontally. Try to fit so that the window isn't out of the 00199 * working area horizontally. Keep left edge visible always. 00200 */ 00201 if (lprcDest->right > lprcNewWork->right) { 00202 OffsetRect(lprcDest, lprcNewWork->right - lprcDest->right, 0); 00203 } 00204 00205 if (lprcDest->left < lprcNewWork->left) { 00206 OffsetRect(lprcDest, lprcNewWork->left - lprcDest->left, 0); 00207 } 00208 00209 /* 00210 * Fit vertically. Try to fit so that the window isn't out of the 00211 * working area vertically. Keep top edge visible always. 00212 */ 00213 if (lprcDest->bottom > lprcNewWork->bottom) { 00214 OffsetRect(lprcDest, 0, lprcNewWork->bottom - lprcDest->bottom); 00215 } 00216 00217 if (lprcDest->top < lprcNewWork->top) { 00218 OffsetRect(lprcDest, 0, lprcNewWork->top - lprcDest->top); 00219 } 00220 00221 /* 00222 * If the window is sizeable then shrink it if necessary. 00223 */ 00224 if (style & WS_THICKFRAME) 00225 { 00226 int cSnap = 0; 00227 00228 if (lprcDest->right > lprcNewWork->right) { 00229 lprcDest->right = lprcNewWork->right; 00230 cSnap++; 00231 } 00232 00233 if (lprcDest->bottom > lprcNewWork->bottom) { 00234 lprcDest->bottom = lprcNewWork->bottom; 00235 cSnap++; 00236 } 00237 00238 00239 /* 00240 * Now make sure we didn't turn this normal window into a 00241 * fullscreen window. This is a complete hack but it is much 00242 * better than changing from 800x600 to 640x480 and ending up with 00243 * a bunch of fullscreen apps... 00244 */ 00245 if (cSnap == 2) { 00246 InflateRect(lprcDest, -1, -1); 00247 } 00248 } 00249 00250 AllDone: 00251 return pMonitor; 00252 } 00253 00254 00255 /***************************************************************************\ 00256 * _SetRipFlags 00257 * 00258 * Sets the debug rip flags 00259 * 00260 * History: 00261 * 16-Aug-1996 adams Created. 00262 \***************************************************************************/ 00263 00264 VOID _SetRipFlags( 00265 DWORD dwRipFlags, DWORD dwPID) 00266 { 00267 if (gpsi) { 00268 if ((dwRipFlags != (DWORD)-1) && !(dwRipFlags & ~RIPF_VALIDUSERFLAGS)) { 00269 gpsi->wRIPFlags = (WORD)((gpsi->wRIPFlags & ~RIPF_VALIDUSERFLAGS) | dwRipFlags); 00270 } 00271 if (dwPID != (DWORD)-1) { 00272 gpsi->wRIPPID = (WORD)dwPID; 00273 } 00274 } 00275 } 00276 00277 /***************************************************************************\ 00278 * _SetDbgTag 00279 * 00280 * Sets debugging level for a tag. 00281 * 00282 * History: 00283 * 16-Aug-1996 adams Created. 00284 \***************************************************************************/ 00285 00286 void 00287 _SetDbgTag(int tag, DWORD dwDBGTAGFlags) 00288 { 00289 #if DEBUGTAGS 00290 if (gpsi && tag < DBGTAG_Max && !(dwDBGTAGFlags & ~DBGTAG_VALIDUSERFLAGS)) { 00291 COPY_FLAG(gpsi->adwDBGTAGFlags[tag], dwDBGTAGFlags, DBGTAG_VALIDUSERFLAGS); 00292 } 00293 #else 00294 UNREFERENCED_PARAMETER(tag); 00295 UNREFERENCED_PARAMETER(dwDBGTAGFlags); 00296 #endif 00297 } 00298 00299 00300 /***************************************************************************\ 00301 * UpdateWinIniInt 00302 * 00303 * History: 00304 * 18-Apr-1994 mikeke Created 00305 \***************************************************************************/ 00306 BOOL UpdateWinIniInt(PUNICODE_STRING pProfileUserName, 00307 UINT idSection, 00308 UINT wKeyNameId, 00309 int value 00310 ) 00311 { 00312 WCHAR szTemp[40]; 00313 WCHAR szKeyName[40]; 00314 swprintf(szTemp, L"%d", value); 00315 00316 ServerLoadString(hModuleWin, 00317 wKeyNameId, 00318 szKeyName, 00319 sizeof(szKeyName) / sizeof(WCHAR)); 00320 00321 return FastWriteProfileStringW(pProfileUserName, 00322 idSection, 00323 szKeyName, 00324 szTemp); 00325 00326 00327 } 00328 00329 /***************************************************************************\ 00330 * SetDesktopMetrics 00331 * 00332 * History: 00333 * 31-Jan-1994 mikeke Ported 00334 \***************************************************************************/ 00335 00336 void SetDesktopMetrics() 00337 { 00338 LPRECT lprcWork; 00339 00340 lprcWork = &GetPrimaryMonitor()->rcWork; 00341 00342 SYSMET(CXFULLSCREEN) = lprcWork->right - lprcWork->left; 00343 SYSMET(CXMAXIMIZED) = lprcWork->right - lprcWork->left + 2*SYSMET(CXSIZEFRAME); 00344 00345 SYSMET(CYFULLSCREEN) = lprcWork->bottom - lprcWork->top - SYSMET(CYCAPTION); 00346 SYSMET(CYMAXIMIZED) = lprcWork->bottom - lprcWork->top + 2*SYSMET(CYSIZEFRAME); 00347 } 00348 00349 /***************************************************************************\ 00350 * xxxMetricsRecalc (Win95: MetricsRecalc) 00351 * 00352 * Does work to size/position all minimized or nonminimized 00353 * windows. Called when frame metrics or min metrics are changed. 00354 * 00355 * Note that you can NOT do DeferWindowPos() with this function. SWP doesn't 00356 * work when you do parents and children at the same time--it's only for 00357 * peer windows. Thus we must do SetWindowPos() for each window. 00358 * 00359 * History: 00360 * 06-28-91 MikeHar Ported. 00361 \***************************************************************************/ 00362 void xxxMetricsRecalc( 00363 UINT wFlags, 00364 int dx, 00365 int dy, 00366 int dyCaption, 00367 int dyMenu) 00368 { 00369 PHWND phwnd; 00370 PWND pwnd; 00371 RECT rc; 00372 PCHECKPOINT pcp; 00373 TL tlpwnd; 00374 BOOL fResized; 00375 PBWL pbwl; 00376 PTHREADINFO ptiCurrent; 00377 int c; 00378 00379 ptiCurrent = PtiCurrent(); 00380 pbwl = BuildHwndList( 00381 GETDESKINFO(ptiCurrent)->spwnd->spwndChild, 00382 BWL_ENUMLIST | BWL_ENUMCHILDREN, 00383 NULL); 00384 00385 if (!pbwl) 00386 return; 00387 00388 UserAssert(*pbwl->phwndNext == (HWND) 1); 00389 for ( c = (int)(pbwl->phwndNext - pbwl->rghwnd), phwnd = pbwl->rghwnd; 00390 c > 0; 00391 c--, phwnd++) { 00392 00393 pwnd = RevalidateHwnd(*phwnd); 00394 if (!pwnd) 00395 continue; 00396 00397 ThreadLockAlwaysWithPti(ptiCurrent, pwnd, &tlpwnd); 00398 00399 fResized = FALSE; 00400 00401 if ((wFlags & CALC_MINIMIZE) && TestWF(pwnd, WFMINIMIZED)) { 00402 /* 00403 * We're changing the minimized window dimensions. We need to 00404 * resize. Note that we do NOT move. 00405 */ 00406 CopyRect(&rc, (&pwnd->rcWindow)); 00407 rc.right += dx; 00408 rc.bottom += dy; 00409 00410 goto PositionWnd; 00411 } 00412 00413 /* 00414 * We're changing the size of the window because the sizing border 00415 * changed. 00416 */ 00417 if ((wFlags & CALC_RESIZE) && TestWF(pwnd, WFSIZEBOX)) { 00418 00419 pcp = (CHECKPOINT *)_GetProp(pwnd, PROP_CHECKPOINT, PROPF_INTERNAL); 00420 00421 /* 00422 * Update maximized position to account for sizing border 00423 * We do this for DOS box also. This way client of max'ed windows 00424 * stays in same relative position. 00425 */ 00426 if (pcp && (pcp->fMaxInitialized)) { 00427 pcp->ptMax.x -= dx; 00428 pcp->ptMax.y -= dy; 00429 } 00430 00431 if (TestWF(pwnd, WFMINIMIZED)) { 00432 if (pcp) 00433 InflateRect(&pcp->rcNormal, dx, dy); 00434 } else { 00435 CopyInflateRect(&rc, (&pwnd->rcWindow), dx, dy); 00436 if (TestWF(pwnd, WFCPRESENT)) 00437 rc.bottom += dyCaption; 00438 if (TestWF(pwnd, WFMPRESENT)) 00439 rc.bottom += dyMenu; 00440 00441 PositionWnd: 00442 fResized = TRUE; 00443 00444 /* 00445 * Remember SWP expects values in PARENT CLIENT coordinates. 00446 */ 00447 if (pwnd->spwndParent != PWNDDESKTOP(pwnd)) { 00448 OffsetRect(&rc, 00449 -pwnd->spwndParent->rcClient.left, 00450 -pwnd->spwndParent->rcClient.top); 00451 } 00452 00453 xxxSetWindowPos(pwnd, 00454 PWND_TOP, 00455 rc.left, 00456 rc.top, 00457 rc.right-rc.left, 00458 rc.bottom-rc.top, 00459 00460 #if 0 // Win95 flags 00461 SWP_NOZORDER | SWP_NOACTIVATE | SWP_DEFERDRAWING | SWP_FRAMECHANGED); 00462 #else 00463 SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_FRAMECHANGED | SWP_NOREDRAW); 00464 #endif 00465 } 00466 } 00467 00468 /* 00469 * We're changing the nonclient widgets, so recalculate the 00470 * client. 00471 */ 00472 if (wFlags & CALC_FRAME) { 00473 00474 /* 00475 * Delete any cached small icons... 00476 */ 00477 if (dyCaption) 00478 xxxSendMessage(pwnd, WM_SETICON, ICON_RECREATE, 0); 00479 00480 if (!TestWF(pwnd, WFMINIMIZED) && !fResized) { 00481 00482 CopyRect(&rc, &(pwnd->rcWindow)); 00483 if (TestWF(pwnd, WFMPRESENT)) 00484 rc.bottom += dyMenu; 00485 00486 if (TestWF(pwnd, WFCPRESENT)) { 00487 rc.bottom += dyCaption; 00488 /* 00489 * Maximized MDI child windows position their caption 00490 * outside their parent's client area (negative y). 00491 * If the caption has changed, they need to be 00492 * repositioned. 00493 */ 00494 if (TestWF(pwnd, WFMAXIMIZED) 00495 && TestWF(pwnd, WFCHILD) 00496 && (GETFNID(pwnd->spwndParent) == FNID_MDICLIENT)) { 00497 00498 xxxSetWindowPos(pwnd, 00499 PWND_TOP, 00500 rc.left - pwnd->spwndParent->rcWindow.left, 00501 rc.top - pwnd->spwndParent->rcWindow.top - dyCaption, 00502 rc.right - rc.left, 00503 rc.bottom- rc.top, SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED | SWP_NOREDRAW); 00504 goto LoopCleanup; 00505 } 00506 } 00507 00508 xxxSetWindowPos(pwnd, 00509 PWND_TOP, 00510 0, 00511 0, 00512 rc.right-rc.left, 00513 rc.bottom-rc.top, 00514 #if 0 // Win95 flags 00515 SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED | SWP_NOREDRAW); 00516 #else 00517 SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED | SWP_NOCOPYBITS | SWP_NOREDRAW); 00518 #endif 00519 } 00520 } 00521 00522 LoopCleanup: 00523 ThreadUnlock(&tlpwnd); 00524 } 00525 00526 FreeHwndList(pbwl); 00527 } 00528 00529 /***************************************************************************\ 00530 * FindOldMonitor 00531 * 00532 * Returns the index of the monitor in "pmr" which has the greatest 00533 * overlap with a rectangle. This function is used to determine which 00534 * monitor a window was on after one or more monitor rectangles have 00535 * changed. 00536 * 00537 * History: 00538 * 11-Sep-1996 adams Created. 00539 \***************************************************************************/ 00540 00541 int 00542 FindOldMonitor(LPCRECT lprc, PMONITORRECTS pmr) 00543 { 00544 DWORD dwClosest; 00545 int iClosest, i; 00546 int cxRect, cyRect; 00547 PMONITORPOS pmp; 00548 00549 iClosest = -1; 00550 dwClosest = 0; 00551 00552 cxRect = (lprc->right - lprc->left); 00553 cyRect = (lprc->bottom - lprc->top); 00554 00555 for (i = 0, pmp = pmr->amp; i < pmr->cMonitor; pmp++, i++) 00556 { 00557 RECT rcT; 00558 00559 if (IntersectRect(&rcT, lprc, &pmp->rcMonitor)) 00560 { 00561 DWORD dwT; 00562 00563 // 00564 // convert to width/height 00565 // 00566 rcT.right -= rcT.left; 00567 rcT.bottom -= rcT.top; 00568 00569 // 00570 // if fully enclosed, we're done 00571 // 00572 if ((rcT.right == cxRect) && (rcT.bottom == cyRect)) 00573 return i; 00574 00575 // 00576 // use largest area 00577 // 00578 dwT = (DWORD)rcT.right * (DWORD)rcT.bottom; 00579 if (dwT > dwClosest) 00580 { 00581 dwClosest = dwT; 00582 iClosest = i; 00583 } 00584 } 00585 } 00586 00587 return iClosest; 00588 } 00589 00590 00591 00592 /***************************************************************************\ 00593 * xxxDesktopRecalc 00594 * 00595 * Moves all top-level nonpopup windows into free desktop area, 00596 * attempting to keep them in the same position relative to the monitor 00597 * they were on. Also resets minimized info (so that when a window is 00598 * subsequently minimized it will go to the correct location). 00599 * 00600 * History: 00601 * 11-Sep-1996 adams Created. 00602 \***************************************************************************/ 00603 00604 void 00605 xxxDesktopRecalc(PMONITORRECTS pmrOld) 00606 { 00607 PWND pwndDesktop; 00608 PSMWP psmwp; 00609 PHWND phwnd; 00610 PBWL pbwl; 00611 PWND pwnd; 00612 CHECKPOINT * pcp; 00613 int iOldMonitor; 00614 int codeFullScreen; 00615 00616 UserVerify(pwndDesktop = _GetDesktopWindow()); 00617 if ((pbwl = BuildHwndList(pwndDesktop->spwndChild, BWL_ENUMLIST, NULL)) == NULL) 00618 return; 00619 00620 if ((psmwp = InternalBeginDeferWindowPos(4)) != NULL) { 00621 for (phwnd = pbwl->rghwnd; *phwnd != (HWND)1 && psmwp; phwnd++) { 00622 /* 00623 * Make sure this hwnd is still around. 00624 */ 00625 if ( (pwnd = RevalidateHwnd(*phwnd)) == NULL || 00626 TestWF(pwnd, WEFTOOLWINDOW)) { 00627 00628 continue; 00629 } 00630 00631 codeFullScreen = TestWF(pwnd, WFFULLSCREEN) ? 00632 NORMALIZERECT_FULLSCREEN : NORMALIZERECT_NORMAL; 00633 00634 pcp = (CHECKPOINT *)_GetProp(pwnd, PROP_CHECKPOINT, PROPF_INTERNAL); 00635 if (pcp) { 00636 00637 /* 00638 * We don't need to blow away saved maximized positions 00639 * anymore, since the max position is always (for top level 00640 * windows) relative to the origin of the monitor's working 00641 * area. And for child windows, we shouldn't do it period 00642 * anyway. 00643 */ 00644 pcp->fMinInitialized = FALSE; 00645 00646 /* 00647 * Figure out which monitor the position was on before things 00648 * got shuffled around and try to keep it on that monitor. If 00649 * it was never visible on a monitor then leave it alone. 00650 */ 00651 iOldMonitor = FindOldMonitor(&pcp->rcNormal, pmrOld); 00652 if (iOldMonitor != (UINT)-1) { 00653 NormalizeRect( 00654 &pcp->rcNormal, 00655 &pcp->rcNormal, 00656 pmrOld, 00657 iOldMonitor, 00658 codeFullScreen, 00659 pwnd->style); 00660 } 00661 } 00662 00663 /* 00664 * Figure out which monitor the position was on before things got 00665 * shuffled around and try to keep it on that monitor. If it 00666 * was never visible on a monitor then leave it alone. 00667 */ 00668 00669 iOldMonitor = FindOldMonitor(&pwnd->rcWindow, pmrOld); 00670 if (iOldMonitor != -1) { 00671 00672 PMONITOR pMonitorDst; 00673 RECT rc; 00674 00675 /* 00676 * Check for maximized apps that are truly maximized. 00677 * (As opposed to apps that manage their owm maximized rect.) 00678 */ 00679 if (TestWF(pwnd, WFMAXIMIZED)) { 00680 LPRECT lprcOldWork = &pmrOld->amp[iOldMonitor].rcWork; 00681 00682 if ( (pwnd->rcWindow.right - pwnd->rcWindow.left >= 00683 lprcOldWork->right - lprcOldWork->left) 00684 && 00685 (pwnd->rcWindow.bottom - pwnd->rcWindow.top >= 00686 lprcOldWork->bottom - lprcOldWork->top)) { 00687 00688 codeFullScreen = NORMALIZERECT_MAXIMIZED; 00689 } 00690 } 00691 00692 pMonitorDst = NormalizeRect( 00693 &rc, 00694 &pwnd->rcWindow, 00695 pmrOld, 00696 iOldMonitor, 00697 codeFullScreen, 00698 pwnd->style); 00699 00700 if (TestWF(pwnd, WFMAXFAKEREGIONAL)) { 00701 UserAssert(pMonitorDst->hrgnMonitor); 00702 pwnd->hrgnClip = pMonitorDst->hrgnMonitor; 00703 } 00704 00705 psmwp = _DeferWindowPos( 00706 psmwp, 00707 pwnd, 00708 (PWND)HWND_TOP, 00709 rc.left, 00710 rc.top, 00711 rc.right - rc.left, 00712 rc.bottom - rc.top, 00713 SWP_NOACTIVATE | SWP_NOZORDER); 00714 } 00715 } 00716 00717 if (psmwp) { 00718 xxxEndDeferWindowPosEx(psmwp, TRUE); 00719 } 00720 } 00721 00722 FreeHwndList(pbwl); 00723 } 00724 00725 00726 00727 /***************************************************************************\ 00728 * SetWindowMetricInt 00729 * 00730 * History: 00731 * 25-Feb-96 BradG Added Pixel -> TWIPS conversion 00732 \***************************************************************************/ 00733 00734 BOOL SetWindowMetricInt(PUNICODE_STRING pProfileUserName, 00735 WORD wKeyNameId, 00736 int iIniValue 00737 ) 00738 { 00739 /* 00740 * If you change the below list of STR_* make sure you make a corresponding 00741 * change in FastGetProfileIntFromID (profile.c) 00742 */ 00743 switch (wKeyNameId) { 00744 case STR_BORDERWIDTH: 00745 case STR_SCROLLWIDTH: 00746 case STR_SCROLLHEIGHT: 00747 case STR_CAPTIONWIDTH: 00748 case STR_CAPTIONHEIGHT: 00749 case STR_SMCAPTIONWIDTH: 00750 case STR_SMCAPTIONHEIGHT: 00751 case STR_MENUWIDTH: 00752 case STR_MENUHEIGHT: 00753 case STR_ICONHORZSPACING: 00754 case STR_ICONVERTSPACING: 00755 case STR_MINWIDTH: 00756 case STR_MINHORZGAP: 00757 case STR_MINVERTGAP: 00758 /* 00759 * Always store window metrics in TWIPS 00760 */ 00761 iIniValue = -MultDiv(iIniValue, 72*20, gpsi->dmLogPixels); 00762 break; 00763 } 00764 00765 return UpdateWinIniInt(pProfileUserName, 00766 PMAP_METRICS, 00767 wKeyNameId, 00768 iIniValue); 00769 } 00770 00771 /***************************************************************************\ 00772 * SetWindowMetricFont 00773 * 00774 * History: 00775 \***************************************************************************/ 00776 00777 BOOL SetWindowMetricFont(PUNICODE_STRING pProfileUserName, 00778 UINT idKey, 00779 LPLOGFONT lplf 00780 ) 00781 { 00782 return FastWriteProfileValue( 00783 pProfileUserName, 00784 PMAP_METRICS, 00785 (LPWSTR)UIntToPtr( idKey ), 00786 REG_BINARY, 00787 (LPBYTE)lplf, 00788 sizeof(LOGFONTW) 00789 ); 00790 } 00791 00792 00793 /***************************************************************************\ 00794 * SetAndDrawNCMetrics 00795 * 00796 * History: 00797 \***************************************************************************/ 00798 00799 BOOL xxxSetAndDrawNCMetrics(PUNICODE_STRING pProfileUserName, 00800 int clNewBorder, 00801 LPNONCLIENTMETRICS lpnc) 00802 { 00803 int dl; 00804 int dxMinOld; 00805 int dyMinOld; 00806 int cxBorder; 00807 int cyBorder; 00808 int dyCaption; 00809 int dyMenu; 00810 00811 dl = clNewBorder - gpsi->gclBorder; 00812 dxMinOld = SYSMET(CXMINIMIZED); 00813 dyMinOld = SYSMET(CYMINIMIZED); 00814 cxBorder = SYSMET(CXBORDER); 00815 cyBorder = SYSMET(CYBORDER); 00816 00817 00818 /* 00819 * Do we need to recalculate? 00820 */ 00821 if ((lpnc == NULL) && !dl) 00822 return(FALSE); 00823 00824 if (lpnc) { 00825 dyCaption = (int)lpnc->iCaptionHeight - SYSMET(CYSIZE); 00826 dyMenu = (int)lpnc->iMenuHeight - SYSMET(CYMENUSIZE); 00827 } else { 00828 dyCaption = dyMenu = 0; 00829 } 00830 00831 00832 /* 00833 * Recalculate the system metrics 00834 */ 00835 xxxSetWindowNCMetrics(pProfileUserName, lpnc, TRUE, clNewBorder); 00836 00837 /* 00838 * Reset our saved menu size/position info 00839 */ 00840 MenuRecalc(); 00841 00842 /* 00843 * Reset window sized, positions, frames 00844 */ 00845 xxxMetricsRecalc( 00846 CALC_FRAME | (dl ? CALC_RESIZE : 0), 00847 dl*cxBorder, 00848 dl*cyBorder, 00849 dyCaption, 00850 dyMenu); 00851 00852 dxMinOld = SYSMET(CXMINIMIZED) - dxMinOld; 00853 dyMinOld = SYSMET(CYMINIMIZED) - dyMinOld; 00854 if (dxMinOld || dyMinOld) { 00855 xxxMetricsRecalc(CALC_MINIMIZE, dxMinOld, dyMinOld, 0, 0); 00856 } 00857 00858 xxxRedrawScreen(); 00859 00860 00861 return TRUE; 00862 } 00863 00864 /***************************************************************************\ 00865 * xxxSetAndDrawMinMetrics 00866 * 00867 * History: 00868 * 13-May-1994 mikeke mikeke Ported 00869 \***************************************************************************/ 00870 BOOL xxxSetAndDrawMinMetrics(PUNICODE_STRING pProfileUserName, 00871 LPMINIMIZEDMETRICS lpmin 00872 ) 00873 { 00874 /* 00875 * Save minimized window dimensions 00876 */ 00877 int dxMinOld = SYSMET(CXMINIMIZED); 00878 int dyMinOld = SYSMET(CYMINIMIZED); 00879 00880 00881 SetMinMetrics(pProfileUserName,lpmin); 00882 00883 /* 00884 * Do we need to adjust minimized size? 00885 */ 00886 dxMinOld = SYSMET(CXMINIMIZED) - dxMinOld; 00887 dyMinOld = SYSMET(CYMINIMIZED) - dyMinOld; 00888 00889 if (dxMinOld || dyMinOld) { 00890 xxxMetricsRecalc(CALC_MINIMIZE, dxMinOld, dyMinOld, 0, 0); 00891 } 00892 00893 xxxRedrawScreen(); 00894 00895 00896 return TRUE; 00897 } 00898 00899 00900 /***************************************************************************\ 00901 * xxxSPISetNCMetrics 00902 * 00903 * History: 00904 * 13-May-1994 mikeke mikeke Ported 00905 \***************************************************************************/ 00906 00907 BOOL xxxSPISetNCMetrics(PUNICODE_STRING pProfileUserName, 00908 LPNONCLIENTMETRICS lpnc, 00909 BOOL fAlterWinIni 00910 ) 00911 { 00912 BOOL fWriteAllowed = !fAlterWinIni; 00913 BOOL fChanged = FALSE; 00914 00915 if (fAlterWinIni) { 00916 fChanged = SetWindowMetricInt(pProfileUserName,STR_BORDERWIDTH, (int) lpnc->iBorderWidth ); 00917 fChanged &= SetWindowMetricInt(pProfileUserName,STR_SCROLLWIDTH, (int) lpnc->iScrollWidth ); 00918 fChanged &= SetWindowMetricInt(pProfileUserName,STR_SCROLLHEIGHT, (int) lpnc->iScrollHeight ); 00919 fChanged &= SetWindowMetricInt(pProfileUserName,STR_CAPTIONWIDTH, (int) lpnc->iCaptionWidth ); 00920 fChanged &= SetWindowMetricInt(pProfileUserName,STR_CAPTIONHEIGHT, (int) lpnc->iCaptionHeight ); 00921 fChanged &= SetWindowMetricInt(pProfileUserName,STR_SMCAPTIONWIDTH, (int) lpnc->iSmCaptionWidth ); 00922 fChanged &= SetWindowMetricInt(pProfileUserName,STR_SMCAPTIONHEIGHT, (int) lpnc->iSmCaptionHeight ); 00923 fChanged &= SetWindowMetricInt(pProfileUserName,STR_MENUWIDTH, (int) lpnc->iMenuWidth ); 00924 fChanged &= SetWindowMetricInt(pProfileUserName,STR_MENUHEIGHT, (int) lpnc->iMenuHeight ); 00925 00926 fChanged &= SetWindowMetricFont(pProfileUserName,STR_CAPTIONFONT, &lpnc->lfCaptionFont ); 00927 fChanged &= SetWindowMetricFont(pProfileUserName,STR_SMCAPTIONFONT, &lpnc->lfSmCaptionFont ); 00928 fChanged &= SetWindowMetricFont(pProfileUserName,STR_MENUFONT, &lpnc->lfMenuFont ); 00929 fChanged &= SetWindowMetricFont(pProfileUserName,STR_STATUSFONT, &lpnc->lfStatusFont ); 00930 fChanged &= SetWindowMetricFont(pProfileUserName,STR_MESSAGEFONT, &lpnc->lfMessageFont ); 00931 00932 fWriteAllowed = fChanged; 00933 } 00934 00935 if (fWriteAllowed) 00936 xxxSetAndDrawNCMetrics(pProfileUserName,(int) lpnc->iBorderWidth, lpnc); 00937 00938 return fChanged; 00939 } 00940 00941 /***************************************************************************\ 00942 * xxxSPISetMinMetrics 00943 * 00944 * History: 00945 * 13-May-1994 mikeke mikeke Ported 00946 \***************************************************************************/ 00947 00948 BOOL xxxSPISetMinMetrics(PUNICODE_STRING pProfileUserName, 00949 LPMINIMIZEDMETRICS lpmin, 00950 BOOL fAlterWinIni 00951 ) 00952 { 00953 BOOL fWriteAllowed = !fAlterWinIni; 00954 BOOL fChanged = FALSE; 00955 00956 if (fAlterWinIni) { 00957 fChanged = SetWindowMetricInt(pProfileUserName,STR_MINWIDTH, (int) lpmin->iWidth ); 00958 fChanged &= SetWindowMetricInt(pProfileUserName,STR_MINHORZGAP, (int) lpmin->iHorzGap ); 00959 fChanged &= SetWindowMetricInt(pProfileUserName,STR_MINVERTGAP, (int) lpmin->iVertGap ); 00960 fChanged &= SetWindowMetricInt(pProfileUserName,STR_MINARRANGE, (int) lpmin->iArrange ); 00961 00962 fWriteAllowed = fChanged; 00963 } 00964 00965 if (fWriteAllowed) { 00966 xxxSetAndDrawMinMetrics(pProfileUserName,lpmin); 00967 } 00968 00969 return fChanged; 00970 } 00971 00972 00973 /***************************************************************************\ 00974 * SPISetIconMetrics 00975 * 00976 * History: 00977 * 13-May-1994 mikeke mikeke Ported 00978 \***************************************************************************/ 00979 BOOL SPISetIconMetrics(PUNICODE_STRING pProfileUserName, 00980 LPICONMETRICS lpicon, 00981 BOOL fAlterWinIni 00982 ) 00983 { 00984 BOOL fWriteAllowed = !fAlterWinIni; 00985 BOOL fChanged = FALSE; 00986 00987 if (fAlterWinIni) { 00988 fChanged = SetWindowMetricInt(pProfileUserName,STR_ICONHORZSPACING, (int) lpicon->iHorzSpacing); 00989 fChanged &= SetWindowMetricInt(pProfileUserName,STR_ICONVERTSPACING, (int) lpicon->iVertSpacing); 00990 fChanged &= SetWindowMetricInt(pProfileUserName,STR_ICONTITLEWRAP, (int) lpicon->iTitleWrap); 00991 fChanged &= SetWindowMetricFont(pProfileUserName,STR_ICONFONT, &lpicon->lfFont); 00992 00993 fWriteAllowed = fChanged; 00994 } 00995 00996 if (fWriteAllowed) { 00997 00998 SetIconMetrics(pProfileUserName,lpicon); 00999 01000 xxxRedrawScreen(); 01001 } 01002 01003 return fChanged; 01004 } 01005 01006 01007 /***************************************************************************\ 01008 * SPISetIconTitleFont 01009 * 01010 * History: 01011 * 13-May-1994 mikeke mikeke Ported 01012 \***************************************************************************/ 01013 01014 BOOL SPISetIconTitleFont(PUNICODE_STRING pProfileUserName, 01015 LPLOGFONT lplf, 01016 BOOL fAlterWinIni 01017 ) 01018 { 01019 HFONT hfnT; 01020 BOOL fWriteAllowed = !fAlterWinIni; 01021 BOOL fWinIniChanged = FALSE; 01022 01023 if (hfnT = CreateFontFromWinIni(pProfileUserName,lplf, STR_ICONFONT)) { 01024 if (fAlterWinIni) { 01025 01026 if (lplf) { 01027 LOGFONT lf; 01028 01029 GreExtGetObjectW(hfnT, sizeof(LOGFONTW), &lf); 01030 fWinIniChanged = SetWindowMetricFont(pProfileUserName,STR_ICONFONT, &lf); 01031 } else { 01032 /* 01033 * !lParam so go back to current win.ini settings so 01034 */ 01035 fWinIniChanged = TRUE; 01036 } 01037 01038 fWriteAllowed = fWinIniChanged; 01039 } 01040 01041 if (fWriteAllowed) { 01042 01043 if (ghIconFont) { 01044 GreMarkDeletableFont(ghIconFont); 01045 GreDeleteObject(ghIconFont); 01046 } 01047 01048 ghIconFont = hfnT; 01049 01050 } else { 01051 GreMarkDeletableFont(hfnT); 01052 GreDeleteObject(hfnT); 01053 } 01054 } 01055 01056 return fWinIniChanged; 01057 } 01058 01059 /***************************************************************************\ 01060 * xxxSetSPIMetrics 01061 * 01062 * History: 01063 * 13-May-1994 mikeke mikeke Ported 01064 \***************************************************************************/ 01065 01066 BOOL 01067 xxxSetSPIMetrics(PUNICODE_STRING pProfileUserName, 01068 DWORD wFlag, 01069 LPVOID lParam, 01070 BOOL fAlterWinIni 01071 ) 01072 { 01073 BOOL fWinIniChanged; 01074 01075 switch (wFlag) { 01076 case SPI_SETANIMATION: 01077 if (fAlterWinIni) { 01078 fWinIniChanged = SetWindowMetricInt(pProfileUserName, 01079 STR_MINANIMATE, 01080 (int) ((LPANIMATIONINFO) lParam)->iMinAnimate 01081 ); 01082 01083 if (!fWinIniChanged) { 01084 return FALSE; 01085 } 01086 } else { 01087 fWinIniChanged = FALSE; 01088 } 01089 01090 SET_OR_CLEAR_PUDF(PUDF_ANIMATE, ((LPANIMATIONINFO) lParam)->iMinAnimate); 01091 return fWinIniChanged; 01092 01093 case SPI_SETNONCLIENTMETRICS: 01094 return xxxSPISetNCMetrics(pProfileUserName,(LPNONCLIENTMETRICS) lParam, fAlterWinIni); 01095 01096 case SPI_SETICONMETRICS: 01097 return SPISetIconMetrics(pProfileUserName,(LPICONMETRICS) lParam, fAlterWinIni); 01098 01099 case SPI_SETMINIMIZEDMETRICS: 01100 return xxxSPISetMinMetrics(pProfileUserName,(LPMINIMIZEDMETRICS) lParam, fAlterWinIni); 01101 01102 case SPI_SETICONTITLELOGFONT: 01103 return SPISetIconTitleFont(pProfileUserName,(LPLOGFONT) lParam, fAlterWinIni); 01104 01105 default: 01106 RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING, "SetSPIMetrics. Invalid wFlag: %#lx", wFlag); 01107 return FALSE; 01108 } 01109 } 01110 01111 /***************************************************************************\ 01112 * SetFilterKeys 01113 * 01114 * History: 01115 * 10-12-94 JimA Created. 01116 \***************************************************************************/ 01117 01118 BOOL SetFilterKeys(PUNICODE_STRING pProfileUserName, 01119 LPFILTERKEYS pFilterKeys) 01120 { 01121 LPWSTR pwszd = L"%d"; 01122 BOOL fWinIniChanged; 01123 WCHAR szTemp[40]; 01124 01125 swprintf(szTemp, pwszd, pFilterKeys->dwFlags); 01126 fWinIniChanged = FastWriteProfileStringW(pProfileUserName, 01127 PMAP_KEYBOARDRESPONSE, 01128 L"Flags", 01129 szTemp 01130 ); 01131 01132 swprintf(szTemp, pwszd, pFilterKeys->iWaitMSec); 01133 fWinIniChanged &= FastWriteProfileStringW(pProfileUserName, 01134 PMAP_KEYBOARDRESPONSE, 01135 L"DelayBeforeAcceptance", 01136 szTemp 01137 ); 01138 01139 swprintf(szTemp, pwszd, pFilterKeys->iDelayMSec); 01140 fWinIniChanged &= FastWriteProfileStringW(pProfileUserName, 01141 PMAP_KEYBOARDRESPONSE, 01142 L"AutoRepeatDelay", 01143 szTemp 01144 ); 01145 01146 swprintf(szTemp, pwszd, pFilterKeys->iRepeatMSec); 01147 fWinIniChanged &= FastWriteProfileStringW(pProfileUserName, 01148 PMAP_KEYBOARDRESPONSE, 01149 L"AutoRepeatRate", 01150 szTemp 01151 ); 01152 01153 swprintf(szTemp, pwszd, pFilterKeys->iBounceMSec); 01154 fWinIniChanged &= FastWriteProfileStringW(pProfileUserName, 01155 PMAP_KEYBOARDRESPONSE, 01156 L"BounceTime", 01157 szTemp 01158 ); 01159 01160 return fWinIniChanged; 01161 } 01162 01163 /***************************************************************************\ 01164 * SetMouseKeys 01165 * 01166 * History: 01167 * 10-12-94 JimA Created. 01168 \***************************************************************************/ 01169 01170 BOOL SetMouseKeys(PUNICODE_STRING pProfileUserName, 01171 LPMOUSEKEYS pMK) 01172 { 01173 LPWSTR pwszd = L"%d"; 01174 BOOL fWinIniChanged; 01175 WCHAR szTemp[40]; 01176 01177 swprintf(szTemp, pwszd, pMK->dwFlags); 01178 fWinIniChanged = FastWriteProfileStringW(pProfileUserName, 01179 PMAP_MOUSEKEYS, 01180 L"Flags", 01181 szTemp 01182 ); 01183 01184 swprintf(szTemp, pwszd, pMK->iMaxSpeed); 01185 fWinIniChanged &= FastWriteProfileStringW(pProfileUserName, 01186 PMAP_MOUSEKEYS, 01187 L"MaximumSpeed", 01188 szTemp 01189 ); 01190 01191 swprintf(szTemp, pwszd, pMK->iTimeToMaxSpeed); 01192 fWinIniChanged &= FastWriteProfileStringW(pProfileUserName, 01193 PMAP_MOUSEKEYS, 01194 L"TimeToMaximumSpeed", 01195 szTemp 01196 ); 01197 01198 return fWinIniChanged; 01199 } 01200 01201 /***************************************************************************\ 01202 * SetSoundSentry 01203 * 01204 * History: 01205 * 10-12-94 JimA Created. 01206 \***************************************************************************/ 01207 01208 BOOL SetSoundSentry(PUNICODE_STRING pProfileUserName, 01209 LPSOUNDSENTRY pSS) 01210 { 01211 LPWSTR pwszd = L"%d"; 01212 BOOL fWinIniChanged; 01213 WCHAR szTemp[40]; 01214 01215 swprintf(szTemp, pwszd, pSS->dwFlags); 01216 fWinIniChanged = FastWriteProfileStringW(pProfileUserName, 01217 PMAP_SOUNDSENTRY, 01218 L"Flags", 01219 szTemp 01220 ); 01221 01222 swprintf(szTemp, pwszd, pSS->iFSTextEffect); 01223 fWinIniChanged &= FastWriteProfileStringW(pProfileUserName, 01224 PMAP_SOUNDSENTRY, 01225 L"TextEffect", 01226 szTemp 01227 ); 01228 01229 swprintf(szTemp, pwszd, pSS->iWindowsEffect); 01230 fWinIniChanged &= FastWriteProfileStringW(pProfileUserName, 01231 PMAP_SOUNDSENTRY, 01232 L"WindowsEffect", 01233 szTemp 01234 ); 01235 01236 return fWinIniChanged; 01237 } 01238 01239 01240 /***************************************************************************\ 01241 * CalculateMouseSensitivity 01242 * 01243 * History: 01244 * 09-27-96 jparsons Created. 01245 \***************************************************************************/ 01246 01247 LONG CalculateMouseSensitivity(LONG lSens) 01248 /* 01249 * The resultant table looks like this... 01250 * 01251 * Sens | Sensitivity Adjustment 01252 * 0 | 0 * SENS_SCALAR ALGORITHM 0<=NUM<=2 01253 * 1 | 1/32 * SENS_SCALAR (NUM/32)*SENS_SCALAR 01254 * 2 | 1/16 * SENS_SCALAR 01255 * 3 | 1/8 * SENS_SCALAR ALGORITHM 3<=NUM<=10 01256 * 4 | 1/4 (2/8) * SENS_SCALAR ((NUM-2)/8)*SENS_SCALAR 01257 * 5 | 3/8 * SENS_SCALAR 01258 * 6 | 1/2 (4/8) * SENS_SCALAR 01259 * 7 | 5/8 * SENS_SCALAR 01260 * 8 | 3/4 (6/8) * SENS_SCALAR 01261 * 9 | 7/8 * SENS_SCALAR 01262 * 10 | 1 * SENS_SCALAR 01263 * 11 | 5/4 * SENS_SCALAR ALGORITHM NUM>=11 01264 * 12 | 3/2 (6/4) * SENS_SCALAR ((NUM-6)/4)*SENS_SCALAR 01265 * 13 | 7/4 * SENS_SCALAR 01266 * 14 | 2 (8/4) * SENS_SCALAR 01267 * 15 | 9/4 * SENS_SCALAR 01268 * 16 | 5/2 (10/4) * SENS_SCALAR 01269 * 17 | 11/4 * SENS_SCALAR 01270 * 18 | 3 (12/4) * SENS_SCALAR 01271 * 19 | 13/4 * SENS_SCALAR 01272 * 20 | 7/2 (14/4) * SENS_SCALAR 01273 * 01274 * COMMENTS: Sensitivities are constrained to be between 1 and 20. 01275 */ 01276 { 01277 LONG lSenFactor ; 01278 01279 if(lSens <= 2) 01280 lSenFactor=lSens*256/32 ; 01281 else if(lSens >= 3 && lSens <= 10 ) 01282 lSenFactor=(lSens-2)*256/8 ; 01283 else 01284 lSenFactor=(lSens-6)*256/4 ; 01285 01286 return lSenFactor ; 01287 } 01288 01289 01290 /***************************************************************************\ 01291 * xxxSystemParametersInfo 01292 * 01293 * SPI_GETBEEP: wParam is not used. lParam is long pointer to a boolean which 01294 * gets true if beep on, false if beep off. 01295 * 01296 * SPI_SETBEEP: wParam is a bool which sets beep on (true) or off (false). 01297 * lParam is not used. 01298 * 01299 * SPI_GETMOUSE: wParam is not used. lParam is long pointer to an integer 01300 * array where rgw[0] gets xMouseThreshold, rgw[1] gets 01301 * yMouseThreshold, and rgw[2] gets gMouseSpeed. 01302 * 01303 * SPI_SETMOUSE: wParam is not used. lParam is long pointer to an integer 01304 * array as described above. User's values are set to values 01305 * in array. 01306 * 01307 * SPI_GETBORDER: wParam is not used. lParam is long pointer to an integer 01308 * which gets the value of clBorder (border multiplier factor). 01309 * 01310 * SPI_SETBORDER: wParam is an integer which sets gpsi->gclBorder. 01311 * lParam is not used. 01312 * 01313 * SPI_GETKEYBOARDDELAY: wParam is not used. lParam is a long pointer to an int 01314 * which gets the current keyboard repeat delay setting. 01315 * 01316 * SPI_SETKEYBOARDDELAY: wParam is the new keyboard delay setting. 01317 * lParam is not used. 01318 * 01319 * SPI_GETKEYBOARDSPEED: wParam is not used. lParam is a long pointer 01320 * to an int which gets the current keyboard repeat 01321 * speed setting. 01322 * 01323 * SPI_SETKEYBOARDSPEED: wParam is the new keyboard speed setting. 01324 * lParam is not used. 01325 * 01326 * SPI_KANJIMENU: wParam contains: 01327 * 1 - Mouse accelerator 01328 * 2 - ASCII accelerator 01329 * 3 - Kana accelerator 01330 * lParam is not used. The wParam value is stored in the global 01331 * KanjiMenu for use in accelerator displaying & searching. 01332 * 01333 * SPI_LANGDRIVER: wParam is not used. 01334 * lParam contains a LPSTR to the new language driver filename. 01335 * 01336 * SPI_ICONHORIZONTALSPACING: wParam is the width in pixels of an icon cell. 01337 * 01338 * SPI_ICONVERTICALSPACING: wParam is the height in pixels of an icon cell. 01339 * 01340 * SPI_GETSCREENSAVETIMEOUT: wParam is not used 01341 * lParam is a pointer to an int which gets the screen saver 01342 * timeout value. 01343 * 01344 * SPI_SETSCREENSAVETIMEOUT: wParam is the time in seconds for the system 01345 * to be idle before screensaving. 01346 * 01347 * SPI_GETSCREENSAVEACTIVE: lParam is a pointer to a BOOL which gets TRUE 01348 * if the screensaver is active else gets false. 01349 * 01350 * SPI_SETSCREENSAVEACTIVE: if wParam is TRUE, screensaving is activated 01351 * else it is deactivated. 01352 * 01353 * SPI_GETLOWPOWERTIMEOUT: 01354 * SPI_GETPOWEROFFTIMEOUT: wParam is not used 01355 * lParam is a pointer to an int which gets the appropriate 01356 * power saving screen blanker timeout value. 01357 * 01358 * SPI_SETLOWPOWERTIMEOUT: 01359 * SPI_SETPOWEROFFTIMEOUT: wParam is the time in seconds for the system 01360 * to be idle before power saving screen blanking. 01361 * 01362 * SPI_GETLOWPOWERACTIVE: 01363 * SPI_GETPOWEROFFACTIVE: lParam is a pointer to a BOOL which gets TRUE 01364 * if the power saving screen blanker is active else gets false. 01365 * 01366 * SPI_SETLOWPOWERACTIVE: 01367 * SPI_SETPOWEROFFACTIVE: if wParam is TRUE, power saving screen blanking is 01368 * activated else it is deactivated. 01369 * 01370 * SPI_GETGRIDGRANULARITY: Obsolete. Returns 1 always. 01371 * 01372 * SPI_SETGRIDGRANULARITY: Obsolete. Does nothing. 01373 * 01374 * SPI_SETDESKWALLPAPER: wParam is not used; lParam is a long ptr to a string 01375 * that holds the name of the bitmap file to be used as the 01376 * desktop wall paper. 01377 * 01378 * SPI_SETDESKPATTERN: Both wParam and lParam are not used; USER will read the 01379 * "pattern=" from WIN.INI and make it as the current desktop 01380 * pattern; 01381 * 01382 * SPI_GETICONTITLEWRAP: lParam is LPINT which gets 0 if wrapping if off 01383 * else gets 1. 01384 * 01385 * SPI_SETICONTITLEWRAP: wParam specifies TRUE to turn wrapping on else false 01386 * 01387 * SPI_GETMENUDROPALIGNMENT: lParam is LPINT which gets 0 specifies if menus 01388 * drop left aligned else 1 if drop right aligned. 01389 * 01390 * SPI_SETMENUDROPALIGNMENT: wParam 0 specifies if menus drop left aligned else 01391 * the drop right aligned. 01392 * 01393 * SPI_SETDOUBLECLKWIDTH: wParam specifies the width of the rectangle 01394 * within which the second click of a double click must fall 01395 * for it to be registered as a double click. 01396 * 01397 * SPI_SETDOUBLECLKHEIGHT: wParam specifies the height of the rectangle 01398 * within which the second click of a double click must fall 01399 * for it to be registered as a double click. 01400 * 01401 * SPI_GETICONTITLELOGFONT: lParam is a pointer to a LOGFONT struct which 01402 * gets the logfont for the current icon title font. wParam 01403 * specifies the size of the logfont struct. 01404 * 01405 * SPI_SETDOUBLECLICKTIME: wParm specifies the double click time 01406 * 01407 * SPI_SETMOUSEBUTTONSWAP: if wParam is 1, swap mouse buttons else if wParam 01408 * is 0, don't swap buttons 01409 * SPI_SETDRAGFULLWINDOWS: wParam = fSet. 01410 * SPI_GETDRAGFULLWINDOWS: returns fSet. 01411 * 01412 * SPI_GETFILTERKEYS: lParam is a pointer to a FILTERKEYS struct. wParam 01413 * specifies the size of the filterkeys struct. 01414 * 01415 * SPI_SETFILTERKEYS: lParam is a pointer to a FILTERKEYS struct. wParam 01416 * is not used. 01417 * 01418 * SPI_GETSTICKYKEYS: lParam is a pointer to a STICKYKEYS struct. wParam 01419 * specifies the size of the stickykeys struct. 01420 * 01421 * SPI_SETSTICKYKEYS: lParam is a pointer to a STICKYKEYS struct. wParam 01422 * is not used. 01423 * 01424 * SPI_GETMOUSEKEYS: lParam is a pointer to a MOUSEKEYS struct. wParam 01425 * specifies the size of the mousekeys struct. 01426 * 01427 * SPI_SETMOUSEKEYS: lParam is a pointer to a MOUSEKEYS struct. wParam 01428 * is not used. 01429 * 01430 * SPI_GETACCESSTIMEOUT: lParam is a pointer to an ACCESSTIMEOUT struct. 01431 * wParam specifies the size of the accesstimeout struct. 01432 * 01433 * SPI_SETACCESSTIMEOUT: lParam is a pointer to a ACCESSTIMEOUT struct. 01434 * wParam is not used. 01435 * 01436 * SPI_GETTOGGLEKEYS: lParam is a pointer to a TOGGLEKEYS struct. wParam 01437 * specifies the size of the togglekeys struct. 01438 * 01439 * SPI_SETTOGGLEKEYS: lParam is a pointer to a TOGGLEKEYS struct. wParam 01440 * is not used. 01441 * 01442 * SPI_GETKEYBOARDPREF: lParam is a pointer to a BOOL. 01443 * wParam is not used. 01444 * 01445 * SPI_SETKEYBOARDPREF: wParam is a BOOL. 01446 * lParam is not used. 01447 * 01448 * SPI_GETSCREENREADER: lParam is a pointer to a BOOL. 01449 * wParam is not used. 01450 * 01451 * SPI_SETSCREENREADER: wParam is a BOOL. 01452 * lParam is not used. 01453 * 01454 * SPI_GETSHOWSOUNDS: lParam is a pointer to a SHOWSOUNDS struct. wParam 01455 * specifies the size of the showsounds struct. 01456 * 01457 * SPI_SETSHOWSOUNDS: lParam is a pointer to a SHOWSOUNDS struct. wParam 01458 * is not used. 01459 * 01460 * SPI_GETNONCLIENTMETRICS: lParam is a pointer to a NONCLIENTMETRICSW struct. 01461 * wPAram is not used. 01462 * 01463 * SPI_GETSNAPTODEFBUTTON: lParam is a pointer to a BOOL which gets TRUE 01464 * if the snap to default push button is active else gets false. 01465 * 01466 * SPI_SETSNAPTODEFBUTTON: if wParam is TRUE, dialog boxes will snap the mouse 01467 * pointer to the default push button when created. 01468 * 01469 * SPI_GETFONTSMOOTHING: 01470 * wParam is unused 01471 * lParam is LPINT for boolean fFontSmoothing 01472 * 01473 * SPI_SETFONTSMOOTHING: 01474 * wParam is INT for boolean fFontSmoothing 01475 * 01476 * SPI_GETWHEELSCROLLLINES: lParam is a pointer to a ULONG to receive the 01477 * suggested number of lines to scroll when the wheel is 01478 * rotated. wParam is unused. 01479 * 01480 * SPI_SETWHEELSCROLLLINES: wParam is a ULONG containing the suggested number 01481 * of lines to scroll when the wheel is rotated. lParam is 01482 * unused. 01483 * 01484 * SPI_SETSCREENSAVERRUNNING / SPI_SCREENSAVERRUNNING: not supported on NT. 01485 * SPI_GETSCREENSAVERRUNNING: wParam - Not used. lParam a pointer to a BOOL which 01486 * will receive TRUE is a screen saver is running or FALSE otherwise. 01487 * 01488 * SPI_SETSHOWIMEUI wParam is TRUE or FALSE 01489 * SPI_GETSHOWIMEUI neither wParam or lParam used 01490 * 01491 * History: 01492 * 06-28-91 MikeHar Ported. 01493 * 12-8-93 SanfordS Added SPI_SET/GETDRAGFULLWINDOWS 01494 * 20-May-1996 adams Added SPI_SET/GETWHEELSCROLLLINES 01495 \***************************************************************************/ 01496 01497 BOOL xxxSystemParametersInfo( 01498 UINT wFlag, // Item to change 01499 DWORD wParam, 01500 PVOID lParam, 01501 UINT flags 01502 ) 01503 { 01504 PPROCESSINFO ppi = PpiCurrent(); 01505 int clBorderOld; 01506 int clBorderNew; 01507 LPWSTR pwszd = L"%d"; 01508 WCHAR szSection[40]; 01509 WCHAR szTemp[40]; 01510 WCHAR szPat[MAX_PATH]; 01511 BOOL fWinIniChanged = FALSE; 01512 BOOL fAlterWinIni = ((flags & SPIF_UPDATEINIFILE) != 0); 01513 BOOL fSendWinIniChange = ((flags & SPIF_SENDCHANGE) != 0); 01514 BOOL fWriteAllowed = !fAlterWinIni; 01515 ACCESS_MASK amRequest; 01516 LARGE_UNICODE_STRING strSection; 01517 int *piTimeOut; 01518 int iResID; 01519 TL tlName; 01520 PUNICODE_STRING pProfileUserName = NULL; 01521 01522 UserAssert(IsWinEventNotifyDeferredOK()); 01523 01524 /* 01525 * CONSIDER(adams) : Many of the SPI_GET* could be implemented 01526 * on the client side (SnapTo, WheelScrollLines, etc.). 01527 */ 01528 01529 /* 01530 * Features not implemented 01531 */ 01532 01533 switch (wFlag) 01534 { 01535 case SPI_TIMEOUTS: 01536 case SPI_KANJIMENU: 01537 case SPI_LANGDRIVER: 01538 case SPI_UNUSED39: 01539 case SPI_UNUSED40: 01540 case SPI_SETPENWINDOWS: 01541 01542 case SPI_GETWINDOWSEXTENSION: 01543 case SPI_SETSCREENSAVERRUNNING: // same as SPI_SCREENSAVERRUNNING 01544 01545 case SPI_GETSERIALKEYS: 01546 case SPI_SETSERIALKEYS: 01547 01548 case SPI_SETMOUSETRAILS: 01549 case SPI_GETMOUSETRAILS: 01550 RIPERR1(ERROR_INVALID_PARAMETER, 01551 RIP_WARNING, 01552 "SPI_ 0x%lx parameter not supported", wFlag ); 01553 01554 return FALSE; 01555 } 01556 01557 01558 /* 01559 * Perform access check. Always grant access to CSR. 01560 */ 01561 if (ppi->Process != gpepCSRSS) { 01562 switch (wFlag) { 01563 case SPI_SETBEEP: 01564 case SPI_SETMOUSE: 01565 case SPI_SETBORDER: 01566 case SPI_SETKEYBOARDSPEED: 01567 case SPI_SETDEFAULTINPUTLANG: 01568 case SPI_SETSCREENSAVETIMEOUT: 01569 case SPI_SETSCREENSAVEACTIVE: 01570 case SPI_SETLOWPOWERTIMEOUT: 01571 case SPI_SETPOWEROFFTIMEOUT: 01572 case SPI_SETLOWPOWERACTIVE: 01573 case SPI_SETPOWEROFFACTIVE: 01574 case SPI_SETGRIDGRANULARITY: 01575 case SPI_SETDESKWALLPAPER: 01576 case SPI_SETDESKPATTERN: 01577 case SPI_SETKEYBOARDDELAY: 01578 case SPI_SETICONTITLEWRAP: 01579 case SPI_SETMENUDROPALIGNMENT: 01580 case SPI_SETDOUBLECLKWIDTH: 01581 case SPI_SETDOUBLECLKHEIGHT: 01582 case SPI_SETDOUBLECLICKTIME: 01583 case SPI_SETMOUSEBUTTONSWAP: 01584 case SPI_SETICONTITLELOGFONT: 01585 case SPI_SETFASTTASKSWITCH: 01586 case SPI_SETFILTERKEYS: 01587 case SPI_SETTOGGLEKEYS: 01588 case SPI_SETMOUSEKEYS: 01589 case SPI_SETSHOWSOUNDS: 01590 case SPI_SETSTICKYKEYS: 01591 case SPI_SETACCESSTIMEOUT: 01592 case SPI_SETSOUNDSENTRY: 01593 case SPI_SETKEYBOARDPREF: 01594 case SPI_SETSCREENREADER: 01595 case SPI_SETSNAPTODEFBUTTON: 01596 case SPI_SETANIMATION: 01597 case SPI_SETNONCLIENTMETRICS: 01598 case SPI_SETICONMETRICS: 01599 case SPI_SETMINIMIZEDMETRICS: 01600 case SPI_SETWORKAREA: 01601 case SPI_SETFONTSMOOTHING: 01602 case SPI_SETMOUSEHOVERWIDTH: 01603 case SPI_SETMOUSEHOVERHEIGHT: 01604 case SPI_SETMOUSEHOVERTIME: 01605 case SPI_SETWHEELSCROLLLINES: 01606 case SPI_SETMENUSHOWDELAY: 01607 case SPI_SETHIGHCONTRAST: 01608 case SPI_SETDRAGFULLWINDOWS: 01609 case SPI_SETDRAGWIDTH: 01610 case SPI_SETDRAGHEIGHT: 01611 case SPI_SETCURSORS: 01612 case SPI_SETICONS: 01613 case SPI_SETLANGTOGGLE: 01614 amRequest = WINSTA_WRITEATTRIBUTES; 01615 break; 01616 01617 case SPI_ICONHORIZONTALSPACING: 01618 case SPI_ICONVERTICALSPACING: 01619 if (IS_PTR(lParam)) { 01620 amRequest = WINSTA_READATTRIBUTES; 01621 } else if (wParam) { 01622 amRequest = WINSTA_WRITEATTRIBUTES; 01623 } else 01624 return TRUE; 01625 break; 01626 01627 default: 01628 if ((wFlag & SPIF_RANGETYPEMASK) && (wFlag & SPIF_SET)) { 01629 amRequest = WINSTA_WRITEATTRIBUTES; 01630 } else { 01631 amRequest = WINSTA_READATTRIBUTES; 01632 } 01633 break; 01634 } 01635 01636 if (amRequest == WINSTA_READATTRIBUTES) { 01637 RETURN_IF_ACCESS_DENIED(ppi->amwinsta, amRequest, FALSE); 01638 } else { 01639 UserAssert(amRequest == WINSTA_WRITEATTRIBUTES); 01640 if (!CheckWinstaWriteAttributesAccess()) { 01641 return FALSE; 01642 } 01643 } 01644 01645 /* 01646 * If we're reading, then set the write flag to ensure that 01647 * the return value will be TRUE. 01648 */ 01649 if (amRequest == WINSTA_READATTRIBUTES) 01650 fWriteAllowed = TRUE; 01651 } else { 01652 fWriteAllowed = TRUE; 01653 } 01654 01655 /* 01656 * Make sure the section buffer is terminated. 01657 */ 01658 szSection[0] = 0; 01659 01660 switch (wFlag) { 01661 case SPI_GETBEEP: 01662 (*(BOOL *)lParam) = TEST_BOOL_PUDF(PUDF_BEEP); 01663 break; 01664 01665 case SPI_SETBEEP: 01666 if (fAlterWinIni) { 01667 ServerLoadString( 01668 hModuleWin, 01669 (UINT)(wParam ? STR_BEEPYES : STR_BEEPNO), 01670 (LPWSTR)szTemp, 10); 01671 01672 fWinIniChanged = FastUpdateWinIni(NULL, 01673 PMAP_BEEP, 01674 (UINT) STR_BEEP, 01675 szTemp 01676 ); 01677 01678 fWriteAllowed = fWinIniChanged; 01679 } 01680 01681 if (fWriteAllowed) { 01682 SET_OR_CLEAR_PUDF(PUDF_BEEP, wParam); 01683 } 01684 01685 break; 01686 01687 01688 case SPI_SETMOUSESPEED: 01689 if (((LONG_PTR) lParam < MOUSE_SENSITIVITY_MIN) || ((LONG_PTR) lParam > MOUSE_SENSITIVITY_MAX)) { 01690 return FALSE ; 01691 } 01692 01693 if (fAlterWinIni) { 01694 swprintf(szTemp, pwszd, lParam) ; 01695 fWinIniChanged = FastUpdateWinIni(NULL, 01696 PMAP_MOUSE, 01697 STR_MOUSESENSITIVITY, 01698 szTemp 01699 ); 01700 01701 fWriteAllowed = fWinIniChanged; 01702 } 01703 01704 if (fWriteAllowed) { 01705 gMouseSensitivity = PtrToLong(lParam); 01706 gMouseSensitivityFactor = CalculateMouseSensitivity(PtrToLong(lParam)) ; 01707 } 01708 break; 01709 01710 case SPI_GETMOUSESPEED: 01711 *((LPINT)lParam) = gMouseSensitivity ; 01712 break; 01713 01714 case SPI_GETMOUSE: 01715 ((LPINT)lParam)[0] = gMouseThresh1; 01716 ((LPINT)lParam)[1] = gMouseThresh2; 01717 ((LPINT)lParam)[2] = gMouseSpeed; 01718 break; 01719 01720 case SPI_SETMOUSE: 01721 if (fAlterWinIni) { 01722 BOOL bWritten1, bWritten2, bWritten3; 01723 01724 pProfileUserName = CreateProfileUserName(&tlName); 01725 bWritten1 = UpdateWinIniInt(pProfileUserName, PMAP_MOUSE, STR_MOUSETHRESH1, ((LPINT)lParam)[0]); 01726 bWritten2 = UpdateWinIniInt(pProfileUserName, PMAP_MOUSE, STR_MOUSETHRESH2, ((LPINT)lParam)[1]); 01727 bWritten3 = UpdateWinIniInt(pProfileUserName, PMAP_MOUSE, STR_MOUSESPEED, ((LPINT)lParam)[2]); 01728 if (bWritten1 && bWritten2 && bWritten3) 01729 fWinIniChanged = TRUE; 01730 else { 01731 01732 /* 01733 * Attempt to backout any changes. 01734 */ 01735 if (bWritten1) { 01736 UpdateWinIniInt(pProfileUserName, PMAP_MOUSE, STR_MOUSETHRESH1, gMouseThresh1); 01737 } 01738 if (bWritten2) { 01739 UpdateWinIniInt(pProfileUserName, PMAP_MOUSE, STR_MOUSETHRESH2, gMouseThresh2); 01740 } 01741 if (bWritten3) { 01742 UpdateWinIniInt(pProfileUserName, PMAP_MOUSE, STR_MOUSESPEED, gMouseSpeed); 01743 } 01744 } 01745 fWriteAllowed = fWinIniChanged; 01746 FreeProfileUserName(pProfileUserName, &tlName); 01747 } 01748 if (fWriteAllowed) { 01749 gMouseThresh1 = ((LPINT)lParam)[0]; 01750 gMouseThresh2 = ((LPINT)lParam)[1]; 01751 gMouseSpeed = ((LPINT)lParam)[2]; 01752 } 01753 break; 01754 01755 case SPI_GETSNAPTODEFBUTTON: 01756 (*(LPBOOL)lParam) = TEST_BOOL_PUSIF(PUSIF_SNAPTO); 01757 break; 01758 01759 case SPI_SETSNAPTODEFBUTTON: 01760 wParam = (wParam != 0); 01761 01762 if (fAlterWinIni) { 01763 fWinIniChanged = UpdateWinIniInt(NULL, PMAP_MOUSE, STR_SNAPTO, wParam); 01764 fWriteAllowed = fWinIniChanged; 01765 } 01766 01767 if (fWriteAllowed) { 01768 SET_OR_CLEAR_PUSIF(PUSIF_SNAPTO, wParam); 01769 } 01770 01771 break; 01772 01773 case SPI_GETBORDER: 01774 (*(LPINT)lParam) = gpsi->gclBorder; 01775 break; 01776 01777 case SPI_SETBORDER: 01778 pProfileUserName = CreateProfileUserName(&tlName); 01779 if (fAlterWinIni) { 01780 fWinIniChanged = SetWindowMetricInt(pProfileUserName, STR_BORDERWIDTH, wParam); 01781 fWriteAllowed = fWinIniChanged; 01782 } 01783 if (fWriteAllowed) { 01784 clBorderOld = gpsi->gclBorder; 01785 clBorderNew = wParam; 01786 01787 if (clBorderNew < 1) 01788 clBorderNew = 1; 01789 else if (clBorderNew > 50) 01790 clBorderNew = 50; 01791 01792 if (clBorderOld == clBorderNew) { 01793 01794 /* 01795 * If border size doesn't change, don't waste time. 01796 */ 01797 FreeProfileUserName(pProfileUserName, &tlName); 01798 break; 01799 } 01800 01801 xxxSetAndDrawNCMetrics(pProfileUserName, clBorderNew, NULL); 01802 01803 /* 01804 * Nice magic number of 3. So if the border is set to 1, there are actualy 01805 * 4 pixels in the border 01806 */ 01807 01808 bSetDevDragWidth(gpDispInfo->hDev, gpsi->gclBorder + BORDER_EXTRA); 01809 } 01810 FreeProfileUserName(pProfileUserName, &tlName); 01811 break; 01812 01813 case SPI_GETFONTSMOOTHING: 01814 (*(LPINT)lParam) = !!(GreGetFontEnumeration() & FE_AA_ON); 01815 break; 01816 01817 case SPI_SETFONTSMOOTHING: 01818 wParam = (wParam ? FE_AA_ON : 0); 01819 if (fAlterWinIni) { 01820 fWinIniChanged = UpdateWinIniInt(NULL,PMAP_DESKTOP, STR_FONTSMOOTHING, wParam); 01821 fWriteAllowed = fWinIniChanged; 01822 } 01823 if (fWriteAllowed) { 01824 GreSetFontEnumeration(wParam | FE_SET_AA); 01825 } 01826 break; 01827 01828 case SPI_GETKEYBOARDSPEED: 01829 (*(int *)lParam) = (gnKeyboardSpeed & KSPEED_MASK); 01830 break; 01831 01832 case SPI_SETKEYBOARDSPEED: 01833 /* 01834 * Limit the range to max value; SetKeyboardRate takes both speed and delay 01835 */ 01836 if (wParam > KSPEED_MASK) // KSPEED_MASK == KSPEED_MAX 01837 wParam = KSPEED_MASK; 01838 if (fAlterWinIni) { 01839 fWinIniChanged = UpdateWinIniInt(NULL,PMAP_KEYBOARD, STR_KEYSPEED, wParam); 01840 fWriteAllowed = fWinIniChanged; 01841 } 01842 if (fWriteAllowed) { 01843 gnKeyboardSpeed = (gnKeyboardSpeed & ~KSPEED_MASK) | wParam; 01844 SetKeyboardRate(gnKeyboardSpeed ); 01845 } 01846 break; 01847 01848 case SPI_GETKEYBOARDDELAY: 01849 (*(int *)lParam) = (gnKeyboardSpeed & KDELAY_MASK) >> KDELAY_SHIFT; 01850 break; 01851 01852 case SPI_SETKEYBOARDDELAY: 01853 if (fAlterWinIni) { 01854 fWinIniChanged = UpdateWinIniInt(NULL,PMAP_KEYBOARD, STR_KEYDELAY, wParam); 01855 fWriteAllowed = fWinIniChanged; 01856 } 01857 if (fWriteAllowed) { 01858 gnKeyboardSpeed = (gnKeyboardSpeed & ~KDELAY_MASK) | (wParam << KDELAY_SHIFT); 01859 SetKeyboardRate(gnKeyboardSpeed); 01860 } 01861 break; 01862 01863 case SPI_SETLANGTOGGLE: 01864 01865 /* 01866 * wParam unused, lParam unused. Simply reread the registry setting. 01867 */ 01868 01869 return GetKbdLangSwitch(NULL); 01870 01871 break; 01872 01873 case SPI_GETDEFAULTINPUTLANG: 01874 /* 01875 * wParam unused. lParam is a pointer to buffer to store hkl. 01876 */ 01877 UserAssert(gspklBaseLayout != NULL); 01878 (*(HKL *)lParam) = gspklBaseLayout->hkl; 01879 break; 01880 01881 case SPI_SETDEFAULTINPUTLANG: { 01882 PKL pkl; 01883 /* 01884 * wParam unused. lParam is new language of hkl (depending on whether the 01885 * hiword is set. 01886 */ 01887 pkl = HKLtoPKL(PtiCurrent(), *(HKL *)lParam); 01888 if (pkl == NULL) { 01889 return FALSE; 01890 } 01891 if (fWriteAllowed) { 01892 Lock(&gspklBaseLayout, pkl); 01893 } 01894 break; 01895 } 01896 01897 case SPI_ICONHORIZONTALSPACING: 01898 if (IS_PTR(lParam)) { 01899 *(LPINT)lParam = SYSMET(CXICONSPACING); 01900 } else if (wParam) { 01901 01902 /* 01903 * Make sure icon spacing is reasonable. 01904 */ 01905 wParam = max(wParam, (DWORD)SYSMET(CXICON)); 01906 01907 if (fAlterWinIni) { 01908 fWinIniChanged = SetWindowMetricInt(NULL, STR_ICONHORZSPACING, wParam ); 01909 fWriteAllowed = fWinIniChanged; 01910 } 01911 if (fWriteAllowed) { 01912 SYSMET(CXICONSPACING) = (UINT)wParam; 01913 } 01914 } 01915 break; 01916 01917 case SPI_ICONVERTICALSPACING: 01918 if (IS_PTR(lParam)) { 01919 *(LPINT)lParam = SYSMET(CYICONSPACING); 01920 } else if (wParam) { 01921 wParam = max(wParam, (DWORD)SYSMET(CYICON)); 01922 01923 if (fAlterWinIni) { 01924 fWinIniChanged = SetWindowMetricInt(NULL, STR_ICONVERTSPACING, wParam); 01925 fWriteAllowed = fWinIniChanged; 01926 } 01927 if (fWriteAllowed) { 01928 SYSMET(CYICONSPACING) = (UINT)wParam; 01929 } 01930 } 01931 break; 01932 01933 case SPI_GETSCREENSAVETIMEOUT: 01934 piTimeOut = &giScreenSaveTimeOutMs; 01935 goto HandleGetTimeouts; 01936 01937 case SPI_GETLOWPOWERTIMEOUT: 01938 if (!NT_SUCCESS(DrvGetMonitorPowerState(gpDispInfo->pmdev, PowerDeviceD1))) { 01939 return FALSE; 01940 } 01941 piTimeOut = &giLowPowerTimeOutMs; 01942 goto HandleGetTimeouts; 01943 01944 case SPI_GETPOWEROFFTIMEOUT: 01945 if (!NT_SUCCESS(DrvGetMonitorPowerState(gpDispInfo->pmdev, PowerDeviceD3))) { 01946 return FALSE; 01947 } 01948 piTimeOut = &giPowerOffTimeOutMs; 01949 01950 HandleGetTimeouts: 01951 /* 01952 * If the screen saver is disabled, I store this fact as a negative 01953 * time out value. So, we give the Control Panel the absolute value 01954 * of the screen save time out. We store this in milliseconds. 01955 */ 01956 if (*piTimeOut < 0) 01957 (*(int *)lParam) = -*piTimeOut / 1000; 01958 else 01959 (*(int *)lParam) = *piTimeOut / 1000; 01960 break; 01961 01962 case SPI_SETSCREENSAVETIMEOUT: 01963 piTimeOut = &giScreenSaveTimeOutMs; 01964 iResID = STR_SCREENSAVETIMEOUT; 01965 goto HandleSetTimeouts; 01966 01967 case SPI_SETLOWPOWERTIMEOUT: 01968 if (!NT_SUCCESS(DrvGetMonitorPowerState(gpDispInfo->pmdev, PowerDeviceD1))) { 01969 return FALSE; 01970 } 01971 piTimeOut = &giLowPowerTimeOutMs; 01972 iResID = STR_LOWPOWERTIMEOUT; 01973 goto HandleSetTimeouts; 01974 01975 case SPI_SETPOWEROFFTIMEOUT: 01976 if (!NT_SUCCESS(DrvGetMonitorPowerState(gpDispInfo->pmdev, PowerDeviceD3))) { 01977 return FALSE; 01978 } 01979 piTimeOut = &giPowerOffTimeOutMs; 01980 iResID = STR_POWEROFFTIMEOUT; 01981 01982 HandleSetTimeouts: 01983 /* 01984 * Maintain the screen save active/inactive state when setting the 01985 * time out value. Timeout value is given in seconds but stored 01986 * in milliseconds 01987 */ 01988 if (CheckDesktopPolicy(NULL, (PCWSTR)iResID)) { 01989 fAlterWinIni = FALSE; 01990 fWriteAllowed = FALSE; 01991 } 01992 if (fAlterWinIni) { 01993 fWinIniChanged = UpdateWinIniInt(NULL,PMAP_DESKTOP, iResID, wParam); 01994 fWriteAllowed = fWinIniChanged; 01995 } 01996 if (fWriteAllowed) { 01997 if (glinp.dwFlags & LINP_POWERTIMEOUTS) { 01998 // Call video driver here to exit power down mode. 01999 KdPrint(("Exit video power down mode\n")); 02000 DrvSetMonitorPowerState(gpDispInfo->pmdev, PowerDeviceD0); 02001 } 02002 glinp.dwFlags &= ~LINP_INPUTTIMEOUTS; 02003 glinp.timeLastInputMessage = NtGetTickCount(); 02004 if (*piTimeOut < 0) { 02005 *piTimeOut = -((int)wParam); 02006 } else { 02007 *piTimeOut = wParam; 02008 } 02009 *piTimeOut *= 1000; 02010 } 02011 break; 02012 02013 case SPI_GETSCREENSAVEACTIVE: 02014 (*(BOOL *)lParam) = (giScreenSaveTimeOutMs > 0); 02015 break; 02016 02017 case SPI_GETLOWPOWERACTIVE: 02018 if (!NT_SUCCESS(DrvGetMonitorPowerState(gpDispInfo->pmdev, PowerDeviceD1))) { 02019 return FALSE; 02020 } 02021 (*(BOOL *)lParam) = (giLowPowerTimeOutMs > 0); 02022 break; 02023 02024 case SPI_GETPOWEROFFACTIVE: 02025 if (!NT_SUCCESS(DrvGetMonitorPowerState(gpDispInfo->pmdev, PowerDeviceD3))) { 02026 return FALSE; 02027 } 02028 (*(BOOL *)lParam) = (giPowerOffTimeOutMs > 0); 02029 break; 02030 02031 case SPI_SETSCREENSAVEACTIVE: 02032 piTimeOut = &giScreenSaveTimeOutMs; 02033 iResID = STR_SCREENSAVEACTIVE; 02034 goto HandleSetActive; 02035 02036 case SPI_SETLOWPOWERACTIVE: 02037 if (!NT_SUCCESS(DrvGetMonitorPowerState(gpDispInfo->pmdev, PowerDeviceD1))) { 02038 return FALSE; 02039 } 02040 piTimeOut = &giLowPowerTimeOutMs; 02041 iResID = STR_LOWPOWERACTIVE; 02042 goto HandleSetActive; 02043 02044 case SPI_SETPOWEROFFACTIVE: 02045 if (!NT_SUCCESS(DrvGetMonitorPowerState(gpDispInfo->pmdev, PowerDeviceD3))) { 02046 return FALSE; 02047 } 02048 piTimeOut = &giPowerOffTimeOutMs; 02049 iResID = STR_POWEROFFACTIVE; 02050 02051 HandleSetActive: 02052 wParam = (wParam != 0); 02053 02054 if (CheckDesktopPolicy(NULL, (PCWSTR)iResID)) { 02055 fAlterWinIni = FALSE; 02056 fWriteAllowed = FALSE; 02057 } 02058 if (fAlterWinIni) { 02059 fWinIniChanged = UpdateWinIniInt(NULL,PMAP_DESKTOP, iResID, wParam); 02060 fWriteAllowed = fWinIniChanged; 02061 } 02062 if (fWriteAllowed) { 02063 if (glinp.dwFlags & LINP_POWERTIMEOUTS) { 02064 // Call video driver here to exit power down mode. 02065 KdPrint(("Exit video power down mode\n")); 02066 DrvSetMonitorPowerState(gpDispInfo->pmdev, PowerDeviceD0); 02067 } 02068 glinp.dwFlags &= ~LINP_INPUTTIMEOUTS; 02069 glinp.timeLastInputMessage = NtGetTickCount(); 02070 if ((*piTimeOut < 0 && wParam) || 02071 (*piTimeOut >= 0 && !wParam)) { 02072 *piTimeOut = -*piTimeOut; 02073 } 02074 } 02075 break; 02076 02077 02078 case SPI_SETDESKWALLPAPER: 02079 pProfileUserName = CreateProfileUserName(&tlName); 02080 if (fAlterWinIni) { 02081 02082 if (wParam != (WPARAM)-1) { 02083 02084 /* 02085 * Save current wallpaper in case of failure. 02086 */ 02087 FastGetProfileStringFromIDW(pProfileUserName, 02088 PMAP_DESKTOP, 02089 STR_DTBITMAP, 02090 TEXT(""), 02091 szPat, 02092 sizeof(szPat) / sizeof(WCHAR) 02093 ); 02094 02095 fWinIniChanged = FastUpdateWinIni(pProfileUserName, 02096 PMAP_DESKTOP, 02097 STR_DTBITMAP, 02098 (LPWSTR)lParam 02099 ); 02100 02101 fWriteAllowed = fWinIniChanged; 02102 02103 } else { 02104 fWriteAllowed = TRUE; 02105 } 02106 } 02107 02108 if (fWriteAllowed) { 02109 02110 if (xxxSetDeskWallpaper(pProfileUserName,(LPWSTR)lParam)) { 02111 02112 if (grpdeskRitInput) { 02113 02114 xxxInternalInvalidate(grpdeskRitInput->pDeskInfo->spwnd, 02115 HRGN_FULL, 02116 RDW_INVALIDATE | 02117 RDW_ERASE | 02118 RDW_FRAME | 02119 RDW_ALLCHILDREN); 02120 } 02121 02122 } else if (fAlterWinIni && (wParam != 0xFFFFFFFF)) { 02123 02124 /* 02125 * Backout any change to win.ini. 02126 */ 02127 FastUpdateWinIni(pProfileUserName,PMAP_DESKTOP, STR_DTBITMAP, szPat); 02128 fWinIniChanged = FALSE; 02129 fWriteAllowed = fWinIniChanged; 02130 } else if (!fAlterWinIni) { 02131 /* 02132 * Bug 304109 - joejo 02133 * Make sure we return a 0 retval if we didn't do anything! 02134 */ 02135 fWinIniChanged = FALSE; 02136 fWriteAllowed = fWinIniChanged; 02137 } 02138 } 02139 FreeProfileUserName(pProfileUserName, &tlName); 02140 break; 02141 02142 /* 02143 * Bug 257718 - joejo 02144 * Add SPI_GETDESKWALLPAPER to SystemParametersInfo 02145 */ 02146 case SPI_GETDESKWALLPAPER: 02147 /* 02148 * Bug 283318 - jojeo 02149 * 02150 * Get the string from the gobal var, not the registry, 02151 * as it's more current. 02152 */ 02153 if (gpszWall != NULL) { 02154 /* 02155 * Copy the global wallpaper name ONLY if nun null 02156 */ 02157 wcscpy(lParam, gpszWall); 02158 } else { 02159 /* 02160 * Null out the string so no garbage can corrupt the user's 02161 * buffer. 02162 */ 02163 (*(LPWSTR)lParam) = (WCHAR)0; 02164 } 02165 break; 02166 02167 case SPI_SETDESKPATTERN: { 02168 BOOL fRet; 02169 02170 if (wParam == -1 && lParam != 0) 02171 return FALSE; 02172 02173 pProfileUserName = CreateProfileUserName(&tlName); 02174 if (fAlterWinIni && wParam != -1) { 02175 02176 /* 02177 * Save the current pattern in case of failure. 02178 */ 02179 FastGetProfileStringFromIDW(pProfileUserName, 02180 PMAP_DESKTOP, 02181 STR_DESKPATTERN, 02182 TEXT(""), 02183 szPat, 02184 sizeof(szPat) / sizeof(WCHAR) 02185 ); 02186 02187 fWinIniChanged = FastUpdateWinIni(pProfileUserName, 02188 PMAP_DESKTOP, 02189 STR_DESKPATTERN, 02190 (LPWSTR)lParam 02191 ); 02192 02193 fWriteAllowed = fWinIniChanged; 02194 } 02195 02196 if (fWriteAllowed) { 02197 02198 fRet = xxxSetDeskPattern(pProfileUserName, 02199 wParam == -1 ? (LPWSTR)-1 : (LPWSTR)lParam, 02200 FALSE); 02201 02202 if (!fRet) { 02203 02204 /* 02205 * Back out any change to win.ini 02206 */ 02207 if (fAlterWinIni && wParam != -1) { 02208 02209 FastUpdateWinIni(pProfileUserName, 02210 PMAP_DESKTOP, 02211 STR_DESKPATTERN, 02212 szPat 02213 ); 02214 } 02215 02216 FreeProfileUserName(pProfileUserName, &tlName); 02217 return FALSE; 02218 } 02219 } 02220 } 02221 FreeProfileUserName(pProfileUserName, &tlName); 02222 break; 02223 02224 case SPI_GETICONTITLEWRAP: 02225 *((int *)lParam) = TEST_BOOL_PUDF(PUDF_ICONTITLEWRAP); 02226 break; 02227 02228 case SPI_SETICONTITLEWRAP: 02229 wParam = (wParam != 0); 02230 if (fAlterWinIni) { 02231 fWinIniChanged = SetWindowMetricInt(NULL, STR_ICONTITLEWRAP, wParam); 02232 fWriteAllowed = fWinIniChanged; 02233 } 02234 if (fWriteAllowed) { 02235 SET_OR_CLEAR_PUDF(PUDF_ICONTITLEWRAP, wParam); 02236 xxxMetricsRecalc(CALC_FRAME, 0, 0, 0, 0); 02237 } 02238 break; 02239 02240 case SPI_SETDRAGWIDTH: 02241 if (fAlterWinIni) { 02242 fWinIniChanged = UpdateWinIniInt(NULL, PMAP_DESKTOP, STR_DRAGWIDTH, wParam); 02243 fWriteAllowed = fWinIniChanged; 02244 } 02245 if (fWriteAllowed) { 02246 SYSMET(CXDRAG) = wParam; 02247 } 02248 break; 02249 02250 case SPI_SETDRAGHEIGHT: 02251 if (fAlterWinIni) { 02252 fWinIniChanged = UpdateWinIniInt(NULL, PMAP_DESKTOP, STR_DRAGHEIGHT, wParam); 02253 fWriteAllowed = fWinIniChanged; 02254 } 02255 if (fWriteAllowed) { 02256 SYSMET(CYDRAG) = wParam; 02257 } 02258 break; 02259 02260 case SPI_GETMENUDROPALIGNMENT: 02261 (*(int *)lParam) = (SYSMET(MENUDROPALIGNMENT)); 02262 break; 02263 02264 case SPI_SETMENUDROPALIGNMENT: 02265 if (fAlterWinIni) { 02266 fWinIniChanged = UpdateWinIniInt(NULL, PMAP_WINDOWSU, STR_MENUDROPALIGNMENT, wParam); 02267 fWriteAllowed = fWinIniChanged; 02268 } 02269 if (fWriteAllowed) { 02270 SYSMET(MENUDROPALIGNMENT) = (BOOL)(wParam != 0); 02271 } 02272 break; 02273 02274 case SPI_SETDOUBLECLKWIDTH: 02275 if (fAlterWinIni) { 02276 fWinIniChanged = UpdateWinIniInt(NULL, PMAP_MOUSE, STR_DOUBLECLICKWIDTH, wParam); 02277 fWriteAllowed = fWinIniChanged; 02278 } 02279 if (fWriteAllowed) { 02280 SYSMET(CXDOUBLECLK) = wParam; 02281 } 02282 break; 02283 02284 case SPI_SETDOUBLECLKHEIGHT: 02285 if (fAlterWinIni) { 02286 fWinIniChanged = UpdateWinIniInt(NULL, PMAP_MOUSE, STR_DOUBLECLICKHEIGHT, wParam); 02287 fWriteAllowed = fWinIniChanged; 02288 } 02289 if (fWriteAllowed) { 02290 SYSMET(CYDOUBLECLK) = wParam; 02291 } 02292 break; 02293 02294 case SPI_GETICONTITLELOGFONT: 02295 GreExtGetObjectW(ghIconFont, sizeof(LOGFONTW), lParam); 02296 break; 02297 02298 case SPI_SETICONTITLELOGFONT: 02299 { 02300 if (lParam != NULL) { 02301 if (wParam != sizeof(LOGFONTW)) 02302 return FALSE; 02303 } else if (wParam) { 02304 return FALSE; 02305 } 02306 02307 pProfileUserName = CreateProfileUserName(&tlName); 02308 fWinIniChanged = xxxSetSPIMetrics(pProfileUserName, wFlag, lParam, fAlterWinIni); 02309 FreeProfileUserName(pProfileUserName, &tlName); 02310 if (fAlterWinIni) { 02311 fWriteAllowed = fWinIniChanged; 02312 } 02313 break; 02314 } 02315 02316 case SPI_SETDOUBLECLICKTIME: 02317 if (fAlterWinIni) { 02318 fWinIniChanged = UpdateWinIniInt(NULL,PMAP_MOUSE, STR_DBLCLKSPEED, wParam); 02319 fWriteAllowed = fWinIniChanged; 02320 } 02321 if (fWriteAllowed) { 02322 _SetDoubleClickTime((UINT)wParam); 02323 } 02324 break; 02325 02326 case SPI_GETANIMATION: { 02327 LPANIMATIONINFO lpai = (LPANIMATIONINFO) lParam; 02328 02329 if (lpai == NULL || (wParam != sizeof(ANIMATIONINFO))) 02330 return(FALSE); 02331 02332 lpai->cbSize = sizeof(ANIMATIONINFO); 02333 lpai->iMinAnimate = TEST_BOOL_PUDF(PUDF_ANIMATE); 02334 02335 break; 02336 } 02337 02338 case SPI_GETNONCLIENTMETRICS: { 02339 LPNONCLIENTMETRICS lpnc = (LPNONCLIENTMETRICS) lParam; 02340 if (lpnc == NULL) 02341 return FALSE; 02342 02343 GetWindowNCMetrics(lpnc); 02344 break; 02345 } 02346 02347 case SPI_GETMINIMIZEDMETRICS: { 02348 LPMINIMIZEDMETRICS lpmin = (LPMINIMIZEDMETRICS)lParam; 02349 02350 lpmin->cbSize = sizeof(MINIMIZEDMETRICS); 02351 02352 lpmin->iWidth = SYSMET(CXMINIMIZED) - 2*SYSMET(CXFIXEDFRAME); 02353 lpmin->iHorzGap = SYSMET(CXMINSPACING) - SYSMET(CXMINIMIZED); 02354 lpmin->iVertGap = SYSMET(CYMINSPACING) - SYSMET(CYMINIMIZED); 02355 lpmin->iArrange = SYSMET(ARRANGE); 02356 02357 break; 02358 } 02359 02360 case SPI_GETICONMETRICS: { 02361 LPICONMETRICS lpicon = (LPICONMETRICS)lParam; 02362 02363 lpicon->cbSize = sizeof(ICONMETRICS); 02364 02365 lpicon->iHorzSpacing = SYSMET(CXICONSPACING); 02366 lpicon->iVertSpacing = SYSMET(CYICONSPACING); 02367 lpicon->iTitleWrap = TEST_BOOL_PUDF(PUDF_ICONTITLEWRAP); 02368 GreExtGetObjectW(ghIconFont, sizeof(LOGFONTW), &(lpicon->lfFont)); 02369 02370 break; 02371 } 02372 02373 case SPI_SETANIMATION: 02374 case SPI_SETNONCLIENTMETRICS: 02375 case SPI_SETICONMETRICS: 02376 case SPI_SETMINIMIZEDMETRICS: 02377 { 02378 fWinIniChanged = xxxSetSPIMetrics(NULL, wFlag, lParam, fAlterWinIni); 02379 if (fAlterWinIni) { 02380 fWriteAllowed = fWinIniChanged; 02381 } 02382 ServerLoadString(hModuleWin, STR_METRICS, szSection, ARRAY_SIZE(szSection)); 02383 break; 02384 } 02385 case SPI_SETMOUSEBUTTONSWAP: 02386 if (fAlterWinIni) { 02387 fWinIniChanged = UpdateWinIniInt(NULL, PMAP_MOUSE, STR_SWAPBUTTONS, wParam); 02388 fWriteAllowed = fWinIniChanged; 02389 } 02390 if (fWriteAllowed) { 02391 _SwapMouseButton((wParam != 0)); 02392 } 02393 break; 02394 02395 case SPI_GETFASTTASKSWITCH: 02396 *((PINT)lParam) = TRUE; // do the work so we don't screw anybody 02397 02398 case SPI_SETFASTTASKSWITCH: 02399 RIPMSG0(RIP_WARNING,"SPI_SETFASTTASKSWITCH and SPI_GETFASTTASKSWITCH are obsolete actions."); 02400 break; 02401 02402 case SPI_GETWORKAREA: 02403 CopyRect((LPRECT)lParam, &GetPrimaryMonitor()->rcWork); 02404 break; 02405 02406 case SPI_SETWORKAREA: 02407 { 02408 RECT rcNewWork; 02409 LPRECT lprcNewWork; 02410 PMONITOR pMonitorWork; 02411 02412 lprcNewWork = (LPRECT)lParam; 02413 02414 /* 02415 * Validate Rectangle 02416 */ 02417 if ((lprcNewWork != NULL) && 02418 ((lprcNewWork->right < lprcNewWork->left) || 02419 (lprcNewWork->bottom < lprcNewWork->top))) { 02420 02421 RIPMSG0(RIP_WARNING, "Bad work rectangle passed to SystemParametersInfo(SPI_SETWORKAREA, ...)\n"); 02422 return FALSE; 02423 } 02424 02425 /* 02426 * Figure out which monitor has the working area. 02427 */ 02428 if (!lprcNewWork) { 02429 pMonitorWork = GetPrimaryMonitor(); 02430 lprcNewWork = &pMonitorWork->rcMonitor; 02431 } else { 02432 pMonitorWork = _MonitorFromRect(lprcNewWork, MONITOR_DEFAULTTOPRIMARY); 02433 } 02434 02435 /* 02436 * Get new working area, clipped to monitor of course. 02437 */ 02438 if (!IntersectRect(&rcNewWork, lprcNewWork, &pMonitorWork->rcMonitor) || 02439 !EqualRect(&rcNewWork, lprcNewWork)) 02440 { 02441 /* 02442 * Complain. 02443 */ 02444 RIPERR4( 02445 ERROR_INVALID_PARAMETER, 02446 RIP_WARNING, 02447 "Bad work rectangle passed to SystemParametersInfo(SPI_SETWORKAREA, ...) %d, %d, %d, %d", 02448 lprcNewWork->left, lprcNewWork->top, lprcNewWork->right, lprcNewWork->bottom); 02449 return FALSE; 02450 } 02451 02452 if (!EqualRect(&pMonitorWork->rcWork, &rcNewWork)) 02453 { 02454 PMONITORRECTS pmr; 02455 02456 /* 02457 * If we are going to reposition windows, remember the old 02458 * monitor positions for xxxDesktopRecalc. 02459 */ 02460 if (wParam) { 02461 pmr = SnapshotMonitorRects(); 02462 if (!pmr) { 02463 return FALSE; 02464 } 02465 } 02466 02467 pMonitorWork->rcWork = rcNewWork; 02468 if (pMonitorWork == GetPrimaryMonitor()) { 02469 SetDesktopMetrics(); 02470 } 02471 02472 /* 02473 * Reposition windows 02474 */ 02475 02476 if (wParam) { 02477 02478 TL tlPool; 02479 02480 ThreadLockPool(PtiCurrent(), pmr, &tlPool); 02481 xxxDesktopRecalc(pmr); 02482 ThreadUnlockAndFreePool(PtiCurrent(), &tlPool); 02483 } 02484 02485 fWinIniChanged = TRUE; 02486 } 02487 02488 fWriteAllowed = TRUE; 02489 break; 02490 } 02491 02492 case SPI_SETDRAGFULLWINDOWS: 02493 wParam = (wParam == 1); 02494 if (fAlterWinIni) { 02495 fWinIniChanged = UpdateWinIniInt(NULL, PMAP_DESKTOP, STR_DRAGFULLWINDOWS, wParam); 02496 fWriteAllowed = fWinIniChanged; 02497 } 02498 if (fWriteAllowed) { 02499 SET_OR_CLEAR_PUDF(PUDF_DRAGFULLWINDOWS, wParam); 02500 } 02501 break; 02502 02503 case SPI_GETDRAGFULLWINDOWS: 02504 *((PINT)lParam) = TEST_BOOL_PUDF(PUDF_DRAGFULLWINDOWS); 02505 break; 02506 02507 case SPI_GETFILTERKEYS: 02508 { 02509 LPFILTERKEYS pFK = (LPFILTERKEYS)lParam; 02510 int cbSkip = sizeof(gFilterKeys.cbSize); 02511 02512 if ((wParam != 0) && (wParam != sizeof(FILTERKEYS))) { 02513 return FALSE; 02514 } 02515 if (!pFK || (pFK->cbSize != sizeof(FILTERKEYS))) { 02516 return FALSE; 02517 } 02518 /* 02519 * In the future we may support multiple sizes of this data structure. Don't 02520 * change the cbSize field of the data structure passed in. 02521 */ 02522 RtlCopyMemory((LPVOID)((LPBYTE)pFK + cbSkip), 02523 (LPVOID)((LPBYTE)&gFilterKeys + cbSkip), 02524 pFK->cbSize - cbSkip); 02525 } 02526 break; 02527 02528 case SPI_SETFILTERKEYS: 02529 { 02530 LPFILTERKEYS pFK = (LPFILTERKEYS)lParam; 02531 02532 if ((wParam != 0) && (wParam != sizeof(FILTERKEYS))) { 02533 return FALSE; 02534 } 02535 if (!pFK || (pFK->cbSize != sizeof(FILTERKEYS))) 02536 return FALSE; 02537 02538 /* 02539 * SlowKeys and BounceKeys cannot both be active simultaneously 02540 */ 02541 if (pFK->iWaitMSec && pFK->iBounceMSec) { 02542 return FALSE; 02543 } 02544 02545 /* 02546 * Do some parameter validation. We will fail on unsupported and 02547 * undefined bits being set. 02548 */ 02549 if ((pFK->dwFlags & FKF_VALID) != pFK->dwFlags) { 02550 return FALSE; 02551 } 02552 /* 02553 * FKF_AVAILABLE can't be set via API. Use registry value. 02554 */ 02555 if (TEST_ACCESSFLAG(FilterKeys, FKF_AVAILABLE)) { 02556 pFK->dwFlags |= FKF_AVAILABLE; 02557 } else { 02558 pFK->dwFlags &= ~FKF_AVAILABLE; 02559 } 02560 if ((pFK->iWaitMSec > 2000) || 02561 (pFK->iDelayMSec > 2000) || 02562 (pFK->iRepeatMSec > 2000) || 02563 (pFK->iBounceMSec > 2000)) { 02564 return FALSE; 02565 } 02566 02567 if (fAlterWinIni) { 02568 pProfileUserName = CreateProfileUserName(&tlName); 02569 fWinIniChanged = SetFilterKeys(pProfileUserName, pFK); 02570 fWriteAllowed = fWinIniChanged; 02571 if (!fWinIniChanged) { 02572 02573 /* 02574 * Back out any changes to win.ini 02575 */ 02576 SetFilterKeys(pProfileUserName, &gFilterKeys); 02577 } 02578 FreeProfileUserName(pProfileUserName, &tlName); 02579 } 02580 if (fWriteAllowed) { 02581 RtlCopyMemory(&gFilterKeys, pFK, pFK->cbSize); 02582 02583 /* 02584 * Don't allow user to change cbSize field 02585 */ 02586 gFilterKeys.cbSize = sizeof(FILTERKEYS); 02587 02588 if (!TEST_ACCESSFLAG(FilterKeys, FKF_FILTERKEYSON)) { 02589 StopFilterKeysTimers(); 02590 } 02591 SetAccessEnabledFlag(); 02592 if (FCallHookTray()) 02593 xxxCallHook(HSHELL_ACCESSIBILITYSTATE, 02594 ACCESS_FILTERKEYS, 02595 (LONG)0, 02596 WH_SHELL); 02597 PostShellHookMessages(HSHELL_ACCESSIBILITYSTATE, ACCESS_FILTERKEYS); 02598 } 02599 } 02600 break; 02601 02602 case SPI_GETSTICKYKEYS: 02603 { 02604 LPSTICKYKEYS pSK = (LPSTICKYKEYS)lParam; 02605 int cbSkip = sizeof(gStickyKeys.cbSize); 02606 02607 if ((wParam != 0) && (wParam != sizeof(STICKYKEYS))) { 02608 return FALSE; 02609 } 02610 if (!pSK || (pSK->cbSize != sizeof(STICKYKEYS))) { 02611 return FALSE; 02612 } 02613 /* 02614 * In the future we may support multiple sizes of this data structure. Don't 02615 * change the cbSize field of the data structure passed in. 02616 */ 02617 RtlCopyMemory((LPVOID)((LPBYTE)pSK + cbSkip), 02618 (LPVOID)((LPBYTE)&gStickyKeys + cbSkip), 02619 pSK->cbSize - cbSkip); 02620 02621 pSK->dwFlags &= ~SKF_STATEINFO; 02622 pSK->dwFlags |= (gLatchBits&0xff) <<24; 02623 02624 #if SKF_LALTLATCHED != 0x10000000 02625 #error SKF_LALTLATCHED value is incorrect 02626 #endif 02627 #if SKF_LCTLLATCHED != 0x04000000 02628 #error SKF_LCTLLATCHED value is incorrect 02629 #endif 02630 #if SKF_LSHIFTLATCHED != 0x01000000 02631 #error SKF_LSHIFTLATCHED value is incorrect 02632 #endif 02633 #if SKF_RALTLATCHED != 0x20000000 02634 #error SKF_RALTLATCHED value is incorrect 02635 #endif 02636 #if SKF_RCTLLATCHED != 0x08000000 02637 #error SKF_RCTLLATCHED value is incorrect 02638 #endif 02639 #if SKF_RSHIFTLATCHED != 0x02000000 02640 #error SKF_RSHIFTLATCHED value is incorrect 02641 #endif 02642 pSK->dwFlags |= (gLockBits&0xff) <<16; 02643 #if SKF_LALTLOCKED != 0x00100000 02644 #error SKF_LALTLOCKED value is incorrect 02645 #endif 02646 #if SKF_LCTLLOCKED != 0x00040000 02647 #error SKF_LCTLLOCKED value is incorrect 02648 #endif 02649 #if SKF_LSHIFTLOCKED != 0x00010000 02650 #error SKF_LSHIFTLOCKED value is incorrect 02651 #endif 02652 #if SKF_RALTLOCKED != 0x00200000 02653 #error SKF_RALTLOCKED value is incorrect 02654 #endif 02655 #if SKF_RCTLLOCKED != 0x00080000 02656 #error SKF_RCTLLOCKED value is incorrect 02657 #endif 02658 #if SKF_RSHIFTLOCKED != 0x00020000 02659 #error SKF_RSHIFTLOCKED value is incorrect 02660 #endif 02661 02662 } 02663 02664 break; 02665 02666 case SPI_SETSTICKYKEYS: 02667 { 02668 LPSTICKYKEYS pSK = (LPSTICKYKEYS)lParam; 02669 BOOL fWasOn; 02670 02671 fWasOn = TEST_BOOL_ACCESSFLAG(StickyKeys, SKF_STICKYKEYSON); 02672 if ((wParam != 0) && (wParam != sizeof(STICKYKEYS))) { 02673 return FALSE; 02674 } 02675 if (!pSK || (pSK->cbSize != sizeof(STICKYKEYS))) 02676 return FALSE; 02677 02678 pSK->dwFlags &= ~SKF_STATEINFO; /* Don't penalize them for using 02679 * data from SPI_GETSTICKYKEYS. 02680 */ 02681 02682 /* 02683 * Do some parameter validation. We will fail on unsupported and 02684 * undefined bits being set. 02685 */ 02686 if ((pSK->dwFlags & SKF_VALID) != pSK->dwFlags) { 02687 return FALSE; 02688 } 02689 /* 02690 * SKF_AVAILABLE can't be set via API. Use registry value. 02691 */ 02692 if (TEST_ACCESSFLAG(StickyKeys, SKF_AVAILABLE)) { 02693 pSK->dwFlags |= SKF_AVAILABLE; 02694 } else { 02695 pSK->dwFlags &= ~SKF_AVAILABLE; 02696 } 02697 02698 if (fAlterWinIni) { 02699 swprintf(szTemp, pwszd, pSK->dwFlags); 02700 fWinIniChanged = FastWriteProfileStringW(NULL, 02701 PMAP_STICKYKEYS, 02702 L"Flags", 02703 szTemp 02704 ); 02705 fWriteAllowed = fWinIniChanged; 02706 } 02707 if (fWriteAllowed) { 02708 RtlCopyMemory(&gStickyKeys, pSK, pSK->cbSize); 02709 02710 /* 02711 * Don't allow user to change cbSize field 02712 */ 02713 gStickyKeys.cbSize = sizeof(STICKYKEYS); 02714 if (!TEST_ACCESSFLAG(StickyKeys, SKF_STICKYKEYSON) && fWasOn) { 02715 xxxTurnOffStickyKeys(); 02716 } 02717 02718 SetAccessEnabledFlag(); 02719 if (FCallHookTray()) 02720 xxxCallHook(HSHELL_ACCESSIBILITYSTATE, 02721 ACCESS_STICKYKEYS, 02722 (LONG)0, 02723 WH_SHELL); 02724 PostShellHookMessages(HSHELL_ACCESSIBILITYSTATE, ACCESS_STICKYKEYS); 02725 } 02726 } 02727 break; 02728 02729 case SPI_GETTOGGLEKEYS: 02730 { 02731 LPTOGGLEKEYS pTK = (LPTOGGLEKEYS)lParam; 02732 int cbSkip = sizeof(gToggleKeys.cbSize); 02733 02734 if ((wParam != 0) && (wParam != sizeof(TOGGLEKEYS))) { 02735 return FALSE; 02736 } 02737 if (!pTK || (pTK->cbSize != sizeof(TOGGLEKEYS))) { 02738 return FALSE; 02739 } 02740 /* 02741 * In the future we may support multiple sizes of this data structure. Don't 02742 * change the cbSize field of the data structure passed in. 02743 */ 02744 RtlCopyMemory((LPVOID)((LPBYTE)pTK + cbSkip), 02745 (LPVOID)((LPBYTE)&gToggleKeys + cbSkip), 02746 pTK->cbSize - cbSkip); 02747 } 02748 break; 02749 02750 case SPI_SETTOGGLEKEYS: 02751 { 02752 LPTOGGLEKEYS pTK = (LPTOGGLEKEYS)lParam; 02753 02754 if ((wParam != 0) && (wParam != sizeof(TOGGLEKEYS))) { 02755 return FALSE; 02756 } 02757 if (!pTK || (pTK->cbSize != sizeof(TOGGLEKEYS))) 02758 return FALSE; 02759 02760 /* 02761 * Do some parameter validation. We will fail on unsupported and 02762 * undefined bits being set. 02763 */ 02764 if ((pTK->dwFlags & TKF_VALID) != pTK->dwFlags) { 02765 return FALSE; 02766 } 02767 /* 02768 * TKF_AVAILABLE can't be set via API. Use registry value. 02769 */ 02770 if (TEST_ACCESSFLAG(ToggleKeys, TKF_AVAILABLE)) { 02771 pTK->dwFlags |= TKF_AVAILABLE; 02772 } else { 02773 pTK->dwFlags &= ~TKF_AVAILABLE; 02774 } 02775 02776 if (fAlterWinIni) { 02777 swprintf(szTemp, pwszd, pTK->dwFlags); 02778 fWinIniChanged = FastWriteProfileStringW(NULL, 02779 PMAP_TOGGLEKEYS, 02780 L"Flags", 02781 szTemp 02782 ); 02783 fWriteAllowed = fWinIniChanged; 02784 } 02785 if (fWriteAllowed) { 02786 RtlCopyMemory(&gToggleKeys, pTK, pTK->cbSize); 02787 02788 /* 02789 * Don't allow user to change cbSize field 02790 */ 02791 gToggleKeys.cbSize = sizeof(TOGGLEKEYS); 02792 02793 SetAccessEnabledFlag(); 02794 } 02795 } 02796 break; 02797 02798 case SPI_GETMOUSEKEYS: 02799 { 02800 LPMOUSEKEYS pMK = (LPMOUSEKEYS)lParam; 02801 int cbSkip = sizeof(gMouseKeys.cbSize); 02802 02803 if ((wParam != 0) && (wParam != sizeof(MOUSEKEYS))) { 02804 return FALSE; 02805 } 02806 if (!pMK || (pMK->cbSize != sizeof(MOUSEKEYS))) { 02807 return FALSE; 02808 } 02809 /* 02810 * In the future we may support multiple sizes of this data structure. Don't 02811 * change the cbSize field of the data structure passed in. 02812 */ 02813 RtlCopyMemory((LPVOID)((LPBYTE)pMK + cbSkip), 02814 (LPVOID)((LPBYTE)&gMouseKeys + cbSkip), 02815 pMK->cbSize - cbSkip); 02816 02817 02818 pMK->dwFlags &= ~MKF_STATEINFO; 02819 02820 if (gbMKMouseMode) pMK->dwFlags |= MKF_MOUSEMODE; 02821 02822 pMK->dwFlags |= (gwMKButtonState & 3) << 24; 02823 #if MOUSE_BUTTON_LEFT != 0x01 02824 #error MOUSE_BUTTON_LEFT value is incorrect 02825 #endif 02826 #if MOUSE_BUTTON_RIGHT != 0x02 02827 #error MOUSE_BUTTON_RIGHT value is incorrect 02828 #endif 02829 #if MKF_LEFTBUTTONDOWN != 0x01000000 02830 #error MKF_LEFTBUTTONDOWN value is incorrect 02831 #endif 02832 #if MKF_RIGHTBUTTONDOWN != 0x02000000 02833 #error MKF_RIGHTBUTTONDOWN value is incorrect 02834 #endif 02835 02836 pMK->dwFlags |= (gwMKCurrentButton & 3)<< 28; 02837 #if MKF_LEFTBUTTONSEL != 0x10000000 02838 #error MKF_LEFTBUTTONSEL value is incorrect 02839 #endif 02840 #if MKF_RIGHTBUTTONSEL != 0x20000000 02841 #error MKF_RIGHTBUTTONSEL value is incorrect 02842 #endif 02843 } 02844 break; 02845 02846 case SPI_SETMOUSEKEYS: { 02847 LPMOUSEKEYS pMK = (LPMOUSEKEYS)lParam; 02848 02849 if ((wParam != 0) && (wParam != sizeof(MOUSEKEYS))) { 02850 return FALSE; 02851 } 02852 if (!pMK || (pMK->cbSize != sizeof(MOUSEKEYS))) 02853 return FALSE; 02854 02855 /* 02856 * Do some parameter validation. We will fail on unsupported and 02857 * undefined bits being set. 02858 */ 02859 pMK->dwFlags &= ~MKF_STATEINFO; /* Don't penalize them for using 02860 * data from SPI_GETMOUSEKEYS. 02861 */ 02862 02863 if ((pMK->dwFlags & MKF_VALID) != pMK->dwFlags) { 02864 return FALSE; 02865 } 02866 /* 02867 * MKF_AVAILABLE can't be set via API. Use registry value. 02868 */ 02869 if (TEST_ACCESSFLAG(MouseKeys, MKF_AVAILABLE)) { 02870 pMK->dwFlags |= MKF_AVAILABLE; 02871 } else { 02872 pMK->dwFlags &= ~MKF_AVAILABLE; 02873 } 02874 if ((pMK->iMaxSpeed < 10) || (pMK->iMaxSpeed > 360)) { 02875 return FALSE; 02876 } 02877 if ((pMK->iTimeToMaxSpeed < 1000) || (pMK->iTimeToMaxSpeed > 5000)) { 02878 return FALSE; 02879 } 02880 02881 if (fAlterWinIni) { 02882 pProfileUserName = CreateProfileUserName(&tlName); 02883 fWinIniChanged = SetMouseKeys(pProfileUserName, pMK); 02884 fWriteAllowed = fWinIniChanged; 02885 if (!fWinIniChanged) { 02886 02887 /* 02888 * Back out any changes to win.ini 02889 */ 02890 SetMouseKeys(pProfileUserName, &gMouseKeys); 02891 } 02892 FreeProfileUserName(pProfileUserName, &tlName); 02893 } 02894 if (fWriteAllowed) { 02895 RtlCopyMemory(&gMouseKeys, pMK, pMK->cbSize); 02896 02897 /* 02898 * Don't allow user to change cbSize field 02899 */ 02900 gMouseKeys.cbSize = sizeof(MOUSEKEYS); 02901 02902 CalculateMouseTable(); 02903 02904 if (TEST_ACCESSFLAG(MouseKeys, MKF_MOUSEKEYSON)) { 02905 if ((TestAsyncKeyStateToggle(gNumLockVk) != 0) ^ 02906 (TEST_ACCESSFLAG(MouseKeys, MKF_REPLACENUMBERS) != 0)) 02907 gbMKMouseMode = TRUE; 02908 else 02909 gbMKMouseMode = FALSE; 02910 MKShowMouseCursor(); 02911 } else { 02912 MKHideMouseCursor(); 02913 } 02914 02915 SetAccessEnabledFlag(); 02916 02917 if (FCallHookTray()) 02918 xxxCallHook(HSHELL_ACCESSIBILITYSTATE, 02919 ACCESS_MOUSEKEYS, 02920 (LONG)0, 02921 WH_SHELL); 02922 PostShellHookMessages(HSHELL_ACCESSIBILITYSTATE, ACCESS_MOUSEKEYS); 02923 } 02924 } 02925 break; 02926 02927 case SPI_GETHIGHCONTRAST: 02928 { 02929 LPHIGHCONTRAST pHC = (LPHIGHCONTRAST)lParam; 02930 02931 /* 02932 * In the future we may support multiple sizes of this data structure. Don't 02933 * change the cbSize field of the data structure passed in. 02934 */ 02935 02936 pHC->dwFlags = gHighContrast.dwFlags; 02937 02938 /* 02939 * A hostile app could deallocate the memory using a second thread, 02940 * so shelter the copy with a try. 02941 */ 02942 try { 02943 RtlCopyMemory(pHC->lpszDefaultScheme, gHighContrastDefaultScheme, MAX_SCHEME_NAME_SIZE * sizeof(WCHAR)); 02944 } except (W32ExceptionHandler(FALSE, RIP_WARNING)) { 02945 } 02946 } 02947 02948 break; 02949 02950 case SPI_SETHIGHCONTRAST: 02951 { 02952 LPINTERNALSETHIGHCONTRAST pHC = (LPINTERNALSETHIGHCONTRAST)lParam; 02953 WCHAR wcDefaultScheme[MAX_SCHEME_NAME_SIZE]; 02954 02955 if (pHC->usDefaultScheme.Length >= MAX_SCHEME_NAME_SIZE*sizeof(WCHAR) ) 02956 return FALSE; 02957 02958 if (pHC->usDefaultScheme.Buffer) { 02959 /* 02960 * Only set the scheme if the user specifies a scheme. An empty 02961 * buffer is ignored. We do the copy here so that we don't need to 02962 * put a try/except around the WriteProfileString code. 02963 */ 02964 02965 try { 02966 RtlCopyMemory(wcDefaultScheme, pHC->usDefaultScheme.Buffer, pHC->usDefaultScheme.Length); 02967 } except (W32ExceptionHandler(TRUE, RIP_WARNING)) { 02968 return FALSE; 02969 } 02970 } 02971 wcDefaultScheme[pHC->usDefaultScheme.Length / sizeof(WCHAR)] = 0; 02972 02973 if (fAlterWinIni) { 02974 pProfileUserName = CreateProfileUserName(&tlName); 02975 swprintf(szTemp, pwszd, pHC->dwFlags); 02976 fWinIniChanged = FastWriteProfileStringW(pProfileUserName, 02977 PMAP_HIGHCONTRAST, 02978 L"Flags", 02979 szTemp 02980 ); 02981 02982 fWriteAllowed = fWinIniChanged; 02983 /* 02984 * Note -- we do not write anything if there is no default scheme 02985 * from the app. This is consistent with Win95/Win98 behavior. 02986 */ 02987 02988 if (pHC->usDefaultScheme.Buffer) { 02989 fWinIniChanged |= FastWriteProfileStringW(pProfileUserName, 02990 PMAP_HIGHCONTRAST, 02991 TEXT("High Contrast Scheme"), 02992 wcDefaultScheme 02993 ); 02994 } 02995 FreeProfileUserName(pProfileUserName, &tlName); 02996 02997 } 02998 if (fWriteAllowed) { 02999 DWORD dwFlagsOld = gHighContrast.dwFlags; 03000 LPARAM lp = fAlterWinIni?0:ACCESS_HIGHCONTRASTNOREG; 03001 03002 #if (ACCESS_HIGHCONTRASTNOREG | ACCESS_HIGHCONTRASTOFF) != ACCESS_HIGHCONTRASTOFFNOREG 03003 #error ACCESS_HIGHCONTRASTOFF value is incorrect 03004 #endif 03005 #if (ACCESS_HIGHCONTRASTNOREG | ACCESS_HIGHCONTRASTON) != ACCESS_HIGHCONTRASTONNOREG 03006 #error ACCESS_HIGHCONTRASTON value is incorrect 03007 #endif 03008 #if (ACCESS_HIGHCONTRASTNOREG | ACCESS_HIGHCONTRASTCHANGE) != ACCESS_HIGHCONTRASTCHANGENOREG 03009 #error ACCESS_HIGHCONTRASTCHANGE value is incorrect 03010 #endif 03011 03012 /* 03013 * If a NULL is specified in the lpszDefaultScheme, then it is 03014 * not changed. This is consistent with Win95/Win98 behavior. 03015 */ 03016 03017 if (pHC->usDefaultScheme.Buffer) 03018 wcscpy(gHighContrastDefaultScheme, wcDefaultScheme); 03019 03020 gHighContrast.dwFlags = pHC->dwFlags; 03021 03022 /* 03023 * now, post message to turn high contrast on or off 03024 */ 03025 03026 if (pHC->dwFlags & HCF_HIGHCONTRASTON) { 03027 _PostMessage(gspwndLogonNotify, WM_LOGONNOTIFY, LOGON_ACCESSNOTIFY, 03028 (dwFlagsOld & HCF_HIGHCONTRASTON)? (ACCESS_HIGHCONTRASTCHANGE | lp): 03029 (ACCESS_HIGHCONTRASTON | lp)); 03030 } else { 03031 _PostMessage(gspwndLogonNotify, WM_LOGONNOTIFY, LOGON_ACCESSNOTIFY, ACCESS_HIGHCONTRASTOFF | lp); 03032 } 03033 03034 } 03035 break; 03036 } 03037 03038 case SPI_GETACCESSTIMEOUT: 03039 { 03040 LPACCESSTIMEOUT pTO = (LPACCESSTIMEOUT)lParam; 03041 int cbSkip = sizeof(gAccessTimeOut.cbSize); 03042 03043 if ((wParam != 0) && (wParam != sizeof(ACCESSTIMEOUT))) { 03044 return FALSE; 03045 } 03046 if (!pTO || (pTO->cbSize != sizeof(ACCESSTIMEOUT))) { 03047 return FALSE; 03048 } 03049 /* 03050 * In the future we may support multiple sizes of this data structure. Don't 03051 * change the cbSize field of the data structure passed in. 03052 */ 03053 RtlCopyMemory((LPVOID)((LPBYTE)pTO + cbSkip), 03054 (LPVOID)((LPBYTE)&gAccessTimeOut + cbSkip), 03055 pTO->cbSize - cbSkip); 03056 } 03057 break; 03058 03059 case SPI_SETACCESSTIMEOUT: 03060 { 03061 LPACCESSTIMEOUT pTO = (LPACCESSTIMEOUT)lParam; 03062 03063 if ((wParam != 0) && (wParam != sizeof(ACCESSTIMEOUT))) { 03064 return FALSE; 03065 } 03066 if (!pTO || (pTO->cbSize != sizeof(ACCESSTIMEOUT))) 03067 return FALSE; 03068 03069 /* 03070 * Do some parameter validation. We will fail on unsupported and 03071 * undefined bits being set. 03072 */ 03073 if ((pTO->dwFlags & ATF_VALID) != pTO->dwFlags) { 03074 return FALSE; 03075 } 03076 if (pTO->iTimeOutMSec > 3600000) { 03077 return FALSE; 03078 } 03079 03080 if (fAlterWinIni) { 03081 pProfileUserName = CreateProfileUserName(&tlName); 03082 swprintf(szTemp, pwszd, pTO->dwFlags); 03083 fWinIniChanged = FastWriteProfileStringW(pProfileUserName, 03084 PMAP_TIMEOUT, 03085 L"Flags", 03086 szTemp 03087 ); 03088 03089 swprintf(szTemp, pwszd, pTO->iTimeOutMSec); 03090 fWinIniChanged = FastWriteProfileStringW(pProfileUserName, 03091 PMAP_TIMEOUT, 03092 L"TimeToWait", 03093 szTemp 03094 ); 03095 03096 fWriteAllowed = fWinIniChanged; 03097 if (!fWinIniChanged) { 03098 03099 /* 03100 * Back out any changes to win.ini 03101 */ 03102 swprintf(szTemp, pwszd, gAccessTimeOut.dwFlags); 03103 fWinIniChanged = FastWriteProfileStringW(pProfileUserName, 03104 PMAP_TIMEOUT, 03105 L"Flags", 03106 szTemp 03107 ); 03108 03109 swprintf(szTemp, pwszd, gAccessTimeOut.iTimeOutMSec); 03110 fWinIniChanged = FastWriteProfileStringW(pProfileUserName, 03111 PMAP_TIMEOUT, 03112 L"TimeToWait", 03113 szTemp 03114 ); 03115 } 03116 FreeProfileUserName(pProfileUserName, &tlName); 03117 } 03118 if (fWriteAllowed) { 03119 RtlCopyMemory(&gAccessTimeOut, pTO, pTO->cbSize); 03120 03121 /* 03122 * Don't allow user to change cbSize field 03123 */ 03124 gAccessTimeOut.cbSize = sizeof(ACCESSTIMEOUT); 03125 03126 SetAccessEnabledFlag(); 03127 03128 AccessTimeOutReset(); 03129 } 03130 } 03131 break; 03132 03133 case SPI_SETSHOWSOUNDS: 03134 if (fAlterWinIni) { 03135 swprintf(szTemp, pwszd, (wParam == 1)); 03136 fWinIniChanged = FastWriteProfileStringW(NULL, 03137 PMAP_SHOWSOUNDS, 03138 L"On", 03139 szTemp 03140 ); 03141 03142 fWriteAllowed = fWinIniChanged; 03143 } 03144 if (fWriteAllowed) { 03145 SET_OR_CLEAR_ACCF(ACCF_SHOWSOUNDSON, wParam == 1); 03146 SetAccessEnabledFlag(); 03147 03148 /* 03149 * Bug 2079. Update the System Metrics Info. 03150 */ 03151 SYSMET(SHOWSOUNDS) = TEST_BOOL_ACCF(ACCF_SHOWSOUNDSON); 03152 } 03153 break; 03154 03155 case SPI_GETSHOWSOUNDS: { 03156 PINT pint = (int *)lParam; 03157 03158 *pint = TEST_BOOL_ACCF(ACCF_SHOWSOUNDSON); 03159 } 03160 break; 03161 03162 case SPI_GETKEYBOARDPREF: 03163 { 03164 PBOOL pfKeyboardPref = (PBOOL)lParam; 03165 03166 *pfKeyboardPref = TEST_BOOL_ACCF(ACCF_KEYBOARDPREF); 03167 } 03168 break; 03169 03170 case SPI_SETKEYBOARDPREF: 03171 { 03172 BOOL fKeyboardPref = (BOOL)wParam; 03173 03174 if (fAlterWinIni) { 03175 fWinIniChanged = FastWriteProfileStringW(NULL, 03176 PMAP_KEYBOARDPREF, 03177 L"On", 03178 (fKeyboardPref) ? L"1" : L"0" 03179 ); 03180 03181 fWriteAllowed = fWinIniChanged; 03182 } 03183 if (fWriteAllowed) 03184 { 03185 SET_OR_CLEAR_ACCF(ACCF_KEYBOARDPREF, wParam); 03186 } 03187 } 03188 break; 03189 03190 case SPI_GETSCREENREADER: 03191 { 03192 PBOOL pfScreenReader = (PBOOL)lParam; 03193 03194 *pfScreenReader = TEST_BOOL_ACCF(ACCF_SCREENREADER); 03195 } 03196 break; 03197 03198 case SPI_SETSCREENREADER: 03199 { 03200 BOOL fScreenReader = (BOOL)wParam; 03201 03202 if (fAlterWinIni) { 03203 fWinIniChanged = FastWriteProfileStringW(NULL, 03204 PMAP_SCREENREADER, 03205 L"On", 03206 (fScreenReader) ? L"1" : L"0" 03207 ); 03208 fWriteAllowed = fWinIniChanged; 03209 } 03210 if (fWriteAllowed) 03211 { 03212 SET_OR_CLEAR_ACCF(ACCF_SCREENREADER, wParam); 03213 } 03214 } 03215 break; 03216 03217 case SPI_GETSOUNDSENTRY: 03218 { 03219 LPSOUNDSENTRY pSS = (LPSOUNDSENTRY)lParam; 03220 int cbSkip = sizeof(gSoundSentry.cbSize); 03221 03222 if ((wParam != 0) && (wParam != sizeof(SOUNDSENTRY))) { 03223 return FALSE; 03224 } 03225 if (!pSS || (pSS->cbSize != sizeof(SOUNDSENTRY))) { 03226 return FALSE; 03227 } 03228 /* 03229 * In the future we may support multiple sizes of this data structure. Don't 03230 * change the cbSize field of the data structure passed in. 03231 */ 03232 RtlCopyMemory((LPVOID)((LPBYTE)pSS + cbSkip), 03233 (LPVOID)((LPBYTE)&gSoundSentry + cbSkip), 03234 pSS->cbSize - cbSkip); 03235 } 03236 break; 03237 03238 case SPI_SETSOUNDSENTRY: 03239 { 03240 LPSOUNDSENTRY pSS = (LPSOUNDSENTRY)lParam; 03241 03242 if ((wParam != 0) && (wParam != sizeof(SOUNDSENTRY))) { 03243 return FALSE; 03244 } 03245 if (!pSS || (pSS->cbSize != sizeof(SOUNDSENTRY))) 03246 return FALSE; 03247 03248 /* 03249 * Do some parameter validation. We will fail on unsupported and 03250 * undefined bits being set. 03251 */ 03252 if ((pSS->dwFlags & SSF_VALID) != pSS->dwFlags) { 03253 return FALSE; 03254 } 03255 /* 03256 * We don't support SSWF_CUSTOM. 03257 */ 03258 if (pSS->iWindowsEffect > SSWF_DISPLAY) { 03259 return FALSE; 03260 } 03261 /* 03262 * No support for non-windows apps. 03263 */ 03264 if (pSS->iFSTextEffect != SSTF_NONE) { 03265 return FALSE; 03266 } 03267 if (pSS->iFSGrafEffect != SSGF_NONE) { 03268 return FALSE; 03269 } 03270 /* 03271 * SSF_AVAILABLE can't be set via API. Use registry value. 03272 */ 03273 if (TEST_ACCESSFLAG(SoundSentry, SSF_AVAILABLE)) { 03274 pSS->dwFlags |= SSF_AVAILABLE; 03275 } else { 03276 pSS->dwFlags &= ~SSF_AVAILABLE; 03277 } 03278 03279 if (fAlterWinIni) { 03280 pProfileUserName = CreateProfileUserName(&tlName); 03281 fWinIniChanged = SetSoundSentry(pProfileUserName, pSS); 03282 fWriteAllowed = fWinIniChanged; 03283 if (!fWinIniChanged) { 03284 03285 /* 03286 * Back out any changes to win.ini 03287 */ 03288 SetSoundSentry(pProfileUserName, &gSoundSentry); 03289 } 03290 FreeProfileUserName(pProfileUserName, &tlName); 03291 } 03292 if (fWriteAllowed) { 03293 RtlCopyMemory(&gSoundSentry, pSS, pSS->cbSize); 03294 03295 /* 03296 * Don't allow user to change cbSize field 03297 */ 03298 gSoundSentry.cbSize = sizeof(SOUNDSENTRY); 03299 03300 SetAccessEnabledFlag(); 03301 } 03302 } 03303 break; 03304 03305 case SPI_SETCURSORS: 03306 pProfileUserName = CreateProfileUserName(&tlName); 03307 xxxUpdateSystemCursorsFromRegistry(pProfileUserName); 03308 FreeProfileUserName(pProfileUserName, &tlName); 03309 03310 break; 03311 03312 case SPI_SETICONS: 03313 pProfileUserName = CreateProfileUserName(&tlName); 03314 xxxUpdateSystemIconsFromRegistry(pProfileUserName); 03315 FreeProfileUserName(pProfileUserName, &tlName); 03316 03317 break; 03318 03319 case SPI_GETMOUSEHOVERWIDTH: 03320 *((UINT *)lParam) = gcxMouseHover; 03321 break; 03322 03323 case SPI_SETMOUSEHOVERWIDTH: 03324 if (fAlterWinIni) { 03325 fWinIniChanged = UpdateWinIniInt(NULL, PMAP_MOUSE, STR_MOUSEHOVERWIDTH, wParam); 03326 fWriteAllowed = fWinIniChanged; 03327 } 03328 if (fWriteAllowed) { 03329 gcxMouseHover = wParam; 03330 } 03331 break; 03332 03333 case SPI_GETMOUSEHOVERHEIGHT: 03334 *((UINT *)lParam) = gcyMouseHover; 03335 break; 03336 03337 case SPI_SETMOUSEHOVERHEIGHT: 03338 if (fAlterWinIni) { 03339 fWinIniChanged = UpdateWinIniInt(NULL, PMAP_MOUSE, STR_MOUSEHOVERHEIGHT, wParam); 03340 fWriteAllowed = fWinIniChanged; 03341 } 03342 if (fWriteAllowed) { 03343 gcyMouseHover = wParam; 03344 } 03345 break; 03346 03347 case SPI_GETMOUSEHOVERTIME: 03348 *((UINT *)lParam) = gdtMouseHover; 03349 break; 03350 03351 case SPI_SETMOUSEHOVERTIME: 03352 if (fAlterWinIni) { 03353 fWinIniChanged = UpdateWinIniInt(NULL, PMAP_MOUSE, STR_MOUSEHOVERTIME, wParam); 03354 fWriteAllowed = fWinIniChanged; 03355 } 03356 if (fWriteAllowed) { 03357 gdtMouseHover = wParam; 03358 } 03359 break; 03360 03361 case SPI_GETWHEELSCROLLLINES: 03362 (*(LPDWORD)lParam) = gpsi->ucWheelScrollLines; 03363 break; 03364 03365 case SPI_SETWHEELSCROLLLINES: 03366 if (fAlterWinIni) { 03367 fWinIniChanged = UpdateWinIniInt(NULL, PMAP_DESKTOP, STR_WHEELSCROLLLINES, wParam); 03368 fWriteAllowed = fWinIniChanged; 03369 } 03370 03371 if (fWriteAllowed) 03372 gpsi->ucWheelScrollLines = (UINT)wParam; 03373 break; 03374 03375 case SPI_GETMENUSHOWDELAY: 03376 (*(LPDWORD)lParam) = gdtMNDropDown; 03377 break; 03378 03379 case SPI_SETMENUSHOWDELAY: 03380 if (fAlterWinIni) { 03381 fWinIniChanged = UpdateWinIniInt(NULL, PMAP_DESKTOP, STR_MENUSHOWDELAY, wParam); 03382 fWriteAllowed = fWinIniChanged; 03383 } 03384 if (fWriteAllowed) 03385 gdtMNDropDown = wParam; 03386 break; 03387 03388 case SPI_GETSCREENSAVERRUNNING: 03389 (*(LPBOOL)lParam) = gppiScreenSaver != NULL; 03390 break; 03391 03392 case SPI_SETSHOWIMEUI: 03393 return xxxSetIMEShowStatus(!!wParam); 03394 03395 case SPI_GETSHOWIMEUI: 03396 (*(LPBOOL)lParam) = _GetIMEShowStatus(); 03397 break; 03398 03399 default: 03400 03401 #define ppvi (UPDWORDPointer(wFlag)) 03402 #define uDataRead ((UINT)fWinIniChanged) 03403 03404 if (wFlag < SPI_MAX) { 03405 RIPERR1(ERROR_INVALID_SPI_VALUE, RIP_WARNING, "xxxSystemParamtersInfo: Invalid SPI_:%#lx", wFlag); 03406 return FALSE; 03407 } 03408 03409 UserAssert(wFlag & SPIF_RANGETYPEMASK); 03410 03411 if (!(wFlag & SPIF_SET)) { 03412 03413 if ((wFlag & SPIF_RANGETYPEMASK) == SPIF_BOOL) { 03414 BOOL fDisable, fDisableValue; 03415 03416 UserAssert(UPIsBOOLRange(wFlag)); 03417 /* 03418 * Handle settings that can be disabled by additional conditions. 03419 */ 03420 fDisable = fDisableValue = FALSE; 03421 if (wFlag < SPI_GETUIEFFECTS) { 03422 if (!TestUP(UIEFFECTS)) { 03423 switch (wFlag) { 03424 case SPI_GETACTIVEWNDTRKZORDER: 03425 case SPI_GETACTIVEWINDOWTRACKING: 03426 break; 03427 03428 case SPI_GETKEYBOARDCUES: 03429 fDisableValue = TRUE; 03430 /* Fall Through */ 03431 03432 default: 03433 fDisable = TRUE; 03434 break; 03435 } 03436 } else { /* if (!TestUP(UIEFFECTS) */ 03437 switch (wFlag) { 03438 case SPI_GETKEYBOARDCUES: 03439 if (TEST_BOOL_ACCF(ACCF_KEYBOARDPREF)) { 03440 fDisableValue = TRUE; 03441 fDisable = TRUE; 03442 } 03443 break; 03444 03445 case SPI_GETGRADIENTCAPTIONS: 03446 case SPI_GETSELECTIONFADE: 03447 case SPI_GETMENUFADE: 03448 case SPI_GETTOOLTIPFADE: 03449 case SPI_GETCURSORSHADOW: 03450 if (gbDisableAlpha) { 03451 fDisable = TRUE; 03452 } 03453 break; 03454 } 03455 } 03456 } /* if (wFlag < SPI_GETUIEFFECTS) */ 03457 /* 03458 * Give them the disabled value or read the actual one 03459 */ 03460 if (fDisable) { 03461 *((BOOL *)lParam) = fDisableValue; 03462 } else { 03463 *((BOOL *)lParam) = !!TestUPBOOL(gpdwCPUserPreferencesMask, wFlag); 03464 } 03465 } else { 03466 UserAssert(UPIsDWORDRange(wFlag)); 03467 *((DWORD *)lParam) = UPDWORDValue(wFlag); 03468 } 03469 03470 } else { /* if (!(wFlag & SPIF_SET)) */ 03471 pProfileUserName = CreateProfileUserName(&tlName); 03472 03473 if ((wFlag & SPIF_RANGETYPEMASK) == SPIF_BOOL) { 03474 DWORD pdwValue [SPI_BOOLMASKDWORDSIZE]; 03475 03476 UserAssert(UPIsBOOLRange(wFlag)); 03477 UserAssert(sizeof(pdwValue) == sizeof(gpdwCPUserPreferencesMask)); 03478 03479 if (fAlterWinIni) { 03480 /* 03481 * We only need to set/clear the bit passed in, however, we write the whole 03482 * bit mask to the registry. Since the info in gpdwCPUserPreferencesMask 03483 * might not match what it is in the registry, we need to read the registry before 03484 * we write to it. 03485 */ 03486 uDataRead = FastGetProfileValue(pProfileUserName, 03487 gpviCPUserPreferences->uSection, 03488 gpviCPUserPreferences->pwszKeyName, 03489 NULL, 03490 (LPBYTE)pdwValue, 03491 sizeof(pdwValue) 03492 ); 03493 03494 /* 03495 * If some bits are not in the registry, get them from gpdwCPUserPreferencesMask 03496 */ 03497 UserAssert(uDataRead <= sizeof(gpdwCPUserPreferencesMask)); 03498 RtlCopyMemory(pdwValue + uDataRead, 03499 gpdwCPUserPreferencesMask + uDataRead, 03500 sizeof(gpdwCPUserPreferencesMask) - uDataRead); 03501 03502 /* 03503 * Set/Clear the new state and write it 03504 */ 03505 if (lParam) { 03506 SetUPBOOL(pdwValue, wFlag); 03507 } else { 03508 ClearUPBOOL(pdwValue, wFlag); 03509 } 03510 03511 fWinIniChanged = FastWriteProfileValue(pProfileUserName, 03512 gpviCPUserPreferences->uSection, 03513 gpviCPUserPreferences->pwszKeyName, 03514 REG_BINARY, 03515 (LPBYTE)pdwValue, 03516 sizeof(pdwValue) 03517 ); 03518 03519 fWriteAllowed = fWinIniChanged; 03520 } 03521 03522 if (fWriteAllowed) { 03523 if (lParam) { 03524 SetUPBOOL(gpdwCPUserPreferencesMask, wFlag); 03525 } else { 03526 ClearUPBOOL(gpdwCPUserPreferencesMask, wFlag); 03527 } 03528 03529 /* 03530 * Propagate gpsi flags 03531 */ 03532 switch (wFlag) { 03533 case SPI_SETUIEFFECTS: 03534 PropagetUPBOOLTogpsi(UIEFFECTS); 03535 SetPointer(TRUE); 03536 /* 03537 * Fall through 03538 */ 03539 03540 case SPI_SETGRADIENTCAPTIONS: 03541 CreateBitmapStrip(); 03542 xxxRedrawScreen(); 03543 break; 03544 03545 case SPI_SETCOMBOBOXANIMATION: 03546 PropagetUPBOOLTogpsi(COMBOBOXANIMATION); 03547 break; 03548 03549 case SPI_SETLISTBOXSMOOTHSCROLLING: 03550 PropagetUPBOOLTogpsi(LISTBOXSMOOTHSCROLLING); 03551 break; 03552 03553 case SPI_SETKEYBOARDCUES: 03554 PropagetUPBOOLTogpsi(KEYBOARDCUES); 03555 break; 03556 03557 case SPI_SETCURSORSHADOW: 03558 SetPointer(TRUE); 03559 break; 03560 03561 } /* switch (wFlag) */ 03562 03563 } /* if (fWriteAllowed) */ 03564 03565 } else { /* if ((wFlag & SPIF_RANGETYPEMASK) == SPIF_BOOL) */ 03566 03567 UserAssert(UPIsDWORDRange(wFlag)); 03568 03569 if (fAlterWinIni) { 03570 fWinIniChanged = FastWriteProfileValue(pProfileUserName, 03571 ppvi->uSection, 03572 ppvi->pwszKeyName, 03573 REG_DWORD, 03574 (LPBYTE)&lParam, 03575 sizeof(DWORD) 03576 ); 03577 03578 fWriteAllowed = fWinIniChanged; 03579 } 03580 03581 if (fWriteAllowed) { 03582 03583 ppvi->dwValue = PtrToUlong(lParam); 03584 03585 switch(wFlag) { 03586 case SPI_SETCARETWIDTH: 03587 gpsi->uCaretWidth = ppvi->dwValue; 03588 break; 03589 default: 03590 break; 03591 } 03592 } 03593 03594 } /* if ((wFlag & SPIF_RANGETYPEMASK) == SPIF_BOOL) */ 03595 03596 FreeProfileUserName(pProfileUserName, &tlName); 03597 } /* if (!(wFlag & SPIF_SET)) */ 03598 03599 break; 03600 #undef ppvi 03601 #undef uDataRead 03602 } /* switch (wFlag) */ 03603 03604 03605 if (fWinIniChanged && fSendWinIniChange) { 03606 ULONG_PTR dwResult; 03607 03608 /* 03609 * dwResult is defined so that xxxSendMessageTimeout will really 03610 * and truly do a timeout. Yeah, I know, this is a hack, but, 03611 * it is compatible. 03612 */ 03613 03614 RtlInitLargeUnicodeString(&strSection, szSection, (UINT)-1); 03615 xxxSendMessageTimeout(PWND_BROADCAST, WM_SETTINGCHANGE, wFlag, (LPARAM)&strSection, 03616 SMTO_NORMAL, 100, &dwResult); 03617 } 03618 03619 return fWriteAllowed; 03620 } 03621 03622 /***************************************************************************\ 03623 * _RegisterShellHookWindow 03624 * 03625 * History: 03626 \***************************************************************************/ 03627 03628 BOOL _RegisterShellHookWindow(PWND pwnd) { 03629 PDESKTOPINFO pdeskinfo; 03630 03631 if (pwnd->head.rpdesk == NULL) 03632 return FALSE; 03633 03634 pdeskinfo = pwnd->head.rpdesk->pDeskInfo; 03635 03636 /* 03637 * Add pwnd to the desktop's Volatile Window Pointer List (VWPL) of 03638 * ShellHook windows. If this call initializes the VWPL, set the 03639 * (re)allocation threshhold to 2 PWNDs (we know we never have more than 03640 * 2 windows in this list anyway) 03641 */ 03642 if (VWPLAdd(&(pdeskinfo->pvwplShellHook), pwnd, 2)) { 03643 SetWF(pwnd, WFSHELLHOOKWND); 03644 return TRUE; 03645 } 03646 return FALSE; 03647 } 03648 03649 /***************************************************************************\ 03650 * _DeregisterShellHookWindow 03651 * 03652 * History: 03653 \***************************************************************************/ 03654 03655 BOOL _DeregisterShellHookWindow(PWND pwnd) { 03656 PDESKTOPINFO pdeskinfo; 03657 03658 if (pwnd->head.rpdesk == NULL) 03659 return FALSE; 03660 03661 pdeskinfo = pwnd->head.rpdesk->pDeskInfo; 03662 03663 if (VWPLRemove(&(pdeskinfo->pvwplShellHook), pwnd)) { 03664 ClrWF(pwnd, WFSHELLHOOKWND); 03665 } 03666 return TRUE; 03667 } 03668 03669 /***************************************************************************\ 03670 * xxxSendMinRectMessages 03671 * 03672 * History: 03673 \***************************************************************************/ 03674 03675 BOOL xxxSendMinRectMessages(PWND pwnd, RECT *lpRect) { 03676 BOOL fRet = FALSE; 03677 HWND hwnd = HW(pwnd); 03678 PTHREADINFO pti = PtiCurrent(); 03679 PDESKTOPINFO pdeskinfo; 03680 DWORD nPwndShellHook; 03681 PWND pwndShellHook; 03682 03683 if (IsHooked(pti, WHF_SHELL)) { 03684 xxxCallHook(HSHELL_GETMINRECT, (WPARAM)hwnd, 03685 (LPARAM)lpRect, WH_SHELL); 03686 fRet = TRUE; 03687 } 03688 03689 pdeskinfo = GETDESKINFO(pti); 03690 if (pdeskinfo->pvwplShellHook == NULL) 03691 return fRet; 03692 03693 nPwndShellHook = 0; 03694 pwndShellHook = NULL; 03695 while (pwndShellHook = VWPLNext(pdeskinfo->pvwplShellHook, pwndShellHook, &nPwndShellHook)) { 03696 TL tlpwnd; 03697 ULONG_PTR dwRes; 03698 03699 ThreadLock(pwndShellHook, &tlpwnd); 03700 if (xxxSendMessageTimeout(pwndShellHook, WM_KLUDGEMINRECT, (WPARAM)(hwnd), (LPARAM)lpRect, 03701 SMTO_NORMAL, 100, &dwRes)) 03702 fRet = TRUE; 03703 03704 /* 03705 * pdeskinfo->pvwplShellHook may have been realloced to a different 03706 * location and size during the WM_KLUDGEMINRECT callback. 03707 */ 03708 ThreadUnlock(&tlpwnd); 03709 } 03710 return fRet; 03711 } 03712 03713 /***************************************************************************\ 03714 * PostShellHookMessages 03715 * 03716 * History: 03717 \***************************************************************************/ 03718 03719 void PostShellHookMessages(UINT message, LPARAM lParam) { 03720 PDESKTOPINFO pdeskinfo = GETDESKINFO(PtiCurrent()); 03721 DWORD nPwndShellHook; 03722 PWND pwndShellHook; 03723 03724 nPwndShellHook = 0; 03725 pwndShellHook = NULL; 03726 03727 /* 03728 * Hack for WM_APPCOMMAND (bug 389210): 03729 * We want to allow anyone who's listening for these wm_appcommand messages to be able to 03730 * take the foreground. ie pressing mail will launch outlook AND bring it to the foreground 03731 * We set the token to null so anyone can steal the foreground - else it isn't clear who should 03732 * have the right to steal it - only one person gets the right. We let them fight it out to 03733 * decide who gets foreground if more than one listener will try make a foreground change. 03734 */ 03735 if (HSHELL_APPCOMMAND == message) { 03736 TAGMSG0(DBGTAG_FOREGROUND, "PostShellHookMessages cleared last input token - open foreground."); 03737 03738 glinp.ptiLastWoken = NULL; 03739 } 03740 03741 /* 03742 * Loop through all the windows registered to listen for shell hooks and post the message 03743 * to them 03744 */ 03745 while (pwndShellHook = VWPLNext(pdeskinfo->pvwplShellHook, pwndShellHook, &nPwndShellHook)) { 03746 if (pwndShellHook == pdeskinfo->spwndProgman) { 03747 switch (message) { 03748 case HSHELL_WINDOWCREATED: 03749 _PostMessage(pwndShellHook, gpsi->uiShellMsg, guiOtherWindowCreated, lParam); 03750 break; 03751 case HSHELL_WINDOWDESTROYED: 03752 _PostMessage(pwndShellHook, gpsi->uiShellMsg, guiOtherWindowDestroyed, lParam); 03753 break; 03754 } 03755 } else { 03756 _PostMessage(pwndShellHook, gpsi->uiShellMsg, message, lParam); 03757 } 03758 } 03759 03760 } 03761 03762 /***************************************************************************\ 03763 * _ResetDblClk 03764 * 03765 * History: 03766 \***************************************************************************/ 03767 03768 VOID _ResetDblClk(VOID) 03769 { 03770 PtiCurrent()->pq->timeDblClk = 0L; 03771 } 03772 03773 /***************************************************************************\ 03774 * SetMsgBox 03775 * 03776 * History: 03777 \***************************************************************************/ 03778 03779 void SetMsgBox(PWND pwnd) 03780 { 03781 pwnd->head.rpdesk->pDeskInfo->cntMBox++; 03782 SetWF(pwnd, WFMSGBOX); 03783 return; 03784 } 03785 03786 /***************************************************************************\ 03787 * xxxSimulateShiftF10 03788 * 03789 * This routine is called to convert a WM_CONTEXTHELP message back to a 03790 * SHIFT-F10 sequence for old applications. It is called from the default 03791 * window procedure. 03792 * 03793 * History: 03794 * 22-Aug-95 BradG Ported from Win95 (rare.asm) 03795 \***************************************************************************/ 03796 03797 VOID xxxSimulateShiftF10( VOID ) 03798 { 03799 /* 03800 * VK_SHIFT down 03801 */ 03802 xxxKeyEvent(VK_LSHIFT, 0x2A | SCANCODE_SIMULATED, NtGetTickCount(), 0, FALSE); 03803 03804 /* 03805 * VK_F10 down 03806 */ 03807 xxxKeyEvent(VK_F10, 0x44 | SCANCODE_SIMULATED, NtGetTickCount(), 0, FALSE); 03808 03809 /* 03810 * VK_F10 up 03811 */ 03812 xxxKeyEvent(VK_F10 | KBDBREAK, 0x44 | SCANCODE_SIMULATED, NtGetTickCount(), 0, FALSE); 03813 03814 /* 03815 * VK_SHIFT up 03816 */ 03817 xxxKeyEvent(VK_LSHIFT | KBDBREAK, 0x2A | SCANCODE_SIMULATED, NtGetTickCount(), 0, FALSE); 03818 } 03819 03820 /* 03821 * VWPL (Volatile Window Pointer List) Implementation details. 03822 * =========================================================== 03823 * Volatile Window Pointer Lists are used to keep a list of windows that we want 03824 * to send messages to, where the list may get altered during each of those send 03825 * message callbacks. 03826 * 03827 * The list is volatile in that it can change its size, contents and location 03828 * while we continue to traverse the list. 03829 * 03830 * Examples of use: 03831 * - hungapp redraw code in hungapp.c 03832 * - xxxSendMinRectMessages stuff in rare.c 03833 * 03834 * Members of the VWPL struct: 03835 * cPwnd 03836 * The number of pwnds in the list, not including NULLs 03837 * cElem 03838 * The size of the list, including NULLs. 03839 * cThreshhold 03840 * When growing, the number of extra spaces to add to the list. 03841 * When (cElem - cPwnd) > cThreshhold, that's when we reallocate to shrink. 03842 * apwnd[] 03843 * An array of pwnds. 03844 * The array may have some empty slots, but they will all be at the end. 03845 * 03846 * VWPL Internal Invariants: 03847 * - no pwnd appears more than once. 03848 * - cPwnd <= cElem 03849 * - number of unused slots (cElem - cPwnd) < cThreshhold 03850 * - all unused slots are at the end of the aPwnd[] array 03851 * 03852 * Restrictions on use of VWPLs: 03853 * - NULL pwnd is not allowed (except in unused slots) 03854 * - all pwnds in the list must be valid: pwnds must be explicitly removed from 03855 * the list in their xxxFreeWindow. 03856 */ 03857 03858 #if DBG_VWPL 03859 BOOL DbgCheckVWPL(PVWPL pvwpl) 03860 { 03861 DWORD ixPwnd; 03862 03863 if (!pvwpl) { 03864 return TRUE; 03865 } 03866 03867 UserAssert(pvwpl->cElem >= pvwpl->cPwnd); 03868 // Low memory may have made a shrinking realloc fail, which doesn't 03869 // really bother us. 03870 // UserAssert((pvwpl->cElem - pvwpl->cPwnd) < pvwpl->cThreshhold); 03871 03872 // Check that cElem is not too big 03873 UserAssert(pvwpl->cElem < 1000); 03874 03875 // check that the pwnds are all in the first cPwnd slots. 03876 for (ixPwnd = 0; ixPwnd < pvwpl->cPwnd; ixPwnd++) { 03877 UserAssert(pvwpl->aPwnd[ixPwnd] != NULL); 03878 } 03879 03880 #if ZERO_INIT_VWPL 03881 // check that the NULLs are all in the last few slots. 03882 for (ixPwnd = pvwpl->cPwnd; ixPwnd < pvwpl->cElem; ixPwnd++) { 03883 UserAssert(pvwpl->aPwnd[ixPwnd] == NULL); 03884 } 03885 #endif 03886 03887 #if 0 03888 // check that all pwnds are valid? 03889 for (ixPwnd = 0; ixPwnd < pvwpl->cPwnd; ixPwnd++) { 03890 PWND pwnd = pvwpl->aPwnd[ixPwnd]; 03891 UserAssert(ValidateHwnd(pwnd->head.h) == pwnd); 03892 } 03893 #endif 03894 03895 // check that no pwnds appears twice 03896 for (ixPwnd = 0; ixPwnd < pvwpl->cPwnd; ixPwnd++) { 03897 DWORD ix2; 03898 for (ix2 = ixPwnd + 1; ix2 < pvwpl->cPwnd; ix2++) { 03899 UserAssert(pvwpl->aPwnd[ixPwnd] != pvwpl->aPwnd[ix2]); 03900 } 03901 } 03902 } 03903 #else 03904 #define DbgCheckVWPL(foo) 03905 #endif 03906 03907 /*****************************************************************************\ 03908 * VWPLAdd 03909 * 03910 * Adds a pwnd to a VWPL (Volatile Window Pointer List). 03911 * Allocates or reallocates memory as required. 03912 * 03913 * History: 03914 * 98-01-30 IanJa Created. 03915 \*****************************************************************************/ 03916 BOOL VWPLAdd( 03917 PVWPL *ppvwpl, 03918 PWND pwnd, 03919 DWORD dwThreshhold) 03920 { 03921 PVWPL pvwpl; 03922 DWORD ixPwnd; 03923 03924 TAGMSG2(DBGTAG_VWPL, "VWPL %#p + %#p", *ppvwpl, pwnd); 03925 UserAssert(pwnd); 03926 03927 if (*ppvwpl == NULL) { 03928 /* 03929 * Initialize the VWPL 03930 */ 03931 UserAssert(dwThreshhold >= 2); // could be 1, but that would be silly 03932 pvwpl = (PVWPL)UserAllocPool( 03933 sizeof(VWPL) + (sizeof(PWND) * dwThreshhold), TAG_VWPL); 03934 if (pvwpl == NULL) { 03935 RIPMSG1(RIP_WARNING, 03936 "VWPLAdd fail to allocate initial %lx", 03937 sizeof(VWPL) + (sizeof(PWND) * dwThreshhold)); 03938 DbgCheckVWPL(*ppvwpl); 03939 return FALSE; 03940 } 03941 pvwpl->cElem = dwThreshhold; 03942 pvwpl->cThreshhold = dwThreshhold; 03943 #if ZERO_INIT_VWPL 03944 RtlZeroMemory(&(pvwpl->aPwnd[0]), (sizeof(PWND) * dwThreshhold)); 03945 #endif 03946 pvwpl->cPwnd = 0; 03947 *ppvwpl = pvwpl; 03948 ixPwnd = 0; 03949 goto AddPwnd; 03950 } else { 03951 pvwpl = *ppvwpl; 03952 for (ixPwnd = 0; ixPwnd < pvwpl->cElem; ixPwnd++) { 03953 if (pwnd == pvwpl->aPwnd[ixPwnd]) { 03954 DbgCheckVWPL(*ppvwpl); 03955 return FALSE; // callers require FALSE this case 03956 } 03957 } 03958 03959 if (pvwpl->cPwnd >= pvwpl->cElem ) { 03960 /* 03961 * didn't find it already there, and no space so grow the VWPL 03962 */ 03963 DWORD dwSize; 03964 DWORD dwSizeNew; 03965 03966 dwSize = sizeof(VWPL) + (sizeof(PWND) * pvwpl->cElem); 03967 dwSizeNew = dwSize + (sizeof(PWND) * pvwpl->cThreshhold); 03968 pvwpl = (PVWPL)UserReAllocPool(pvwpl, dwSize, dwSizeNew, TAG_VWPL); 03969 if (pvwpl == NULL) { 03970 RIPMSG2(RIP_WARNING, 03971 "VWPLAdd fail to reallocate %lx to %lx", dwSize, dwSizeNew); 03972 DbgCheckVWPL(*ppvwpl); 03973 return FALSE; 03974 } 03975 #if ZERO_INIT_VWPL 03976 RtlZeroMemory(&(pvwpl->aPwnd[pvwpl->cPwnd]), (sizeof(PWND) * dwThreshhold)); 03977 #endif 03978 pvwpl->cElem += pvwpl->cThreshhold; 03979 *ppvwpl = pvwpl; 03980 } 03981 } 03982 03983 AddPwnd: 03984 ixPwnd = pvwpl->cPwnd; 03985 pvwpl->aPwnd[ixPwnd] = pwnd; 03986 pvwpl->cPwnd++; 03987 DbgCheckVWPL(*ppvwpl); 03988 return TRUE; 03989 } 03990 03991 /*****************************************************************************\ 03992 * VWPLRemove 03993 * 03994 * Removes a pwnd from a VWPL list of pwnds. 03995 * Reallocates memory as required. 03996 * 03997 * Returns FALSE if the pwnd was not found 03998 * 03999 * History: 04000 * 98-01-30 IanJa Created. 04001 \*****************************************************************************/ 04002 BOOL VWPLRemove( 04003 PVWPL *ppvwpl, 04004 PWND pwnd) 04005 { 04006 PVWPL pvwpl = *ppvwpl; 04007 DWORD ixPwnd; 04008 04009 TAGMSG2(DBGTAG_VWPL, "VWPL %#p - %#p", *ppvwpl, pwnd); 04010 UserAssert(pwnd); 04011 04012 if (!pvwpl) { 04013 return FALSE; 04014 } 04015 for (ixPwnd = 0; ixPwnd < pvwpl->cElem; ixPwnd++) { 04016 if (pwnd == pvwpl->aPwnd[ixPwnd]) { 04017 goto PwndIsFound; 04018 } 04019 } 04020 DbgCheckVWPL(*ppvwpl); 04021 return FALSE; 04022 04023 PwndIsFound: 04024 pvwpl->aPwnd[ixPwnd] = NULL; 04025 pvwpl->cPwnd--; 04026 04027 if (pvwpl->cPwnd == 0) { 04028 UserFreePool(pvwpl); 04029 *ppvwpl = NULL; 04030 return TRUE; 04031 } 04032 04033 /* 04034 * Compact the VWPL to keep all the empty slots at the end. 04035 * If these free slots exceeds the threshhold, realloc to shrink. 04036 * It doesn't matter that we change the order. 04037 */ 04038 pvwpl->aPwnd[ixPwnd] = pvwpl->aPwnd[pvwpl->cPwnd]; 04039 #if ZERO_INIT_VWPL 04040 pvwpl->aPwnd[pvwpl->cPwnd] = NULL; 04041 #endif 04042 04043 04044 if ((pvwpl->cElem - pvwpl->cPwnd) >= pvwpl->cThreshhold) { 04045 DWORD dwSize; 04046 DWORD dwSizeNew; 04047 04048 // Low memory may have made a shrinking realloc fail, which doesn't 04049 // really bother us. 04050 // UserAssert((pvwpl->cElem - pvwpl->cPwnd) == pvwpl->cThreshhold); 04051 04052 dwSize = sizeof(VWPL) + (sizeof(PWND) * pvwpl->cElem); 04053 dwSizeNew = sizeof(VWPL) + (sizeof(PWND) * pvwpl->cPwnd); 04054 pvwpl = (PVWPL)UserReAllocPool(pvwpl, dwSize, dwSizeNew, TAG_VWPL); 04055 if (pvwpl == NULL) { 04056 RIPMSG2(RIP_WARNING, 04057 "VWPLRemove fail to reallocate %lx to %lx", 04058 dwSize, dwSizeNew); 04059 DbgCheckVWPL(*ppvwpl); 04060 return TRUE; 04061 } 04062 pvwpl->cElem = pvwpl->cPwnd; 04063 *ppvwpl = pvwpl; 04064 } 04065 04066 DbgCheckVWPL(*ppvwpl); 04067 return TRUE; 04068 } 04069 04070 /*****************************************************************************\ 04071 * VWPLNext 04072 * 04073 * Returns the next pwnd from a VWPL (Volatile Window Pointer List). 04074 * 04075 * Setting *pnPrev to 0 will return the first pwnd in the VWPL, and gets a new 04076 * value in *pnPrev which is to be used in a subsequent call to VWPLNext to 04077 * obtain the next pwnd. 04078 * Returns NULL when the last pwnd has been obtained, and sets *pnPrev back to 0 04079 * 04080 * History: 04081 * 98-01-30 IanJa Created. 04082 \*****************************************************************************/ 04083 PWND VWPLNext(PVWPL pvwpl, PWND pwndPrev, DWORD *pnPrev) 04084 { 04085 DbgCheckVWPL(pvwpl); 04086 04087 if (!pvwpl) { 04088 TAGMSG1(DBGTAG_VWPL, "VWPL %#p => NULL (empty)", pvwpl); 04089 return NULL; 04090 } 04091 04092 if (*pnPrev >= pvwpl->cPwnd) { 04093 goto NoMorePwnds; 04094 } 04095 04096 /* 04097 * If our previous pwnd is still there, advance to the next slot 04098 * (else it has gone, so return the one now occupying its slot) 04099 */ 04100 if (pvwpl->aPwnd[*pnPrev] == pwndPrev) { 04101 (*pnPrev)++; 04102 } 04103 04104 if (*pnPrev < pvwpl->cPwnd) { 04105 UserAssert(pvwpl->aPwnd[*pnPrev] != pwndPrev); 04106 TAGMSG2(DBGTAG_VWPL, "VWPL %#p => %#p", pvwpl, pvwpl->aPwnd[*pnPrev]); 04107 return pvwpl->aPwnd[*pnPrev]; 04108 } 04109 04110 /* 04111 * We came to the end 04112 */ 04113 NoMorePwnds: 04114 TAGMSG1(DBGTAG_VWPL, "VWPL %#p => NULL (end)", pvwpl); 04115 *pnPrev = 0; 04116 return NULL; 04117 }

Generated on Sat May 15 19:41:36 2004 for test by doxygen 1.3.7