先前相关:微软将发布.NET框架库的大量源代码
在上次Blog的评论中,有人称赞道:确实,调试方便了不是一点点;这真是太cool了;很好,期待很久了!不过也有这样的评论:买一张MSDN就可以了。实际上,MSDN中并没有包含将发布的.NET Framework的源代码。
这项服务还在最后的调试阶段,很快就会对外发布。我在这个周末通过Visual Studio 2008使用了这一服务。对于.NET程序员来说,这真的是非常有助于调试,也提供了软件开发时候很有价值的参考。
为了在Visual Studio 2008中使用此服务,有以下几个要点:
- 在Debugging | General 选项中,不要选Enable Just My Code (Managed Only).
- 在Debugging | General 选项中,选择Enable source server support.
- 在Debugging | Symbols 选项中,添加Microsoft Reference源代码服务的URL。 正式的URL很快会对外发布。
首次使用时需要接受2个License:一个是symbol,另外一个是Source.
这样在调试程序的时候就可以看到.NET Framework的源代码,也可以在调试时跟进(Step into)。
比如说WinForm的Button.cs就被下载到\src\source\.net\8.0\DEVDIV\depot\DevDiv\releases\whidbey\REDBITS\ndp\fx\src\WinForms\Managed\System\WinForms\Button.cs\1\Button.cs。从文件夹的结构可以看到,.NET框架3.5下的WinForm代码实质上还是Whidbey即.NET 2.0。但的确有了一些更新。REDBITS下是.NET 3.5发布时候的代码。
即使将Winform的项目的Target Framework改成2.0或者3.0,我们一样得到上述的Button.cs. 这是因为REDBITS在安装时取代了早先2.0的程序集。
在WPF下的Button.cs被下载到\src\source\.net\8.0\WIN_WINDOWS\lh_tools_devdiv_wpf\Windows\wcp\Framework\System\Windows\Controls\Button.cs\1\Button.cs。虽然现在WPF属于DevDiv的一部分了,从这个文件夹的结构可以看到以前WPF是隶属于Windows的。
在代码的格式上,您也一定能够看出DevDiv和Windows的区别。
除了在文件中添加了几行版权声明:
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
您看到的代码与微软内部能够看到的代码是完全相同的。那些代码中的注释,还有对private或者internal members的说明,都是在此之前无法从MSDN的文档中得到的信息。
当然没有任何代码是十全十美的。我已经注意到标有HACK HACK HACK注释的代码了。
阅读代码对程序员而言是一件有趣的活动。随着Microsoft Reference源代码服务的推出,我们有更多的阅读材料了!
伴随着Visual Studio 2008的发布,微软将在Microsoft Reference License规则下发布.NET框架库的大量源代码。这意味着只要您接受了许可条款,您就可以浏览这些源代码,而且,Visual Studio 2008的Standard edition和更高版本还支持在调试时跟进(Step into).NET源码。
首批发布的源代码包括BCL (System, IO, Text, Collections, CodeDom, Regular Expression等), ASP.NET, WinForms和WPF。
更多细节,将在最近的blog中讨论,
问:在.NET框架函数库中, 是否每一个KeyDown事件都有保证一个对应的KeyUp事件?
答:不是,因为WinForm底层的Windows 32 Messages WM_KEYDOWN和WM_KEYUP并不能保证这一点,而WinForm所作的就是将其转化为对应的事件。
这一回答也适用于WPF中的对应事件。
控件System.Windows.Forms.ProcessBar只能水平显示其进度。但是其封装的Win32控件同时还支持垂直显示。以下的代码提供了实现的示例。
class ProgressBarVertical : ProgressBar
{
const int PBS_VERTICAL = 4;
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.Style |= PBS_VERTICAL;
return cp;
}
}
}
相关的MSDN文档可供参考。
PDC2005的与会者都得到了一张关于WinFX之Namespace的海报(Poster).其中列出了Windows Presentation Foundation, Windows Communication Foundation,Windows Workflow Foundation所增加的名称空间。同时列出的还有.NET框架2.0/3.0新增的和有了显著改进的名称空间。
没有参加PDC2005的你我可以在此下载该Poster。我已经将其作为Tech Ed期间的Wallpaper了。
代码示例:
private System.Windows.Forms.PictureBox pictureBox1;
this.pictureBox1.Dock = System.Windows.Forms.DockStyle.Fill;
this.pictureBox1.ImageLocation = "http://www.microsoft.com/h/en-us/i/ts_1024_25_KidsandSpyware.jpg";
this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
在WinForm 2.0下,新增加的ImageLocation属性支持文件系统或者Web上的图像位置。这使得显示一个源自万维网上图像的任务变得十分简单。
PictureBox的SizeMode属性的类型是枚举型PicturBoxSizeMode,在1.x下有Autosize, CenterImage, Normal和StretchImage四个值。WinForm 2.0中新增加了Zoom,这个模式下图像在根据PictureBox大小缩放的时候保持纵横比(aspect ratio)。
对Longhorn Client: 2006年正式发布的随笔评论中提到了这样一个问题:在FCL里面没有对多媒体功能进行必要的封装,比如说如果要喇叭发出声音靠.Net FCL是不可能的,只能自己调用Win32API。
如的评论提到,在.NET Fx 1.x下,可以通过
System.Console.WriteLine(Chr(7)) 'VB.NET
Console.WriteLine("\a"); //C#
实现beep的功能。
在.NET Fx 2.0下,Console类专门提供了Beep这个静态函数。简单的使用就是Beep();会得到与前面的方法类似的beep.但是还另外一个重载,Beep(int frequency, int duration);比如下面这句代码以2000Hz的频率发出1秒的beep.
Console.Beep(2000, 1000);
在WinForm2.0下,System.Windows.Forms.SoundPlayer 可以用来播放.Wav文件,简单举例如下:
System.Windows.Forms.SoundPlayer player = new System.Windows.Forms.SoundPlayer(@"C:\demo.wav");
player.Play();
但是SoundPlayer并不能够播放mp3或者wma文件,Play()会抛出FromatException:The file is not a valid wave file.
在Avalon下,所有Windows支持的Audio/Video文件都是可以播放的了。
贴子以"现状"提供且没有任何担保也没有授予任何权利
在周末休闲之.NET Quiz (9) 中有这样一道题目:
已知在此处可以看到Tech Ed 2003 China会场的照片一:http://www.microsoft.com/china/techED/images/a04.jpg
在一个WinForm应用程序中的用户界面包含一个Button控件btn1和PictureBox控件pictureBox1(pictureBox1的SizeMode为AutoSize)。当用户点击btn1时,其Event Handler就会读取那张照片并且在pictureBox1中显示出来。只用一行代码实现这个功能,请填空:
pictureBox1.______ = ______________________________________;
因为这里没有特别指出使用WinForm的版本号,我期待的答案是:
pictureBox1.Image = new Bitmap((new System.Net.WebClient()).OpenRead(http://www.microsoft.com/china/techED/images/a04.jpg));
Ninputer写出了:
pictureBox1.Image = Image.FromStream(System.Net.WebRequest.Create(http://www.microsoft.com/china/techED/images/a04.jpg).GetResponse().GetResponseStream());
在WinForm2.0下,一个新的property(属性)使得这一操作变得非常简单:
this.pictureBox1.ImageLocation = http://www.microsoft.com/china/techED/images/a04.jpg;
重粒子也在Quiz中提到了这一属性。在Winform Designer中对其解释是:Disk or web location to load image from.
(URL需要用引号引起来的,但是这个blog系统自动把引号去掉了。)
贴子以"现状"提供且没有任何担保也没有授予任何权利
从使用ContainerControl.ActiveControl的讨论之中,应该注意到一个控件的CanFocus和CanSelect可以是不同的。Label这样的Control,虽然CanSelect为False,其CanFocus确是可以为True的.
CanFocus: in order for a control to receive input focus, the control must have a handle assigned to it, and the Visible and Enabled properties must both be set to true.
CanSelect: This property returns true if the control has ControlStyles.Selectable set to true, is contained in another control, and all its parent controls are both visible and enabled.
System.Windows.Forms.Form继承于System.Windows.Forms.ContainerControl也就继承了public virtual Control ActiveControl {get; set;}你经常使用ActiveControl么?
假设在当前Form上有2个TextBox接受用户输入的密码。2次输入的密码必须一致,否则我们弹出一个MessageBox告诉用户密码必须重新输入。我们希望当用户点击OK按钮后,MessageBox消失而光标位置回到第一个TextBox上。如何做到呢?
最常用的代码使用Control.Focus:
if (this.textBox1.Text != this.textBox2.Text)
{
MessageBox.Show(this, "Make sure two passwords are the same", "Demo", MessageBoxButtons.OK, MessageBoxIcon.Error);
this.textBox1.Focus();
}
但是我们还可以使用ContainerControl.ActiveControl:
this.ActiveControl = this.textBox1;
Toggle Button (接换按钮,开关按钮) 在2种状态下切换:On或者Off, Enabled或者Disabled, Applicable或者Not Applicable等等。
如何在WinForm下实现Toggle Button呢?使用CheckBox并将其Appearance属性设为Button(而不是Normal):
示例如下:
boldStateIndicator = new System.Windows.Forms.CheckBox();
boldStateIndicator.Appearance = System.Windows.Forms.Appearance.Button;
boldStateIndicator.Text = "Bold";