Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

2917 lines
89 KiB

/****************************** Module Header ******************************\
* Module Name: rare.c
*
* Copyright (c) 1985-96, Microsoft Corporation
*
* History:
* 06-28-91 MikeHar Created.
\***************************************************************************/
#include "precomp.h"
#pragma hdrstop
/*
* MetricsRecalc flags
*/
#define CALC_RESIZE 0x0001
#define CALC_FRAME 0x0002
#define CALC_MINIMIZE 0x0004
/***************************************************************************\
* NormalizeRect
*
*
* History:
\***************************************************************************/
VOID NormalizeRect(
LPRECT lprcDest,
LPRECT lprcSrc,
LPRECT lprcNewScreen,
int dxOrigin,
int dyOrigin,
int dx,
int cxOld,
int dy,
int cyOld,
BOOL fProportion)
{
int cxOverflow;
int cyOverflow;
CopyOffsetRect(lprcDest,
lprcSrc,
dxOrigin + MultDiv(lprcSrc->left, dx, cxOld),
dyOrigin + MultDiv(lprcSrc->top , dy, cyOld));
if (fProportion &&
(dx > 0) &&
(dy > 0) &&
(lprcDest->left <= lprcNewScreen->left) &&
(lprcDest->top <= lprcNewScreen->top) &&
((cxOverflow = (lprcDest->right - lprcDest->left - cxOld)) >= 0) &&
((cyOverflow = (lprcDest->bottom - lprcDest->top - cyOld)) >= 0)) {
/*
* we're growing and this is a full screen window -- so we need to grow
* this window to preserve it's fullscreenness (jeffbog -- 01/10/95)
*/
lprcDest->right = lprcNewScreen->right + cxOverflow;
lprcDest->bottom = lprcNewScreen->bottom + cyOverflow;
return;
}
/*
* Fit horizontally. Try to fit so that the window isn't out of the
* working area horizontally. Keep left edge visible always.
*/
if (lprcDest->right > lprcNewScreen->right)
OffsetRect(lprcDest, lprcNewScreen->right - lprcDest->right, 0);
if (lprcDest->left < lprcNewScreen->left)
OffsetRect(lprcDest, lprcNewScreen->left - lprcDest->left, 0);
/*
* If inspite of the above adjustment, the right edge is out of the
* screen, then change the width to fit it within the screen.
*/
if (fProportion && (lprcDest->right > lprcNewScreen->right))
lprcDest->right = lprcNewScreen->right;
/*
* Fit vertically. Try to fit so that the window isn't out of the
* working area vertically. Keep top edge visible always.
*/
if (lprcDest->bottom > lprcNewScreen->bottom)
OffsetRect(lprcDest, 0, lprcNewScreen->bottom - lprcDest->bottom);
if (lprcDest->top < lprcNewScreen->top)
OffsetRect(lprcDest, 0, lprcNewScreen->top - lprcDest->top);
/*
* If inspite of the above adjustment, the bottom edge is out of the
* screen, then change the height to fit it within the screen.
*/
if (fProportion && (lprcDest->bottom > lprcNewScreen->bottom))
lprcDest->bottom = lprcNewScreen->bottom;
}
/***************************************************************************\
* _SetDebugErrorLevel
*
* History:
\***************************************************************************/
VOID _SetDebugErrorLevel(
DWORD dwLevel)
{
gpsi->dwDebugErrorLevel = dwLevel;
/*
* We call this here to prevent NTSD from keeping
* the hour-glass pointer up.
*/
WakeInputIdle(PtiCurrent());
}
/***************************************************************************\
* UpdateWinIniInt
*
* History:
* 18-Apr-1994 mikeke Created
\***************************************************************************/
BOOL UpdateWinIniInt(
UINT idSection,
UINT wKeyNameId,
int value)
{
WCHAR szTemp[40];
wsprintfW(szTemp, L"%d", value);
return UT_FastUpdateWinIni(idSection, wKeyNameId, szTemp);
}
/***************************************************************************\
* SetDesktopMetrics
*
* History:
* 31-Jan-1994 mikeke Ported
\***************************************************************************/
void SetDesktopMetrics()
{
SYSMET(CXFULLSCREEN) = gpsi->rcWork.right - gpsi->rcWork.left;
SYSMET(CXMAXIMIZED) = gpsi->rcWork.right - gpsi->rcWork.left + 2*SYSMET(CXSIZEFRAME);
SYSMET(CYFULLSCREEN) = gpsi->rcWork.bottom - gpsi->rcWork.top - SYSMET(CYCAPTION);
SYSMET(CYMAXIMIZED) = gpsi->rcWork.bottom - gpsi->rcWork.top + 2*SYSMET(CYSIZEFRAME);
}
/***************************************************************************\
* xxxMetricsRecalc (Win95: MetricsRecalc)
*
* Does work to size/position all minimized or nonminimized
* windows. Called when frame metrics or min metrics are changed.
*
* Note that you can NOT do DeferWindowPos() with this function. SWP doesn't
* work when you do parents and children at the same time--it's only for
* peer windows. Thus we must do SetWindowPos() for each window.
*
* History:
* 06-28-91 MikeHar Ported.
\***************************************************************************/
void xxxMetricsRecalc(
UINT wFlags,
int dx,
int dy,
int dyCaption,
int dyMenu)
{
PHWND phwnd;
PWND pwnd;
RECT rc;
PCHECKPOINT pcp;
TL tlpwnd;
BOOL fResized;
PBWL pbwl;
PTHREADINFO ptiCurrent;
int c;
ptiCurrent = PtiCurrent();
pbwl = BuildHwndList(
GETDESKINFO(ptiCurrent)->spwnd->spwndChild,
BWL_ENUMLIST | BWL_ENUMCHILDREN,
NULL);
if (!pbwl)
return;
UserAssert(*pbwl->phwndNext == (HWND) 1);
for ( c = pbwl->phwndNext - pbwl->rghwnd, phwnd = pbwl->rghwnd;
c > 0;
c--, phwnd++) {
pwnd = RevalidateHwnd(*phwnd);
if (!pwnd)
continue;
ThreadLockAlwaysWithPti(ptiCurrent, pwnd, &tlpwnd);
fResized = FALSE;
if ((wFlags & CALC_MINIMIZE) && TestWF(pwnd, WFMINIMIZED)) {
/*
* We're changing the minimized window dimensions. We need to
* resize. Note that we do NOT move.
*/
CopyRect(&rc, (&pwnd->rcWindow));
rc.right += dx;
rc.bottom += dy;
goto PositionWnd;
}
/*
* We're changing the size of the window because the sizing border
* changed.
*/
if ((wFlags & CALC_RESIZE) && TestWF(pwnd, WFSIZEBOX)) {
pcp = (CHECKPOINT *)_GetProp(pwnd, PROP_CHECKPOINT, PROPF_INTERNAL);
/*
* Update maximized position to account for sizing border
* We do this for DOS box also. This way client of max'ed windows
* stays in same relative position.
*/
if (pcp && (pcp->fMaxInitialized)) {
pcp->ptMax.x -= dx;
pcp->ptMax.y -= dy;
}
if (TestWF(pwnd, WFMINIMIZED)) {
if (pcp)
InflateRect(&pcp->rcNormal, dx, dy);
} else {
CopyInflateRect(&rc, (&pwnd->rcWindow), dx, dy);
if (TestWF(pwnd, WFCPRESENT))
rc.bottom += dyCaption;
if (TestWF(pwnd, WFMPRESENT))
rc.bottom += dyMenu;
PositionWnd:
fResized = TRUE;
/*
* Remember SWP expects values in PARENT CLIENT coordinates.
*/
OffsetRect(&rc,
-pwnd->spwndParent->rcClient.left,
-pwnd->spwndParent->rcClient.top);
xxxSetWindowPos(pwnd,
PWND_TOP,
rc.left,
rc.top,
rc.right-rc.left,
rc.bottom-rc.top,
#if 0 // Win95 flags
SWP_NOZORDER | SWP_NOACTIVATE | SWP_DEFERDRAWING | SWP_FRAMECHANGED);
#else
SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_FRAMECHANGED | SWP_NOREDRAW);
#endif
}
}
/*
* We're changing the nonclient widgets, so recalculate the
* client.
*/
if (wFlags & CALC_FRAME) {
/*
* Delete any cached small icons...
*/
if (dyCaption)
xxxSendMessage(pwnd, WM_SETICON, ICON_RECREATE, 0);
if (!TestWF(pwnd, WFMINIMIZED) && !fResized) {
CopyRect(&rc, &(pwnd->rcWindow));
if (TestWF(pwnd, WFMPRESENT))
rc.bottom += dyMenu;
if (TestWF(pwnd, WFCPRESENT)) {
rc.bottom += dyCaption;
/*
* Maximized MDI child windows position their caption
* outside their parent's client area (negative y).
* If the caption has changed, they need to be
* repositioned.
*/
if (TestWF(pwnd, WFMAXIMIZED)
&& TestWF(pwnd, WFCHILD)
&& (GETFNID(pwnd->spwndParent) == FNID_MDICLIENT)) {
xxxSetWindowPos(pwnd,
PWND_TOP,
rc.left - pwnd->spwndParent->rcWindow.left,
rc.top - pwnd->spwndParent->rcWindow.top - dyCaption,
rc.right - rc.left,
rc.bottom- rc.top, SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED | SWP_NOREDRAW);
goto LoopCleanup;
}
}
xxxSetWindowPos(pwnd,
PWND_TOP,
0,
0,
rc.right-rc.left,
rc.bottom-rc.top,
#if 0 // Win95 flags
SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED | SWP_NOREDRAW);
#else
SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED | SWP_NOCOPYBITS | SWP_NOREDRAW);
#endif
}
}
LoopCleanup:
ThreadUnlock(&tlpwnd);
}
FreeHwndList(pbwl);
}
/***************************************************************************\
* DesktopRecalc
*
* Moves all top-level nonpopup windows into free-desktop area. Also resets
* minimized/maximized info. That way when a window is minimized or maximzied,
* it goes to the minimized area.
*
* Called when desktop area changes.
*
* History:
\***************************************************************************/
VOID DesktopRecalc(
LPRECT lprcOldScreen,
LPRECT lprcNewScreen,
BOOL fProportion)
{
PWND pwnd;
RECT rc;
HDWP hdwp;
PCHECKPOINT pcp;
PTHREADINFO pti = PtiCurrent();
TL tlpwnd;
int dxOrigin;
int dyOrigin;
int cxOld;
int cyOld;
int dx;
int dy;
dxOrigin = lprcNewScreen->left - lprcOldScreen->left;
dyOrigin = lprcNewScreen->top - lprcOldScreen->top;
cxOld = lprcOldScreen->right - lprcOldScreen->left;
cyOld = lprcOldScreen->bottom - lprcOldScreen->top;
if (!fProportion) {
dx = 0;
dy = 0;
} else {
dx = (lprcNewScreen->right - lprcNewScreen->left) - cxOld;
dy = (lprcNewScreen->bottom - lprcNewScreen->top) - cyOld;
}
/*
* BOGUS
* Should use BuildHwndList().
* Loop through top level windows.
*/
if ((hdwp = _BeginDeferWindowPos(4)) == NULL)
return;
for (pwnd = pti->rpdesk->pDeskInfo->spwnd->spwndChild; pwnd; pwnd = pwnd->spwndNext) {
/*
* BOGUS
*
* TOOLWINDOW and SMCAPTION need to be rev'ed post-M6! TOOLWINDOW
* has come to mean SYSTEMWINDOW and SMCAPTION is the sucker that
* should mutate into TOOLWINDOW. Todd Laney agrees.
*
*
* Skip tool windows
*/
if (TestWF(pwnd, WEFTOOLWINDOW))
continue;
/*
* Reset data
*/
pcp = (PCHECKPOINT)_GetProp(pwnd, PROP_CHECKPOINT, PROPF_INTERNAL);
if (pcp) {
/*
* Blow away saved positions
*/
if (pcp->fMaxInitialized)
pcp->fMaxInitialized = FALSE;
if (pcp->fMinInitialized)
pcp->fMinInitialized = FALSE;
/*
* Adjust normal rectangle
*/
NormalizeRect(&pcp->rcNormal,
&pcp->rcNormal,
lprcNewScreen,
dxOrigin,
dyOrigin,
dx,
cxOld,
dy,
cyOld,
fProportion);
}
/*
* Skip windows completely utterly offscreen. They are probably
* there for a good reason, like some "multiple-desktop" program put
* them there or something.
*/
if (!IntersectRect(&rc, lprcOldScreen, &pwnd->rcWindow))
continue;
/*
* If really maximized, then make maximized window fill working
* area. Really maximized means maximized && bigger than old working
* area.
*/
if (TestWF(pwnd, WFMAXIMIZED) &&
(pwnd->rcWindow.right - pwnd->rcWindow.left >= cxOld) &&
(pwnd->rcWindow.bottom - pwnd->rcWindow.top >= cyOld)) {
ThreadLockAlways(pwnd, &tlpwnd);
xxxInitSendValidateMinMaxInfo(pwnd);
ThreadUnlock(&tlpwnd);
if ((rgptMinMaxWnd[MMI_MAXPOS].x <= lprcNewScreen->left) &&
(rgptMinMaxWnd[MMI_MAXPOS].y <= lprcNewScreen->top) &&
(rgptMinMaxWnd[MMI_MAXSIZE].x >= lprcNewScreen->right - lprcNewScreen->left) &&
(rgptMinMaxWnd[MMI_MAXSIZE].y >= lprcNewScreen->bottom - lprcNewScreen->top) &&
TestWF(pwnd, WFBORDERMASK) == LOBYTE(WFCAPTION)) {
int dxy;
/*
* Shrink this puppy back.
*/
if (lprcNewScreen->left)
dxy = rgptMinMaxWnd[MMI_MAXPOS].y;
else
dxy = rgptMinMaxWnd[MMI_MAXPOS].x;
rgptMinMaxWnd[MMI_MAXPOS].x = lprcNewScreen->left + dxy;
rgptMinMaxWnd[MMI_MAXPOS].y = lprcNewScreen->top + dxy;
dxy *= 2;
rgptMinMaxWnd[MMI_MAXSIZE].x =
lprcNewScreen->right - lprcNewScreen->left - dxy;
rgptMinMaxWnd[MMI_MAXSIZE].y =
lprcNewScreen->bottom - lprcNewScreen->top - dxy;
}
hdwp = _DeferWindowPos(hdwp,
pwnd,
PWND_TOP,
rgptMinMaxWnd[MMI_MAXPOS].x,
rgptMinMaxWnd[MMI_MAXPOS].y,
rgptMinMaxWnd[MMI_MAXSIZE].x,
rgptMinMaxWnd[MMI_MAXSIZE].y,
SWP_NOZORDER | SWP_NOACTIVATE);
} else {
/*
* Offset all windows by dxOff, dyOff. But make sure that
* they don't go completely outside the new working area.
*/
NormalizeRect(&rc,
&pwnd->rcWindow,
lprcNewScreen,
dxOrigin,
dyOrigin,
dx,
cxOld,
dy,
cyOld,
fProportion);
/*
* We're a top level window, so we don't have to
* convert to parent's client coords. Screen coords
* and parent client coords are same for children of
* desktop.
*/
hdwp = _DeferWindowPos(hdwp,
pwnd,
PWND_TOP,
rc.left,
rc.top,
rc.right - rc.left,
rc.bottom - rc.top,
SWP_NOACTIVATE | SWP_NOZORDER);
}
}
xxxEndDeferWindowPosEx(hdwp, TRUE);
}
/***************************************************************************\
* SetWindowMetricInt
*
* History:
* 25-Feb-96 BradG Added Pixel -> TWIPS conversion
\***************************************************************************/
BOOL SetWindowMetricInt(
WORD wKeyNameId,
int iIniValue)
{
/*
* If you change the below list of STR_* make sure you make a corresponding
* change in FastGetProfileIntFromID (profile.c)
*/
switch (wKeyNameId) {
case STR_BORDERWIDTH:
case STR_SCROLLWIDTH:
case STR_SCROLLHEIGHT:
case STR_CAPTIONWIDTH:
case STR_CAPTIONHEIGHT:
case STR_SMCAPTIONWIDTH:
case STR_SMCAPTIONHEIGHT:
case STR_MENUWIDTH:
case STR_MENUHEIGHT:
case STR_ICONHORZSPACING:
case STR_ICONVERTSPACING:
case STR_MINWIDTH:
case STR_MINHORZGAP:
case STR_MINVERTGAP:
/*
* Always store window metrics in TWIPS
*/
iIniValue = -UserMulDiv(iIniValue, 72*20, oemInfo.cyPixelsPerInch);
break;
}
return UpdateWinIniInt(PMAP_METRICS, wKeyNameId, iIniValue);
}
/***************************************************************************\
* SetWindowMetricStruct
*
* History:
\***************************************************************************/
BOOL SetWindowMetricStruct(
WORD wKeyNameId,
LPVOID pvStruct,
UINT cbStruct)
{
return GetSetProfileStructFromResID(PMAP_METRICS, wKeyNameId, pvStruct,
cbStruct, TRUE);
}
/***************************************************************************\
* SetWindowMetricFont
*
* History:
\***************************************************************************/
BOOL SetWindowMetricFont(
WORD wKeyNameId,
LPLOGFONT lplf)
{
return SetWindowMetricStruct(wKeyNameId, lplf, sizeof(LOGFONTW));
}
/***************************************************************************\
* SetAndDrawNCMetrics
*
* History:
\***************************************************************************/
BOOL xxxSetAndDrawNCMetrics(int clNewBorder, LPNONCLIENTMETRICS lpnc)
{
int dl = clNewBorder - gpsi->gclBorder;
int dxMinOld = SYSMET(CXMINIMIZED);
int dyMinOld = SYSMET(CYMINIMIZED);
int cxBorder = SYSMET(CXBORDER);
int cyBorder = SYSMET(CYBORDER);
int dyCaption;
int dyMenu;
/*
* Do we need to recalculate?
*/
if ((lpnc == NULL) && !dl)
return(FALSE);
if (lpnc) {
dyCaption = (int)lpnc->iCaptionHeight - SYSMET(CYSIZE);
dyMenu = (int)lpnc->iMenuHeight - SYSMET(CYMENUSIZE);
} else {
dyCaption = dyMenu = 0;
}
/*
* Recalculate the system metrics
*/
SetWindowNCMetrics(lpnc, TRUE, clNewBorder);
/*
* Reset our saved menu size/position info
*/
MenuRecalc();
/*
* Reset window sized, positions, frames
*/
xxxMetricsRecalc(
CALC_FRAME | (dl ? CALC_RESIZE : 0),
dl*cxBorder,
dl*cyBorder,
dyCaption,
dyMenu);
dxMinOld = SYSMET(CXMINIMIZED) - dxMinOld;
dyMinOld = SYSMET(CYMINIMIZED) - dyMinOld;
if (dxMinOld || dyMinOld) {
xxxMetricsRecalc(CALC_MINIMIZE, dxMinOld, dyMinOld, 0, 0);
}
xxxRedrawScreen();
return TRUE;
}
/***************************************************************************\
* xxxSetAndDrawMinMetrics
*
* History:
* 13-May-1994 mikeke mikeke Ported
\***************************************************************************/
BOOL xxxSetAndDrawMinMetrics(
LPMINIMIZEDMETRICS lpmin)
{
/*
* Save minimized window dimensions
*/
int dxMinOld = SYSMET(CXMINIMIZED);
int dyMinOld = SYSMET(CYMINIMIZED);
SetMinMetrics(lpmin);
/*
* Do we need to adjust minimized size?
*/
dxMinOld = SYSMET(CXMINIMIZED) - dxMinOld;
dyMinOld = SYSMET(CYMINIMIZED) - dyMinOld;
if (dxMinOld || dyMinOld) {
xxxMetricsRecalc(CALC_MINIMIZE, dxMinOld, dyMinOld, 0, 0);
}
xxxRedrawScreen();
return TRUE;
}
/***************************************************************************\
* SetAndDrawIconMetrics
*
* History:
* 13-May-1994 mikeke mikeke Ported
\***************************************************************************/
BOOL SetAndDrawIconMetrics(
LPICONMETRICS lpicon)
{
SetIconMetrics(lpicon);
xxxRedrawScreen();
return TRUE;
}
/***************************************************************************\
* xxxSPISetNCMetrics
*
* History:
* 13-May-1994 mikeke mikeke Ported
\***************************************************************************/
BOOL xxxSPISetNCMetrics(
LPNONCLIENTMETRICS lpnc,
BOOL fAlterWinIni)
{
BOOL fWriteAllowed = !fAlterWinIni;
BOOL fChanged = FALSE;
if (fAlterWinIni) {
fChanged = SetWindowMetricInt(STR_BORDERWIDTH, (int) lpnc->iBorderWidth);
fChanged &= SetWindowMetricInt(STR_SCROLLWIDTH, (int) lpnc->iScrollWidth);
fChanged &= SetWindowMetricInt(STR_SCROLLHEIGHT, (int) lpnc->iScrollHeight);
fChanged &= SetWindowMetricInt(STR_CAPTIONWIDTH, (int) lpnc->iCaptionWidth);
fChanged &= SetWindowMetricInt(STR_CAPTIONHEIGHT, (int) lpnc->iCaptionHeight);
fChanged &= SetWindowMetricInt(STR_SMCAPTIONWIDTH, (int) lpnc->iSmCaptionWidth);
fChanged &= SetWindowMetricInt(STR_SMCAPTIONHEIGHT, (int) lpnc->iSmCaptionHeight);
fChanged &= SetWindowMetricInt(STR_MENUWIDTH, (int) lpnc->iMenuWidth);
fChanged &= SetWindowMetricInt(STR_MENUHEIGHT, (int) lpnc->iMenuHeight);
fChanged &= SetWindowMetricFont(STR_CAPTIONFONT, &lpnc->lfCaptionFont);
fChanged &= SetWindowMetricFont(STR_SMCAPTIONFONT, &lpnc->lfSmCaptionFont);
fChanged &= SetWindowMetricFont(STR_MENUFONT, &lpnc->lfMenuFont);
fChanged &= SetWindowMetricFont(STR_STATUSFONT, &lpnc->lfStatusFont);
fChanged &= SetWindowMetricFont(STR_MESSAGEFONT, &lpnc->lfMessageFont);
fWriteAllowed = fChanged;
}
if (fWriteAllowed)
xxxSetAndDrawNCMetrics((int) lpnc->iBorderWidth, lpnc);
return fChanged;
}
/***************************************************************************\
* xxxSPISetMinMetrics
*
* History:
* 13-May-1994 mikeke mikeke Ported
\***************************************************************************/
BOOL xxxSPISetMinMetrics(
LPMINIMIZEDMETRICS lpmin,
BOOL fAlterWinIni)
{
BOOL fWriteAllowed = !fAlterWinIni;
BOOL fChanged = FALSE;
if (fAlterWinIni) {
fChanged = SetWindowMetricInt(STR_MINWIDTH, (int) lpmin->iWidth);
fChanged &= SetWindowMetricInt(STR_MINHORZGAP, (int) lpmin->iHorzGap);
fChanged &= SetWindowMetricInt(STR_MINVERTGAP, (int) lpmin->iVertGap);
fChanged &= SetWindowMetricInt(STR_MINARRANGE, (int) lpmin->iArrange);
fWriteAllowed = fChanged;
}
if (fWriteAllowed)
xxxSetAndDrawMinMetrics(lpmin);
return fChanged;
}
/***************************************************************************\
* SPISetIconMetrics
*
* History:
* 13-May-1994 mikeke mikeke Ported
\***************************************************************************/
BOOL SPISetIconMetrics(
LPICONMETRICS lpicon,
BOOL fAlterWinIni)
{
BOOL fWriteAllowed = !fAlterWinIni;
BOOL fChanged = FALSE;
if (fAlterWinIni) {
fChanged = SetWindowMetricInt(STR_ICONHORZSPACING, (int) lpicon->iHorzSpacing);
fChanged &= SetWindowMetricInt(STR_ICONVERTSPACING, (int) lpicon->iVertSpacing);
fChanged &= SetWindowMetricInt(STR_ICONTITLEWRAP, (int) lpicon->iTitleWrap);
fChanged &= SetWindowMetricFont(STR_ICONFONT, &lpicon->lfFont);
fWriteAllowed = fChanged;
}
if (fWriteAllowed)
SetAndDrawIconMetrics(lpicon);
return fChanged;
}
/***************************************************************************\
* SPISetIconTitleFont
*
* History:
* 13-May-1994 mikeke mikeke Ported
\***************************************************************************/
BOOL SPISetIconTitleFont(
LPLOGFONT lplf,
BOOL fAlterWinIni)
{
HFONT hfnT;
BOOL fWriteAllowed = !fAlterWinIni;
BOOL fWinIniChanged = FALSE;
if (hfnT = CreateFontFromWinIni(lplf, STR_ICONFONT)) {
if (fAlterWinIni) {
if (lplf) {
LOGFONT lf;
GreExtGetObjectW(hfnT, sizeof(LOGFONTW), &lf);
fWinIniChanged = SetWindowMetricStruct(STR_ICONFONT,
&lf,
sizeof(LOGFONTW));
} else {
/*
* !lParam so go back to current win.ini settings so
*/
fWinIniChanged = TRUE;
}
fWriteAllowed = fWinIniChanged;
}
if (fWriteAllowed) {
if (ghIconFont) {
GreMarkDeletableFont(ghIconFont);
GreDeleteObject(ghIconFont);
}
ghIconFont = hfnT;
} else {
GreMarkDeletableFont(hfnT);
GreDeleteObject(hfnT);
}
}
return fWinIniChanged;
}
/***************************************************************************\
* xxxSetSPIMetrics
*
* History:
* 13-May-1994 mikeke mikeke Ported
\***************************************************************************/
BOOL xxxSetSPIMetrics(
DWORD wFlag,
LPVOID lParam,
BOOL fAlterWinIni)
{
BOOL fWinIniChanged;
switch (wFlag) {
case SPI_SETANIMATION:
if (fAlterWinIni) {
fWinIniChanged = SetWindowMetricInt(
STR_MINANIMATE,
(int) ((LPANIMATIONINFO) lParam)->iMinAnimate);
if (!fWinIniChanged) {
return FALSE;
}
} else
fWinIniChanged = FALSE;
gfAnimate = (int) ((LPANIMATIONINFO) lParam)->iMinAnimate;
return fWinIniChanged;
case SPI_SETNONCLIENTMETRICS:
return xxxSPISetNCMetrics((LPNONCLIENTMETRICS) lParam, fAlterWinIni);
case SPI_SETICONMETRICS:
return SPISetIconMetrics((LPICONMETRICS) lParam, fAlterWinIni);
case SPI_SETMINIMIZEDMETRICS:
return xxxSPISetMinMetrics((LPMINIMIZEDMETRICS) lParam, fAlterWinIni);
case SPI_SETICONTITLELOGFONT:
return SPISetIconTitleFont((LPLOGFONT) lParam, fAlterWinIni);
#ifdef DEBUG
default:
RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING, "SetSPIMetrics. Invalid wFlag: %#lx", wFlag);
return FALSE;
#endif
}
}
/***************************************************************************\
* SetFilterKeys
*
* History:
* 10-12-94 JimA Created.
\***************************************************************************/
BOOL SetFilterKeys(
LPFILTERKEYS pFilterKeys)
{
LPWSTR pwszd = L"%d";
BOOL fWinIniChanged;
WCHAR szTemp[40];
wsprintfW(szTemp, pwszd, pFilterKeys->dwFlags);
fWinIniChanged = UT_FastWriteProfileStringW(
PMAP_KEYBOARDRESPONSE,
L"Flags",
szTemp);
wsprintfW(szTemp, pwszd, pFilterKeys->iWaitMSec);
fWinIniChanged &= UT_FastWriteProfileStringW(
PMAP_KEYBOARDRESPONSE,
L"DelayBeforeAcceptance",
szTemp);
wsprintfW(szTemp, pwszd, pFilterKeys->iDelayMSec);
fWinIniChanged &= UT_FastWriteProfileStringW(
PMAP_KEYBOARDRESPONSE,
L"AutoRepeatDelay",
szTemp);
wsprintfW(szTemp, pwszd, pFilterKeys->iRepeatMSec);
fWinIniChanged &= UT_FastWriteProfileStringW(
PMAP_KEYBOARDRESPONSE,
L"AutoRepeatRate",
szTemp);
wsprintfW(szTemp, pwszd, pFilterKeys->iBounceMSec);
fWinIniChanged &= UT_FastWriteProfileStringW(
PMAP_KEYBOARDRESPONSE,
L"BounceTime",
szTemp);
return fWinIniChanged;
}
/***************************************************************************\
* SetMouseKeys
*
* History:
* 10-12-94 JimA Created.
\***************************************************************************/
BOOL SetMouseKeys(
LPMOUSEKEYS pMK)
{
LPWSTR pwszd = L"%d";
BOOL fWinIniChanged;
WCHAR szTemp[40];
wsprintfW(szTemp, pwszd, pMK->dwFlags);
fWinIniChanged = UT_FastWriteProfileStringW(
PMAP_MOUSEKEYS,
L"Flags",
szTemp);
wsprintfW(szTemp, pwszd, pMK->iMaxSpeed);
fWinIniChanged &= UT_FastWriteProfileStringW(
PMAP_MOUSEKEYS,
L"MaximumSpeed",
szTemp);
wsprintfW(szTemp, pwszd, pMK->iTimeToMaxSpeed);
fWinIniChanged &= UT_FastWriteProfileStringW(
PMAP_MOUSEKEYS,
L"TimeToMaximumSpeed",
szTemp);
return fWinIniChanged;
}
/***************************************************************************\
* SetSoundSentry
*
* History:
* 10-12-94 JimA Created.
\***************************************************************************/
BOOL SetSoundSentry(
LPSOUNDSENTRY pSS)
{
LPWSTR pwszd = L"%d";
BOOL fWinIniChanged;
WCHAR szTemp[40];
wsprintfW(szTemp, pwszd, pSS->dwFlags);
fWinIniChanged = UT_FastWriteProfileStringW(
PMAP_SOUNDSENTRY,
L"Flags",
szTemp);
wsprintfW(szTemp, pwszd, pSS->iFSTextEffect);
fWinIniChanged &= UT_FastWriteProfileStringW(
PMAP_SOUNDSENTRY,
L"TextEffect",
szTemp);
wsprintfW(szTemp, pwszd, pSS->iWindowsEffect);
fWinIniChanged &= UT_FastWriteProfileStringW(
PMAP_SOUNDSENTRY,
L"WindowsEffect",
szTemp);
return fWinIniChanged;
}
/***************************************************************************\
* xxxSystemParametersInfo
*
* SPI_GETBEEP: wParam is not used. lParam is long pointer to a boolean which
* gets true if beep on, false if beep off.
*
* SPI_SETBEEP: wParam is a bool which sets beep on (true) or off (false).
* lParam is not used.
*
* SPI_GETMOUSE: wParam is not used. lParam is long pointer to an integer
* array where rgw[0] gets xMouseThreshold, rgw[1] gets
* yMouseThreshold, and rgw[2] gets MouseSpeed.
*
* SPI_SETMOUSE: wParam is not used. lParam is long pointer to an integer
* array as described above. User's values are set to values
* in array.
*
* SPI_GETBORDER: wParam is not used. lParam is long pointer to an integer
* which gets the value of clBorder (border multiplier factor).
*
* SPI_SETBORDER: wParam is an integer which sets gpsi->gclBorder.
* lParam is not used.
*
* SPI_GETKEYBOARDDELAY: wParam is not used. lParam is a long pointer to an int
* which gets the current keyboard repeat delay setting.
*
* SPI_SETKEYBOARDDELAY: wParam is the new keyboard delay setting.
* lParam is not used.
*
* SPI_GETKEYBOARDSPEED: wParam is not used. lParam is a long pointer
* to an int which gets the current keyboard repeat
* speed setting.
*
* SPI_SETKEYBOARDSPEED: wParam is the new keyboard speed setting.
* lParam is not used.
*
* SPI_KANJIMENU: wParam contains:
* 1 - Mouse accelerator
* 2 - ASCII accelerator
* 3 - Kana accelerator
* lParam is not used. The wParam value is stored in the global
* KanjiMenu for use in accelerator displaying & searching.
*
* SPI_LANGDRIVER: wParam is not used.
* lParam contains a LPSTR to the new language driver filename.
*
* SPI_ICONHORIZONTALSPACING: wParam is the width in pixels of an icon cell.
*
* SPI_ICONVERTICALSPACING: wParam is the height in pixels of an icon cell.
*
* SPI_GETSCREENSAVETIMEOUT: wParam is not used
* lParam is a pointer to an int which gets the screen saver
* timeout value.
*
* SPI_SETSCREENSAVETIMEOUT: wParam is the time in seconds for the system
* to be idle before screensaving.
*
* SPI_GETSCREENSAVEACTIVE: lParam is a pointer to a BOOL which gets TRUE
* if the screensaver is active else gets false.
*
* SPI_SETSCREENSAVEACTIVE: if wParam is TRUE, screensaving is activated
* else it is deactivated.
*
* SPI_GETGRIDGRANULARITY: Obsolete. Returns 1 always.
*
* SPI_SETGRIDGRANULARITY: Obsolete. Does nothing.
*
* SPI_SETDESKWALLPAPER: wParam is not used; lParam is a long ptr to a string
* that holds the name of the bitmap file to be used as the
* desktop wall paper.
*
* SPI_SETDESKPATTERN: Both wParam and lParam are not used; USER will read the
* "pattern=" from WIN.INI and make it as the current desktop
* pattern;
*
* SPI_GETICONTITLEWRAP: lParam is LPINT which gets 0 if wrapping if off
* else gets 1.
*
* SPI_SETICONTITLEWRAP: wParam specifies TRUE to turn wrapping on else false
*
* SPI_GETMENUDROPALIGNMENT: lParam is LPINT which gets 0 specifies if menus
* drop left aligned else 1 if drop right aligned.
*
* SPI_SETMENUDROPALIGNMENT: wParam 0 specifies if menus drop left aligned else
* the drop right aligned.
*
* SPI_SETDOUBLECLKWIDTH: wParam specifies the width of the rectangle
* within which the second click of a double click must fall
* for it to be registered as a double click.
*
* SPI_SETDOUBLECLKHEIGHT: wParam specifies the height of the rectangle
* within which the second click of a double click must fall
* for it to be registered as a double click.
*
* SPI_GETICONTITLELOGFONT: lParam is a pointer to a LOGFONT struct which
* gets the logfont for the current icon title font. wParam
* specifies the size of the logfont struct.
*
* SPI_SETDOUBLECLICKTIME: wParm specifies the double click time
*
* SPI_SETMOUSEBUTTONSWAP: if wParam is 1, swap mouse buttons else if wParam
* is 0, don't swap buttons
* SPI_SETDRAGFULLWINDOWS: wParam = fSet.
* SPI_GETDRAGFULLWINDOWS: returns fSet.
*
* SPI_GETFILTERKEYS: lParam is a pointer to a FILTERKEYS struct. wParam
* specifies the size of the filterkeys struct.
*
* SPI_SETFILTERKEYS: lParam is a pointer to a FILTERKEYS struct. wParam
* is not used.
*
* SPI_GETSTICKYKEYS: lParam is a pointer to a STICKYKEYS struct. wParam
* specifies the size of the stickykeys struct.
*
* SPI_SETSTICKYKEYS: lParam is a pointer to a STICKYKEYS struct. wParam
* is not used.
*
* SPI_GETMOUSEKEYS: lParam is a pointer to a MOUSEKEYS struct. wParam
* specifies the size of the mousekeys struct.
*
* SPI_SETMOUSEKEYS: lParam is a pointer to a MOUSEKEYS struct. wParam
* is not used.
*
* SPI_GETACCESSTIMEOUT: lParam is a pointer to an ACCESSTIMEOUT struct.
* wParam specifies the size of the accesstimeout struct.
*
* SPI_SETACCESSTIMEOUT: lParam is a pointer to a ACCESSTIMEOUT struct.
* wParam is not used.
*
* SPI_GETTOGGLEKEYS: lParam is a pointer to a TOGGLEKEYS struct. wParam
* specifies the size of the togglekeys struct.
*
* SPI_SETTOGGLEKEYS: lParam is a pointer to a TOGGLEKEYS struct. wParam
* is not used.
*
* SPI_GETSHOWSOUNDS: lParam is a pointer to a SHOWSOUNDS struct. wParam
* specifies the size of the showsounds struct.
*
* SPI_SETSHOWSOUNDS: lParam is a pointer to a SHOWSOUNDS struct. wParam
* is not used.
*
* SPI_GETNONCLIENTMETRICS: lParam is a pointer to a NONCLIENTMETRICSW struct.
* wPAram is not used.
*
* SPI_GETSNAPTODEFBUTTON: lParam is a pointer to a BOOL which gets TRUE
* if the snap to default push button is active else gets false.
*
* SPI_SETSNAPTODEFBUTTON: if wParam is TRUE, dialog boxes will snap the mouse
* pointer to the default push button when created.
*
* SPI_GETFONTSMOOTHING:
* wParam is unused
* lParam is LPINT for boolean fFontSmoothing
*
* SPI_SETFONTSMOOTHING:
* wParam is INT for boolean fFontSmoothing
*
* SPI_GETWHEELSCROLLLINES: lParam is a pointer to a ULONG to receive the
* suggested number of lines to scroll when the wheel is
* rotated. wParam is unused.
*
* SPI_SETWHEELSCROLLLINES: wParam is a ULONG containing the suggested number
* of lines to scroll when the wheel is rotated. lParam is
* unused.
*
* History:
* 06-28-91 MikeHar Ported.
* 12-8-93 SanfordS Added SPI_SET/GETDRAGFULLWINDOWS
* 20-May-1996 adams Added SPI_SET/GETWHEELSCROLLLINES
\***************************************************************************/
BOOL xxxSystemParametersInfo(
UINT wFlag, // Item to change
DWORD wParam,
PVOID lParam,
UINT flags)
{
PPROCESSINFO ppi = PpiCurrent();
int clBorderOld;
int clBorderNew;
LPWSTR pwszd = L"%d";
WCHAR szSection[40];
WCHAR szTemp[40];
WCHAR szPat[MAX_PATH];
BOOL fWinIniChanged = FALSE;
BOOL fAlterWinIni = ((flags & SPIF_UPDATEINIFILE) != 0);
BOOL fSendWinIniChange = ((flags & SPIF_SENDCHANGE) != 0);
BOOL fWriteAllowed = !fAlterWinIni;
ACCESS_MASK amRequest;
LARGE_UNICODE_STRING strSection;
/*
* CONSIDER(adams) : Many of the SPI_GET* could be implemented
* on the client side (SnapTo, WheelScrollLines, etc.).
*/
/*
* Features not implemented
*/
switch (wFlag)
{
case SPI_TIMEOUTS:
case SPI_KANJIMENU:
case SPI_LANGDRIVER:
case SPI_UNUSED39:
case SPI_UNUSED40:
case SPI_SETPENWINDOWS:
case SPI_GETHIGHCONTRAST:
case SPI_SETHIGHCONTRAST:
case SPI_GETKEYBOARDPREF:
case SPI_SETKEYBOARDPREF:
case SPI_GETSCREENREADER:
case SPI_SETSCREENREADER:
case SPI_GETLOWPOWERTIMEOUT:
case SPI_GETPOWEROFFTIMEOUT:
case SPI_GETLOWPOWERACTIVE:
case SPI_GETPOWEROFFACTIVE:
case SPI_SETLOWPOWERTIMEOUT:
case SPI_SETPOWEROFFTIMEOUT:
case SPI_SETLOWPOWERACTIVE:
case SPI_SETPOWEROFFACTIVE:
case SPI_GETWINDOWSEXTENSION:
case SPI_SCREENSAVERRUNNING:
case SPI_GETSERIALKEYS:
case SPI_SETSERIALKEYS:
case SPI_SETMOUSETRAILS:
case SPI_GETMOUSETRAILS:
RIPERR1(ERROR_INVALID_PARAMETER,
RIP_WARNING,
"SystemParametersInfo call not supported parameter SPI_ 0x%lx\n", wFlag );
return FALSE;
}
/*
* Perform access check. Always grant access to CSR.
*/
if (ppi->Process != gpepCSRSS) {
switch (wFlag) {
case SPI_SETBEEP:
case SPI_SETMOUSE:
case SPI_SETBORDER:
case SPI_SETKEYBOARDSPEED:
case SPI_SETDEFAULTINPUTLANG:
case SPI_SETSCREENSAVETIMEOUT:
case SPI_SETSCREENSAVEACTIVE:
case SPI_SETGRIDGRANULARITY:
case SPI_SETDESKWALLPAPER:
case SPI_SETDESKPATTERN:
case SPI_SETKEYBOARDDELAY:
case SPI_SETICONTITLEWRAP:
case SPI_SETMENUDROPALIGNMENT:
case SPI_SETDOUBLECLKWIDTH:
case SPI_SETDOUBLECLKHEIGHT:
case SPI_SETDOUBLECLICKTIME:
case SPI_SETMOUSEBUTTONSWAP:
case SPI_SETICONTITLELOGFONT:
case SPI_SETFASTTASKSWITCH:
case SPI_SETFILTERKEYS:
case SPI_SETTOGGLEKEYS:
case SPI_SETMOUSEKEYS:
case SPI_SETSHOWSOUNDS:
case SPI_SETSTICKYKEYS:
case SPI_SETACCESSTIMEOUT:
case SPI_SETSOUNDSENTRY:
case SPI_SETSNAPTODEFBUTTON:
case SPI_SETANIMATION:
case SPI_SETNONCLIENTMETRICS:
case SPI_SETICONMETRICS:
case SPI_SETMINIMIZEDMETRICS:
case SPI_SETWORKAREA:
case SPI_SETFONTSMOOTHING:
case SPI_SETMOUSEHOVERWIDTH:
case SPI_SETMOUSEHOVERHEIGHT:
case SPI_SETMOUSEHOVERTIME:
case SPI_SETWHEELSCROLLLINES:
case SPI_SETMENUSHOWDELAY:
case SPI_SETUSERPREFERENCE:
amRequest = WINSTA_WRITEATTRIBUTES;
break;
case SPI_ICONHORIZONTALSPACING:
case SPI_ICONVERTICALSPACING:
if (HIWORD(lParam)) {
amRequest = WINSTA_READATTRIBUTES;
} else if (wParam) {
amRequest = WINSTA_WRITEATTRIBUTES;
} else
return TRUE;
break;
default:
amRequest = WINSTA_READATTRIBUTES;
break;
}
if (amRequest == WINSTA_READATTRIBUTES) {
RETURN_IF_ACCESS_DENIED(ppi->amwinsta, amRequest, FALSE);
} else {
UserAssert(amRequest == WINSTA_WRITEATTRIBUTES);
if (!CheckWinstaWriteAttributesAccess()) {
return FALSE;
}
}
/*
* If we're reading, then set the write flag to ensure that
* the return value will be TRUE.
*/
if (amRequest == WINSTA_READATTRIBUTES)
fWriteAllowed = TRUE;
} else {
fWriteAllowed = TRUE;
}
/*
* Make sure the section buffer is terminated.
*/
szSection[0] = 0;
switch (wFlag) {
case SPI_GETBEEP:
(*(BOOL *)lParam) = fBeep;
break;
case SPI_SETBEEP:
if (fAlterWinIni) {
ServerLoadString(hModuleWin,
(UINT)(wParam ? STR_BEEPYES : STR_BEEPNO),
(LPWSTR)szTemp, 10);
fWinIniChanged = UT_FastUpdateWinIni(PMAP_BEEP,
(UINT)STR_BEEP, szTemp);
fWriteAllowed = fWinIniChanged;
}
if (fWriteAllowed)
fBeep = wParam;
break;
case SPI_GETMOUSE:
((LPINT)lParam)[0] = MouseThresh1;
((LPINT)lParam)[1] = MouseThresh2;
((LPINT)lParam)[2] = MouseSpeed;
break;
case SPI_SETMOUSE:
if (fAlterWinIni) {
BOOL bWritten1, bWritten2, bWritten3;
wsprintfW(szTemp, pwszd, ((LPINT)lParam)[0]);
bWritten1 = UT_FastUpdateWinIni(PMAP_MOUSE, STR_MOUSETHRESH1, szTemp);
wsprintfW(szTemp, pwszd, ((LPINT)lParam)[1]);
bWritten2 = UT_FastUpdateWinIni(PMAP_MOUSE, STR_MOUSETHRESH2, szTemp);
wsprintfW(szTemp, pwszd, ((LPINT)lParam)[2]);
bWritten3 = UT_FastUpdateWinIni(PMAP_MOUSE, STR_MOUSESPEED, szTemp);
if (bWritten1 && bWritten2 && bWritten3)
fWinIniChanged = TRUE;
else {
/*
* Attempt to backout any changes.
*/
if (bWritten1) {
wsprintfW(szTemp, pwszd, MouseThresh1);
UT_FastUpdateWinIni(PMAP_MOUSE, STR_MOUSETHRESH1, szTemp);
}
if (bWritten2) {
wsprintfW(szTemp, pwszd, MouseThresh2);
UT_FastUpdateWinIni(PMAP_MOUSE, STR_MOUSETHRESH2, szTemp);
}
if (bWritten3) {
wsprintfW(szTemp, pwszd, MouseSpeed);
UT_FastUpdateWinIni(PMAP_MOUSE, STR_MOUSESPEED, szTemp);
}
}
fWriteAllowed = fWinIniChanged;
}
if (fWriteAllowed) {
MouseThresh1 = ((LPINT)lParam)[0];
MouseThresh2 = ((LPINT)lParam)[1];
MouseSpeed = ((LPINT)lParam)[2];
}
break;
case SPI_GETSNAPTODEFBUTTON:
(*(LPBOOL)lParam) = gpsi->fSnapTo;
break;
case SPI_SETSNAPTODEFBUTTON:
wParam = (wParam != 0);
if (fAlterWinIni) {
wsprintfW(szTemp, pwszd, wParam);
fWinIniChanged = UT_FastUpdateWinIni(PMAP_MOUSE,
STR_SNAPTO, szTemp);
fWriteAllowed = fWinIniChanged;
}
if (fWriteAllowed)
gpsi->fSnapTo = (BOOL)wParam;
break;
case SPI_GETBORDER:
(*(LPINT)lParam) = gpsi->gclBorder;
break;
case SPI_SETBORDER:
if (fAlterWinIni) {
wsprintfW(szTemp, pwszd, wParam);
fWinIniChanged = UT_FastUpdateWinIni(PMAP_DESKTOP, STR_BORDERWIDTH, szTemp);
fWriteAllowed = fWinIniChanged;
}
if (fWriteAllowed) {
clBorderOld = gpsi->gclBorder;
clBorderNew = wParam;
if (clBorderNew < 1)
clBorderNew = 1;
else if (clBorderNew > 50)
clBorderNew = 50;
if (clBorderOld == clBorderNew) {
/*
* If border size doesn't change, don't waste time.
*/
break;
}
xxxSetAndDrawNCMetrics(clBorderNew, NULL);
/*
* Nice magic number of 3. So if the border is set to 1, there are actualy
* 4 pixels in the border
*/
bSetDevDragWidth(gpDispInfo->hDev, gpsi->gclBorder + BORDER_EXTRA);
}
break;
case SPI_GETFONTSMOOTHING:
(*(LPINT)lParam) = !!(GreGetFontEnumeration() & FE_AA_ON);
break;
case SPI_SETFONTSMOOTHING:
if (fAlterWinIni) {
wsprintfW(szTemp, pwszd, (wParam ? FE_AA_ON : 0));
fWinIniChanged = UT_FastUpdateWinIni(PMAP_DESKTOP, STR_FONTSMOOTHING, szTemp);
fWriteAllowed = fWinIniChanged;
}
if (fWriteAllowed) {
GreSetFontEnumeration(wParam ? ( FE_AA_ON | FE_SET_AA ) : FE_SET_AA);
}
break;
case SPI_GETKEYBOARDSPEED:
(*(int *)lParam) = (nKeyboardSpeed & KSPEED_MASK);
break;
case SPI_SETKEYBOARDSPEED:
/*
* Limit the range to max value; SetKeyboardRate takes both speed and delay
*/
if (wParam > KSPEED_MASK) // KSPEED_MASK == KSPEED_MAX
wParam = KSPEED_MASK;
if (fAlterWinIni) {
wsprintfW(szTemp, pwszd, wParam);
fWinIniChanged = UT_FastUpdateWinIni(PMAP_KEYBOARD, STR_KEYSPEED, szTemp);
fWriteAllowed = fWinIniChanged;
}
if (fWriteAllowed) {
nKeyboardSpeed = (nKeyboardSpeed & ~KSPEED_MASK) | wParam;
SetKeyboardRate(nKeyboardSpeed);
}
break;
case SPI_GETKEYBOARDDELAY:
(*(int *)lParam) = (nKeyboardSpeed & KDELAY_MASK) >> KDELAY_SHIFT;
break;
case SPI_SETKEYBOARDDELAY:
if (fAlterWinIni) {
wsprintfW(szTemp, pwszd, wParam);
fWinIniChanged = UT_FastUpdateWinIni(PMAP_KEYBOARD, STR_KEYDELAY, szTemp);
fWriteAllowed = fWinIniChanged;
}
if (fWriteAllowed) {
nKeyboardSpeed = (nKeyboardSpeed & ~KDELAY_MASK) | (wParam << KDELAY_SHIFT);
SetKeyboardRate(nKeyboardSpeed);
}
break;
case SPI_SETLANGTOGGLE:
/*
* wParam unused, lParam unused. Simply reread the registry setting.
*/
return GetKbdLangSwitch();
break;
case SPI_GETDEFAULTINPUTLANG:
/*
* wParam unused. lParam is a pointer to buffer to store hkl.
*/
UserAssert(gspklBaseLayout != NULL);
(*(HKL *)lParam) = gspklBaseLayout->hkl;
break;
case SPI_SETDEFAULTINPUTLANG: {
PKL pkl;
/*
* wParam unused. lParam is new language of hkl (depending on whether the
* hiword is set.
*/
pkl = HKLtoPKL(*(HKL *)lParam);
if (pkl == NULL) {
return FALSE;
}
if (fWriteAllowed) {
Lock(&gspklBaseLayout, pkl);
}
break;
}
case SPI_ICONHORIZONTALSPACING:
if (HIWORD(lParam)) {
*(LPINT)lParam = SYSMET(CXICONSPACING);
} else if (wParam) {
/*
* Make sure icon spacing is reasonable.
*/
wParam = max(wParam, (DWORD)SYSMET(CXICON));
if (fAlterWinIni) {
wsprintfW(szTemp, pwszd, wParam);
fWinIniChanged = UT_FastUpdateWinIni(PMAP_DESKTOP, STR_ICONHORZSPACING,
szTemp);
fWriteAllowed = fWinIniChanged;
}
if (fWriteAllowed) {
SYSMET(CXICONSPACING) = (UINT)wParam;
}
}
break;
case SPI_ICONVERTICALSPACING:
if (HIWORD(lParam)) {
*(LPINT)lParam = SYSMET(CYICONSPACING);
} else if (wParam) {
wParam = max(wParam, (DWORD)SYSMET(CYICON));
if (fAlterWinIni) {
wsprintfW(szTemp, pwszd, wParam);
fWinIniChanged = UT_FastUpdateWinIni(PMAP_DESKTOP,
STR_ICONVERTSPACING, szTemp);
fWriteAllowed = fWinIniChanged;
}
if (fWriteAllowed) {
SYSMET(CYICONSPACING) = (UINT)wParam;
}
}
break;
case SPI_GETSCREENSAVETIMEOUT:
/*
* If the screen saver is disabled, I store this fact as a negative
* time out value. So, we give the Control Panel the absolute value
* of the screen save time out.
*/
if (iScreenSaveTimeOut < 0)
(*(int *)lParam) = -iScreenSaveTimeOut;
else
(*(int *)lParam) = iScreenSaveTimeOut;
break;
case SPI_SETSCREENSAVETIMEOUT:
/*
* Maintain the screen save active/inactive state when setting the
* time out value. Timeout value is given in seconds.
*/
if (fAlterWinIni) {
wsprintfW(szTemp, pwszd, wParam);
fWinIniChanged = UT_FastUpdateWinIni(PMAP_DESKTOP,
STR_SCREENSAVETIMEOUT, szTemp);
fWriteAllowed = fWinIniChanged;
}
if (fWriteAllowed) {
timeLastInputMessage = NtGetTickCount();
if (iScreenSaveTimeOut < 0)
iScreenSaveTimeOut = -((int)wParam);
else
iScreenSaveTimeOut = wParam;
}
break;
case SPI_GETSCREENSAVEACTIVE:
(*(BOOL *)lParam) = (iScreenSaveTimeOut > 0);
break;
case SPI_SETSCREENSAVEACTIVE:
if (fAlterWinIni) {
wsprintfW(szTemp, pwszd, (wParam ? 1 : 0));
fWinIniChanged = UT_FastUpdateWinIni(PMAP_DESKTOP, STR_SCREENSAVEACTIVE, szTemp);
fWriteAllowed = fWinIniChanged;
}
if (fWriteAllowed) {
timeLastInputMessage = NtGetTickCount();
if ((iScreenSaveTimeOut < 0 && wParam) ||
(iScreenSaveTimeOut >= 0 && !wParam)) {
iScreenSaveTimeOut = -iScreenSaveTimeOut;
}
}
break;
case SPI_SETDESKWALLPAPER:
if (fAlterWinIni) {
if (wParam != (WPARAM)-1) {
WCHAR wszWallpaper[20];
/*
* Save current wallpaper in case of failure.
*/
ServerLoadString(hModuleWin,
STR_DTBITMAP,
wszWallpaper,
sizeof(wszWallpaper));
UT_FastGetProfileStringW(PMAP_DESKTOP,
wszWallpaper,
TEXT(""),
szPat,
MAX_PATH);
fWinIniChanged = UT_FastUpdateWinIni(PMAP_DESKTOP,
STR_DTBITMAP,
(LPWSTR)lParam);
fWriteAllowed = fWinIniChanged;
} else {
fWriteAllowed = TRUE;
}
}
if (fWriteAllowed) {
if (xxxSetDeskWallpaper((LPWSTR)lParam)) {
if (grpdeskRitInput) {
xxxInternalInvalidate(grpdeskRitInput->pDeskInfo->spwnd,
MAXREGION,
RDW_INVALIDATE |
RDW_ERASE |
RDW_FRAME |
RDW_ALLCHILDREN);
}
} else if (fAlterWinIni && (wParam != 0xFFFFFFFF)) {
/*
* Backout any change to win.ini.
*/
UT_FastUpdateWinIni(PMAP_DESKTOP, STR_DTBITMAP, szPat);
fWinIniChanged = FALSE;
}
}
break;
case SPI_SETDESKPATTERN: {
BOOL fRet;
if (wParam == -1 && lParam != 0)
return FALSE;
if (fAlterWinIni && wParam != -1) {
WCHAR wszDeskPattern[20];
/*
* Save the current pattern in case of failure.
*/
ServerLoadString(
hModuleWin,
STR_DESKPATTERN,
wszDeskPattern,
sizeof(wszDeskPattern) / sizeof(WCHAR));
UT_FastGetProfileStringW(
PMAP_DESKTOP,
wszDeskPattern,
TEXT(""),
szPat,
MAX_PATH);
fWinIniChanged = UT_FastUpdateWinIni(
PMAP_DESKTOP,
STR_DESKPATTERN,
(LPWSTR)lParam);
fWriteAllowed = fWinIniChanged;
}
if (fWriteAllowed) {
fRet = xxxSetDeskPattern(
wParam == -1 ? (LPWSTR)-1 : (LPWSTR)lParam,
FALSE);
if (!fRet) {
/*
* Back out any change to win.ini
*/
if (fAlterWinIni && wParam != -1) {
UT_FastUpdateWinIni(
PMAP_DESKTOP,
STR_DESKPATTERN,
szPat);
}
return FALSE;
}
}
}
break;
case SPI_GETICONTITLEWRAP:
*((int *)lParam) = (int)fIconTitleWrap;
break;
case SPI_SETICONTITLEWRAP:
wParam = (wParam != 0);
if (fAlterWinIni) {
wsprintfW(szTemp, pwszd, wParam);
fWinIniChanged = UT_FastUpdateWinIni(PMAP_DESKTOP,
STR_ICONTITLEWRAP, szTemp);
fWriteAllowed = fWinIniChanged;
}
if (fWriteAllowed) {
fIconTitleWrap = wParam;
xxxMetricsRecalc(CALC_FRAME, 0, 0, 0, 0);
}
break;
case SPI_SETDRAGWIDTH:
if (fAlterWinIni) {
wsprintfW(szTemp, pwszd, wParam);
fWinIniChanged = UT_FastUpdateWinIni(PMAP_DESKTOP, STR_DRAGWIDTH, szTemp);
fWriteAllowed = fWinIniChanged;
}
if (fWriteAllowed) {
SYSMET(CXDRAG) = wParam;
}
break;
case SPI_SETDRAGHEIGHT:
if (fAlterWinIni) {
wsprintfW(szTemp, pwszd, wParam);
fWinIniChanged = UT_FastUpdateWinIni(PMAP_DESKTOP, STR_DRAGHEIGHT, szTemp);
fWriteAllowed = fWinIniChanged;
}
if (fWriteAllowed) {
SYSMET(CYDRAG) = wParam;
}
break;
case SPI_GETMENUDROPALIGNMENT:
(*(int *)lParam) = (SYSMET(MENUDROPALIGNMENT));
break;
case SPI_SETMENUDROPALIGNMENT:
if (fAlterWinIni) {
wsprintfW(szTemp, pwszd, wParam);
fWinIniChanged = UT_FastUpdateWinIni(PMAP_WINDOWSU,
STR_MENUDROPALIGNMENT, szTemp);
fWriteAllowed = fWinIniChanged;
}
if (fWriteAllowed) {
SYSMET(MENUDROPALIGNMENT) = (BOOL)(wParam != 0);
}
break;
case SPI_SETDOUBLECLKWIDTH:
if (fAlterWinIni) {
wsprintfW(szTemp, pwszd, wParam);
fWinIniChanged = UT_FastUpdateWinIni(PMAP_MOUSE,
STR_DOUBLECLICKWIDTH, szTemp);
fWriteAllowed = fWinIniChanged;
}
if (fWriteAllowed) {
SYSMET(CXDOUBLECLK) = wParam;
}
break;
case SPI_SETDOUBLECLKHEIGHT:
if (fAlterWinIni) {
wsprintfW(szTemp, pwszd, wParam);
fWinIniChanged = UT_FastUpdateWinIni(PMAP_MOUSE,
STR_DOUBLECLICKHEIGHT, szTemp);
fWriteAllowed = fWinIniChanged;
}
if (fWriteAllowed) {
SYSMET(CYDOUBLECLK) = wParam;
}
break;
case SPI_GETICONTITLELOGFONT:
GreExtGetObjectW(ghIconFont, sizeof(LOGFONTW), lParam);
break;
case SPI_SETICONTITLELOGFONT:
if (lParam != NULL) {
if (wParam != sizeof(LOGFONTW))
return FALSE;
} else if (wParam) {
return FALSE;
}
fWinIniChanged = xxxSetSPIMetrics(wFlag, lParam, fAlterWinIni);
if (fAlterWinIni) {
fWriteAllowed = fWinIniChanged;
}
break;
case SPI_SETDOUBLECLICKTIME:
if (fAlterWinIni) {
wsprintfW(szTemp, pwszd, wParam);
fWinIniChanged = UT_FastUpdateWinIni(PMAP_MOUSE,
STR_DBLCLKSPEED, szTemp);
fWriteAllowed = fWinIniChanged;
}
if (fWriteAllowed) {
_SetDoubleClickTime((UINT)wParam);
}
break;
case SPI_GETANIMATION: {
LPANIMATIONINFO lpai = (LPANIMATIONINFO) lParam;
if (lpai == NULL || (wParam != sizeof(ANIMATIONINFO)))
return(FALSE);
lpai->cbSize = sizeof(ANIMATIONINFO);
lpai->iMinAnimate = gfAnimate;
break;
}
case SPI_GETNONCLIENTMETRICS: {
LPNONCLIENTMETRICS lpnc = (LPNONCLIENTMETRICS) lParam;
if (lpnc == NULL)
return FALSE;
GetWindowNCMetrics(lpnc);
break;
}
case SPI_GETMINIMIZEDMETRICS: {
LPMINIMIZEDMETRICS lpmin = (LPMINIMIZEDMETRICS)lParam;
lpmin->cbSize = sizeof(MINIMIZEDMETRICS);
lpmin->iWidth = SYSMET(CXMINIMIZED) - 2*SYSMET(CXFIXEDFRAME);
lpmin->iHorzGap = SYSMET(CXMINSPACING) - SYSMET(CXMINIMIZED);
lpmin->iVertGap = SYSMET(CYMINSPACING) - SYSMET(CYMINIMIZED);
lpmin->iArrange = SYSMET(ARRANGE);
break;
}
case SPI_GETICONMETRICS: {
LPICONMETRICS lpicon = (LPICONMETRICS)lParam;
lpicon->cbSize = sizeof(ICONMETRICS);
lpicon->iHorzSpacing = SYSMET(CXICONSPACING);
lpicon->iVertSpacing = SYSMET(CYICONSPACING);
lpicon->iTitleWrap = fIconTitleWrap;
GreExtGetObjectW(ghIconFont, sizeof(LOGFONTW), &(lpicon->lfFont));
break;
}
case SPI_SETANIMATION:
case SPI_SETNONCLIENTMETRICS:
case SPI_SETICONMETRICS:
case SPI_SETMINIMIZEDMETRICS:
fWinIniChanged = xxxSetSPIMetrics(wFlag, lParam, fAlterWinIni);
if (fAlterWinIni) {
fWriteAllowed = fWinIniChanged;
}
ServerLoadString(hModuleWin, STR_METRICS, szSection, sizeof(szSection));
break;
case SPI_SETMOUSEBUTTONSWAP:
if (fAlterWinIni) {
wsprintfW(szTemp, pwszd, wParam);
fWinIniChanged = UT_FastUpdateWinIni(PMAP_MOUSE,
STR_SWAPBUTTONS, szTemp);
fWriteAllowed = fWinIniChanged;
}
if (fWriteAllowed) {
_SwapMouseButton((wParam != 0));
}
break;
case SPI_GETFASTTASKSWITCH:
*((PINT)lParam) = TRUE; // do the work so we don't screw anybody
case SPI_SETFASTTASKSWITCH:
RIPMSG0(RIP_WARNING,"SPI_SETFASTTASKSWITCH and SPI_GETFASTTASKSWITCH are obsolete actions.");
break;
case SPI_GETWORKAREA:
CopyRect((LPRECT)lParam, &(gpsi->rcWork));
break;
case SPI_SETWORKAREA: {
RECT rcOldWork;
LPRECT prcNewWork = (LPRECT)lParam;
/*
* Validate Rectangle
*/
if ((prcNewWork != NULL) &&
((prcNewWork->right < prcNewWork->left) ||
(prcNewWork->bottom < prcNewWork->top))) {
RIPMSG0(RIP_WARNING, "Bad work rectangle passed to SystemParametersInfo()\n");
return FALSE;
}
/*
* Save old working area
*/
CopyRect(&rcOldWork, &(gpsi->rcWork));
/*
* Get new working area
*/
if (prcNewWork == NULL || IsRectEmpty(prcNewWork)) {
CopyRect(&(gpsi->rcWork), &gpDispInfo->rcScreen);
} else {
IntersectRect(&(gpsi->rcWork), prcNewWork, &gpDispInfo->rcScreen);
}
/*
* Recalculate desktop-dependent values
*/
if (!EqualRect(&rcOldWork, &(gpsi->rcWork))) {
SetDesktopMetrics();
/*
* Reposition windows
*/
if (wParam)
DesktopRecalc(&rcOldWork, &(gpsi->rcWork), FALSE);
fWinIniChanged = TRUE;
}
fWriteAllowed = TRUE;
break;
}
case SPI_SETDRAGFULLWINDOWS:
if (fAlterWinIni) {
wsprintfW(szTemp, pwszd, (wParam == 1));
fWinIniChanged = UT_FastUpdateWinIni(PMAP_DESKTOP,
STR_DRAGFULLWINDOWS, szTemp);
fWriteAllowed = fWinIniChanged;
}
if (fWriteAllowed) {
fDragFullWindows = (wParam == 1);
}
break;
case SPI_GETDRAGFULLWINDOWS:
{
PINT pint = (int *)lParam;
*pint = fDragFullWindows;
}
break;
case SPI_GETFILTERKEYS:
{
LPFILTERKEYS pFK = (LPFILTERKEYS)lParam;
int cbSkip = sizeof(gFilterKeys.cbSize);
if ((wParam != 0) && (wParam != sizeof(FILTERKEYS))) {
return FALSE;
}
if (!pFK || (pFK->cbSize != sizeof(FILTERKEYS))) {
return FALSE;
}
/*
* In the future we may support multiple sizes of this data structure. Don't
* change the cbSize field of the data structure passed in.
*/
RtlCopyMemory((LPVOID)((LPBYTE)pFK + cbSkip),
(LPVOID)((LPBYTE)&gFilterKeys + cbSkip),
pFK->cbSize - cbSkip);
}
break;
case SPI_SETFILTERKEYS:
{
LPFILTERKEYS pFK = (LPFILTERKEYS)lParam;
if ((wParam != 0) && (wParam != sizeof(FILTERKEYS))) {
return FALSE;
}
if (!pFK || (pFK->cbSize != sizeof(FILTERKEYS)))
return FALSE;
/*
* SlowKeys and BounceKeys cannot both be active simultaneously
*/
if (pFK->iWaitMSec && pFK->iBounceMSec) {
return FALSE;
}
/*
* Do some parameter validation. We will fail on unsupported and
* undefined bits being set.
*/
if ((pFK->dwFlags & FKF_VALID) != pFK->dwFlags) {
return FALSE;
}
/*
* FKF_AVAILABLE can't be set via API. Use registry value.
*/
if (ISACCESSFLAGSET(gFilterKeys, FKF_AVAILABLE)) {
pFK->dwFlags |= FKF_AVAILABLE;
} else {
pFK->dwFlags &= ~FKF_AVAILABLE;
}
if ((pFK->iWaitMSec > 2000) ||
(pFK->iDelayMSec > 2000) ||
(pFK->iRepeatMSec > 2000) ||
(pFK->iBounceMSec > 2000)) {
return FALSE;
}
if (fAlterWinIni) {
fWinIniChanged = SetFilterKeys(pFK);
fWriteAllowed = fWinIniChanged;
if (!fWinIniChanged) {
/*
* Back out any changes to win.ini
*/
SetFilterKeys(&gFilterKeys);
}
}
if (fWriteAllowed) {
RtlCopyMemory(&gFilterKeys, pFK, pFK->cbSize);
/*
* Don't allow user to change cbSize field
*/
gFilterKeys.cbSize = sizeof(FILTERKEYS);
if (!ISACCESSFLAGSET(gFilterKeys, FKF_FILTERKEYSON)) {
StopFilterKeysTimers();
}
SetAccessEnabledFlag();
}
}
break;
case SPI_GETSTICKYKEYS:
{
LPSTICKYKEYS pSK = (LPSTICKYKEYS)lParam;
int cbSkip = sizeof(gStickyKeys.cbSize);
if ((wParam != 0) && (wParam != sizeof(STICKYKEYS))) {
return FALSE;
}
if (!pSK || (pSK->cbSize != sizeof(STICKYKEYS))) {
return FALSE;
}
/*
* In the future we may support multiple sizes of this data structure. Don't
* change the cbSize field of the data structure passed in.
*/
RtlCopyMemory((LPVOID)((LPBYTE)pSK + cbSkip),
(LPVOID)((LPBYTE)&gStickyKeys + cbSkip),
pSK->cbSize - cbSkip);
}
break;
case SPI_SETSTICKYKEYS:
{
LPSTICKYKEYS pSK = (LPSTICKYKEYS)lParam;
BOOL fWasOn;
fWasOn = ISACCESSFLAGSET(gStickyKeys, SKF_STICKYKEYSON);
if ((wParam != 0) && (wParam != sizeof(STICKYKEYS))) {
return FALSE;
}
if (!pSK || (pSK->cbSize != sizeof(STICKYKEYS)))
return FALSE;
/*
* Do some parameter validation. We will fail on unsupported and
* undefined bits being set.
*/
if ((pSK->dwFlags & SKF_VALID) != pSK->dwFlags) {
return FALSE;
}
/*
* SKF_AVAILABLE can't be set via API. Use registry value.
*/
if (ISACCESSFLAGSET(gStickyKeys, SKF_AVAILABLE)) {
pSK->dwFlags |= SKF_AVAILABLE;
} else {
pSK->dwFlags &= ~SKF_AVAILABLE;
}
if (fAlterWinIni) {
wsprintfW(szTemp, pwszd, pSK->dwFlags);
fWinIniChanged = UT_FastWriteProfileStringW(
PMAP_STICKYKEYS,
L"Flags",
szTemp);
fWriteAllowed = fWinIniChanged;
}
if (fWriteAllowed) {
RtlCopyMemory(&gStickyKeys, pSK, pSK->cbSize);
/*
* Don't allow user to change cbSize field
*/
gStickyKeys.cbSize = sizeof(STICKYKEYS);
if (!ISACCESSFLAGSET(gStickyKeys, SKF_STICKYKEYSON) && fWasOn) {
LeaveCrit();
TurnOffStickyKeys();
EnterCrit();
}
SetAccessEnabledFlag();
}
}
break;
case SPI_GETTOGGLEKEYS:
{
LPTOGGLEKEYS pTK = (LPTOGGLEKEYS)lParam;
int cbSkip = sizeof(gToggleKeys.cbSize);
if ((wParam != 0) && (wParam != sizeof(TOGGLEKEYS))) {
return FALSE;
}
if (!pTK || (pTK->cbSize != sizeof(TOGGLEKEYS))) {
return FALSE;
}
/*
* In the future we may support multiple sizes of this data structure. Don't
* change the cbSize field of the data structure passed in.
*/
RtlCopyMemory((LPVOID)((LPBYTE)pTK + cbSkip),
(LPVOID)((LPBYTE)&gToggleKeys + cbSkip),
pTK->cbSize - cbSkip);
}
break;
case SPI_SETTOGGLEKEYS:
{
LPTOGGLEKEYS pTK = (LPTOGGLEKEYS)lParam;
if ((wParam != 0) && (wParam != sizeof(TOGGLEKEYS))) {
return FALSE;
}
if (!pTK || (pTK->cbSize != sizeof(TOGGLEKEYS)))
return FALSE;
/*
* Do some parameter validation. We will fail on unsupported and
* undefined bits being set.
*/
if ((pTK->dwFlags & TKF_VALID) != pTK->dwFlags) {
return FALSE;
}
/*
* TKF_AVAILABLE can't be set via API. Use registry value.
*/
if (ISACCESSFLAGSET(gToggleKeys, TKF_AVAILABLE)) {
pTK->dwFlags |= TKF_AVAILABLE;
} else {
pTK->dwFlags &= ~TKF_AVAILABLE;
}
if (fAlterWinIni) {
wsprintfW(szTemp, pwszd, pTK->dwFlags);
fWinIniChanged = UT_FastWriteProfileStringW(
PMAP_TOGGLEKEYS,
L"Flags",
szTemp);
fWriteAllowed = fWinIniChanged;
}
if (fWriteAllowed) {
RtlCopyMemory(&gToggleKeys, pTK, pTK->cbSize);
/*
* Don't allow user to change cbSize field
*/
gToggleKeys.cbSize = sizeof(TOGGLEKEYS);
SetAccessEnabledFlag();
}
}
break;
case SPI_GETMOUSEKEYS:
{
LPMOUSEKEYS pMK = (LPMOUSEKEYS)lParam;
int cbSkip = sizeof(gMouseKeys.cbSize);
if ((wParam != 0) && (wParam != sizeof(MOUSEKEYS))) {
return FALSE;
}
if (!pMK || (pMK->cbSize != sizeof(MOUSEKEYS))) {
return FALSE;
}
/*
* In the future we may support multiple sizes of this data structure. Don't
* change the cbSize field of the data structure passed in.
*/
RtlCopyMemory((LPVOID)((LPBYTE)pMK + cbSkip),
(LPVOID)((LPBYTE)&gMouseKeys + cbSkip),
pMK->cbSize - cbSkip);
}
break;
case SPI_SETMOUSEKEYS: {
LPMOUSEKEYS pMK = (LPMOUSEKEYS)lParam;
if ((wParam != 0) && (wParam != sizeof(MOUSEKEYS))) {
return FALSE;
}
if (!pMK || (pMK->cbSize != sizeof(MOUSEKEYS)))
return FALSE;
/*
* Do some parameter validation. We will fail on unsupported and
* undefined bits being set.
*/
if ((pMK->dwFlags & MKF_VALID) != pMK->dwFlags) {
return FALSE;
}
/*
* MKF_AVAILABLE can't be set via API. Use registry value.
*/
if (ISACCESSFLAGSET(gMouseKeys, MKF_AVAILABLE)) {
pMK->dwFlags |= MKF_AVAILABLE;
} else {
pMK->dwFlags &= ~MKF_AVAILABLE;
}
if ((pMK->iMaxSpeed < 10) || (pMK->iMaxSpeed > 360)) {
return FALSE;
}
if ((pMK->iTimeToMaxSpeed < 1000) || (pMK->iTimeToMaxSpeed > 5000)) {
return FALSE;
}
if (fAlterWinIni) {
fWinIniChanged = SetMouseKeys(pMK);
fWriteAllowed = fWinIniChanged;
if (!fWinIniChanged) {
/*
* Back out any changes to win.ini
*/
SetMouseKeys(&gMouseKeys);
}
}
if (fWriteAllowed) {
RtlCopyMemory(&gMouseKeys, pMK, pMK->cbSize);
/*
* Don't allow user to change cbSize field
*/
gMouseKeys.cbSize = sizeof(MOUSEKEYS);
CalculateMouseTable();
if (ISACCESSFLAGSET(gMouseKeys, MKF_MOUSEKEYSON)) {
MKShowMouseCursor();
} else
MKHideMouseCursor();
SetAccessEnabledFlag();
}
}
break;
case SPI_GETACCESSTIMEOUT:
{
LPACCESSTIMEOUT pTO = (LPACCESSTIMEOUT)lParam;
int cbSkip = sizeof(gAccessTimeOut.cbSize);
if ((wParam != 0) && (wParam != sizeof(ACCESSTIMEOUT))) {
return FALSE;
}
if (!pTO || (pTO->cbSize != sizeof(ACCESSTIMEOUT))) {
return FALSE;
}
/*
* In the future we may support multiple sizes of this data structure. Don't
* change the cbSize field of the data structure passed in.
*/
RtlCopyMemory((LPVOID)((LPBYTE)pTO + cbSkip),
(LPVOID)((LPBYTE)&gAccessTimeOut + cbSkip),
pTO->cbSize - cbSkip);
}
break;
case SPI_SETACCESSTIMEOUT:
{
LPACCESSTIMEOUT pTO = (LPACCESSTIMEOUT)lParam;
if ((wParam != 0) && (wParam != sizeof(ACCESSTIMEOUT))) {
return FALSE;
}
if (!pTO || (pTO->cbSize != sizeof(ACCESSTIMEOUT)))
return FALSE;
/*
* Do some parameter validation. We will fail on unsupported and
* undefined bits being set.
*/
if ((pTO->dwFlags & ATF_VALID) != pTO->dwFlags) {
return FALSE;
}
if (pTO->iTimeOutMSec > 3600000) {
return FALSE;
}
if (fAlterWinIni) {
wsprintfW(szTemp, pwszd, pTO->dwFlags);
fWinIniChanged = UT_FastWriteProfileStringW(
PMAP_TIMEOUT,
L"Flags",
szTemp);
wsprintfW(szTemp, pwszd, pTO->iTimeOutMSec);
fWinIniChanged = UT_FastWriteProfileStringW(
PMAP_TIMEOUT,
L"TimeToWait",
szTemp);
fWriteAllowed = fWinIniChanged;
if (!fWinIniChanged) {
/*
* Back out any changes to win.ini
*/
wsprintfW(szTemp, pwszd, gAccessTimeOut.dwFlags);
fWinIniChanged = UT_FastWriteProfileStringW(
PMAP_TIMEOUT,
L"Flags",
szTemp);
wsprintfW(szTemp, pwszd, gAccessTimeOut.iTimeOutMSec);
fWinIniChanged = UT_FastWriteProfileStringW(
PMAP_TIMEOUT,
L"TimeToWait",
szTemp);
}
}
if (fWriteAllowed) {
RtlCopyMemory(&gAccessTimeOut, pTO, pTO->cbSize);
/*
* Don't allow user to change cbSize field
*/
gAccessTimeOut.cbSize = sizeof(ACCESSTIMEOUT);
SetAccessEnabledFlag();
AccessTimeOutReset();
}
}
break;
case SPI_SETSHOWSOUNDS:
if (fAlterWinIni) {
wsprintfW(szTemp, pwszd, (wParam == 1));
fWinIniChanged = UT_FastWriteProfileStringW(
PMAP_SHOWSOUNDS,
L"On",
szTemp);
fWriteAllowed = fWinIniChanged;
}
if (fWriteAllowed) {
fShowSoundsOn = (wParam == 1);
SetAccessEnabledFlag();
/*
* Bug 2079. Update the System Metrics Info.
*/
SYSMET(SHOWSOUNDS) = fShowSoundsOn;
}
break;
case SPI_GETSHOWSOUNDS: {
PINT pint = (int *)lParam;
*pint = fShowSoundsOn;
}
break;
case SPI_GETSOUNDSENTRY:
{
LPSOUNDSENTRY pSS = (LPSOUNDSENTRY)lParam;
int cbSkip = sizeof(gSoundSentry.cbSize);
if ((wParam != 0) && (wParam != sizeof(SOUNDSENTRY))) {
return FALSE;
}
if (!pSS || (pSS->cbSize != sizeof(SOUNDSENTRY))) {
return FALSE;
}
/*
* In the future we may support multiple sizes of this data structure. Don't
* change the cbSize field of the data structure passed in.
*/
RtlCopyMemory((LPVOID)((LPBYTE)pSS + cbSkip),
(LPVOID)((LPBYTE)&gSoundSentry + cbSkip),
pSS->cbSize - cbSkip);
}
break;
case SPI_SETSOUNDSENTRY:
{
LPSOUNDSENTRY pSS = (LPSOUNDSENTRY)lParam;
if ((wParam != 0) & (wParam != sizeof(SOUNDSENTRY))) {
return FALSE;
}
if (!pSS || (pSS->cbSize != sizeof(SOUNDSENTRY)))
return FALSE;
/*
* Do some parameter validation. We will fail on unsupported and
* undefined bits being set.
*/
if ((pSS->dwFlags & SSF_VALID) != pSS->dwFlags) {
return FALSE;
}
/*
* We don't support SSWF_CUSTOM.
*/
if (pSS->iWindowsEffect > SSWF_DISPLAY) {
return FALSE;
}
/*
* No support for non-windows apps.
*/
if (pSS->iFSTextEffect != SSTF_NONE) {
return FALSE;
}
if (pSS->iFSGrafEffect != SSGF_NONE) {
return FALSE;
}
/*
* SSF_AVAILABLE can't be set via API. Use registry value.
*/
if (ISACCESSFLAGSET(gSoundSentry, SSF_AVAILABLE)) {
pSS->dwFlags |= SSF_AVAILABLE;
} else {
pSS->dwFlags &= ~SSF_AVAILABLE;
}
if (fAlterWinIni) {
fWinIniChanged = SetSoundSentry(pSS);
fWriteAllowed = fWinIniChanged;
if (!fWinIniChanged) {
/*
* Back out any changes to win.ini
*/
SetSoundSentry(&gSoundSentry);
}
}
if (fWriteAllowed) {
RtlCopyMemory(&gSoundSentry, pSS, pSS->cbSize);
/*
* Don't allow user to change cbSize field
*/
gSoundSentry.cbSize = sizeof(SOUNDSENTRY);
SetAccessEnabledFlag();
}
}
break;
case SPI_SETCURSORS:
UpdateSystemCursorsFromRegistry();
break;
case SPI_SETICONS:
UpdateSystemIconsFromRegistry();
break;
case SPI_GETMOUSEHOVERWIDTH:
*((UINT *)lParam) = gcxMouseHover;
break;
case SPI_SETMOUSEHOVERWIDTH:
if (fAlterWinIni) {
wsprintfW(szTemp, pwszd, wParam);
fWinIniChanged = UT_FastUpdateWinIni(PMAP_MOUSE,
STR_MOUSEHOVERWIDTH, szTemp);
fWriteAllowed = fWinIniChanged;
}
if (fWriteAllowed) {
gcxMouseHover = wParam;
}
break;
case SPI_GETMOUSEHOVERHEIGHT:
*((UINT *)lParam) = gcyMouseHover;
break;
case SPI_SETMOUSEHOVERHEIGHT:
if (fAlterWinIni) {
wsprintfW(szTemp, pwszd, wParam);
fWinIniChanged = UT_FastUpdateWinIni(PMAP_MOUSE,
STR_MOUSEHOVERHEIGHT, szTemp);
fWriteAllowed = fWinIniChanged;
}
if (fWriteAllowed) {
gcyMouseHover = wParam;
}
break;
case SPI_GETMOUSEHOVERTIME:
*((UINT *)lParam) = gdtMouseHover;
break;
case SPI_SETMOUSEHOVERTIME:
if (fAlterWinIni) {
wsprintfW(szTemp, pwszd, wParam);
fWinIniChanged = UT_FastUpdateWinIni(PMAP_MOUSE,
STR_MOUSEHOVERTIME, szTemp);
fWriteAllowed = fWinIniChanged;
}
if (fWriteAllowed) {
gdtMouseHover = wParam;
}
break;
case SPI_GETWHEELSCROLLLINES:
(*(LPDWORD)lParam) = gpsi->ucWheelScrollLines;
break;
case SPI_SETWHEELSCROLLLINES:
if (fAlterWinIni) {
wsprintfW(szTemp, pwszd, wParam);
fWinIniChanged = UT_FastUpdateWinIni(
PMAP_DESKTOP, STR_WHEELSCROLLLINES, szTemp);
fWriteAllowed = fWinIniChanged;
}
if (fWriteAllowed)
gpsi->ucWheelScrollLines = (BOOL)wParam;
break;
case SPI_GETMENUSHOWDELAY:
(*(LPDWORD)lParam) = dtMNDropDown;
break;
case SPI_SETMENUSHOWDELAY:
if (fAlterWinIni) {
wsprintfW(szTemp, pwszd, wParam);
fWinIniChanged = UT_FastUpdateWinIni(PMAP_DESKTOP,
STR_MENUSHOWDELAY, szTemp);
fWriteAllowed = fWinIniChanged;
}
if (fWriteAllowed)
dtMNDropDown = wParam;
break;
case SPI_GETUSERPREFERENCE:
(*(LPDWORD)lParam) = (gpviCPUserPreferences + wParam)->dwValue;
break;
case SPI_SETUSERPREFERENCE:
{
PPROFILEVALUEINFO ppvi = gpviCPUserPreferences + wParam;
if (fAlterWinIni) {
fWinIniChanged = UT_FastWriteProfileValue(ppvi->uSection,
ppvi->pwszKeyName, REG_DWORD,
(LPBYTE)&lParam, sizeof (DWORD));
fWriteAllowed = fWinIniChanged;
}
if (fWriteAllowed) {
ppvi->dwValue = (UINT)lParam;
}
}
break;
default:
RIPERR0(ERROR_INVALID_SPI_VALUE, RIP_VERBOSE, "");
return FALSE;
}
if (fWinIniChanged && fSendWinIniChange) {
DWORD dwResult;
/*
* dwResult is defined so that xxxSendMessageTimeout will really
* and truly do a timeout. Yeah, I know, this is a hack, but,
* it is compatible.
*/
RtlInitLargeUnicodeString(&strSection, szSection, (UINT)-1);
xxxSendMessageTimeout((PWND)-1, WM_SETTINGCHANGE, wFlag, (long)&strSection,
SMTO_NORMAL, 100, &dwResult);
}
return fWriteAllowed;
}
/***************************************************************************\
* _RegisterShellHookWindow
*
* History:
\***************************************************************************/
BOOL _RegisterShellHookWindow(PWND pwnd) {
PWND *ppwnd;
int i;
PDESKTOPINFO pdeskinfo;
if (pwnd->head.rpdesk == NULL)
return FALSE;
pdeskinfo = pwnd->head.rpdesk->pDeskInfo;
if (pdeskinfo->papwndShellHook == NULL) {
ppwnd = (PWND *)UserAllocPool(sizeof(PWND), TAG_SHELL);
} else {
DWORD dwSize;
ppwnd = pdeskinfo->papwndShellHook;
for (i=0;i<pdeskinfo->nShellHookPwnd;i++) {
if (pwnd == ppwnd[i]) return FALSE;
}
dwSize = pdeskinfo->nShellHookPwnd * sizeof(PWND);
ppwnd = (PWND *)UserReAllocPool(pdeskinfo->papwndShellHook,
dwSize, dwSize + sizeof(PWND), TAG_SHELL);
}
if (ppwnd == NULL) return FALSE;
ppwnd[pdeskinfo->nShellHookPwnd] = NULL; // clear new entry
Lock(ppwnd + pdeskinfo->nShellHookPwnd,pwnd);
pdeskinfo->nShellHookPwnd++;
pdeskinfo->papwndShellHook = ppwnd;
SetWF(pwnd,WFSHELLHOOKWND);
return TRUE;
}
/***************************************************************************\
* _DeregisterShellHookWindow
*
* History:
\***************************************************************************/
void _DeregisterShellHookWindow(PWND pwnd) {
PWND *ppwnd;
int i, i1;
PDESKTOPINFO pdeskinfo;
if (pwnd->head.rpdesk == NULL)
return;
pdeskinfo = pwnd->head.rpdesk->pDeskInfo;
pdeskinfo = pwnd->head.rpdesk->pDeskInfo;
i1 = -1;
ppwnd = pdeskinfo->papwndShellHook;
for (i = 0; i < pdeskinfo->nShellHookPwnd; i++) {
if (pwnd == ppwnd[i]) {
i1 = i;
ClrWF(pwnd, WFSHELLHOOKWND);
Unlock(ppwnd + i);
break;
}
}
if (i1 == -1) return;
pdeskinfo->nShellHookPwnd--;
if (i1 < pdeskinfo->nShellHookPwnd) {
ppwnd[i1] = ppwnd[pdeskinfo->nShellHookPwnd];
}
if (pdeskinfo->nShellHookPwnd) {
DWORD dwSize = pdeskinfo->nShellHookPwnd * sizeof(PWND);
ppwnd = (PWND *)UserReAllocPool(pdeskinfo->papwndShellHook,
dwSize, dwSize, TAG_SHELL);
if (ppwnd == NULL) return;
pdeskinfo->papwndShellHook = ppwnd;
} else {
UserFreePool(pdeskinfo->papwndShellHook);
pdeskinfo->papwndShellHook = NULL;
}
}
/***************************************************************************\
* xxxSendMinRectMessages
*
* History:
\***************************************************************************/
BOOL xxxSendMinRectMessages(PWND pwnd, RECT *lpRect) {
int i;
BOOL fRet = FALSE;
PWND *ppwnd;
HWND hwnd = HW(pwnd);
PTHREADINFO pti = PtiCurrent();
PDESKTOPINFO pdeskinfo;
if (IsHooked(pti, WHF_SHELL)) {
xxxCallHook(HSHELL_GETMINRECT, (DWORD)hwnd,
(LONG)lpRect, WH_SHELL);
fRet = TRUE;
}
pdeskinfo = GETDESKINFO(pti);
if ((ppwnd=pdeskinfo->papwndShellHook) == NULL) return fRet;
for (i=0;i<pdeskinfo->nShellHookPwnd;i++) {
TL tlpwnd;
DWORD dwRes;
ThreadLock(ppwnd[i], &tlpwnd);
if (xxxSendMessageTimeout(ppwnd[i], WM_KLUDGEMINRECT, (WPARAM)(hwnd), (LPARAM)lpRect,
SMTO_NORMAL, 100, &dwRes))
fRet = TRUE;
ThreadUnlock(&tlpwnd);
}
return fRet;
}
/***************************************************************************\
* PostShellHookMessages
*
* History:
\***************************************************************************/
void PostShellHookMessages(UINT message, HWND hwnd) {
int i;
PWND *ppwnd;
PWND pwnd;
PDESKTOPINFO pdeskinfo = GETDESKINFO(PtiCurrent());
ppwnd=pdeskinfo->papwndShellHook;
pwnd = RevalidateHwnd(hwnd);
for (i=0;i<pdeskinfo->nShellHookPwnd;i++) {
if (ppwnd[i] == pdeskinfo->spwndProgman) {
switch (message) {
case HSHELL_WINDOWCREATED:
_PostMessage(ppwnd[i], gpsi->uiShellMsg, guiOtherWindowCreated, (LPARAM)hwnd);
break;
case HSHELL_WINDOWDESTROYED:
_PostMessage(ppwnd[i], gpsi->uiShellMsg, guiOtherWindowDestroyed, (LPARAM)hwnd);
break;
}
} else {
if((message == HSHELL_RUDEAPPACTIVATED) && pwnd) {
/*
* On NT we have a problem with apps that create full screen windows
* that are not initially visible. User posts the fullscreen window
* notification but the shell immediately wakes up and tests if the
* window going fullscreen is visible. In some cases it is not yet
* visible and the shell will make itself topmost and then the
* fullscreen window will be made visible but under the shell.
* On Win 95 things are more serialized for 16 bit apps so the
* app almost always has a chance to make the window visible
* before the shell tests to see if the window is visible.
* To fix this problem we will do a PostEventMessage which will
* ensure that the app has enough time to make the window visible
* before shell gets this message
*
*/
PostEventMessage(GETPTI(pwnd),GETPTI(pwnd)->pq,
QEVENT_POSTMESSAGE, ppwnd[i],
gpsi->uiShellMsg,
(WPARAM)message,(LPARAM)hwnd);
} else {
_PostMessage(ppwnd[i], gpsi->uiShellMsg, message, (LPARAM)hwnd);
}
}
}
}
/***************************************************************************\
* _ResetDblClk
*
* History:
\***************************************************************************/
VOID _ResetDblClk(VOID)
{
PtiCurrent()->pq->timeDblClk = 0L;
}
/***************************************************************************\
* IncrMBox
*
* History:
\***************************************************************************/
void IncrMBox(void)
{
gpsi->cntMBox++;
}
/***************************************************************************\
* DecrMBox
*
* History:
\***************************************************************************/
void DecrMBox(void)
{
if (gpsi->cntMBox)
gpsi->cntMBox--;
}
/***************************************************************************\
* SimulateShiftF10
*
* This routine is called to convert a WM_CONTEXTHELP message back to a
* SHIFT-F10 sequence for old applications. It is called from the default
* window procedure.
*
* History:
* 22-Aug-95 BradG Ported from Win95 (rare.asm)
\***************************************************************************/
VOID SimulateShiftF10( VOID )
{
/*
* VK_SHIFT down
*/
_KeyEvent(VK_LSHIFT, 0x2A | SCANCODE_SIMULATED, 0);
/*
* VK_F10 down
*/
_KeyEvent(VK_F10, 0x44 | SCANCODE_SIMULATED, 0);
/*
* VK_F10 up
*/
_KeyEvent(VK_F10 | KBDBREAK, 0x44 | SCANCODE_SIMULATED, 0);
/*
* VK_SHIFT up
*/
_KeyEvent(VK_LSHIFT | KBDBREAK, 0x2A | SCANCODE_SIMULATED, 0);
}
/***************************************************************************\
* IsSyncOnlyMessage
*
* History:
\***************************************************************************/
BOOL IsSyncOnlyMessage(UINT message, WPARAM wParam) {
return (TESTSYNCONLYMESSAGE(message, wParam));
}