⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 msstyles.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
 *
 * 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 + -