每周源代码45-在Win7 *和*WinXP 上点击按钮


[原文发表地址]The Weekly Source Code 45 - Kicking Butt on Windows 7 *and* Windows XP

[原文发表时间]2009-08-31 06:53 PM

clip_image002

我真的建议大家尽可能多读一些源代码,因为能读得像写的一样多的话,你将会成为更好的代码书写者。这是每周源代码的宗旨——读代码以便成为更好的开发者。

现在正在举行一个很酷的开发者竞赛活动,叫"Code7"。如果你在现在到十月七号之间编写一个Windows 7的应用程序,你就可能会赢得巨额奖金和/或者参加PDC(译者注:专业开发人员大会)的一次机会。

Windows 7中有很多新的API(以及现在已经存在的有用的Vista API),像下面这些:

* Windows 7 Taskbar Integration

* Transactional File System

* I/O Optimization

* Event Tracing for Windows (ETW)

* Windows 7 Libraries

* Windows 7 Sensor and Location Platform

* Aero Glass

在其中的一些实际使用的例子中,(还)没有针对像环境光感应器(Ambient Light Sensors)这些东西的硬件。有人已经能把网络摄像头关联到Windows 7 Sensors API,并用新的显示器配置 API*做了一个程序使其显示器变成黑屏。他甚至可以让它在他离开的时候关掉机器。

XP2Win7 - Windows 7样本代码/应用程序

我已经找出一些可以作为Win7起步学习的应用程序示例。目前为止最好的是“PhotoView”。不要惊于它是YAPA(另外一个图片程序)的事实,可以把它当作一个松散耦合的示例集和。

clip_image004

该程序很好的地方是它可以在Windows XPWindows Vista Windows 7上运行。这对你来说可能是显而易见的甚至很傻的陈述,但是亲爱的读者,值得着重指出的是应用程序在三个平台上运行得都很棒。我使用的程序99%在Win7上工作很好。当然,需要更新一些驱动和古怪的VPN(译者注: 虚拟专用网络),但是令我感到欣慰的是,我知道可以编写一个Windows程序,嗯,它可以运行在所有Windows平台上。J

这个PhotoView应用程序(也叫XP2Win7是用托管代码编写,用插件“在更高级平台上自动照亮(light up on up-level platforms)”。这是幽默的Microsoft 说法,意思是如果你的操作系统有个功能,程序会检测并使用该功能。

有个不错的概述Word文档,解释该程序以及它是如何编写的。MSI会安装程序,如果你找不到,它的源代码根据需要安装在~\MyDocuments\Xp2Win7目录下。如果你想编译几个部分的话,你需要Visual C++……读一下readme文件。这是个很好的非常广义的示例,示范了如何制作MMC 报告查看器、snapins、延迟服务、注册计划任务、堆。

(不幸的是,编写这个的人没有将MEF用于他们的插件模型,但我会跟他们交谈。这会让他们可以删除很多没用的样本插件代码。)

它用Windows API Code Pack(下面会谈到)来做很多工作。这里是一些有趣的部分。

任务栏弹出列表

如果程序在Win7下运行,当你在任务栏按钮右击(或刷一下)时,会出现一个”jumplists”。

image

用Taskbar API这个很容易添加。请注意多个分类目录、用户任务、最近项目以及自定义类别。

 1: Taskbar.JumpList.CustomCategories.Clear();

 2: Taskbar.JumpList.UserTasks.Clear();

 3: Taskbar.JumpList.KnownCategoryToDisplay = KnownCategoryType.Recent;

 4: 

 5: CustomCategory allAlbumsCategory = new CustomCategory("All Albums");

 6: //...snip out enumerating of the filesystem to get photo albums

 7: Taskbar.JumpList.CustomCategories.Add(allAlbumsCategory);

 8: 

 9: Taskbar.JumpList.UserTasks.Add(

 10: new JumpListLink()

 11: {

 12: Title = "Reset configuration",

 13: Path = typeof(XP2Win7.VistaPlugins.ConfigurationResetter.Program).Assembly.Location,

 14: Arguments = XP2Win7.VistaPlugins.ConfigurationResetter.Program.ResetCommand

 15: });

 16: Taskbar.JumpList.UserTasks.Add(

 17: new JumpListLink

 18: {

 19: Title = "Launch indexing task",

 20: Path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Constants.ServiceCommandLine),

 21: Arguments = Constants.ServiceAsTaskCommandLine

 22: });

 23: Taskbar.JumpList.UserTasks.Add(

 24: new JumpListLink { Title = "Open albums directory", Path = Host.UserConfiguration.AlbumRepositoryPath });

 25: 

 26: Taskbar.JumpList.RefreshTaskbarList();

Windows 7 Libraries

你也可以为你的程序添加Windows 7 Libraries。

 1: //Create new shell library under the default Libraries

 2: using (ShellLibrary library = new ShellLibrary("XP2Win7", true))

 3: {

 4: library.LibraryType = LibraryFolderType.Pictures;

 5: library.IconResourceId = GetPictureLibraryIcon(); //Set the same Icon as the Picture library

 6: library.IsPinnedToNavigationPane = true;

 7: 

 8: 

 9: foreach (string folderPath in GetPicturesFolders())

 10: {

 11: library.Add(folderPath);

 12: }

 13: 

 14: library.ShowManageLibraryUI(Application.Current.MainWindow,

 15: "Manage the XP2Win7 library", "You can manualy add or remove folders",

 16: true);

 17: }

用户访问控制(UAC

Windows Vista 和 Windows 7都包含用户访问控制(UAC)。你会注意到一个按钮旁的小盾牌图标,在下面的对话框中该按钮需要来自用户的响应。

Application reconfiguration

他们的程序在几个地方用到这个。首先,我们可以显示下小盾牌图标吗?我们只有在UAC启用的时候才会这么做。

 1: protected override BitmapSource BitmapSource

 2: {

 3: get

 4: {

 5: if (UacHelpers.UserAccountControl.IsUacEnabled)

 6: {

 7: return Microsoft.SDK.Samples.VistaBridge.Library.StockIcons.StockIcons.Shield;

 8: }

 9: else

 10: {

 11: return ImageFromResource(Assembly.GetExecutingAssembly(), 

 12: "UserAccountControl.StartService-128x128.png");

 13: }

 14: }

 15: }

然后,如果他们确实点击按钮,我们想要以管理员的身份启动一些进程时,我们需要调动一个特殊的API来完成。这意味着通过辅助API很容易实现。

 1: if (UacHelpers.UserAccountControl.IsUacEnabled || !UacHelpers.UserAccountControl.IsUserAdmin)

 2: {

 3: UacHelpers.UserAccountControl.CreateProcessAsAdmin(

 4: typeof(ServiceStarter.Program).Assembly.Location, "XP2Win7ImageDataService");

 5: }

 6: else

 7: {

 8: Process.Start(typeof(ServiceStarter.Program).Assembly.Location, "XP2Win7ImageDataService");

 9: }

非常灵活,易于编码。Windows API Code Pack让所有这些以及其它很多APIs对托管代码开发者(C#, VB以及其他任何人)来说更简单。

Windows API Code Pack

另一个不错的Windows示例代码包是Windows API Code Pack. 是个示例金矿,都是用C#VB编写。大约有20多个示例。这里是其中的几个示例。

电源管理

如果你的程序知道机器当前的电源状态,避免在用电池的时候做一些疯狂的事情,这是很棒的。

Power Management

你可以获取所有种类的很棒的与电量有关的信息。

 1: private void GetPowerSettings()

 2: {

 3: settings.PowerPersonality = PowerManager.PowerPersonality.ToString();

 4: settings.PowerSource = PowerManager.PowerSource.ToString();

 5: settings.BatteryPresent = PowerManager.IsBatteryPresent;

 6: settings.UpsPresent = PowerManager.IsUpsPresent;

 7: settings.MonitorOn = PowerManager.IsMonitorOn;

 8: settings.MonitorRequired = PowerManager.MonitorRequired;

 9: 

 10: if (PowerManager.IsBatteryPresent)

 11: {

 12: settings.BatteryShortTerm = PowerManager.IsBatteryShortTerm;

 13: settings.BatteryLifePercent = PowerManager.BatteryLifePercent;

 14: 

 15: BatteryState batteryState = PowerManager.GetCurrentBatteryState();

 16: 

 17: string batteryStateStr = string.Format(

 18: "ACOnline: {1}{0}Max Charge: {2} mWh{0}Current Charge: {3} mWh{0}Discharge Rate: {4} {0}Estimated Time Remaining: {5}{0}Suggested Critical Battery Charge: {6} mWh{0}Suggested Battery Warning Charge: {7} mWh{0}",

 19: Environment.NewLine, 

 20: batteryState.ACOnline, 

 21: batteryState.MaxCharge, 

 22: batteryState.CurrentCharge, 

 23: batteryState.ACOnline == true ? "N/A" : batteryState.DischargeRate.ToString() + " mWh", 

 24: batteryState.ACOnline == true ? "N/A" : batteryState.EstimatedTimeRemaining.ToString(), 

 25: batteryState.SuggestedCriticalBatteryCharge, 

 26: batteryState.SuggestedBatteryWarningCharge

 27: );

 28: 

 29: settings.BatteryState = batteryStateStr;

 30: }

 31: }

也可能被告知很多与电源有关的事件

 1: PowerManager.IsMonitorOnChanged += new EventHandler(MonitorOnChanged);

 2: PowerManager.PowerPersonalityChanged += new EventHandler(

 3: PowerPersonalityChanged);

 4: PowerManager.PowerSourceChanged += new EventHandler(PowerSourceChanged);

 5: if (PowerManager.IsBatteryPresent)

 6: {

 7: PowerManager.BatteryLifePercentChanged += new EventHandler(BatteryLifePercentChanged);

 8: 

 9: // Set the label for the battery life

 10: SetLabelButtonStatus(batteryLifePercentLabel, string.Format("{0}%", PowerManager.BatteryLifePercent.ToString()));

 11: }

 12: 

 13: PowerManager.SystemBusyChanged += new EventHandler(SystemBusyChanged);

素材图标

很多人没有意识到在Windows中有一些素材图标可用,你可以通过程序访问它们。

image

这就是说如果你的BluRayRom 或 ZipFile需要素材图标,你只要向它请求就可以了。

任务栏进程

Win7 最好用的微妙功能之一就是:如果在你的程序处理某些事件时有一个进度条,你就可以在任务栏图标上显示进度。这对像文件复制等长时间运行的程序来说是很棒的。

注意这个程序中的进度条,右下方的任务栏按钮显示了这个。

image

还有一些图标/图象叠加以及其它很好的功能。更妙的是,这非常简单:

 1: // When the user changes the trackBar value,

 2: // update the progress bar in our UI as well as Taskbar

 3: progressBar1.Value = trackBar1.Value;

 4: 

 5: TaskbarManager.Instance.SetProgressValue(trackBar1.Value, 100);

因为程序可以有多个进度条,你不得不手动决定你想让任务栏上的进度显示哪一个。

核心辅助函数

最后,有些不错的“CoreHelpers”让你的程序易于阅读,并可以同时在XP, Vista 和Win7上运行。

 1: //example

 2: if (CoreHelpers.RunningOnXP()) { ... } 

 3: //example

 4: if (CoreHelpers.ThrowifNotWin7() { ... } 

 5: // and all the others you'd expect for XP, Vista, Win7

我只涉及到了这些示例的表面。如果你在做Windows 客户端开发,一定要查看http://windowsclient.net/http://www.msdn.com/windows以了解更多,并开始为https://www.code7contest.com编写你的程序。

1. 获取 Windows 7 SDK

* Windows SDK

2. 开发测试你的应用程序

* 获取 Windows API 代码包

* 了解 应用程序兼容性

* 阅读 Windows 7 应用程序质量清单

* 下载 针对开发人员的indows 7 教材

3. 获取 Windows 7 徽标

* 了解 保证程序

* 获取 Windows 7徽标

4. Windows 7点亮你的应用程序

* 阅读 Windows 7 开发者指南

* 理解怎样 开发Windows 7

Comments (0)

Skip to main content