从数据库读取图片发生“无效的参数”异常

介绍 我发现对于很多人来说,当从数据库里载入一张图片然后重新创建成一张图片显示的话会有这样一个问题—-当他们尝试重新创建新的图片的时候,会抛出一个“无效的参数”异常 因此,本文介绍该异常如何产生。并且我希望未来当我或是你发生这个错误的时候还能有所帮助。。 背景 存储图片到数据库里面是一个很有效的想法。很多人在一些场合都会这样做。的确,这是一个很好的想法。在图片很小的情况下,或者图片不是太多。在这两种情况下,当你需要图片的时候,你会实时去加载它们。而当你不需要的时候如果从数据库里加载图片会浪费很多带宽。并使得你的程序有一些慢。 但问题是这种方法也很容易发生错误。–尤其是你使用字符串连接,然后组合到你的SQL语句里面—并且这个错误只有当你打算使用存储的信息的时候才会发生。然后,看起来似乎是你的读取代码写错了—不可能—它是正常的。我在其他地方都可以的。。 从数据库里加载图片 重数据库里读取一张图片然后转换成图片显示是很简单的。 using (SqlConnection con = DBAccess.DBCon) { using (SqlCommand cmd = new SqlCommand("SELECT picture FROM Pictures WHERE Id=@ID", con)) { cmd.Parameters.AddWithValue("@ID", Id); SqlDataReader reader = cmd.ExecuteReader(); if (reader.Read()) { byte[] data = (byte[])reader["Picture"]; using (MemoryStream stream = new MemoryStream(bytes)) { myImage = new Bitmap(stream); } } } } 但是-如果data因为一些原因不是有效的图片,那么这一行 myImage = new Bitmap(stream); 将会抛出一个异常—无效的参数 只有当你真正看了从数据库里返回到data里的数据-而不是简单的瞄了一眼调试器,你才能注意到是什么原因。。 {byte[21]} [0] 83 [1] 121 [2] 115 [3] 116 [4] 101 [5] 109 [6] 46 [7] 68 [8] 114 [9] 97 [10] 119 [11] 105 [12] 110 [13] 103 [14] 46 ... 它看起来不像是错的,所以它可能就是你想要的。-虽然21字节是一个很大的线索:你的图片可能只有21字节长?那图片可真小。。 但是,上面的是可以读懂的。。稍微练习一下。。每个字节是一个ASCII码。。 "83" is an uppercase 'S' "121" is an lowercase 'y' "115" is an lowercase 's' "116" is an lowercase 't' "101" is an lowercase 'e' "109" is an lowercase 'm' "46" is a '.' "68" is an uppercase 'D' "114" is an lowercase 'r' "97" is an lowercase 'a' "119" is an lowercase 'w' "105" is an lowercase 'i' "110" is an lowercase 'n' "103" is an lowercase 'g' "46" is an lowercase '.' ... 简而言之,你从数据库里得到的数据是一个人类可以读懂的字符串,意思是是 ...

2012-09-27 · 2 min · bystander

JavaCC入门教程及相关资源

今天下午翻译了一篇简单的文章后。就去看JavaCC的东西了。。然后就找到了一篇入门教程 然后之前我是找到了一篇翻译过来的的某熊的战略储备基地 从头到尾读了一遍英文的。感觉还是英文的写的要好一些。建议对照着翻译看英文。JavaCC也就那么回事。。 同时在在这目测百慕大群岛的什么工程与应用科学学院找到了一些其他的文档。其中一篇是JavaCC-FAQ很好。基本上有关JavaCC的问题都有解释。 在FAQ里,看到了一个关于JJTree的介绍,写的不错。建议看看。 还有一个是国外某学校的编译原理课程的ppt下载,好象是以JavaCC作为工具的。还没认真看。 还有一篇JavaCC 研究与应用 ,写的平常。不过是中文版的。 最后。千万不要忘了官方文档。也包括你下载的JavaCC里面的Demo。。

2012-09-27 · 1 min · bystander

C#使用Graphics创建饼图

介绍 这个程序是使用C#中的Graphics来创建一个饼图的,我已经尽我所能写的很好了。如果你有任何建议可以分享给我,这样我也能从中学习。 使用代码 最近我迷上了Graphics类。我仅仅体验了一下Graphics的DrawPie() 和FillPie() 方法。 最为一个简单的Demo,我创建一个有着五个文本框的窗体,一个按钮,一个图片框。一会我就把饼图画在图片框里 在创建一个饼图之前,我们头脑里要有这个意识。我们不能创建一个不符合常规的圆,创建圆我们需要度数信息。 为了转换度数。我们首先把给定的值做个求和。然后得出文本框里所有值的和。然后呢。用每个值除以总值再乘以360度。 代码如下: int i1 = Int32.Parse(textBox1.Text); int i2 = Int32.Parse(textBox2.Text); int i3 = Int32.Parse(textBox3.Text); int i4 = Int32.Parse(textBox4.Text); int i5 = Int32.Parse(textBox5.Text); float total = i1 + i2 + i3 + i4 + i5 ; float deg1 = (i1 / total) * 360; float deg2 = (i2 / total) * 360; float deg3 = (i3 / total) * 360; float deg4 = (i4 / total) * 360; float deg5 = (i5 / total) * 360; 值转换完毕后。我们可以创建Graphics类的实例了。 Graphics graphics = pictureBox1.CreateGraphics(); 然后我们需要创建一个矩形区域,在这个矩形区域里绘制饼图。 Rectangle rect = new Rectangle(0, 0, 150, 150); 前两个参数定义了矩形左上角的坐标,后两个分别定义了举行的宽和高。 为了能够比较清晰的看出饼图各部分的比例。我们需要创建五个笔刷。 Brush brush1 = new SolidBrush(Color.Red); Brush brush2 = new SolidBrush(Color.Blue); Brush brush3 = new SolidBrush(Color.Maroon); Brush brush4 = new SolidBrush(Color.Navy); Brush brush5 = new SolidBrush(Color.YellowGreen); graphics.Clear(pictureBox1.BackColor); 现在我们可以开始创建我们的饼图了。graphics.FillPie();方法接受四个参数 笔刷,用来填充扇形 矩形:饼图将被创建的区域。 开始角度:饼部分的开始角度 覆盖角度:饼部分扫过的角度 一般来说graphics.FillPie();方法并不是创建一个完全的饼图,而是创建饼图的一个扇形部分,我们会创建一系列的扇形最终看起来像是一个饼图。 ...

2012-09-27 · 2 min · bystander

AvalonDock 2.0入门指南第一部分

AvalonDock 2.0可以用来为WPF创建一个类似Visual Studio的界面,深入理解如何使用AvalonDock进行开发是很重要的。 在这个入门指南里,我将演示如何开始使用AvalonDock,下面的文章都是基于2.0版本的。并且不能用于早期的版本。 AvalonDock是一个组合的布局模型,很多的控件都在视图上显示,一个DockingManager 类也显示在停靠区,用于可以拖拽文档和工具。 从下面这个截图中我们可以理解AvalonDock组件 DockingManager 这是AvalonDock中的核心控件,它将包含的窗格排序,处理飞出的窗格,还有浮动的窗口。在上面这个图中,DockingManager 对象包含了所有空间(WPF控件),从顶部的工具栏到底部的状态栏都算。同时。DockingManager 也可以处理保存和恢复布局。 LayoutPanel 这个面板用来管理在一个方向上的子窗口(通过Orientation属性来选择方向),并且在它们之间添加了一个大小调节控件,在一个Orientation属性是Horizontal(水平)的LayoutPanel 上,排列了三个窗格。一个LayoutAnchorablePane在左,一个LayoutDocumentPane在中间。一个LayoutDockablePane在右边。 LayoutDockablePane 这个布局元素包含一个LayoutAnchorable对象的集合。通过它用来管理想TabControl这样的控件,在上面的截图中,LayoutDockablePanes是在左边的’Strumenti’ 和 ‘Progetti’ (工具和项目) 和在右边的’Classi’ 和 ‘Proprieta’’ (类视图和属性视图)的容器,一个LayoutDockablePane可以自动隐藏,就像’Errori’(错误)和’Lista Azioni’(操作列表) and ‘Uscita’(输出)。并且LayoutDockablePane可以被拖动到DockingManager上,成为一个浮动窗口或者附着到它的父控件DockingManager的边缘上。 LayoutDocumentPane 通常包含文档(DocumentContent类型)的一种窗格,但是其实也可以包含像上面提到的工具视图和类视图这样的DockableContents。在一个文档里。LayoutDocumentPane 被放置在ResizingPanel(水平方向)里。ResizingPanel则是上卖弄提到的在两个DockablePane中间的区域。注意。文档窗格是不能被移动的。 LayoutAnchorable 一个停靠内容,是软件控件的容器,总是被包含在一个窗格里(LayoutAnchorablePane或是LayoutDocumentPane),在截图里。LayoutAnchorable是一类对象(包含一个SharpDevelop对象),工具对象,但是错误窗口(它处于自动隐藏状态,被好办在一个自动隐藏窗格里)不是。LayoutAnchorable就像它名字所暗示的那样。可以被从他的容器窗格里拖走。然后重新放置在一个存在的窗格里。或者是放置在父DockingManager的边缘,或者是放置在一个浮动窗口里(LayoutAnchorableFloatingWindow)。 LayoutDocument 是一个仅可以被寄宿到LayoutDocumentPane的内容。它是一个特殊的内容,因为不能被停靠到边缘。仅能被放置到LayoutDocumentPane里。或者浮动在一个LayoutDocumentFloatingWindow窗口里。在途中,DocumentContent对象是program.cs’ 或 ‘MainForm.cs’ 文件视图 **LayoutFloatingWindow **,是一个包含内容的窗口,当被拖动到一个DockingManager上面的时候,LayoutFloatingWindow(LayoutAnchorableFloatingWindow和LayoutDocumentFloatingWindow继承自他)集成在Window,总是包含一个窗格(LayoutAnchorablePane或是LayoutDocumentPane),窗格包含更多的内容(LayoutAnchorable或LayoutDocument),当用户对一个内容或是DockablePane执行拖拽,或者直接手工使用代码调用LayoutContent.Float()方法 LayoutFloatingWindow就被直接从DockingManager创建出来了。 LayoutPane 一个基类,LayoutDockablePane和LayoutDocumentPane继承自它。它为他们提供了一些共有的属性和方法。 LayoutContent 是LayoutAnchorable 和LayoutAnchorable类的父类。提供了共有的属性和方法。 理解布局元素是一些属于布局模型的类而不是属于视图是很重要的。因为,他们不是继承自FrameworkElement类,取而代之。AvalonDock包含了另一些类来展示这些组件的视图。这些类通常被命名为相关联的类名+Control字串。举个例子,在布局里创建的LayoutAnchorable创建了一个LayoutAnchorableControl(继承自FrameworkElement的类),并且绑定了LayoutAnchorableControl.Model 到这个LayoutAnchorable对象上。 每一个被创建的视图控件总是有着Model属性的布局元素。因此,重新设计一个相关视图控件的样式是可以的。 为了开始创建一个新的.net 4/.net 4.5的解决方案。并且添加对AvalonDock.dll的引用(可以直接添加也可以使用NuGet),然后添加AD命名空间到MainWindow.xaml中。 在根Grid下放置DockingManager组件和一个简单的布局。 <Window x:Class="MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:avalonDock="http://avalondock.codeplex.com" Title="MainWindow" Height="434" Width="684"> <Grid> <avalonDock:DockingManager x:Name="dockingManager"> <avalonDock:LayoutRoot> <avalonDock:LayoutPanel Orientation="Horizontal"> <avalonDock:LayoutDocumentPane/> <avalonDock:LayoutAnchorablePane DockWidth="150"> <avalonDock:LayoutAnchorable Title="Sample Tool Pane"> <TextBox/> </avalonDock:LayoutAnchorable> </avalonDock:LayoutAnchorablePane> </avalonDock:LayoutPanel> <avalonDock:LayoutRoot.LeftSide> <avalonDock:LayoutAnchorSide> <avalonDock:LayoutAnchorGroup> <avalonDock:LayoutAnchorable Title="Autohidden Content"> <TextBox/> </avalonDock:LayoutAnchorable> </avalonDock:LayoutAnchorGroup> </avalonDock:LayoutAnchorSide> </avalonDock:LayoutRoot.LeftSide> </avalonDock:LayoutRoot> </avalonDock:DockingManager> </Grid> </Window> DockingManager是AvalonDock的核心类,他的责任就是创建管理布局。布局被定义成一个ILayoutElement的树。树的根由LayoutRoot类指定。LayoutRoot由一些基本的子树来构成。。 1.根面板的 根属性指向主 LayoutPanel,也是LayoutRoot的内容属性。 2.大体上讲,RightSide/LeftSide/TopSide/BottonSide是LayoutAnchorGroup对象的集合属性,他们表示了停靠管理器的四个边。停靠管理器的锚通常是隐藏的。当用户移动鼠标到这些区域的时候。就会在自动隐藏的窗口里显示出来。 3.FloatingWindows属性是FloatingWindow的集合。一个浮动窗口当用户拖动一个窗格(LayoutAnchorable或是LayoutDocument)的时候就被创建出来,这个集合可以被AvalonDock自动更新,但是用户依然可以通过调用LayoutContent的Float()方法来创建一个浮动窗口。 Hidden是一个Anchorable(停靠)对象的集合。默认情况下,当用户点击一个LayoutAnchorable对象的关闭按钮,AvalonDock隐藏它:通过从布局里移除停靠元素,并且把他放入Hidden集合,当用户想要再一次显示的时候,AD又把这个内容从隐藏集合里删除重新显示在他被隐藏的那个窗格里。 当使用布局树的时候,程序员可以创建任何复杂的界面,LayoutAnchorablePane的DockWidth和DockHeight属性可以被用来设置窗格的初始宽度和高度。而LayoutDocumentPane类通常则填满可用的空间。AvalonDock管理内容元素的宽度和高度以使得可以使用所有的可用空间。因此如果一个LayoutAnchorablePane被放置在一个LayoutPanel里,为LayoutAnchorablePane使用一个固定尺寸而为LayoutDocumentPane使用一个比例长度。也就是说为停靠对象使用了比例长度。 一个LayoutDocumentGroup/ LayoutAnchorableGroup类可以被用来包含更多的LayoutDocumentPane/ LayoutAnchorablePane,举个例子,让我们来改变上面的例子来实现更复杂的例子。 <Window x:Class="AvalonDock2Tutorial.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:avalonDock="http://avalondock.codeplex.com" Title="MainWindow" Height="350" Width="525"> <Grid> <avalonDock:DockingManager x:Name="dockingManager"> <avalonDock:LayoutRoot> <avalonDock:LayoutPanel Orientation="Horizontal"> <avalonDock:LayoutDocumentPaneGroup> <avalonDock:LayoutDocumentPane> <avalonDock:LayoutDocument Title="Doc1"> <TextBox/> </avalonDock:LayoutDocument> <avalonDock:LayoutDocument Title="Doc2"> <TextBox/> </avalonDock:LayoutDocument> </avalonDock:LayoutDocumentPane> <avalonDock:LayoutDocumentPane> <avalonDock:LayoutDocument Title="Doc3"> <TextBox/> </avalonDock:LayoutDocument> </avalonDock:LayoutDocumentPane> </avalonDock:LayoutDocumentPaneGroup> <avalonDock:LayoutAnchorablePaneGroup DockWidth="150" Orientation="Vertical"> <avalonDock:LayoutAnchorablePane> <avalonDock:LayoutAnchorable Title="Tool 1"> <TextBox/> </avalonDock:LayoutAnchorable> <avalonDock:LayoutAnchorable Title="Tool 2"> <TextBox/> </avalonDock:LayoutAnchorable> </avalonDock:LayoutAnchorablePane> <avalonDock:LayoutAnchorablePane> <avalonDock:LayoutAnchorable Title="Tool 3"> <TextBox/> </avalonDock:LayoutAnchorable> <avalonDock:LayoutAnchorable Title="Tool 4"> <TextBox/> </avalonDock:LayoutAnchorable> </avalonDock:LayoutAnchorablePane> </avalonDock:LayoutAnchorablePaneGroup> </avalonDock:LayoutPanel> <avalonDock:LayoutRoot.LeftSide> <avalonDock:LayoutAnchorSide> <avalonDock:LayoutAnchorGroup> <avalonDock:LayoutAnchorable Title="Autohidden Content"> <TextBox/> </avalonDock:LayoutAnchorable> </avalonDock:LayoutAnchorGroup> </avalonDock:LayoutAnchorSide> </avalonDock:LayoutRoot.LeftSide> </avalonDock:LayoutRoot> </avalonDock:DockingManager> </Grid> </Window> 运行这个工程你就可以重新排列内容了。移动他们到浮动窗口。为了更加熟悉AvalonDock,我建议你多试几次,然后重新排列内容实现更复杂的布局。 ...

2012-09-26 · 1 min · bystander

C#编写youtube下载器

介绍 本文将会暂时如何仅仅使用C#来下载youtub视频,代码简单也容易理解,每个人都可以把它整合到自己的工程项目里。 我没有使用任何第三方的库来完成这段代码,你所要做的仅仅是把两个.cs文件整合进你的项目里。 使用代码 这个工程里有两个主要的类 YouTubeVideoQuality Class(youtube视频质量类) public class YouTubeVideoQuality { /// <summary> /// Gets or Sets 文件名 /// </summary> public string Videotitle: { get; set; } /// <summary> /// Gets or Sets 文件扩展 /// </summary> public string Extention { get; set; } /// <summary> /// Gets or Sets 文件地址 /// </summary> public string DownloadUrl { get; set; } /// <summary> /// Gets or Sets 视频地址 /// </summary> public string VideoUrl { get; set; } /// <summary> /// Gets or Sets 文件大小 /// </summary> public Size Dimension { get; set; } public override string ToString() { return Extention + " File " + Dimension.Width + "x" + Dimension.Height; } public void SetQuality(string Extention, Size Dimension) { this.Extention = Extention; this.Dimension = Dimension; } } YouTubeDownloader Class(youtube下载类) public class YouTubeDownloader { public static List<YouTubeVideoQuality> GetYouTubeVideoUrls(params string[] VideoUrls) { List<YouTubeVideoQuality> urls = new List<YouTubeVideoQuality>(); foreach (var VideoUrl in VideoUrls) { string html = Helper.DownloadWebPage(VideoUrl); string title: = GetTitle(html); foreach (var videoLink in ExtractUrls(html)) { YouTubeVideoQuality q = new YouTubeVideoQuality(); q.VideoUrl = VideoUrl; q.Videotitle: = title; q.DownloadUrl = videoLink + "&title=" + title; if (getQuality(q)) urls.Add(q); } } return urls; } private static string GetTitle(string RssDoc) { string str14 = Helper.GetTxtBtwn(RssDoc, "'VIDEO_TITLE': '", "'", 0); if (str14 == "") str14 = Helper.GetTxtBtwn(RssDoc, "\"title\" content=\"", "\"", 0); if (str14 == "") str14 = Helper.GetTxtBtwn(RssDoc, "&title=", "&", 0); str14 = str14.Replace(@"\", "").Replace("'", "'").Replace( "\"", """).Replace("<", "<").Replace( ">", ">").Replace("+", " "); return str14; } private static List<string> ExtractUrls(string html) { html = Uri.UnescapeDataString(Regex.Match(html, "url_encoded_fmt_stream_map=(.+?)&", RegexOptions.Singleline).Groups[1].ToString()); MatchCollection matchs = Regex.Matches(html, "url=(.+?)&quality=(.+?)&fallback_host=(.+?)&type=(.+?)&itag=(.+?),", RegexOptions.Singleline); bool firstTry = matchs.Count > 0; if (!firstTry) matchs = Regex.Matches(html, "itag=(.+?)&url=(.+?)&type=(.+?)&fallback_host=(.+?)&sig=(.+?)&quality=(.+?),{0,1}", RegexOptions.Singleline); List<string> urls = new List<string>(); foreach (Match match in matchs) { if (firstTry) urls.Add(Uri.UnescapeDataString(match.Groups[1] + "")); else urls.Add(Uri.UnescapeDataString(match.Groups[2] + "") + "&signature=" + match.Groups[5]); } return urls; } private static bool getQuality(YouTubeVideoQuality q) { if (q.DownloadUrl.Contains("itag=5")) q.SetQuality("flv", new Size(320, 240)); else if (q.DownloadUrl.Contains("itag=34")) q.SetQuality("flv", new Size(400, 226)); else if (q.DownloadUrl.Contains("itag=6")) q.SetQuality("flv", new Size(480, 360)); else if (q.DownloadUrl.Contains("itag=35")) q.SetQuality("flv", new Size(640, 380)); else if (q.DownloadUrl.Contains("itag=18")) q.SetQuality("mp4", new Size(480, 360)); else if (q.DownloadUrl.Contains("itag=22")) q.SetQuality("mp4", new Size(1280, 720)); else if (q.DownloadUrl.Contains("itag=37")) q.SetQuality("mp4", new Size(1920, 1280)); else if (q.DownloadUrl.Contains("itag=38")) q.SetQuality("mp4", new Size(4096, 72304)); else return false; return true; } } 有趣的地方 使用这个代码,你可以根据你的网速来选择不同品质的视频来下载 ...

2012-09-25 · 2 min · bystander

C#删除文件和文件夹到回收站

如果使用C#代码来删除文件或是文件夹。会将文件和文件夹直接删除,而不是删除到回收站。可以调用Microsoft.VisualBasic.dll提供的方法。 首先对项目添加名为Microsoft.VisualBasic.dll的引用,然后添加命名空间 using Microsoft.VisualBasic.FileIO; 最后示例代码如下: using System; using Microsoft.VisualBasic.FileIO; namespace leaver { class Program { static void Main(string[] args) { Console.WriteLine("删除文件到回收站"); string filepath = "leaver.txt"; FileSystem.DeleteFile(filepath, UIOption.OnlyErrorDialogs, RecycleOption.SendToRecycleBin); Console.WriteLine("删除文件完成"); Console.WriteLine("删除文件夹到回收站"); string dirpath = "leaver"; FileSystem.DeleteDirectory(dirpath, UIOption.OnlyErrorDialogs, RecycleOption.SendToRecycleBin); Console.WriteLine("删除文件夹完成"); } } } 很简单。。就不多说了。。

2012-09-24 · 1 min · bystander

VS扩展故障,错误码:80131515

介绍 如果你给VS安装了Web Search扩展,如果第一次运行就出现了错误代码是80131515的问题。那么本文对你是有用的。。 背景 当我远程试图运行Web Search的时候出现了这个错误。我用本文第一种方法解决了。。 解决方法 这个错误发生在当我远程以dll的方式调用的时候提示我说权限不够。。 为了解决这个问题,我们需要给devenv.exe.config文件添加loadFromRemoteSources 元素 首先使用管理员权限从下面的路径打开devenv.exe.config文件。 具体路径:你的VS安装目录\Common7\IDE\devenv.exe.config 并且添加loadFromRemoteSources 元素,并设为true。如下: <configuration> <runtime> <loadFromRemoteSources enabled="true"/> </runtime> </configuration> 有时候windows会把下载的文件标记为“此文件来自一个不同的位置” ,然后对这些文件进行了很多的限制,这部分就是解锁下载的zip或是dll文件 为了解锁这些文件,只要右键点击这些文件,属性,选择常规,然后点击解锁按钮。如下图: 如果你还有其他的解决方法请告诉我哦。 许可 本文,包括源代码和文件,在CPOL下授权。 原文地址:Visual-Studio-Add-in-Troubleshooting-Error-Number 著作权声明:本文由http://leaver.me 翻译,欢迎转载分享。请尊重作者劳动,转载时保留该声明和作者博客链接,谢谢!

2012-09-24 · 1 min · bystander

WPF毛玻璃效果Demo和一个问题

 那天看到WPF书上讲的毛玻璃效果,就去找了下效果。。忘了例子是从哪发现得了。。先看下效果, 但是这不是重点,作者给出的代码有一个设计时错误。。错误提示为: 无法将类型为“Microsoft.Expression.Platform.WPF.InstanceBuilders.WindowInstance”的对象强制转换为类型“System.Windows.Window”,, 中文搜了一下。没有发现有人解决过。目测。。。然后又拿英文搜了下。几经辗转。。终于是解决了。。原文在Unable to cast XAML error。其实就是将原作者这个函数修改如下的 public static void OnIsEnabledChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) { if ((bool)args.NewValue == true) { Window wnd = obj as Window; if (wnd != null) wnd.Loaded += new RoutedEventHandler(wnd_Loaded); } } 也就是验证了一下转换是否成功。 下载:修改后的RGSamples

2012-09-24 · 1 min · bystander

.net显示网络连接状态图标

效果图: 介绍 越来越多的软件要通过连接互联网来执行一些业务层的业务操作,比如调用web services服务,获取数据等等。 通常你可能希望知道当前你的网络连接是不是真的连上了,当然有很多种方法可以做到,比如,你可以查看System.Net 命名空间中的NetworkInterface 的状态,但是有这以太网连接并不表示你的连接真的可以用。 本文将会展示一种方法,该方法在程序的状态栏StatusStrip 显示一个简单的图标来指示是不是真的连接到了互联网。 使用代码 最简单的我们会想到使用一个Timer来进行http-get请求来判断一个特定的网页是否可用。 当然这种方法下,我们最应该考虑的就是请求不能阻塞UI线程,因此,我将使用一个BackgroundWorker 对象来进行get请求,BackgroundWorker 对象声明了DoWork方法。该方法定义了一个事件句柄,该句柄传递一个DoWorkEventArgs 类来将事件的处理结果返回到UI线程,因此,你不必与任何的UI元素进行交互,因为它运行在一个独立的线程里。 private void InitializeComponent() { // Background Worker this._worker = new BackgroundWorker(); this._worker.WorkerReportsProgress = false; this._worker.WorkerSupportsCancellation = false; this._worker.DoWork += new DoWorkEventHandler(this.BackgroundWorker_DoWork); this._worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(this.BackgroundWorker_RunWorkerCompleted); // Timer this._updateTimer = new Timer(); this._updateTimer.Enabled = !this.DesignMode; // Enabled when not in design mode this._updateTimer.Tick += delegate { this.OnTick(); }; } private void OnTick() { if (this.DesignMode) return; // Stop the timer while the process is running this._updateTimer.Enabled = false; // Disable so we get the grayed-out look this.Enabled = false; this.Invalidate(); // Execute the Ping Query on a separate thread... this._worker.RunWorkerAsync(); } 这个查询很简单,我执行简单的HttpWebRequest 来请求一个必然是可用的网页。比如微软的主页或是Google的主页。通过这样,我们就能知道是不是真的连接上了互联网。 private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e) { try { // Create an HTTP Web request // to an Uri that's always available. HttpWebRequest request = (HttpWebRequest) HttpWebRequest.Create(this._alwaysAvailableUrl); // Perform GET HttpWebResponse response = (HttpWebResponse) request.GetResponse(); if (HttpStatusCode.OK == response.StatusCode) { // HTTP = 200, close the request and return true response.Close(); e.Result = true; } else { // Other status; return false e.Result = false; } } catch (WebException) { // Deffinitely offline e.Result = false; } } 当BackgroundWorker 对象完成了他的工作,,也就是定义DoWork 里的事件,他会触发RunWorkerCompleted 事件,这个事件也定义了一个定制的事件句柄- RunWorkerCompletedEventArgs 有了这个类,我们就可以管理ToolStripStatusLabel的显示了 ...

2012-09-24 · 2 min · bystander

汇编-32位CPU所含有的寄存器

今年的课程有汇编。真为校领导的智商捉鸡。。不过还是要学的。分享一篇来自中文FLEX例子的汇编寄存器的文章。很不错的一篇寄存器详解的文章。文章最后是我找到的一个汇编指令助手。 4个数据寄存器(EAX、EBX、ECX和EDX) 2个变址和指针寄存器(ESI和EDI) 2个指针寄存器(ESP和EBP) 6个段寄存器(ES、CS、SS、DS、FS和GS) 1个指令指针寄存器(EIP) 1个标志寄存器(EFlags) 1、数据寄存器 数据寄存器主要用来保存操作数和运算结果等信息,从而节省读取操作数所需占用总线和访问存储器的时间。32位CPU有4个32位的通用寄存器EAX、EBX、ECX和EDX。对低16位数据的存取,不会影响高16位的数据。这些低16位寄存器分别命名为:AX、BX、CX和DX,它和先前的CPU中的寄存器相一致。 4个16位寄存器又可分割成8个独立的8位寄存器(AX:AH-AL、BX:BH-BL、CX:CH-CL、DX:DH-DL),每个寄存器都有自己的名称,可独立存取。程序员可利用数据寄存器的这种”可分可合”的特性,灵活地处理字/字节的信息。 寄存器AX和AL通常称为累加器(Accumulator),用累加器进行的操作可能需要更少时间。累加器可用于乘、 除、输入/输出等操作,它们的使用频率很高; 寄存器BX称为基地址寄存器(Base Register)。它可作为存储器指针来使用; 寄存器CX称为计数寄存器(Count Register)。在循环和字符串操作时,要用它来控制循环次数;在位操作 中,当移多位时,要用CL来指明移位的位数; 寄存器DX称为数据寄存器(Data Register)。在进行乘、除运算时,它可作为默认的操作数参与运算,也 可用于存放I/O的端口地址。在16位CPU中,AX、BX、CX和DX不能作为基址和变址寄存器来存放存储单元的地址,但在32位CPU中,其32位寄存器EAX、EBX、ECX和EDX不仅可传送数据、暂存数据保存算术逻辑运算结果,而且也可作为指针寄存器,所以,这些32位寄存器更具有通用性。 2、变址寄存器 32位CPU有2个32位通用寄存器ESI和EDI。其低16位对应先前CPU中的SI和DI,对低16位数据的存取,不影响高16位的数据。 寄存器ESI、EDI、SI和DI称为变址寄存器(Index Register),它们主要用于存放存储单元在段内的偏移量,用它们可实现多种存储器操作数的寻址方式,为以不同的地址形式访问存储单元提供方便。变址寄存器不可分割成8位寄存器。作为通用寄存器,也可存储算术逻辑运算的操作数和运算结果。它们可作一般的存储器指针使用。在字符串操作指令的执行过程中,对它们有特定的要求,而且还具有特殊的功能。 3、指针寄存器 32位CPU有2个32位通用寄存器EBP和ESP。其低16位对应先前CPU中的SBP和SP,对低16位数据的存取,不影响高16位的数据。 寄存器EBP、ESP、BP和SP称为指针寄存器(Pointer Register),主要用于存放堆栈内存储单元的偏移量,用它们可实现多种存储器操作数的寻址方式,为以不同的地址形式访问存储单元提供方便。指针寄存器不可分割成8位寄存器。作为通用寄存器,也可存储算术逻辑运算的操作数和运算结果。 它们主要用于访问堆栈内的存储单元,并且规定: BP为基指针(Base Pointer)寄存器,用它可直接存取堆栈中的数据; SP为堆栈指针(Stack Pointer)寄存器,用它只可访问栈顶。 4、段寄存器 段寄存器是根据内存分段的管理模式而设置的。内存单元的物理地址由段寄存器的值和一个偏移量组合而成 的,这样可用两个较少位数的值组合成一个可访问较大物理空间的内存地址。 CPU内部的段寄存器: CS——代码段寄存器(Code Segment Register),其值为代码段的段值; DS——数据段寄存器(Data Segment Register),其值为数据段的段值; ES——附加段寄存器(Extra Segment Register),其值为附加数据段的段值; SS——堆栈段寄存器(Stack Segment Register),其值为堆栈段的段值; FS——附加段寄存器(Extra Segment Register),其值为附加数据段的段值; GS——附加段寄存器(Extra Segment Register),其值为附加数据段的段值。 在16位CPU系统中,它只有4个段寄存器,所以,程序在任何时刻至多有4个正在使用的段可直接访问;在32位微机系统中,它有6个段寄存器,所以,在此环境下开发的程序最多可同时访问6个段。32位CPU有两个不同的工作方式:实方式和保护方式。在每种方式下,段寄存器的作用是不同的。有关规定简单描述如下: 实方式: 前4个段寄存器CS、DS、ES和SS与先前CPU中的所对应的段寄存器的含义完全一致,内存单元的逻辑地址仍为”段值:偏移量”的形式。为访问某内存段内的数据,必须使用该段寄存器和存储单元的偏移量。 保护方式: 在此方式下,情况要复杂得多,装入段寄存器的不再是段值,而是称为”选择子”(Selector)的某个值。 5、指令指针寄存器 32位CPU把指令指针扩展到32位,并记作EIP,EIP的低16位与先前CPU中的IP作用相同。 指令指针EIP、IP(Instruction Pointer)是存放下次将要执行的指令在代码段的偏移量。在具有预取指令功能的系统中,下次要执行的指令通常已被预取到指令队列中,除非发生转移情况。所以,在理解它们的功能时,不考虑存在指令队列的情况。 在实方式下,由于每个段的最大范围为64K,所以,EIP中的高16位肯定都为0,此时,相当于只用其低16位的IP来反映程序中指令的执行次序。 6、标志寄存器 一、运算结果标志位 1、进位标志CF(Carry Flag) 进位标志CF主要用来反映运算是否产生进位或借位。如果运算结果的最高位产生了一个进位或借位,那么,其值为1,否则其值为0。使用该标志位的情况有:多字(字节)数的加减运算,无符号数的大小比较运算,移位操作,字(字节)之间移位,专门改变CF值的指令等。 2、奇偶标志PF(Parity Flag) 奇偶标志PF用于反映运算结果中”1″的个数的奇偶性。如果”1″的个数为偶数,则PF的值为1,否则其值为0。 利用PF可进行奇偶校验检查,或产生奇偶校验位。在数据传送过程中,为了提供传送的可靠性,如果采用奇偶校验的方法,就可使用该标志位。 3、辅助进位标志AF(Auxiliary Carry Flag) 在发生下列情况时,辅助进位标志AF的值被置为1,否则其值为0: (1)、在字操作时,发生低字节向高字节进位或借位时; (2)、在字节操作时,发生低4位向高4位进位或借位时。 对以上6个运算结果标志位,在一般编程情况下,标志位CF、ZF、SF和OF的使用频率较高,而标志位PF和AF的使用频率较低。 4、零标志ZF(Zero Flag) 零标志ZF用来反映运算结果是否为0。如果运算结果为0,则其值为1,否则其值为0。在判断运算结果是否为0时,可使用此标志位。 5、符号标志SF(Sign Flag) 符号标志SF用来反映运算结果的符号位,它与运算结果的最高位相同。在微机系统中,有符号数采用补码表示法,所以,SF也就反映运算结果的正负号。运算结果为正数时,SF的值为0,否则其值为1。 6、溢出标志OF(Overflow Flag) 溢出标志OF用于反映有符号数加减运算所得结果是否溢出。如果运算结果超过当前运算位数所能表示的范围,则称为溢出,OF的值被置为1,否则,OF的值被清为0。”溢出”和”进位”是两个不同含义的概念,不要混淆。如果不太清楚的话,请查阅《计算机组成原理》课程中的有关章节。 二、状态控制标志位 状态控制标志位是用来控制CPU操作的,它们要通过专门的指令才能使之发生改变。 1、追踪标志TF(Trap Flag) 当追踪标志TF被置为1时,CPU进入单步执行方式,即每执行一条指令,产生一个单步中断请求。这种方式主要用于程序的调试。指令系统中没有专门的指令来改变标志位TF的值,但程序员可用其它办法来改变其值。 2、中断允许标志IF(Interrupt-enable Flag) 中断允许标志IF是用来决定CPU是否响应CPU外部的可屏蔽中断发出的中断请求。但不管该标志为何值,CPU都必须响应CPU外部的不可屏蔽中断所发出的中断请求,以及CPU内部产生的中断请求。具体规定如下: (1)、当IF=1时,CPU可以响应CPU外部的可屏蔽中断发出的中断请求; (2)、当IF=0时,CPU不响应CPU外部的可屏蔽中断发出的中断请求。 CPU的指令系统中也有专门的指令来改变标志位IF的值。 3、方向标志DF(Direction Flag) 方向标志DF用来决定在串操作指令执行时有关指针寄存器发生调整的方向。具体规定在第5.2.11节——字符串操作指令——中给出。在微机的指令系统中,还提供了专门的指令来改变标志位DF的值。 三、32位标志寄存器增加的标志位 1、I/O特权标志IOPL(I/O Privilege Level) I/O特权标志用两位二进制位来表示,也称为I/O特权级字段。该字段指定了要求执行I/O指令的特权级。如果当前的特权级别在数值上小于等于IOPL的值,那么,该I/O指令可执行,否则将发生一个保护异常。 2、嵌套任务标志NT(Nested Task) 嵌套任务标志NT用来控制中断返回指令IRET的执行。具体规定如下: (1)、当NT=0,用堆栈中保存的值恢复EFLAGS、CS和EIP,执行常规的中断返回操作; (2)、当NT=1,通过任务转换实现中断返回。 3、重启动标志RF(Restart Flag) 重启动标志RF用来控制是否接受调试故障。规定:RF=0时,表示”接受”调试故障,否则拒绝之。在成功执行完一条指令后,处理机把RF置为0,当接受到一个非调试故障时,处理机就把它置为1。 4、虚拟8086方式标志VM(Virtual 8086 Mode) 如果该标志的值为1,则表示处理机处于虚拟的8086方式下的工作状态,否则,处理机处于一般保护方式下的工作状态。 下载:汇编指令助手

2012-09-24 · 1 min · bystander