diff options
author | Constantin Kaplinsky <const@tightvnc.com> | 2004-10-08 09:43:57 +0000 |
---|---|---|
committer | Constantin Kaplinsky <const@tightvnc.com> | 2004-10-08 09:43:57 +0000 |
commit | 47ed8d321c32c6b741cff1f4ff686165c4f269f4 (patch) | |
tree | da413648adbff4ff10c8ee26124673f8e7cf238a /winvnc/STrayIcon.cxx | |
parent | 266bb36cd47555280fffd3aab1ed86683e26d748 (diff) | |
download | tigervnc-47ed8d321c32c6b741cff1f4ff686165c4f269f4.tar.gz tigervnc-47ed8d321c32c6b741cff1f4ff686165c4f269f4.zip |
Initial revision
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@2 3789f03b-4d11-0410-bbf8-ca57d06f2519
Diffstat (limited to 'winvnc/STrayIcon.cxx')
-rw-r--r-- | winvnc/STrayIcon.cxx | 234 |
1 files changed, 234 insertions, 0 deletions
diff --git a/winvnc/STrayIcon.cxx b/winvnc/STrayIcon.cxx new file mode 100644 index 00000000..7cfea3c2 --- /dev/null +++ b/winvnc/STrayIcon.cxx @@ -0,0 +1,234 @@ +/* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved. + * + * This 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 software 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 software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +// -=- WinVNC Version 4.0 Tray Icon implementation + +#include <winvnc/STrayIcon.h> +#include <winvnc/resource.h> + +#include <rfb/LogWriter.h> +#include <rfb/Configuration.h> +#include <rfb_win32/LaunchProcess.h> +#include <rfb_win32/TrayIcon.h> +#include <rfb_win32/AboutDialog.h> +#include <rfb_win32/Win32Util.h> +#include <rfb_win32/Service.h> +#include <rfb_win32/CurrentUser.h> + +using namespace rfb; +using namespace win32; +using namespace winvnc; + +static LogWriter vlog("STrayIcon"); + +BoolParameter STrayIconThread::disableOptions("DisableOptions", "Disable the Options entry in the VNC Server tray menu.", false); + + +// +// -=- AboutDialog global values +// + +const WORD rfb::win32::AboutDialog::DialogId = IDD_ABOUT; +const WORD rfb::win32::AboutDialog::Copyright = IDC_COPYRIGHT; +const WORD rfb::win32::AboutDialog::Version = IDC_VERSION; +const WORD rfb::win32::AboutDialog::BuildTime = IDC_BUILDTIME; +const WORD rfb::win32::AboutDialog::Description = IDC_DESCRIPTION; + + +// +// -=- Internal tray icon class +// + +const UINT WM_SET_TOOLTIP = WM_USER + 1; + + +class winvnc::STrayIcon : public TrayIcon { +public: + STrayIcon(STrayIconThread& t) : thread(t), + vncConfig(_T("vncconfig.exe"), isServiceProcess() ? _T("-noconsole -service") : _T("-noconsole")), + vncConnect(_T("winvnc4.exe"), _T("-connect")) { + + // *** + SetWindowText(getHandle(), _T("winvnc::IPC_Interface")); + // *** + + SetTimer(getHandle(), 1, 3000, 0); + PostMessage(getHandle(), WM_TIMER, 1, 0); + PostMessage(getHandle(), WM_SET_TOOLTIP, 0, 0); + } + + virtual LRESULT processMessage(UINT msg, WPARAM wParam, LPARAM lParam) { + switch(msg) { + + case WM_USER: + { + bool userKnown = CurrentUserToken().isValid(); + bool allowOptions = !STrayIconThread::disableOptions && userKnown; + + switch (lParam) { + case WM_LBUTTONDBLCLK: + SendMessage(getHandle(), WM_COMMAND, allowOptions ? ID_OPTIONS : ID_ABOUT, 0); + break; + case WM_RBUTTONUP: + HMENU menu = LoadMenu(GetModuleHandle(0), MAKEINTRESOURCE(thread.menu)); + HMENU trayMenu = GetSubMenu(menu, 0); + + + // Default item is Options, if available, or About if not + SetMenuDefaultItem(trayMenu, allowOptions ? ID_OPTIONS : ID_ABOUT, FALSE); + + // Enable/disable options as required + EnableMenuItem(trayMenu, ID_OPTIONS, (!allowOptions ? MF_GRAYED : MF_ENABLED) | MF_BYCOMMAND); + EnableMenuItem(trayMenu, ID_CONNECT, (!userKnown ? MF_GRAYED : MF_ENABLED) | MF_BYCOMMAND); + EnableMenuItem(trayMenu, ID_CLOSE, (isServiceProcess() ? MF_GRAYED : MF_ENABLED) | MF_BYCOMMAND); + + // SetForegroundWindow is required, otherwise Windows ignores the + // TrackPopupMenu because the window isn't the foreground one, on + // some older Windows versions... + SetForegroundWindow(getHandle()); + + // Display the menu + POINT pos; + GetCursorPos(&pos); + TrackPopupMenu(trayMenu, 0, pos.x, pos.y, 0, getHandle(), 0); + break; + } + return 0; + } + + // Handle tray icon menu commands + case WM_COMMAND: + switch (LOWORD(wParam)) { + case ID_OPTIONS: + { + CurrentUserToken token; + if (token.isValid()) + vncConfig.start(isServiceProcess() ? (HANDLE)token : 0); + else + vlog.error("Options: unknown current user"); + } + break; + case ID_CONNECT: + { + CurrentUserToken token; + if (token.isValid()) + vncConnect.start(isServiceProcess() ? (HANDLE)token : 0); + else + vlog.error("Options: unknown current user"); + } + break; + case ID_DISCONNECT: + thread.server.disconnectClients("tray menu disconnect"); + break; + case ID_CLOSE: + if (!isServiceProcess()) + thread.server.stop(); + break; + case ID_ABOUT: + AboutDialog::instance.showDialog(); + break; + } + return 0; + + // Handle commands send by other processes + case WM_COPYDATA: + { + COPYDATASTRUCT* command = (COPYDATASTRUCT*)lParam; + switch (command->dwData) { + case 1: + { + CharArray viewer = new char[command->cbData + 1]; + memcpy(viewer.buf, command->lpData, command->cbData); + viewer.buf[command->cbData] = 0; + thread.server.addNewClient(viewer.buf); + } + break; + case 2: + thread.server.disconnectClients("IPC disconnect"); + break; + }; + }; + break; + + case WM_CLOSE: + PostQuitMessage(0); + break; + + case WM_TIMER: + if (rfb::win32::desktopChangeRequired()) { + SendMessage(getHandle(), WM_CLOSE, 0, 0); + return 0; + } + setIcon(thread.server.isServerInUse() ? thread.activeIcon : thread.inactiveIcon); + return 0; + + case WM_SET_TOOLTIP: + { + rfb::Lock l(thread.lock); + if (thread.toolTip.buf) + setToolTip(thread.toolTip.buf); + } + return 0; + + } + + return TrayIcon::processMessage(msg, wParam, lParam); + } + +protected: + LaunchProcess vncConfig; + LaunchProcess vncConnect; + STrayIconThread& thread; +}; + + +STrayIconThread::STrayIconThread(VNCServerWin32& sm, UINT inactiveIcon_, UINT activeIcon_, UINT menu_) +: server(sm), inactiveIcon(inactiveIcon_), activeIcon(activeIcon_), menu(menu_), + windowHandle(0), runTrayIcon(true) { + start(); +} + + +void STrayIconThread::run() { + while (runTrayIcon) { + if (rfb::win32::desktopChangeRequired() && + !rfb::win32::changeDesktop()) + Sleep(2000); + + STrayIcon icon(*this); + windowHandle = icon.getHandle(); + + MSG msg; + while (runTrayIcon && ::GetMessage(&msg, 0, 0, 0) > 0) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + windowHandle = 0; + } +} + +void STrayIconThread::setToolTip(const TCHAR* text) { + if (!windowHandle) return; + Lock l(lock); + delete [] toolTip.buf; + toolTip.buf = tstrDup(text); + PostMessage(windowHandle, WM_SET_TOOLTIP, 0, 0); +} + + |