|
|
/***************************************************************************\
* * INCTLPAN.C * * Copyright (c) 1985 - 1999, Microsoft Corporation * * Init Routines which are also used by Control Panel * * -- Scalable Window Frame Support * * exports from this module: * > xxxSetWindowNCMetrics -- called by LoadWindows & SystemParametersInfo * \***************************************************************************/
#include "precomp.h"
#pragma hdrstop
__inline int MetricGetID( PUNICODE_STRING pProfileUserName, UINT idStr, int defValue ) { int iRet; FastGetProfileIntFromID( pProfileUserName, PMAP_METRICS, idStr, defValue, &iRet, 0); return iRet; }
static CONST WORD sysBmpStyles[OBI_COUNT][2] = {
DFC_CAPTION, DFCS_CAPTIONCLOSE, // OBI_CLOSE
DFC_CAPTION, DFCS_CAPTIONCLOSE | DFCS_PUSHED, // OBI_CLOSE_D
DFC_CAPTION, DFCS_CAPTIONCLOSE | DFCS_HOT, // OBI_CLOSE_H
DFC_CAPTION, DFCS_CAPTIONCLOSE | DFCS_INACTIVE, // OBI_CLOSE_I
DFC_CAPTION, DFCS_CAPTIONMIN, // OBI_REDUCE
DFC_CAPTION, DFCS_CAPTIONMIN | DFCS_PUSHED, // OBI_REDUCE_D
DFC_CAPTION, DFCS_CAPTIONMIN | DFCS_HOT, // OBI_REDUCE_H
DFC_CAPTION, DFCS_CAPTIONMIN | DFCS_INACTIVE, // OBI_REDUCE_I
DFC_CAPTION, DFCS_CAPTIONRESTORE, // OBI_RESTORE
DFC_CAPTION, DFCS_CAPTIONRESTORE | DFCS_PUSHED, // OBI_RESTORE_D
DFC_CAPTION, DFCS_CAPTIONRESTORE | DFCS_HOT, // OBI_RESTORE_H
DFC_CAPTION, DFCS_CAPTIONHELP, // OBI_HELP
DFC_CAPTION, DFCS_CAPTIONHELP | DFCS_PUSHED, // OBI_HELP_D
DFC_CAPTION, DFCS_CAPTIONHELP | DFCS_HOT, // OBI_HELP_H
DFC_CAPTION, DFCS_CAPTIONMAX, // OBI_ZOOM
DFC_CAPTION, DFCS_CAPTIONMAX | DFCS_PUSHED, // OBI_ZOOM_D
DFC_CAPTION, DFCS_CAPTIONMAX | DFCS_HOT, // OBI_ZOOM_H
DFC_CAPTION, DFCS_CAPTIONMAX | DFCS_INACTIVE, // OBI_ZOOM_I
DFC_CAPTION, DFCS_CAPTIONCLOSE | DFCS_INMENU, // OBI_CLOSE_MBAR
DFC_CAPTION, DFCS_CAPTIONCLOSE | DFCS_INMENU | DFCS_PUSHED, // OBI_CLOSE_MBAR_D
DFC_CAPTION, DFCS_CAPTIONCLOSE | DFCS_INMENU | DFCS_HOT, // OBI_CLOSE_MBAR_H
DFC_CAPTION, DFCS_CAPTIONCLOSE | DFCS_INMENU | DFCS_INACTIVE, // OBI_CLOSE_MBAR_I
DFC_CAPTION, DFCS_CAPTIONMIN | DFCS_INMENU, // OBI_REDUCE_MBAR
DFC_CAPTION, DFCS_CAPTIONMIN | DFCS_INMENU | DFCS_PUSHED, // OBI_REDUCE_MBAR_D
DFC_CAPTION, DFCS_CAPTIONMIN | DFCS_INMENU | DFCS_HOT, // OBI_REDUCE_MBAR_H
DFC_CAPTION, DFCS_CAPTIONMIN | DFCS_INMENU | DFCS_INACTIVE, // OBI_REDUCE_MBAR_I
DFC_CAPTION, DFCS_CAPTIONRESTORE | DFCS_INMENU, // OBI_RESTORE_MBAR
DFC_CAPTION, DFCS_CAPTIONRESTORE | DFCS_INMENU | DFCS_PUSHED, // OBI_RESTORE_MBAR_D
DFC_CAPTION, DFCS_CAPTIONRESTORE | DFCS_INMENU | DFCS_HOT, // OBI_RESTORE_MBAR_H
DFC_CACHE, DFCS_CACHEICON, // OBI_CAPICON1
DFC_CACHE, DFCS_CACHEICON | DFCS_INACTIVE, // OBI_CAPICON1_I
DFC_CACHE, DFCS_CACHEICON, // OBI_CAPICON2
DFC_CACHE, DFCS_CACHEICON | DFCS_INACTIVE, // OBI_CAPICON2_I
DFC_CACHE, DFCS_CACHEICON, // OBI_CAPICON3
DFC_CACHE, DFCS_CACHEICON | DFCS_INACTIVE, // OBI_CAPICON3_I
DFC_CACHE, DFCS_CACHEICON, // OBI_CAPICON4
DFC_CACHE, DFCS_CACHEICON | DFCS_INACTIVE, // OBI_CAPICON4_I
DFC_CACHE, DFCS_CACHEICON, // OBI_CAPICON5
DFC_CACHE, DFCS_CACHEICON | DFCS_INACTIVE, // OBI_CAPICON5_I
DFC_CACHE, DFCS_CACHEBUTTONS, // OBI_CAPBTNS
DFC_CACHE, DFCS_CACHEBUTTONS | DFCS_INACTIVE, // OBI_CAPBTNS_I
DFC_CAPTION, DFCS_CAPTIONCLOSE | DFCS_INSMALL, // OBI_CLOSE_PAL
DFC_CAPTION, DFCS_CAPTIONCLOSE | DFCS_INSMALL | DFCS_PUSHED, // OBI_CLOSE_PAL_D
DFC_CAPTION, DFCS_CAPTIONCLOSE | DFCS_INSMALL | DFCS_HOT, // OBI_CLOSE_PAL_H
DFC_CAPTION, DFCS_CAPTIONCLOSE | DFCS_INSMALL | DFCS_INACTIVE,// OBI_CLOSE_PAL_I
DFC_SCROLL, DFCS_SCROLLSIZEGRIP, // OBI_NCGRIP
DFC_SCROLL, DFCS_SCROLLUP, // OBI_UPARROW
DFC_SCROLL, DFCS_SCROLLUP | DFCS_PUSHED | DFCS_FLAT, // OBI_UPARROW_D
DFC_SCROLL, DFCS_SCROLLUP | DFCS_HOT, // OBI_UPARROW_H
DFC_SCROLL, DFCS_SCROLLUP | DFCS_INACTIVE, // OBI_UPARROW_I
DFC_SCROLL, DFCS_SCROLLDOWN, // OBI_DNARROW
DFC_SCROLL, DFCS_SCROLLDOWN | DFCS_PUSHED | DFCS_FLAT, // OBI_DNARROW_D
DFC_SCROLL, DFCS_SCROLLDOWN | DFCS_HOT, // OBI_DNARROW_H
DFC_SCROLL, DFCS_SCROLLDOWN | DFCS_INACTIVE, // OBI_DNARROW_I
DFC_SCROLL, DFCS_SCROLLRIGHT, // OBI_RGARROW
DFC_SCROLL, DFCS_SCROLLRIGHT | DFCS_PUSHED | DFCS_FLAT, // OBI_RGARROW_D
DFC_SCROLL, DFCS_SCROLLRIGHT | DFCS_HOT, // OBI_RGARROW_H
DFC_SCROLL, DFCS_SCROLLRIGHT | DFCS_INACTIVE, // OBI_RGARROW_I
DFC_SCROLL, DFCS_SCROLLLEFT, // OBI_LFARROW
DFC_SCROLL, DFCS_SCROLLLEFT | DFCS_PUSHED | DFCS_FLAT, // OBI_LFARROW_D
DFC_SCROLL, DFCS_SCROLLLEFT | DFCS_HOT, // OBI_LFARROW_H
DFC_SCROLL, DFCS_SCROLLLEFT | DFCS_INACTIVE, // OBI_LFARROW_I
DFC_MENU, DFCS_MENUARROW, // OBI_MENUARROW
DFC_MENU, DFCS_MENUCHECK, // OBI_MENUCHECK
DFC_MENU, DFCS_MENUBULLET, // OBI_MENUBULLET
DFC_MENU, DFCS_MENUARROWUP, // OBI_MENUARROWUP
DFC_MENU, DFCS_MENUARROWUP | DFCS_HOT, // OBI_MENUARROWUP_H
DFC_MENU, DFCS_MENUARROWUP | DFCS_INACTIVE, // OBI_MENUARROWUP_I
DFC_MENU, DFCS_MENUARROWDOWN, // OBI_MENUARROWDOWN
DFC_MENU, DFCS_MENUARROWDOWN | DFCS_HOT, // OBI_MENUARROWDOWN_H
DFC_MENU, DFCS_MENUARROWDOWN | DFCS_INACTIVE, // OBI_MENUARROWDOWN_I
DFC_BUTTON, DFCS_BUTTONRADIOMASK, // OBI_RADIOMASK
DFC_BUTTON, DFCS_BUTTONCHECK, // OBI_CHECK
DFC_BUTTON, DFCS_BUTTONCHECK | DFCS_CHECKED, // OBI_CHECK_C
DFC_BUTTON, DFCS_BUTTONCHECK | DFCS_PUSHED, // OBI_CHECK_D
DFC_BUTTON, DFCS_BUTTONCHECK | DFCS_CHECKED | DFCS_PUSHED, // OBI_CHECK_CD
DFC_BUTTON, DFCS_BUTTONCHECK | DFCS_CHECKED | DFCS_INACTIVE, // OBI_CHECK_CDI
DFC_BUTTON, DFCS_BUTTONRADIOIMAGE, // OBI_RADIO
DFC_BUTTON, DFCS_BUTTONRADIOIMAGE | DFCS_CHECKED, // OBI_RADIO_C
DFC_BUTTON, DFCS_BUTTONRADIOIMAGE | DFCS_PUSHED, // OBI_RADIO_D
DFC_BUTTON, DFCS_BUTTONRADIOIMAGE | DFCS_CHECKED | DFCS_PUSHED, // OBI_RADIO_CD
DFC_BUTTON, DFCS_BUTTONRADIOIMAGE | DFCS_CHECKED | DFCS_INACTIVE, // OBI_RADIO_CDI
DFC_BUTTON, DFCS_BUTTON3STATE, // OBI_3STATE
DFC_BUTTON, DFCS_BUTTON3STATE | DFCS_CHECKED, // OBI_3STATE_C
DFC_BUTTON, DFCS_BUTTON3STATE | DFCS_PUSHED, // OBI_3STATE_D
DFC_BUTTON, DFCS_BUTTON3STATE | DFCS_CHECKED | DFCS_PUSHED, // OBI_3STATE_CD
DFC_BUTTON, DFCS_BUTTON3STATE | DFCS_CHECKED | DFCS_INACTIVE, // OBI_3STATE_CDI
DFC_POPUPMENU, DFCS_CAPTIONCLOSE | DFCS_INMENU, // OBI_CLOSE_POPUP
DFC_POPUPMENU, DFCS_CAPTIONRESTORE | DFCS_INMENU, // OBI_RESTORE_POPUP
DFC_POPUPMENU, DFCS_CAPTIONMAX | DFCS_INMENU, // OBI_ZOOM_POPUP
DFC_POPUPMENU, DFCS_CAPTIONMIN | DFCS_INMENU, // OBI_REDUCE_POPUP
DFC_SCROLL, DFCS_SCROLLSIZEGRIPRIGHT, // OBI_NCGRIP_L
DFC_MENU, DFCS_MENUARROWRIGHT // OBI_MENUARROW_L
};
#define DIVISOR 72
#define DU_BTNWIDTH 50 // D.U. of minimum button width in a message box
UINT xxxMB_FindLongestString(HDC hdc);
#ifdef LATER
/***************************************************************************\
\***************************************************************************/
WCHAR NibbleToChar( BYTE x) { WCHAR static N2C[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', };
return N2C[x]; }
BYTE CharToNibble( WCHAR ch) { BYTE x = (BYTE)ch;
return x >= '0' && x <= '9' ? x - '0' : ((10 + x - 'A' ) & 0x0f); }
BOOL TextToBinary( LPBYTE pbyte, LPWSTR pwstr, int length) { BYTE checksum = 0;
while (TRUE) { BYTE byte;
byte = (CharToNibble(pwstr[0]) << 4) | CharToNibble(pwstr[1]);
if (length == 0) { return checksum == byte; }
checksum += byte; *pbyte = byte;
pwstr += 2; length--; pbyte++; } }
void BinaryToText( LPWSTR pwstr, LPBYTE pbyte, int length) { BYTE checksum = 0;
while (length > 0) { checksum += *pbyte;
pwstr[0] = NibbleToChar((BYTE)((*pbyte >> 4) & 0x0f)); pwstr[1] = NibbleToChar((BYTE)(*pbyte & 0x0f));
pbyte++; pwstr += 2; length--; }
pwstr[0] = NibbleToChar((BYTE)((checksum >> 4) & 0x0f)); pwstr[1] = NibbleToChar((BYTE)(checksum & 0x0f)); pwstr[2] = '\0'; }
/***************************************************************************\
\***************************************************************************/
// these are the exported apis. The User* versions are for server use only
// I didn't get them to work since no one calls them yet.
BOOL GetPrivateProfileStruct( LPWSTR szSection, LPWSTR szKey, LPWSTR lpStruct, DWORD uSizeStruct, LPWSTR szFile) { WCHAR szBuf[256]; BOOL fAlloc = FALSE; LPSTR lpBuf, lpBufTemp; int nLen; BOOL fError = FALSE;
nLen = uSizeStruct * 4 + 10; if (nLen > (WORD)sizeof(szBuf)) { fAlloc = TRUE; lpBuf = (LPSTR)UserAllocPoolWithQuota(nLen, TAG_PROFILE); if (lpBuf == NULL) return FALSE; } else { lpBuf = (LPSTR)szBuf; }
if (szFile && *szFile) { nLen = GetPrivateProfileString(szSection, szKey, NULL, lpBuf, nLen, szFile); } else { nLen = GetProfileString(szSection, szKey, NULL, lpBuf, nLen); }
if (nLen == (int)(uSizeStruct * 4 + 4)) { /*
* decode the string */ fError = TextToBinary(lpStruct, lpBufTemp, uSizeStruct); }
if (fAlloc) UserFreePool(lpBuf);
return fError; }
BOOL WritePrivateProfileStruct( LPWSTR szSection, LPWSTR szKey, LPWSTR lpStruct, WORD uSizeStruct, LPWSTR szFile) { LPWSTR lpBuf; BOOL bRet; BOOL fAlloc; WCHAR szBuf[256]; BYTE checksum=0; int allocsize = (uSizeStruct * 2 + 3) * sizeof(WCHAR);
/* NULL lpStruct erases the the key */
if (lpStruct == NULL) { if (szFile && *szFile) { return WritePrivateProfileString(szSection, szKey, (LPSTR)NULL, szFile); } else { return WriteProfileString(szSection, szKey, (LPSTR)NULL); } }
fAlloc = (allocsize > sizeof(szBuf)); if (fAlloc) { lpBuf = (LPSTR)UserAllocPoolWithQuota(allocsize, TAG_PROFILE); if (!lpBuf) return FALSE; } else { lpBuf = (LPSTR)szBuf; }
BinaryToText(lpBuf, lpStruct, uSizeStruct);
if (szFile && *szFile) { bRet = WritePrivateProfileString(szSection, szKey, lpBuf, szFile); } else { bRet = WriteProfileString(szSection, szKey, lpBuf); }
if (fAlloc) UserFreePool(lpBuf);
return bRet; } #endif
/***************************************************************************\
* * GetFrameControlMetrics * * (cx = 0) is a code meaning cy is the obi of the "shared" bitmap * \***************************************************************************/ int GetFrameControlMetrics( UINT obi, int cxMax ) { int cx, cy; UINT wType = sysBmpStyles[obi][0]; UINT wState = sysBmpStyles[obi][1]; POEMBITMAPINFO pOem = gpsi->oembmi + obi;
switch (wType) { case DFC_SCROLL: if (wState & DFCS_SCROLLSIZEGRIP) { cx = SYSMET(CXVSCROLL); cy = SYSMET(CYHSCROLL); break; } else if (wState & DFCS_SCROLLHORZ) { cx = SYSMET(CXHSCROLL); cy = SYSMET(CYHSCROLL); } else { cx = SYSMET(CXVSCROLL); cy = SYSMET(CYVSCROLL); } break;
case DFC_MENU: case DFC_POPUPMENU: if (wState & (DFCS_MENUARROWUP | DFCS_MENUARROWDOWN)) { cy = gcyMenuScrollArrow; } else { /*
* Add on proper space for space above underscore. * the 0xFFFE and -1 are to insure an ODD height */ cy = ((gcyMenuFontChar + gcyMenuFontExternLeading + SYSMET(CYBORDER)) & 0xFFFE) - 1; } cx = cy; break;
case DFC_CAPTION: if (wState & DFCS_INSMALL) { cx = SYSMET(CXSMSIZE); cy = SYSMET(CYSMSIZE); } else if (wState & DFCS_INMENU) { if ((SYSMET(CXSIZE) == SYSMET(CXMENUSIZE)) && (SYSMET(CYSIZE) == SYSMET(CYMENUSIZE))) { cx = 0; cy = obi - DOBI_MBAR; break; } else { cx = SYSMET(CXMENUSIZE); cy = SYSMET(CYMENUSIZE); } } else { cx = SYSMET(CXSIZE); cy = SYSMET(CYSIZE); }
cx -= SYSMET(CXEDGE); cy -= 2 * SYSMET(CYEDGE); break;
case DFC_CACHE: if (wState & DFCS_CACHEBUTTONS) { cx = SYSMET(CXSIZE) * 4; cy = SYSMET(CYSIZE); } else cx = cy = SYSMET(CYSIZE); break;
case DFC_BUTTON: if (((wState & 0x00FF) & DFCS_BUTTON3STATE) && !(wState & DFCS_CHECKED)) { cx = 0; cy = obi - DOBI_3STATE; } else { /*
* Scale button size with screen DPI so we look OK on high * resolution monitors. */ cx = cy = (gpsi->dmLogPixels / 8) + 1; } break; }
pOem->cx = cx; pOem->cy = cy;
return((cx > cxMax) ? cx : cxMax); }
/***************************************************************************\
* * PackFrameControls * * Given the dimensions that GetFrameControlMetrics has calculated, this * arranges all the system bitmaps to fit within a bitmap of the given width * \***************************************************************************/
int PackFrameControls(int cxMax, BOOL fRecord) { UINT obi; int cy = 0; int x = 0; int y = 0;
POEMBITMAPINFO pOem = gpsi->oembmi;
for (obi = 0; obi < OBI_COUNT; obi++, pOem++) { if (pOem->cx) { if ((x + pOem->cx) > cxMax) { y += cy; cy = 0; x = 0; }
if (fRecord) { pOem->x = x; pOem->y = y; }
if (cy < pOem->cy) cy = pOem->cy;
x += pOem->cx; } }
return(y + cy); }
void DrawCaptionButtons( int x, int y ) { x += SYSMET(CXEDGE); y += SYSMET(CYEDGE);
BitBltSysBmp(HDCBITS(), x, y, OBI_REDUCE); x += SYSMET(CXSIZE) - SYSMET(CXEDGE); BitBltSysBmp(HDCBITS(), x, y, OBI_ZOOM); x += SYSMET(CXSIZE); BitBltSysBmp(HDCBITS(), x, y, OBI_CLOSE); x += SYSMET(CXSIZE); BitBltSysBmp(HDCBITS(), x, y, OBI_HELP); }
/***************************************************************************\
* CreateCaptionStrip * * \***************************************************************************/ HBITMAP CreateCaptionStrip(VOID) { HBITMAP hbm;
hbm = GreCreateCompatibleBitmap(gpDispInfo->hdcScreen, SYSMET(CXVIRTUALSCREEN), (SYSMET(CYCAPTION) - 1) * 2);
if (hbm) GreSetBitmapOwner(hbm, OBJECT_OWNER_PUBLIC);
return hbm; }
/***************************************************************************\
* * CreateBitmapStrip * * This routine sets up either the color or monochrome strip bitmap -- a * large horizontal bitmap which contains all of the system bitmaps. By * having all of these bitmaps in one long bitmap, we can have that one * bitmap always selected in, speeding up paint time by not having to do * a SelectBitmap() everytime we need to Blt one of the system bitmaps. * \***************************************************************************/
BOOL CreateBitmapStrip(VOID) { int cxBmp = 0; int cyBmp = 0; int iCache = 0; int cy[5]; HBITMAP hOldBitmap; HBITMAP hNewBmp; UINT iType; RECT rc; UINT wBmpType; UINT wBmpStyle; POEMBITMAPINFO pOem;
/*
* Each OBI_ must have an entry in sysBmpStyles */ UserAssert(OBI_COUNT == sizeof(sysBmpStyles) / sizeof(*sysBmpStyles)); UserAssert(OBI_COUNT == sizeof(gpsi->oembmi) / sizeof(*(gpsi->oembmi)));
/*
* load all the bitmap dimensions into the OEMBITMAPINFO array oemInfo.bm */ for (iType = 0; iType < OBI_COUNT; iType++) cxBmp = GetFrameControlMetrics(iType, cxBmp);
for (iType = 0; iType < 5; iType++) cy[iType] = PackFrameControls(cxBmp * (iType + 1), FALSE) * (iType + 1);
cyBmp = min(cy[0], min(cy[1], min(cy[2], min(cy[3], cy[4])))); for (iType = 0; cyBmp != cy[iType]; iType++);
cxBmp *= iType + 1; cyBmp = PackFrameControls(cxBmp, TRUE);
hNewBmp = GreCreateCompatibleBitmap(gpDispInfo->hdcScreen, cxBmp, cyBmp);
if (hNewBmp == NULL) { RIPMSG0(RIP_WARNING, "CreateBitmapStrip: failed to create bitmap"); return FALSE; }
GreSetBitmapOwner(hNewBmp, OBJECT_OWNER_PUBLIC);
/*
* Select in Bitmap Strip -- then delete old one if it exists. */ hOldBitmap = GreSelectBitmap(HDCBITS(), hNewBmp);
if (ghbmBits) { #if DBG
/*
* Don't RIP if we're out of memory. */ if (hOldBitmap != NULL && ghbmBits != hOldBitmap) { RIPMSG0(RIP_WARNING, "ghbmBits != hOldBitmap"); } #endif
GreDeleteObject(ghbmCaption); GreDeleteObject(hOldBitmap); }
ghbmBits = hNewBmp;
ghbmCaption = CreateCaptionStrip();
if (ghbmCaption == NULL) { RIPMSG0(RIP_WARNING, "CreateBitmapStrip: failed to create bitmap for caption"); return FALSE; }
/*
* Draw individual bitmaps into the strip bitmap and record the offsets. */ for (pOem = gpsi->oembmi, iType = 0; iType < OBI_COUNT; iType++, pOem++) { if (!pOem->cx) { *pOem = gpsi->oembmi[pOem->cy]; } else { rc.left = pOem->x; rc.top = pOem->y; rc.right = rc.left + pOem->cx; rc.bottom = rc.top + pOem->cy;
wBmpType = sysBmpStyles[iType][0]; wBmpStyle = sysBmpStyles[iType][1];
if (wBmpType == DFC_CACHE) { if (wBmpStyle & DFCS_CACHEBUTTONS) { HBRUSH hbr; if (TestALPHA(GRADIENTCAPTIONS)) { hbr = (wBmpStyle & DFCS_INACTIVE) ? SYSHBR(GRADIENTINACTIVECAPTION) : SYSHBR(GRADIENTACTIVECAPTION); } else { hbr = (wBmpStyle & DFCS_INACTIVE) ? SYSHBR(INACTIVECAPTION) : SYSHBR(ACTIVECAPTION); } FillRect(HDCBITS(), &rc, hbr); DrawCaptionButtons(rc.left, rc.top); } else if (!(wBmpStyle & DFCS_INACTIVE)) { /*
* Setup Caption Cache Entry */ UserAssert(iCache < CCACHEDCAPTIONS); if (gcachedCaptions[iCache].spcursor) { Unlock(&(gcachedCaptions[iCache].spcursor)); } gcachedCaptions[iCache++].pOem = pOem; } } else { DrawFrameControl(HDCBITS(), &rc, wBmpType, wBmpStyle); } } }
/*
* Setup other frame metric dependent values. */ SYSMET(CXMENUCHECK) = gpsi->oembmi[OBI_MENUCHECK].cx; SYSMET(CYMENUCHECK) = gpsi->oembmi[OBI_MENUCHECK].cy;
return TRUE; }
void SetNCMetrics( LPNONCLIENTMETRICS lpnc) { int nMin;
/*
* Scroll metrics */ SYSMET(CXVSCROLL) = SYSMET(CYHSCROLL) = (int) lpnc->iScrollWidth; SYSMET(CYVSCROLL) = SYSMET(CXHSCROLL) = (int) lpnc->iScrollHeight; SYSMET(CYVTHUMB) = SYSMET(CXHTHUMB) = (int) lpnc->iScrollHeight;
/*
* Caption metrics */ SYSMET(CXSIZE) = (int) lpnc->iCaptionWidth; SYSMET(CYSIZE) = (int) lpnc->iCaptionHeight; SYSMET(CYCAPTION) = SYSMET(CYSIZE) + SYSMET(CYBORDER);
/*
* Keep small icon square? * ?? Should we allow rectangles? */ SYSMET(CXSMICON) = (SYSMET(CXSIZE) - SYSMET(CXEDGE)) & ~1; SYSMET(CYSMICON) = (SYSMET(CYSIZE) - SYSMET(CYEDGE)) & ~1; nMin = min(SYSMET(CXSMICON), SYSMET(CYSMICON)); SYSMET(CXSMICON) = nMin; SYSMET(CYSMICON) = nMin;
/*
* Small Caption metrics */ SYSMET(CXSMSIZE) = (int) lpnc->iSmCaptionWidth; SYSMET(CYSMSIZE) = (int) lpnc->iSmCaptionHeight; SYSMET(CYSMCAPTION) = SYSMET(CYSMSIZE) + SYSMET(CYBORDER);
/*
* Menu metrics */ SYSMET(CXMENUSIZE) = (int) lpnc->iMenuWidth; SYSMET(CYMENUSIZE) = (int) lpnc->iMenuHeight; SYSMET(CYMENU) = SYSMET(CYMENUSIZE) + SYSMET(CYBORDER);
/*
* Border metrics */ gpsi->gclBorder = (int) lpnc->iBorderWidth;
SYSMET(CXFRAME) = SYSMET(CXEDGE) + (gpsi->gclBorder+1)*SYSMET(CXBORDER); SYSMET(CYFRAME) = SYSMET(CYEDGE) + (gpsi->gclBorder+1)*SYSMET(CYBORDER);
/*
* Minimium tracking size is * Across: Space for small icon, 4 chars & space + 3 buttons + borders * Down: Space for caption + borders * Yes, we use CYSIZE. This is because the width of any small icon * is the same as the height, and the height is CYSIZE. */ SYSMET(CXMINTRACK) = SYSMET(CYSIZE) + (gcxCaptionFontChar * 4) + 2 * SYSMET(CXEDGE) + (SYSMET(CXSIZE) * 3) + (SYSMET(CXSIZEFRAME) * 2); SYSMET(CYMINTRACK) = SYSMET(CYCAPTION) + (SYSMET(CYSIZEFRAME) * 2);
/*
* Max track size * Yeah, max track is bigger than maximized. The reason why is the DOS * box. It has a normal sizing border plus the sunken edge around the * client. We need to make this big enough to allow the dos box to grow. * When it hits its max size, it maximizes automatically. */ SYSMET(CXMAXTRACK) = SYSMET(CXVIRTUALSCREEN) + (2 * (SYSMET(CXSIZEFRAME) + SYSMET(CXEDGE))); SYSMET(CYMAXTRACK) = SYSMET(CYVIRTUALSCREEN) + (2 * (SYSMET(CYSIZEFRAME) + SYSMET(CYEDGE)));
SYSMET(CXMIN) = SYSMET(CXMINTRACK); SYSMET(CYMIN) = SYSMET(CYMINTRACK);
SYSMET(CYMINIMIZED) = 2*SYSMET(CYFIXEDFRAME) + SYSMET(CYSIZE);
/*
* Desktop stuff--working area */ bSetDevDragWidth(gpDispInfo->hDev, gpsi->gclBorder + BORDER_EXTRA);
SetDesktopMetrics(); }
/***************************************************************************\
* * CreateFontFromWinIni() - * * If lplf is NULL, we do a first time, default initialization. * Otherwise, lplf is a pointer to the logfont we will use. * \***************************************************************************/ HFONT CreateFontFromWinIni( PUNICODE_STRING pProfileUserName, LPLOGFONTW lplf, UINT idFont) { LOGFONTW lf; HFONT hFont;
if (lplf == NULL) { static CONST WCHAR szDefFont[] = TEXT("MS Shell Dlg"); /*
* Fill logfont w/ 0 so we can check if values were filled in. */ lplf = &lf; RtlZeroMemory(&lf, sizeof(lf)); lf.lfCharSet = gSystemCPCharSet;
FastGetProfileValue(pProfileUserName,PMAP_METRICS, (LPWSTR)UIntToPtr( idFont ), NULL, (LPBYTE)&lf, sizeof(lf), 0);
/*
* Default font is MS Shell Dlg */ if (! lf.lfFaceName[0]) { RtlCopyMemory(lf.lfFaceName, szDefFont, sizeof(szDefFont)); }
/*
* Warning! these values are different then Win 95. They did not have a True Type * font so they would round up when they asked for a 6 pt font. We have to ask * for an 8 point font ICONFONT to be the same. */ if (!lf.lfHeight) { switch (idFont) { case STR_SMCAPTIONFONT: case STR_MINFONT: case STR_ICONFONT: default: lf.lfHeight = 8; break; } }
/*
* We need to convert the point size properly. GDI expects a * height in pixels, not points. */ if (lf.lfHeight > 0) { lf.lfHeight = -MultDiv(lf.lfHeight, gpsi->dmLogPixels, 72); }
if (! lf.lfWeight) { switch (idFont) { case STR_CAPTIONFONT: case STR_MINFONT: lf.lfWeight = FW_BOLD; break;
default: lf.lfWeight = FW_NORMAL; break; } }
lf.lfOutPrecision = OUT_DEFAULT_PRECIS; lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; lf.lfQuality = DEFAULT_QUALITY; }
hFont = GreCreateFontIndirectW(lplf);
if (hFont) { LOGFONTW lfT;
GreExtGetObjectW(hFont, sizeof(LOGFONTW), &lfT); if (lfT.lfHeight != lplf->lfHeight) { /*
* Couldn't find a font with the height that we * wanted so use the system font instead. */ GreDeleteObject(hFont); hFont = NULL; } else { GreMarkUndeletableFont(hFont); GreSetLFONTOwner((HLFONT)hFont, OBJECT_OWNER_PUBLIC); } }
if (!hFont) { /*
* We've tried to create the font from the app-supplied description. * If failure, return NULL so that we don't change the previous * font. */ if (lplf) hFont = NULL; else hFont = ghFontSys; }
return hFont; }
/***************************************************************************\
* \***************************************************************************/
BOOL UserSetFont( PUNICODE_STRING pProfileUserName, LPLOGFONTW lplf, UINT idFont, HFONT* phfont) { HFONT hNewFont;
if (hNewFont = CreateFontFromWinIni(pProfileUserName, lplf, idFont)) { if (*phfont != NULL && *phfont != ghFontSys) { GreMarkDeletableFont(*phfont); GreDeleteObject(*phfont); }
*phfont = hNewFont; return TRUE; } return FALSE; }
/***************************************************************************\
* * xxxSetNCFonts() - * * Creates fonts to be used in the frame components: * Caption * Small caption * Menu * Minimized * Icon * * 01-21-98 [SamerA] Renamed to xxxSetNCFonts since it may leave the * critical section when a client LPK is installed. \***************************************************************************/ BOOL xxxSetNCFonts( PUNICODE_STRING pProfileUserName, LPNONCLIENTMETRICS lpnc) { HFONT hOldFont; TEXTMETRIC tm; LOGFONTW lf; LPLOGFONTW lplf = (lpnc) ? &lf : 0;
/*
* Caption font */ if (lplf) { *lplf = lpnc->lfCaptionFont; }
if (!UserSetFont(pProfileUserName,lplf, STR_CAPTIONFONT, &gpsi->hCaptionFont)) { RIPMSG0(RIP_WARNING, "xxxSetNCFonts failed for gpsi->hCaptionFont"); return FALSE; }
hOldFont = GreSelectFont(HDCBITS(), gpsi->hCaptionFont); gcxCaptionFontChar = GetCharDimensions( HDCBITS(), NULL, &gcyCaptionFontChar);
#ifdef LAME_BUTTON
/*
* Lame! button font */ { LOGFONTW lfLame; WCHAR szLameButtonKey[60]; SIZE btnSize;
if (ghLameFont != NULL) { GreMarkDeletableFont(ghLameFont); GreDeleteObject(ghLameFont); }
GreExtGetObjectW(gpsi->hCaptionFont, sizeof(LOGFONTW), &lfLame);
lfLame.lfUnderline = 1; lfLame.lfWeight = FW_THIN;
ghLameFont = GreCreateFontIndirectW(&lfLame); if (ghLameFont == NULL) { RIPMSG0(RIP_WARNING, "xxxSetNCFonts failed for ghLameFont"); return FALSE; } else { GreMarkUndeletableFont(ghLameFont); GreSetLFONTOwner((HLFONT)ghLameFont, OBJECT_OWNER_PUBLIC); }
ServerLoadString(hModuleWin, STR_LAMEBUTTONTEXT, szLameButtonKey, ARRAY_SIZE(szLameButtonKey));
FastGetProfileStringW(pProfileUserName, PMAP_DESKTOP, szLameButtonKey, TEXT("Comments?"), gpsi->gwszLame, 50, 0);
GreSelectFont(HDCBITS(), ghLameFont);
GreGetTextExtentW(HDCBITS(), gpsi->gwszLame, wcslen(gpsi->gwszLame), &btnSize, GGTE_WIN3_EXTENT);
gpsi->ncxLame = btnSize.cx; } #endif // LAME_BUTTON
/*
* Small caption font */ if (lplf) { *lplf = lpnc->lfSmCaptionFont; }
if (!UserSetFont(pProfileUserName,lplf, STR_SMCAPTIONFONT, &ghSmCaptionFont)) { RIPMSG0(RIP_WARNING, "xxxSetNCFonts failed for ghSmCaptionFont"); return FALSE; }
GreSelectFont(HDCBITS(), ghSmCaptionFont); gcxSmCaptionFontChar = GetCharDimensions( HDCBITS(), NULL, &gcySmCaptionFontChar);
/*
* Menu font */ if (lplf) { *lplf = lpnc->lfMenuFont; }
if (!UserSetFont(pProfileUserName,lplf, STR_MENUFONT, &ghMenuFont)) { RIPMSG0(RIP_WARNING, "xxxSetNCFonts failed for ghMenuFont"); return FALSE; }
/*
* if ghMenuFont is selected in cached animation DC, select the new one. */ if (gMenuState.hdcAni != NULL) { GreSelectFont(gMenuState.hdcAni, ghMenuFont); }
GreSelectFont(HDCBITS(), ghMenuFont); gcxMenuFontChar = GetCharDimensions( HDCBITS(), &tm, &gcyMenuFontChar); gcxMenuFontOverhang = tm.tmOverhang;
gcyMenuFontExternLeading = tm.tmExternalLeading; gcyMenuScrollArrow = gcyMenuFontChar + gcyMenuFontExternLeading + SYSMET(CYEDGE); gcyMenuFontAscent = tm.tmAscent;
/*
* We only use gcyMenuFontAscent in mndraw.c once, and in U.S. we * always add on CYBORDER! So calculate gcyMenuFontAscent+CYBORDER * once only. * Legacy NT4: For Korean version, don't add it on; the underline would * be too low. * NT5: according to #254327, Korean version now sees underline is * too close to menu strings. Korean hack is pulled out so. */ gcyMenuFontAscent += SYSMET(CYBORDER);
/*
* Default menu item font: bolder version of menu font */
/*
* Create default menu font by bolding hMenuFont. If this doesn't * work, then fall back to using simulation. */ if (ghMenuFontDef != NULL && ghMenuFontDef != ghFontSys) { GreMarkDeletableFont(ghMenuFontDef); GreDeleteObject(ghMenuFontDef); ghMenuFontDef = NULL; }
GreExtGetObjectW(ghMenuFont, sizeof(LOGFONTW), &lf); if (lf.lfWeight < FW_BOLD) { lf.lfWeight += 200;
ghMenuFontDef = GreCreateFontIndirectW(&lf); if (ghMenuFontDef) { GreMarkUndeletableFont(ghMenuFontDef); GreSetLFONTOwner((HLFONT)ghMenuFontDef, OBJECT_OWNER_PUBLIC); } }
/*
* Status Bar font */ if (lplf) { *lplf = lpnc->lfStatusFont; }
if (!UserSetFont(pProfileUserName,lplf, STR_STATUSFONT, &ghStatusFont)) { RIPMSG0(RIP_WARNING, "xxxSetNCFonts failed for ghStatusFont"); return FALSE; }
/*
* Message Box font */ if (lplf) { *lplf = lpnc->lfMessageFont; }
if (!UserSetFont(pProfileUserName,lplf, STR_MESSAGEFONT, &gpsi->hMsgFont)) { RIPMSG0(RIP_WARNING, "xxxSetNCFonts failed for gpsi->hMsgFont"); return FALSE; }
GreSelectFont(HDCBITS(), gpsi->hMsgFont); gpsi->cxMsgFontChar = GetCharDimensions( HDCBITS(), NULL, &gpsi->cyMsgFontChar);
/*
* Recalculate length of the widest MessageBox button * Make sure the width is no less than DU_BTNWIDTH dialog units MCostea #170582 */ gpsi->wMaxBtnSize = max((UINT)XPixFromXDU(DU_BTNWIDTH, gpsi->cxMsgFontChar), xxxMB_FindLongestString(HDCBITS())); GreSelectFont(HDCBITS(), hOldFont);
return TRUE; }
BOOL SetIconFonts( PUNICODE_STRING pProfileUserName, LPICONMETRICS lpicon) { LOGFONTW lf; LPLOGFONTW lplf = 0;
if (lpicon) { lplf = &lf; lf = lpicon->lfFont; }
return UserSetFont(pProfileUserName, lplf, STR_ICONFONT, &ghIconFont); }
/***************************************************************************\
* GetWindowMetrics * * Retrieve the current NC metrics. * * \***************************************************************************/
VOID GetWindowNCMetrics( LPNONCLIENTMETRICS lpnc) { lpnc->cbSize = sizeof(NONCLIENTMETRICS); lpnc->iBorderWidth = gpsi->gclBorder; lpnc->iScrollWidth = SYSMET(CXVSCROLL); lpnc->iScrollHeight = SYSMET(CYVSCROLL); lpnc->iCaptionWidth = SYSMET(CXSIZE); lpnc->iCaptionHeight = SYSMET(CYSIZE); lpnc->iSmCaptionWidth = SYSMET(CXSMSIZE); lpnc->iSmCaptionHeight = SYSMET(CYSMSIZE); lpnc->iMenuWidth = SYSMET(CXMENUSIZE); lpnc->iMenuHeight = SYSMET(CYMENUSIZE);
/*
* Get the font info. */ GreExtGetObjectW(gpsi->hCaptionFont, sizeof(LOGFONTW), &(lpnc->lfCaptionFont));
GreExtGetObjectW(ghSmCaptionFont, sizeof(LOGFONTW), &(lpnc->lfSmCaptionFont));
GreExtGetObjectW(ghMenuFont, sizeof(LOGFONTW), &(lpnc->lfMenuFont));
GreExtGetObjectW(ghStatusFont, sizeof(LOGFONTW), &(lpnc->lfStatusFont));
GreExtGetObjectW(gpsi->hMsgFont, sizeof(LOGFONTW), &(lpnc->lfMessageFont)); }
/***************************************************************************\
* * xxxSetWindowNCMetrics() - * * creates system fonts and bitmaps and sets the system metrics based on the * values of the given FRAMEMETRICS struct. If NULL is passed in, the * default values (found in WIN.INI) are used instead. * * 01-21-98 [SamerA] Renamed to xxxSetWindowNCMetrics since it may leave the * critical section if an LPK is installed. \***************************************************************************/
BOOL xxxSetWindowNCMetrics( PUNICODE_STRING pProfileUserName, LPNONCLIENTMETRICS lpnc, BOOL fSizeChange, int clNewBorder) { NONCLIENTMETRICS nc; int cxEdge4;
if (fSizeChange) { if (!xxxSetNCFonts(pProfileUserName, lpnc)) { RIPMSG0(RIP_WARNING, "xxxSetWindowNCMetrics failed in xxxSetNCFonts"); return FALSE; }
if (lpnc == NULL) { if (clNewBorder < 0) nc.iBorderWidth = MetricGetID(pProfileUserName,STR_BORDERWIDTH, 1); else nc.iBorderWidth = clNewBorder;
nc.iScrollWidth = MetricGetID(pProfileUserName,STR_SCROLLWIDTH, 16 ); nc.iScrollHeight = MetricGetID(pProfileUserName,STR_SCROLLHEIGHT, 16 ); nc.iCaptionWidth = MetricGetID(pProfileUserName,STR_CAPTIONWIDTH, 18 ); nc.iCaptionHeight = MetricGetID(pProfileUserName,STR_CAPTIONHEIGHT, 18 ); nc.iSmCaptionWidth = MetricGetID(pProfileUserName,STR_SMCAPTIONWIDTH, 13 ); nc.iSmCaptionHeight = MetricGetID(pProfileUserName,STR_SMCAPTIONHEIGHT, 13 ); nc.iMenuWidth = MetricGetID(pProfileUserName,STR_MENUWIDTH, 18 ); nc.iMenuHeight = MetricGetID(pProfileUserName,STR_MENUHEIGHT, 18 );
lpnc = &nc; }
/*
* SANITY CHECK for metric values */ cxEdge4 = 4 * SYSMET(CXEDGE);
/*
* Border */ lpnc->iBorderWidth = max(lpnc->iBorderWidth, 1); lpnc->iBorderWidth = min(lpnc->iBorderWidth, 50);
/*
* Scrollbar */ lpnc->iScrollWidth = max(lpnc->iScrollWidth, cxEdge4); lpnc->iScrollHeight = max(lpnc->iScrollHeight, 4 * SYSMET(CYEDGE));
/*
* Caption -- Buttons must be wide enough to draw edges, and text * area must be tall enough to fit caption font with a border above * and below. If we have to reset the caption height, should we * reset the button width as well? */ lpnc->iCaptionWidth = max(lpnc->iCaptionWidth, cxEdge4); lpnc->iCaptionHeight = max(lpnc->iCaptionHeight, gcyCaptionFontChar + SYSMET(CYEDGE));
/*
* Small caption -- Buttons must be wide enough to draw edges, and * text area must be tall enough to fit small caption font with a * border above and below. Again, if we have to reset the height, * reset the width as well? */ lpnc->iSmCaptionWidth = max(lpnc->iSmCaptionWidth, cxEdge4); lpnc->iSmCaptionHeight = max(lpnc->iSmCaptionHeight, gcySmCaptionFontChar + SYSMET(CYEDGE));
/*
* Menu -- Buttons must be wide enough to draw edges, and text * area must be tall enough to fit menu font with underscore. */ lpnc->iMenuWidth = max(lpnc->iMenuWidth, cxEdge4); lpnc->iMenuHeight = max(lpnc->iMenuHeight, gcyMenuFontChar + gcyMenuFontExternLeading + SYSMET(CYEDGE));
/*
* SET UP SYSTEM METRIC VALUES */ SetNCMetrics(lpnc); }
if (!CreateBitmapStrip()) { RIPMSG0(RIP_WARNING, "CreateBitmapStrip failed"); return FALSE; }
return TRUE; }
VOID SetMinMetrics( PUNICODE_STRING pProfileUserName, LPMINIMIZEDMETRICS lpmin) { MINIMIZEDMETRICS min;
if (!lpmin) {
/*
* Minimized */ min.iWidth = MetricGetID(pProfileUserName,STR_MINWIDTH, 154); min.iHorzGap = MetricGetID(pProfileUserName,STR_MINHORZGAP, 0); min.iVertGap = MetricGetID(pProfileUserName,STR_MINVERTGAP, 0); min.iArrange = MetricGetID(pProfileUserName,STR_MINARRANGE, ARW_BOTTOMLEFT | ARW_RIGHT); lpmin = &min; }
/*
* SANITY CHECK for metric values */
/*
* Minimized window -- Text area must be >= 0, as must gap between * windows horizontally and vertically. */ lpmin->iWidth = max(lpmin->iWidth, 0); lpmin->iHorzGap = max(lpmin->iHorzGap, 0); lpmin->iVertGap = max(lpmin->iVertGap, 0); lpmin->iArrange &= ARW_VALID;
/*
* Minimized size */ SYSMET(CXMINIMIZED) = 2*SYSMET(CXFIXEDFRAME) + (int) lpmin->iWidth; SYSMET(CYMINIMIZED) = 2*SYSMET(CYFIXEDFRAME) + SYSMET(CYSIZE);
SYSMET(CXMINSPACING) = SYSMET(CXMINIMIZED) + (int) lpmin->iHorzGap; SYSMET(CYMINSPACING) = SYSMET(CYMINIMIZED) + (int) lpmin->iVertGap;
SYSMET(ARRANGE) = (int) lpmin->iArrange; }
BOOL SetIconMetrics( PUNICODE_STRING pProfileUserName, LPICONMETRICS lpicon) { ICONMETRICS icon;
if (!SetIconFonts(pProfileUserName,lpicon)) { RIPMSG0(RIP_WARNING, "SetIconMetrics failed in SetIconFonts"); return FALSE; }
if (!lpicon) {
icon.iTitleWrap = MetricGetID(pProfileUserName, STR_ICONTITLEWRAP, TRUE);
icon.iHorzSpacing = MetricGetID(pProfileUserName, STR_ICONHORZSPACING, (GreGetDeviceCaps(HDCBITS(), LOGPIXELSX) * 75) / 96);
icon.iVertSpacing = MetricGetID(pProfileUserName, STR_ICONVERTSPACING, (GreGetDeviceCaps(HDCBITS(), LOGPIXELSY) * 75) / 96);
lpicon = &icon; }
/*
* SANITY CHECK for metric values */ lpicon->iHorzSpacing = max(lpicon->iHorzSpacing, (int)SYSMET(CXICON)); lpicon->iVertSpacing = max(lpicon->iVertSpacing, (int)SYSMET(CYICON));
SYSMET(CXICONSPACING) = (int) lpicon->iHorzSpacing; SYSMET(CYICONSPACING) = (int) lpicon->iVertSpacing; SET_OR_CLEAR_PUDF(PUDF_ICONTITLEWRAP, lpicon->iTitleWrap);
return TRUE; }
/***************************************************************************\
* xxxMB_FindLongestString * * History: * 10-23-90 DarrinM Ported from Win 3.0 sources. * 01-21-98 SamerA Renamed to xxx since it may leave the crit sec if * a client LPK is installed. \***************************************************************************/
UINT xxxMB_FindLongestString(HDC hdc) { UINT wRetVal; int i, iMaxLen = 0, iNewMaxLen; LPWSTR pszCurStr, szMaxStr; SIZE sizeOneChar; SIZE sizeMaxStr; PTHREADINFO ptiCurrent = PtiCurrentShared();
/*
* Be sure that MBStrings are already loaded. */ UserAssert(gpsi->MBStrings[0].szName[0] != TEXT('\0'));
/*
* We are assuming that the longest string is the widest one, * which is not always true. * What we really have to do is call PSMGetTextExtent for each string * and get the max width. * This behavior get rectified by workaround for bug #170582 * in CheckMsgFontDimensions(). Mhamid. */
for (i = 0; i < MAX_SEB_STYLES; i++) { pszCurStr = GETGPSIMBPSTR(i); if ((iNewMaxLen = wcslen(pszCurStr)) > iMaxLen) { iMaxLen = iNewMaxLen; szMaxStr = pszCurStr; } }
/*
* Find the longest string */ if (CALL_LPK(ptiCurrent)) { xxxClientGetTextExtentPointW(hdc, (PWSTR)szOneChar, 1, &sizeOneChar); } else { GreGetTextExtentW(hdc, (PWSTR)szOneChar, 1, &sizeOneChar, GGTE_WIN3_EXTENT); } xxxPSMGetTextExtent(hdc, szMaxStr, iMaxLen, &sizeMaxStr); wRetVal = (UINT)(sizeMaxStr.cx + (sizeOneChar.cx * 2));
return wRetVal; }
|