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

📄 clientconnection.cpp

📁 tightvnc源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		vnclog.Print(3, _T("Palette-based display - %d entries, %d reserved\n"), 
			GetDeviceCaps(m_hBitmapDC, SIZEPALETTE), GetDeviceCaps(m_hBitmapDC, NUMRESERVED));
		BYTE buf[sizeof(LOGPALETTE)+216*sizeof(PALETTEENTRY)];
		LOGPALETTE *plp = (LOGPALETTE *) buf;
		int pepos = 0;
		for (int r = 5; r >= 0; r--) {
			for (int g = 5; g >= 0; g--) {
				for (int b = 5; b >= 0; b--) {
					plp->palPalEntry[pepos].peRed   = r * 255 / 5; 	
					plp->palPalEntry[pepos].peGreen = g * 255 / 5;
					plp->palPalEntry[pepos].peBlue  = b * 255 / 5;
					plp->palPalEntry[pepos].peFlags  = NULL;
					pepos++;
				}
			}
		}
		plp->palVersion = 0x300;
		plp->palNumEntries = 216;
		m_hPalette = CreatePalette(plp);
	}

	// Add stuff to System menu
	HMENU hsysmenu = GetSystemMenu(m_hwnd1, FALSE);
	if (!m_opts.m_restricted) {
		bool save_item_flags = (m_serverInitiated) ? MF_GRAYED : 0;
		AppendMenu(hsysmenu, MF_SEPARATOR, NULL, NULL);
		AppendMenu(hsysmenu, MF_STRING, IDC_OPTIONBUTTON,
				   _T("Connection &options...\tCtrl-Alt-Shift-O"));
		AppendMenu(hsysmenu, MF_STRING, ID_CONN_ABOUT,
				   _T("Connection &info\tCtrl-Alt-Shift-I"));
		AppendMenu(hsysmenu, MF_STRING, ID_REQUEST_REFRESH,
				   _T("Request screen &refresh\tCtrl-Alt-Shift-R"));
		AppendMenu(hsysmenu, MF_SEPARATOR, NULL, NULL);
		AppendMenu(hsysmenu, MF_STRING, ID_FULLSCREEN,
				   _T("&Full screen\tCtrl-Alt-Shift-F"));
		AppendMenu(hsysmenu, MF_STRING, ID_TOOLBAR,
				   _T("Show &toolbar\tCtrl-Alt-Shift-T"));
		AppendMenu(hsysmenu, MF_SEPARATOR, NULL, NULL);
		AppendMenu(hsysmenu, MF_STRING, ID_CONN_CTLALTDEL,
				   _T("Send Ctrl-Alt-&Del"));
		AppendMenu(hsysmenu, MF_STRING, ID_CONN_CTLESC,
				   _T("Send Ctrl-Esc"));
		AppendMenu(hsysmenu, MF_STRING, ID_CONN_CTLDOWN,
				   _T("Ctrl key down"));
		AppendMenu(hsysmenu, MF_STRING, ID_CONN_ALTDOWN,
				   _T("Alt key down"));
		AppendMenu(hsysmenu, MF_SEPARATOR, NULL, NULL);
		AppendMenu(hsysmenu, MF_STRING | MF_GRAYED, IDD_FILETRANSFER,
				   _T("Transf&er files...\tCtrl-Alt-Shift-E"));
		AppendMenu(hsysmenu, MF_SEPARATOR, NULL, NULL);
		AppendMenu(hsysmenu, MF_STRING, ID_NEWCONN,
				   _T("&New connection...\tCtrl-Alt-Shift-N"));
		AppendMenu(hsysmenu, save_item_flags, ID_CONN_SAVE_AS,
				   _T("&Save connection info as...\tCtrl-Alt-Shift-S"));
	}

	AppendMenu(hsysmenu, MF_SEPARATOR, NULL, NULL);
	AppendMenu(hsysmenu, MF_STRING, IDD_APP_ABOUT,
			   _T("&About TightVNC Viewer..."));
	if (m_opts.m_listening) {
		AppendMenu(hsysmenu, MF_SEPARATOR, NULL, NULL);
		AppendMenu(hsysmenu, MF_STRING, ID_CLOSEDAEMON,
				   _T("Close &listening daemon"));
	}
	DrawMenuBar(m_hwnd1);

	m_hToolbar = CreateToolbar();

	m_hwnd = CreateWindow("ChildClass",
			      NULL,
			      WS_CHILD | WS_CLIPSIBLINGS,
			      CW_USEDEFAULT,
			      CW_USEDEFAULT,
			      CW_USEDEFAULT,       // x-size
			      CW_USEDEFAULT,	   // y-size
			      m_hwndscroll,             // Parent handle
			      NULL,                // Menu handle
			      m_pApp->m_instance,
			      NULL);
	m_opts.m_hWindow = m_hwnd;
	hotkeys.SetWindow(m_hwnd1);
    ShowWindow(m_hwnd, SW_HIDE);
		
	SetWindowLong(m_hwnd, GWL_USERDATA, (LONG) this);
	SetWindowLong(m_hwnd, GWL_WNDPROC, (LONG)ClientConnection::WndProc);
	
	if(pApp->m_options.m_toolbar) {
		CheckMenuItem(GetSystemMenu(m_hwnd1, FALSE),
					ID_TOOLBAR, MF_BYCOMMAND|MF_CHECKED);
	}
	SaveListConnection();
	
	// record which client created this window
	
#ifndef _WIN32_WCE
	// We want to know when the clipboard changes, so
	// insert ourselves in the viewer chain. But doing
	// this will cause us to be notified immediately of
	// the current state.
	// We don't want to send that.
	m_initialClipboardSeen = false;
	m_hwndNextViewer = SetClipboardViewer(m_hwnd);
#endif
}

HWND ClientConnection::CreateToolbar()
{
	const int MAX_TOOLBAR_BUTTONS = 20;
	TBBUTTON but[MAX_TOOLBAR_BUTTONS];
	memset(but, 0, sizeof(but));
	int i = 0;

	but[i].iBitmap		= 0;
	but[i].idCommand	= IDC_OPTIONBUTTON;
	but[i].fsState		= TBSTATE_ENABLED;
	but[i++].fsStyle	= TBSTYLE_BUTTON;

	but[i].iBitmap		= 1;
	but[i].idCommand	= ID_CONN_ABOUT;
	but[i].fsState		= TBSTATE_ENABLED;
	but[i++].fsStyle	= TBSTYLE_BUTTON;

	but[i++].fsStyle	= TBSTYLE_SEP;

	but[i].iBitmap		= 2;
	but[i].idCommand	= ID_FULLSCREEN;
	but[i].fsState		= TBSTATE_ENABLED;
	but[i++].fsStyle	= TBSTYLE_BUTTON;

	but[i].iBitmap		= 3;
	but[i].idCommand	= ID_REQUEST_REFRESH;
	but[i].fsState		= TBSTATE_ENABLED;
	but[i++].fsStyle	= TBSTYLE_BUTTON;

	but[i++].fsStyle	= TBSTYLE_SEP;

	but[i].iBitmap		= 4;
	but[i].idCommand	= ID_CONN_CTLALTDEL;
	but[i].fsState		= TBSTATE_ENABLED;
	but[i++].fsStyle	= TBSTYLE_BUTTON;

	but[i].iBitmap		= 5;
	but[i].idCommand	= ID_CONN_CTLESC;
	but[i].fsState		= TBSTATE_ENABLED;
	but[i++].fsStyle	= TBSTYLE_BUTTON;

	but[i].iBitmap		= 6;
	but[i].idCommand	= ID_CONN_CTLDOWN;
	but[i].fsState		= TBSTATE_ENABLED;
	but[i++].fsStyle	= TBSTYLE_CHECK;

	but[i].iBitmap		= 7;
	but[i].idCommand	= ID_CONN_ALTDOWN;
	but[i].fsState		= TBSTATE_ENABLED;
	but[i++].fsStyle	= TBSTYLE_CHECK;

	but[i++].fsStyle	= TBSTYLE_SEP;

	but[i].iBitmap		= 8;
	but[i].idCommand	= IDD_FILETRANSFER;
	but[i].fsState		= TBSTATE_INDETERMINATE;
	but[i++].fsStyle	= TBSTYLE_BUTTON;

	but[i++].fsStyle	= TBSTYLE_SEP;

	but[i].iBitmap		= 9;
	but[i].idCommand	= ID_NEWCONN;
	but[i].fsState		= TBSTATE_ENABLED;
	but[i++].fsStyle	= TBSTYLE_BUTTON;

	but[i].iBitmap		= 10;
	but[i].idCommand	= ID_CONN_SAVE_AS;
	but[i].fsState		= TBSTATE_ENABLED;
	but[i++].fsStyle	= TBSTYLE_BUTTON;

	but[i].iBitmap		= 11;
	but[i].idCommand	= ID_DISCONNECT;
	but[i].fsState		= TBSTATE_ENABLED;
	but[i++].fsStyle	= TBSTYLE_BUTTON;

	int numButtons = i;
	assert(numButtons <= MAX_TOOLBAR_BUTTONS);

	HWND hwndToolbar = CreateToolbarEx(m_hwnd1,
		WS_CHILD | TBSTYLE_TOOLTIPS | 
		WS_CLIPSIBLINGS | TBSTYLE_FLAT,
		ID_TOOLBAR, 12, m_pApp->m_instance,
		IDB_BITMAP1, but, numButtons, 0, 0, 0, 0, sizeof(TBBUTTON));

	if (hwndToolbar != NULL)
		SendMessage(hwndToolbar, TB_SETINDENT, 4, 0);

	return hwndToolbar;
}

void ClientConnection::SaveListConnection()
{
	if (!m_serverInitiated) {
		TCHAR  valname[3];
		int dwbuflen = 255;
		int i, j;
		int maxEntries = pApp->m_options.m_historyLimit;
		TCHAR list[80];
		HKEY m_hRegKey;
		TCHAR  buf[256];
		DWORD dispos;
		TCHAR  buf1[256];
				
		itoa(maxEntries, list, 10);
		RegCreateKeyEx(HKEY_CURRENT_USER,
					KEY_VNCVIEWER_HISTORI, 0, NULL, 
					REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 
					NULL, &m_hRegKey, &dispos);
		_tcscpy(buf1, m_opts.m_display);
							
		for ( i = 0; i < maxEntries; i++) {
			j = i;
			itoa(i, valname, 10);
			dwbuflen = 255;
			if ((RegQueryValueEx( m_hRegKey, (LPTSTR)valname, 
						NULL, NULL, 
						(LPBYTE) buf, (LPDWORD) &dwbuflen) != ERROR_SUCCESS) ||
						(_tcscmp(buf, m_opts.m_display) == NULL)) {
				RegSetValueEx( m_hRegKey, valname, 
							NULL, REG_SZ, 
							(CONST BYTE *)buf1, (_tcslen(buf1)+1));
				break;
			}
			RegSetValueEx(m_hRegKey, valname, 
						NULL, REG_SZ, 
						(CONST BYTE *)buf1, (_tcslen(buf1)+1)); 
				_tcscpy(buf1, buf);
		}
		if (j == maxEntries) {
			dwbuflen = 255;
			_tcscpy(valname, list);
			_tcscpy(buf, "");
			RegQueryValueEx( m_hRegKey, (LPTSTR)valname, 
						NULL, NULL, 
						(LPBYTE)buf, (LPDWORD)&dwbuflen);
			m_opts.delkey(buf, KEY_VNCVIEWER_HISTORI);
		}
		RegCloseKey(m_hRegKey);
		m_opts.SaveOpt(m_opts.m_display,
						KEY_VNCVIEWER_HISTORI);
	}		
}

void ClientConnection::EnableFullControlOptions()
{
	if (m_opts.m_ViewOnly) {
		SwitchOffKey();
		EnableAction(IDD_FILETRANSFER, false);
		EnableAction(ID_CONN_CTLALTDEL, false);
		EnableAction(ID_CONN_CTLDOWN, false);
		EnableAction(ID_CONN_ALTDOWN, false);
		EnableAction(ID_CONN_CTLESC, false);
	} else {
		EnableAction(IDD_FILETRANSFER, m_enableFileTransfers);
		EnableAction(ID_CONN_CTLALTDEL, true);
		EnableAction(ID_CONN_CTLDOWN, true);
		EnableAction(ID_CONN_ALTDOWN, true);
		EnableAction(ID_CONN_CTLESC, true);
	}
}

void ClientConnection::EnableAction(int id, bool enable)
{
	if (enable) {
		EnableMenuItem(GetSystemMenu(m_hwnd1, FALSE), id,
					   MF_BYCOMMAND | MF_ENABLED);
		SendMessage(m_hToolbar, TB_SETSTATE, (WPARAM)id,
					(LPARAM)MAKELONG(TBSTATE_ENABLED, 0));
	} else {
		EnableMenuItem(GetSystemMenu(m_hwnd1, FALSE), id,
					   MF_BYCOMMAND | MF_GRAYED);
		SendMessage(m_hToolbar, TB_SETSTATE, (WPARAM)id,
					(LPARAM)MAKELONG(TBSTATE_INDETERMINATE, 0));
	}
}

void ClientConnection::SwitchOffKey()
{
	CheckMenuItem(GetSystemMenu(m_hwnd1, FALSE),
					ID_CONN_ALTDOWN, MF_BYCOMMAND|MF_UNCHECKED);
	CheckMenuItem(GetSystemMenu(m_hwnd1, FALSE),
					ID_CONN_CTLDOWN, MF_BYCOMMAND|MF_UNCHECKED);
	SendMessage(m_hToolbar, TB_SETSTATE, (WPARAM)ID_CONN_CTLDOWN,
					(LPARAM)MAKELONG(TBSTATE_ENABLED, 0));
	SendMessage(m_hToolbar, TB_SETSTATE, (WPARAM)ID_CONN_ALTDOWN,
					(LPARAM)MAKELONG(TBSTATE_ENABLED, 0));
	SendKeyEvent(XK_Alt_L,     false);
	SendKeyEvent(XK_Control_L, false);
	SendKeyEvent(XK_Shift_L,   false);
	SendKeyEvent(XK_Alt_R,     false);
	SendKeyEvent(XK_Control_R, false);
	SendKeyEvent(XK_Shift_R,   false);
}

void ClientConnection::GetConnectDetails()
{
	
	if (m_opts.m_configSpecified) {
		LoadConnection(m_opts.m_configFilename, false);
	} else {
		SessionDialog sessdlg(&m_opts, this);
		if (!sessdlg.DoDialog()) {
			throw QuietException("User Cancelled");
		}		
	}
	// This is a bit of a hack: 
	// The config file may set various things in the app-level defaults which 
	// we don't want to be used except for the first connection. So we clear them
	// in the app defaults here.
	m_pApp->m_options.m_host[0] = '\0';
	m_pApp->m_options.m_port = -1;
	m_pApp->m_options.m_connectionSpecified = false;
	m_pApp->m_options.m_configSpecified = false;
#ifndef _WIN32_WCE
	// We want to know when the clipboard changes, so
	// insert ourselves in the viewer chain. But doing
	// this will cause us to be notified immediately of
	// the current state.
	// We don't want to send that.
	m_initialClipboardSeen = false;
	m_hwndNextViewer = SetClipboardViewer(m_hwnd); 	
#endif
}

void ClientConnection::Connect()
{
	struct sockaddr_in thataddr;
	int res;

	if (m_connDlg != NULL)
		m_connDlg->SetStatus("Connection initiated");

	m_sock = socket(PF_INET, SOCK_STREAM, 0);
	if (m_sock == INVALID_SOCKET) throw WarningException(_T("Error creating socket"));
	int one = 1;
	
	// The host may be specified as a dotted address "a.b.c.d"
	// Try that first
	thataddr.sin_addr.s_addr = inet_addr(m_host);
	
	// If it wasn't one of those, do gethostbyname
	if (thataddr.sin_addr.s_addr == INADDR_NONE) {
		LPHOSTENT lphost;
		lphost = gethostbyname(m_host);
		
		if (lphost == NULL) { 
			char msg[512];
			sprintf(msg, "Failed to get server address (%s).\n"
					"Did you type the host name correctly?", m_host);
			throw WarningException(msg);
		};
		thataddr.sin_addr.s_addr = ((LPIN_ADDR) lphost->h_addr)->s_addr;
	};
	
	thataddr.sin_family = AF_INET;
	thataddr.sin_port = htons(m_port);
	res = connect(m_sock, (LPSOCKADDR) &thataddr, sizeof(thataddr));
	if (res == SOCKET_ERROR) {
		char msg[512];
		sprintf(msg, "Failed to connect to server (%.255s)", m_opts.m_display);
		throw WarningException(msg);
	}
	vnclog.Print(0, _T("Connected to %s port %d\n"), m_host, m_port);

	if (m_connDlg != NULL)
		m_connDlg->SetStatus("Connection established");
}

void ClientConnection::SetSocketOptions() {
	// Disable Nagle's algorithm
	BOOL nodelayval = TRUE;
	if (setsockopt(m_sock, IPPROTO_TCP, TCP_NODELAY, (const char *) &nodelayval, sizeof(BOOL)))
		throw WarningException("Error disabling Nagle's algorithm");
}


void ClientConnection::NegotiateProtocolVersion()
{
	rfbProtocolVersionMsg pv;

	ReadExact(pv, sz_rfbProtocolVersionMsg);

    pv[sz_rfbProtocolVersionMsg] = 0;

	if (m_connDlg != NULL)
		m_connDlg->SetStatus("Server protocol version received");

	// XXX This is a hack.  Under CE we just return to the server the
	// version number it gives us without parsing it.  
	// Too much hassle replacing sscanf for now. Fix this!
#ifdef UNDER_CE
	m_minorVersion = 8;
#else
	int majorVersion, minorVersion;
	if (sscanf(pv, rfbProtocolVersionFormat, &majorVersion, &minorVersion) != 2) {
		throw WarningException(_T("Invalid protocol"));
	}
	vnclog.Print(0, _T("RFB server supports protocol version 3.%d\n"),
				 minorVersion);

	if (majorVersion == 3 && minorVersion >= 8) {
		m_minorVersion = 8;
	} else if (majorVersion == 3 && minorVersion == 7) {
		m_minorVersion = 7;
	} else {
		m_minorVersion = 3;
	}

	m_tightVncProtocol = false;

    sprintf(pv, rfbProtocolVersionFormat, 3, m_minorVersion);
#endif

⌨️ 快捷键说明

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