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

📄 hidedesktop.cpp

📁 teamviewer source code vc++
💻 CPP
字号:
//  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 TeamViewer.
//
//  TeamViewer 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
//

#include "stdhdrs.h"
#include "vncservice.h"
#define WIN32_LEAN_AND_MEAN

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<IActiveDesktop, &IID_IActiveDesktop>	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(bool doImpersonateUser = true)
{
	BOOL personateState = FALSE;
	try
	{
		if (doImpersonateUser)
			personateState = vncService::BeginImpersonation();
				
				
		//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();

		vnclog.Print(LL_STATE, VNCLOG("Hide desktop"));

	}
	catch(...)
	{
		vnclog.Print(LL_INTERR, VNCLOG("HideDesktop catch(...)"));
	}
	if (personateState)
		vncService::EndImpersonation();
}

void RestoreDesktop(bool doImpersonateUser = true)
{
	BOOL personateState = FALSE;
	try
	{
		if (doImpersonateUser)
			personateState = vncService::BeginImpersonation();

		if (!personateState)
			vnclog.Print(LL_STATE, VNCLOG("Restoring Desktop: impersonating actual user failed!"));

		if (ADWasEnabled)
			ShowActiveDesktop();

		DWORD ret = SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, SETWALLPAPER_DEFAULT, SPIF_SENDCHANGE);
		if(ret != 0)						// somehow LastError may be set though the call succeeded
			SetLastError(0);				// so clear it

		vnclog.Print(LL_STATE, VNCLOG("Restoring Desktop returned %d"),ret);

	}
	catch(...)
	{
		vnclog.Print(LL_INTERR, VNCLOG("RestoreDesktop catch(...)"));
	}
	if (personateState)
		vncService::EndImpersonation();
	//SystemParametersInfo(SPI_SETDESKPATTERN, 0, DesktopPattern, SPIF_SENDCHANGE);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -