第 14 章: Windows 7 ジャンプ リストおよびタスク バー タブのサポートの追加

Hilo Browser および Annotator は、Windows 7 ジャンプ リストとタスク バー タブをサポートしています。ジャンプ リストによって、最近使ったファイルに簡単にアクセスすることが可能になり、主なタスクを起動するためのメカニズムも提供されます。また、タスク バー タブを使用して、Windows タスク バーからプレビュー 画像を表示し、追加のアクションを実行することができます。この章では、Hilo Browser および Annotator アプリケーションで Windows 7 ジャンプ リストおよびタスク バー タブのサポートがどのように実装されているかを検証します。

ジャンプ リストの項目の実装

アプリケーションのジャンプ リストは、タスク バーに表示されるアプリケーションのタブを右クリックすると表示されます。タッチ スクリーンでジャンプ リストを表示するには 3 つの方法があります。1 本の指でタブにタッチした後、別の指で必要な画面にタッチする方法、パン ジェスチャを使用してタブをタスク バーから外にドラッグする方法、およびタブにタッチして円が表示されたら離す方法です。

ジャンプ リストに表示される項目には、ジャンプ先とタスクの 2 種類があります。たとえば、図 1 に示す Internet Explorer のジャンプ リストには、[よくアクセスするサイト] と [タスク] の 2 つのカテゴリがあります。[よくアクセスするサイト] にはよく表示される Web ページが示されています。このようにコンテンツを参照している項目は、ジャンプ先と呼ばれます。他のアプリケーションでは、ファイルやフォルダー、その他のコンテンツ ベースの項目がジャンプ先として表示されます。通常、これらの項目は、IShellItem オブジェクト (または IShellLink オブジェクト) によって表すことができます。このスクリーンショットでは、[よくアクセスするサイト] に 5 つの項目が表示されていますが、表示される項目の数は、[スタート] メニューのプロパティからアクセスできる [[スタート] メニューのカスタマイズ] ダイアログ ボックスで設定できます。

[タスク] では、InPrivate ブラウズの開始および新しいタブを開くという、Internet Explorer で実行可能な操作が項目として表示されています。タスクは、タスクを実行するプロセスおよびタスク アクションを指定するパラメーターに関する情報を必要とするため、IShellLink オブジェクトとして作成されます。

図 1 Internet Explorer のジャンプ リスト

Gg281362.5045aa6b-4a9b-43cd-b8b7-e331b18dcb53(ja-jp,MSDN.10).png

Windows 7 シェル API を使用することにより、複数の方法でジャンプ リストを変更できます。最も簡単なアクションは、[最近使ったもの] の一覧にジャンプ先を追加することです。指定したジャンプ先をこのリストに追加することもできますが、多くの場合、Windows 7 ではコードを介さずにこの処理を行うことができます。シェル API により、ICustomDestinationList インターフェイスを通じたアクセスが提供され、カスタム カテゴリおよびカスタム タスクの追加といった、ジャンプ リストのカスタマイズが可能になります。

最近使ったファイルの一覧

最近使ったファイルの一覧は、Windows XP 以降の Windows で提供されている機能であり、Windows 7 アプリケーション プログラミング インターフェイス (API) の SHAddToRecentDocs 関数によって提供されています。この関数は、[スタート] メニューの [最近使ったファイル] (Windows XP) または [最近使った項目] (Windows Vista 以降) メニューにドキュメントを追加します。図 2 に [最近使った項目] メニューの例を示します。このメニューには、Word 文書、Visual Studio ソリューション、および 2 つの画像ファイルが表示されています。[最近使った項目] メニューのエントリはデータ ファイルへのパスであり、シェルはファイルの関連付けに関するレジストリ情報を使用して、ファイルを開くアプリケーションを特定します。

図 2 Windows 7 の [最近使った項目] メニューの表示

Gg281362.f78e2a61-1d1b-43a6-8c30-366635f23ad2-thumb(ja-jp,MSDN.10).png

Windows 7 では、[最近使った項目] の概念が個々のアプリケーションにまで拡張されているため、SHAddToRecentDocs 関数は、ファイルをシステムの [最近使った項目] メニューに追加するだけでなく、各アプリケーションのジャンプ リストの [最近使ったもの] にも追加します。図 3 に Annotator のジャンプ リストを示します。下の 3 つの項目はすべてのジャンプ リストに追加されるタスクで、それぞれアプリケーションの新しいインスタンスの起動、タスク バーへのアプリケーション項目の表示、インスタンスの終了を実行します。上部の [最近使ったもの] のファイル一覧は、Annotator で最近開いたファイルを表示しています。項目が [最近使ったもの] の一覧に追加されるのは、アプリケーションがシェルのファイル API (GetOpenFileName 関数または IFileOpenDialog インターフェイス) のいずれかを使用してファイルを開いた場合か、アプリケーションが明示的に SHAddToRecentDocs 関数を呼び出した場合です。

図 3 Annotator のジャンプ リストの表示

Gg281362.f9431739-c783-436f-9e69-137275028a4b(ja-jp,MSDN.10).png

図 3 では、Annotator で最近 2 つの画像ファイルを開いたことが示されています。また、図 2 からわかるように、これらのファイルは Windows 7 のシステム全体の [最近使った項目] メニューにも表示されています。SHAddToRecentDocs 関数がファイルを [最近使った項目] の一覧に追加することは上で述べましたが、Windows 7 側では、これらのファイルが他の画像エディターではなく Annotator で開かれたということを、どのようにして識別するのでしょうか。その答えはアプリケーション ユーザー モデル ID (または短縮して AppID) にあります。

AppID はアプリケーションを識別するための文字列です。Windows 7 シェルでは、これを利用することにより、同じアプリケーションの複数のインスタンスのタブをタスク バー上で重ねて表示することができます。Windows 7 で自動的にアプリケーションの AppID を割り当てることも可能ですが、独自に文字列を指定することによって柔軟性が向上します。これを行うための API 関数が SetCurrentProcessExplicitAppUserModelID で、現在、最も名前の長い Windows 7 API 関数です。この関数は、Unicode 文字列の AppID を唯一のパラメーターとして受け取ります。AppID として使用する一意の文字列は任意に指定できますが、ProgID の文字列と同じ形式を使用することをお勧めします。もちろん、アプリケーションの ProgID とは別の値を使用してください。リスト 1 に、AnnotatorApplication.cpp ファイルの先頭にある、ProgID と AppID を定義する定数文字列の宣言を示します。

リスト 1 Annotator の ProgID と AppID の宣言

const std::wstring ProgID = L"Microsoft.Hilo.AnnotatorProgID";
const std::wstring FriendlyName = L"Microsoft Hilo Annotator";
const std::wstring AppUserModelID = L"Microsoft.Hilo.Annotator";
const std::wstring FileTypeExtensions[] =
{
    L".bmp",
    L".dib",
    L".jpg",
    L".jpeg",
    L".jpe",
    L".jfif",
    L".gif",
    L".tif",
    L".tiff",
    L".png"
};

SetCurrentProcessExplicitAppUserModelID 関数は、最初のウィンドウが作成される前に呼び出す必要があります。Annotator では、メイン ウィンドウが作成される前に、AnnotatorApplication::Initialize メソッドでこの関数が呼び出されます。この関数は、指定された AppID をアプリケーションとそのウィンドウに関連付けますが、アプリケーションと、アプリケーションで編集できるファイルとの関連付けは行いません。これを行うのは ProgID レジストリ設定です。リスト 2 に、Annotator でジャンプ リストの [最近使ったもの] の一覧にファイルを追加するために必要な登録処理の一部を示します。最初の数行に示すように、編集するファイルの種類に対するハンドラーとして Annotator を登録する必要があります。リスト 2 ではファイルの種類として .bmp ファイルのみ登録しています (リスト 1 の FileTypeExtensions 配列に示されているすべてのファイルの種類について、同様の値を設定できます)。重要な点は、このファイルの種類の OpenWithProgIDs キー内に、Annotator でファイルを開くことを示す文字列エントリがあることです。ファイルの種類のハンドラーとして登録されるアプリケーションは、Annotator だけではありません。

リスト 2 ジャンプ リストへの登録

[HKEY_CLASSES_ROOT\.bmp\OpenWithProgids]
"Microsoft.Hilo.AnnotatorProgID"="":

[HKEY_CLASSES_ROOT\Microsoft.Hilo.AnnotatorProgID]
"FriendlyTypeName"="Microsoft Hilo Annotator"
"AppUserModelID"="Microsoft.Hilo.Annotator"

[HKEY_CLASSES_ROOT\Microsoft.Hilo.AnnotatorProgID\CurVer]
@="Microsoft.Hilo.AnnotatorProgID"

[HKEY_CLASSES_ROOT\Microsoft.Hilo.AnnotatorProgID\Shell\Open\Command]
@="C:\\Hilo\\annotator.exe %1"

ProgID の登録には、アプリケーションの AppID を含む AppUserModelID という値が必要です。この登録値によって AppID と ProgID がリンクされます。シェルがアプリケーションのインスタンスを起動できるようにするには、アプリケーションの場所とコマンド ラインの形式に関する情報が必要です。これが、Shell\Open\Command サブキーの目的です。このキーの既定値には、パスと、データ ファイルをコマンド ラインの最初のパラメーターにするという指示が含まれます。第 12 章で、Hilo Annotator アプリケーションを最初に使用したときに自動的に呼び出される RegistrationHelper ユーティリティについて説明しました。このユーティリティは、Annotator がジャンプ リストを使用できるようにするための登録を行います。

Annotator でファイルを読み込むには 3 つの方法があります。

  • **コマンド ラインを使用する方法。**Hilo Browser で [Annotator] ボタンをクリックすると、現在選択されている写真への完全なパスを指定して Annotator が起動されます。
  • **Annotator の画像エディターで別のファイルを選択する方法。**ファイル名を指定せずに Annotator を起動すると、ピクチャ ライブラリ内のすべての写真が表示され、写真の一覧をスクロールして編集する写真を選択できます。
  • Annotator のメイン メニューの [Open] を使用する方法。 メイン メニューの [Open] をクリックすると、標準の [File Open] ダイアログ ボックスが表示され、ファイルの一覧を参照して編集するファイルを選択することができます。

最後の方法では、IFileOpenDialog インターフェイスを通じて標準の [File Open] ダイアログ ボックスを使用します。この API を通じてファイルを開くと、シェルによって自動的に SHAddToRecentDocs 関数が呼び出されます。他の 2 つの方法でファイルを開く場合は、ファイルをジャンプ リストに追加する Windows 7 API が使用されないため、Annotator で SHAddToRecentDocs を呼び出して明示的にこの処理を行う必要があります。この呼び出しは ImageEditorHandler::SaveFileAtIndex メソッドで行われます。このメソッドは、Annotator のメニューで [Save] または [Save A Copy As] をクリックしたとき、またはアプリケーションを閉じるときに呼び出されます。

ジャンプ リストのタスク

[最近使ったもの] のファイル一覧を使用する以外にも、ジャンプ リストに項目を追加する方法はあります。Windows 7 シェルではジャンプ リストをさらにカスタマイズすることが可能です。たとえば、Browser ではカスタム タスクを追加できます。ジャンプ リストのカスタマイズの鍵は、ICustomDestinationList インターフェイスです。ジャンプ リストに対する変更は、トランザクション的な方法で行われます。まず、ICustomDestinationList::BeginList メソッドを呼び出し、変更を行った後、ICustomDestinationList::CommitList メソッドを呼び出して変更を永続化します。アプリケーションに明示的な AppID がある場合は、ICustomDestinationList::SetAppID メソッドを呼び出してから、BeginList メソッドを呼び出す必要があります。

Browser では、最初にアプリケーションを作成するときに BrowserApplication::Initialize メソッドの最後に呼び出される JumpList クラスでこの処理を行います。リスト 3 に、JumpList クラスを使用してカスタム タスクを追加するコードを示します。Browser は Annotator が同じフォルダー内にあることを前提としているため、最初のアクションはこのフォルダーへのパスを取得し、これを使用して Annotator への完全なパスを作成することです。次に、JumpList クラスのインスタンスが作成され、アプリケーションの AppID を使用して初期化されます。最後に、JumpList::AddUserTask メソッドが呼び出され、コマンド ライン パラメーターを指定せずに Annotator アプリケーションを起動するタスクが作成されます。

リスト 3 Browser ジャンプ リストのタスクを作成

wchar_t currentFileName[FILENAME_MAX];

if (!GetModuleFileName(nullptr, currentFileName, FILENAME_MAX))
{
   return S_OK;
}

// Annotator はこのバイナリと同じディレクトリにある必要がある
std::wstring currentDirectory = currentFileName;
std::wstring externalFileName = currentDirectory.substr(0, currentDirectory.find_last_of(L"\\") + 1);
externalFileName += L"annotator.exe";

JumpList jumpList(AppUserModeId);
hr = jumpList.AddUserTask(externalFileName.c_str(), L"Launch Annotator", nullptr);

リスト 4 に、JumpList::AddUserTask メソッドのメイン コードを示します。このコードでは、最初にジャンプ先リスト オブジェクトを作成し、ICustomDestinationList::SetAppID メソッドの呼び出しによって、変更するジャンプ リストを識別します。次に、ICustomDestinationList::BeginList メソッドを呼び出して、ジャンプ リストの変更を開始します。このメソッドは 2 つのアイテムを返します。1 つは ([スタート] メニューのプロパティで設定できる) [最近使ったもの] または [よく使うもの] のジャンプ先一覧に表示される項目の数で、もう 1 つのオブジェクトは、(項目を右クリックし、コンテキスト メニューの [この一覧から削除] をクリックすることによって) ジャンプ リストから削除した項目のコレクションです。Browser では削除された項目の一覧は処理しないので、JumpList クラスのメンバーとして配列を格納していても、このインターフェイス ポインターが使用されることはありません。次に、JumpList::CreateUserTask メソッドを呼び出してタスク項目を追加してから、ICustomDestinationList::CommitList メソッドを呼び出して変更を完了します。

リスト 4 Browser の新しいカテゴリの作成

HRESULT hr = CoCreateInstance(
   CLSID_DestinationList, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&m_destinationList));

hr = m_destinationList->SetAppID(m_appId.c_str());
UINT cMinSlots;
hr = m_destinationList->BeginList(&cMinSlots, IID_PPV_ARGS(&m_objectArray));

hr = CreateUserTask(applicationPath, title, commandLine);
hr = m_destinationList->CommitList();

JumpList::CreateUserTask メソッドをリスト 5 に示します。このコードは、ジャンプ リストに追加する項目を格納するオブジェクト コレクション オブジェクトを作成します (このオブジェクトはIObjectCollection インターフェイスを介してアクセスされます)。このコードは、シェル リンク オブジェクトをタスクに追加した後、ICustomDestinationList::AddUserTasks メソッドを呼び出してユーザー タスク一覧にコレクションを追加することにより、このオブジェクトを初期化します。ユーザー タスク一覧は [タスク] と呼ばれる標準カテゴリですが、カスタム カテゴリの作成も可能です。これを行うには、ICustomDestinationList::AppendCategory メソッドを呼び出し、カテゴリ項目をリターン オブジェクト配列に追加します。

リスト 5 Browser ジャンプ リストに新しいカテゴリを作成

ComPtr<IObjectCollection> shellObjectCollection;
HRESULT hr = CoCreateInstance(
   CLSID_EnumerableObjectCollection, nullptr, CLSCTX_INPROC, IID_PPV_ARGS(&shellObjectCollection));

// 最初にシェル リンクを作成する
ComPtr<IShellLink> shellLink;
hr = CreateShellLink(applicationPath, title, commandLine, &shellLink);
hr = shellObjectCollection->AddObject(shellLink);

// 指定されたユーザー タスクをジャンプ リストの [タスク] カテゴリに追加する
ComPtr<IObjectArray> userTask;
hr = shellObjectCollection->QueryInterface(&userTask);
hr = m_destinationList->AddUserTasks(userTask);

通常、タスクはシェル リンク オブジェクトであるため、ドキュメントではなくアプリケーションへのパスを指定することができます。Browser では、リスト 6 に示されている JumpList::CreateShellLink メソッドを呼び出すことによってシェル リンク オブジェクトが作成されます。このコードは、呼び出し元の JumpList::CreateUserTask メソッドに返されるシェル リンク オブジェクト (shellLink) を作成し、初期化します。このシェル リンク オブジェクトには、実行されるアプリケーションのパスおよびアプリケーションに渡されるコマンド ライン引数を含む複数のプロパティがあります。プロパティの多くは、IShellLink インターフェイスの Set メソッドによって設定されますが、ジャンプ リストに表示されるタイトルにはこのようなメソッドがありません。そこで、この値を設定するために、JumpList::CreateShellLink メソッドは、IPropertyStore インターフェイスをクエリして、シェル リンク オブジェクトの拡張プロパティを取得します。このメソッドは、タスク名を使用して PKEY_Title プロパティを設定します。プロパティは PROPVARIANT 構造体であり、VARIANT 構造体と同様に使用されます。使用する前に初期化し、不要になったらクリアする必要があります。

リスト 6 シェル リンク オブジェクトの作成

ComPtr<IShellLink> shellLink;
HRESULT hr = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&shellLink));

// シェル リンク オブジェクトのパスとファイル名を設定する
hr = shellLink->SetPath(applicationPath);

// シェル リンク オブジェクトのコマンド ライン引数を設定する
hr = shellLink->SetArguments(commandLine);

// シェル リンク オブジェクトの名前を設定する
ComPtr<IPropertyStore> propertyStore;
hr = shellLink->QueryInterface(&propertyStore);
PROPVARIANT propertyValue;
hr = InitPropVariantFromString(title, &propertyValue);
hr = propertyStore->SetValue(PKEY_Title, propertyValue);
hr = propertyStore->Commit();
hr = shellLink->QueryInterface(shellLinkAddress);
PropVariantClear(&propertyValue);

Annotator のタスク バー タブの実装

Windows 7 では、タスク バー タブから実行中のアプリケーションのサムネイルを表示することができます。タブをマウスでポイントするか、タッチ スクリーンでタブを指でタッチしてホールドすると、サムネイルが表示されます。図 4 に示す Browser の例のように、既定では、このサムネイルはウィンドウ全体のプレビューとなります。

図 4 Browser のタスク バー サムネイルの表示

Gg281362.cbc0c868-de7c-42ce-b151-3e8dd38f2d20-thumb(ja-jp,MSDN.10).png

サムネイルはアプリケーションのメイン ウィンドウの一部であり、既定ではウィンドウ全体を表示します。ただし、コードを使用して、ウィンドウの特定の部分を表示することも可能です。さらに、サムネイル ウィンドウにコントロールを追加して、アプリケーションを最小化しているときもアプリケーションの基本的な機能にアクセスできるようにすることができます。

Annotator では、サムネイルに表示されるウィンドウのセクションを変更し、画像エディターで画像をスクロールするためのコントロールを追加するコードを提供しています。このコードを確認するには、[スタート] メニュー (検索ボックスに「Annotator.exe」と入力し、表示されたリンクをクリックする) または Browser のジャンプ リストの [Launch Annotator] タスクを使用して、Annotator を単体で起動します。いずれの場合も、画像エディター ウィンドウに複数の画像が表示された状態で Annotator が起動されます。この時点で、タスク バーの Annotator のタブをマウスでポイントすると、Annotator のサムネイルには、現在編集中の画像のみが表示されます (図 5 を参照)。サムネイルにリボンは表示されず、下部に Backward ButtonForward Button という 2 つのボタンが表示されています。これらのボタンをクリックすると、キーボードの左右の方向キーを押したときと同じように、Annotator の画像が切り替わります。

図 5 Annotator のタスク バー サムネイルの表示

Gg281362.9a4dcc77-8941-43fd-aec7-51a3d937d60c-thumb(ja-jp,MSDN.10).png

Annotator でズーム ボタンを使用して画像のサイズを変更すると、サムネイルに表示される画像も同様に拡大縮小されます。

大部分の処理は、Taskbar というクラスのコードにより実行されます。このクラスは、ITaskbarList3 インターフェイスを実装するタスク バー リスト オブジェクトへのアクセスをラップします。サムネイルにはウィンドウの内容が表示され、子コントロールを追加することもできます。これらのコントロールはコマンド メッセージをウィンドウに送信するので、ITaskbarList3 インターフェイスのメソッドの多くは HWND パラメーターを必要とします。Taskbar クラスのコンストラクターは、メンバー変数として格納されている HWND パラメーターを受け取り、このハンドルはウィンドウ ハンドルを必要とするオブジェクト メソッドに渡されます。もう 1 つの重要なメンバー変数はタスク バー リスト オブジェクトへのインターフェイス ポインターで、これは Initialize メソッドによって初期化され、すべてのパブリック メソッドによって呼び出されます。Taskbar::Initialize メソッドをリスト 7 に示します。タスク バー リスト オブジェクトを作成し、初期化する単純なコードです。

リスト 7 タスク バー リスト オブジェクトの作成

HRESULT Taskbar::Initialize()
{
   HRESULT hr = S_OK;
   if (!m_taskbarList)
   {
      hr = CoCreateInstance(
         CLSID_TaskbarList, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&m_taskbarList));
      if (SUCCEEDED(hr))
      {
         hr = m_taskbarList->HrInit();
      }
   }
   return hr;
}

サムネイル画像

サムネイル画像を表示する処理は比較的単純で、タスク バー リスト オブジェクトに、ウィンドウのクライアント領域の座標を含む四角形を指定するだけです。この処理を行うと、必要に応じてタスク バーがウィンドウの適切な部分を取得し、サムネイルに描画します。これ以外の描画を行う必要はありません。

Annotator では、アプリケーション ウィンドウの再描画の要求は、ImageEditorHandler::OnRender メソッドにルーティングされ、このメソッドが ImageEditorHandler::UpdateTaskbarThumbnail メソッドを呼び出します。このメソッドは、大部分が現在の写真のクリッピング四角形を計算する処理となっています (リスト 8 では、この四角形は rect 変数として示されています)。ウィンドウの現在のクリッピング四角形を設定し、サムネイルに表示するコードをリスト 8 に示します。Taskbar::SetThumbnailClip メソッドは ITaskbarList3::SetThumbnailClip メソッドを呼び出して、Taskbar クラス コンストラクターに渡されたウィンドウ ハンドル (メイン ウィンドウのハンドルである hWndParent) とクリッピング四角形を渡します。

リスト 8 サムネイルのクリッピング四角形の指定

static Taskbar taskbar(hWndParent);
// 画像をサムネイルに拡大縮小する
hr = taskbar.SetThumbnailClip(&rect);

サムネイル ボタン

サムネイルにボタンを追加するには、複数のステップが必要です。最初に、タスク バーに対し、使用するボタンの画像を示します。次に、ボタンを追加して、ツールヒントのキャプションや ID などの情報を指定します。最後に、ボタンがクリックされたときに生成されるコマンド メッセージを処理するコードを提供する必要があります。Annotator では、Taskbar クラスによってタスク バーへのボタンとボタン 画像の追加を処理します。このコードは、AnnotatorApplication::Initialize メソッドで呼び出されます。リスト 9 にこのコードを示します。Taskbar オブジェクトは、Annotator アプリケーションのメイン ウィンドウのハンドルを使用して初期化されます。このオブジェクトを使用して、タスク バーに対し、この特定のウィンドウのサムネイルに表示するボタンを指定します。このコードに示されている ThumbnailToolbarButton 構造体は、ボタンの識別子を保持し、ボタンが有効であるかどうかを示すために使用されます (この時点では、既定で両方のボタンが有効になっています)。ボタンをクリックすると、WM_COMMAND メッセージがハンドラー ウィンドウに送信され、ボタンの識別子はこのメッセージの wParam の一部として提供されます。

リスト 9 サムネイル画像へのボタンの追加

HWND hwnd;
mainWindow->GetWindowHandle(&hwnd);
Taskbar taskbar(hwnd);
ThumbnailToobarButton backButton = {APPCOMMAND_BROWSER_BACKWARD, true};
ThumbnailToobarButton nextButton = {APPCOMMAND_BROWSER_FORWARD, true};
hr = taskbar.CreateThumbnailToolbarButtons(backButton, nextButton);

Taskbar::CreateThumbnailToolbarButtons メソッドは、サムネイルにボタンを追加するための主な処理を実行します。サムネイル ボタンの画像は、Windows 7 に標準で組み込まれた画像リスト コントロールによって提供されます。CreateThumbnailToolbarButtons メソッドの最初のアクションは、画像リストを使用してタスク バー リスト オブジェクトを初期化することであり、これを実行するコードは、リスト 10 に示す Taskbar::SetThumbnailToolbarImage メソッドによって提供されます。このコードは単純です。Annotator のリソースに 2 つの画像 arrow_toolbar_16.bmp および arrow_toolbar_24.bmp が含まれており、これらはそれぞれ、システムで 16x16 ピクセルおよび 24x24 ピクセルのアイコンを使用する場合に使用されます。各画像には 2 つのボタン 画像が含まれています。ImageList_LoadImage 関数を呼び出して imageList コントロールを初期化するために、コンピューターのアイコン サイズの設定に応じていずれかの画像が使用されます。画像リストは初期化された後、ITaskbarList3::ThumbBarSetImageList メソッドの呼び出しにより、Annotator のタスク バー サムネイルに関連付けられます。

リスト 10 サムネイル画像の設定

// 小さいアイコンの推奨幅 (ピクセル単位) を取得する
int const smallIconWidth = GetSystemMetrics(SM_CXSMICON);
// システムの小さいアイコンの幅に基づいてビットマップを読み込む
HIMAGELIST imageList;
if (smallIconWidth <= 16)
{
   imageList = ImageList_LoadImage(
      HINST_THISCOMPONENT, MAKEINTRESOURCE(IDB_BITMAP_TOOLBAR_16), 
      16, 0, RGB(255, 0, 255), IMAGE_BITMAP, LR_CREATEDIBSECTION);
}
else
{
   imageList = ImageList_LoadImage(
      INST_THISCOMPONENT, MAKEINTRESOURCE(IDB_BITMAP_TOOLBAR_24), 
      24, 0, RGB(255, 0, 255), IMAGE_BITMAP, LR_CREATEDIBSECTION);
}
// タスク バーにツール バー ボタンを追加する
if (imageList)
{
   hr = m_taskbarList->ThumbBarSetImageList(m_hWnd, imageList);
}
ImageList_Destroy(imageList);

サムネイル コントロールの画像リストが読み込まれると、リスト 11 の Taskbar::CreateThumbnailToolbarButtons メソッドによりボタンを作成することができます。このメソッドは、画像リスト内のボタン 画像のインデックス、ツールヒントの文字列、コントロールの ID に関する情報を含む配列を指定して ITaskbarList3::ThumbBarAddButtons メソッドを呼び出します。この情報は、ボタンがクリックされたときに、WM_COMMAND メソッドを介して渡されます。

リスト 11 サムネイル ボタンの作成

// サムネイル ツール バー ボタンのアイコン/画像を設定
hr = SetThumbnailToolbarImage();
THUMBBUTTON buttons[2] = {};

// 最初のボタン
buttons[0].dwMask = THB_BITMAP | THB_TOOLTIP | THB_FLAGS;
buttons[0].dwFlags = THBF_ENABLED | THBF_DISMISSONCLICK;;
buttons[0].iId = backButton.buttonId;
buttons[0].iBitmap = 0;
StringCchCopyW(buttons[0].szTip, ARRAYSIZE(buttons[0].szTip), L"Backward Button");

// 2 番目のボタン
buttons[1].dwMask = THB_BITMAP | THB_TOOLTIP | THB_FLAGS;
buttons[1].dwFlags = THBF_ENABLED | THBF_DISMISSONCLICK;
buttons[1].iId = nextButton.buttonId;
buttons[1].iBitmap = 1;
StringCchCopyW(buttons[1].szTip, ARRAYSIZE(buttons[1].szTip), L"Forward Button");

// ボタンをサムネイル ツール バーとして設定する
hr = m_taskbarList->ThumbBarAddButtons(m_hWnd, ARRAYSIZE(buttons), buttons);

ボタンが作成された後も、ITaskbarList3:: ThumbBarUpdateButtons メソッドを呼び出すことによって、これらの値を変更できます。Annotator では、(メイン ウィンドウが更新されたときに呼び出される) ImageEditorHandler::UpdateTaskbarThumbnail メソッドでこの処理を行います。このメソッドには、画像エディター ウィンドウの写真一覧における現在の写真の位置を調べるコードが含まれています。現在の写真が一覧の最初の写真である場合、Backward Button は無効になり、写真が一覧の最後にある場合、Forward Button は無効になります。サムネイル ボタンを有効または無効にするこのアクションは、Taskbar::EnableThumbnailToolbarButtons を呼び出すことによって実行されます。これに関するコードをリスト 12 に示します。ボタンを有効にする場合、このメソッドは THBF_ENABLED フラグを使用し、ボタンを無効にする場合、ボタンは THBF_DISABLED フラグを使用します。

リスト 12 サムネイル ボタンの有効化

HRESULT Taskbar::EnableThumbnailToolbarButtons(ThumbnailToobarButton backButton, ThumbnailToobarButton nextButton)
{
    HRESULT hr = Initialize();
    if (SUCCEEDED(hr))
    {
        THUMBBUTTON buttons[2] = {};
// 最初のボタン
        buttons[0].dwMask = THB_BITMAP | THB_TOOLTIP | THB_FLAGS;
        if (backButton.enabled)
        {
            buttons[0].dwFlags = THBF_ENABLED | THBF_DISMISSONCLICK;
        }
        else
        {
            buttons[0].dwFlags = THBF_DISABLED;
        }
        buttons[0].iId = backButton.buttonId;
        buttons[0].iBitmap = 0;
        StringCchCopyW(buttons[0].szTip, ARRAYSIZE(buttons[0].szTip), L"Backward Button");
// 2 番目のボタン
        buttons[1].dwMask = THB_BITMAP | THB_TOOLTIP | THB_FLAGS;
        if (nextButton.enabled)
        {
            buttons[1].dwFlags = THBF_ENABLED | THBF_DISMISSONCLICK;
        }
        else
        {
            buttons[1].dwFlags = THBF_DISABLED;
        }
        buttons[1].iId = nextButton.buttonId;
        buttons[1].iBitmap = 1;
        StringCchCopyW(buttons[1].szTip, ARRAYSIZE(buttons[1].szTip), L"Forward Button");
// サムネイル ツール バーのボタンを更新する
        hr = m_taskbarList->ThumbBarUpdateButtons(m_hWnd, ARRAYSIZE(buttons), buttons);
    }
    return hr;
}

[Forward Button] または [Backward Button] をクリックすると、サムネイルに関連付けられたウィンドウ (Annotator では、メイン ウィンドウ) に WM_COMMAND メッセージが送信されます。このメッセージは、画像エディター クラスにルーティングされ、ImageEditorHandler::OnCommand メソッドで処理されます。このメソッドは、クリックされたボタンに応じて、ImageEditorHandler::NextImage メソッドまたは ImageEditorHandler::PreviousImage メソッドを呼び出します。リスト 12 のコードでは、有効になったボタンの THBF_DISMISSONCLICK フラグによって、サムネイル ボタンをクリックしたときに、サムネイルを非表示にすることを指定しています。このフラグを省略すると、サムネイルは画面に表示されたままになり、サムネイルおよび Annotator ウィンドウ内でスクロール アクションが実行されます。

まとめ

この章では、アプリケーションの Windows 7 ジャンプ リストおよびタスク バーのサムネイルのサポートを実装する方法について説明しました。次の章では、Windows 7 Web サービス API を使用して、写真をオンラインの写真共有アプリケーションにアップロードする方法を見ていきます。

前へ | 次へ | ホーム