📄 msstyles.c
字号:
*
* RETURNS
* The part/state found, or NULL
*/
PTHEME_PARTSTATE MSSTYLES_FindPartState(PTHEME_CLASS tc, int iPartId, int iStateId, PTHEME_CLASS *tcNext)
{
PTHEME_PARTSTATE cur = tc->partstate;
while(cur) {
if(cur->iPartId == iPartId && cur->iStateId == iStateId) {
if(tcNext) *tcNext = tc->overrides;
return cur;
}
cur = cur->next;
}
if(tc->overrides) return MSSTYLES_FindPartState(tc->overrides, iPartId, iStateId, tcNext);
return NULL;
}
/***********************************************************************
* MSSTYLES_AddPartState
*
* Add a part/state to a class
*
* PARAMS
* tc Theme class
* iPartId Part ID to add
* iStateId State ID to add
*
* RETURNS
* The part/state added, or a part/state previously added with the same IDs
*/
static PTHEME_PARTSTATE MSSTYLES_AddPartState(PTHEME_CLASS tc, int iPartId, int iStateId)
{
PTHEME_PARTSTATE cur = MSSTYLES_FindPartState(tc, iPartId, iStateId, NULL);
if(cur) return cur;
cur = HeapAlloc(GetProcessHeap(), 0, sizeof(THEME_PARTSTATE));
cur->iPartId = iPartId;
cur->iStateId = iStateId;
cur->properties = NULL;
cur->next = tc->partstate;
tc->partstate = cur;
return cur;
}
/***********************************************************************
* MSSTYLES_LFindProperty
*
* Find a property within a property list
*
* PARAMS
* tp property list to scan
* iPropertyPrimitive Type of value expected
* iPropertyId ID of the required value
*
* RETURNS
* The property found, or NULL
*/
static PTHEME_PROPERTY MSSTYLES_LFindProperty(PTHEME_PROPERTY tp, int iPropertyPrimitive, int iPropertyId)
{
PTHEME_PROPERTY cur = tp;
while(cur) {
if(cur->iPropertyId == iPropertyId) {
if(cur->iPrimitiveType == iPropertyPrimitive) {
return cur;
}
else {
if(!iPropertyPrimitive)
return cur;
return NULL;
}
}
cur = cur->next;
}
return NULL;
}
/***********************************************************************
* MSSTYLES_PSFindProperty
*
* Find a value within a part/state
*
* PARAMS
* ps Part/state to search
* iPropertyPrimitive Type of value expected
* iPropertyId ID of the required value
*
* RETURNS
* The property found, or NULL
*/
static inline PTHEME_PROPERTY MSSTYLES_PSFindProperty(PTHEME_PARTSTATE ps, int iPropertyPrimitive, int iPropertyId)
{
return MSSTYLES_LFindProperty(ps->properties, iPropertyPrimitive, iPropertyId);
}
/***********************************************************************
* MSSTYLES_FFindMetric
*
* Find a metric property for a theme file
*
* PARAMS
* tf Theme file
* iPropertyPrimitive Type of value expected
* iPropertyId ID of the required value
*
* RETURNS
* The property found, or NULL
*/
static inline PTHEME_PROPERTY MSSTYLES_FFindMetric(PTHEME_FILE tf, int iPropertyPrimitive, int iPropertyId)
{
return MSSTYLES_LFindProperty(tf->metrics, iPropertyPrimitive, iPropertyId);
}
/***********************************************************************
* MSSTYLES_FindMetric
*
* Find a metric property for the current installed theme
*
* PARAMS
* tf Theme file
* iPropertyPrimitive Type of value expected
* iPropertyId ID of the required value
*
* RETURNS
* The property found, or NULL
*/
PTHEME_PROPERTY MSSTYLES_FindMetric(int iPropertyPrimitive, int iPropertyId)
{
if(!tfActiveTheme) return NULL;
return MSSTYLES_FFindMetric(tfActiveTheme, iPropertyPrimitive, iPropertyId);
}
/***********************************************************************
* MSSTYLES_AddProperty
*
* Add a property to a part/state
*
* PARAMS
* ps Part/state
* iPropertyPrimitive Primitive type of the property
* iPropertyId ID of the property
* lpValue Raw value (non-NULL terminated)
* dwValueLen Length of the value
*
* RETURNS
* The property added, or a property previously added with the same IDs
*/
static PTHEME_PROPERTY MSSTYLES_AddProperty(PTHEME_PARTSTATE ps, int iPropertyPrimitive, int iPropertyId, LPCWSTR lpValue, DWORD dwValueLen, BOOL isGlobal)
{
PTHEME_PROPERTY cur = MSSTYLES_PSFindProperty(ps, iPropertyPrimitive, iPropertyId);
/* Should duplicate properties overwrite the original, or be ignored? */
if(cur) return cur;
cur = HeapAlloc(GetProcessHeap(), 0, sizeof(THEME_PROPERTY));
cur->iPrimitiveType = iPropertyPrimitive;
cur->iPropertyId = iPropertyId;
cur->lpValue = lpValue;
cur->dwValueLen = dwValueLen;
if(ps->iStateId)
cur->origin = PO_STATE;
else if(ps->iPartId)
cur->origin = PO_PART;
else if(isGlobal)
cur->origin = PO_GLOBAL;
else
cur->origin = PO_CLASS;
cur->next = ps->properties;
ps->properties = cur;
return cur;
}
/***********************************************************************
* MSSTYLES_AddMetric
*
* Add a property to a part/state
*
* PARAMS
* tf Theme file
* iPropertyPrimitive Primitive type of the property
* iPropertyId ID of the property
* lpValue Raw value (non-NULL terminated)
* dwValueLen Length of the value
*
* RETURNS
* The property added, or a property previously added with the same IDs
*/
static PTHEME_PROPERTY MSSTYLES_AddMetric(PTHEME_FILE tf, int iPropertyPrimitive, int iPropertyId, LPCWSTR lpValue, DWORD dwValueLen)
{
PTHEME_PROPERTY cur = MSSTYLES_FFindMetric(tf, iPropertyPrimitive, iPropertyId);
/* Should duplicate properties overwrite the original, or be ignored? */
if(cur) return cur;
cur = HeapAlloc(GetProcessHeap(), 0, sizeof(THEME_PROPERTY));
cur->iPrimitiveType = iPropertyPrimitive;
cur->iPropertyId = iPropertyId;
cur->lpValue = lpValue;
cur->dwValueLen = dwValueLen;
cur->origin = PO_GLOBAL;
cur->next = tf->metrics;
tf->metrics = cur;
return cur;
}
/* Color-related state for theme ini parsing */
struct PARSECOLORSTATE
{
int colorCount;
int colorElements[TMT_LASTCOLOR-TMT_FIRSTCOLOR];
COLORREF colorRgb[TMT_LASTCOLOR-TMT_FIRSTCOLOR];
int captionColors;
};
static inline void parse_init_color (struct PARSECOLORSTATE* state)
{
memset (state, 0, sizeof (*state));
}
static BOOL parse_handle_color_property (struct PARSECOLORSTATE* state,
int iPropertyId, LPCWSTR lpValue,
DWORD dwValueLen)
{
int r,g,b;
LPCWSTR lpValueEnd = lpValue + dwValueLen;
MSSTYLES_GetNextInteger(lpValue, lpValueEnd, &lpValue, &r);
MSSTYLES_GetNextInteger(lpValue, lpValueEnd, &lpValue, &g);
if(MSSTYLES_GetNextInteger(lpValue, lpValueEnd, &lpValue, &b)) {
state->colorElements[state->colorCount] = iPropertyId - TMT_FIRSTCOLOR;
state->colorRgb[state->colorCount++] = RGB(r,g,b);
switch (iPropertyId)
{
case TMT_ACTIVECAPTION:
state->captionColors |= 0x1;
break;
case TMT_INACTIVECAPTION:
state->captionColors |= 0x2;
break;
case TMT_GRADIENTACTIVECAPTION:
state->captionColors |= 0x4;
break;
case TMT_GRADIENTINACTIVECAPTION:
state->captionColors |= 0x8;
break;
}
return TRUE;
}
else {
return FALSE;
}
}
static void parse_apply_color (struct PARSECOLORSTATE* state)
{
if (state->colorCount > 0)
SetSysColors(state->colorCount, state->colorElements, state->colorRgb);
if (state->captionColors == 0xf)
SystemParametersInfoW (SPI_SETGRADIENTCAPTIONS, 0, (PVOID)TRUE, 0);
}
/* Non-client-metrics-related state for theme ini parsing */
struct PARSENONCLIENTSTATE
{
NONCLIENTMETRICSW metrics;
BOOL metricsDirty;
LOGFONTW iconTitleFont;
};
static inline void parse_init_nonclient (struct PARSENONCLIENTSTATE* state)
{
memset (state, 0, sizeof (*state));
state->metrics.cbSize = sizeof (NONCLIENTMETRICSW);
SystemParametersInfoW (SPI_GETNONCLIENTMETRICS, sizeof (NONCLIENTMETRICSW),
(PVOID)&state->metrics, 0);
SystemParametersInfoW (SPI_GETICONTITLELOGFONT, sizeof (LOGFONTW),
(PVOID)&state->iconTitleFont, 0);
}
static BOOL parse_handle_nonclient_font (struct PARSENONCLIENTSTATE* state,
int iPropertyId, LPCWSTR lpValue,
DWORD dwValueLen)
{
LOGFONTW font;
memset (&font, 0, sizeof (font));
if (SUCCEEDED (MSSTYLES_GetFont (lpValue, lpValue + dwValueLen, &lpValue,
&font)))
{
switch (iPropertyId)
{
case TMT_CAPTIONFONT:
memcpy (&state->metrics.lfCaptionFont, &font, sizeof (LOGFONTW));
state->metricsDirty = TRUE;
break;
case TMT_SMALLCAPTIONFONT:
memcpy (&state->metrics.lfSmCaptionFont, &font, sizeof (LOGFONTW));
state->metricsDirty = TRUE;
break;
case TMT_MENUFONT:
memcpy (&state->metrics.lfMenuFont, &font, sizeof (LOGFONTW));
state->metricsDirty = TRUE;
break;
case TMT_STATUSFONT:
memcpy (&state->metrics.lfStatusFont, &font, sizeof (LOGFONTW));
state->metricsDirty = TRUE;
break;
case TMT_MSGBOXFONT:
memcpy (&state->metrics.lfMessageFont, &font, sizeof (LOGFONTW));
state->metricsDirty = TRUE;
break;
case TMT_ICONTITLEFONT:
memcpy (&state->iconTitleFont, &font, sizeof (LOGFONTW));
state->metricsDirty = TRUE;
break;
}
return TRUE;
}
else
return FALSE;
}
static BOOL parse_handle_nonclient_size (struct PARSENONCLIENTSTATE* state,
int iPropertyId, LPCWSTR lpValue,
DWORD dwValueLen)
{
int size;
LPCWSTR lpValueEnd = lpValue + dwValueLen;
if(MSSTYLES_GetNextInteger(lpValue, lpValueEnd, &lpValue, &size)) {
switch (iPropertyId)
{
case TMT_SIZINGBORDERWIDTH:
state->metrics.iBorderWidth = size;
state->metricsDirty = TRUE;
break;
case TMT_SCROLLBARWIDTH:
state->metrics.iScrollWidth = size;
state->metricsDirty = TRUE;
break;
case TMT_SCROLLBARHEIGHT:
state->metrics.iScrollHeight = size;
state->metricsDirty = TRUE;
break;
case TMT_CAPTIONBARWIDTH:
state->metrics.iCaptionWidth = size;
state->metricsDirty = TRUE;
break;
case TMT_CAPTIONBARHEIGHT:
state->metrics.iCaptionHeight = size;
state->metricsDirty = TRUE;
break;
case TMT_SMCAPTIONBARWIDTH:
state->metrics.iSmCaptionWidth = size;
state->metricsDirty = TRUE;
break;
case TMT_SMCAPTIONBARHEIGHT:
state->metrics.iSmCaptionHeight = size;
state->metricsDirty = TRUE;
break;
case TMT_MENUBARWIDTH:
state->metrics.iMenuWidth = size;
state->metricsDirty = TRUE;
break;
case TMT_MENUBARHEIGHT:
state->metrics.iMenuHeight = size;
state->metricsDirty = TRUE;
break;
}
return TRUE;
}
else
return FALSE;
}
static void parse_apply_nonclient (struct PARSENONCLIENTSTATE* state)
{
if (state->metricsDirty)
{
SystemParametersInfoW (SPI_SETNONCLIENTMETRICS, sizeof (state->metrics),
(PVOID)&state->metrics, 0);
SystemParametersInfoW (SPI_SETICONTITLELOGFONT, sizeof (state->iconTitleFont),
(PVOID)&state->iconTitleFont, 0);
}
}
/***********************************************************************
* MSSTYLES_ParseThemeIni
*
* Parse the theme ini for the selected color/style
*
* PARAMS
* tf Theme to parse
*/
void MSSTYLES_ParseThemeIni(PTHEME_FILE tf, BOOL setMetrics)
{
static const WCHAR szSysMetrics[] = {'S','y','s','M','e','t','r','i','c','s','\0'};
static const WCHAR szGlobals[] = {'g','l','o','b','a','l','s','\0'};
PTHEME_CLASS cls;
PTHEME_CLASS globals;
PTHEME_PARTSTATE ps;
PUXINI_FILE ini;
WCHAR szAppName[MAX_THEME_APP_NAME];
WCHAR szClassName[MAX_THEME_CLASS_NAME];
WCHAR szPropertyName[MAX_THEME_VALUE_NAME];
int iPartId;
int iStateId;
int iPropertyPrimitive;
int iPropertyId;
DWORD dwLen;
LPCWSTR lpName;
DWORD dwValueLen;
LPCWSTR lpValue;
ini = MSSTYLES_GetActiveThemeIni(tf);
while((lpName=UXINI_GetNextSection(ini, &dwLen))) {
if(CompareStringW(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, lpName, dwLen, szSysMetrics, -1) == CSTR_EQUAL) {
struct PARSECOLORSTATE colorState;
struct PARSENONCLIENTSTATE nonClientState;
parse_init_color (&colorState);
parse_init_nonclient (&nonClientState);
while((lpName=UXINI_GetNextValue(ini, &dwLen, &lpValue, &dwValueLen))) {
lstrcpynW(szPropertyName, lpName, min(dwLen+1, sizeof(szPropertyName)/sizeof(szPropertyName[0])));
if(MSSTYLES_LookupProperty(szPropertyName, &iPropertyPrimitive, &iPropertyId)) {
if(iPropertyId >= TMT_FIRSTCOLOR && iPropertyId <= TMT_LASTCOLOR) {
if (!parse_handle_color_property (&colorState, iPropertyId,
lpValue, dwValueLen))
FIXME("Invalid color value for %s\n",
debugstr_w(szPropertyName));
}
else if (setMetrics && (iPropertyId == TMT_FLATMENUS)) {
BOOL flatMenus = (*lpValue == 'T') || (*lpValue == 't');
SystemParametersInfoW (SPI_SETFLATMENU, 0, (PVOID)(INT_PTR)flatMenus, 0);
}
else if ((iPropertyId >= TMT_FIRSTFONT)
&& (iPropertyId <= TMT_LASTFONT))
{
if (!parse_handle_nonclient_font (&nonClientState,
iPropertyId, lpValue, dwValueLen))
FIXME("Invalid font value for %s\n",
debugstr_w(szPropertyName));
}
else if ((iPropertyId >= TMT_FIRSTSIZE)
&& (iPropertyId <= TMT_LASTSIZE))
{
if (!parse_handle_nonclient_size (&nonClientState,
iPropertyId, lpValue, dwValueLen))
FIXME("Invalid size value for %s\n",
debugstr_w(szPropertyName));
}
/* Catch all metrics, including colors */
MSSTYLES_AddMetric(tf, iPropertyPrimitive, iPropertyId, lpValue, dwValueLen);
}
else {
TRACE("Unknown system metric %s\n", debugstr_w(szPropertyName));
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -