mirror of https://github.com/lianthony/NT4.0
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.
1155 lines
36 KiB
1155 lines
36 KiB
/***************************************************************************\
|
|
*
|
|
* INCTLPAN.C
|
|
*
|
|
* Copyright (c) 1985-95, Microsoft Corporation
|
|
*
|
|
* Init Routines which are also used by Control Panel
|
|
*
|
|
* -- Scalable Window Frame Support
|
|
*
|
|
* exports from this module:
|
|
* > SetCaretBlinkTime -- API called internally (kinda) by control panel
|
|
* > SetKeyboardSpeed -- called by LoadWindows & SystemParametersInfo
|
|
* > SetMinMaxInfo -- called by LoadWindows & SystemParemetersInfo
|
|
* > SetWindowMetrics -- called by LoadWindows & SystemParametersInfo
|
|
*
|
|
\***************************************************************************/
|
|
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
#define MetricGetID(str, default) \
|
|
FastGetProfileIntFromID(PMAP_METRICS, str, default)
|
|
|
|
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_INACTIVE, // OBI_CLOSE_I
|
|
DFC_CAPTION, DFCS_CAPTIONMIN, // OBI_REDUCE
|
|
DFC_CAPTION, DFCS_CAPTIONMIN | DFCS_PUSHED, // OBI_REDUCE_D
|
|
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_CAPTIONHELP, // OBI_HELP
|
|
DFC_CAPTION, DFCS_CAPTIONHELP | DFCS_PUSHED, // OBI_HELP_D
|
|
DFC_CAPTION, DFCS_CAPTIONMAX, // OBI_ZOOM
|
|
DFC_CAPTION, DFCS_CAPTIONMAX | DFCS_PUSHED, // OBI_ZOOM_D
|
|
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_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_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_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_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_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_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_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_INACTIVE, // OBI_LFARROW_I
|
|
DFC_MENU, DFCS_MENUARROW, // OBI_MENUARROW
|
|
DFC_MENU, DFCS_MENUCHECK, // OBI_MENUCHECK
|
|
DFC_MENU, DFCS_MENUBULLET, // OBI_MENUBULLET
|
|
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
|
|
};
|
|
|
|
#define DIVISOR 72
|
|
|
|
UINT MB_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
|
|
|
|
/***************************************************************************\
|
|
\***************************************************************************/
|
|
|
|
int GetSetProfileStructFromResID(
|
|
UINT idSection,
|
|
UINT id,
|
|
LPVOID pv,
|
|
UINT cbv,
|
|
BOOL fSet)
|
|
{
|
|
WCHAR szKey[40];
|
|
|
|
ServerLoadString(hModuleWin, id, szKey, sizeof(szKey));
|
|
if (fSet) {
|
|
return UT_FastWriteProfileValue(idSection, szKey, REG_BINARY, pv, cbv);
|
|
} else {
|
|
return UT_FastGetProfileValue(idSection, szKey, NULL, pv, cbv);
|
|
}
|
|
}
|
|
|
|
/***************************************************************************\
|
|
*
|
|
* 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 = oemInfo.bm + 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:
|
|
/*
|
|
* Add on proper space for space above underscore.
|
|
* the 0xFFFE and -1 are to insure an ODD height
|
|
*/
|
|
cy = ((cyMenuFontChar + cyMenuFontExternLeading + 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 {
|
|
cx = 13;
|
|
cy = 13;
|
|
}
|
|
break;
|
|
}
|
|
|
|
pOem->cx = cx;
|
|
pOem->cy = cy;
|
|
|
|
return((cx > cxMax) ? cx : cxMax);
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
*
|
|
* 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 = oemInfo.bm;
|
|
|
|
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(gpDispInfo->hdcBits, x, y, OBI_REDUCE);
|
|
x += SYSMET(CXSIZE) - SYSMET(CXEDGE);
|
|
BitBltSysBmp(gpDispInfo->hdcBits, x, y, OBI_ZOOM);
|
|
x += SYSMET(CXSIZE);
|
|
BitBltSysBmp(gpDispInfo->hdcBits, x, y, OBI_CLOSE);
|
|
x += SYSMET(CXSIZE);
|
|
BitBltSysBmp(gpDispInfo->hdcBits, x, y, OBI_HELP);
|
|
}
|
|
|
|
/***************************************************************************\
|
|
* CreateCaptionStrip
|
|
*
|
|
*
|
|
\***************************************************************************/
|
|
HBITMAP CreateCaptionStrip(VOID)
|
|
{
|
|
HBITMAP hbm;
|
|
|
|
hbm = GreCreateCompatibleBitmap(gpDispInfo->hdcScreen,
|
|
SYSMET(CXSCREEN),
|
|
(SYSMET(CYCAPTION) - 1) * 2);
|
|
|
|
if (hbm)
|
|
GreSetBitmapOwner(hbm, OBJECT_OWNER_PUBLIC);
|
|
|
|
return hbm;
|
|
}
|
|
|
|
int cy[5];
|
|
|
|
/***************************************************************************\
|
|
*
|
|
* 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.
|
|
*
|
|
\***************************************************************************/
|
|
void CreateBitmapStrip(void) {
|
|
int cxBmp = 0;
|
|
int cyBmp = 0;
|
|
int iCache = 0;
|
|
HBITMAP hOldBitmap;
|
|
HBITMAP hNewBmp;
|
|
UINT iType;
|
|
RECT rc;
|
|
UINT wBmpType;
|
|
UINT wBmpStyle;
|
|
POEMBITMAPINFO pOem;
|
|
|
|
/*
|
|
* 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);
|
|
GreSetBitmapOwner(hNewBmp, OBJECT_OWNER_PUBLIC);
|
|
|
|
/*
|
|
* Select in Bitmap Strip -- then delete old one if it exists
|
|
* Yanked for Chicago since these can now be paged
|
|
* GDIMoveBitmap(hNewBmp);
|
|
*/
|
|
hOldBitmap = GreSelectBitmap(gpDispInfo->hdcBits, hNewBmp);
|
|
|
|
if (hbmBits) {
|
|
UserAssert(hbmBits == hOldBitmap);
|
|
GreDeleteObject(ghbmCaption);
|
|
GreDeleteObject(hOldBitmap);
|
|
} else {
|
|
/*
|
|
* hack to clear out display driver's font cache
|
|
*/
|
|
GreExtTextOutW(gpDispInfo->hdcBits, 0, 0, 0, NULL, szOneChar, 1, NULL);
|
|
}
|
|
|
|
hbmBits = hNewBmp;
|
|
|
|
ghbmCaption = CreateCaptionStrip();
|
|
|
|
/*
|
|
* draw individual bitmaps into the strip bitmap and record the offsets
|
|
*/
|
|
for (pOem = oemInfo.bm, iType = 0; iType < OBI_COUNT; iType++, pOem++) {
|
|
if (!pOem->cx) {
|
|
*pOem = oemInfo.bm[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) {
|
|
FillRect(gpDispInfo->hdcBits, &rc, (wBmpStyle & DFCS_INACTIVE) ? SYSHBR(INACTIVECAPTION) : SYSHBR(ACTIVECAPTION));
|
|
DrawCaptionButtons(rc.left, rc.top);
|
|
} else if (!(wBmpStyle & DFCS_INACTIVE)) {
|
|
/*
|
|
* Setup Caption Cache Entry
|
|
*/
|
|
UserAssert(iCache < CCACHEDCAPTIONS);
|
|
if (cachedCaptions[iCache].spcursor) {
|
|
Unlock(&(cachedCaptions[iCache].spcursor));
|
|
}
|
|
cachedCaptions[iCache++].pOem = pOem;
|
|
}
|
|
} else {
|
|
DrawFrameControl(gpDispInfo->hdcBits, &rc, wBmpType, wBmpStyle);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Setup other frame metric dependent values.
|
|
*/
|
|
SYSMET(CXMENUCHECK) = oemInfo.bm[OBI_MENUCHECK].cx;
|
|
SYSMET(CYMENUCHECK) = oemInfo.bm[OBI_MENUCHECK].cy;
|
|
}
|
|
|
|
void NEAR 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) + (cxCaptionFontChar * 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(CXSCREEN) + (2 * (SYSMET(CXSIZEFRAME) + SYSMET(CXEDGE)));
|
|
SYSMET(CYMAXTRACK) = SYSMET(CYSCREEN) + (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(
|
|
LPLOGFONTW lplf,
|
|
UINT idFont)
|
|
{
|
|
LOGFONTW lf;
|
|
HFONT hFont;
|
|
|
|
if (lplf == NULL) {
|
|
static WCHAR szDefFont[] = TEXT("MS Sans Serif");
|
|
/*
|
|
* Fill logfont w/ 0 so we can check if values were filled in.
|
|
*/
|
|
lplf = &lf;
|
|
RtlFillMemory(lplf, sizeof(LOGFONTW), 0);
|
|
|
|
GetSetProfileStructFromResID(PMAP_METRICS, idFont, &lf, sizeof(LOGFONTW), FALSE);
|
|
|
|
/*
|
|
* Default font is MS Sans Serif
|
|
*/
|
|
if (! lf.lfFaceName[0])
|
|
wcscpy(lf.lfFaceName, szDefFont);
|
|
|
|
if (!lf.lfHeight) {
|
|
switch (idFont) {
|
|
case STR_SMCAPTIONFONT:
|
|
lf.lfHeight = 4;
|
|
break;
|
|
|
|
case STR_MINFONT:
|
|
case STR_ICONFONT:
|
|
lf.lfHeight = 6;
|
|
break;
|
|
|
|
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 = -UserMulDiv(lf.lfHeight, oemInfo.cyPixelsPerInch, 72);
|
|
}
|
|
|
|
if (! lf.lfWeight) {
|
|
switch (idFont) {
|
|
case STR_CAPTIONFONT:
|
|
case STR_MINFONT:
|
|
lf.lfWeight = FW_BOLD;
|
|
break;
|
|
|
|
default:
|
|
lf.lfWeight = FW_NORMAL;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* LATER - Win95 calls GetTextCharset here */
|
|
lf.lfCharSet = ANSI_CHARSET;
|
|
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 ||
|
|
_wcsicmp(lfT.lfFaceName, lplf->lfFaceName)) {
|
|
/*
|
|
* Couldn't find a font with the height or facename 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;
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
*
|
|
\***************************************************************************/
|
|
|
|
void UserSetFont(
|
|
LPLOGFONTW lplf,
|
|
UINT idFont,
|
|
HFONT *phfont)
|
|
{
|
|
HFONT hNewFont;
|
|
|
|
if (hNewFont = CreateFontFromWinIni(lplf, idFont)) {
|
|
if (*phfont != NULL && *phfont != ghFontSys) {
|
|
GreMarkDeletableFont(*phfont);
|
|
GreDeleteObject(*phfont);
|
|
}
|
|
|
|
*phfont = hNewFont;
|
|
}
|
|
}
|
|
|
|
/***************************************************************************\
|
|
*
|
|
* SetFrameFonts() -
|
|
*
|
|
* Creates fonts to be used in the frame components:
|
|
* Caption
|
|
* Small caption
|
|
* Menu
|
|
* Minimized
|
|
* Icon
|
|
*
|
|
\***************************************************************************/
|
|
VOID SetNCFonts(
|
|
LPNONCLIENTMETRICS lpnc)
|
|
{
|
|
HFONT hOldFont;
|
|
TEXTMETRIC tm;
|
|
LOGFONTW lf;
|
|
LPLOGFONTW lplf = (lpnc) ? &lf : 0;
|
|
|
|
/*
|
|
* Caption font
|
|
*/
|
|
if (lplf) {
|
|
*lplf = lpnc->lfCaptionFont;
|
|
}
|
|
UserSetFont(lplf, STR_CAPTIONFONT, &gpsi->hCaptionFont);
|
|
|
|
hOldFont = GreSelectFont(gpDispInfo->hdcBits, gpsi->hCaptionFont);
|
|
cxCaptionFontChar = GetCharDimensions(gpDispInfo->hdcBits, NULL, &cyCaptionFontChar);
|
|
|
|
/*
|
|
* Small caption font
|
|
*/
|
|
if (lplf) {
|
|
*lplf = lpnc->lfSmCaptionFont;
|
|
}
|
|
UserSetFont(lplf, STR_SMCAPTIONFONT, &ghSmCaptionFont);
|
|
|
|
GreSelectFont(gpDispInfo->hdcBits, ghSmCaptionFont);
|
|
cxSmCaptionFontChar = GetCharDimensions(gpDispInfo->hdcBits, NULL, &cySmCaptionFontChar);
|
|
|
|
/*
|
|
* Menu font
|
|
*/
|
|
if (lplf) {
|
|
*lplf = lpnc->lfMenuFont;
|
|
}
|
|
UserSetFont(lplf, STR_MENUFONT, &ghMenuFont);
|
|
|
|
GreSelectFont(gpDispInfo->hdcBits, ghMenuFont);
|
|
cxMenuFontChar = GetCharDimensions(gpDispInfo->hdcBits, &tm, &cyMenuFontChar);
|
|
cxMenuFontOverhang = tm.tmOverhang;
|
|
|
|
cyMenuFontExternLeading = tm.tmExternalLeading;
|
|
cyMenuFontAscent = tm.tmAscent;
|
|
#ifndef KOREA
|
|
/*
|
|
* We only use cyMenuFontAscent in mndraw.c once, and in U.S. we
|
|
* always add on CYBORDER! So calculate cyMenuFontAscent+CYBORDER
|
|
* once only. For Korean version, don't add it on; the underline would
|
|
* be too low.
|
|
*/
|
|
cyMenuFontAscent += SYSMET(CYBORDER);
|
|
#endif
|
|
|
|
/*
|
|
* 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;
|
|
}
|
|
UserSetFont(lplf, STR_STATUSFONT, &ghStatusFont);
|
|
|
|
/*
|
|
* Message Box font
|
|
*/
|
|
if (lplf) {
|
|
*lplf = lpnc->lfMessageFont;
|
|
}
|
|
UserSetFont(lplf, STR_MESSAGEFONT, &gpsi->hMsgFont);
|
|
|
|
GreSelectFont(gpDispInfo->hdcBits, gpsi->hMsgFont);
|
|
gpsi->cxMsgFontChar = GetCharDimensions(gpDispInfo->hdcBits, NULL, &gpsi->cyMsgFontChar);
|
|
|
|
/*
|
|
* Recalculate length of the biggest MessageBox string
|
|
*/
|
|
gpsi->wMaxBtnSize = MB_FindLongestString(gpDispInfo->hdcBits);
|
|
|
|
GreSelectFont(gpDispInfo->hdcBits, hOldFont);
|
|
}
|
|
|
|
void SetIconFonts(LPICONMETRICS lpicon) {
|
|
LOGFONTW lf;
|
|
LPLOGFONTW lplf = 0;
|
|
|
|
if (lpicon) {
|
|
lplf = &lf;
|
|
lf = lpicon->lfFont;
|
|
}
|
|
|
|
UserSetFont(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));
|
|
}
|
|
|
|
/***************************************************************************\
|
|
*
|
|
* SetWindowMetrics() -
|
|
*
|
|
* 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.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
VOID SetWindowNCMetrics(
|
|
LPNONCLIENTMETRICS lpnc,
|
|
BOOL fSizeChange,
|
|
int clNewBorder)
|
|
{
|
|
NONCLIENTMETRICS nc;
|
|
int cxEdge4;
|
|
|
|
if (fSizeChange) {
|
|
|
|
SetNCFonts(lpnc);
|
|
|
|
if (!lpnc) {
|
|
|
|
if (clNewBorder < 0)
|
|
nc.iBorderWidth = MetricGetID(STR_BORDERWIDTH, 1);
|
|
else
|
|
nc.iBorderWidth = clNewBorder;
|
|
|
|
nc.iScrollWidth = MetricGetID(STR_SCROLLWIDTH, 16);
|
|
nc.iScrollHeight = MetricGetID(STR_SCROLLHEIGHT, 16);
|
|
nc.iCaptionWidth = MetricGetID(STR_CAPTIONWIDTH, 18);
|
|
nc.iCaptionHeight = MetricGetID(STR_CAPTIONHEIGHT, 18);
|
|
nc.iSmCaptionWidth = MetricGetID(STR_SMCAPTIONWIDTH, 13);
|
|
nc.iSmCaptionHeight = MetricGetID(STR_SMCAPTIONHEIGHT, 13);
|
|
nc.iMenuWidth = MetricGetID(STR_MENUWIDTH, 18);
|
|
nc.iMenuHeight = MetricGetID(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, cyCaptionFontChar + 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, cySmCaptionFontChar + 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, cyMenuFontChar + cyMenuFontExternLeading + SYSMET(CYEDGE));
|
|
|
|
/*
|
|
* SET UP SYSTEM METRIC VALUES
|
|
*/
|
|
SetNCMetrics(lpnc);
|
|
}
|
|
|
|
CreateBitmapStrip();
|
|
}
|
|
|
|
|
|
VOID SetMinMetrics(
|
|
LPMINIMIZEDMETRICS lpmin)
|
|
{
|
|
MINIMIZEDMETRICS min;
|
|
|
|
if (!lpmin) {
|
|
|
|
/*
|
|
* Minimized
|
|
*/
|
|
min.iWidth = MetricGetID(STR_MINWIDTH, 154);
|
|
min.iHorzGap = MetricGetID(STR_MINHORZGAP, 0);
|
|
min.iVertGap = MetricGetID(STR_MINVERTGAP, 0);
|
|
min.iArrange = MetricGetID(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;
|
|
}
|
|
|
|
VOID SetIconMetrics(LPICONMETRICS lpicon)
|
|
{
|
|
ICONMETRICS icon;
|
|
|
|
SetIconFonts(lpicon);
|
|
|
|
if (!lpicon) {
|
|
|
|
icon.iTitleWrap = MetricGetID(STR_ICONTITLEWRAP, TRUE);
|
|
icon.iHorzSpacing = MetricGetID(STR_ICONHORZSPACING,
|
|
(GreGetDeviceCaps(gpDispInfo->hdcBits, LOGPIXELSX) * 75) / 96);
|
|
icon.iVertSpacing = MetricGetID(STR_ICONVERTSPACING,
|
|
(GreGetDeviceCaps(gpDispInfo->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;
|
|
fIconTitleWrap = (int) lpicon->iTitleWrap;
|
|
}
|
|
|
|
/***************************************************************************\
|
|
* MB_FindLongestString
|
|
*
|
|
* History:
|
|
* 10-23-90 DarrinM Ported from Win 3.0 sources.
|
|
\***************************************************************************/
|
|
|
|
UINT MB_FindLongestString(HDC hdc)
|
|
{
|
|
UINT wRetVal;
|
|
int i, iMaxLen = 0, iNewMaxLen;
|
|
LPWSTR pszCurStr, szMaxStr;
|
|
SIZE sizeOneChar;
|
|
SIZE sizeMaxStr;
|
|
|
|
for (i = 0; i < MAX_SEB_STYLES; i++) {
|
|
pszCurStr = GETGPSIMBPSTR(i);
|
|
if ((iNewMaxLen = wcslen(pszCurStr)) > iMaxLen) {
|
|
iMaxLen = iNewMaxLen;
|
|
szMaxStr = pszCurStr;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Find the longest string
|
|
*/
|
|
GreGetTextExtentW(hdc, szOneChar, 1, &sizeOneChar, GGTE_WIN3_EXTENT);
|
|
PSMGetTextExtent(hdc, szMaxStr, iMaxLen, &sizeMaxStr);
|
|
wRetVal = (UINT)(sizeMaxStr.cx + (sizeOneChar.cx * 2));
|
|
|
|
return wRetVal;
|
|
}
|