预览软件 窗口“排排坐”

技术与开发

魏伟,微软MVP(微软最有价值专家),产品设计&系统架构师,研发的产品主要有电话会议服务、移动代理服务器、无线开发中间件等。

用户打开10多个网页时,可以在任务栏上通过窗口分组预览功能快速查看每一个网页的内容,甚至在预览窗口中可以直接关闭网页。酷毙了!其实这个功能不仅浏览器等大软件可以用,我们个人开发的部分小软件也可以用(见图)。

45-f10-1-2.jpg

在软件中添加窗口分组预览代码(代码下载地址:http://www.shudoo.com/bzsoft),只要软件支持微软的Framework,就可以直接使用代码。有了这个功能,我们的软件就跟浏览器、QQ等软件一样引人注目了。

分组预览的奥秘

软件要想牵手Win7的窗口分组预览功能,可不是一个简单的事情,要编辑默认缩略图、自定义缩略图、让应用程序拥有更多的缩略图、让缩略图动起来、增加缩略图的自定义工具按钮,要做这些功能,就必须用到Win7相关的API。

与预览窗口开发有关的API主要分为缩略图、缩略图工具栏、屏幕截图三种类型。

缩略图相关API最重要的是TabbedThumbnail类和TabbedThumbnailManager类。在编写Win7应用程序时,必然要定义一些非系统默认的缩略图,数量也不仅仅限于一张。使用这两个类可实现修改系统默认缩略图、添加及删除缩略图等。

有些应用程序可使用这两个类完成全新的缩略图功能,例如一个自动更新程序,需要启动多线程下载多个任务,应用程序可为每一个下载任务创建一个缩略图,当下载任务完成后,对缩略图排序,将最先完成的任务的缩略图排在第一位,也可以对缩略图进行一些图片特效处理,比如将失败的下载任务的缩略图变为灰色。

缩略图工具栏相关API最重要的当然是ThumbnailToolbarButton。如果仅仅包含了缩略图功能,只能向用户报告最新的程序运行情况和界面截图,而在预览窗口中加入工具栏,就可以给用户提供额外的操作。

例如一个邮件提醒程序,当有新邮件到达时,可以看到新邮件标题和发件人的缩略图,常规操作是激活这个程序,然后进入收件箱,打开邮件正文查看。如果在预览窗口的工具栏中增加一个查看邮件的按钮,在按钮的点击事件中加入查看这封邮件正文的代码,就可以为用户省去繁琐的步骤。屏幕截图相关API是TabbedThumbnailScreenCapture,除了能对指定窗体或控件截图外,还可以选择截图范围。

分组预览代码出炉

第一步:创建缩略图

要让我们的软件使用窗口分组预览的功能,先要实现缩略图的功能,这需要引用Microsoft.WindowsAPICodePack和Microsoft.WindowsAPICodePack.Shell,在软件中输入以下代码:

private void Form1_Load(object sender, EventArgs e)

{

Bitmap bm = new Bitmap("d:\\1.jpg"); //请修改为正确的图片路径

pictureBox1.Image = bm;

GraphicsUnit bmGU = GraphicsUnit.Pixel;

RectangleF rectF = bm.GetBounds(ref bmGU);

pictureBox1.SetBounds(0, this.button1.Height, (int)rectF.Width, (int)rectF.Height); //让pictureBox1随图片大小变化

}

代码中的pictureBox1,是程序的主功能,1.jpg是程序的图标,可根据实际情况修改。

第二步:自定义缩略图

我们要窗口分组预览,就要改动默认缩略图的格式,需要在软件的Form1中增加一个button,名为button2,在button2的click事件中添加代码,其中关键代码如下所示(完整代码下载地址:http://www.shudoo.com/bzsoft):

if (!TaskbarManager.IsPlatformSupported)

{

MessageBox.Show("你的操作系统不支持任务栏预览");

}

else

{

//判断缩略图中是不是已经包含pictureBox1的缩略图,如果有,则清除。

TabbedThumbnail preview = TaskbarManager.Instance.TabbedThumbnail.GetThumbnailPreview(this.pictureBox1);

if (preview != null) {

TaskbarManager.Instance.TabbedThumbnail.RemoveThumbnailPreview(preview);

}

第三步:分组预览缩略图

现在我们的软件可以自定义多个缩略图,进行分组预览了。在Form1中增加一个button,名为button3。在button3的click事件中添加代码,其中关键代码如下所示(完整代码下载地址:http://www.shudoo.com/bzsoft):

if (!TaskbarManager.IsPlatformSupported)

{

MessageBox.Show(“你的操作系统不支持任务栏预览”);

}

else

{

TabbedThumbnail preview = TaskbarManager.Instance.TabbedThumbnail.GetThumbnailPreview(this.button2);

if (preview != null) {

TaskbarManager.Instance.TabbedThumbnail.RemoveThumbnailPreview(preview);

}

preview = new TabbedThumbnail(this.Handle, this.button2);//一个control只能有一个缩略图,为了不和前面几步的操作冲突,这里我们选择了为button2生成缩略图。

第四步:即时效果的预览窗口

如果软件执行一个耗时的命令,我们会发现缩略图是静止不变的,我们必须将鼠标移走,重新悬浮,才可以看到最新软件界面的缩略图,那么,如何得到即时效果的缩略图呢?用一个Timer来控制图片的定时轮换,来代替程序界面的更新。在Form1中添加一个button,名为button4,在button4的click事件中添加以下代码:

timer1.Enabled = ! timer1.Enabled;//将button4设置成了一个开关,点击一次开启timer,再点击一次关闭timer

在Form1中添加一个Timer,名为Timer1,将属性中Interval设置为1000(毫秒),Enabled设为false,在Timer1的Tick事件中加入代码,其中关键代码如下所示(完整代码下载地址:http://www.shudoo.com/bzsoft):

if (preview != null)

{

if (preview.Title.Equals("图片一"))

{

//如果是图片一,就将缩略图换为图片二

preview.Title = "图片二";

preview.SetImage(new Bitmap("d:\\2.jpg"));

}

else

{

preview.Title = "图片一";

preview.SetImage(new Bitmap("d:\\1.jpg"));

第五步:在缩略图中增加按钮

在缩略图中直接点击按钮,就跟点击应用程序的按钮一样,这个功能是不是很酷?在Form1中添加一个button,名为button5,在button5的click事件中加入代码,其中关键代码如下所示(完整代码下载地址:http://www.shudoo.com/bzsoft):

ThumbnailToolbarButton ttb = new ThumbnailToolbarButton(this.Icon,"动态缩略图");

ttb.Enabled = true;

ttb.Click += new EventHandler(button4_Click);//将工具按钮的click事件绑定到button4的click事件

TaskbarManager.Instance.ThumbnailToolbars.AddButtons(Handle, ttb);

小编救急

在讲解手机编程时,小编建立了很多开发QQ群,有许多读者朋友在里面交流,其中谈论得较多的是开发过程中碰到的各种问题。为此,小编特意开辟了一个救急板块,无论你开发哪种程序,无论你碰到什么问题,我们都可以给你提供帮助。来信请发到pcw-chendx@vip.sina.com。

关键词:取消“关闭”按钮

读者来信:我是一名计算机专业的老师,时常用VB制作练习题发给学生做,由于在VB中创建的应用程序窗口都有“关闭”按钮,在操作时不小心就关闭了该试题窗口,老有学生向我抱怨。我想问问怎么才能在创建的应用程序窗体中取消“关闭”按钮?

小编:感觉你的学生是在找借口,哈哈!可以使用下面的方法来取消窗体(如Form1)中“关闭”按钮的显示(如果要关闭该程序可按“Alt+F4”组合键)。首先在窗体Form1的“通用模块”中声明下面的过程:

Public lpPrevWndProc As Long

Private lngHWnd As Long

Private Declare Function DeleteMenu Lib "user32" (ByVal hMenu As Long, ByVal nPosition As Long, ByVal wFlags As Long) As Long

Private Declare Function ModifyMenu Lib "user32" Alias "ModifyMenuA" (ByVal hMenu As Long, ByVal nPosition As Long, ByVal wFlags As Long, ByVal wIDNewItem As Long, ByVal lpString As String) As Long

然后在当前窗体的Load事件中输入下面的代码:

Private Sub Form_Load()

DeleteMenu GetSystemMenu(Me.hWnd, 0), &HF060&, 0

End Sub

保存后运行该程序,窗体中的“关闭”按钮就被禁用了。

关键词:中文表头

开发QQ群:我在用Delphi数据库时,需要在窗体上添加一个表格用于显示数据记录,可是由于数据库字段的名称定义为英文,在窗体上添加表格DBGrid并连接数据源时表头是数据库中定义的英文字段名,这样看起来很不爽,请问可以把窗体上表格的表头做成中文字段名吗?

小编:有多种方法可以换中文表头,我给你介绍一种简捷的方法: 双击DBGrid控件,弹出一个对话框,点击“Add All Fields”按钮,把字段名添加进来,再点击第一个字段,在属性页中,选择Title的Caption属性,修改标题为“中文1”,依次选择各个字段,修改Title的Caption属性为中文就可以了。