上次在SideShow Gadget開發[1]中介紹了本地Gadget的開發,現在介紹一下常規Gadget的開發。
在介紹Gadget之前,我們先說一下我們認識上的一個誤區,很多開發人員認為常規Gadget和本地 Gadget類似,是一個.Net Micro Framework應用程序(至少是一個DLL),在連接時,由PC端把該DLL下載 到Sideshow設備上去,Sideshow主程序加載並運行該程序。我一開始也是這樣認為的,但是隨著開發的深 入,對Sideshow的運行機理也越來越了解,其實常規Gadget更像一個網頁應用,普通的網頁浏覽基於http 協議,而Gadget基於SCF(Simple Content Format,目前sideshow支持兩種協議,另一種是ICAL,在 Sideshow中不稱為通信協議,專業術語是endpoint)協議,此時的Gadget更像一個網頁,而Sideshow設備 更像一個IE客戶端。
從以上描述,你就會明白了,其實沒有什麼DLL,對於Sideshow設備來說僅有一些基於SCF格式的數據 流而已。
所以開發常規Gadget理論上不拘於什麼開發語言,只要能輸出符合SCF格式的數據流即可。不過這裡還 是推薦使用C#(或基於.NET開發平台開發語言),可以直接引用相關開發庫,非常簡單的生成符合SCF格 式的界面要素。
下面先“秀”一下我們已經開發好的圖片浏覽Gadget,然後再介紹一下是如何開發的。
1、安裝後,會在Sideshow控制面板上出現如下圖標
2、可以設置PC上要共享的圖片目錄
3、在Sideshow設備上的顯示
4、按左右鍵進行圖片浏覽
5、顯示圖片,也可以通過listbox進行選擇
下面簡單介紹一下相關代碼:
1、兩個GUIO
一個是Gadget的GUID,Sideshow管理程序通過這個GUID加載相對應的Gadget。
一個是該Gadget對應的屬性頁的GUID(在代碼中,屬性頁其實就是一個標識了GUID的控件,該控件派 生於Microsoft.SideShow.GadgetPropertyPage),Sideshow管理程序加載並顯示屬性對話框。
注意:在注冊時,一定保證VS2008或相關程序具有管理員權限,否則操作注冊表會失敗。
2、注冊代碼
GadgetRegistration.Register
(
false, //true 對全部用戶有效 false 對當 前用戶有效
GadgetId, //本gadget的ID
ScfSideShowGadget.ScfEndpointId, //內容端點,需要使用SCF
"Picture Share", //SideShow控制面板中顯示的名字
"""" + Assembly.GetEntryAssembly().Location + """", //程序所在的路徑
String.Format("""{0}"",{1}", Assembly.GetEntryAssembly().Location, - GadgetRegistration.DefaultIconResourceId), //程序圖標位置
false, //True 連接時才顯示內 容,false 不用連接也能顯示內容
GadgetCachePolicies.KeepNewest, //接收消息項的策略 KeepNewest保留最新 KeepOldest保留最老 KeepFrequentlyAccessed 保留最頻繁 KeepRecentlyAccessed保留最近以前沒有收到的消息
new Guid("9B84055E- E253-4119-8719-F684ECB9FBC1") //屬性頁ID
);
3、事件設置
YFGadget = new Microsoft.SideShow.SimpleContentFormat.ScfSideShowGadget(new Guid (GadgetEntry.Gadget_GUID));
#region Listen to SideShow Events
// Subscribe to events from the Windows SideShow platform.
YFGadget.AllDevicesRemoved += new System.EventHandler(OnAllDevicesRemoved);
YFGadget.ContentMissing += new System.EventHandler<Microsoft.SideShow.ContentMissingEventArgs> (OnContentMissing);
YFGadget.ContentNavigate += new System.EventHandler<Microsoft.SideShow.SimpleContentFormat.ContentNavigateEventArgs> (OnContentNavigate);
YFGadget.ContextMenuSelect += new System.EventHandler<Microsoft.SideShow.SimpleContentFormat.ContextMenuSelectEventArgs> (OnContextMenuSelect);
YFGadget.DeviceAdded += new System.EventHandler<Microsoft.SideShow.DeviceCapabilityEventArgs> (OnDeviceAdded);
YFGadget.DeviceRemoved += new System.EventHandler<Microsoft.SideShow.DeviceCapabilityEventArgs> (OnDeviceRemoved);
YFGadget.GadgetEnter += new System.EventHandler (OnGadgetEnter);
YFGadget.GadgetExit += new System.EventHandler (OnGadgetExit);
YFGadget.MenuSelect += new System.EventHandler<Microsoft.SideShow.SimpleContentFormat.MenuSelectEventArgs> (OnMenuSelect);
#endregion
4、傳送圖片、菜單等
//枚舉當前路徑下的所有圖片
string[] strPath = Directory.GetFiles (SharePath);
List<string> strImgPath = new List<string>();
foreach (string path in strPath)
{
if (path.Length > 3)
{
switch (path.Substring(path.Length - 3).ToLower())
{
case "jpg":
case "bmp":
case "gif":
strImgPath.Add(path);
break;
}
}
}
List<ScfElement> item = new List<ScfElement> ();
for (int i = 0; i < strImgPath.Count; i++)
{
FileInfo fi = new FileInfo(strImgPath[i]);
Bitmap bmp = new Bitmap(fi.FullName);
PageNo = i + 1;
PicNo = 10000 + i + 1;
bmp = new Bitmap (bmp, 240, (int)(240 * ((float)bmp.Height / bmp.Width)));
YFGadget.AddContent (PicNo, ImageContentTransforms.ReduceColorDepth, bmp); // | ImageContentTransforms.KeepAspectRatio| ImageContentTransforms.KeepAspectRatio
ScfElement content = Scf.Content(
PageNo,
fi.Name,
200,
Scf.Img(PicNo, ScfAlign.Center, ScfImageFit.Native, fi.Name),
Scf.Txt(ScfAlign.Center, false, Color.Black, "", "<< " + PageNo.ToString() + "/" + strImgPath.Count.ToString() + " >>"),
Scf.Btn(DeviceButton.Left, "", PageNo - 1 == 0 ? strImgPath.Count : PageNo - 1),
Scf.Btn(DeviceButton.Right, "", PageNo + 1 > strImgPath.Count ? 1 : PageNo + 1),
Scf.Btn (DeviceButton.Back, "", 100)
);
item.Add(Scf.Item (PageNo, fi.Name));
YFGadget.AddContent(content);
bmp.Dispose ();
}
YFGadget.AddContent(Scf.Menu(
100,
"Main Menu",
ScfSelectAction.Target,
item.ToArray()
));
YFGadget.AddContent(Scf.Menu(
200,
"Right Menu",
ScfSelectAction.Target,
Scf.Item(100, "主菜單")
));
由於SDK提供了相關SCF操作函數,所以我們就沒有必要寫原始的XML格式的文件了。
OK,由於網上已有一些詳細介紹Gadget編寫的文章,所以我這裡也就不啰嗦了。如有必要,可以給我 留言,我們可以進一步交流Gadget編寫技巧。