www.pudn.com > cjbtaskbarapplet.zip > TaskBarApplet.cpp


/////////////////////////////////////////////////////////////////////////////// 
// 
// File           : $Workfile:   TaskBarApplet.cpp  $ 
// Version        : $Revision:   1.0  $ 
// Function       :  
// 
// Author         : $Author:   Len  $ 
// Date           : $Date:   Dec 28 1997 12:16:08  $ 
// 
// Notes          :  
// 
// Modifications  : 
// 
// $Log:   D:/Documents/Len/Sources/Stuff/TaskBarApplet/TaskBarLib/PVCS/TaskBarApplet.cpv  $ 
//  
//    Rev 1.0   Dec 28 1997 12:16:08   Len 
// Initial revision. 
//  
/////////////////////////////////////////////////////////////////////////////// 
// 
// Copyright 1997 JetByte Limited. 
// 
// JetByte Limited grants you ("Licensee") a non-exclusive, royalty free,  
// licence to use, modify and redistribute this software in source and binary  
// code form, provided that i) this copyright notice and licence appear on all  
// copies of the software; and ii) Licensee does not utilize the software in a  
// manner which is disparaging to JetByte Limited. 
// 
// This software is provided "AS IS," without a warranty of any kind. ALL 
// EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING  
// ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE  
// OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBYTE LIMITED AND ITS LICENSORS  
// SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF  
// USING, MODIFYING OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO  
// EVENT WILL JETBYTE LIMITED BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,  
// OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE  
// DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING  
// OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF JETBYTE LIMITED  
// HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 
// 
// This software is not designed or intended for use in on-line control of 
// aircraft, air traffic, aircraft navigation or aircraft communications; or in 
// the design, construction, operation or maintenance of any nuclear 
// facility. Licensee represents and warrants that it will not use or 
// redistribute the Software for such purposes. 
// 
/////////////////////////////////////////////////////////////////////////////// 
 
/////////////////////////////////////////////////////////////////////////////// 
// Include files 
/////////////////////////////////////////////////////////////////////////////// 
 
#include  
#include  
#include "TaskBarApplet.hpp" 
 
/////////////////////////////////////////////////////////////////////////////// 
// Namespace: JetByteTools 
/////////////////////////////////////////////////////////////////////////////// 
 
namespace JetByteTools { 
 
/////////////////////////////////////////////////////////////////////////////// 
// CJBTaskBarApplet 
/////////////////////////////////////////////////////////////////////////////// 
 
/////////////////////////////////////////////////////////////////////////////// 
// Initialise class static data 
/////////////////////////////////////////////////////////////////////////////// 
 
int CJBTaskBarApplet::s_nActiveApps = 0; 
 
HWND CJBTaskBarApplet::s_hWnd = 0; 
HINSTANCE CJBTaskBarApplet::s_hInstance = 0; 
 
const UINT CJBTaskBarApplet::s_uNotificationMessageID =  
   ::RegisterWindowMessage(_T("CJBTaskBarAppletMessage")); 
 
/////////////////////////////////////////////////////////////////////////////// 
// Construction and destruction 
/////////////////////////////////////////////////////////////////////////////// 
 
CJBTaskBarApplet::CJBTaskBarApplet() 
{ 
   s_nActiveApps++; 
} 
 
CJBTaskBarApplet::~CJBTaskBarApplet() 
{ 
   // Nothing to do, yet. 
} 
 
/////////////////////////////////////////////////////////////////////////////// 
// Static access function to run all applets in the executable. 
/////////////////////////////////////////////////////////////////////////////// 
 
int CJBTaskBarApplet::Run(HINSTANCE hInstance, LPSTR lpCmdLine) 
{ 
   int result = 1; 
 
   if (Initialise(hInstance, lpCmdLine)) 
   { 
      for (Iterator addIt = Begin(); addIt != End(); ++addIt) 
      { 
         addIt->AddIcon(); 
      } 
 
      MSG msg; 
 
      while (::GetMessage(&msg, NULL, 0, 0)) 
      { 
         ::TranslateMessage(&msg); 
         ::DispatchMessage(&msg); 
      } 
 
      for (Iterator removeIt = Begin(); removeIt != End(); ++removeIt) 
      { 
         removeIt->RemoveIcon(); 
      } 
 
      result = msg.wParam; 
   } 
 
   return result; 
} 
 
/////////////////////////////////////////////////////////////////////////////// 
// Override these to provide required functionality 
/////////////////////////////////////////////////////////////////////////////// 
 
HMENU CJBTaskBarApplet::GetMenu() 
{ 
   // By default we have a menu with "close" on it... 
 
   HMENU hMenu = ::CreatePopupMenu(); 
 
   MENUITEMINFO item; 
 
   memset(&item, 0, sizeof(MENUITEMINFO)); 
 
   item.cbSize = sizeof(MENUITEMINFO); 
 
   item.fMask = MIIM_TYPE | MIIM_ID; 
 
   item.wID = ID_CLOSE; 
 
   item.fType = MFT_STRING; 
 
   item.dwTypeData = "&Close"; 
 
   ::InsertMenuItem(hMenu, 1, TRUE, &item); 
 
   return hMenu; 
} 
 
void CJBTaskBarApplet::ReleaseMenu(HMENU hMenu) 
{ 
   // This can handle any menu created with CreatePopupMenu() 
   // change it if you want to cache the menu rather than create it 
   // each time 
 
   if (hMenu) 
   { 
      ::DestroyMenu(hMenu); 
   } 
} 
 
/////////////////////////////////////////////////////////////////////////////// 
// You may need to call these. 
/////////////////////////////////////////////////////////////////////////////// 
 
void CJBTaskBarApplet::ShowMenu() 
{ 
   // Obtain, display, handle selections and destroy a menu 
 
   HMENU hMenu = GetMenu(); 
 
   if (hMenu) 
   { 
      POINT pt; 
 
      ::GetCursorPos(&pt); 
 
      int cmd = ::TrackPopupMenu(hMenu,  
         TPM_RIGHTBUTTON | TPM_RETURNCMD,  
         pt.x,  
         pt.y,  
         0,  
         s_hWnd,  
         NULL); 
 
      HandleMenuCommand(cmd); 
   } 
 
   ReleaseMenu(hMenu); 
} 
 
void CJBTaskBarApplet::CloseApplet() 
{ 
   // The correct way to end an applet's life... 
 
   RemoveIcon(); 
 
   if (0 == --s_nActiveApps) 
   { 
      ::PostQuitMessage(0);  // Last one out turns out the lights 
   } 
} 
 
bool CJBTaskBarApplet::UpdateShellInfo()  
{ 
   // Call whenever you want to change the icon or tray tip, have GetIcon() 
   // or GetTrayTip() return the new items... 
 
   return SetShellNotification(NIM_MODIFY); 
} 
 
/////////////////////////////////////////////////////////////////////////////// 
// Override these to provide applet functionality, just don't expect  
// to call them yourself.  
/////////////////////////////////////////////////////////////////////////////// 
 
bool CJBTaskBarApplet::InitInstance(LPSTR /* lpCmdLine */) 
{ 
   return true; 
} 
 
void CJBTaskBarApplet::HandleMenuCommand(int command) 
{ 
   // Handle the default menu... 
 
   switch (command) 
   { 
      case ID_CLOSE : 
 
         CloseApplet(); 
 
      break; 
   } 
} 
 
void CJBTaskBarApplet::OnLeftButtonDown() 
{ 
} 
 
void CJBTaskBarApplet::OnLeftButtonUp() 
{ 
} 
 
void CJBTaskBarApplet::OnRightButtonDown() 
{ 
} 
 
void CJBTaskBarApplet::OnRightButtonUp() 
{ 
   ShowMenu(); 
} 
 
void CJBTaskBarApplet::OnLeftDoubleClick() 
{ 
} 
 
void CJBTaskBarApplet::OnRightDoubleClick() 
{ 
} 
 
void CJBTaskBarApplet::OnMouseMove() 
{ 
} 
 
void CJBTaskBarApplet::OnUnknownMessage(LPARAM /*lParam*/) 
{ 
   ::MessageBox(s_hWnd, "Unknown Message", "Odd", MB_ICONINFORMATION); 
} 
 
/////////////////////////////////////////////////////////////////////////////// 
// Private helper functions 
/////////////////////////////////////////////////////////////////////////////// 
       
const LPCTSTR CJBTaskBarApplet::SafeGetTrayTip() 
{ 
   LPCTSTR safeTip = GetTrayTip(); 
 
   if (lstrlen(safeTip) >= 64) 
   { 
      safeTip = _T("Error: Tip too long!"); 
   } 
 
   return safeTip; 
} 
 
void CJBTaskBarApplet::AddIcon() 
{ 
   SetShellNotification(NIM_ADD); 
} 
 
void CJBTaskBarApplet::RemoveIcon() 
{ 
   SetShellNotification(NIM_DELETE); 
} 
 
bool CJBTaskBarApplet::SetShellNotification(DWORD message) 
{ 
   NOTIFYICONDATA notifyIconData; 
 
   notifyIconData.cbSize = sizeof(notifyIconData); 
   notifyIconData.hWnd = s_hWnd; 
   notifyIconData.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; 
   notifyIconData.uCallbackMessage = s_uNotificationMessageID; 
   notifyIconData.uID = m_nObjectIndex; //m_nAppIndex; 
   notifyIconData.hIcon = GetIcon(); 
   ::lstrcpy(notifyIconData.szTip, SafeGetTrayTip()); 
 
   return (0 != ::Shell_NotifyIcon(message, ¬ifyIconData)); 
} 
 
/////////////////////////////////////////////////////////////////////////////// 
// Application level static functions. 
/////////////////////////////////////////////////////////////////////////////// 
 
bool CJBTaskBarApplet::Initialise(HINSTANCE hInstance, LPSTR lpCmdLine) 
{ 
   bool ok = false; 
 
   s_hInstance = hInstance; 
 
   if (CreateAppWindow()) 
   { 
      ok = InitInstances(lpCmdLine); 
   } 
 
   return ok; 
} 
 
bool CJBTaskBarApplet::CreateAppWindow() 
{ 
   bool ok = false; 
 
   WNDCLASS wndClass; 
 
   wndClass.style = 0;  
   wndClass.lpfnWndProc = CJBTaskBarApplet::WndProc; 
   wndClass.cbClsExtra = 0; 
   wndClass.cbWndExtra = 0; 
   wndClass.hInstance = s_hInstance; 
   wndClass.hIcon = NULL; 
   wndClass.hCursor = NULL; 
   wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); 
   wndClass.lpszMenuName = NULL; 
   wndClass.lpszClassName = _T("CJBTaskBarApplet"); 
 
   if (0 != ::RegisterClass(&wndClass)) 
   { 
      s_hWnd = CreateWindow(_T("CJBTaskBarApplet"),  
         _T("Invisible Message Window"),  
         WS_OVERLAPPEDWINDOW, 
         CW_USEDEFAULT, 
         CW_USEDEFAULT, 
         CW_USEDEFAULT, 
         CW_USEDEFAULT, 
         NULL, 
         NULL, 
         s_hInstance, 
         NULL); 
 
      if (s_hWnd) 
      { 
         ::ShowWindow(s_hWnd, SW_HIDE); 
          
         ok = (0 != ::UpdateWindow(s_hWnd)); 
      } 
   } 
 
   return ok; 
} 
 
bool CJBTaskBarApplet::InitInstances(LPSTR lpCmdLine) 
{ 
   Iterator it = Begin(); 
 
   bool ok = false; 
 
   do  
   { 
      ok = it->InitInstance(lpCmdLine); 
   } 
   while (ok && ++it != End()); 
 
   return ok; 
} 
 
/////////////////////////////////////////////////////////////////////////////// 
// Our message window's window procedure... 
/////////////////////////////////////////////////////////////////////////////// 
 
long APIENTRY CJBTaskBarApplet::WndProc( 
   HWND hWnd,  
   WPARAM message,  
   WPARAM wParam,  
   LPARAM lParam) 
{ 
   HMENU hMenu = 0; 
 
   CJBTaskBarApplet *pApplet = 0; 
 
   if (message == s_uNotificationMessageID) 
   { 
      ::SetForegroundWindow(hWnd); 
 
      pApplet = GetObjectByIndex(wParam); 
 
      switch (lParam) 
      { 
         case WM_LBUTTONDOWN: 
 
            pApplet->OnLeftButtonDown(); 
 
         break; 
 
	      case WM_LBUTTONUP: 
 
            pApplet->OnLeftButtonUp(); 
 
         break; 
 
	      case WM_RBUTTONDOWN: 
 
            pApplet->OnRightButtonDown(); 
 
         break; 
 
	      case WM_RBUTTONUP: 
 
            pApplet->OnRightButtonUp(); 
 
         break; 
 
	      case WM_LBUTTONDBLCLK: 
 
            pApplet->OnLeftDoubleClick(); 
 
	      break; 
 
	      case WM_RBUTTONDBLCLK: 
 
            pApplet->OnRightDoubleClick(); 
 
	      break; 
 
      	case WM_MOUSEMOVE: 
		    
            pApplet->OnMouseMove(); 
 
         break; 
 
         default : 
 
            pApplet->OnUnknownMessage(lParam); 
 
         break; 
      } 
 
      return 0; 
   } 
   else if (message == WM_DESTROY)  
   { 
      ::PostQuitMessage(0);   
 
      return 0; 
   } 
 
   return ::DefWindowProc(hWnd, message, wParam, lParam); 
} 
 
/////////////////////////////////////////////////////////////////////////////// 
// Namespace: JetByteTools 
/////////////////////////////////////////////////////////////////////////////// 
 
} // End of namespace JetByteTools  
 
/////////////////////////////////////////////////////////////////////////////// 
// End of file... 
///////////////////////////////////////////////////////////////////////////////