win32systemtraypeer.cpp

来自「这是VCF框架的代码」· C++ 代码 · 共 420 行

CPP
420
字号
//Win32SystemTrayPeer.cpp/*Copyright 2000-2004 The VCF Project.Please see License.txt in the top level directorywhere you installed the VCF.*/#include "vcf/ApplicationKit/ApplicationKit.h"#include "vcf/ApplicationKit/ApplicationKitPrivate.h"#include "vcf/ApplicationKit/SystemTrayPeer.h"#include <shellapi.h>#include "vcf/ApplicationKit/Win32SystemTrayPeer.h"#include "vcf/ApplicationKit/Win32PopupMenu.h"#include "vcf/ApplicationKit/MenuItemPeer.h"#include "vcf/ApplicationKit/Win32MenuItem.h"#define WM_WIN32SYTEMTRAY		WM_APP + 405using namespace VCF;std::map<HWND,Win32SystemTrayPeer*> Win32SystemTrayPeer::sysTrayWndMap;Win32SystemTrayPeer::Win32SystemTrayPeer():	trayWnd_(NULL),	enabled_(true),	hidden_(true),	removed_(true),	notifyIconData_(NULL),	popupMenu_(NULL){		Win32ToolKit* toolkit = (Win32ToolKit*) UIToolkit::internal_getDefaultUIToolkit();	HWND parent = toolkit->getDummyParent();	static bool isWin32SystemTrayPeerWndClassRegistered = false;	if ( !isWin32SystemTrayPeerWndClassRegistered ) {		if ( System::isUnicodeEnabled() ) {			WNDCLASSEXW wcex;			wcex.cbSize = sizeof(wcex);			wcex.style			= CS_HREDRAW | CS_VREDRAW;			wcex.lpfnWndProc	= (WNDPROC)Win32SystemTrayPeer::wndProc;			wcex.cbClsExtra		= 0;			wcex.cbWndExtra		= 0;			wcex.hInstance		= ::GetModuleHandleW( NULL );			wcex.hIcon			= NULL;			wcex.hCursor		= NULL;			wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);			wcex.lpszMenuName	= NULL;			wcex.lpszClassName	= L"VCF::Win32SytemTray";			wcex.hIconSm		= NULL;			RegisterClassExW(&wcex);		}		else{			WNDCLASSEXA wcex;			wcex.cbSize = sizeof(wcex);			wcex.style			= CS_HREDRAW | CS_VREDRAW;			wcex.lpfnWndProc	= (WNDPROC)Win32SystemTrayPeer::wndProc;			wcex.cbClsExtra		= 0;			wcex.cbWndExtra		= 0;			wcex.hInstance		= ::GetModuleHandleA( NULL );			wcex.hIcon			= NULL;			wcex.hCursor		= NULL;			wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);			wcex.lpszMenuName	= NULL;			wcex.lpszClassName	= "VCF::Win32SytemTray";			wcex.hIconSm		= NULL;			RegisterClassExA(&wcex);		}	}	isWin32SystemTrayPeerWndClassRegistered = true;	if ( System::isUnicodeEnabled() ) {		notifyIconData_ = new NOTIFYICONDATAW;		memset( notifyIconData_, 0, sizeof(NOTIFYICONDATAW) );		trayWnd_ = ::CreateWindowW( L"VCF::Win32SytemTray", NULL, WS_CHILD , 0, 0, 0, 0, parent, NULL, ::GetModuleHandleW( NULL ), NULL );		Win32SystemTrayPeer::sysTrayWndMap[trayWnd_] = this;		NOTIFYICONDATAW& notifyIconData = *notifyIconDataW();		notifyIconData.cbSize = sizeof(NOTIFYICONDATAW);		notifyIconData.hWnd = trayWnd_;		notifyIconData.uID = (UINT)this;		notifyIconData.uCallbackMessage = WM_WIN32SYTEMTRAY;		notifyIconData.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;	}	else {		notifyIconData_ = new NOTIFYICONDATAA;		memset( notifyIconData_, 0, sizeof(NOTIFYICONDATAA) );		trayWnd_ = ::CreateWindowA( "VCF::Win32SytemTray", NULL, WS_CHILD , 0, 0, 0, 0, parent, NULL, ::GetModuleHandleA( NULL ), NULL );		Win32SystemTrayPeer::sysTrayWndMap[trayWnd_] = this;		NOTIFYICONDATAA& notifyIconData = *notifyIconDataA();		notifyIconData.cbSize = sizeof(NOTIFYICONDATAA);		notifyIconData.hWnd = trayWnd_;		notifyIconData.uID = (UINT)this;		notifyIconData.uCallbackMessage = WM_WIN32SYTEMTRAY;		notifyIconData.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;	}}Win32SystemTrayPeer::~Win32SystemTrayPeer(){	std::map<HWND,Win32SystemTrayPeer*>::iterator found =		Win32SystemTrayPeer::sysTrayWndMap.find( trayWnd_ );	::DestroyWindow( trayWnd_);	if ( System::isUnicodeEnabled() ) {		NOTIFYICONDATAW* ptr = (NOTIFYICONDATAW*)notifyIconData_;		delete ptr;	}	else {		NOTIFYICONDATAA* ptr = (NOTIFYICONDATAA*)notifyIconData_;		delete ptr;	}		if ( found != Win32SystemTrayPeer::sysTrayWndMap.end() ) {		Win32SystemTrayPeer::sysTrayWndMap.erase( found );	}}void Win32SystemTrayPeer::setIconImage( Image* image ){	if ( !enabled_ ) {        return;	}	HICON hIcon = NULL;	if ( NULL != image ) {		Win32Image* win32Img = (Win32Image*)image;		hIcon = win32Img->convertToIcon();		VCF_ASSERT( NULL != hIcon );	}	if ( System::isUnicodeEnabled() ) {		NOTIFYICONDATAW* notifyIconData = notifyIconDataW();		notifyIconData->uFlags = NIF_ICON;		notifyIconData->hIcon = hIcon;		if ( !hidden_ ) {			Shell_NotifyIconW( NIM_MODIFY, notifyIconData );		}	}	else {		NOTIFYICONDATAA* notifyIconData = notifyIconDataA();		notifyIconData->uFlags = NIF_ICON;		notifyIconData->hIcon = hIcon;		if ( !hidden_ ) {			Shell_NotifyIconA( NIM_MODIFY, notifyIconData );		}	}}void Win32SystemTrayPeer::setPopupMenu( PopupMenu* popupMenu ){	popupMenu_ = popupMenu;}void Win32SystemTrayPeer::setTooltipText( const String& tooltipText ){	if ( System::isUnicodeEnabled() ) {		NOTIFYICONDATAW* notifyIconData = notifyIconDataW();		int len = sizeof(notifyIconData->szTip);		tooltipText.copy( notifyIconData->szTip, len );		notifyIconData->szTip[minVal<unsigned int>(len-1,tooltipText.length())]=NULL;		notifyIconData->uFlags = NIF_TIP;		if ( !hidden_ ) {			Shell_NotifyIconW( NIM_MODIFY, notifyIconData );		}	}	else {		AnsiString tmp = tooltipText;		NOTIFYICONDATAA* notifyIconData = notifyIconDataA();		int len = sizeof(notifyIconData->szTip);		tmp.copy( notifyIconData->szTip, len );		notifyIconData->szTip[minVal<unsigned int>(len-1,tmp.length())]=NULL;		notifyIconData->uFlags = NIF_TIP;		if ( !hidden_ ) {			Shell_NotifyIconA( NIM_MODIFY, notifyIconData );		}	}}void Win32SystemTrayPeer::addToTray(){	if (!removed_) {        removeFromTray();	}    if (enabled_)  {		if ( System::isUnicodeEnabled() ) {			NOTIFYICONDATAW* notifyIconData = notifyIconDataW();			notifyIconData->uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;			if (!Shell_NotifyIconW(NIM_ADD, notifyIconData)) {						//  m_bShowIconPending = TRUE;			}			else {				removed_ = hidden_ = false;			}		}		else{			NOTIFYICONDATAA* notifyIconData = notifyIconDataA();			notifyIconData->uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;			if (!Shell_NotifyIconA(NIM_ADD, notifyIconData)) {						//  m_bShowIconPending = TRUE;			}			else {				removed_ = hidden_ = false;			}		}    }}void Win32SystemTrayPeer::removeFromTray(){	if (!enabled_ || removed_) {        return;	}	if ( System::isUnicodeEnabled() ) {		NOTIFYICONDATAW* notifyIconData = notifyIconDataW();		notifyIconData->uFlags = 0;		if ( Shell_NotifyIconW(NIM_DELETE, notifyIconData ) ) {			removed_ = hidden_ = true;		}	}	else {		NOTIFYICONDATAA* notifyIconData = notifyIconDataA();		notifyIconData->uFlags = 0;		if ( Shell_NotifyIconA(NIM_DELETE, notifyIconData ) ) {			removed_ = hidden_ = true;		}	}}void Win32SystemTrayPeer::showInTray(){	if ( removed_ ) {        addToTray();	}	if (!hidden_) {        return;	}		addToTray();}void Win32SystemTrayPeer::hideFromTray(){	if ( !enabled_ || removed_ || hidden_ ) {        return;	}	removeFromTray();}LRESULT Win32SystemTrayPeer::handleTrayMessage( WPARAM wParam, LPARAM lParam ){	LRESULT result = 0;	UINT uid = 0;	if ( System::isUnicodeEnabled() ) {		uid = notifyIconDataW()->uID;	}	else {		uid = notifyIconDataA()->uID;	}	if ( wParam != uid ) {		return result;	}	Win32ToolKit* toolkit = (Win32ToolKit*) UIToolkit::internal_getDefaultUIToolkit();	HWND dummyWnd = toolkit->getDummyParent();    // Clicking with right button brings up a context menu    if ( LOWORD(lParam) == WM_RBUTTONUP ) {		HWND wnd = dummyWnd;		if ( NULL != this->popupMenu_ ) {			// Display and track the popup menu			POINT pos = {0};			::GetCursorPos(&pos);								if ( Frame::getActiveFrame() ) {				wnd = (HWND)Frame::getActiveFrame()->getPeer()->getHandleID();			}			else if ( Application::getRunningInstance() ) {				wnd = (HWND) Application::getRunningInstance()->getMainWindow()->getPeer()->getHandleID();			}			::SetForegroundWindow( wnd ); 						MenuItem* rootItem = popupMenu_->getRootMenuItem();			if  ( NULL != rootItem )  {				MenuItemPeer* peer = rootItem->getPeer();				HMENU menuHandle = (HMENU)peer->getMenuID();				UINT flags = TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD | TPM_NONOTIFY;				UINT retVal = ::TrackPopupMenu( menuHandle, flags, pos.x, pos.y, 0, dummyWnd, NULL );				if ( retVal ){					MenuItem* item = Win32MenuItem::getMenuItemFromID( retVal );					if ( NULL != item ){						item->click();					}				}			}		}        // BUGFIX: See "PRB: Menus for Notification Icons Don't Work Correctly"		::PostMessage( wnd, WM_NULL, 0, 0);    }     else if (LOWORD(lParam) == WM_LBUTTONDBLCLK) {        // double click received, the default action is to execute default menu item		       }	return result;}LRESULT CALLBACK Win32SystemTrayPeer::wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){	LRESULT result = 0;	Win32SystemTrayPeer* thisPtr = NULL;	std::map<HWND,Win32SystemTrayPeer*>::iterator found =		Win32SystemTrayPeer::sysTrayWndMap.find( hWnd );	if ( found != Win32SystemTrayPeer::sysTrayWndMap.end() ) {		thisPtr = found->second;	}	bool trayMessage = false;	if ( NULL != thisPtr ) {		if ( System::isUnicodeEnabled() ) {			if ( thisPtr->notifyIconDataW()->uCallbackMessage == message ) {				trayMessage = true;			}		}		else{			if ( thisPtr->notifyIconDataA()->uCallbackMessage == message ) {				trayMessage = true;			}		}	}	if ( trayMessage ) {		result = thisPtr->handleTrayMessage( wParam, lParam );	}	else {		switch ( message ) {			case 0: // to make the compiler happy for switch with no case label			default : {				if ( System::isUnicodeEnabled() ) {					result = ::DefWindowProcW( hWnd, message, wParam, lParam );				}				else {					result = ::DefWindowProcA( hWnd, message, wParam, lParam );				}			}			break;		}	}	return result;}/***CVS Log info*$Log$*Revision 1.3  2006/04/07 02:35:26  ddiego*initial checkin of merge from 0.6.9 dev branch.**Revision 1.2.4.1  2005/11/14 17:11:21  pallindo*Fixed a crash that came from not nulling out the end of szTip in setTooltipText.**Revision 1.2  2004/12/01 04:31:39  ddiego*merged over devmain-0-6-6 code. Marcello did a kick ass job*of fixing a nasty bug (1074768VCF application slows down modal dialogs.)*that he found. Many, many thanks for this Marcello.**Revision 1.1.2.4  2004/09/09 02:41:06  marcelloptr*warning eliminated**/

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?