Code/Resource
Windows Develop
Linux-Unix program
Internet-Socket-Network
Web Server
Browser Client
Ftp Server
Ftp Client
Browser Plugins
Proxy Server
Email Server
Email Client
WEB Mail
Firewall-Security
Telnet Server
Telnet Client
ICQ-IM-Chat
Search Engine
Sniffer Package capture
Remote Control
xml-soap-webservice
P2P
WEB(ASP,PHP,...)
TCP/IP Stack
SNMP
Grid Computing
SilverLight
DNS
Cluster Service
Network Security
Communication-Mobile
Game Program
Editor
Multimedia program
Graph program
Compiler program
Compress-Decompress algrithms
Crypt_Decrypt algrithms
Mathimatics-Numerical algorithms
MultiLanguage
Disk/Storage
Java Develop
assembly language
Applications
Other systems
Database system
Embeded-SCM Develop
FlashMX/Flex
source in ebook
Delphi VCL
OS Develop
MiddleWare
MPI
MacOS develop
LabView
ELanguage
Software/Tools
E-Books
Artical/Document
vncMenu.cpp
Package: vnc3326s.zip [view]
Upload User: sbftbdw
Upload Date: 2007-01-03
Package Size: 379k
Code Size: 12k
Category:
Remote Control
Development Platform:
Visual C++
- // Copyright (C) 1997, 1998 Olivetti & Oracle Research Laboratory
- //
- // 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.orl.co.uk/vnc or contact
- // the authors on vnc@orl.co.uk for information on obtaining it.
- // vncMenu
- // Implementation of a system tray icon & menu for WinVNC
- #include "stdhdrs.h"
- #include "WinVNC.h"
- #include "vncService.h"
- #include <lmcons.h>
- // Header
- #include "vncMenu.h"
- // Constants
- const UINT MENU_PROPERTIES_SHOW = RegisterWindowMessage("WinVNC.Properties.Show");
- const UINT MENU_ABOUTBOX_SHOW = RegisterWindowMessage("WinVNC.AboutBox.Show");
- const char *MENU_CLASS_NAME = "WinVNC Tray Icon";
- // Implementation
- vncMenu::vncMenu(vncServer *server)
- {
- // Save the server pointer
- m_server = server;
- // Set the initial user name to something sensible...
- vncService::CurrentUser((char *)&m_username, sizeof(m_username));
- // Create a dummy window to handle tray icon messages
- WNDCLASSEX wndclass;
- wndclass.cbSize = sizeof(wndclass);
- wndclass.style = 0;
- wndclass.lpfnWndProc = vncMenu::WndProc;
- wndclass.cbClsExtra = 0;
- wndclass.cbWndExtra = 0;
- wndclass.hInstance = hAppInstance;
- 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 = MENU_CLASS_NAME;
- wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
- RegisterClassEx(&wndclass);
- m_hwnd = CreateWindow(MENU_CLASS_NAME,
- MENU_CLASS_NAME,
- WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- 200, 200,
- NULL,
- NULL,
- hAppInstance,
- NULL);
- if (m_hwnd == NULL)
- {
- PostQuitMessage(0);
- return;
- }
- // *** HACK for running servicified on WinNT
- if (vncService::IsWinNT() && vncService::RunningAsService())
- SetTimer(m_hwnd, 1, 5000, NULL);
- // record which client created this window
- SetWindowLong(m_hwnd, GWL_USERDATA, (LONG) this);
- // Ask the server object to notify us of stuff
- server->AddNotify(m_hwnd);
- // Initialise the properties dialog object
- if (!m_properties.Init(m_server))
- {
- PostQuitMessage(0);
- return;
- }
- // Load the icons for the tray
- m_winvnc_icon = LoadIcon(hAppInstance, MAKEINTRESOURCE(IDI_WINVNC));
- m_flash_icon = LoadIcon(hAppInstance, MAKEINTRESOURCE(IDI_FLASH));
- // Load the popup menu
- m_hmenu = LoadMenu(hAppInstance, MAKEINTRESOURCE(IDR_TRAYMENU));
- // Install the tray icon!
- AddTrayIcon();
- }
- vncMenu::~vncMenu()
- {
- // Remove the tray icon
- DelTrayIcon();
- // Destroy the loaded menu
- if (m_hmenu != NULL)
- DestroyMenu(m_hmenu);
- // Tell the server to stop notifying us!
- if (m_server != NULL)
- m_server->RemNotify(m_hwnd);
- }
- void
- vncMenu::AddTrayIcon()
- {
- // If the user name is non-null then we have a user!
- if (strcmp(m_username, "") != 0)
- SendTrayMsg(NIM_ADD, FALSE);
- }
- void
- vncMenu::DelTrayIcon()
- {
- SendTrayMsg(NIM_DELETE, FALSE);
- }
- void
- vncMenu::FlashTrayIcon(BOOL flash)
- {
- SendTrayMsg(NIM_MODIFY, flash);
- }
- // Get the local ip addresses as a human-readable string.
- // If more than one, then with n between them.
- // If not available, then gets a message to that effect.
- void GetIPAddrString(char *buffer, int buflen) {
- char namebuf[256];
- if (gethostname(namebuf, 256) != 0) {
- strncpy(buffer, "Host name unavailable", buflen);
- return;
- };
- HOSTENT *ph = gethostbyname(namebuf);
- if (!ph) {
- strncpy(buffer, "IP address unavailable", buflen);
- return;
- };
- *buffer = '';
- char digtxt[5];
- for (int i = 0; ph->h_addr_list[i]; i++) {
- for (int j = 0; j < ph->h_length; j++) {
- sprintf(digtxt, "%d.", (unsigned char) ph->h_addr_list[i][j]);
- strncat(buffer, digtxt, (buflen-1)-strlen(buffer));
- }
- buffer[strlen(buffer)-1] = '';
- if (ph->h_addr_list[i+1] != 0)
- strncat(buffer, ", ", (buflen-1)-strlen(buffer));
- }
- }
- void
- vncMenu::SendTrayMsg(DWORD msg, BOOL flash)
- {
- // Create the tray icon message
- m_nid.hWnd = m_hwnd;
- m_nid.cbSize = sizeof(m_nid);
- m_nid.uID = IDI_WINVNC; // never changes after construction
- m_nid.hIcon = flash ? m_flash_icon : m_winvnc_icon;
- m_nid.uFlags = NIF_ICON | NIF_MESSAGE;
- m_nid.uCallbackMessage = WM_TRAYNOTIFY;
- // Use resource string as tip if there is one
- if (LoadString(hAppInstance, IDI_WINVNC, m_nid.szTip, sizeof(m_nid.szTip)))
- {
- m_nid.uFlags |= NIF_TIP;
- }
- // Try to add the server's IP addresses to the tip string, if possible
- if (m_nid.uFlags & NIF_TIP)
- {
- strncat(m_nid.szTip, " - ", (sizeof(m_nid.szTip)-1)-strlen(m_nid.szTip));
- if (m_server->SockConnected())
- {
- unsigned long tiplen = strlen(m_nid.szTip);
- char *tipptr = ((char *)&m_nid.szTip) + tiplen;
- GetIPAddrString(tipptr, sizeof(m_nid.szTip) - tiplen);
- }
- else
- {
- strncat(m_nid.szTip, "Not listening", (sizeof(m_nid.szTip)-1)-strlen(m_nid.szTip));
- }
- }
- // Send the message
- if (Shell_NotifyIcon(msg, &m_nid))
- {
- // Set the enabled/disabled state of the menu items
- log.Print(LL_INTINFO, VNCLOG("tray icon added okn"));
- EnableMenuItem(m_hmenu, ID_PROPERTIES,
- m_properties.AllowProperties() ? MF_ENABLED : MF_GRAYED);
- EnableMenuItem(m_hmenu, ID_CLOSE,
- m_properties.AllowShutdown() ? MF_ENABLED : MF_GRAYED);
- } else {
- if (!vncService::RunningAsService())
- {
- if (msg == NIM_ADD)
- {
- // The tray icon couldn't be created, so use the Properties dialog
- // as the main program window
- log.Print(LL_INTINFO, VNCLOG("opening dialog boxn"));
- m_properties.Show(TRUE);
- PostQuitMessage(0);
- }
- }
- }
- }
- // Process window messages
- LRESULT CALLBACK vncMenu::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 use Allen Hadden's (ahadden@taratec.com) suggestion
- // from a newsgroup to get the pseudo-this.
- vncMenu *_this = (vncMenu *) GetWindowLong(hwnd, GWL_USERDATA);
- switch (iMsg)
- {
- // *** HACK
- // This timer message is used to cause the current user to be checked
- // every five seconds...
- case WM_TIMER:
- _this->AddTrayIcon();
- PostMessage(hwnd, WM_USERCHANGED, 0, 0);
- break;
- // DEAL WITH NOTIFICATIONS FROM THE SERVER:
- case WM_SRV_CLIENT_AUTHENTICATED:
- case WM_SRV_CLIENT_DISCONNECT:
- // Adjust the icon accordingly
- _this->FlashTrayIcon(_this->m_server->AuthClientCount() != 0);
- return 0;
- // STANDARD MESSAGE HANDLING
- case WM_CREATE:
- return 0;
- case WM_COMMAND:
- // User has clicked an item on the tray menu
- switch (LOWORD(wParam))
- {
- case ID_PROPERTIES:
- // Show the properties dialog, unless it is already displayed
- log.Print(LL_INTINFO, VNCLOG("show properties requestedn"));
- _this->m_properties.Show(TRUE);
- _this->FlashTrayIcon(_this->m_server->AuthClientCount() != 0);
- break;
- case ID_KILLCLIENTS:
- // Disconnect all currently connected clients
- _this->m_server->KillAll();
- break;
- case ID_ABOUT:
- // Show the About box
- _this->m_about.Show(TRUE);
- break;
- case ID_CLOSE:
- // User selected Close from the tray menu
- PostMessage(hwnd, WM_CLOSE, 0, 0);
- break;
- }
- return 0;
- case WM_TRAYNOTIFY:
- // User has clicked on the tray icon or the menu
- {
- // Get the submenu to use as a pop-up menu
- HMENU submenu = GetSubMenu(_this->m_hmenu, 0);
- // What event are we responding to, RMB click?
- if (lParam==WM_RBUTTONUP)
- {
- if (submenu == NULL)
- {
- log.Print(LL_INTERR, VNCLOG("no submenu availablen"));
- return 0;
- }
- // Make the first menu item the default (bold font)
- SetMenuDefaultItem(submenu, 0, TRUE);
- // Get the current cursor position, to display the menu at
- POINT mouse;
- GetCursorPos(&mouse);
- // 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.
- //
- SetForegroundWindow(_this->m_nid.hWnd);
- // Display the menu at the desired position
- TrackPopupMenu(submenu,
- 0, mouse.x, mouse.y, 0,
- _this->m_nid.hWnd, NULL);
- return 0;
- }
- // Or was there a LMB double click?
- if (lParam==WM_LBUTTONDBLCLK)
- {
- // double click: execute first menu item
- SendMessage(_this->m_nid.hWnd,
- WM_COMMAND,
- GetMenuItemID(submenu, 0),
- 0);
- }
- return 0;
- }
- case WM_CLOSE:
- // Only accept WM_CLOSE if the logged on user has AllowShutdown set
- if (!_this->m_properties.AllowShutdown())
- return 0;
- break;
- case WM_DESTROY:
- // The user wants WinVNC to quit cleanly...
- PostQuitMessage(0);
- return 0;
- case WM_QUERYENDSESSION:
- // Are we running as a system service?
- // Or is the system shutting down (in which case we should check anyway!)
- if ((!vncService::RunningAsService()) || (lParam == 0))
- {
- // No, so we are about to be killed
- // If there are remote connections then we should verify
- // that the user is happy about killing them.
- if (_this->m_server->AuthClientCount() > 0)
- {
- if (MessageBox(NULL,
- "There are remote clients connected to this computer.n"
- "Ending the session will disconnect them and close down WinVNC.n"
- "Are you sure you want to do this?",
- "WinVNC Warning",
- MB_OKCANCEL | MB_ICONWARNING) == IDCANCEL)
- {
- // User doesn't want to log-out, so stop the logout.
- return FALSE;
- }
- }
- // The user wishes to log out (or no users are connected)
- // Try to clean ourselves up nicely, if possible...
- // Firstly, disable incoming CORBA or socket connections
- _this->m_server->SockConnect(FALSE);
- _this->m_server->CORBAConnect(FALSE);
- // Now kill all the server's clients
- _this->m_server->KillAll();
- _this->m_server->WaitUntilAuthEmpty();
- // Finally, post a quit message, just in case
- PostQuitMessage(0);
- return TRUE;
- }
- // Tell the OS that we've handled it anyway
- return TRUE;
- case WM_USERCHANGED:
- // The current user may have changed.
- {
- char newuser[UNLEN+1];
- if (vncService::CurrentUser((char *) &newuser, sizeof(newuser)))
- {
- log.Print(LL_INTINFO,
- VNCLOG("usernames : old="%s", new="%s"n"),
- _this->m_username, newuser);
- // Check whether the user name has changed!
- if (strcmp(newuser, _this->m_username) != 0)
- {
- log.Print(LL_INTINFO,
- VNCLOG("user name has changedn"));
- // User has changed!
- strcpy(_this->m_username, newuser);
- // Redraw the tray icon and set it's state
- _this->DelTrayIcon();
- _this->AddTrayIcon();
- _this->FlashTrayIcon(_this->m_server->AuthClientCount() != 0);
- // We should load in the prefs for the new user
- _this->m_properties.Load();
- }
- }
- }
- return 0;
- default:
- // Deal with any of our custom message types
- if (iMsg == MENU_PROPERTIES_SHOW)
- {
- // External request to show our Properties dialog
- PostMessage(hwnd, WM_COMMAND, MAKELONG(ID_PROPERTIES, 0), 0);
- return 0;
- }
- if (iMsg == MENU_ABOUTBOX_SHOW)
- {
- // External request to show our About dialog
- PostMessage(hwnd, WM_COMMAND, MAKELONG(ID_ABOUT, 0), 0);
- return 0;
- }
- }
- // Message not recognised
- return DefWindowProc(hwnd, iMsg, wParam, lParam);
- }