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

📄 vncdesktop.cpp

📁 realvnc是一个非常流行的远程控制程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		// Register it		m_wndClass = RegisterClassEx(&wndclass);		if (!m_wndClass) {			vnclog.Print(LL_INTERR, VNCLOG("failed to register window class\n"));			return FALSE;		}	}	// And create a window	m_hwnd = CreateWindow(szDesktopSink,				"WinVNC",				WS_OVERLAPPEDWINDOW,				CW_USEDEFAULT,				CW_USEDEFAULT,				400, 200,				NULL,				NULL,				hAppInstance,				NULL);	if (m_hwnd == NULL) {		vnclog.Print(LL_INTERR, VNCLOG("failed to create hook window\n"));		return FALSE;	}	// Set the "this" pointer for the window	SetWindowLong(m_hwnd, GWL_USERDATA, (long)this);	// Enable clipboard hooking	m_hnextviewer = SetClipboardViewer(m_hwnd);	return TRUE;}voidvncDesktop::EnableOptimisedBlits(){	vnclog.Print(LL_INTINFO, VNCLOG("attempting to enable DIBsection blits\n"));  // *** not necessary?  /*	if (m_formatmunged) {		vnclog.Print(LL_INTINFO, VNCLOG("unable to enable fast blits\n"));		m_DIBbits = NULL;		return;	}  *//*	// Prepare the bitmapinfo palette if necessary (*** DOESN'T QUITE WORK!)	if (!m_bminfo.truecolour) {		LOGPALETTE *palette;		UINT size = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * 256);		palette = (LOGPALETTE *) new char[size];		if (palette == NULL) {			vnclog.Print(LL_INTERR, VNCLOG("failed to create temp fast palette - disabling fast blits\n"));			return;		}		// Initialise the structure		palette->palVersion = 0x300;		palette->palNumEntries = 256;		// Get the system colours		if (GetSystemPaletteEntries(m_hrootdc,			0, 256, palette->palPalEntry) == 0) {			delete [] palette;			vnclog.Print(LL_INTERR, VNCLOG("failed to init fast palette - disabling fast blits\n"));			return;		}		// Copy the system palette into the bitmap info		for (int i=0; i<256; i++) {			m_bminfo.bmi.bmiColors[i].rgbReserved = 0;			m_bminfo.bmi.bmiColors[i].rgbRed = palette->palPalEntry[i].peRed;			m_bminfo.bmi.bmiColors[i].rgbGreen = palette->palPalEntry[i].peGreen;			m_bminfo.bmi.bmiColors[i].rgbBlue = palette->palPalEntry[i].peBlue;		}		// It worked!		delete [] palette;		vnclog.Print(LL_INTINFO, VNCLOG("initialised fast palette OK\n"));	}*/	// Create a new DIB section	HBITMAP tempbitmap = CreateDIBSection(m_hmemdc, &m_bminfo.bmi, DIB_RGB_COLORS, &m_DIBbits, NULL, 0);	if (tempbitmap == NULL) {		vnclog.Print(LL_INTINFO, VNCLOG("failed to build DIB section - reverting to slow blits\n"));		m_DIBbits = NULL;		return;	}	// Delete the old memory bitmap	if (m_membitmap != NULL) {		DeleteObject(m_membitmap);		m_membitmap = NULL;	}	// Replace old membitmap with DIB section	m_membitmap = tempbitmap;	vnclog.Print(LL_INTINFO, VNCLOG("enabled fast DIBsection blits OK\n"));}BOOLvncDesktop::Init(vncServer *server){	vnclog.Print(LL_INTINFO, VNCLOG("initialising desktop handler\n"));	// Save the server pointer	m_server = server;	// Load in the arrow cursor	m_hdefcursor = LoadCursor(NULL, IDC_ARROW);	m_hcursor = m_hdefcursor;	// Spawn a thread to handle that window's message queue	vncDesktopThread *thread = new vncDesktopThread;	if (thread == NULL) {		vnclog.Print(LL_INTERR, VNCLOG("failed to start hook thread\n"));		return FALSE;	}	m_thread = thread;	return thread->Init(this, m_server);}intvncDesktop::ScreenBuffSize(){	return m_scrinfo.format.bitsPerPixel/8 *		m_scrinfo.framebufferWidth *		m_scrinfo.framebufferHeight;}voidvncDesktop::FillDisplayInfo(rfbServerInitMsg *scrinfo){	memcpy(scrinfo, &m_scrinfo, sz_rfbServerInitMsg);}// Function to capture an area of the screen immediately prior to sending// an update.voidvncDesktop::CaptureScreen(const rfb::Rect &rect, BYTE *scrBuff, UINT scrBuffSize){	assert(rect.enclosed_by(m_bmrect));	// Select the memory bitmap into the memory DC	HBITMAP oldbitmap;	if ((oldbitmap = (HBITMAP) SelectObject(m_hmemdc, m_membitmap)) == NULL)		return;	// Capture screen into bitmap	BOOL blitok = BitBlt(m_hmemdc, rect.tl.x, rect.tl.y,		(rect.br.x-rect.tl.x),		(rect.br.y-rect.tl.y),		m_hrootdc, rect.tl.x, rect.tl.y, SRCCOPY);	// Select the old bitmap back into the memory DC	SelectObject(m_hmemdc, oldbitmap);	if (blitok) {		// Copy the new data to the screen buffer (CopyToBuffer optimises this if possible)		CopyToBuffer(rect, scrBuff, scrBuffSize);	}}// Add the mouse pointer to the buffervoidvncDesktop::CaptureMouse(BYTE *scrBuff, UINT scrBuffSize){	POINT CursorPos;	ICONINFO IconInfo;	// If the mouse cursor handle is invalid then forget it	if (m_hcursor == NULL)		return;	// Get the cursor position	if (!GetCursorPos(&CursorPos))		return;	// Translate position for hotspot	if (GetIconInfo(m_hcursor, &IconInfo))	{		CursorPos.x -= ((int) IconInfo.xHotspot);		CursorPos.y -= ((int) IconInfo.yHotspot);		if (IconInfo.hbmMask != NULL)			DeleteObject(IconInfo.hbmMask);		if (IconInfo.hbmColor != NULL)			DeleteObject(IconInfo.hbmColor);	}	// Select the memory bitmap into the memory DC	HBITMAP oldbitmap;	if ((oldbitmap = (HBITMAP) SelectObject(m_hmemdc, m_membitmap)) == NULL)		return;	// Draw the cursor	DrawIconEx(		m_hmemdc,									// handle to device context 		CursorPos.x, CursorPos.y,		m_hcursor,									// handle to icon to draw 		0,0,										// width of the icon 		0,											// index of frame in animated cursor 		NULL,										// handle to background brush 		DI_NORMAL | DI_COMPAT						// icon-drawing flags 		);	// Select the old bitmap back into the memory DC	SelectObject(m_hmemdc, oldbitmap);	// Save the bounding rectangle	m_cursorpos.tl = CursorPos;	m_cursorpos.br = rfb::Point(GetSystemMetrics(SM_CXCURSOR),		GetSystemMetrics(SM_CYCURSOR)).translate(CursorPos);	// Clip the bounding rect to the screen	// Copy the mouse cursor into the screen buffer, if any of it is visible	m_cursorpos = m_cursorpos.intersect(m_bmrect);	if (!m_cursorpos.is_empty()) {		CopyToBuffer(m_cursorpos, scrBuff, scrBuffSize);	}}// Return the current mouse pointer positionrfb::RectvncDesktop::MouseRect(){	return m_cursorpos;}voidvncDesktop::SetCursor(HCURSOR cursor){	if (cursor == NULL)		m_hcursor = m_hdefcursor;	else		m_hcursor = cursor;}// Manipulation of the clipboardvoid vncDesktop::SetClipText(char* rfbStr){  int len = strlen(rfbStr);  char* winStr = new char[len*2+1];  int j = 0;  for (int i = 0; i < len; i++)  {    if (rfbStr[i] == 10)      winStr[j++] = 13;    winStr[j++] = rfbStr[i];  }  winStr[j++] = 0;  // Open the system clipboard  if (OpenClipboard(m_hwnd))  {    // Empty it    if (EmptyClipboard())    {      HANDLE hMem = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, j);      if (hMem != NULL)      {        LPSTR pMem = (char*)GlobalLock(hMem);        // Get the data        strcpy(pMem, winStr);        // Tell the clipboard        GlobalUnlock(hMem);        SetClipboardData(CF_TEXT, hMem);      }    }  }  delete [] winStr;  // Now close it  CloseClipboard();}// INTERNAL METHODSinline voidvncDesktop::MaskToMaxAndShift(DWORD mask, CARD16 &max, CARD8 &shift){	for (shift = 0; (mask & 1) == 0; shift++)		mask >>= 1;	max = (CARD16) mask;}// Copy data from the memory bitmap into a buffervoidvncDesktop::CopyToBuffer(const rfb::Rect &rect, BYTE *destbuff, UINT destbuffsize){	// Finish drawing anything in this thread 	// Wish we could do this for the whole system - maybe we should	// do something with LockWindowUpdate here.	GdiFlush();	// Are we being asked to blit from the DIBsection to itself?	if (destbuff == m_DIBbits) {		// Yes.  Ignore the request!		return;	}	int y_inv;	BYTE * destbuffpos;	// Calculate the scanline-ordered y position to copy from	y_inv = m_scrinfo.framebufferHeight-rect.tl.y-(rect.br.y-rect.tl.y);	// Calculate where in the output buffer to put the data	destbuffpos = destbuff + (m_bytesPerRow * rect.tl.y);	// Set the number of bytes for GetDIBits to actually write	// NOTE : GetDIBits pads the destination buffer if biSizeImage < no. of bytes required	m_bminfo.bmi.bmiHeader.biSizeImage = (rect.br.y-rect.tl.y) * m_bytesPerRow;	// Get the actual bits from the bitmap into the bit buffer	// If fast (DIBsection) blits are disabled then use the old GetDIBits technique	if (m_DIBbits == NULL) {		if (GetDIBits(m_hmemdc, m_membitmap, y_inv,					(rect.br.y-rect.tl.y), destbuffpos,					&m_bminfo.bmi, DIB_RGB_COLORS) == 0)		{			_RPT1(_CRT_WARN, "vncDesktop : [1] GetDIBits failed! %d\n", GetLastError());			_RPT3(_CRT_WARN, "vncDesktop : thread = %d, DC = %d, bitmap = %d\n", omni_thread::self(), m_hmemdc, m_membitmap);			_RPT2(_CRT_WARN, "vncDesktop : y = %d, height = %d\n", y_inv, (rect.br.y-rect.tl.y));		}	} else {		// Fast blits are enabled.  [I have a sneaking suspicion this will never get used, unless		// something weird goes wrong in the code.  It's here to keep the function general, though!]		int bytesPerPixel = m_scrinfo.format.bitsPerPixel / 8;		BYTE *srcbuffpos = (BYTE*)m_DIBbits;		srcbuffpos += (m_bytesPerRow * rect.tl.y) + (bytesPerPixel * rect.tl.x);		destbuffpos += bytesPerPixel * rect.tl.x;		int widthBytes = (rect.br.x-rect.tl.x) * bytesPerPixel;		for(int y = rect.tl.y; y < rect.br.y; y++)		{			memcpy(destbuffpos, srcbuffpos, widthBytes);			srcbuffpos += m_bytesPerRow;			destbuffpos += m_bytesPerRow;		}	}}// Routine to find out which windows have moved// If copyrect detection isn't perfect then this call returns// the copyrect destination region, to allow the caller to check// for mistakesvoidvncDesktop::CalcCopyRects(rfb::UpdateTracker &tracker){	HWND foreground = GetForegroundWindow();	RECT foreground_rect;	// Actually, we just compare the new and old foreground window & its position	if (foreground != m_foreground_window) {		m_foreground_window=foreground;		// Is the window invisible or can we not get its rect?		if (!IsWindowVisible(foreground) ||			!GetWindowRect(foreground, &foreground_rect)) {			m_foreground_window_rect.clear();		} else {			m_foreground_window_rect = foreground_rect;		}	} else {		// Same window is in the foreground - let's see if it's moved		RECT destrect;		rfb::Rect dest;		rfb::Point source;		// Get the window rectangle		if (IsWindowVisible(foreground) && GetWindowRect(foreground, &destrect))		{			rfb::Rect old_foreground_window_rect = m_foreground_window_rect;			source = m_foreground_window_rect.tl;			m_foreground_window_rect = dest = destrect;			if (!dest.is_empty() && !old_foreground_window_rect.is_empty())			{				// Got the destination position.  Now send to clients!				if (!source.equals(dest.tl))				{					rfb::Point delta = rfb::Point(dest.tl.x-source.x, dest.tl.y-source.y);					// Clip the destination rectangle					dest = dest.intersect(m_bmrect);					if (dest.is_empty()) return;					// Clip the source rectangle					dest = dest.translate(delta.negate()).intersect(m_bmrect);					dest = dest.translate(delta);					if (!dest.is_empty()) {						// Tell the buffer about the copyrect						m_buffer.CopyRect(dest, delta);						// Notify all clients of the copyrect						tracker.add_copied(dest, delta);					}				}			}		} else {			m_foreground_window_rect.clear();		}	}}// Window procedure for the Desktop windowLRESULT CALLBACKDesktopWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam){	vncDesktop *_this = (vncDesktop*)GetWindowLong(hwnd, GWL_USERDATA);	switch (iMsg)	{		// GENERAL	case WM_DISPLAYCHANGE:		// The display resolution is changing		// We must kick off any clients since their screen size will be wrong		_this->m_displaychanged = TRUE;		return 0;	case WM_SYSCOLORCHANGE:	case WM_PALETTECHANGED:		// The palette colours have changed, so tell the server		// Get the system palette		if (!_this->SetPalette())			PostQuitMessage(0);		// Update any palette-based clients, too		_this->m_server->UpdatePalette();		return 0;		// CLIPBOARD MESSAGES	case WM_CHANGECBCHAIN:		// The clipboard chain has changed - check our nextviewer handle		if ((HWND)wParam == _this->m_hnextviewer)			_this->m_hnextviewer = (HWND)lParam;		else			if (_this->m_hnextviewer != NULL)				SendMessage(_this->m_hnextviewer,							WM_CHANGECBCHAIN,							wParam, lParam);		return 0;	case WM_DRAWCLIPBOARD:		// The clipboard contents have changed		if((GetClipboardOwner() != _this->Window()) &&		    _this->m_initialClipBoardSeen &&			_this->m_clipboard_active)		{			LPSTR cliptext = NULL;			// Open the clipboard			if (OpenClipboard(_this->Window()))			{				// Get the clipboard data				HGLOBAL cliphandle = GetClipboardData(CF_TEXT);				if (cliphandle != NULL)				{					LPSTR clipdata = (LPSTR) GlobalLock(cliphandle);					// Copy it into a new buffer					if (clipdata == NULL)						cliptext = NULL;					else						cliptext = strdup(clipdata);					// Release the buffer and close the clipboard					GlobalUnlock(cliphandle);				}				CloseClipboard();			}			if (cliptext != NULL)			{				int cliplen = strlen(cliptext);				LPSTR unixtext = (char *)malloc(cliplen+1);				// Replace CR-LF with LF - never send CR-LF on the wire,				// since Unix won't like it				int unixpos=0;				for (int x=0; x<cliplen; x++)				{					if (cliptext[x] != '\x0d')					{						unixtext[unixpos] = cliptext[x];						unixpos++;					}				}				unixtext[unixpos] = 0;				// Free the clip text				free(cliptext);				cliptext = NULL;				// Now send the unix text to the server				_this->m_server->UpdateClipText(unixtext);				free(unixtext);			}		}		_this->m_initialClipBoardSeen = TRUE;		if (_this->m_hnextviewer != NULL)		{			// Pass the message to the next window in clipboard viewer chain.  			return SendMessage(_this->m_hnextviewer, WM_DRAWCLIPBOARD, 0,0); 		}		return 0;	default:		return DefWindowProc(hwnd, iMsg, wParam, lParam);	}}

⌨️ 快捷键说明

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