OrangeMaker_logo
memo アイコン SDK-MFC 備忘録

Windows SDKやMFCに関するメモです。
(記載内容について正しいことを保証するものではありません。MSDN等で確認してください)

Windows7 ThumbnailToolbar ボタンを作る

2009/12/26 作成

Windows7ではタスクバーが一新され様々な新機能が盛り込まれています。そのなかにタスクバーのサムネイル画面にボタンが設定する機能があります。

このAPIを試してみます。

おおよその手順は、
1)タスクバーインタフェースのメッセージを取得する
2)タスクバーボタン生成メッセージをキャッチする。
3)ITaskbarList3のインスタンスを生成する
4)THUMBBUTTON構造体配列に必要な情報を設定する
5)ITaskbarList3クラスのメンバThumbBarAddButtons()でボタンを登録する。
6)ボタンを押されたときは,WM_COMMANDメッセージで通知される。

と、こんな感じです。

登録するボタンは、イメージリストのインタフェースとボタンアイコンとが使用できます。
とりあえずアイコンの方が簡単なのでアイコンで試してみます。

アイコンはVS2008付属のアイコンエディタで作成します。

下図のように青丸と赤丸のアイコンを作成します。

青丸アイコン  
赤丸アイコン  

次にWM_COMMANDで通知してもらうIDを決めます。このIDは他のボタンコントロールのIDと重複しないように決めます。(もちろん狙って同じIDでボタン押下ハンドラ処理に直接飛ばすのもありと思います。むしろ、これを狙ってWM_COMMANDで通知するインタフェースにしているのだと思います。)

リソースシンボルの定義で、それぞれ4001,40002と定義します。

シンボル定義  
WindowProc()ハンドラ:
 LRESULT CTaskBarDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
 {
     // TODO: ここに特定なコードを追加するか、もしくは基本クラスを呼び出してください。
     static UINT msgTBC = (UINT)-1;
     static HICON hIcon1 = 0;
     static HICON hIcon2 = 0;
	
     switch(message){
     case WM_CREATE:
         msgTBC = RegisterWindowMessage(_T("TaskbarButtonCreated"));
         hIcon1 = AfxGetApp()->LoadIcon(IDI_ICON1);
         hIcon2 = AfxGetApp()->LoadIcon(IDI_ICON2);
         //権限を昇格する場合を考慮するならメッセージフィルタにスルー指示を行う
         //ChangeWindowMessageFilter(msgTBC , MSGFLT_ADD);
         //ChangeWindowMessageFilter(WM_COMMAND, MSGFLT_ADD);
         break;
     case WM_COMMAND:
         int const CtlId = LOWORD(wParam);
         switch (CtlId){
         case IDTB_BUTTON1://Thumbnail ボタン1が押された処理
             {
                 WCHAR szMsg[100];
                 StringCchPrintf(szMsg, ARRAYSIZE(szMsg), 
                     _T("Thumbnail toolbar button1 clicked, ID=%d"),
                     CtlId);
                 AfxMessageBox( szMsg);
             }
             return 0;
         case IDTB_BUTTON2://Thumbnail ボタン2が押された処理
             {
                 WCHAR szMsg[100];
                 StringCchPrintf(szMsg, ARRAYSIZE(szMsg), 
                    _T("Thumbnail toolbar button2 clicked, ID=%d"), 
                    CtlId);
                 AfxMessageBox( szMsg);
             }
             return 0;
         }
         break;
		
     }
     if(message == msgTBC){//The taskbar button has been created
         THUMBBUTTON buttons[2];
         buttons[0].dwMask = THB_ICON|THB_TOOLTIP|THB_FLAGS;
         buttons[0].iId = IDTB_BUTTON1;
         buttons[0].hIcon = hIcon1;
         StringCchCopy(buttons[0].szTip, ARRAYSIZE(buttons[0].szTip), 
             _T("Button 1"));
         buttons[0].dwFlags = THBF_ENABLED;
	
         buttons[1].dwMask = THB_ICON|THB_TOOLTIP|THB_FLAGS;
         buttons[1].iId = IDTB_BUTTON1;
         buttons[1].hIcon = hIcon2;
         StringCchCopy(buttons[1].szTip, ARRAYSIZE(buttons[1].szTip), 
             _T("Button 2"));
         buttons[1].dwFlags = THBF_ENABLED;
         // Create an instance of ITaskbarList3
         ITaskbarList3 *ptbl;
         HRESULT hr = CoCreateInstance(CLSID_TaskbarList, NULL, 
             CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&ptbl));
		
         if (SUCCEEDED(hr)){
             // Attach the toolbar to the thumbnail.
             hr = ptbl->ThumbBarAddButtons(this->m_hWnd, 
                 ARRAYSIZE(buttons), buttons);
         }
         else{
             //error !comインスタンス生成失敗
         }
         ptbl->Release();
		
     }
		
     return CDialog::WindowProc(message, wParam, lParam);
 }
		

追加のインクルードは、

#include "strsafe.h"
※strsafe.hはStringCchPrintf()を使用しているためです。(タスクバーとは関係ありません)

WindowProc()内にすべて入れるためにメッセージ変数やアイコンハンドラ変数をstaticにしています。適宜クラス変数にするなど読み替えてください。

実行すると、以下のようにタスクバーのThumbnailにボタンが表示されます。

サムネイルツールバーサンプル  

このサンプルでは、ボタンを押すとそれぞれメッセージダイアログを表示します。

※アプリケーションが権限昇格を考慮する必要がある場合は、WM_CREATEでメッセージをスルーしてもらうためにChangeWindowMessageFilter()で指示する必要があります。(コメントアウト参照)

※Windows7の新機能のAPIをプログラムするには、事前に7用のSDKをインストールする必要がありますのでご注意ください。