trayicon_win.cpp

Go to the documentation of this file.
00001 /****************************************************************
00002  *  Vidalia is distributed under the following license:
00003  *
00004  *  Copyright (C) 2006,  Matt Edman, Justin Hipple
00005  *
00006  *  This program is free software; you can redistribute it and/or
00007  *  modify it under the terms of the GNU General Public License
00008  *  as published by the Free Software Foundation; either version 2
00009  *  of the License, or (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, 
00019  *  Boston, MA  02110-1301, USA.
00020  *****************************************************************
00021  *  The createIcon() method in this class is derived from code in
00022  *  trayicon_win.cpp by Justin Karneges, licensed as follows:
00023  *
00024  *  Copyright (C) 2003  Justin Karneges
00025  *
00026  *  This library is free software; you can redistribute it and/or
00027  *  modify it under the terms of the GNU Lesser General Public
00028  *  License as published by the Free Software Foundation; either
00029  *  version 2.1 of the License, or (at your option) any later version.
00030  * 
00031  *  This library is distributed in the hope that it will be useful,
00032  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00033  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00034  *  Lesser General Public License for more details.
00035  * 
00036  *  You should have received a copy of the GNU Lesser General Public
00037  *  License along with this library; if not, write to the Free Software
00038  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00039  *  02111-1307  USA
00040  ****************************************************************/
00041 
00042 /** 
00043  * \file trayicon_win.cpp
00044  * \version $Id: trayicon_win.cpp 1238 2006-09-25 17:50:57Z edmanm $
00045  * \brief Tray icon implementation on Win32 
00046  */
00047 
00048 #include <QApplication>
00049 
00050 #include "trayicon_win.h"
00051 
00052 #define WM_NOTIFYICON   WM_APP /**< Message sent for events related to our icon.*/
00053 #define TRAY_ICON_ID    0   /**< ID for our tray icon. */
00054 UINT    WM_TASKBARCREATED;  /**< Message sent when taskbar is created. */
00055 
00056 
00057 /** Constructor. */
00058 TrayIconImpl::TrayIconImpl(const QString &iconFile, const QString &toolTip)
00059 {
00060   setObjectName("trayiconimpl");
00061  
00062   /* We want to know when Explorer crashes and recreates the taskbar. */
00063   WM_TASKBARCREATED = RegisterWindowMessage(TEXT("TaskbarCreated"));
00064   
00065   /* Set the tray icon image */
00066   setIcon(iconFile);
00067   
00068   /* Add the tool tip to the structure */
00069   setToolTip(toolTip);
00070 }
00071 
00072 /** Updates the tray icon. */
00073 void
00074 TrayIconImpl::updateTrayIcon(DWORD msg)
00075 {
00076 QT_WA(  
00077   { /* UNICODE */
00078     NOTIFYICONDATAW nfd;
00079     nfd.cbSize = sizeof(NOTIFYICONDATAW);
00080     nfd.hWnd = winId();
00081     nfd.uID = TRAY_ICON_ID;
00082     nfd.uCallbackMessage = WM_NOTIFYICON;
00083     nfd.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
00084     nfd.hIcon = _icon;
00085     lstrcpynW(nfd.szTip, (TCHAR*)_toolTip.unicode(), 
00086               qMin(_toolTip.length()+1, 64));
00087     Shell_NotifyIconW(msg, &nfd);
00088   },
00089   { /* non-UNICODE */
00090     NOTIFYICONDATAA nfd;
00091     nfd.cbSize = sizeof(NOTIFYICONDATAA);
00092     nfd.hWnd = winId();
00093     nfd.uID = TRAY_ICON_ID;
00094     nfd.uCallbackMessage = WM_NOTIFYICON;
00095     nfd.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
00096     nfd.hIcon = _icon;
00097     lstrcpynA(nfd.szTip, (const char*)_toolTip.toLocal8Bit(), 
00098               qMin(_toolTip.length()+1, 64));
00099     Shell_NotifyIconA(msg, &nfd);
00100   })
00101 }
00102 
00103 /** Catches and handles mouse-related native Windows event messages. */
00104 bool
00105 TrayIconImpl::winEvent(MSG *msg, long *result)
00106 {
00107   if (msg->message == WM_NOTIFYICON) {
00108     switch (msg->lParam) {
00109       case WM_LBUTTONUP:
00110         return sendMouseEvent(QEvent::MouseButtonRelease, Qt::LeftButton);
00111 
00112       case WM_RBUTTONUP:
00113         return sendMouseEvent(QEvent::MouseButtonRelease, Qt::RightButton);
00114 
00115       case WM_LBUTTONDBLCLK:
00116         return sendMouseEvent(QEvent::MouseButtonDblClick, Qt::LeftButton);
00117 
00118       default:
00119         break;
00120     }
00121   } else if (msg->message == WM_TASKBARCREATED) {
00122     /* We handle WM_TASKBARCREATED because it's possible that Explorer
00123      * crashed and was recreated, in which case we need to re-add our icon. */
00124     updateTrayIcon(NIM_ADD);
00125   }
00126   return QWidget::winEvent(msg, result);
00127 }
00128 
00129 /** Sends a mouse-related event to the main TrayIcon class. */
00130 bool
00131 TrayIconImpl::sendMouseEvent(QEvent::Type type, Qt::MouseButton button)
00132 {
00133   QPoint pos = QCursor::pos();
00134   QMouseEvent event(type, mapFromGlobal(pos), pos, button, button, Qt::NoModifier);
00135   return QApplication::sendEvent(this, &event);
00136 }
00137 
00138 /** Create an icon for the tray image from a resource identifier. */
00139 HICON
00140 TrayIconImpl::createIcon(const int resourceId)
00141 {
00142   return LoadIconA((HINSTANCE)GetModuleHandleA(NULL),
00143                    MAKEINTRESOURCEA(resourceId));
00144 }
00145 
00146 /** Show the tray icon image. */
00147 void
00148 TrayIconImpl::show()
00149 {
00150   updateTrayIcon(NIM_ADD);
00151 }
00152 
00153 /** Hide the tray icon image. */
00154 void
00155 TrayIconImpl::hide()
00156 {
00157   updateTrayIcon(NIM_DELETE);
00158 }
00159 
00160 /** Set the tray icon's tooltip. */
00161 void
00162 TrayIconImpl::setToolTip(const QString &toolTip)
00163 {
00164   _toolTip = toolTip;
00165   updateTrayIcon(NIM_MODIFY);
00166 }
00167 
00168 /** Set the tray icon's image. */
00169 void
00170 TrayIconImpl::setIcon(const QString &iconFile)
00171 {
00172   _icon = createIcon(iconFile.toInt());
00173   updateTrayIcon(NIM_MODIFY);
00174 }
00175 

Generated on Mon Oct 23 20:08:16 2006 for Vidalia by  doxygen 1.5.0