新的Windows 7任務欄體現了Windows啟動界面近幾年的不斷改進。新的任務欄 集成了很多最終用戶的使用場景:
• 運行應用程序
• 實現了正在運行的應用程序和運 行在同一個應用程序中的窗口之間的切換
• 對用戶最近使用的/ 頻繁使用的應用程序進行管理
• 訪問公用應用程序任務
• 通過任務欄按鈕報告進度和狀態
在不用離開任務欄的 情況下,控制應用程序
圖 1
新的Windows 7任務欄和開始菜單
在Windows 7平台上,新 的任務欄是使應用程序看上去與眾不同的一個很好的機會。它是最終用戶開始和 管理活動的主要地方。因此,在時尚的Windows 7應用程序中對新任務欄特性進行 集成就成了一項非常重要的工作。
將鎖定功能集成到新的任務欄中是為了 向用戶提供一個更加清晰的Windows用戶界面,以減少用戶需要為了和系統交互而 需要學習的新概念的數量,方便查找關鍵特性,任務和目標,以適應大多數最終 用戶的應用場景。
目標
在此次動手試驗中,您將會學習如何將您 的應用程序與Windows 7的任務欄進行集成,包括:
• 使用任務 欄進度條和覆蓋圖標提供可視化的進度和狀態指示器
• 使用縮略 圖工具欄遠程控制一個窗口
• 使用縮略圖剪輯和完全自定制的縮略圖來自定制任務欄縮略圖和實 時預覽
使用彈出列表任務(jump list tasks)系統分類和自定義分類快 速訪問常見任務和經常訪問的目標
系統要求
您必須符合下面全部 條件以完成此次試驗:
• Microsoft Visual Studio 2008 SP1
• Windows 7 RC或更新的版本
• Windows API Code Pack 0.90或更新的版本
顯卡支持Windows Aero
練習: 體驗Windows 7 任務欄的新功能
在這個聯系中,您將體驗Windows 7任務 欄的新功能。您將對一個實例應用程序進行擴展以說明如何使用新的任務欄的功 能來提供一個任務欄進度條,覆蓋圖標,自定義縮略圖,彈出列表等等。大多數 的應用程序界面都沒有完成全部功能;您不得不使用Windows API Code Pack來實 現遺漏的與Windows 7互動的部分。
要開始這個練習,請在Visual Studio 中打開TaskbarConcepts_Starter解決方案(在HOL根文件夾下)
圖 2
在Visual Studio中查看Taskbar Concepts 解決方案的結 構
用一兩分鐘的時間浏覽一下構成這個實例應用程序的XAML和C#文件。為 了方便您,請確定任務列表工具窗口是可見的(在視圖菜單中,選擇任務列表) 並且在工具窗口的下拉菜單中選擇Comments—您將看到此次練習中的所有任 務的TODO項。
幫助
為了使示例應用程序更為簡潔,這個示例並沒 有對WPF UI開發的最佳實踐進行說明,也沒有展示對Windows 7任務欄進行操作的 最佳設計准則。查看更多信息,請參閱Windows 7用戶體驗准則(任務欄) http://msdn.microsoft.com/en-us/library/aa511446.aspx 以及任務欄擴展相 關文章http://msdn.microsoft.com/en-us/library/dd378460(VS.85).aspx
任務 1 —使用任務覆蓋圖標(overlay icon )
在這個任務中, 當一個圖標被用戶選中的時候您將實現讓一個覆蓋圖標出現在應用程序的任務欄 按鈕上。
1.轉到 Overlays.xaml.cs代碼文件並定位到 ShowOrHideOverlayIcon方法
2.在這個方法代碼中,檢查是否選中了 ShowOverlay復選框
3.如果復選框被選中了,則用 iconsList.SelectedItem屬性獲取當前列表中被選中的圖標,如果不為空,則把 它和相應文本描述傳遞到TaskbarManager.Instance.SetOverlayIcon 方法。
這樣,應用程序的任務欄按鈕的右下角會出現一個覆蓋圖標,在無需切換 到應用程序窗口的情況下就可以提供一個中間狀態指示器。這一特性被用來顯示 Windows Live Messenger的登錄狀態,對於Microsoft Office Outlook 14則用來 顯示新郵件提醒,還有很多其他的應用程序也用到了這一特性。
4.如果復選框沒有被選中,則把null傳遞給相同的方法以去除覆蓋圖標。(您 也可以傳null表示文本描述)
5.完成的代碼應該和下面的代碼類似:
C#
if (ShowOverlay.IsChecked.Value)
{
Icon icon = iconsList.SelectedItem as Icon;
if (icon != null)
TaskbarManager.Instance.SetOverlayIcon(
icon, "icon" + iconsList.SelectedIndex.ToString());
}
else
{
TaskbarManager.Instance.SetOverlayIcon(null, null);
}
6.編譯並運行應用程序
7.轉到Overlay Icon選項卡,點擊復選框並確 定覆蓋圖標顯示在了應用程序的任務按鈕上。如圖:
圖 3
當選中‘Show selected icon as overlay’時 ,任務欄覆蓋圖標顯示了出來
8.選擇另一個圖標並確定覆蓋圖標改變了。
9.清除復選框並確定覆蓋圖標也同時清除了。
任務 2 —使 用任務欄進度條
在這個任務中,當用戶在下拉列表中選擇進度狀態或通過 滑塊改變值的時候,您將對應用程序任務欄進度條的狀態和值進行設置。
1.轉到ProgressBar.xaml.cs 代碼文件並定位到UpdateProgress 方法
2.在方法代碼中,查看ShowProgressBar 是否已被選中
3.如果復 選框被選中了,則使用TaskbarManager.Instance.SetProgressValue 方法來將進 度值設置為progressSlider.Value的屬性值。使用100作為進度條的最大值。
4.如果復選框被選中了,則用 TaskbarManager.Instance.SetProgressState 方法將進度狀態設置為 ProgressStateSelection.SelectedItem的屬性值。
這將會使應用程序的 任務欄按鈕上出現進度條, 在無需切換到應用程序的主窗口的情況下,提供了一 個中間進度指示器。這一特性當進行文件操作的時候廣泛的被應用於Windows Explorer中,當下載文件的時候應用於Internet Explorer中以及其他Windows應 用程序。
5.如果復選框沒有被選中,應用前面步驟中的方法來將進度狀態設置為 TaskbarProgressState.NoProgress,以清除進度條。
6.完成的代碼應該 和下面的代碼類似:
C#
if (ShowProgressBar.IsChecked.Value)
{
TaskbarManager.Instance.SetProgressValue((int)progressSlider.Value, 100);
TaskbarManager.Instance.SetProgressState(
(TaskbarProgressBarState) ProgressStateSelection.SelectedItem);
}
else
{
TaskbarManager.Instance.SetProgressState(
TaskbarProgressBarState.NoProgress);
}
7.轉到 ProgressStateSelection_SelectionChanged方法.
8.在方法代碼中,查看 ProgressStateSelection.SelectedItem屬性是不是等於 TaskbarProgressState.NoProgress.
9.如果相等,將 ShowProgressBar.IsChecked屬性設置為false 。
10.否則,設置該屬性為 true.
11.最後,如果必要的話,調用您之前寫的更新任務欄進度條狀態和 值的UpdateProgress方法。
12.完成的代碼應該和下面的代碼類似:
C#
if ((TaskbarProgressBarState) ProgressStateSelection.SelectedItem
== TaskbarProgressBarState.NoProgress)
{
ShowProgressBar.IsChecked = false;
}
else
{
ShowProgressBar.IsChecked = true;
}
UpdateProgress ();
13.轉到ShowProgressBar_Click方法
14.在方法代碼中,查看 ShowProgressBar.IsChecked的值是否為true。
15.如果是,設置 ProgressStateSelection.SelectedItem的屬性為TaskbarProgressState.Normal 。
16.否則,設置相同的屬性為TaskbarProgressState.NoProgress。
17.最後,如果必要的話,調用您之前寫的更新任務欄進度條狀態和值的 UpdateProgress方法。
18.完成的代碼應該和下面的代碼類似:
C#
if (ShowProgressBar.IsChecked.Value)
{
ProgressStateSelection.SelectedItem = TaskbarProgressBarState.Normal;
}
else
{
ProgressStateSelection.SelectedItem = TaskbarProgressBarState.NoProgress;
}
UpdateProgress ();
19.編譯並運行應用程序
20.轉到進度條選項卡,檢查 下拉列表框並調整滑塊到中間。確認任務欄進度條顯示並隨著改變。如圖:
圖 4
當‘Show slider’s value in progress bar’被選中的時候,任務欄進度條反映了滑塊的值。
21.從下拉列 表框中選擇一個不同的進度狀態並確定進度條狀態改變了(例如,錯誤進度狀態 會觸發一個紅色的進度條)
圖 5
任務欄進度指示器反映了在下拉列表中選中的進度狀態,本例 中——“錯誤”
22.清除下拉列表並確定進度條也 被清除了。
任務 3 —使用縮略圖工具欄
在這個任務中,您 將會創建任務欄縮略圖工具欄按鈕來對在主應用程序窗口中顯示圖片進行導航。
1.轉到ToolbarButtons.xaml.cs 代碼文件並定位到 CreateToolbarButtons 方法。您將會創建四個縮略圖工具欄按鈕用來做圖片導航 ,並在應用程序的縮略圖工具欄中添加這些按鈕。最後,用戶將可以通過任務欄 縮略圖進行導航,而無需切換到應用程序的主窗口。
縮略圖工具欄被用作 在Windows Media Player中正在播放的曲目之間提供便捷的導航,而無須切換到 Media Player窗口。這有效的替換了需要Media Player嵌入任務欄中的需求,該 需求很容易引起Windows任務欄的雜亂並增加了本可以用在任務欄按鈕上的許多屏 幕資源。
圖 6
Windows Media Player縮略圖工具欄
2.在方法代碼中, buttonFirst 成員變量定義為ThumbnailToolbarButton類。在構造函數中傳入 TaskbarConcepts.Resources.first 圖片和作為工具提示的“First Image”字符串。
3.設置buttonFirst.Enabled屬性為 false.
4.注冊buttonFirst_Click方法到buttonFirst.Click事件
5.對buttonPrevious成員變量重復2-4步,使用 TaskbarConcepts.Resources.prevArrow圖片和“Previous Image”字 符串。
6.對buttonNext成員變量重復2-4步(除了第3步),使用 TaskbarConcepts.Resources.nextArrow圖片和“Next Image”字符串 。
7.對buttonLast成員變量重復2-4步(除了第3步),使用 TaskbarConcepts.Resources.last image圖片和“Last Image”字符 串。
8.調用TaskbarManager.Instance.ThumbnailToolbars.AddButtons 方法,將應用程序的主窗口處理(handle)作為第一個參數傳入,後面跟著前一 步創建的按鈕。這步創建了任務欄縮略圖工具欄。
9.完成的代碼應該和下 面的代碼類似:
C#
buttonFirst = new ThumbnailToolbarButton(
TaskbarConcepts.Resources.first, "First Image");
buttonFirst.Enabled = false;
buttonFirst.Click += buttonFirst_Click;
buttonPrevious = new ThumbnailToolbarButton(
TaskbarConcepts.Resources.prevArrow, "Previous Image");
buttonPrevious.Enabled = false;
buttonPrevious.Click += buttonPrevious_Click;
buttonNext = new ThumbnailToolbarButton(
TaskbarConcepts.Resources.nextArrow, "Next Image");
buttonNext.Click += buttonNext_Click;
buttonLast = new ThumbnailToolbarButton(
TaskbarConcepts.Resources.last, "Last Image");
buttonLast.Click += buttonLast_Click;
TaskbarManager.Instance.ThumbnailToolbars.AddButtons(
new WindowInteropHelper(Application.Current.MainWindow).Handle,
buttonFirst, buttonPrevious, buttonNext, buttonLast);
10.編譯並運行應用程序
11.轉到Thumbnail Toolbar 選項卡並確定有 圖片出現。如果沒有圖片,則確定您的Pictures庫中含有圖片。
12.將鼠 標放到任務欄按鈕上面直到圖片出現。使用四個縮略圖工具欄按鈕進行圖片間的 導航。如圖:
圖 7
當鼠標放到應用程序的縮略圖上的時候,縮略圖工具欄允許您進 行圖片間的導航。
任務 4 —使用即時縮略圖預覽
在這個任 務中,您將為應用程序窗口自定制一個即時縮略圖(可預覽)並支持縮略圖(按 需)顯示。
1.轉到Thumbnail.xaml.cs 代碼文件並定位到 createOnDemandThumbnail_Click 方法。
2.在方法代碼中,查看 trickyBorder 的可視化屬性有一個縮略圖預覽。您可以使用 Utilities.HasThumbnailPreview 方法來完成這項工作。
3.如果它沒有預 覽圖,請進行下面的步驟。否則,從方法返回——因為已經有了一個 縮略圖就無需再創建一個了。
4.計算trickyBorder 可視化屬性的偏移量 。(您可以使用Application.Current.MainWindow屬性獲取主窗口框架。)要計 算偏移量,您可以使用幫助方法(helper method)Utilities.GetOffset。
要計算偏移量是因為,我們想要任務欄縮略圖只顯示圖片,並不是整個窗 口。這裡,任務欄縮略圖APIs需要應用程序主窗口的偏移量。當顯示一個縮略圖 的時候,如果您想要在一個窗口的特殊部分引起注意,或者當您想要動態決定哪 個窗口以縮略圖的形式顯示時,縮略圖自定義是很有用的。特別的,它並沒有和 您的窗口進行綁定——您那可以顯示一個完全自定制的圖片 ——但這可能會給用戶帶來潛在的困惑。
圖 8
Internet Explorer 8的特性,多個TGI界面的縮略圖
5.創 建一個TabbedThumbnail類的新實例並將應用程序主窗口,trickyBorder 可視化 元素和上一步運算的偏移量傳入構造函數。
6.使用 TaskbarManager.Instance.TabbedThumbnail.AddThumbnailPreview 方法對任務 欄添加新創建的預覽對象。
7.用 TabbedThumbnail_TabbedThumbnailBitmapRequested 來注冊TabbedThumbnail實 例的TabbedThumbnailBitmapRequested事件。這意味著我們沒有靜態的提供縮略 圖;而是,DWM會回調我們的事件來完成,以便於我們可以在需要的時候提供動態 的圖片。
8.將TabbedThumbnail實例的Tooltip屬性設置為一個您選擇的字 符串。
9.完成的代碼應該和下面的代碼類似:
C#
if (!Utilities.HasThumbnailPreview(trickyBorder))
{
Vector offset = Utilities.GetOffset(
Application.Current.MainWindow, trickyBorder);
TabbedThumbnail preview = new TabbedThumbnail(
Application.Current.MainWindow, trickyBorder, offset);
TaskbarManager.Instance.TabbedThumbnail.AddThumbnailPreview (preview);
preview.TabbedThumbnailBitmapRequested +=
TabbedThumbnail_TabbedThumbnailBitmapRequested;
preview.Tooltip = "This bitmap is created and returned on demand";
}
10.轉到removeOnDemandThumbnail_Click 方法。
11.在方法代碼中, 使用TaskbarManager.Instance.TabbedThumbnail.GetThumbnailPreview 方法獲 取與trickyBorder 可視化屬性縮略圖所對應的TabbedThumbnail對象。
12.如果所獲取的實例不為空,則使用 TaskbarManager.Instance.TabbedThumbnail.RemoveThumbnailPreview方法去除 縮略圖預覽。
13.完成的代碼應該和下面的代碼類似:
C#
TabbedThumbnail preview =
TaskbarManager.Instance.TabbedThumbnail.GetThumbnailPreview (trickyBorder);
if (preview != null)
TaskbarManager.Instance.TabbedThumbnail.RemoveThumbnailPreview (preview);
14.轉到 TabbedThumbnail_TabbedThumbnailBitmapRequested 方法。
15.在方法代 碼中,查看_sneakySource成員變量是否為空。
16.如果為空,分配一個新 的BitmapImage 對象給它,調用它的BeginInit方法,設置它的 DecodePixelHeight屬性為200,設置它的UriSource屬性為一個初始值為 “pack://application:,,,/assets/SpeedyGonzalez.jpg”的新的Uri 實例,然後調用它的EndInit 方法。
17.最後,使用事件參數中的 TabbedThumbnail.SetImage 方法並將它傳遞給_sneakySource成員變量。
18.完成的代碼應該和下面的代碼類似 :
C#
if (_sneakySource == null)
{
_sneakySource = new BitmapImage();
_sneakySource.BeginInit();
_sneakySource.DecodePixelHeight = 200;
_sneakySource.UriSource =
new Uri("pack://application:,,,/assets/SpeedyGonzales.jpg");
_sneakySource.EndInit();
}
e.TabbedThumbnail.SetImage (_sneakySource);
19.轉到 createThumbnail_Click 方法。在方法中,我們將設置靜態圖片為縮 略圖,不去注冊被DWM調用的事件。這樣,當縮略圖滯後的時候,我們將不得不手 動設置它為無效。
20.對image 可視化元素重復2-8步操作,但是這次不要 注冊TabbedThumbnailBitmapRequested事件。而是調用 TaskbarManager.Instance.TabbedThumbnail.SetActiveTab 方法並把它傳遞給新 創建的TabbedThumbnail實例。
21.完成的代碼應該和下面的代碼類似:
C#
if (!Utilities.HasThumbnailPreview(image))
{
Vector offset = Utilities.GetOffset(
Application.Current.MainWindow, image);
TabbedThumbnail preview = new TabbedThumbnail(
Application.Current.MainWindow, image, offset);
TaskbarManager.Instance.TabbedThumbnail.AddThumbnailPreview (preview);
preview.Tooltip = "This image will be replaced and invalidated";
TaskbarManager.Instance.TabbedThumbnail.SetActiveTab(preview);
}
22.轉到removeThumbnail_Click 方法
23.對image 可視化 元素重復10-12步操作
24.完成的代碼應該和下面的代碼類似:
C#
TabbedThumbnail preview =
TaskbarManager.Instance.TabbedThumbnail.GetThumbnailPreview(image);
if (preview != null)
TaskbarManager.Instance.TabbedThumbnail.RemoveThumbnailPreview (preview);
25.轉到invalidateThumbnail_Click 方法。無效的情況是必要的,因為我們 沒有為圖片注冊一個事件處理函數,並且圖片將始終是靜止的直到我們顯式的把 它設置為無效。
26.在方法代碼中,查看image 可視化元素是否有一個縮 略圖預覽(查看地11-12步)。
27.如果有,則使用TabbedThumbnail對象 的InvalidatePreview方法來將縮略圖預覽設置為無效。
28.完成的代碼應 該和下面的代碼類似:
C#
TabbedThumbnail preview =
TaskbarManager.Instance.TabbedThumbnail.GetThumbnailPreview(image);
if (preview != null)
preview.InvalidatePreview ();
29.編譯並運行應用程序
30.轉到Thumbnail Preview 選項卡並點擊‘Thumbnail with Callback’組中的‘Add as thumbnail’按鈕
31.將鼠標放在應用程序的任務欄按鈕上並確定縮 略圖顯示了圖片。將鼠標放在縮略圖上並確定即時預覽也顯示了通用的圖片。如 圖:
圖 9
在應用程序窗口中顯示按需生成的即時縮略圖和即時預覽
32.在‘Thumbnail with Callback’組中點擊‘Remove thumbnail’按鈕並確定應用程序的任務欄縮略圖並實時預覽都回到了默認 狀態。(整個窗口)
33.在‘Tabbed Thumbnail’組中點擊‘Add as thumbnail’按鈕
34.將鼠標放在應用程序的任務欄按鈕上並確定縮 略圖和實時預覽映射到主窗口中的當前圖片。
35.在‘Tabbed Thumbnail’組中點擊‘Update image’按鈕並注意縮略圖沒有 被刷新——還是顯示之前的圖片。如圖:
圖 10
縮略圖並沒有自動的刷新(因為並不是按需生成的),且顯示一 個滯後的圖片並不能反映UI的情況除非顯式的設置為無效。
36.在 ‘Tabbed Thumbnail’組中點擊‘Invalidate thumbnail’按鈕,確定縮略圖被更新並映射到新圖片。
37.最後, 在‘Tabbed Thumbnail’組中點擊‘Remove thumbnail’ 按鈕並確定應用程序任務欄縮略圖和實時預覽都回到了默認狀態(整個窗口)
任務 5 —使用縮略圖截圖(Clips )
在這個任務中,您將 設置一個方形截圖在窗口任務縮略圖中顯示,以縮放窗口的相關部分。
1. 轉到ThumbnailClip.xaml.cs 代碼文件並定位到mediaElement_MediaOpened 方法 。
2.在方法代碼中,計算主窗體中的mediaElement可視化元素的偏移量( 您可以通過Application.Current.MainWindow屬性獲取主窗口)要計算偏移量, 您可以使用幫助(helper)方法Utilities.GetOffset。
3.用WindowInteropHelper類獲取主窗口的處理(handle)。
4.創建一 個方形截圖(一個System.Drawing.Rectangle對象)。用第2步中所計算的偏移量 初始化x,y坐標,並初始化它的高度和寬度以賦給mediaElement的寬和高。
5.通過TaskbarManager.Instance.TabbedThumbnail.SetThumbnailClip方 法並傳入第3步中的主窗口處理(handle)和第4步中的方形截圖。
當您希 望關注窗口的某一特定區域並且不想為此創建自定義的縮略圖處理程序和自己繪 制縮略圖的時候,被剪輯的縮略圖是很有用的。例如,一個文本編輯器可能為此 獲益,即一個縮略圖截圖顯示光標所在的附近幾行——這可能比顯示 整個編輯窗口更加有效。
6.完成的代碼應該和下面的代碼類似:
C#
Vector offset = Utilities.GetOffset(
Application.Current.MainWindow, (Visual)mediaElement);
Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
{
IntPtr mainWindowHandle = new WindowInteropHelper(
Application.Current.MainWindow).Handle;
System.Drawing.Rectangle clipRect = new System.Drawing.Rectangle (
(int)offset.X, (int)offset.Y,
(int)mediaElement.ActualWidth, (int) mediaElement.ActualHeight);
TaskbarManager.Instance.TabbedThumbnail.SetThumbnailClip(
mainWindowHandle, clipRect);
}));
7.編譯並運行應用程序
8.轉到Thumbnail Clip選項卡並點擊按鈕來選 擇一個視頻文件(您可以從網上下載一個或用Sample Videos文件夾下的視頻)
9.當視頻正在播放的時候,把鼠標放到應用程序任務欄按鈕上並確定縮略 圖只顯示窗口的一部分,粗略裁剪的視頻的一部分。如圖:
圖 11
縮略圖截圖確保只在任務欄縮略圖中顯示相關窗口的一部 分
任務 6 —使用任務欄彈出列表
在這個任務中,您將會實 現添加用戶任務,自定義列表和目標(destination)的功能,以及清理用戶任務 列表。
1.轉到JL.xaml.cs 代碼文件並定位到OnAddTasks方法。
2. 在方法代碼中,創建一個JumpListLink類的實例並把notepad.exe的路徑(用 Environment.GetFolderPath方法決定System32目錄的位置,也就是Notepad所在 的位置),和作為連接標題的字符串“Open Notepad”傳遞給構造函 數。
3.將新創建的IconReference類的實例設置為新創建的實例的 IconReference 屬性,並把notepad.exe的路徑(在前一步中獲得的),以及圖標 索引值 0傳遞給構造函數.
4.重復步驟2和3來創建calc.exe 和 mspaint.exe 的連接和與之相對應的字符串“Open Calculator”和 “Open Paint”。
5.調用方法並將Notepad和Calculator連接 對象,JumpListSeparator的新實例,Paint的連接對象傳遞給它。
這樣,您就將通用用戶任務添加到了應用程序的彈出列表。實際上,可能對於 應用程序而言,並不會在用戶任務中包含不相關的應用程序的啟動項。而通用用 戶任務會包含應用程序的不同的命令行參數,以對應用程序特殊的部分進行導航 ,或者是應用程序的運行實例的特定命令。 例如,Windows Live Messenger用彈 出菜單來改變用戶的在線狀態。
圖 12
Windows Live Messenger任務欄彈出菜單,顯示用戶任務
6.最後,調用JumpList.Refresh 方法來刷新應用程序彈出菜單。
7.完成的代碼應該和下面的代碼類似:
C#
string systemFolder = Environment.GetFolderPath(
Environment.SpecialFolder.System);
IJumpListTask notepadTask = new JumpListLink(
System.IO.Path.Combine (systemFolder, "notepad.exe"), "Open Notepad")
{
IconReference = new IconReference(
Path.Combine(systemFolder, "notepad.exe"), 0)
};
IJumpListTask calcTask = new JumpListLink(
Path.Combine(systemFolder, "calc.exe"), "Open Calculator")
{
IconReference = new IconReference(
Path.Combine(systemFolder, "calc.exe"), 0)
};
IJumpListTask paintTask = new JumpListLink(
Path.Combine (systemFolder, "mspaint.exe"), "Open Paint")
{
IconReference = new IconReference(
Path.Combine(systemFolder, "mspaint.exe"), 0)
};
JumpList.AddUserTasks(
notepadTask, calcTask, new JumpListSeparator(), paintTask);
JumpList.Refresh();
8.轉到JumpList屬性
9.在屬性的get存取器中,查看_jumpList成員變 量是否為空。
10.如果為空,將它的值設置為JumpList.CreateJumpList方 法的結果,如果showRecent.IsChecked屬性為true則設置 KnownCategoryToDisplay屬性為JumpListKnownCategoryType.Recent,為false的 時候則設置為 JumpListKnownCategoryType.Frequent;最後,調用 JumpList.Refresh 方法來更新彈出菜單。
有兩個系統分類(category) 可以作為默認選項:一個是Recent分類,它顯示了最近您的應用程序訪問最多的 文檔,另一個是Frequent分類,顯示最近訪問的文檔。同時使用兩個分類是不推 薦的並且托管包裝也不允許這樣。
幫助
為了顯示Recent或 Frequent分類中的項,您的應用程序在Windows Registry中需要一個恰當定義的 文件類型集合(file-type association)(雖然它不是必須是文件類型的默認處 理函數)。示例應用程序可以被注冊來處理PNG圖形文件。更多關於文件類型集合 (file-type association)的信息,請參閱http://msdn.microsoft.com/en- us/library/dd758090.aspx
11.返回get存取器中的_jumpList成員變量的 值。
12.完成的代碼應該和下面的代碼類似:
C#
if (_jumpList == null)
{
_jumpList = JumpList.CreateJumpList();
_jumpList.KnownCategoryToDisplay =
showRecent.IsChecked.Value ?
JumpListKnownCategoryType.Recent :
JumpListKnownCategoryType.Frequent;
_jumpList.Refresh ();
}
return _jumpList;
13.轉到showRecent_Click 方法
14.在方法代碼中,用和第10步中同樣 邏輯來設置JumpList.KnownCategoryToDisplay屬性,並調用JumpList.Refresh方 法。
15.完成的代碼應該和下面的代碼類似:
C#
JumpList.KnownCategoryToDisplay =
showRecent.IsChecked.Value ?
JumpListKnownCategoryType.Recent :
JumpListKnownCategoryType.Frequent;
JumpList.Refresh ();
16.轉到OnClearTasks方法
17.在方法代碼中,調用 JumpList.ClearAllUserTasks方法清除所有用戶任務中的彈出列表。
18. 調用 JumpList.Refresh方法來使更改生效。
19.完成的代碼應該和下面的 代碼類似:
C#
JumpList.ClearAllUserTasks();
JumpList.Refresh();
20.轉到createCategory_Click 方法
21.在方法代碼中,制定_currentCategory成員變量為 JumpListCustomCategory類的一個新實例,並將從成員變量獲得的分類名稱傳遞 給構造函數
自定義分類是一個高級特性可以被應用程序用來提供比Recent 或Frequent系統分類更多的功能。例如,一個email應用程序可以提供收件夾,後 續標志和其他自定義分類。
22.用JumpList.AddCustomCategories 方法並 傳給它一個新創建的分類
23.調用JumpList.Refresh方法來提交變更。
24.將createCategoryItem, createCategoryLink, txtCategoryItem和 txtCategoryLink成員變量的IsEnable屬性設置為true。
25.完成的代碼應該和下面的代碼類似:
C#
_currentCategory = new JumpListCustomCategory (this.txtCategory.Text);
JumpList.AddCustomCategories (_currentCategory);
JumpList.Refresh();
this.createCategoryItem.IsEnabled = true;
this.createCategoryLink.IsEnabled = true;
this.txtCategoryItem.IsEnabled = true;
this.txtCategoryLink.IsEnabled = true;
26.轉到 createCategoryItem_Click方法
27.在方法代碼中,調用CheckFileName方 法並將txtCategoryItem成員變量的Text property屬性傳遞給它。
28.否 則,就創建一個新的JumpListItem類的實例並將包含txtCategoryItem.Text屬性 的調用GetTempFileName方法結果傳遞給構造函數(後面的方法創建了一個新的臨 時文件,並相應的進行了命名。)。
29.用_currentCategory成員變量的 AddJumpListItems方法並把新創建的JumpListItem實例傳遞給它。
30.調 用JumpList.Refresh方法來提交對彈出菜單的變更。
31.完成的代碼應該 和下面的代碼類似:
C#
if (!CheckFileName (txtCategoryItem.Text))
return;
JumpListItem jli = new JumpListItem(GetTempFileName(txtCategoryItem.Text));
_currentCategory.AddJumpListItems(jli);
JumpList.Refresh ();
32.轉到the createCategoryLink_Click方法
33.重復 步驟27-31,但不要使用txtCategoryItem,換成使用txtCategoryLink ,且不要 使用JumpListItem 換成使用JumpListLink。JumpListLink的構造函數需要一個附 加的標題參數——您應該把txtCategoryLink.Text屬性作為這個參數 。
shell items和shell links(在托管封裝中代表JumpListItem 和 JumpListLink,並且通過在COM Shell APIs下的IShellItem和IShellLink)的不 同在於shell item只包含一個您的應用程序注冊處理的文件的路徑,但shell link包含了附加的信息和服務的快捷方式,包括要傳遞給應用程序的啟動,命令 行參數,一個快捷方式圖標和其他參數。
34.完成的代碼應該和下面的代 碼類似:
C#
if (!CheckFileName (txtCategoryItem.Text))
return;
JumpListLink jli = new JumpListLink(
GetTempFileName (txtCategoryLink.Text), txtCategoryLink.Text);
_currentCategory.AddJumpListItems(jli);
JumpList.Refresh ();
35.編譯並運行應用程序.
36.轉到彈出列表選項卡並點 擊‘Ensure type registration’按鈕。應用程序將會在Windows Registry中進行.png文件和應用程序本身聯合注冊。這可能會彈出用戶帳戶控制 框——確定這個操作是合法的。
37.查看‘Show recent category’復選框並點擊上面的按鈕。在通用文件對話框中,選擇一個PNG 文件。確定應用程序的彈出菜單現在在Recent分類中包含了選中PNG文件。
38.點擊‘Add Tasks’按鈕並確定彈出列表現在包含了 Notepad,Calculator和Paint的連接(並且在前兩項和最後一項的中間有一個分 隔符).
39.在分類名稱文本框中輸入‘Important’並點擊 ‘Create’按鈕
40.在項(item)文本框中輸入 ‘Activity report’並點擊‘Add ShellItem’按鈕。確 定彈出列表中現在包含了叫做‘Important’的分類並且其中包含了 ‘Activity report’項。如圖:
圖 13
應用程序在彈出列表顯示了用戶任務, 系統分類 ‘Recent’以及自定義分類‘Important’
總結
在此次實驗中,您體驗了Windows 7 任務欄APIs並將示例應用程序和 Windows 7 任務欄進行了集成。您可以看出,使用進度條和覆蓋圖標在任務欄按 鈕上提供相關進度和狀態信息是很方便,如何使用彈出列表快速的訪問通用任務 和目標,如何使用縮略圖工具欄遠程控制應用程序,以及如何對應用程序縮略圖 中的顯示內容進行自定義縮略圖和實時預覽的擴展。
要將一個產品品質的 應用程序與Windows 7任務欄相集成,可能需要做比本次試驗中所做過的還要多的 工作,但是您現在已經完全具備了這樣的能力。