📄 vncmenu.cpp
字号:
if (Shell_NotifyIcon(msg, &m_nid)) { // Set the enabled/disabled state of the menu items vnclog.Print(LL_INTINFO, VNCLOG("tray icon added ok\n")); EnableMenuItem(m_hmenu, ID_PROPERTIES, m_properties.AllowProperties() ? MF_ENABLED : MF_GRAYED); EnableMenuItem(m_hmenu, ID_CLOSE, m_properties.AllowShutdown() ? MF_ENABLED : MF_GRAYED); EnableMenuItem(m_hmenu, ID_KILLCLIENTS, m_properties.AllowEditClients() ? MF_ENABLED : MF_GRAYED); EnableMenuItem(m_hmenu, ID_OUTGOING_CONN, m_properties.AllowEditClients() ? 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 vnclog.Print(LL_INTINFO, VNCLOG("opening dialog box\n")); m_properties.Show(TRUE, TRUE); vnclog.Print(LL_INTERR, VNCLOG("unable to add tray icon\n"), GetLastError()); PostQuitMessage(0); } } }}// Process window messagesLRESULT 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) { // Every five seconds, a timer message causes the icon to update case WM_TIMER: // *** HACK for running servicified if (vncService::RunningAsService()) { // Attempt to add the icon if it's not already there _this->AddTrayIcon(); // Trigger a check of the current user PostMessage(hwnd, WM_USERCHANGED, 0, 0); } // Update the icon _this->FlashTrayIcon(_this->m_server->AuthClientCount() != 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); if (_this->m_server->AuthClientCount() != 0) { if (_this->m_server->RemoveWallpaperEnabled()) KillWallpaper(); } else { RestoreWallpaper(); } 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_DEFAULT_PROPERTIES: // Show the default properties dialog, unless it is already displayed vnclog.Print(LL_INTINFO, VNCLOG("show default properties requested\n")); _this->m_properties.Show(TRUE, FALSE); _this->FlashTrayIcon(_this->m_server->AuthClientCount() != 0); break; case ID_PROPERTIES: // Show the properties dialog, unless it is already displayed vnclog.Print(LL_INTINFO, VNCLOG("show user properties requested\n")); _this->m_properties.Show(TRUE, TRUE); _this->FlashTrayIcon(_this->m_server->AuthClientCount() != 0); break; case ID_OUTGOING_CONN: // Connect out to a listening VNC viewer { vncConnDialog *newconn = new vncConnDialog(_this->m_server); if (newconn) newconn->DoDialog(); } break; case ID_KILLCLIENTS: // Disconnect all currently connected clients _this->m_server->KillAuthClients(); 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) { vnclog.Print(LL_INTERR, VNCLOG("no submenu available\n")); 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... vnclog.Print(LL_INTERR, VNCLOG("quitting from WM_DESTROY\n")); PostQuitMessage(0); return 0; case WM_QUERYENDSESSION: vnclog.Print(LL_INTERR, VNCLOG("WM_QUERYENDSESSION\n")); break; case WM_ENDSESSION: vnclog.Print(LL_INTERR, VNCLOG("WM_ENDSESSION\n")); break;/* case WM_ENDSESSION: // Are we running as a system service, or shutting the system down? if (wParam && (lParam == 0)) { // Shutdown! // 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->KillAuthClients(); _this->m_server->KillUnauthClients(); _this->m_server->WaitUntilAuthEmpty(); _this->m_server->WaitUntilUnauthEmpty(); } // Tell the OS that we've handled it anyway return 0; */ case WM_USERCHANGED: // The current user may have changed. { char newuser[UNLEN+1]; if (vncService::CurrentUser((char *) &newuser, sizeof(newuser))) { vnclog.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) { vnclog.Print(LL_INTINFO, VNCLOG("user name has changed\n")); // 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(TRUE); } } } 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_DEFAULT_PROPERTIES_SHOW) { // External request to show our Properties dialog PostMessage(hwnd, WM_COMMAND, MAKELONG(ID_DEFAULT_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; } if (iMsg == MENU_SERVICEHELPER_MSG) { // External ServiceHelper message. // This message holds a process id which we can use to // impersonate a specific user. In doing so, we can load their // preferences correctly vncService::ProcessUserHelperMessage(wParam, lParam); // - Trigger a check of the current user PostMessage(hwnd, WM_USERCHANGED, 0, 0); return 0; } if (iMsg == MENU_ADD_CLIENT_MSG) { // Add Client message. This message includes an IP address // of a listening client, to which we should connect. // If there is no IP address then show the connection dialog if (!lParam) { vncConnDialog *newconn = new vncConnDialog(_this->m_server); if (newconn) newconn->DoDialog(); return 0; } // Get the IP address stringified struct in_addr address; address.S_un.S_addr = lParam; char *name = inet_ntoa(address); if (name == 0) return 0; char *nameDup = strdup(name); if (nameDup == 0) return 0; // Attempt to create a new socket VSocket *tmpsock; tmpsock = new VSocket; if (tmpsock) { // Connect out to the specified host on the VNCviewer listen port tmpsock->Create(); if (tmpsock->Connect(nameDup, INCOMING_PORT_OFFSET)) { // Add the new client to this server _this->m_server->AddClient(tmpsock, TRUE, TRUE); } else { delete tmpsock; } } // Free the duplicate name free(nameDup); return 0; } if (iMsg == MENU_REMOVE_CLIENTS_MSG) { // Kill all connected clients _this->m_server->KillAuthClients(); } } // Message not recognised return DefWindowProc(hwnd, iMsg, wParam, lParam);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -