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

📄 vncdesktop.cpp

📁 Web VNC samples delphi
💻 CPP
📖 第 1 页 / 共 5 页
字号:
BOOL vncDesktop::Shutdown()
{
	// If we created timers then kill them
	if (m_timer_polling)
	{
		KillTimer(Window(), TIMER_POLL);
		m_timer_polling = 0;
	}
	if (m_timer_blank_screen)
	{
		KillTimer(Window(), TIMER_BLANK_SCREEN);
		m_timer_blank_screen = 0;
	}

	// If we created a window then kill it and the hooks
	if (m_hwnd != NULL)
	{	
		//Remove the system hooks
		//Unset keyboard and mouse hooks
		SetLocalInputPriorityHook(false);
		m_hooks_may_change = false;
		ShutdownHooks();

#ifndef HORIZONLIVE
		// Stop the keyboard and mouse filters
		SetKeyboardFilterHook(false);
		SetMouseFilterHook(false);
#endif
		// The window is being closed - remove it from the viewer list
		ChangeClipboardChain(m_hwnd, m_hnextviewer);

		// Close the hook window
		DestroyWindow(m_hwnd);
		m_hwnd = NULL;
		m_hnextviewer = NULL;
	}

	// Now free all the bitmap stuff
	if (m_hrootdc != NULL)
	{
		// Release our device context
		if(ReleaseDC(NULL, m_hrootdc) == 0)
		{
			vnclog.Print(LL_INTERR, VNCLOG("failed to ReleaseDC(m_hrootdc)\n"));
		}
		m_hrootdc = NULL;
	}
	if (m_hmemdc != NULL)
	{
		// Release our device context
		if (!DeleteDC(m_hmemdc))
		{
			vnclog.Print(LL_INTERR, VNCLOG("failed to DeleteDC(m_hmemdc)\n"));
		}
		m_hmemdc = NULL;
	}
	if (m_membitmap != NULL)
	{
		// Release the custom bitmap, if any
		if (!DeleteObject(m_membitmap))
		{
			vnclog.Print(LL_INTERR, VNCLOG("failed to DeleteObject\n"));
		}
		m_membitmap = NULL;
	}

	// Free back buffer
	if (m_backbuff != NULL)
	{
		delete [] m_backbuff;
		m_backbuff = NULL;
	}

	if (m_freemainbuff)
	{
		// Slow blits were enabled - free the slow blit buffer
		if (m_mainbuff != NULL)
		{
			delete [] m_mainbuff;
			m_mainbuff = NULL;
		}
	}

	// Free the WindowPos atom!
	if (VNC_WINDOWPOS_ATOM != NULL)
	{
		if (GlobalDeleteAtom(VNC_WINDOWPOS_ATOM) != 0)
		{
			vnclog.Print(LL_INTERR, VNCLOG("failed to delete atom!\n"));
		}
	}

	ShutdownVideoDriver();

	return TRUE;
}

// Routines to set/unset hooks via VNCHooks.dll

void
vncDesktop::ActivateHooks()
{
	BOOL enable = !(m_server->DontSetHooks() && m_server->PollFullScreen());
	if (enable && !m_hooks_active) {
		m_hooks_active = SetHook(m_hwnd,
								 RFB_SCREEN_UPDATE,
								 RFB_COPYRECT_UPDATE,
								 RFB_MOUSE_UPDATE);
		if (!m_hooks_active) {
			vnclog.Print(LL_INTERR, VNCLOG("failed to set system hooks\n"));
			// Switch on full screen polling, so they can see something, at least...
			m_server->PollFullScreen(TRUE);
		}
	} else if (!enable) {
		ShutdownHooks();
	}
}

void
vncDesktop::ShutdownHooks()
{
	if (m_hooks_active)
		m_hooks_active = !UnSetHook(m_hwnd);
}

void
vncDesktop::TryActivateHooks()
{
	if (m_hooks_may_change)
		ActivateHooks();
}

// Routine to ensure we're on the correct NT desktop

BOOL
vncDesktop::InitDesktop()
{
	if (vncService::InputDesktopSelected())
		return TRUE;

	// Ask for the current input desktop
	return vncService::SelectDesktop(NULL);
}

// Routine used to close the screen saver, if it's active...

BOOL CALLBACK
KillScreenSaverFunc(HWND hwnd, LPARAM lParam)
{
	char buffer[256];

	// - ONLY try to close Screen-saver windows!!!
	if ((GetClassName(hwnd, buffer, 256) != 0) &&
		(strcmp(buffer, "WindowsScreenSaverClass") == 0))
		PostMessage(hwnd, WM_CLOSE, 0, 0);
	return TRUE;
}

void
vncDesktop::KillScreenSaver()
{
	OSVERSIONINFO osversioninfo;
	osversioninfo.dwOSVersionInfoSize = sizeof(osversioninfo);

	// Get the current OS version
	if (!GetVersionEx(&osversioninfo))
		return;

	vnclog.Print(LL_INTINFO, VNCLOG("KillScreenSaver...\n"));

	// How to kill the screen saver depends on the OS
	switch (osversioninfo.dwPlatformId)
	{
	case VER_PLATFORM_WIN32_WINDOWS:
		{
			// Windows 95

			// Fidn the ScreenSaverClass window
			HWND hsswnd = FindWindow ("WindowsScreenSaverClass", NULL);
			if (hsswnd != NULL)
				PostMessage(hsswnd, WM_CLOSE, 0, 0); 
			break;
		} 
	case VER_PLATFORM_WIN32_NT:
		{
			// Windows NT

			// Find the screensaver desktop
			HDESK hDesk = OpenDesktop(
				"Screen-saver",
				0,
				FALSE,
				DESKTOP_READOBJECTS | DESKTOP_WRITEOBJECTS
				);
			if (hDesk != NULL)
			{
				vnclog.Print(LL_INTINFO, VNCLOG("Killing ScreenSaver\n"));

				// Close all windows on the screen saver desktop
				EnumDesktopWindows(hDesk, (WNDENUMPROC) &KillScreenSaverFunc, 0);
				CloseDesktop(hDesk);
				// Pause long enough for the screen-saver to close
				//Sleep(2000);
				// Reset the screen saver so it can run again
				SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, TRUE, 0, SPIF_SENDWININICHANGE); 
			}
			break;
		}
	}
}

void vncDesktop::ChangeResNow()
{
// IMPORTANT: Screen mode alteration may only take place on a single-mon system.
	if (IsMultiMonDesktop())
	{
		return;
	}

	BOOL settingsUpdated = false;
	int i = 0;

	_ASSERTE(!m_lpAlternateDevMode);
	m_lpAlternateDevMode = new DEVMODE; // *** create an instance of DEVMODE - Jeremy Peaks
	if (!m_lpAlternateDevMode)
	{
		vnclog.Print(LL_INTINFO, VNCLOG("SCR-WBB: failed to allocate memory "
										"for alternate DEVMODE representation!\n"));
		return;
	}

	// *** WBB - Obtain the current display settings.
	// only on unimon
	if (! EnumDisplaySettings(0, ENUM_CURRENT_SETTINGS, m_lpAlternateDevMode))
	{
		vnclog.Print(LL_INTINFO,
					 VNCLOG("SCR-WBB: could not get current display settings!\n"));
		delete m_lpAlternateDevMode;
		m_lpAlternateDevMode = NULL;
		return;

	}

	vnclog.Print(LL_INTINFO,
				 VNCLOG("SCR-WBB: current display: w=%d h=%d bpp=%d vRfrsh=%d.\n"),
				 m_lpAlternateDevMode->dmPelsWidth,
				 m_lpAlternateDevMode->dmPelsHeight,
				 m_lpAlternateDevMode->dmBitsPerPel,
				 m_lpAlternateDevMode->dmDisplayFrequency);

	origPelsWidth = m_lpAlternateDevMode->dmPelsWidth; // *** sets the original resolution for use later
	origPelsHeight = m_lpAlternateDevMode->dmPelsHeight; // *** - Jeremy Peaks

	// *** Open the registry key for resolution settings
	HKEY checkdetails = 0;
	RegOpenKeyEx(HKEY_LOCAL_MACHINE, 
				WINVNC_REGISTRY_KEY,
				0,
				KEY_READ,
				&checkdetails);
	if (checkdetails)
	{
		int slen=MAX_REG_ENTRY_LEN;
		int valType;
		char inouttext[MAX_REG_ENTRY_LEN];

		memset(inouttext, 0, MAX_REG_ENTRY_LEN);
		
		// *** Get the registry values for resolution change - Jeremy Peaks
		RegQueryValueEx(checkdetails,
			"ResWidth",
			NULL,
			(LPDWORD) &valType,
			(LPBYTE) &inouttext,
			(LPDWORD) &slen);

		
		if ((valType == REG_SZ) &&
			atol(inouttext)) { // *** if width is 0, then this isn't a valid resolution, so do nothing - Jeremy Peaks
			m_lpAlternateDevMode->dmPelsWidth = atol(inouttext);

			memset(inouttext, 0, MAX_REG_ENTRY_LEN);

			RegQueryValueEx(checkdetails,
				"ResHeight",
				NULL,
				(LPDWORD) &valType,
				(LPBYTE) &inouttext,
				(LPDWORD) &slen);
			
			m_lpAlternateDevMode->dmPelsHeight = atol(inouttext);
			if ((valType == REG_SZ ) &&
				(m_lpAlternateDevMode->dmPelsHeight > 0)) {

				vnclog.Print(LL_INTINFO,
					VNCLOG("SCR-WBB: attempting to change "
						   "resolution w=%d h=%d\n"),
					m_lpAlternateDevMode->dmPelsWidth,
					m_lpAlternateDevMode->dmPelsHeight);

				// *** make res change - Jeremy Peaks
				// testing: predefined Width/Height may become incompatible
				// with new clrdepth/timings
				long resultOfResChange = ChangeDisplaySettings(m_lpAlternateDevMode, CDS_TEST);
				if (resultOfResChange == DISP_CHANGE_SUCCESSFUL) {
					ChangeDisplaySettings(m_lpAlternateDevMode, CDS_UPDATEREGISTRY);
					settingsUpdated = true;
				}
			} 
		}

		RegCloseKey(checkdetails);
	}

	if (! settingsUpdated)
	{
// Did not change the resolution.
		delete m_lpAlternateDevMode;
		m_lpAlternateDevMode = NULL;
	}
}

void
vncDesktop::SetupDisplayForConnection()
{
	KillScreenSaver();

	ChangeResNow(); // *** - Jeremy Peaks
}

void
vncDesktop::ResetDisplayToNormal()
{
	if (m_lpAlternateDevMode != NULL)
	{
		// *** In case the resolution was changed, revert to original settings now
		m_lpAlternateDevMode->dmPelsWidth = origPelsWidth;
		m_lpAlternateDevMode->dmPelsHeight = origPelsHeight;

		long resultOfResChange = ChangeDisplaySettings(m_lpAlternateDevMode, CDS_TEST);
		if (resultOfResChange == DISP_CHANGE_SUCCESSFUL)
			ChangeDisplaySettings(m_lpAlternateDevMode, CDS_UPDATEREGISTRY);

		delete m_lpAlternateDevMode;
		m_lpAlternateDevMode = NULL;
	}
}

RECT vncDesktop::GetSourceRect()
{
	if (m_server->WindowShared())
	{
		RECT wrect;
		GetWindowRect(m_server->GetWindowShared(), &wrect);
		return wrect;
	}
	else if (m_server->ScreenAreaShared())
	{
		return m_server->GetScreenAreaRect();
	}
	else if (m_server->PrimaryDisplayOnlyShared())
	{
		RECT pdr = { 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN) };
		return pdr;
	}
	else
	{
#ifdef _DEBUG
		RECT rd;
		_ASSERTE(GetSourceDisplayRect(rd));
		_ASSERTE(EqualRect(&rd, &m_bmrect));
#endif
		return m_bmrect;
	}
}

RECT	GetScreenRect()
{
	RECT screenrect;
	if (IsWinVerOrHigher(4, 10))
	{
		screenrect.left		= GetSystemMetrics(SM_XVIRTUALSCREEN);
		screenrect.top		= GetSystemMetrics(SM_YVIRTUALSCREEN);
		screenrect.right	= screenrect.left + GetSystemMetrics(SM_CXVIRTUALSCREEN);
		screenrect.bottom	= screenrect.top + GetSystemMetrics(SM_CYVIRTUALSCREEN);
	}
	else
	{
		screenrect.left = 0;
		screenrect.top = 0;
		screenrect.right = GetSystemMetrics(SM_CXSCREEN);
		screenrect.bottom = GetSystemMetrics(SM_CYSCREEN);
	}
	return screenrect;
}

BOOL vncDesktop::GetSourceDisplayRect(RECT &rdisp_rect)
{
	if (!m_hrootdc)
		m_hrootdc = ::GetDC(NULL);
	if (!m_hrootdc)
	{
		vnclog.Print(LL_INTERR, VNCLOG("GetDC() failed, error=%d\n"), GetLastError());
		return FALSE;
	}

// TODO: refactor it
	rdisp_rect = GetScreenRect();
	return TRUE;
}

BOOL vncDesktop::InitBitmap()
{
// IMPORTANT: here an optimization may be implemented
// when only a fixed rect is shared.
// then m_bmrect should be set to that rect.
	if (!GetSourceDisplayRect(m_bmrect))
	{
		return FALSE;
	}

	vnclog.Print(
		LL_INTINFO,
		VNCLOG("source desktop metrics: (%d, %d, %d, %d)\n"),
		m_bmrect.left,
		m_bmrect.top,
		m_bmrect.right,
		m_bmrect.bottom);

	vnclog.Print(
		LL_INTINFO,
		VNCLOG("bitmap dimensions are %dx%d\n"),
		m_bmrect.right - m_bmrect.left,
		m_bmrect.bottom - m_bmrect.top);

	// Create a compatible memory DC
	m_hmemdc = CreateCompatibleDC(m_hrootdc);
	if (m_hmemdc == NULL) {
		vnclog.Print(LL_INTERR, VNCLOG("CreateCompatibleDC() failed, error=%d\n"),
					 GetLastError());
		return FALSE;
	}

	// Check that the device capabilities are ok
	if ((GetDeviceCaps(m_hrootdc, RASTERCAPS) & RC_BITBLT) == 0)
	{
// FIXME: MessageBox in a service
		MessageBox(
			NULL,
			"vncDesktop : root device doesn't support BitBlt\n"
			"WinVNC cannot be used with this graphic device driver",
			szAppName,
			MB_ICONSTOP | MB_OK
			);
		return FALSE;
	}
	if ((GetDeviceCaps(m_hmemdc, RASTERCAPS) & RC_DI_BITMAP) == 0)
	{
// FIXME: MessageBox in a service
		MessageBox(
			NULL,
			"vncDesktop : memory device doesn't support GetDIBits\n"
			"WinVNC cannot be used with this graphics device driver",
			szAppName,
			MB_ICONSTOP | MB_OK
			);
		return FALSE;
	}

	// Create the bitmap to be compatible with the ROOT DC!!!
	m_membitmap = CreateCompatibleBitmap(
		m_hrootdc,
		m_bmrect.right - m_bmrect.left,
		m_bmrect.bottom - m_bmrect.top);
	if (m_membitmap == NULL)
	{
		vnclog.Print(
			LL_INTERR,
			VNCLOG("failed to create memory bitmap, error=%d\n"),
			GetLastError());
		return FALSE;
	}
	vnclog.Print(LL_INTINFO, VNCLOG("created memory bitmap\n"));

	// Get the bitmap's format and colour details
	int result;
	m_bminfo.bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	m_bminfo.bmi.bmiHeader.biBitCount = 0;
	result = ::GetDIBits(m_hmemdc, m_membitmap, 0, 1, NULL, &m_bminfo.bmi, DIB_RGB_COLORS);
	if (result == 0) {
		return FALSE;

⌨️ 快捷键说明

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