ソフトウエア Archive
タスクトレイに猫入れる
●タスクトレイに入れる
この手の(常駐?)アプリケーションでは,タスクバー(デフォルトで画面一番下にある,開いたウィンドウとかが並ぶところ)に表示せずに,タスクトレイ(タスクバー右側の時計の辺り)にアイコンを表示するのが一般的なようです.
そこで,猫ウィンドウクラスCCatWndのウィンドウ生成用メソッドであるCCatWnd::CreateWnd()に引数を追加し,猫ウィンドウ生成時にタスクトレイに入れるかどうかを選べるようにします.
virtual bool CreateWnd( …, bool bInTaskTray, UINT IconID );
bInTaskTrayがtrueのときは,IconIDでタスクトレイに表示するためのアイコンを指定します.
(コレ,IconIDの値だけで判断すれば,bInTaskTray引数はいらないような…)
(と,ここまでコード書いたところで,ウィンドウクラス(RagisterClassExで登録する方の「ウィンドウクラス」ね)自体のアイコンを指定する手段」が無いことに気付きました……後で考えよう)
●タスクトレイへのアイコン登録方法
…については,先に他者が書いた記事があるようなので簡潔に箇条書き.
- ウィンドウの拡張スタイルにWS_EX_TOOLWINDOWを指定すればタスクバーに表示されなくなる.
- タスクトレイへは ::Shell_NotifyIcon(NIM_ADD,…) で登録する.(要#include “shellapi.h”)
- タスクトレイへ登録したアイコンは,最後にちゃんと Shell_NotifyIcon(NIM_DELETE,…) で登録解除する必要がある.
- 登録時に Shell_NotifyIcon() に与える構造体にウィンドウハンドルとイベント通知用のメッセージ番号を指定しておけば,タスクトレイ上でアイコンに対するマウスイベント等が起こったときに通知される.
といった感じです.登録はCCatWnd::CreateWnd()内にて
if( bInTaskTray ) //タスクトレイに入れる指定がされていたら {//※このコードは一部省略して抜粋しています. NOTIFYICONDATA ncd = { 0 };//Shell_NotifyIcon()に与える構造体 ncd.hWnd = m_hWnd;//猫ウィンドウのウィンドウハンドル ncd.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; ncd.hIcon = ::LoadIcon( GetHInstance(), MAKEINTRESOURCE(IconID) );//アイコン指定.※GetHInstance()はインスタンスハンドルを取得してくるメンバ関数 ncd.uCallbackMessage = CATWNDIMPL_TASKTRAY_EVENT;//メッセージ番号.WM_APP+1あたりにしてあります. m_bIsInTaskTray = ( ::Shell_NotifyIcon( NIM_ADD, &ncd ) == TRUE );//登録が成功したことはメンバ変数で覚えておく(登録解除処理のために) }のようにしています.
これで,タスクトレイ上のアイコンにイベントが起こったら,m_hWnd宛にCATWNDIMPL_TASKTRAY_EVENTメッセージが送られてくるので,ウィンドウプロシージャでしかるべき処理を行うことができます.
猫ウィンドウではタスクトレイ上のアイコンが右クリックされたら,猫が右クリックされたときと同じポップアップメニューを表示することにしました.
CATWNDIMPL_TASKTRAY_EVENTメッセージ時に,イベントの種類はlParamに入っているので,猫ウィンドウでは lParam==WM_RBUTTONUP を条件にしてポップアップメニューを出しています.
なお,このときにメニューを出すべき場所は,::GetCursorPos()でマウスカーソル位置を取得して使っています.
(動き回る猫をクリックするのはそれなりに難しかった.これでやっと安定してメニューを出せます)
アイコン表示できた
アイコン出たけど…なんということでしょう……ぼけている……
32*32と16*16のサイズを持つアイコンを指定したら大きい方が使われてしまいぼけ具合が激しくなるようなので,16*16サイズだけのアイコンを用意して与えていますが,やはりぼけている.
(見たところ,タスクトレイに表示されている大きさは16*16ピクセルなはずなのだが……なんで??)
タスクトレイからの登録解除は,NOTIFYICONDATA構造体のnIDメンバとhWndメンバを,登録時と同じ値にして, ::Shell_NotifyIcon( NIM_DELETE, &構造体変数 ) とすればOK.
猫ウィンドウではウィンドウ破棄時に行っています.
(登録解除処理を忘れると,アプリ終了後も残ってしまいます.残骸をクリックしたりするとOSが消してくれる(?)ように見えますが)
- Comments (Close): 0
- Trackbacks (Close): 0
気まぐれ Programming TIPS 【1】
【1】 タスクトレイ常駐アプリ(C++,Win32 API,MFC)
気まぐれに思いついた内容を、備忘録的に殴り書く。
今回はタスクトレイ常駐アプリについて。
タスクトレイ常駐アプリを作るには、
・タスクトレイにアイコンを追加する
・メインウィンドウを非表示にする
とすれば良いのではなかろうか。
●タスクトレイにアイコンを追加する
これをやるにはAPIの「Shell_NotifyIcon」関数を使う。
Shell_NotifyIcon関数は、タスクバーのステータスエリアにメッセージを送る関数らしい。
BOOL
Shell_NotifyIcon(
DWORD dwMessage,
PNOTIFYICONDATA lpdata
);
第一引数がメッセージの種類、第二引数がもろもろの情報をまとめたNOTIFYICONDATA構造体。
で、関数が成功したらTRUE,失敗したらFALSEを返す。
ちなみにShell_NotifyIconを使うにはshellapi.hをインクルード、shell32.libをリンクする。
メッセージの種類は以下の通り。
NIM_ADD - アイコンの追加
NIM_MODIFY - アイコンの変更
NIM_DELETE - アイコンの削除
NIM_SETFOCUS - タスクトレイにフォーカスをセット
NIM_SETVERSION - バージョン設定
NOTIFYICONDATA構造体のメンバは以下の通り。
cbSize - 構造体のサイズをバイト単位で指定する
hWnd - アイコンの通知メッセージを受け取るウィンドウのハンドル
uID - アイコンのアプリケーショ定義のID
uFlags - 構造体のどのメンバを有効にするかのフラグ
(
NIF_MESSAGE:uCallbackMessage
NIF_ICON:hIcon
NIF_TIP:szTip
NIF_STATE:dwState, dwStateMask
NIF_INFO:szInfo, uTimeout,szInfoTitle,dwInfoFlags
NIF_GUID:使用しない
)
uCallbackMessage - アプリケーション定義のメッセージコード、タスクトレイアイコンにイベントが起こったと時にhWndで指定したウィンドウに送られる
hIcon - 表示アイコンのハンドル
szTip - ツールチップに表示される文字列
dwState - アイコンの状態
(
NIS_HIDDEN:アイコンは非表示
NIS_SHAREDICON:アイコンは共有
)
dwStateMask - dwStateメンバでどの状態を設定、取得するのかの指定
szInfo - バルーンツールチップに表示される文字列
uTimeout - バルーンツールチップの表示タイムアウト時間(10000 ~ 30000 msec)
uVersion - バージョン指定
(
0:Windows 95
NOTIFYICON_VERSION:Windows 2000
)
szTitleInfo - バルーンツールチップのタイトルとして表示される文字列
dwInfoFlags - バルーンツールチップに表示されるアイコンに設定
(
NIIF_NONE:アイコン無し
NIIF_INFO:情報アイコン
NIIF_WARNING:警告アイコン
NIIF_ERROR:エラーアイコン
NIIF_ICON_MASK:使用しない
NIIF_NOSOUND:音を鳴らさないようにする
)
guidItem - 使用しない
実際のコード
NOTIFYICONDATA nid; nid.cbSize = sizeof(NOTIFYICONDATA); nid.hWnd = GetSafeHwnd(); nid.uID = 0; nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; nid.uCallbackMessage = MSG_TASKTRAY; nid.hIcon = AfxGetApp()->LoadIcon(IDI_ICON); strcpy(nid.szTip,"tool tip"); Shell_NotifyIcon(NIM_ADD, &m_nid);最低限上記で、表示できる。
で、メインウィンドウを非表示にすれば、タスクトレイ常駐アプリの完成。ついでに、バルーンツールチップの表示の仕方。
NOTIFYICONDATA nid; nid.cbSize = sizeof(NOTIFYICONDATA); nid.uFlags = NIF_INFO; nid.hWnd = GetSafeHwnd(); strcpy(nid.szTip,"balloon title"); strcpy(nid.szInfo,"balloon info"); nid.dwInfoFlags = NIIF_INFO; nid.uTimeout = 20; Shell_NotifyIcon(NIM_MODIFY, &nid);
- Comments (Close): 0
- Trackbacks (Close): 0