// Copyright (C) 2002 Ultr@VNC Team Members. All Rights Reserved. // Copyright (C) 2002 RealVNC Ltd. All Rights Reserved. // Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. // // This file is part of the VNC system. // // The VNC system 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 program 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 program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, // USA. // // Functions to hide the Windows Desktop // // This hides three variants: // - Desktop Patterns (WIN.INI [Desktop] Pattern=) // - Desktop Wallpaper (.bmp [and JPEG on Windows XP]) // - Active Desktop // // Written by Ed Hardebeck - Glance Networks, Inc. // With some code from Paul DiLascia, MSDN Magazine - May 2001 // // HideDesktop() - hides the desktop // RestoreDesktop() - restore the desktop // #define WIN32_LEAN_AND_MEAN #include #include // Shell object uses INTERNET_MAX_URL_LENGTH (go figure) //#define _WIN32_IE 0x0400 #include // ATL smart pointers #include // shell GUIDs #include // IActiveDesktop struct __declspec(uuid("F490EB00-1240-11D1-9888-006097DEACF9")) IActiveDesktop; #define PACKVERSION(major,minor) MAKELONG(minor,major) DWORD GetDllVersion(LPCTSTR lpszDllName) { HINSTANCE hinstDll; DWORD dwVersion = 0; hinstDll = LoadLibrary(lpszDllName); if(hinstDll) { DLLGETVERSIONPROC pDllGetVersion; pDllGetVersion = (DLLGETVERSIONPROC) GetProcAddress(hinstDll, "DllGetVersion"); // Because some DLLs might not implement this function, // test for it explicitly. Depending on the particular // DLL, the lack of a DllGetVersion function can be an // indicator of the version. if (pDllGetVersion) { DLLVERSIONINFO dvi; HRESULT hr; ZeroMemory(&dvi, sizeof(dvi)); dvi.cbSize = sizeof(dvi); hr = (*pDllGetVersion)(&dvi); if(SUCCEEDED(hr)) { dwVersion = PACKVERSION(dvi.dwMajorVersion, dvi.dwMinorVersion); } } FreeLibrary(hinstDll); } return dwVersion; } typedef void (CALLBACK * P_SHGetSettings)(LPSHELLFLAGSTATE lpsfs, DWORD dwMask); BOOL SHDesktopHTML() { // Determine if Active Desktop is enabled. SHGetSettings is apparently // more reliable than IActiveDesktop::GetDesktopItemOptions, which can // report incorrectly during the middle of ApplyChanges! // Dynamically link to SHGetVersion so this can load on Windows with pre 4.71 shell HINSTANCE hinstDll; BOOL enabled = FALSE; hinstDll = LoadLibrary("shell32.dll"); if (hinstDll) { P_SHGetSettings pSHGetSettings; if ((pSHGetSettings = (P_SHGetSettings)GetProcAddress(hinstDll, "SHGetSettings"))) { SHELLFLAGSTATE shfs; (*pSHGetSettings)(&shfs, SSF_DESKTOPHTML); enabled = shfs.fDesktopHTML; } FreeLibrary(hinstDll); } return enabled; } static HRESULT EnableActiveDesktop(bool enable) { CComQIPtr pIActiveDesktop; HRESULT hr; CoInitialize(NULL); hr = pIActiveDesktop.CoCreateInstance(CLSID_ActiveDesktop, NULL, CLSCTX_INPROC_SERVER); if (!SUCCEEDED(hr)) return hr; COMPONENTSOPT opt; opt.dwSize = sizeof(opt); opt.fActiveDesktop = opt.fEnableComponents = enable; hr = pIActiveDesktop->SetDesktopItemOptions(&opt, 0); if (!SUCCEEDED(hr)) return hr; return pIActiveDesktop->ApplyChanges(AD_APPLY_REFRESH); } bool HideActiveDesktop() { // returns true if the Active Desktop was enabled and has been hidden if (GetDllVersion(TEXT("shell32.dll")) >= PACKVERSION(4,71)) if (SHDesktopHTML()) return SUCCEEDED(EnableActiveDesktop(false)); return false; } void ShowActiveDesktop() { if (GetDllVersion(TEXT("shell32.dll")) >= PACKVERSION(4,71)) EnableActiveDesktop(true); } // OK, so this doesn't work in multiple threads or nest... static TCHAR DesktopPattern[40]; static BOOL ADWasEnabled = false; void HideDesktop() { GetProfileString("Desktop", "Pattern", "0 0 0 0 0 0 0 0", DesktopPattern, sizeof(DesktopPattern)); // @@@efh Setting the desktop pattern via pvParam works, but is undocumented (except by www.winehq.com) SystemParametersInfo(SPI_SETDESKPATTERN, 0, "0 0 0 0 0 0 0 0", SPIF_SENDCHANGE); // Tell all applications that there is no wallpaper // Note that this doesn't change the wallpaper registry setting! // @@@efh On Win98 and Win95 this returns an error in the debug build (but not in release)... SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, "", SPIF_SENDCHANGE); ADWasEnabled = HideActiveDesktop(); } void RestoreDesktop() { if (ADWasEnabled) ShowActiveDesktop(); SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, NULL, SPIF_SENDCHANGE); SystemParametersInfo(SPI_SETDESKPATTERN, 0, DesktopPattern, SPIF_SENDCHANGE); }