📄 vncmenu.cpp
字号:
// Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.// 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.// vncMenu// Implementation of a system tray icon & menu for WinVNC#include "stdhdrs.h"#include "WinVNC.h"#include "vncService.h"#include "vncConnDialog.h"#include <lmcons.h>#include <wininet.h>#include <shlobj.h>// Header#include "vncMenu.h"// Constantsconst UINT MENU_PROPERTIES_SHOW = RegisterWindowMessage("WinVNC.Properties.User.Show");const UINT MENU_DEFAULT_PROPERTIES_SHOW = RegisterWindowMessage("WinVNC.Properties.Default.Show");const UINT MENU_ABOUTBOX_SHOW = RegisterWindowMessage("WinVNC.AboutBox.Show");const UINT MENU_SERVICEHELPER_MSG = RegisterWindowMessage("WinVNC.ServiceHelper.Message");const UINT MENU_ADD_CLIENT_MSG = RegisterWindowMessage("WinVNC.AddClient.Message");const UINT MENU_REMOVE_CLIENTS_MSG = RegisterWindowMessage("WinVNC.RemoveClients.Message");const char *MENU_CLASS_NAME = "WinVNC Tray Icon";bool g_restore_ActiveDesktop = false;static voidKillActiveDesktop(){ vnclog.Print(LL_INTERR, VNCLOG("KillActiveDesktop\n")); // Contact Active Desktop if possible HRESULT result; IActiveDesktop* active_desktop = 0; result = CoCreateInstance(CLSID_ActiveDesktop, NULL, CLSCTX_INPROC_SERVER, IID_IActiveDesktop, (void**)&active_desktop); if (result != S_OK) { vnclog.Print(LL_INTERR, VNCLOG("unable to access Active Desktop object:%x\n"), result); return; } // Get Active Desktop options COMPONENTSOPT options; options.dwSize = sizeof(options); result = active_desktop->GetDesktopItemOptions(&options, 0); if (result != S_OK) { vnclog.Print(LL_INTERR, VNCLOG("unable to fetch Active Desktop options:%x\n"), result); active_desktop->Release(); return; } // Disable if currently active g_restore_ActiveDesktop = options.fActiveDesktop; if (options.fActiveDesktop) { vnclog.Print(LL_INTINFO, VNCLOG("attempting to disable Active Desktop\n")); options.fActiveDesktop = FALSE; result = active_desktop->SetDesktopItemOptions(&options, 0); if (result != S_OK) { vnclog.Print(LL_INTERR, VNCLOG("unable to disable Active Desktop:%x\n"), result); active_desktop->Release(); return; } } else { vnclog.Print(LL_INTINFO, VNCLOG("Active Desktop not enabled - ignoring\n")); } active_desktop->ApplyChanges(AD_APPLY_REFRESH); active_desktop->Release();}static voidKillWallpaper(){ KillActiveDesktop(); // Tell all applications that there is no wallpaper // Note that this doesn't change the wallpaper registry setting! SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, "", SPIF_SENDCHANGE);}static voidRestoreActiveDesktop(){ // Contact Active Desktop if possible HRESULT result; IActiveDesktop* active_desktop = 0; result = CoCreateInstance(CLSID_ActiveDesktop, NULL, CLSCTX_INPROC_SERVER, IID_IActiveDesktop, (void**)&active_desktop); if (result != S_OK) { vnclog.Print(LL_INTERR, VNCLOG("unable to access Active Desktop object:%x\n"), result); return; } // Get Active Desktop options COMPONENTSOPT options; options.dwSize = sizeof(options); result = active_desktop->GetDesktopItemOptions(&options, 0); if (result != S_OK) { vnclog.Print(LL_INTERR, VNCLOG("unable to fetch Active Desktop options:%x\n"), result); active_desktop->Release(); return; } // Re-enable if previously disabled if (g_restore_ActiveDesktop) { g_restore_ActiveDesktop = false; vnclog.Print(LL_INTINFO, VNCLOG("attempting to re-enable Active Desktop\n")); options.fActiveDesktop = TRUE; result = active_desktop->SetDesktopItemOptions(&options, 0); if (result != S_OK) { vnclog.Print(LL_INTERR, VNCLOG("unable to re-enable Active Desktop:%x\n"), result); active_desktop->Release(); return; } } active_desktop->ApplyChanges(AD_APPLY_REFRESH); active_desktop->Release();}static voidRestoreWallpaper(){ RestoreActiveDesktop(); SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, NULL, SPIF_SENDCHANGE);}// ImplementationvncMenu::vncMenu(vncServer *server){ CoInitialize(0); // 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) { vnclog.Print(LL_INTERR, VNCLOG("unable to CreateWindow:%d\n"), GetLastError()); PostQuitMessage(0); return; } // Timer to trigger icon updating 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)) { vnclog.Print(LL_INTERR, VNCLOG("unable to initialise Properties dialog\n")); 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);}voidvncMenu::AddTrayIcon(){ // If the user name is non-null then we have a user! if (strcmp(m_username, "") != 0) SendTrayMsg(NIM_ADD, FALSE);}voidvncMenu::DelTrayIcon(){ SendTrayMsg(NIM_DELETE, FALSE);}voidvncMenu::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 = '\0'; 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] = '\0'; if (ph->h_addr_list[i+1] != 0) strncat(buffer, ", ", (buflen-1)-strlen(buffer)); }}voidvncMenu::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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -