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

📄 clientconnection.cpp

📁 realvnc是一个非常流行的远程控制程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:
			case ID_CLOSEDAEMON:				if (MessageBox(NULL, _T("Are you sure you want to exit?"), 						_T("Closing VNCviewer"), 						MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON2) == IDYES)					PostQuitMessage(0);				return 0;			}			break;		}	case WM_DRAWCLIPBOARD:		_this->ProcessLocalClipboardChange();		return 0;	case WM_CHANGECBCHAIN:		{			// The clipboard chain is changing			HWND hWndRemove = (HWND) wParam;     // handle of window being removed 			HWND hWndNext = (HWND) lParam;       // handle of next window in chain 			// If next window is closing, update our pointer.			if (hWndRemove == _this->m_hwndNextViewer)  				_this->m_hwndNextViewer = hWndNext;  			// Otherwise, pass the message to the next link.  			else if (_this->m_hwndNextViewer != NULL) 				::SendMessage(_this->m_hwndNextViewer, WM_CHANGECBCHAIN, 				(WPARAM) hWndRemove,  (LPARAM) hWndNext );  			return 0;		}
#endif

	//Added by: Lars Werner (http://lars.werner.no) - These is the custom messages from the TitleBar
	case tbWM_CLOSE:
		SendMessage(_this->m_hwnd, WM_CLOSE,NULL,NULL);
		return 0;

	case tbWM_MINIMIZE:
		_this->SetDormant(true);
		ShowWindow(_this->m_hwnd, SW_MINIMIZE);
		return 0;

	case tbWM_MAXIMIZE:
		_this->SetFullScreenMode(!_this->InFullScreenMode());
		return 0;
	}	} catch (Exception &e) {		// Eeek.  Something went wrong, so let's clean up and pretend it never happened.		_this->KillThread();		DestroyWindow(hwnd);		return 0;	};	return DefWindowProc(hwnd, iMsg, wParam, lParam);		// We know about an unused variable here.#pragma warning(disable : 4101)}#pragma warning(default : 4101)// ProcessPointerEvent handles the delicate case of emulating 3 buttons// on a two button mouse, then passes events off to SubProcessPointerEvent.voidClientConnection::ProcessPointerEvent(int x, int y, DWORD keyflags, UINT msg) {	if (m_opts.m_Emul3Buttons) {		// XXX To be done:		// If this is a left or right press, the user may be 		// about to press the other button to emulate a middle press.		// We need to start a timer, and if it expires without any		// further presses, then we send the button press. 		// If a press of the other button, or any release, comes in		// before timer has expired, we cancel timer & take different action.	  if (m_waitingOnEmulateTimer)	    {	      if (msg == WM_LBUTTONUP || msg == WM_RBUTTONUP ||		  abs(x - m_emulateButtonPressedX) > m_opts.m_Emul3Fuzz ||		  abs(y - m_emulateButtonPressedY) > m_opts.m_Emul3Fuzz)		{		  // if button released or we moved too far then cancel.		  // First let the remote know where the button was down		  SubProcessPointerEvent(					 m_emulateButtonPressedX, 					 m_emulateButtonPressedY, 					 m_emulateKeyFlags);		  // Then tell it where we are now		  SubProcessPointerEvent(x, y, keyflags);		}	      else if (		       (msg == WM_LBUTTONDOWN && (m_emulateKeyFlags & MK_RBUTTON))		       || (msg == WM_RBUTTONDOWN && (m_emulateKeyFlags & MK_LBUTTON)))		{		  // Triggered an emulate; remove left and right buttons, put		  // in middle one.		  DWORD emulatekeys = keyflags & ~(MK_LBUTTON|MK_RBUTTON);		  emulatekeys |= MK_MBUTTON;		  SubProcessPointerEvent(x, y, emulatekeys);		  		  m_emulatingMiddleButton = true;		}	      else		{		  // handle movement normally & don't kill timer.		  // just remove the pressed button from the mask.		  DWORD keymask = m_emulateKeyFlags & (MK_LBUTTON|MK_RBUTTON);		  DWORD emulatekeys = keyflags & ~keymask;		  SubProcessPointerEvent(x, y, emulatekeys);		  return;		}	      	      // if we reached here, we don't need the timer anymore.	      KillTimer(m_hwnd, m_emulate3ButtonsTimer);	      m_waitingOnEmulateTimer = false;	    }	  else if (m_emulatingMiddleButton)	    {	      if ((keyflags & MK_LBUTTON) == 0 && (keyflags & MK_RBUTTON) == 0)		{		  // We finish emulation only when both buttons come back up.		  m_emulatingMiddleButton = false;		  SubProcessPointerEvent(x, y, keyflags);		}	      else		{		  // keep emulating.		  DWORD emulatekeys = keyflags & ~(MK_LBUTTON|MK_RBUTTON);		  emulatekeys |= MK_MBUTTON;		  SubProcessPointerEvent(x, y, emulatekeys);		}	    }	  else	    {	      // Start considering emulation if we've pressed a button	      // and the other isn't pressed.	      if ( (msg == WM_LBUTTONDOWN && !(keyflags & MK_RBUTTON))		   || (msg == WM_RBUTTONDOWN && !(keyflags & MK_LBUTTON)))		{		  // Start timer for emulation.		  m_emulate3ButtonsTimer = 		    SetTimer(			     m_hwnd, 			     IDT_EMULATE3BUTTONSTIMER, 			     m_opts.m_Emul3Timeout, 			     NULL);		  		  if (!m_emulate3ButtonsTimer)		    {		      log.Print(0, _T("Failed to create timer for emulating 3 buttons"));		      PostMessage(m_hwnd, WM_CLOSE, 0, 0);		      return;		    }		  		  m_waitingOnEmulateTimer = true;		  		  // Note that we don't send the event here; we're batching it for		  // later.		  m_emulateKeyFlags = keyflags;		  m_emulateButtonPressedX = x;		  m_emulateButtonPressedY = y;		}	      else		{		  // just send event noramlly		  SubProcessPointerEvent(x, y, keyflags);		}	    } 	}	else	  {	    SubProcessPointerEvent(x, y, keyflags);	  }}// SubProcessPointerEvent takes windows positions and flags and converts // them into VNC ones.inline void ClientConnection::SubProcessPointerEvent(int x, int y, DWORD keyflags){  int mask;    if (m_opts.m_SwapMouse) {    mask = ( ((keyflags & MK_LBUTTON) ? rfbButton1Mask : 0) |             ((keyflags & MK_MBUTTON) ? rfbButton3Mask : 0) |             ((keyflags & MK_RBUTTON) ? rfbButton2Mask : 0)  );  } else {    mask = ( ((keyflags & MK_LBUTTON) ? rfbButton1Mask : 0) |             ((keyflags & MK_MBUTTON) ? rfbButton2Mask : 0) |             ((keyflags & MK_RBUTTON) ? rfbButton3Mask : 0)  );  }  try {    SendPointerEvent((x + m_hScrollPos) * m_opts.m_scale_den / m_opts.m_scale_num,                      (y + m_vScrollPos) * m_opts.m_scale_den / m_opts.m_scale_num, mask);  } catch (Exception &e) {    e.Report();    PostMessage(m_hwnd, WM_CLOSE, 0, 0);  }}void ClientConnection::ProcessMouseWheel(int delta){  int wheelMask = rfbWheelUpMask;  if (delta < 0) {    wheelMask = rfbWheelDownMask;    delta = -delta;  }  while (delta > 0) {    SendPointerEvent(oldPointerX, oldPointerY, oldButtonMask | wheelMask);    SendPointerEvent(oldPointerX, oldPointerY, oldButtonMask & ~wheelMask);    delta -= 120;  }}//// SendPointerEvent.//inline voidClientConnection::SendPointerEvent(int x, int y, int buttonMask){    rfbPointerEventMsg pe;    oldPointerX = x;    oldPointerY = y;    oldButtonMask = buttonMask;    pe.type = rfbPointerEvent;    pe.buttonMask = buttonMask;    if (x < 0) x = 0;    if (y < 0) y = 0;    pe.x = Swap16IfLE(x);    pe.y = Swap16IfLE(y);    WriteExact((char *)&pe, sz_rfbPointerEventMsg);}//// ProcessKeyEvent//// Normally a single Windows key event will map onto a single RFB// key message, but this is not always the case.  Much of the stuff// here is to handle AltGr (=Ctrl-Alt) on international keyboards.// Example cases:////    We want Ctrl-F to be sent as://      Ctrl-Down, F-Down, F-Up, Ctrl-Up.//    because there is no keysym for ctrl-f, and because the ctrl//    will already have been sent by the time we get the F.////    On German keyboards, @ is produced using AltGr-Q, which is//    Ctrl-Alt-Q.  But @ is a valid keysym in its own right, and when//    a German user types this combination, he doesn't mean Ctrl-@.//    So for this we will send, in total:////      Ctrl-Down, Alt-Down,   //                 (when we get the AltGr pressed)////      Alt-Up, Ctrl-Up, @-Down, Ctrl-Down, Alt-Down //                 (when we discover that this is @ being pressed)////      Alt-Up, Ctrl-Up, @-Up, Ctrl-Down, Alt-Down//                 (when we discover that this is @ being released)////      Alt-Up, Ctrl-Up//                 (when the AltGr is released)inline void ClientConnection::ProcessKeyEvent(int virtkey, DWORD keyData){    bool down = ((keyData & 0x80000000l) == 0);    // if virtkey found in mapping table, send X equivalent    // else    //   try to convert directly to ascii    //   if result is in range supported by X keysyms,    //      raise any modifiers, send it, then restore mods    //   else    //      calculate what the ascii would be without mods    //      send that#ifdef _DEBUG#ifdef UNDER_CE	char *keyname="";#else    char keyname[32];    if (GetKeyNameText(  keyData,keyname, 31)) {        log.Print(4, _T("Process key: %s (keyData %04x): "), keyname, keyData);    };#endif#endif	try {		KeyActionSpec kas = m_keymap.PCtoX(virtkey, keyData);    				if (kas.releaseModifiers & KEYMAP_LCONTROL) {			SendKeyEvent(XK_Control_L, false );			log.Print(5, _T("fake L Ctrl raised\n"));		}		if (kas.releaseModifiers & KEYMAP_LALT) {			SendKeyEvent(XK_Alt_L, false );			log.Print(5, _T("fake L Alt raised\n"));		}		if (kas.releaseModifiers & KEYMAP_RCONTROL) {			SendKeyEvent(XK_Control_R, false );			log.Print(5, _T("fake R Ctrl raised\n"));		}		if (kas.releaseModifiers & KEYMAP_RALT) {			SendKeyEvent(XK_Alt_R, false );			log.Print(5, _T("fake R Alt raised\n"));		}				for (int i = 0; kas.keycodes[i] != XK_VoidSymbol && i < MaxKeysPerKey; i++) {			SendKeyEvent(kas.keycodes[i], down );			log.Print(4, _T("Sent keysym %04x (%s)\n"), 				kas.keycodes[i], down ? _T("press") : _T("release"));		}				if (kas.releaseModifiers & KEYMAP_RALT) {			SendKeyEvent(XK_Alt_R, true );			log.Print(5, _T("fake R Alt pressed\n"));		}		if (kas.releaseModifiers & KEYMAP_RCONTROL) {			SendKeyEvent(XK_Control_R, true );			log.Print(5, _T("fake R Ctrl pressed\n"));		}		if (kas.releaseModifiers & KEYMAP_LALT) {			SendKeyEvent(XK_Alt_L, false );			log.Print(5, _T("fake L Alt pressed\n"));		}		if (kas.releaseModifiers & KEYMAP_LCONTROL) {			SendKeyEvent(XK_Control_L, false );			log.Print(5, _T("fake L Ctrl pressed\n"));		}	} catch (Exception &e) {		e.Report();		PostMessage(m_hwnd, WM_CLOSE, 0, 0);	}}//// SendKeyEvent//inline voidClientConnection::SendKeyEvent(CARD32 key, bool down){    rfbKeyEventMsg ke;    ke.type = rfbKeyEvent;    ke.down = down ? 1 : 0;    ke.key = Swap32IfLE(key);    WriteExact((char *)&ke, sz_rfbKeyEventMsg);    log.Print(6, _T("SendKeyEvent: key = x%04x status = %s\n"), key,         down ? _T("down") : _T("up"));}#ifndef UNDER_CE//// SendClientCutText//void ClientConnection::SendClientCutText(char *str, int len){    rfbClientCutTextMsg cct;    cct.type = rfbClientCutText;    cct.length = Swap32IfLE(len);    WriteExact((char *)&cct, sz_rfbClientCutTextMsg);	WriteExact(str, len);	log.Print(6, _T("Sent %d bytes of clipboard\n"), len);}#endif// Copy any updated areas from the bitmap onto the screen.inline void ClientConnection::DoBlit() {	if (m_hBitmap == NULL) return;	if (!m_running) return;					// No other threads can use bitmap DC	omni_mutex_lock l(m_bitmapdcMutex);	PAINTSTRUCT ps;	HDC hdc = BeginPaint(m_hwnd, &ps);	// Select and realize hPalette	PaletteSelector p(hdc, m_hPalette);	ObjectSelector b(m_hBitmapDC, m_hBitmap);				if (m_opts.m_delay) {		// Display the area to be updated for debugging purposes		COLORREF oldbgcol = SetBkColor(hdc, RGB(0,0,0));		::ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &ps.rcPaint, NULL, 0, NULL);		SetBkColor(hdc,oldbgcol);		::Sleep(m_pApp->m_options.m_delay);	}		if (m_opts.m_scaling) {		int n = m_opts.m_scale_num;		int d = m_opts.m_scale_den;				// We're about to do some scaling on these values in the StretchBlt		// We want to make sure that they divide nicely by n so we round them		// down and up appropriately.		ps.rcPaint.left =   ((ps.rcPaint.left   + m_hScrollPos) / n * n)         - m_hScrollPos;		ps.rcPaint.right =  ((ps.rcPaint.right  + m_hScrollPos + n - 1) / n * n) - m_hScrollPos;		ps.rcPaint.top =    ((ps.rcPaint.top    + m_vScrollPos) / n * n)         - m_vScrollPos;		ps.rcPaint.bottom = ((ps.rcPaint.bottom + m_vScrollPos + n - 1) / n * n) - m_vScrollPos;				// This is supposed to give better results.  I think my driver ignores it?		SetStretchBltMode(hdc, HALFTONE);		// The docs say that you should call SetBrushOrgEx after SetStretchBltMode, 		// but not what the arguments should be.		SetBrushOrgEx(hdc, 0,0, NULL);				if (!StretchBlt(			hdc, 			ps.rcPaint.left, 			ps.rcPaint.top, 			ps.rcPaint.right-ps.rcPaint.left, 			ps.rcPaint.bottom-ps.rcPaint.top, 			m_hBitmapDC, 			(ps.rcPaint.left+m_hScrollPos)     * d / n, 			(ps.rcPaint.top+m_vScrollPos)      * d / n,			(ps.rcPaint.right-ps.rcPaint.left) * d / n, 			(ps.rcPaint.bottom-ps.rcPaint.top) * d / n, 			SRCCOPY)) 		{			log.Print(0, _T("Blit error %d\n"), GetLastError());			// throw ErrorException("Error in blit!\n");		};	} else {

⌨️ 快捷键说明

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