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

📄 vncclient.cpp

📁 teamviewer source code vc++
💻 CPP
📖 第 1 页 / 共 5 页
字号:
			break;

		case rfbPointerEvent:
			// Read the rest of the message:
			if (m_socket->ReadExact(((char *) &msg)+nTO, sz_rfbPointerEventMsg-nTO))
			{
				// do not accept input while single window is pending
				if(m_client->m_encodemgr.m_buffer->m_desktop->m_stop_input_while_sw)
					break;

				DWORD timeSinceLastMouseMove=timeGetTime() - lastMouseMove;
				if (m_client->m_pointerenabled && timeSinceLastMouseMove > 1000)  // && false)// m_client->m_encodemgr.m_buffer->m_desktop->l
				{
					// Convert the coords to Big Endian
					// Modif sf@2002 - Scaling
					msg.pe.x = (Swap16IfLE(msg.pe.x) + m_client->m_SWOffsetx+m_client->m_ScreenOffsetx) * m_client->m_nScale;
					msg.pe.y = (Swap16IfLE(msg.pe.y) + m_client->m_SWOffsety+m_client->m_ScreenOffsety) * m_client->m_nScale;

					// Work out the flags for this event
					DWORD flags = MOUSEEVENTF_ABSOLUTE;

					// do not allow remote control of TeamViewer windows
					POINT p;							
					p.x = msg.pe.x;
					p.y = msg.pe.y;
					HWND over = WindowFromPoint(p);
					while(GetParent(over))
						over = GetParent(over);
					if(over == SessionDialog::Hwnd())
					{
						msg.pe.buttonMask = 0;
					}

					if (msg.pe.x != m_client->m_ptrevent.x ||
						msg.pe.y != m_client->m_ptrevent.y)
						flags |= MOUSEEVENTF_MOVE;
					if ( (msg.pe.buttonMask & rfbButton1Mask) != 
						(m_client->m_ptrevent.buttonMask & rfbButton1Mask) )
					{
					    if (GetSystemMetrics(SM_SWAPBUTTON))
						flags |= (msg.pe.buttonMask & rfbButton1Mask) 
						    ? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_RIGHTUP;
					    else
						flags |= (msg.pe.buttonMask & rfbButton1Mask) 
						    ? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_LEFTUP;
					}
					if ( (msg.pe.buttonMask & rfbButton2Mask) != 
						(m_client->m_ptrevent.buttonMask & rfbButton2Mask) )
					{
						flags |= (msg.pe.buttonMask & rfbButton2Mask) 
						    ? MOUSEEVENTF_MIDDLEDOWN : MOUSEEVENTF_MIDDLEUP;
					}
					if ( (msg.pe.buttonMask & rfbButton3Mask) != 
						(m_client->m_ptrevent.buttonMask & rfbButton3Mask) )
					{
					    if (GetSystemMetrics(SM_SWAPBUTTON))
						flags |= (msg.pe.buttonMask & rfbButton3Mask) 
						    ? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_LEFTUP;
					    else
						flags |= (msg.pe.buttonMask & rfbButton3Mask) 
						    ? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_RIGHTUP;
					}
						

					// Treat buttons 4 and 5 presses as mouse wheel events
					DWORD wheel_movement = 0;
					if (m_client->m_encodemgr.IsMouseWheelTight())
					{
						if ((msg.pe.buttonMask & rfbButton4Mask) != 0 &&
							(m_client->m_ptrevent.buttonMask & rfbButton4Mask) == 0)
						{
							flags |= MOUSEEVENTF_WHEEL;
							wheel_movement = (DWORD)+120;
						}
						else if ((msg.pe.buttonMask & rfbButton5Mask) != 0 &&
								 (m_client->m_ptrevent.buttonMask & rfbButton5Mask) == 0)
						{
							flags |= MOUSEEVENTF_WHEEL;
							wheel_movement = (DWORD)-120;
						}
					}
					else
					{
						// RealVNC 335 Mouse wheel support
						if (msg.pe.buttonMask & rfbWheelUpMask) {
							flags |= MOUSEEVENTF_WHEEL;
							wheel_movement = WHEEL_DELTA;
						}
						if (msg.pe.buttonMask & rfbWheelDownMask) {
							flags |= MOUSEEVENTF_WHEEL;
							wheel_movement = -WHEEL_DELTA;
						}
					}

					// Generate coordinate values
					// bug fix John Latino
					// offset for multi display
					int screenX, screenY, screenDepth;
					m_server->GetScreenInfo(screenX, screenY, screenDepth);
//					vnclog.Print(LL_INTINFO, VNCLOG("########mouse :%i %i %i %i "),screenX, screenY,m_client->m_ScreenOffsetx,m_client->m_ScreenOffsety );
					if (m_client->m_display_type==1)
						{//primary display always have (0,0) as corner
							unsigned long x = (msg.pe.x *  65535) / (screenX-1);
							unsigned long y = (msg.pe.y * 65535) / (screenY-1);
							// Do the pointer event
							::mouse_event(flags, (DWORD) x, (DWORD) y, wheel_movement, 0);
//							vnclog.Print(LL_INTINFO, VNCLOG("########mouse_event :%i %i "),x,y);
						}
					else
						{//second or spanned
							if (m_client->Sendinput)
							{							
								INPUT evt;
								evt.type = INPUT_MOUSE;
								msg.pe.x=msg.pe.x-GetSystemMetrics(SM_XVIRTUALSCREEN);
								msg.pe.y=msg.pe.y-GetSystemMetrics(SM_YVIRTUALSCREEN);
								evt.mi.dx = (msg.pe.x * 65535) / (GetSystemMetrics(SM_CXVIRTUALSCREEN)-1);
								evt.mi.dy = (msg.pe.y* 65535) / (GetSystemMetrics(SM_CYVIRTUALSCREEN)-1);
								evt.mi.dwFlags = flags | MOUSEEVENTF_VIRTUALDESK;
								evt.mi.dwExtraInfo = 0;
								evt.mi.mouseData = wheel_movement;
								evt.mi.time = 0;
								m_client->Sendinput(1, &evt, sizeof(evt));
							}
							else
							{
								POINT cursorPos; GetCursorPos(&cursorPos);
								ULONG oldSpeed, newSpeed = 10;
								ULONG mouseInfo[3];
								if (flags & MOUSEEVENTF_MOVE) 
									{
										flags &= ~MOUSEEVENTF_ABSOLUTE;
										SystemParametersInfo(SPI_GETMOUSE, 0, &mouseInfo, 0);
										SystemParametersInfo(SPI_GETMOUSESPEED, 0, &oldSpeed, 0);
										ULONG idealMouseInfo[] = {10, 0, 0};
										SystemParametersInfo(SPI_SETMOUSESPEED, 0, &newSpeed, 0);
										SystemParametersInfo(SPI_SETMOUSE, 0, &idealMouseInfo, 0);
									}
								::mouse_event(flags, msg.pe.x-cursorPos.x, msg.pe.y-cursorPos.y, wheel_movement, 0);
								if (flags & MOUSEEVENTF_MOVE) 
									{
										SystemParametersInfo(SPI_SETMOUSE, 0, &mouseInfo, 0);
										SystemParametersInfo(SPI_SETMOUSESPEED, 0, &oldSpeed, 0);
									}
							}
					}
					// Save the old position
					m_client->m_ptrevent = msg.pe;

					// Staudenmeyer: save event position so it is not mistaken for local input later
					lastRemoteMouseEventPosition.x=msg.pe.x;
					lastRemoteMouseEventPosition.y=msg.pe.y;

					// Flag that a remote event occurred
					m_client->m_remoteevent = TRUE;

					// Tell the desktop hook system to grab the screen...
					m_client->m_encodemgr.m_buffer->m_desktop->TriggerUpdate();
				}
			}
			else
				connected = FALSE;
			
			break;

		case rfbClientCutText:
			// Read the rest of the message:
			if (m_socket->ReadExact(((char *) &msg)+nTO, sz_rfbClientCutTextMsg-nTO))
			{
				// Allocate storage for the text
				const UINT length = Swap32IfLE(msg.cct.length);
				char *text = new char [length+1];
				if (text == NULL)
					break;
				text[length] = 0;

				// Read in the text
				if (!m_socket->ReadExact(text, length)) {
					delete [] text;
					break;
				}

				// Get the server to update the local clipboard
				m_server->UpdateLocalClipText(text);

				// Free the clip text we read
				delete [] text;
			}
			else
				connected = FALSE;
			break;


		// Modif sf@2002 - Scaling
		// Server Scaling Message received
		case rfbPalmVNCSetScaleFactor:
			m_client->m_fPalmVNCScaling = true;
		case rfbSetScale: // Specific PalmVNC SetScaleFactor
			{
				// m_client->m_fPalmVNCScaling = false;
				// Read the rest of the message 
				if (m_client->m_fPalmVNCScaling)
				{
					if (!m_socket->ReadExact(((char *) &msg) + nTO, sz_rfbPalmVNCSetScaleFactorMsg - nTO))
					{
						connected = FALSE;
						break;
					}
				}
				else
				{
					if (!m_socket->ReadExact(((char *) &msg) + nTO, sz_rfbSetScaleMsg - nTO))
					{
						connected = FALSE;
						break;
					}
				}

				// Only accept reasonable scales...
				if (msg.ssc.scale >= 1 || msg.ssc.scale <= 9)
				{
					if(!m_client->SetScaling(msg.ssc.scale))
						connected = FALSE;
				}
			}
			break;

		// TR@2004 - ModeChange
		// Request to change the connection mode was received
		case rfbModeChangeRequest:
			
			if (!m_socket->ReadExact(((char *) &msg) + nTO, sz_rfbModeChangeMsg - nTO))
			{
				connected = FALSE;
				break;
			}

			if ( !(msg.mchange.newmode & rfbMC_Servermodes))
			{
				// a change to a viewer mode was requested

				// disable server data updates
				m_client->DisableProtocol();

				// Finally, it's safe to kill the update thread here
				if (m_client->m_updatethread) {
					m_client->m_updatethread->Kill();
					m_client->m_updatethread->join(NULL);
					m_client->m_updatethread = NULL;
				}

				// accept mode change
				rfbModeChangeMsg mchange;

				mchange.type = rfbModeChange;
				mchange.newmode = msg.mchange.newmode | rfbMC_Servermodes;  // switch the partner to the corresponding server mode

				m_socket->SendExact((char *)&mchange, sz_rfbModeChangeMsg);

				// Clientmodus aktivieren
                //!!!!!! app wird nicht gel鰏cht
				VNCviewerApp32 *app = VNCviewerApp32::Instance();

				// sofort 黚er bestehenden Socket verbinden
				app->NewConnection((SOCKET)m_socket->sock,msg.mchange.newmode, 
									m_client->connectionLogUser, m_client->connectionLogStartTime, m_client->m_ActiveMode);					
				m_client->keepSocket=TRUE;
				
				// Serververbindung beenden
				connected= FALSE;

			} else  // andere Varianten ignorieren
				break;

			break;

		// TR@2004 - read client磗 screen dimensions
		// Client sends screen dimensions so we can display the area the client can see
		case rfbDisplayDimensions:
			
			if (!m_socket->ReadExact(((char *) &msg) + nTO, sz_rfbDisplayDimensionsMsg - nTO))
			{
				connected = FALSE;
				break;
			}
			
			// NOT YET IMPLEMENTED
			break;

		// Set Server Input
		case rfbSetServerInput:
			if (!m_socket->ReadExact(((char *) &msg) + nTO, sz_rfbSetServerInputMsg - nTO))
			{
				connected = FALSE;
				break;
			}
			if (m_client->m_keyboardenabled)
				{
					if (msg.sim.status==1) m_client->m_encodemgr.m_buffer->m_desktop->SetDisableInput(true);
					if (msg.sim.status==0) m_client->m_encodemgr.m_buffer->m_desktop->SetDisableInput(false);
				}
			break;


		// Set Single Window
		case rfbSetSW:
			if (!m_socket->ReadExact(((char *) &msg) + nTO, sz_rfbSetSWMsg - nTO))
			{
				connected = FALSE;
				break;
			}
			if (Swap16IfLE(msg.sw.x)<5 && Swap16IfLE(msg.sw.y)<5) 
			{
				m_client->m_encodemgr.m_buffer->m_desktop->SetSW(1,1);
				break;
			}
			m_client->m_encodemgr.m_buffer->m_desktop->SetSW(
				(Swap16IfLE(msg.sw.x) + m_client->m_SWOffsetx+m_client->m_ScreenOffsetx) * m_client->m_nScale,
				(Swap16IfLE(msg.sw.y) + m_client->m_SWOffsety+m_client->m_ScreenOffsety) * m_client->m_nScale);
			break;


		// Modif sf@2002 - TextChat
		case rfbTextChat:
			m_client->m_pTextChat->ProcessTextChatMsg(nTO);
			break;


		// Modif sf@2002 - FileTransfer
		// File Transfer Message
		case rfbFileTransfer:
			{

			// TR@2004: maybe we have to accept the incoming filetransfer request
 			if (m_client->FileTransferEnabled()==0)
			{
				if (m_server->FileTransferEnabled()==1)
					// no query
					m_client->SetFileTransferEnabled(1);
				if (m_server->FileTransferEnabled()==2)
				{
					// query user - we use the same query restrictions as with incoming conns
					vncAcceptDialog *acceptDlg = new vncAcceptDialog(m_server->QueryTimeout(),m_server->QueryAccept());	
					AcceptDialogResult result=acceptDlg->DoDialog();
					if(result==AcceptWithTimeout)							// yes, filetransfer allowed
					{
						m_client->SetFileTransferEnabled(1);				
						m_client->m_fileTransferDialogTimedOut=true;
					}
					else if(result==Accept)									// yes, filetransfer allowed
					{
						m_client->SetFileTransferEnabled(1);				
					}
					else													// not allowed
					if(m_client->ActiveMode() == rfbMC_FiletransferServer)
					{
						m_client->Kill();							// quit if we are only a filetransferserver
						break;
					}
				}
			}

			// sf@2004 - An unlogged user can't access to FT
			bool fUserOk = true;
			if (m_server->FTUserImpersonation())
			{
				fUserOk = m_client->DoFTUserImpersonation();
			}

			omni_mutex_lock l(m_client->GetUpdateLock());

			// Read the rest of the message:
			m_client->m_fFileTransferRunning = TRUE; 
			if (m_socket->ReadExact(((char *) &msg) + nTO, sz_rfbFileTransferMsg - nTO))
			{
				switch (msg.ft.contentType)
				{
				// A new file is received from the client
					// case rfbFileHeader:
					case rfbFileTransferOffer:
						{
						omni_mutex_lock l(m_client->GetUpdateLock());
						if (m_client->FileTransferEnabled()==0 || !fUserOk) break;	
						// bool fError = false;

						const UINT length = Swap32IfLE(msg.ft.length);
						memset(m_client->m_szFullDestName, 0, sizeof(m_client->m_szFullDestName));
						if (length > sizeof(m_client->m_szFullDestName)) break;
						// Read in the Name of the file to create
						if (!m_socket->ReadExact(m_client->m_szFullDestName, length)) 
						{
							//MessageBox(NULL, "1. Abort !", "Ultra WinVNC", MB_OK);
							// vnclog.Print(LL_INTINFO, VNCLOG("*** FileTransfer: Failed to receive FileName from Viewer. Abort !"));
							break;
						}
						// sf@2004 - Improving huge files size handling
						CARD32 sizeL = Swap32IfLE(msg.ft.size);
						CARD32 sizeH = 0;
						CARD32 sizeHtmp = 0;
						if (!m_socket->ReadExact((char*)&sizeHtmp, sizeof(CARD32)))
						{
							//MessageBox(NULL, "2. Abort !", "Ultra WinVNC", MB_OK);
							//vnclog.Print(LL_INTINFO, VNCLOG("*** FileTransfer: Failed to receive SizeH from Viewer. Abort !"));
							break;
						}
						sizeH = Swap32IfLE(sizeHtmp);

						if(m_client->FileTransferEnabled() == -1)	// filetransfer forbidden
							break;

						// Parse the FileTime
						char *p = strrchr(m_client->m_szFullDestName, ',');
						if (p == NULL)
							m_client->m_szFileTime[0] = '\0';
						else 
						{
							strcpy(m_client->m_szFileTime, p+1);
							*p = '\0';
						}

						// sf@2004 - Directory Delta Transfer
						// If the offered file is a zipped directory, we test if it already exists here
						// and create the zip accordingly. This way we can generate the checksums for it.
						// m_client->CheckAndZipDirectoryForChecksuming

⌨️ 快捷键说明

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