📄 system.c
字号:
{
NONCLIENTMETRICSW ncm;
LOGFONTW iconTitleFont;
DWORD count = sizeof(ncm);
DWORD type;
if (RegQueryValueExW (hKey, keyNonClientMetrics, 0,
&type, (LPBYTE)&ncm, &count) == ERROR_SUCCESS)
{
SystemParametersInfoW (SPI_SETNONCLIENTMETRICS,
count, (LPVOID)&ncm, SPIF_UPDATEINIFILE);
}
count = sizeof(iconTitleFont);
if (RegQueryValueExW (hKey, keyIconTitleFont, 0,
&type, (LPBYTE)&iconTitleFont, &count) == ERROR_SUCCESS)
{
SystemParametersInfoW (SPI_SETICONTITLELOGFONT,
count, (LPVOID)&iconTitleFont, SPIF_UPDATEINIFILE);
}
}
RegCloseKey (hKey);
}
}
/* Make system settings persistent, so they're in effect even w/o uxtheme
* loaded.
* For efficiency reasons, only the last SystemParametersInfoW sets
* SPIF_SENDWININICHANGE */
static void UXTHEME_SaveSystemMetrics(void)
{
const struct BackupSysParam* bsp = backupSysParams;
NONCLIENTMETRICSW ncm;
LOGFONTW iconTitleFont;
save_sys_colors (HKEY_CURRENT_USER);
while (bsp->spiGet >= 0)
{
DWORD value;
SystemParametersInfoW (bsp->spiGet, 0, &value, 0);
SystemParametersInfoW (bsp->spiSet, 0, (LPVOID)value,
SPIF_UPDATEINIFILE);
bsp++;
}
memset (&ncm, 0, sizeof (ncm));
ncm.cbSize = sizeof (ncm);
SystemParametersInfoW (SPI_GETNONCLIENTMETRICS,
sizeof (ncm), (LPVOID)&ncm, 0);
SystemParametersInfoW (SPI_SETNONCLIENTMETRICS,
sizeof (ncm), (LPVOID)&ncm, SPIF_UPDATEINIFILE);
memset (&iconTitleFont, 0, sizeof (iconTitleFont));
SystemParametersInfoW (SPI_GETICONTITLELOGFONT,
sizeof (iconTitleFont), (LPVOID)&iconTitleFont, 0);
SystemParametersInfoW (SPI_SETICONTITLELOGFONT,
sizeof (iconTitleFont), (LPVOID)&iconTitleFont,
SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
}
/***********************************************************************
* UXTHEME_SetActiveTheme
*
* Change the current active theme
*/
static HRESULT UXTHEME_SetActiveTheme(PTHEME_FILE tf)
{
HKEY hKey;
WCHAR tmp[2];
HRESULT hr;
if(tf && !bThemeActive) UXTHEME_BackupSystemMetrics();
hr = MSSTYLES_SetActiveTheme(tf, TRUE);
if(FAILED(hr))
return hr;
if(tf) {
bThemeActive = TRUE;
lstrcpynW(szCurrentTheme, tf->szThemeFile, sizeof(szCurrentTheme)/sizeof(szCurrentTheme[0]));
lstrcpynW(szCurrentColor, tf->pszSelectedColor, sizeof(szCurrentColor)/sizeof(szCurrentColor[0]));
lstrcpynW(szCurrentSize, tf->pszSelectedSize, sizeof(szCurrentSize)/sizeof(szCurrentSize[0]));
}
else {
UXTHEME_RestoreSystemMetrics();
bThemeActive = FALSE;
szCurrentTheme[0] = '\0';
szCurrentColor[0] = '\0';
szCurrentSize[0] = '\0';
}
TRACE("Writing theme config to registry\n");
if(!RegCreateKeyW(HKEY_CURRENT_USER, szThemeManager, &hKey)) {
tmp[0] = bThemeActive?'1':'0';
tmp[1] = '\0';
RegSetValueExW(hKey, szThemeActive, 0, REG_SZ, (const BYTE*)tmp, sizeof(WCHAR)*2);
if(bThemeActive) {
RegSetValueExW(hKey, szColorName, 0, REG_SZ, (const BYTE*)szCurrentColor,
(lstrlenW(szCurrentColor)+1)*sizeof(WCHAR));
RegSetValueExW(hKey, szSizeName, 0, REG_SZ, (const BYTE*)szCurrentSize,
(lstrlenW(szCurrentSize)+1)*sizeof(WCHAR));
RegSetValueExW(hKey, szDllName, 0, REG_SZ, (const BYTE*)szCurrentTheme,
(lstrlenW(szCurrentTheme)+1)*sizeof(WCHAR));
}
else {
RegDeleteValueW(hKey, szColorName);
RegDeleteValueW(hKey, szSizeName);
RegDeleteValueW(hKey, szDllName);
}
RegCloseKey(hKey);
}
else
TRACE("Failed to open theme registry key\n");
UXTHEME_SaveSystemMetrics ();
return hr;
}
/***********************************************************************
* UXTHEME_InitSystem
*/
void UXTHEME_InitSystem(HINSTANCE hInst)
{
static const WCHAR szWindowTheme[] = {
'u','x','_','t','h','e','m','e','\0'
};
static const WCHAR szSubAppName[] = {
'u','x','_','s','u','b','a','p','p','\0'
};
static const WCHAR szSubIdList[] = {
'u','x','_','s','u','b','i','d','l','s','t','\0'
};
static const WCHAR szDialogThemeEnabled[] = {
'u','x','_','d','i','a','l','o','g','t','h','e','m','e','\0'
};
hDllInst = hInst;
atWindowTheme = GlobalAddAtomW(szWindowTheme);
atSubAppName = GlobalAddAtomW(szSubAppName);
atSubIdList = GlobalAddAtomW(szSubIdList);
atDialogThemeEnabled = GlobalAddAtomW(szDialogThemeEnabled);
UXTHEME_LoadTheme();
}
/***********************************************************************
* IsAppThemed (UXTHEME.@)
*/
BOOL WINAPI IsAppThemed(void)
{
return IsThemeActive();
}
/***********************************************************************
* IsThemeActive (UXTHEME.@)
*/
BOOL WINAPI IsThemeActive(void)
{
TRACE("\n");
return bThemeActive;
}
/***********************************************************************
* EnableTheming (UXTHEME.@)
*
* NOTES
* This is a global and persistent change
*/
HRESULT WINAPI EnableTheming(BOOL fEnable)
{
HKEY hKey;
WCHAR szEnabled[] = {'0','\0'};
TRACE("(%d)\n", fEnable);
if(fEnable != bThemeActive) {
if(fEnable)
UXTHEME_BackupSystemMetrics();
else
UXTHEME_RestoreSystemMetrics();
UXTHEME_SaveSystemMetrics ();
bThemeActive = fEnable;
if(bThemeActive) szEnabled[0] = '1';
if(!RegOpenKeyW(HKEY_CURRENT_USER, szThemeManager, &hKey)) {
RegSetValueExW(hKey, szThemeActive, 0, REG_SZ, (LPBYTE)szEnabled, sizeof(WCHAR));
RegCloseKey(hKey);
}
UXTHEME_broadcast_msg (NULL, WM_THEMECHANGED);
}
return S_OK;
}
/***********************************************************************
* UXTHEME_SetWindowProperty
*
* I'm using atoms as there may be large numbers of duplicated strings
* and they do the work of keeping memory down as a cause of that quite nicely
*/
static HRESULT UXTHEME_SetWindowProperty(HWND hwnd, ATOM aProp, LPCWSTR pszValue)
{
ATOM oldValue = (ATOM)(size_t)RemovePropW(hwnd, (LPCWSTR)MAKEINTATOM(aProp));
if(oldValue)
DeleteAtom(oldValue);
if(pszValue) {
ATOM atValue = AddAtomW(pszValue);
if(!atValue
|| !SetPropW(hwnd, (LPCWSTR)MAKEINTATOM(aProp), (LPWSTR)MAKEINTATOM(atValue))) {
HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
if(atValue) DeleteAtom(atValue);
return hr;
}
}
return S_OK;
}
static LPWSTR UXTHEME_GetWindowProperty(HWND hwnd, ATOM aProp, LPWSTR pszBuffer, int dwLen)
{
ATOM atValue = (ATOM)(size_t)GetPropW(hwnd, (LPCWSTR)MAKEINTATOM(aProp));
if(atValue) {
if(GetAtomNameW(atValue, pszBuffer, dwLen))
return pszBuffer;
TRACE("property defined, but unable to get value\n");
}
return NULL;
}
/***********************************************************************
* OpenThemeData (UXTHEME.@)
*/
HTHEME WINAPI OpenThemeData(HWND hwnd, LPCWSTR pszClassList)
{
WCHAR szAppBuff[256];
WCHAR szClassBuff[256];
LPCWSTR pszAppName;
LPCWSTR pszUseClassList;
HTHEME hTheme = NULL;
TRACE("(%p,%s)\n", hwnd, debugstr_w(pszClassList));
if(bThemeActive)
{
pszAppName = UXTHEME_GetWindowProperty(hwnd, atSubAppName, szAppBuff, sizeof(szAppBuff)/sizeof(szAppBuff[0]));
/* If SetWindowTheme was used on the window, that overrides the class list passed to this function */
pszUseClassList = UXTHEME_GetWindowProperty(hwnd, atSubIdList, szClassBuff, sizeof(szClassBuff)/sizeof(szClassBuff[0]));
if(!pszUseClassList)
pszUseClassList = pszClassList;
if (pszUseClassList)
hTheme = MSSTYLES_OpenThemeClass(pszAppName, pszUseClassList);
}
if(IsWindow(hwnd))
SetPropW(hwnd, (LPCWSTR)MAKEINTATOM(atWindowTheme), hTheme);
TRACE(" = %p\n", hTheme);
return hTheme;
}
/***********************************************************************
* GetWindowTheme (UXTHEME.@)
*
* Retrieve the last theme opened for a window.
*
* PARAMS
* hwnd [I] window to retrieve the theme for
*
* RETURNS
* The most recent theme.
*/
HTHEME WINAPI GetWindowTheme(HWND hwnd)
{
TRACE("(%p)\n", hwnd);
return GetPropW(hwnd, (LPCWSTR)MAKEINTATOM(atWindowTheme));
}
/***********************************************************************
* SetWindowTheme (UXTHEME.@)
*
* Persistent through the life of the window, even after themes change
*/
HRESULT WINAPI SetWindowTheme(HWND hwnd, LPCWSTR pszSubAppName,
LPCWSTR pszSubIdList)
{
HRESULT hr;
TRACE("(%p,%s,%s)\n", hwnd, debugstr_w(pszSubAppName),
debugstr_w(pszSubIdList));
hr = UXTHEME_SetWindowProperty(hwnd, atSubAppName, pszSubAppName);
if(SUCCEEDED(hr))
hr = UXTHEME_SetWindowProperty(hwnd, atSubIdList, pszSubIdList);
if(SUCCEEDED(hr))
UXTHEME_broadcast_msg (hwnd, WM_THEMECHANGED);
return hr;
}
/***********************************************************************
* GetCurrentThemeName (UXTHEME.@)
*/
HRESULT WINAPI GetCurrentThemeName(LPWSTR pszThemeFileName, int dwMaxNameChars,
LPWSTR pszColorBuff, int cchMaxColorChars,
LPWSTR pszSizeBuff, int cchMaxSizeChars)
{
if(!bThemeActive)
return E_PROP_ID_UNSUPPORTED;
if(pszThemeFileName) lstrcpynW(pszThemeFileName, szCurrentTheme, dwMaxNameChars);
if(pszColorBuff) lstrcpynW(pszColorBuff, szCurrentColor, cchMaxColorChars);
if(pszSizeBuff) lstrcpynW(pszSizeBuff, szCurrentSize, cchMaxSizeChars);
return S_OK;
}
/***********************************************************************
* GetThemeAppProperties (UXTHEME.@)
*/
DWORD WINAPI GetThemeAppProperties(void)
{
return dwThemeAppProperties;
}
/***********************************************************************
* SetThemeAppProperties (UXTHEME.@)
*/
void WINAPI SetThemeAppProperties(DWORD dwFlags)
{
TRACE("(0x%08x)\n", dwFlags);
dwThemeAppProperties = dwFlags;
}
/***********************************************************************
* CloseThemeData (UXTHEME.@)
*/
HRESULT WINAPI CloseThemeData(HTHEME hTheme)
{
TRACE("(%p)\n", hTheme);
if(!hTheme)
return E_HANDLE;
return MSSTYLES_CloseThemeClass(hTheme);
}
/***********************************************************************
* HitTestThemeBackground (UXTHEME.@)
*/
HRESULT WINAPI HitTestThemeBackground(HTHEME hTheme, HDC hdc, int iPartId,
int iStateId, DWORD dwOptions,
const RECT *pRect, HRGN hrgn,
POINT ptTest, WORD *pwHitTestCode)
{
FIXME("%d %d 0x%08x: stub\n", iPartId, iStateId, dwOptions);
if(!hTheme)
return E_HANDLE;
return ERROR_CALL_NOT_IMPLEMENTED;
}
/***********************************************************************
* IsThemePartDefined (UXTHEME.@)
*/
BOOL WINAPI IsThemePartDefined(HTHEME hTheme, int iPartId, int iStateId)
{
TRACE("(%p,%d,%d)\n", hTheme, iPartId, iStateId);
if(!hTheme) {
SetLastError(E_HANDLE);
return FALSE;
}
if(MSSTYLES_FindPartState(hTheme, iPartId, iStateId, NULL))
return TRUE;
return FALSE;
}
/***********************************************************************
* GetThemeDocumentationProperty (UXTHEME.@)
*
* Try and retrieve the documentation property from string resources
* if that fails, get it from the [documentation] section of themes.ini
*/
HRESULT WINAPI GetThemeDocumentationProperty(LPCWSTR pszThemeName,
LPCWSTR pszPropertyName,
LPWSTR pszValueBuff,
int cchMaxValChars)
{
const WORD wDocToRes[] = {
TMT_DISPLAYNAME,5000,
TMT_TOOLTIP,5001,
TMT_COMPANY,5002,
TMT_AUTHOR,5003,
TMT_COPYRIGHT,5004,
TMT_URL,5005,
TMT_VERSION,5006,
TMT_DESCRIPTION,5007
};
PTHEME_FILE pt;
HRESULT hr;
unsigned int i;
int iDocId;
TRACE("(%s,%s,%p,%d)\n", debugstr_w(pszThemeName), debugstr_w(pszPropertyName),
pszValueBuff, cchMaxValChars);
hr = MSSTYLES_OpenThemeFile(pszThemeName, NULL, NULL, &pt);
if(FAILED(hr)) return hr;
/* Try to load from string resources */
hr = E_PROP_ID_UNSUPPORTED;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -