タスクトレイ常駐プログラムを簡単に作る

画面右下のタスクトレイ(通知領域)にアイコンを登録するアプリケーションは多い。ここでは簡単にアイコンを登録するためのクラスとその使用例を作成した。

ここでは簡単にするためにInternet Explorerのバージョン判断処理やアイコンのID設定処理は省いた。またタスクトレイのアイコンを管理するクラス「CDnpTaskTrayIcon」内には右クリックメッセージ表示用やバルーンメッセージ表示用の処理も備えているが、ここで示した使用例では利用していない。

ダウンロードできるプロジェクトをビルド、実行すると初期状態でタスクトレイにアイコンが表示される。そのアイコンをダブルクリックを繰り返すとダイアログが表示したり消えたりする。


ATL/WTLアプリケーションウイザードでダイアログベースのプロジェクトを作成し、自動生成されたソースコードを編集する。

■以下のコードをDnpTaskTrayIcon.hとして保存
#pragma	once


//#include "dinoputy.h"
//#include "dinoputy.cpp"


//
//	タスクトレイアイコン管理クラス
//
// uIDはゼロ固定のため、複数のアイコン登録は未対応
//
//
//■使用例
//
////stdafx.hでIEバージョン値を次のように定義すること
////#define _WIN32_IE	0x0501
//
//#include "DnpTaskTrayIcon.h"
//
//#define	WM_TRAY_NOTIFY_ICON		WM_APP + 10
//
//class CMainFrame : public CFrameWindowImpl<CMainFr(....省略....)
//{
//protected:
//	//メンバ変数として1行追加
//	CDnpTaskTrayIcon	_cTrayIcon;
//public:
//
//	(....省略....)
//
//	//メッセージマップに2行追加\
//	BEGIN_MSG_MAP(CMainFrame)
//		(....省略....)
//		MESSAGE_HANDLER(WM_TRAY_NOTIFY_ICON, OnTrayNotify)
//		CHAIN_MSG_MAP_MEMBER(_cTrayIcon)			//タスクトレイにメッセージを回す
//	END_MSG_MAP()
//
//	//トレイの登録とバルーンメッセージの表示
//	//OnCreateに限らず好きな位置に行を追加
//	LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
//	{
//		(....省略....)
//
//		//トレイアイコンの登録
//		_cTrayIcon.CreateTrayIcon(_T("テスト"),IDR_MAINFRAME,m_hWnd,WM_TRAY_NOTIFY_ICON);
//
//		//バルーンメッセージの表示
//		_cTrayIcon.ShowBaloonHelp(_T("バルーン"),_T("メッセージです"),15000);
//
//		(....省略....)
//	}
//
//
//	(....省略....)
//
//
//	//アイコンのクリック処理用関数を追加
//	LRESULT OnTrayNotify(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
//	{
//		switch(lParam)
//		{
//		case	WM_LBUTTONDBLCLK:		//ダブルクリック処理
//			break;
//
//		case	WM_RBUTTONDOWN:			//右クリック処理
//			break;
//
//		case	NIN_BALLOONSHOW:		//バルーンが表示されたとき
//			break;
//
//		case	NIN_BALLOONTIMEOUT:		//バルーンがタイムアウトで消えたとき
//			break;
//
//		case	NIN_BALLOONHIDE:		//バルーンが×ボタンのクリックにより消えたとき
//			break;
//
//		case	NIN_BALLOONUSERCLICK:	//バルーンが通知領域のクリックで消えたとき
//			break;
//		}
//
//		return	0;
//	}
//};
//
class	CDnpTaskTrayIcon
{
protected:

	bool	_bCreateIcon;			//アイコンが登録されているかどうか
	HWND	_hWnd;					//通知先HWND
	bool	_bIsIE5orLater;			//IEが5.0以上かどうか

	UINT	_nWmTaskbarCreated;		//タスクバー再描画を知らせる登録メッセージのID

	NOTIFYICONDATA	_sData;			//アイコン登録時情報

public:

	BEGIN_MSG_MAP(CDnpTaskTrayIcon)
		MESSAGE_HANDLER(_nWmTaskbarCreated, OnTaskbarCreated)
		MESSAGE_HANDLER(WM_DESTROY,OnClose)
		MESSAGE_HANDLER(WM_CLOSE,OnClose)
	END_MSG_MAP()



	//
	//	コンストラクタ
	//
	CDnpTaskTrayIcon()
	{
		_hWnd = NULL;
		_bIsIE5orLater = true;//IsIEVerion5orLater();
		_nWmTaskbarCreated = ::RegisterWindowMessage(_T("TaskbarCreated"));
		_bCreateIcon = false;

		ZeroMemory(&_sData,sizeof(NOTIFYICONDATA));
	}


	//
	//	アイコンの登録
	//
	bool	CreateTrayIcon(LPCTSTR pszTitle,UINT nIconResource,HWND hWnd,UINT nNotifyMessage)
	{
		BOOL	ret;

		_hWnd = hWnd;

		ATLASSERT(_bCreateIcon == false);			//既にアイコンが登録されている

		ZeroMemory(&_sData,sizeof(NOTIFYICONDATA));
		_sData.cbSize	= sizeof(NOTIFYICONDATA);
		_sData.hWnd		= hWnd;
		_sData.uID		= 0;						//IDはゼロで固定している!
		_sData.uFlags	= NIF_ICON | NIF_MESSAGE | NIF_TIP;
		_sData.hIcon	= ::LoadIcon(_Module.m_hInst,MAKEINTRESOURCE(IDR_MAINFRAME));
		_sData.uCallbackMessage = nNotifyMessage;

		//IEのバージョンによって最大TIPS長が異なる!
		if(pszTitle)
		{
			if(_bIsIE5orLater)
				_tcsncpy_s(_sData.szTip,128 * sizeof(TCHAR),pszTitle,64 * sizeof(TCHAR));
			else
				_tcsncpy_s(_sData.szTip,128 * sizeof(TCHAR),pszTitle,128 * sizeof(TCHAR));
		}

		ret = Shell_NotifyIcon(NIM_ADD,&_sData);

		_bCreateIcon = (ret) ? true : false;

		return	(ret) ? true : false;
	}



	//
	//	アイコンの変更
	//
	bool	ChangeTrayIcon(UINT nIconResource)
	{
		BOOL	ret;

		ATLASSERT(_bCreateIcon);		//アイコンが登録されていない
		if(_bCreateIcon == false)
			return	false;

		ZeroMemory(&_sData,sizeof(NOTIFYICONDATA));
		_sData.cbSize	= sizeof(NOTIFYICONDATA);
		_sData.hWnd		= _hWnd;
		_sData.uID		= 0;						//IDはゼロで固定している!
		_sData.uFlags	= NIF_ICON;
		_sData.hIcon	= ::LoadIcon(_Module.m_hInst,MAKEINTRESOURCE(nIconResource));

		ret = Shell_NotifyIcon(NIM_MODIFY,&_sData);

		return	(ret) ? true : false;
	}





	//
	//	バルーンヘルプの表示
	//
	bool	ShowBaloonHelp(LPCTSTR pszTitle,LPCTSTR pszMessage,UINT nTimeOut)
	{
		BOOL			ret;
		NOTIFYICONDATA	sData;

		//■■OSのバージョンチェックもするべき
//		ATLASSERT(_bCreateIcon);		//アイコンが登録されていない
//		ATLASSERT(_bIsIE5orLater);		//IE5以上ではない!
		if(_bCreateIcon == false)
			return	false;

		ZeroMemory(&sData, sizeof(NOTIFYICONDATA));
		sData.cbSize		= sizeof(NOTIFYICONDATA);
		sData.uFlags		= NIF_INFO;
		sData.hWnd			= _hWnd;
		sData.dwInfoFlags	= NIIF_INFO;
		sData.uTimeout		= nTimeOut;

		if(_bIsIE5orLater)
		{
			_tcsncpy_s(sData.szInfoTitle,64 * sizeof(TCHAR),pszTitle,64 * sizeof(TCHAR));
			_tcsncpy_s(sData.szInfo,256 * sizeof(TCHAR),pszMessage,256 * sizeof(TCHAR));
		}

		ret = Shell_NotifyIcon(NIM_MODIFY,&sData);

		return	(ret) ? true : false;
	}


	//
	//	トレイアイコンの削除
	//
	bool	RemoveTrayIcon(void)
	{
		BOOL			ret;
		NOTIFYICONDATA	sData;

		ATLASSERT(_bCreateIcon);		//アイコンが登録されていない

		ZeroMemory(&sData,sizeof(NOTIFYICONDATA));
		sData.cbSize	= sizeof(NOTIFYICONDATA);
		sData.hWnd		= _hWnd;
		sData.uID		= 0;
		ret = Shell_NotifyIcon(NIM_DELETE,&sData);

		_bCreateIcon = false;

		return	(ret) ? true : false;
	}



	//
	//	ポップアップメニューの表示
	//
	BOOL	TrackPopupMenu(HMENU hMenu,UINT uFlags=TPM_LEFTALIGN | TPM_RIGHTBUTTON)
	{
		BOOL	ret;
		POINT	pt;

		if(hMenu == NULL)
		{
			ATLASSERT(0);
			return	FALSE;
		}

		//カーソル位置の取得
		::GetCursorPos(&pt);

		::SetForegroundWindow(_hWnd);					//これがないとメニューが消えない

		//メニューの表示
		ret = ::TrackPopupMenu(hMenu,uFlags,pt.x,pt.y,0,_hWnd,NULL);

		::PostMessage(_hWnd,WM_NULL,NULL,NULL);			//これがないとメニューが消えない可能性がある

		return	ret;
	}


	//
	//	ポップアップメニューの表示
	//
	bool	TrackPopupMenu(UINT nMenuResource,int nSubMenu)
	{
		bool	ret;
		HMENU	hMenu;
		HMENU	hPopMenu;

		hMenu = ::LoadMenu(_Module.m_hInst,MAKEINTRESOURCE(nMenuResource));
		ATLASSERT(hMenu);
		if(hMenu == NULL)
			return	false;

		hPopMenu = ::GetSubMenu(hMenu,nSubMenu);

		ret = TrackPopupMenu(hPopMenu) ? true : false;

		::DestroyMenu(hMenu);

		return	ret;
	}


protected:

	//
	//	アプリケーション終了時処理
	//
	LRESULT OnClose(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
	{
		bHandled = FALSE;

		if(_bCreateIcon)
			RemoveTrayIcon();		//アイコンを削除する

		return	0;
	}

	//
	//	アイコン再描画処理
	//
	//タスクマネージャでexplorer.exeを強制終了させた場合などに消えたアイコンを再描画する
	//
	LRESULT OnTaskbarCreated(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
	{
		bHandled = FALSE;

		if(_bCreateIcon)
			Shell_NotifyIcon(NIM_ADD,&_sData);	//前回の情報を用いてアイコンを登録

		return	0;
	}
};
■MainDlg.h内に定義を追加
#include "DnpTaskTrayIcon.h"

#define	WM_TRAY_NOTIFY_ICON		WM_APP + 10
■MainDlg.hのCMainDlgにメンバー変数を追加
	CDnpTaskTrayIcon	_cTrayIcon;
■MainDlg.hのCMainDlgにメッセージマップを追加
	BEGIN_MSG_MAP(CMainDlg)

(。。。省略。。。)

		MESSAGE_HANDLER(WM_TRAY_NOTIFY_ICON, OnTrayNotify)
		CHAIN_MSG_MAP_MEMBER(_cTrayIcon)			//タスクトレイにメッセージを回す
	END_MSG_MAP()
■MainDlg.hのOnInitDialogでアイコン登録処理を追加
		//トレイアイコンの登録
		_cTrayIcon.CreateTrayIcon(_T("テスト"),IDR_MAINFRAME,m_hWnd,WM_TRAY_NOTIFY_ICON);
■MainDlg.hのCMainDlgにメンバー関数を追加
	//アイコンのクリック処理用関数を追加
	LRESULT OnTrayNotify(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
	{
		switch(lParam)
		{
		case	WM_LBUTTONDBLCLK:		//ダブルクリック処理
			if(IsWindowVisible())
				ShowWindow(SW_HIDE);
			else
				ShowWindow(SW_SHOWDEFAULT);
			break;

		case	WM_RBUTTONDOWN:			//右クリック処理
			break;

		case	NIN_BALLOONSHOW:		//バルーンが表示されたとき
			break;

		case	NIN_BALLOONTIMEOUT:		//バルーンがタイムアウトで消えたとき
			break;

		case	NIN_BALLOONHIDE:		//バルーンが×ボタンのクリックにより消えたとき
			break;

		case	NIN_BALLOONUSERCLICK:	//バルーンが通知領域のクリックで消えたとき
			break;
		}

		return	0;
	}


プロジェクトファイルをダウンロード


カテゴリー「その他」 のエントリー