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

📄 daemon.cpp

📁 realvnc是一个非常流行的远程控制程序
💻 CPP
字号:
//  Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.////  This file is part of the VNC system.////  The VNC system is free software; you can redistribute it and/or modify//  it under the terms of the GNU General Public License as published by//  the Free Software Foundation; either version 2 of the License, or//  (at your option) any later version.////  This program is distributed in the hope that it will be useful,//  but WITHOUT ANY WARRANTY; without even the implied warranty of//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the//  GNU General Public License for more details.////  You should have received a copy of the GNU General Public License//  along with this program; if not, write to the Free Software//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,//  USA.//// If the source code for the VNC system is not available from the place // whence you received this file, check http://www.uk.research.att.com/vnc or contact// the authors on vnc@uk.research.att.com for information on obtaining it.// Daemon.cpp: implementation of the Daemon class.#include "stdhdrs.h"#include "vncviewer.h"#include "Daemon.h"#include "Exception.h"#include "ClientConnection.h"#include "AboutBox.h"//////////////////////////////////////////////////////////////////////// Construction/Destruction//////////////////////////////////////////////////////////////////////#define DAEMON_CLASS_NAME "VNCviewer Daemon"Daemon::Daemon(int port){	// Create a dummy window	WNDCLASSEX wndclass;	wndclass.cbSize			= sizeof(wndclass);	wndclass.style			= CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;	wndclass.lpfnWndProc	= Daemon::WndProc;	wndclass.cbClsExtra		= 0;	wndclass.cbWndExtra		= 0;	wndclass.hInstance		= pApp->m_instance;	wndclass.hIcon			= LoadIcon(NULL, IDI_APPLICATION);	wndclass.hCursor		= LoadCursor(NULL, IDC_ARROW);	wndclass.hbrBackground	= (HBRUSH) GetStockObject(WHITE_BRUSH);	wndclass.lpszMenuName	= (const char *) NULL;	wndclass.lpszClassName	= DAEMON_CLASS_NAME;	wndclass.hIconSm		= LoadIcon(NULL, IDI_APPLICATION);	RegisterClassEx(&wndclass);	m_hwnd = CreateWindow(DAEMON_CLASS_NAME,				DAEMON_CLASS_NAME,				WS_OVERLAPPEDWINDOW,				CW_USEDEFAULT,				CW_USEDEFAULT,				200, 200,				NULL,				NULL,				pApp->m_instance,				NULL);		// record which client created this window	SetWindowLong(m_hwnd, GWL_USERDATA, (LONG) this);	// Load a popup menu	m_hmenu = LoadMenu(pApp->m_instance, MAKEINTRESOURCE(IDR_TRAYMENU));	// Create a listening socket    struct sockaddr_in addr;    addr.sin_family = AF_INET;    addr.sin_port = htons(port);    addr.sin_addr.s_addr = INADDR_ANY;    m_sock = socket(AF_INET, SOCK_STREAM, 0);	if (!m_sock) throw WarningException("Error creating Daemon socket");    	try {		int one = 1, res = 0;		//res = setsockopt(m_sock, SOL_SOCKET, SO_REUSEADDR, (const char *) &one, sizeof(one));		//if (res == SOCKET_ERROR) 		//  throw WarningException("Error setting Daemon socket options");				res = bind(m_sock, (struct sockaddr *)&addr, sizeof(addr));		if (res == SOCKET_ERROR)			throw WarningException("Error binding Daemon socket");				res = listen(m_sock, 5);		if (res == SOCKET_ERROR)			throw WarningException("Error when Daemon listens");	} catch (...) {		closesocket(m_sock);		m_sock = 0;		throw;	}		// Send a message to specified window on an incoming connection	WSAAsyncSelect (m_sock,  m_hwnd,  WM_SOCKEVENT, FD_ACCEPT);	// Create the tray icon	AddTrayIcon();		// A timer checks that the tray icon is intact	m_timer = SetTimer( m_hwnd, IDT_TRAYTIMER,  15000, NULL);}void Daemon::AddTrayIcon() {	log.Print(4, _T("Adding tray icon\n"));	SendTrayMsg(NIM_ADD);}void Daemon::CheckTrayIcon() {	log.Print(8, _T("Checking tray icon\n"));	if (!SendTrayMsg(NIM_MODIFY)) {		log.Print(4, _T("Tray icon not there - reinstalling\n"));		AddTrayIcon();	};}void Daemon::RemoveTrayIcon() {	log.Print(4, _T("Deleting tray icon\n"));	SendTrayMsg(NIM_DELETE);}bool Daemon::SendTrayMsg(DWORD msg){	m_nid.hWnd = m_hwnd;	m_nid.cbSize = sizeof(m_nid);	m_nid.uID = IDR_TRAY;	// never changes after construction        // LoadIcon seems to mess up 16x16 images. Maybe we should use        // LoadImage instead?        m_nid.hIcon = LoadIcon(pApp->m_instance, MAKEINTRESOURCE(IDR_TRAY));  	//m_nid.hIcon = (HICON)LoadImage(pApp->m_instance,        //                               MAKEINTRESOURCE(IDR_TRAY),        //                               IMAGE_ICON, 0, 0,        //                               LR_DEFAULTCOLOR|LR_SHARED);	m_nid.uFlags = NIF_ICON | NIF_MESSAGE;	m_nid.uCallbackMessage = WM_TRAYNOTIFY;	m_nid.szTip[0] = '\0';	// Use resource string as tip if there is one	if (LoadString(pApp->m_instance, IDR_TRAY, m_nid.szTip, sizeof(m_nid.szTip))) {		m_nid.uFlags |= NIF_TIP;	}	return (bool) (Shell_NotifyIcon(msg, &m_nid) != 0);}// Process window messagesLRESULT CALLBACK Daemon::WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) {	// This is a static method, so we don't know which instantiation we're 	// dealing with. We have stored a pseudo-this in the window user data, 	// though.	Daemon *_this = (Daemon *) GetWindowLong(hwnd, GWL_USERDATA);	switch (iMsg) {	case WM_CREATE:		{			return 0;		}	case WM_SOCKEVENT:		{			assert(HIWORD(lParam) == 0);			// A new socket created by accept might send messages to			// this procedure. We can ignore them.			if(wParam != _this->m_sock) {				return 0;			}			switch(lParam) {			case FD_ACCEPT:				{					SOCKET hNewSock;					hNewSock = accept(_this->m_sock, NULL, NULL);					WSAAsyncSelect(hNewSock, hwnd, 0, 0);					unsigned long nbarg = 0;					ioctlsocket(hNewSock, FIONBIO, &nbarg);					pApp->NewConnection(hNewSock);										break;				}			case FD_READ:				{					unsigned long numbytes;					ioctlsocket(_this->m_sock, FIONREAD, &numbytes);					recv(_this->m_sock, _this->netbuf, numbytes, 0);					break;				}			case FD_CLOSE:				log.Print(5, _T("Daemon connection closed\n"));				DestroyWindow(hwnd);				break;			}						return 0;		}	case WM_COMMAND:		switch (LOWORD(wParam)) {		case ID_NEWCONN:			pApp->NewConnection();			break;		case IDC_OPTIONBUTTON:			pApp->m_options.DoDialog();			break;		case ID_CLOSEDAEMON:			PostQuitMessage(0);			break;		case IDD_APP_ABOUT:			ShowAboutBox();			break;		}		return 0;	case WM_TRAYNOTIFY:		{			HMENU hSubMenu = GetSubMenu(_this->m_hmenu, 0);			if (lParam==WM_LBUTTONDBLCLK) {				// double click: execute first menu item				::SendMessage(_this->m_nid.hWnd, WM_COMMAND, 					GetMenuItemID(hSubMenu, 0), 0);			} else if (lParam==WM_RBUTTONUP) {				if (hSubMenu == NULL) { 					log.Print(2, _T("No systray submenu\n"));					return 0;				}				// Make first menu item the default (bold font)				::SetMenuDefaultItem(hSubMenu, 0, TRUE);								// Display the menu at the current mouse location. There's a "bug"				// (Microsoft calls it a feature) in Windows 95 that requires calling				// SetForegroundWindow. To find out more, search for Q135788 in MSDN.				//				POINT mouse;				GetCursorPos(&mouse);				::SetForegroundWindow(_this->m_nid.hWnd);				::TrackPopupMenu(hSubMenu, 0, mouse.x, mouse.y, 0,					_this->m_nid.hWnd, NULL);							} 			return 0;		}	case WM_TIMER:		_this->CheckTrayIcon();		return 0;	case WM_DESTROY:		PostQuitMessage(0);		return 0;	}		return DefWindowProc(hwnd, iMsg, wParam, lParam);}Daemon::~Daemon(){	KillTimer(m_hwnd, m_timer);	RemoveTrayIcon();	DestroyMenu(m_hmenu);	shutdown(m_sock, SD_BOTH);	closesocket(m_sock);}

⌨️ 快捷键说明

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