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

📄 clientconnection.cpp

📁 teamviewer source code vc++
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	{
		m_opts.m_scale_num = nLocalWidth;
		m_opts.m_scale_den = m_si.framebufferWidth;
	}

	m_opts.m_scale_num = (AUTOSCALE_GRANULARITY * m_opts.m_scale_num + m_opts.m_scale_den/2) / m_opts.m_scale_den;
	// denuminator should be as small as possible, so that only small rectangles need to
	// be repainted when scaling
	int g = gcd(m_opts.m_scale_num, AUTOSCALE_GRANULARITY);
	m_opts.m_scale_num /= g;
	m_opts.m_scale_den = AUTOSCALE_GRANULARITY / g;
}

// stop auto scaling
void ClientConnection::StopAutoScaling()
{
	m_opts.FixScaling();
}

void ClientConnection::CenterMainWindow()
{
	RECT workrect;
	// Find how large the desktop work area is
	SystemParametersInfo(SPI_GETWORKAREA, 0, &workrect, 0);
	int workwidth = workrect.right -  workrect.left;
	int workheight = workrect.bottom - workrect.top;
	SetWindowPos(m_hwndMain, HWND_NOTOPMOST,
			workrect.left + (workwidth-m_winwidth) / 2,
			workrect.top + (workheight-m_winheight) / 2,
			m_winwidth, m_winheight, SWP_SHOWWINDOW);
	SetForegroundWindow(m_hwndMain);
}

// do we need scrollbars?
void ClientConnection::AdjustScrollbars()
{
	// Calculate window dimensions
	RECT rect;
	GetWindowRect(m_hwndMain, &rect);
	m_winwidth = rect.right - rect.left;
	m_winheight = rect.bottom - rect.top ;

	//if (m_opts.m_ShowToolbar)
	//{
	//	GetWindowRect(m_hwndTBwin, &Rtb);
	//	SetWindowPos(m_hwndTB,HWND_NOTOPMOST,0,-2,m_winwidth, Rtb.bottom-Rtb.top, SWP_FRAMECHANGED);
	//	UpdateWindow(m_hwndTB);
	//}
	//else
	//{
	//	Rtb.top=0;Rtb.bottom=0;	
	//}
	
	// If the current window size would be large enough to hold the
	// whole screen without scrollbars, or if we're full-screen,
	// we turn them off.  Under CE, the scroll bars are unchangeable.

	bool hasScrollbars = false;
	if (InFullScreenMode() ||
		m_winwidth + 1 >= m_fullwinwidth  &&
		m_winheight + 1>= m_fullwinheight ) 
	{
		ShowScrollBar(m_hwndMain, SB_HORZ, FALSE);
		ShowScrollBar(m_hwndMain, SB_VERT, FALSE);
	} 
	else 
	{
		hasScrollbars = true;
		ShowScrollBar(m_hwndMain, SB_HORZ, TRUE);
		ShowScrollBar(m_hwndMain, SB_VERT, TRUE);
	}
	// Update these for the record
	// And consider that in full-screen mode the window
	// is actually bigger than the remote screen.
	GetClientRect(m_hwndMain, &rect);
	
	m_cliwidth  = min((int)(rect.right - rect.left), 
					  (int)(m_si.framebufferWidth * m_opts.m_scale_num / m_opts.m_scale_den));
	m_cliheight = min((int)(rect.bottom - rect.top) ,
					  (int)(m_si.framebufferHeight * m_opts.m_scale_num / m_opts.m_scale_den));
	
	m_hScrollMax = (int)m_si.framebufferWidth * m_opts.m_scale_num / m_opts.m_scale_den;
	m_vScrollMax = (int)m_si.framebufferHeight* m_opts.m_scale_num / m_opts.m_scale_den;	

	int newhpos, newvpos;
	newhpos = max(0, 
				  min(m_hScrollPos, 
					  m_hScrollMax - max(m_cliwidth, 0)
					 )
				 );
	newvpos = max(0,
				  min(m_vScrollPos, 
					  m_vScrollMax - max(m_cliheight, 0)
					 ) 
				 );
	
	ScrollWindowEx(m_hwnd,
				   m_hScrollPos - newhpos,
				   m_vScrollPos - newvpos,
				   NULL, &rect, NULL, NULL,  SW_INVALIDATE);
	
	m_hScrollPos = newhpos;
	m_vScrollPos = newvpos;

	if(hasScrollbars)
		UpdateScrollbars();
		
}

// Size the window
void ClientConnection::SizeWindow()
{
	// Let's find out how big a window would be needed to display the
	// whole desktop (assuming no scrollbars).
	RECT fullwinrect;
	RECT workrect;
	int fbWidth, fbHeight;

	if (m_opts.m_scaling)										// calculate size of client area
	{
		fbWidth = m_si.framebufferWidth * m_opts.m_scale_num / m_opts.m_scale_den;
		fbHeight = m_si.framebufferHeight * m_opts.m_scale_num / m_opts.m_scale_den;
	}
	else
	{
		fbWidth = m_si.framebufferWidth;
		fbHeight = m_si.framebufferHeight;
	}

	SetRect(&fullwinrect, 0, 0, fbWidth, fbHeight);
	AdjustWindowRectEx(&fullwinrect,							// adjust main window
					   GetWindowLong(m_hwndMain, GWL_STYLE) & ~WS_VSCROLL & ~WS_HSCROLL, 
					   FALSE, GetWindowLong(m_hwndMain, GWL_EXSTYLE));

	// Find how large the desktop work area is
	SystemParametersInfo(SPI_GETWORKAREA, 0, &workrect, 0);
	int workwidth = workrect.right -  workrect.left;
	int workheight = workrect.bottom - workrect.top;
	
	m_fullwinwidth = fullwinrect.right - fullwinrect.left;
	m_fullwinheight = fullwinrect.bottom - fullwinrect.top;

	m_winwidth  = min(m_fullwinwidth,  workwidth);
	m_winheight = min(m_fullwinheight, workheight);
	
	RECT rmain;
	GetWindowRect(m_hwndMain, &rmain);
	if(!m_sizing && (m_opts.m_fAutoScaling ||
	                (!m_opts.m_fAutoScaling && 
					 (m_winwidth<workwidth || m_winheight<workheight))))
	{
		MoveWindow(m_hwndMain, rmain.left, rmain.top, m_winwidth, m_winheight, TRUE);
	}
	MoveWindow(m_hwnd, 0, 0, fbWidth, fbHeight, FALSE);

	RECT cr, tbRect;
	GetClientRect(m_hwndMain, &cr);
	GetClientRect(m_hwndTBwin, &tbRect);
	if (m_opts.m_ShowToolbar)									// display toolbar
	{
		MoveWindow(m_hwndTBwin, (cr.right - cr.left - tbRect.right + tbRect.left)/2, 
			                     0, 
								 tbRect.right - tbRect.left,
								 tbRect.bottom - tbRect.top, TRUE);
	}
	else
	{

		MoveWindow(m_hwndTBwin, (cr.right - cr.left - tbRect.right + tbRect.left)/2, 
			                     -32, 
								 tbRect.right - tbRect.left,
								 tbRect.bottom - tbRect.top, TRUE);
	}

	// Presentation: show toolbar only in fullscreen mode
	ShowWindow(m_hwndTBwin, (m_opts.m_ActiveMode != rfbMC_PresentationClient) ||
					         m_opts.m_FullScreen ? SW_SHOW:SW_HIDE);

	if(m_SecureDesktopDialog)
		CenterSecureDesktopDialog();

	InvalidateRect(m_hwnd, NULL, FALSE);
	m_sizing = false;
	AdjustScrollbars();
}

// We keep a local copy of the whole screen.  This is not strictly necessary
// for VNC, but makes scrolling & deiconifying much smoother.

void ClientConnection::CreateLocalFramebuffer()
{
	omni_mutex_lock l(m_bitmapdcMutex);
	
	// We create a bitmap which has the same pixel characteristics as
	// the local display, in the hope that blitting will be faster.

	TempDC hdc(m_hwnd);

	if (m_hBitmap != NULL)
		DeleteObject(m_hBitmap);

	m_hBitmap = CreateCompatibleBitmap(hdc, m_si.framebufferWidth, m_si.framebufferHeight);
	if (m_hBitmap == NULL)
		throw WarningException("Error creating local image of screen");
	// Select this bitmap into the DC with an appropriate palette
	ObjectSelector b(m_hBitmapDC, m_hBitmap);
	PaletteSelector p(m_hBitmapDC, m_hPalette);
	// Modif RDV@2002 - Cache Encoding
	// Modif sf@2002
	if (m_opts.m_fEnableCache)
	{
		if (m_hCacheBitmap != NULL) DeleteObject(m_hCacheBitmap);
		m_hCacheBitmap = CreateCompatibleBitmap(m_hBitmapDC, m_si.framebufferWidth, m_si.framebufferHeight);
		vnclog.Print(0, VNCLOG(_T("Cache: Cache buffer bitmap creation")));
	}
	
	RECT rect;

	SetRect(&rect, 0,0, m_si.framebufferWidth, m_si.framebufferHeight);
	COLORREF bgcol = RGB(0, 0, 50);
	FillSolidRect(&rect, bgcol);
	
	COLORREF oldbgcol  = SetBkColor(  m_hBitmapDC, bgcol);
	COLORREF oldtxtcol = SetTextColor(m_hBitmapDC, RGB(255,255,255));
	rect.right = m_si.framebufferWidth / 2;
	rect.bottom = m_si.framebufferHeight / 2;
	
	DrawText (m_hBitmapDC, sz_L62, -1, &rect,
		DT_SINGLELINE | DT_CENTER | DT_VCENTER);

	SetBkColor(  m_hBitmapDC, oldbgcol);
	SetTextColor(m_hBitmapDC, oldtxtcol);

	InvalidateRect(m_hwnd, NULL, FALSE);

}

void ClientConnection::SetupPixelFormat() {
	// Have we requested a reduction to 8-bit?
    if (m_opts.m_Use8Bit)
	{		
		switch (m_opts.m_Use8Bit)
		{
		case rfbPF256Colors:
			m_newFormat = vnc8bitFormat;
			break;
		case rfbPF64Colors:
			m_newFormat = vnc8bitFormat_64;
			break;
		case rfbPF8Colors:
			m_newFormat = vnc8bitFormat_8;
			break;
		case rfbPF8GreyColors:
			m_newFormat = vnc8bitFormat_8Grey;
			break;
		case rfbPF4GreyColors:
			m_newFormat = vnc8bitFormat_4Grey;
			break;
		case rfbPF2GreyColors:
			m_newFormat = vnc8bitFormat_2Grey;
			break;
		}
		vnclog.Print(2, VNCLOG(_T("Requesting 8-bit truecolour")));  
		// We don't support colormaps so we'll ask the server to convert
    }
	else if (!m_si.format.trueColour)
	{
        
        // We'll just request a standard 16-bit truecolor
        vnclog.Print(2, VNCLOG(_T("Requesting 16-bit truecolour")));
        m_newFormat = vnc16bitFormat;
    }
	else
	{

		// Normally we just use the sever's format suggestion
		m_newFormat = m_si.format;
        m_newFormat.bigEndian = 0; // except always little endian

		// It's silly requesting more bits than our current display has, but
		// in fact it doesn't usually amount to much on the network.
		// Windows doesn't support 8-bit truecolour.
		// If our display is palette-based, we want more than 8 bit anyway,
		// unless we're going to start doing palette stuff at the server.
		// So the main use would be a 24-bit true-colour desktop being viewed
		// on a 16-bit true-colour display, and unless you have lots of images
		// and hence lots of raw-encoded stuff, the size of the pixel is not
		// going to make much difference.
		//   We therefore don't bother with any restrictions, but here's the
		// start of the code if we wanted to do it.

		if (false) {
		
			// Get a DC for the root window
			TempDC hrootdc(NULL);
			int localBitsPerPixel = GetDeviceCaps(hrootdc, BITSPIXEL);
			int localRasterCaps	  = GetDeviceCaps(hrootdc, RASTERCAPS);
			vnclog.Print(2, VNCLOG(_T("Memory DC has depth of %d and %s pallete-based.")), 
				localBitsPerPixel, (localRasterCaps & RC_PALETTE) ? "is" : "is not");
			
			// If we're using truecolor, and the server has more bits than we do
			if ( (localBitsPerPixel > m_newFormat.depth) && 
				! (localRasterCaps & RC_PALETTE)) {
				m_newFormat.depth = localBitsPerPixel;

				// create a bitmap compatible with the current display
				// call GetDIBits twice to get the colour info.
				// set colour masks and shifts
				
			}
		}
	}
	// The endian will be set before sending

	// really change the pixel format when the next full framebuffer arrives
	m_WaitForFullUpdate = true;
}


void ClientConnection::SetFormatAndEncodings()
{
	// Set pixel format to myFormat
    
	rfbSetPixelFormatMsg spf;

    spf.type = rfbSetPixelFormat;
	if(m_WaitForFullUpdate)
		spf.format = m_newFormat;
	else
		spf.format = m_myFormat;
    spf.format.redMax = Swap16IfLE(spf.format.redMax);
    spf.format.greenMax = Swap16IfLE(spf.format.greenMax);
    spf.format.blueMax = Swap16IfLE(spf.format.blueMax);

    WriteExact((char *)&spf, sz_rfbSetPixelFormatMsg, rfbSetPixelFormat);

    // The number of bytes required to hold at least one pixel.
	m_minPixelBytes = (spf.format.bitsPerPixel + 7) >> 3;

	// Set encodings
    char buf[sz_rfbSetEncodingsMsg + MAX_ENCODINGS * 4];
    rfbSetEncodingsMsg *se = (rfbSetEncodingsMsg *)buf;
    CARD32 *encs = (CARD32 *)(&buf[sz_rfbSetEncodingsMsg]);
    int len = 0;
	
    se->type = rfbSetEncodings;
    se->nEncodings = 0;

	bool useCompressLevel = false;
	int i = 0;
	// Put the preferred encoding first, and change it if the
	// preferred encoding is not actually usable.
	for (i = LASTENCODING; i >= rfbEncodingRaw; i--)
	{
		if (m_opts.m_PreferredEncoding == i) 
		{
			encs[se->nEncodings++] = Swap32IfLE(i);
  			if ( i == rfbEncodingZlib ||
				 i == rfbEncodingTight ||
				 i == rfbEncodingZlibHex)
			{
				useCompressLevel = true;
			}
		}
	}

	// Now we go through and put in all the other encodings in order.
	// We do rather assume that the most recent encoding is the most
	// desirable!
	for (i = LASTENCODING; i >= rfbEncodingRaw; i--)
	{
		if ( (m_opts.m_PreferredEncoding != i) )
		{
			encs[se->nEncodings++] = Swap32IfLE(i);
			if ( i == rfbEncodingZlib ||
				 i == rfbEncodingTight ||
				 i == rfbEncodingZlibHex
				)
			{
				useCompressLevel = true;
			}
		}
	}

	// Tight - Request desired compression level if applicable
	if ( useCompressLevel && m_opts.m_useCompressLevel &&
		 m_opts.m_compressLevel >= 0 &&
		 m_opts.m_compressLevel <= 9) {
		encs[se->nEncodings++] = Swap32IfLE( rfbEncodingCompressLevel0 +
											 m_opts.m_compressLevel );
	}

	// Tight - Request cursor shape updates if enabled by user
	if (m_opts.m_requestShapeUpdates) {
		encs[se->nEncodings++] = Swap32IfLE(rfbEncodingXCursor);
		encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRichCursor);
	}

	// Tight - Request JPEG quality level if JPEG compression was enabled by user
	if ( m_opts.m_enableJpegCompression &&
		 m_opts.m_jpegQualityLevel >= 0 &&
		 m_opts.m_jpegQualityLevel <= 9) {
		encs[se->nEncodings++] = Swap32IfLE( rfbEncodingQualityLevel0 +
											 m_opts.m_jpegQualityLevel );
	}

    // Modif rdv@2002
	//Tell the server that we support the special Zlibencoding
	encs[se->nEncodings++] = Swap32IfLE(rfbEncodingXOREnable);

	// Tight - LastRect - SINGLE WINDOW
	encs[se->nEncodings++] = Swap32IfLE(rfbEncodingLastRect);
	encs[se->nEncodings++] = Swap32IfLE(rfbEncodingNewFBSize);

	// Modif sf@2002
	if (m_opts.m_fEnableCache)
	{
		encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCacheEnable);
		// vnclog.Print(0, VNCLOG(_T("Cache: Enable Cache sent to Server")));
	}

    // len = sz_rfbSetEncodingsMsg + se->nEncodings * 4;
	
	int nEncodings = se->nEncodings;
	se->nEncodings = Swap16IfLE(se->nEncodings);

	omni_mutex_lock l(m_writeMutex); // Otherwise WriteExacts might be interrupted by MouseEvent
	WriteExact((char *)buf, sz_rfbSetEncodingsMsg, rfbSetEncodings);
	for (int x = 0; x < nEncodings; x++)
	{ 
		WriteExact((char *)&encs[x], sizeof(CARD32));
	}
}

⌨️ 快捷键说明

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