You are on page 1of 82

/82

Windows 7 程式開發入

使用 Windows API Code Pack
曹祖聖
台灣微軟資深講師 for Microsoft .NET
jimycao@syset.com
http://teacher.syset.com Framework
MCP, MCP+I, MCSA, MCSE, MCDBA, MCAD, MCSD, MCTS,
MCITP, MCT, MVP

/82
大綱
l 工作列程式設計
l ExplorerBrowser 控制項與通用檔案對
話方塊
l 媒體櫃與搜尋連接器設計
l 如何用 .NET 程式控制 Windows 7
電源管理
l 繪圖 -- Direct2D 、 DirectWrite
l 應用程式如何支援重新啓動與自我修復功能

/82
大綱
l 工作列程式設計
l ExplorerBrowser 控制項與通用檔案對
話方塊
l 媒體櫃與搜尋連接器設計
l 如何用 .NET 程式控制 Windows 7
電源管理
l 繪圖 -- Direct2D 、 DirectWrite
l 應用程式如何支援重新啓動與自我修復功能

/82
客製化工作列圖示

/82
工作列進度與圖示顯示
// 名稱空間 :
Microsoft.WindowsAPICodePack.Shell.Taskbar

Taskbar.ProgressBar.CurrentValue = 10; // 0 ~
100

Taskbar.ProgressBar.State =
TaskbarButtonProgressState.Normal;

// NoProgress ( 不顯示進度 )
// Indeterminate ( 跑馬燈方式 )
// Normal ( 綠色正常顯示 )
// Error ( 顯示紅色 )
// Paused ( 暫停進度 )
/82
工作列進度與圖示顯示

/82
Jump Lists
小型的開始功能表

固定類別
目標 已知類別

自訂類別
使用者工作
工作
工作列工作

/82
加入自訂工作
string taskPath =
"c:\windows\\system32\\notepad.exe";

Taskbar.JumpList.UserTasks.Add(
new JumpListLink {
Title = " 開啓記事本 ",
Path = taskPath,
IconReference = new
IconReference(taskPath, 0)
}
);

Taskbar.JumpList.RefreshTaskbarList();

/82
加入自訂類別
CustomCategory category1 = new
CustomCategory(" 分類 #1");
CustomCategory category2 = new
CustomCategory(" 分類 #2");

Taskbar.JumpList.CustomCategories.Add(category1
);
Taskbar.JumpList.CustomCategories.Add(category2
);

/82
在自訂類別中加入自訂連結
category1.JumpListItems.Add(
new JumpListLink() {
Title = " 開啓記事本 ",
Path = taskPath,
IconReference = new
IconReference(taskPath, 0)
}
);

Taskbar.JumpList.RefreshTaskbarList();

/82
在自訂類別中加入自訂項目
l 在執行以下程式之前,必須要在
Registry 中註冊程式與副檔名的對應
category2.JumpListItems.Add(
new JumpListItem("c:\\data\\demo.txt")
);

Taskbar.JumpList.RefreshTaskbarList();

/82
註冊程式與副檔名的對應

/82
工作列文件與工作清單

/82
即時視窗預覽縮圖
l Windows Vista: 每 個視窗一個
l Windows 7: 使用縮圖群組

/82
明確顯示部份內容
l 與其顯示整個畫面,但是卻不清楚
l 不如只顯示其中最重要的部份

/82
設定工作列縮圖
// 設定縮圖來源區塊
Taskbar.TabbedThumbnail.SetThumbnailClip(
this.Handle,
new Rectangle(
pictureBox1.Location, pictureBox1.Size
)
);

/82
工作列縮圖

/82
MDI / TDI 視窗切換器

/82
設定分頁縮圖
void UpdatePreviewBitmap(TabPage tabPage) {
if (tabPage != null) {
TabbedThumbnailPreview preview =

Taskbar.TabbedThumbnail.GetThumbnailPreview(ta
bPage);

if (preview != null) {
Bitmap bitmap =
ScreenCapture.GrabWindowBitmap(
tabPage.Handle, tabPage.Size);
preview.SetImage(bitmap);
}
}
/82 }
分頁事件
l Taskbar.TabbedThumbnail 的事件
Ø TabbedThumbnailClosed
Ø TabbedThumbnailActivated
Ø TabbedThumbnailMaximized
Ø TabbedThumbnailMinimized
Taskbar.TabbedThumbnail.TabbedThumbnailClosed
+=
new
EventHandler<TabbedThumbnailEventArgs>(
TabbedThumbnail_TabbedThumbnailClosed
);
/82
縮圖工具列
l 允許直接在工作列上操作應用程式

/82
定義縮圖工具列按鈕
ThumbnailButton thumbButtonBack =
new ThumbnailButton(
Properties.Resources.prevArrow, "Back“
);

thumbButtonForward.Click += new
EventHandler(thumbButtonForward_Click);

Taskbar.ThumbnailToolbars.AddButtons(
newTab.Handle,
thumbButtonBack,
thumbButtonForward,
thumbButtonRefresh
);
/82
分頁縮圖與縮圖工具列

/82
大綱
l 工作列程式設計
l ExplorerBrowser 控制項與通用檔案對
話方塊
l 媒體櫃與搜尋連接器設計
l 如何用 .NET 程式控制 Windows 7
電源管理
l 繪圖 -- Direct2D 、 DirectWrite
l 應用程式如何支援重新啓動與自我修復功能

/82
ExplorerBrowser 控制項

explorerBrowser1.Navigate(

ShellFolder.FromParsingName("C:\\Windows\\Syste
m32")
/82
/82
KnownFolder

// Windows Form
explorerBrowser1.Navigate(
KnownFolders.Games as ShellObject );

// WPF
explorerBrowser1.NavigationTarget =
KnownFolders.Games as ShellObject;
/82
ExplorerBrowser 控制項

CommonOpenFileDialog dialog = new


CommonOpenFileDialog();
dialog.FoldersOnly = true;
if (dialog.ShowDialog().Canceled == false)
/82 txtPath.Text =
ExplorerBrowser 與新 案對話
方塊
ExplorerBrowser – WinForm
ExplorerBrowser – WPF
已知資料夾瀏覽
樹狀瀏覽
/82
取得檔案屬性

IShellProperty prop =
ShellObject.FromParsingName(fileName)

.Properties.GetProperty(propertyName);

string value = prop.ValueAsObject == null ? "" :

prop.FormatForDisplay(PropertyDescriptionFormat.
/82
設定檔案屬性

IShellProperty prop =
ShellObject.FromParsingName(fileName)

.Properties.GetProperty(propertyName);

if (prop.ValueType == typeof(short?))
{
(prop as ShellProperty<short?>).Value =
/82 short.Parse(value);
案屬性編輯

/82
大綱
l 工作列程式設計
l ExplorerBrowser 控制項與通用檔案對
話方塊
l 媒體櫃與搜尋連接器設計
l 如何用 .NET 程式控制 Windows 7
電源管理
l 繪圖 -- Direct2D 、 DirectWrite
l 應用程式如何支援重新啓動與自我修復功能

/82
媒體櫃概觀
l 在之前的 Windows 中,使用者將檔案
儲存在已知路徑的資料夾中,
Ø 文件夾、…
l 至少有兩個資料夾
路徑
Ø 個人資料夾
Ø 公用資料夾

/82
媒體櫃的定義

“ 媒體櫃是一個集合、
集中包含了來自不同位
置的文件,使用者可以
透過媒體櫃來組織尋找
文件。”
/82
媒體櫃管理介面

/82
媒體櫃定義檔
l XML 檔案格式
l 副檔名為 .library-ms
l 位於以下路徑中
Ø C:\Users\[UserName]\AppData\Roa
ming\Microsoft\Windows\Libraries

/82
/82
建立媒體櫃
// 建立新的媒體櫃
ShellLibrary library = new ShellLibrary("Hello",
true);
library.Add(@"D:\MP3");
library.Add(@"D:\Source");
library.Close();

// 編輯媒體櫃
ShellLibrary lib = ShellLibrary.Load("Hello", false);
lib.Remove(@"D:\MP3");
lib.Add(@"D:\Drivers");
lib.Close();

/82
媒體櫃選取

/82
搜尋連接器
跨多重來源的搜尋

SharePoi
nt
文件庫

企業資料來源

企業應用程 多重搜尋來源

/82
搜尋連接器運作機制
l 豐富的搜尋經驗
Ø 預覽、 metadata 、拖曳
Ø 檔案總管的操作方式
l 簡單、輕量化整合
Ø 不需要安裝任何用戶端程式碼 2. Windows 透過
HTTP
Ø 支援任何平台 傳送搜尋要求
1. 安裝搜尋連接器
l 支援相關標準 (.osdx)

Ø OpenSearch 1.1
Ø RSS, ATOM 3. 伺服器傳回 RSS

l
/82 身份驗證
Open Search .osdx 檔格

<?xml version="1.0" encoding="UTF-8"?>
<OpenSearchDescription xmlns="http://a9.com/-
/spec/opensearch/1.1/" xmlns:ms-ose=

"http://schemas.microsoft.com/opensearchext/200
9/">
<ShortName>Technet</ShortName>
<Description>OpenSearch for
Technet</Description>
<Url type="application/rss+xml“

template="http://social.technet.microsoft.com/Sea
rch/
Feed.aspx?
/82
搜尋連接器

/82
大綱
l 工作列程式設計
l ExplorerBrowser 控制項與通用檔案對
話方塊
l 媒體櫃與搜尋連接器設計
l 如何用 .NET 程式控制 Windows 7
電源管理
l 繪圖 -- Direct2D 、 DirectWrite
l 應用程式如何支援重新啓動與自我修復功能

/82
節省 CPU 電力
電力狀態讀取
l 避免讀取電腦電力狀態 – 使用事件
l 每秒鐘不取得超過一次的電源狀態
l 不直接取得電源狀態
Ø RegisterPowerSettingNotification
l 使用聯合計數器 (coalescing timers)
Ø 呼叫 SetWaitableTimerEx ( 含 delay
tolerance 參數 )
計數器週期
15.6 ms
Vista
週期性
計數器事件

Windows 7
/82
電力設定通知
PowerManager.PowerSourceChanged +=
delegate {
// 使用 PowerManager.PowerSource
};

/* 其它 PowerManager 方法 / 屬性 :
PowerManager.IsBatteryPresent
PowerManager.BatteryLifePercent
… 等等 */

/82
聯合計數器 (Coalescing
Timer)
CoalescingTimer t =
new CoalescingTimer("Name");
t.Tick += delegate { ... };

//Due time, period, reason, delay


t.Set(0, 1000, "Reason", 50);

/82
節省 CPU 電力
多媒體計數器
l 多媒體計數器可以透過修改計數器間格來
達到更好的效能
Ø 在多處理器上預設是 : 15.6ms
Ø 視需要調整,可以調到 1ms 、甚至更小
l 建議不要低於 10ms
Ø 否則會嚴重耗損電力
Ø 尤其是使用電池供電時

/82
節省 CPU 電力
動畫處理
l 動畫會加重 CPU 和 GPU 的電力使用
l 在系統閒置時避免動畫處理
Ø 通知區域的圖示動畫
Ø Flash 撥放器就算最小化,一樣會使用
CPU
l 當電源計劃啓用、而且是使用電池供電時
停用所有動畫

/82
節省硬 電力
l 空轉的硬碟會浪費將近 8% 的電力
l 在系統閒置時
Ø 避免週期性的磁碟存取
Ø 避免系統登錄 (registry) 的存取
l 最佳範例
Ø Office Word 2007 每隔 5~15 分鐘自
動存檔一次
Ø 如果文件沒有任何變動,就不會進行儲存

/82
背景活動
l 將工作使用背景服務來處理
l 背景活動 ( 工作、服務 ) 可以依照不同環
境進行排程
Ø 有 AC 電源時才啓動工作
Ø 檔使用電池時就暫停工作
Ø 有需要服務時才去啓動服務

l 請參閱 “ Background Services” 投


影片

/82
不要防礙電源轉移
l 如果使用者觸發睡眠模式
Ø 任何程式都不能阻止進入睡眠模式
Ø 停止任何硬體動作 ( 網路傳輸、檔案複製、
…)
l 從睡眠模式還原時 :
Ø 恢復相關變動 ( 網路 )
Ø 所有應用程式同時恢復 ( 可能會有資源瓶頸 )
l 在系統啓動與關機時,使用相同的準則
Ø 包含休眠 / 復原

/82
電力可用性要求
l 應用程式可以延遲自動睡眠
Ø 例如 : 正在下載檔案、錄製電視節目、燒錄
光碟
Ø 呼叫舊的 API:
SetThreadExecutionState

l Windows 7 使用新的 API:


Ø PowerCreateRequest
§ 參數中多了延遲的原因
Ø IT 人員可以透過以下指令取得相關資訊 :
§ powercfg.exe /requests
/82
電力可用性要求
Managed Code

PowerAvailability.CreateRequest(
"My Reason",

PowerRequestType.DisplayReq
uired);

/82
電力使用效率診斷
l Windows 效能計數器
l Windows Performance Toolkit
(xperf)
l 在 Windows 7 中可以產生電力使用效
率報表
Ø powercfg.exe /energy
Ø 系統閒置時會自動執行,並回報給微軟 CEIP
(Customer Experience
Improvement Program)

/82
電源管理

/82
大綱
l 工作列程式設計
l ExplorerBrowser 控制項與通用檔案對
話方塊
l 媒體櫃與搜尋連接器設計
l 如何用 .NET 程式控制 Windows 7
電源管理
l 繪圖 -- Direct2D 、 DirectWrite
l 應用程式如何支援重新啓動與自我修復功能

/82
Windows 7 繪圖平台
Applications
Windows
Taskbar 3rd party
Paint

Frameworks
Ribbon Animation WPF

原生平台

/82
Windows 7 Graphic Platform
Overview Dire
Direc DW ct WIC
t2D M Writ
e
Dire DX
Direct3D 10 ct3 GDI+
VA
D 11
D
DXGI irec U
t3D GDI
SER
9
DXGKernel Win32K

Windows 7 新增
Windows Vista

/82
Direct2D 架構

Application Application

Direct2D
Direct3D Software
DXGI rasterizer

/82
Windows 7 繪圖 API 整

Windows Windows
//DX Code Vista 7
CreateRenderTarg
et()
Draw()
Present()
Copy
1
Copy
// GDI Code 2
GetDC()
DrawLine()
ReleaseDC()

/82
Direct2D 與 Direct3D
整合
l 使用 Direct3D 10 或 10Level9
裝置
l 對應 D3D 平面到 D2D render
target
Ø CreateDxgiSurfaceRenderTar
get()
l 在呼叫之前 Present() 呼叫
EndDraw()

l 在任何硬體組態設定下都可以運作
/82
Direct2D 繪圖
D2DFactory d2dFactory =
D2DFactory.CreateFactory(D2DFactoryType.SingleT
hreaded);

SizeU size = new


SizeU((uint)renderControl.ClientSize.Width,
(uint)renderControl.ClientSize.Height);
RenderTargetProperties props = new
RenderTargetProperties();
HwndRenderTargetProperties hwndProps = new

HwndRenderTargetProperties(renderControl.Handl
e,
size, PresentOptions.None);
/82 HwndRenderTarget renderTarget =
Direct2D 繪圖
Point2F p1 = new Point2F(10, 10);
Point2F p2 = new Point2F(400, 300);
Brush b = renderTarget.CreateSolidColorBrush(
new ColorF(0, 0, 0, 1));

renderTarget.BeginDraw();
renderTarget.Clear(new ColorF(1, 1, 1, 0));
renderTarget.DrawLine(p1, p2, b, 2);
renderTarget.EndDraw();

/82
Text Positioning
l Can start glyphs at a sub-pixel boundary
Ø 在字母之間 Enables more even spacing between
glyphs
Ø Smoother scrolling and text rotation

/82
ClearType
在 GDI 中
ClearTyp
e 只能用
在 X 方向

DirectWri
te 可以同
時用在 X
和 Y 兩個
方向

/82
DirectWrite
DWriteFactory dwriteFactory =
DWriteFactory.CreateFactory();

SizeU size = new


SizeU((uint)renderControl.ClientSize.Width,
(uint)renderControl.ClientSize.Height);
RenderTargetProperties props = new
RenderTargetProperties();
HwndRenderTargetProperties hwndProps = new

HwndRenderTargetProperties(renderControl.Handl
e,
size, PresentOptions.None);
HwndRenderTarget renderTarget =
/82 d2dFactory.CreateHwndRenderTarget(props,
DirectWrite
TextFormat textFormat =
dwriteFactory.CreateTextFormat(
“Arial”, 24, FontWeight.Bold,
FontStyle.Italic,
FontStretch.Normal, "");
TextLayout textLayout =
dwriteFactory.CreateTextLayout(
“Hello”, textFormat, 100, 100);
Point2F p = new Point2F(10, 10);
Brush b = renderTarget.CreateSolidColorBrush(
new ColorF(0, 0, 0, 1));

renderTarget.BeginDraw();
renderTarget.Clear(new ColorF(1, 1, 1, 0));
/82 renderTarget.DrawTextLayout(p, textLayout, b);
Direct2D & DirectWrite

/82
大綱
l 工作列程式設計
l ExplorerBrowser 控制項與通用檔案對
話方塊
l 媒體櫃與搜尋連接器設計
l 如何用 .NET 程式控制 Windows 7
電源管理
l 繪圖 -- Direct2D 、 DirectWrite
l 應用程式如何支援重新啓動與自我修復功能

/82
重新啓動與自我修復
l 當應用程式當掉時, Windows 7 的
WER (Windows Error Reporting
Service) 會進行錯誤回報,並檢查可用的
解決方案

/82
重新啓動與自我修復
l 應用程式可以事先向 WER 註冊,以便由
WER 來重新啓動應用程式

/82
註冊自我修復
private void RegisterForRecovery()
{
// 設定應用程式當掉之前,
// WER 要呼叫 RecoveryProcedure
RecoveryData data = new RecoveryData(
new RecoveryCallback(RecoveryProcedure),
null);

RecoverySettings settings = new


RecoverySettings(data, 0);

ApplicationRestartRecoveryManager.
RegisterForApplicationRecovery(settings);
}
/82
註冊自我修復
private int RecoveryProcedure(object state)
{
PingSystem();

// 儲存將來要復原用的資料
// ….

ApplicationRestartRecoveryManager.
ApplicationRecoveryFinished(true);
return 0;
}

/82
註冊自我修復
private void PingSystem()
{
// 檢查使用者是否取消重新啓動
bool isCanceled =
ApplicationRestartRecoveryManager.
ApplicationRecoveryInProgress();

if (isCanceled)
{
Environment.Exit(2);
}
}

/82
註冊重新啓動
l 讓 WER 知道要帶什麼參數來重新啓動
應用程式,例如 /restart
l 指定例外狀況,例如重新開機、應用程
式修正時不要重新啓動應用程式

ApplicationRestartRecoveryManager.
RegisterForApplicationRestart(
new RestartSettings("/restart",
RestartRestrictions.NotOnReboot |
RestartRestrictions.NotOnPatch)
);

/82
註冊重新啓動
l 應用程式一開始必須檢查是否有帶
/restart 參數,如果有代表是 WER
呼叫
l 進行修復動作,例如將當掉之前的檔案
載入
if
(System.Environment.GetCommandLineArgs().Len
gth > 1 &&

System.Environment.GetCommandLineArgs()[1]
== "/restart")
{
RecoverLastSession(
/82
重新啓動與自我修復

/82
總結
l Windows API Code Pack for Microsoft
.NET Framework
Ø 簡化 .NET 應用程式與 Windows 7 新功能整合的
工作
Ø 底層仍是 COM 元件或作業系統 API 呼叫
Ø 應用程式要自行檢查目前的環境是不是 Windows 7
l 預告 – Tech Days 2009 9/22~9/24
Ø Windows 7 多點觸控應用程式設計入門
Ø 新世代的 Windows 與 Web 應用程式開
發 -- WPF 4.0
/82
相關資訊
l 聖哥的資訊站
Ø http://teacher.syset.com
l MSDN
Ø http://www.microsoft.com/msdn
Ø http://www.microsoft.com/taiwan/msd
n
l Windows 7 API Code Pack
Ø http://code.msdn.microsoft.com/Wind
owsAPICodePack
/82
© 2001 Microsoft Corporation. All rights reserved.
/82

You might also like