diff options
author | Constantin Kaplinsky <const@tightvnc.com> | 2004-10-08 09:43:57 +0000 |
---|---|---|
committer | Constantin Kaplinsky <const@tightvnc.com> | 2004-10-08 09:43:57 +0000 |
commit | 47ed8d321c32c6b741cff1f4ff686165c4f269f4 (patch) | |
tree | da413648adbff4ff10c8ee26124673f8e7cf238a /rfb_win32/CleanDesktop.cxx | |
parent | 266bb36cd47555280fffd3aab1ed86683e26d748 (diff) | |
download | tigervnc-47ed8d321c32c6b741cff1f4ff686165c4f269f4.tar.gz tigervnc-47ed8d321c32c6b741cff1f4ff686165c4f269f4.zip |
Initial revision
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@2 3789f03b-4d11-0410-bbf8-ca57d06f2519
Diffstat (limited to 'rfb_win32/CleanDesktop.cxx')
-rw-r--r-- | rfb_win32/CleanDesktop.cxx | 255 |
1 files changed, 255 insertions, 0 deletions
diff --git a/rfb_win32/CleanDesktop.cxx b/rfb_win32/CleanDesktop.cxx new file mode 100644 index 00000000..9fb83478 --- /dev/null +++ b/rfb_win32/CleanDesktop.cxx @@ -0,0 +1,255 @@ +/* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +// -=- CleanDesktop.cxx + +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#include <wininet.h> +#include <shlobj.h> + +#include <rfb_win32/CleanDesktop.h> +#include <rfb_win32/CurrentUser.h> +#include <rfb_win32/Registry.h> +#include <rfb/LogWriter.h> +#include <rdr/Exception.h> + +using namespace rfb; +using namespace rfb::win32; + +static LogWriter vlog("CleanDesktop"); + + +struct ActiveDesktop { + ActiveDesktop() : handle(0) { + // - Contact Active Desktop + HRESULT result = CoCreateInstance(CLSID_ActiveDesktop, NULL, CLSCTX_INPROC_SERVER, + IID_IActiveDesktop, (PVOID*)&handle); + if (result != S_OK) + throw rdr::SystemException("failed to contact Active Desktop", result); + } + ~ActiveDesktop() { + if (handle) + handle->Release(); + } + bool enable(bool enable_) { + // - Get the current Active Desktop options + COMPONENTSOPT adOptions; + memset(&adOptions, 0, sizeof(adOptions)); + adOptions.dwSize = sizeof(adOptions); + + HRESULT result = handle->GetDesktopItemOptions(&adOptions, 0); + if (result != S_OK) { + vlog.error("failed to get Active Desktop options: %d", result); + return false; + } + + // - If Active Desktop is active, disable it + if ((adOptions.fActiveDesktop==0) != (enable_==0)) { + if (enable_) + vlog.debug("enabling Active Desktop"); + else + vlog.debug("disabling Active Desktop"); + + adOptions.fActiveDesktop = enable_; + result = handle->SetDesktopItemOptions(&adOptions, 0); + if (result != S_OK) { + vlog.error("failed to disable ActiveDesktop: %d", result); + return false; + } + handle->ApplyChanges(AD_APPLY_REFRESH); + return true; + } + return false; + } + IActiveDesktop* handle; +}; + + +DWORD SysParamsInfo(UINT action, UINT param, PVOID ptr, UINT ini) { + DWORD r = ERROR_SUCCESS; + if (!SystemParametersInfo(action, param, ptr, ini)) { + r = GetLastError(); + vlog.info("SPI error: %d", r); + } + return r; +} + + +CleanDesktop::CleanDesktop() : restoreActiveDesktop(false), restoreWallpaper(false), restoreEffects(false) { + CoInitialize(0); +} + +CleanDesktop::~CleanDesktop() { + enableEffects(); + enablePattern(); + enableWallpaper(); + CoUninitialize(); +} + +void CleanDesktop::disableWallpaper() { + try { + ImpersonateCurrentUser icu; + + vlog.debug("disable desktop wallpaper/Active Desktop"); + + // -=- First attempt to remove the wallpaper using Active Desktop + try { + ActiveDesktop ad; + if (ad.enable(false)) + restoreActiveDesktop = true; + } catch (rdr::Exception& e) { + vlog.error(e.str()); + } + + // -=- Switch of normal wallpaper and notify apps + SysParamsInfo(SPI_SETDESKWALLPAPER, 0, "", SPIF_SENDCHANGE); + restoreWallpaper = true; + + } catch (rdr::Exception& e) { + vlog.info(e.str()); + } +} + +void CleanDesktop::enableWallpaper() { + try { + ImpersonateCurrentUser icu; + + if (restoreActiveDesktop) { + vlog.debug("restore Active Desktop"); + + // -=- First attempt to re-enable Active Desktop + try { + ActiveDesktop ad; + ad.enable(true); + restoreActiveDesktop = false; + } catch (rdr::Exception& e) { + vlog.error(e.str()); + } + } + + if (restoreWallpaper) { + vlog.debug("restore desktop wallpaper"); + + // -=- Then restore the standard wallpaper if required + SysParamsInfo(SPI_SETDESKWALLPAPER, 0, NULL, SPIF_SENDCHANGE); + restoreWallpaper = false; + } + + } catch (rdr::Exception& e) { + vlog.info(e.str()); + } +} + + +void CleanDesktop::disablePattern() { + try { + ImpersonateCurrentUser icu; + + vlog.debug("disable desktop pattern"); + SysParamsInfo(SPI_SETDESKPATTERN, 0, "", SPIF_SENDCHANGE); + restorePattern = true; + + } catch (rdr::Exception& e) { + vlog.info(e.str()); + } +} + +void CleanDesktop::enablePattern() { + try { + if (restorePattern) { + ImpersonateCurrentUser icu; + + vlog.debug("restoring pattern..."); + + TCharArray pattern; + if (osVersion.isPlatformWindows) { + RegKey cfgKey; + cfgKey.openKey(HKEY_CURRENT_USER, _T("Control Panel\\Desktop")); + pattern.buf = cfgKey.getString(_T("Pattern")); + } + SysParamsInfo(SPI_SETDESKPATTERN, 0, pattern.buf, SPIF_SENDCHANGE); + restorePattern = false; + } + + } catch (rdr::Exception& e) { + vlog.info(e.str()); + } +} + + +void CleanDesktop::disableEffects() { +#if (WINVER >= 0x500) + try { + ImpersonateCurrentUser icu; + + vlog.debug("disable desktop effects"); + + SysParamsInfo(SPI_SETFONTSMOOTHING, FALSE, 0, SPIF_SENDCHANGE); + if (SysParamsInfo(SPI_GETUIEFFECTS, 0, &uiEffects, 0) == ERROR_CALL_NOT_IMPLEMENTED) { + SysParamsInfo(SPI_GETCOMBOBOXANIMATION, 0, &comboBoxAnim, 0); + SysParamsInfo(SPI_GETGRADIENTCAPTIONS, 0, &gradientCaptions, 0); + SysParamsInfo(SPI_GETHOTTRACKING, 0, &hotTracking, 0); + SysParamsInfo(SPI_GETLISTBOXSMOOTHSCROLLING, 0, &listBoxSmoothScroll, 0); + SysParamsInfo(SPI_GETMENUANIMATION, 0, &menuAnim, 0); + SysParamsInfo(SPI_SETCOMBOBOXANIMATION, 0, FALSE, SPIF_SENDCHANGE); + SysParamsInfo(SPI_SETGRADIENTCAPTIONS, 0, FALSE, SPIF_SENDCHANGE); + SysParamsInfo(SPI_SETHOTTRACKING, 0, FALSE, SPIF_SENDCHANGE); + SysParamsInfo(SPI_SETLISTBOXSMOOTHSCROLLING, 0, FALSE, SPIF_SENDCHANGE); + SysParamsInfo(SPI_SETMENUANIMATION, 0, FALSE, SPIF_SENDCHANGE); + } else { + SysParamsInfo(SPI_SETUIEFFECTS, 0, FALSE, SPIF_SENDCHANGE); + } + restoreEffects = true; + + } catch (rdr::Exception& e) { + vlog.info(e.str()); + } +#else + vlog.info("disableffects not implemented"); +#endif +} + +void CleanDesktop::enableEffects() { + try { + if (restoreEffects) { +#if (WINVER >= 0x500) + ImpersonateCurrentUser icu; + + vlog.debug("restore desktop effects"); + + RegKey desktopCfg; + desktopCfg.openKey(HKEY_CURRENT_USER, _T("Control Panel\\Desktop")); + SysParamsInfo(SPI_SETFONTSMOOTHING, desktopCfg.getInt(_T("FontSmoothing"), 0) != 0, 0, SPIF_SENDCHANGE); + if (SysParamsInfo(SPI_SETUIEFFECTS, 0, (void*)uiEffects, SPIF_SENDCHANGE) == ERROR_CALL_NOT_IMPLEMENTED) { + SysParamsInfo(SPI_SETCOMBOBOXANIMATION, 0, (void*)comboBoxAnim, SPIF_SENDCHANGE); + SysParamsInfo(SPI_SETGRADIENTCAPTIONS, 0, (void*)gradientCaptions, SPIF_SENDCHANGE); + SysParamsInfo(SPI_SETHOTTRACKING, 0, (void*)hotTracking, SPIF_SENDCHANGE); + SysParamsInfo(SPI_SETLISTBOXSMOOTHSCROLLING, 0, (void*)listBoxSmoothScroll, SPIF_SENDCHANGE); + SysParamsInfo(SPI_SETMENUANIMATION, 0, (void*)menuAnim, SPIF_SENDCHANGE); + } + restoreEffects = false; +#else + vlog.info("enableEffects not implemented"); +#endif + } + + } catch (rdr::Exception& e) { + vlog.info(e.str()); + } +} |