[工具]类QQ消息通知,提示博客园发布新文章(三)——有码

引言

不管在公司,还是在路上,听到最多的就是抢票俩字,搞的我不淡定了,心浮躁了......

不管怎样,今天还是将这个小工具,搞出来了,或许会有bug,没测试。

效果图

1.恶搞一下,此窗口为,在未抓取到内容时,一个gif的图片,为loading.gif 至于怎么动,下载源码,看看就知道了。

2.今天真巧,刚加载一篇文章,就看到一个妹子的头像,这是不是代表.... 窗体是半透明状态,标题过长,截取放在两个LinkLabel控件上,简介内容是一个textBox控件,其他的用到的控件头像picturebox,label等

3.单击链接,打开默认浏览器,跳转该文章内容。如图所示。并且,有最新文章时,出发托盘点击事件,弹出窗口。

遇到的问题

1.原来设计的时候,考虑放在一个list集合中,发现并不需要,只是取出第一条信息,再放在集合中,再从集合中取数据,绕了一圈,麻烦。最后,取出第一条,break跳出。

2.在设计如何当前数据是最新的,通过重写Blog实体类的Equals方法,比较所有的属性值是否相同。

3.事件注册时机,这个错误有点sb,竟然将注册事件,放在了timer_Tick(object sender, EventArgs e)这个事件方法中,最后结果可想而知,每10s注册一次,当你撒泡尿回来的时候,你单击一次,发现,电脑直接崩溃了。那是,你单击一次,打开了n多个页面。这低级错误,真sb

4.在提示最新数据,弹出窗口设计逻辑时,有时会出现,博客园第一篇文章和排名第二篇的文章,来回切换的情况,这个bug正在查找。

有码

  1 using System;
  2 using System.Collections.Generic;
  3 using System.ComponentModel;
  4 using System.Data;
  5 using System.Drawing;
  6 using System.IO;
  7 using System.Linq;
  8 using System.Net;
  9 using System.Runtime.InteropServices;
 10 using System.Text;
 11 using System.Text.RegularExpressions;
 12 using System.Threading.Tasks;
 13 using System.Windows.Forms;
 14 
 15 namespace Wolfy.Cnblogs
 16 {
 17     public partial class MainForm : Form
 18     {
 19         public MainForm()
 20         {
 21             InitializeComponent();
 22         }
 23         private event GetBlogsEventHandler GetBlogs;
 24         log4net.ILog myLogger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
 25         Timer timer = null;
 26         Blog preBlog = null;//用来存上一篇博客信息
 27         Blog currentBlog = null;//当前博客信息
 28 
 29         private void MainForm_Load(object sender, EventArgs e)
 30         {
 31             string exePath = AppDomain.CurrentDomain.BaseDirectory;
 32             string rootPath = exePath.Substring(0, exePath.IndexOf("bin"));
 33             pbLoading.ImageLocation = Path.Combine(rootPath, "Image/loading.gif");//当在未读到数据时 加载一张图片 遮盖 
 34             pbLoading.SizeMode = PictureBoxSizeMode.Zoom;
 35             pbLoading.Width = this.panelContent.Width;
 36             pbLoading.Height = this.panelContent.Height;
 37             this.Opacity = 0.8d;
 38             this.BackColor = Color.Green;
 39             this.txtContent.BackColor = Color.Green;
 40             //确定窗体位置 右下角
 41             Rectangle rectangle = Screen.GetWorkingArea(this);
 42             this.Location = new Point(rectangle.Right - this.Width, rectangle.Bottom - this.Height);
 43             panelContent.MouseDown += panelContent_MouseDown;
 44             linkLabelTitle.Focus();
 45             GetBlogs += MainForm_GetBlogs;//注册事件
 46             linkLabelBreakWord.LinkClicked += linkLabelTitle_LinkClicked;//窗体加载时 注册链接单击事件
 47             linkLabelTitle.LinkClicked += linkLabelTitle_LinkClicked;
 48             timer = new Timer();//定时器 每十秒 抓去一次博客园文章 
 49             timer.Interval = 10000;
 50             timer.Start();
 51             timer.Tick += timer_Tick;
 52         }
 53 
 54         void MainForm_GetBlogs(object sender, GetBlogsEventArgs e)
 55         {
 56             if (e != null)
 57             {
 58                 currentBlog = e.Blog;
 59 
 60                 //判断如果当前的博客 和上一篇博客不同 则提示
 61                 if (preBlog != null && !preBlog.Equals(currentBlog))
 62                 {
 63                     notifyIconCnblogs_Click(this, new GetBlogsEventArgs(currentBlog));
 64                 }
 65                 Send(currentBlog);
 66             }
 67         }
 68         private void Send(Blog blog)
 69         {
 70             //头像地址
 71             pbHeader.ImageLocation = string.IsNullOrEmpty(blog.Header) ? "" : blog.Header.Trim();
 72             linkLabelTitle.Text = blog.Title.Length >= 23 ? blog.Title.Substring(0, 23) : blog.Title;//达到换行的目的 用两个linklabel
 73             linkLabelBreakWord.Text = blog.Title.Length >= 23 ? blog.Title.Substring(23) : "";
 74             linkLabelBreakWord.Visible = blog.Title.Length >= 23 ? true : false;
 75             linkLabelBreakWord.VisitedLinkColor = Color.Red;
 76             linkLabelBreakWord.Tag = blog.Url;
 77 
 78             linkLabelTitle.VisitedLinkColor = Color.Red;
 79             linkLabelTitle.Tag = blog.Url;//存放url
 80             txtContent.Text = string.IsNullOrEmpty(blog.Content) ? "" : blog.Content.Trim();
 81 
 82             lblAuthor.Text = blog.Author;
 83             lblDate.Text = blog.Time.ToString("yyyy-MM-dd hh:mm");
 84             preBlog = blog;//显示后将词条信息 保存为上条
 85 
 86         }
 87         void linkLabelTitle_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
 88         {
 89             LinkLabel link = sender as LinkLabel;
 90             System.Diagnostics.Process.Start("explorer.exe", link.Tag.ToString());
 91         }
 92 
 93         private void timer_Tick(object sender, EventArgs e)
 94         {
 95             try
 96             {
 97                 WebClient client = new WebClient();
 98                 byte[] buffer = client.DownloadData("http://www.cnblogs.com/");
 99                 //博客园采用的是utf-8  否则会出现乱码
100                 string html = Encoding.UTF8.GetString(buffer, 0, buffer.Length);
101                 //cnblog简单正则表达式
102                 string regex = "<div\\s*class=\"post_item\">\\s*.*\\s*.*\\s*.*\\s*.*\\s*.*\\s*.*\\s*.*\\s*<div\\s*class=\"post_item_body\">\\s*<h3><a\\s*class=\"titlelnk\"\\s*href=\"(?<href>.*)\"\\s*target=\"_blank\">(?<title>.*)</a>.*\\s*<p\\s*class=\"post_item_summary\">\\s*(?<content>.*)\\s*</p>\\s*<div\\s*class=\"post_item_foot\">\\s*<a\\s*href=\".+?\"\\s*class=\"lightblue\">(?<author>.+?)</a>\\s*发布于\\s*(?<time>\\d{4}\\-\\d{2}\\-\\d{2}\\s*\\d{2}:\\d{2})";
103                 //过滤有标签的content内容 将头像src和内容过滤出来
104                 string regex2 = "<a\\s+href=\"http://.+?\"\\s*target=\"_blank\"><img\\s*width=\"48\"\\s*height=\"48\"\\s*class=\"pfs\"\\s* src=\"(?<imgSrc>.+?)\".+?/></a>(?<content>.+)\\s*";
105                 MatchCollection matches = Regex.Matches(html, regex, RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.CultureInvariant);
106 
107                 foreach (Match match in matches)
108                 {
109                     if (match.Success)
110                     {
111 
112                         Blog blog = new Blog();
113                         blog.Url = match.Groups["href"].Value;
114                         blog.Title = match.Groups["title"].Value;
115                         //其中content中 如果用户有头像 则content包含img标签
116                         blog.Content = match.Groups["content"].Value;
117                         Match m = Regex.Match(blog.Content, regex2);
118                         if (m.Success)
119                         {
120                             if (!string.IsNullOrEmpty(m.Groups["imgSrc"].Value))
121                             {
122                                 blog.Header = m.Groups["imgSrc"].Value;
123                             }
124                             blog.Content = m.Groups["content"].Value;
125                         }
126                         blog.Author = match.Groups["author"].Value;
127                         blog.Time = Convert.ToDateTime(match.Groups["time"].Value);
128                         if (blog != null)
129                         {
130                             this.pbLoading.Visible = false;
131                             this.pbLoading.Dispose();
132                             this.GetBlogs(this, new GetBlogsEventArgs(blog));
133                             break;
134                         }
135                     }
136                 }
137             }
138             catch (Exception ex)
139             {
140                 //MessageBox.Show(ex.Message);
141                 myLogger.Error("错误信息", ex);
142             }
143         }
144         void panelContent_MouseDown(object sender, MouseEventArgs e)
145         {
146             //扑捉事件
147             WindowsHelper.ReleaseCapture();
148             //发送消息给window Api 来实现
149             WindowsHelper.SendMessage(this.Handle, WindowsHelper.WM_SYSCOMMAND, WindowsHelper.SC_MOVE + WindowsHelper.HTCAPTION, 0);//
150         }
151 
152         private void lblClose_Click(object sender, EventArgs e)
153         {
154             this.Hide();
155             this.notifyIconCnblogs.Visible = true;
156         }
157 
158         private void notifyIconCnblogs_Click(object sender, EventArgs e)
159         {
160             this.Visible = true;
161             this.WindowState = FormWindowState.Normal;
162             this.notifyIconCnblogs.Visible = true;
163         }
164 
165         private void menuItem_Hide_Click(object sender, EventArgs e)
166         {
167             this.Hide();
168             this.notifyIconCnblogs.Visible = true;
169         }
170 
171         private void menuItem_Show_Click(object sender, EventArgs e)
172         {
173             this.Visible = true;
174             this.WindowState = FormWindowState.Normal;
175             this.notifyIconCnblogs.Visible = true;
176         }
177 
178         private void menuItem_Aubot_Click(object sender, EventArgs e)
179         {
180             MessageBox.Show("博客园最新博客提示工具");
181         }
182 
183         private void menuItem_Exit_Click(object sender, EventArgs e)
184         {
185             this.Close();
186             this.timer.Dispose();
187             this.Dispose();
188         }
189     }
190 }
Mainform
 1 using System;
 2 using System.Collections;
 3 using System.Collections.Generic;
 4 using System.Linq;
 5 using System.Text;
 6 using System.Threading.Tasks;
 7 
 8 namespace Wolfy.Cnblogs
 9 {
10     public class Blog
11     {
12         /// <summary>
13         /// 文章地址
14         /// </summary>
15         public string Url { set; get; }
16         /// <summary>
17         /// 文章标题
18         /// </summary>
19         public string Title { get; set; }
20         /// <summary>
21         /// 文章简介
22         /// </summary>
23         public string Content { set; get; }
24         /// <summary>
25         /// 头像地址
26         /// </summary>
27         public string Header { set; get; }
28         /// <summary>
29         /// 作者
30         /// </summary>
31         public string Author { set; get; }
32         /// <summary>
33         /// 发布时间
34         /// </summary>
35         public DateTime Time { set; get; }
36         /// <summary>
37         /// 比较是否相等
38         /// </summary>
39         /// <param name="obj"></param>
40         /// <returns></returns>
41         public override bool Equals(object obj)
42         {
43             Blog blog = obj as Blog;
44             return this.Url == blog.Url && this.Title == blog.Title && this.Content == blog.Content && this.Header == blog.Header && this.Author == blog.Author && this.Time == blog.Time;
45         }
46 
47 
48     }
49 }
Blog
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Runtime.InteropServices;
 5 using System.Text;
 6 using System.Threading.Tasks;
 7 
 8 namespace Wolfy.Cnblogs
 9 {
10     public static class WindowsHelper
11     {
12         [DllImport("user32.dll")]
13         //方法扑捉
14         public static extern bool ReleaseCapture();
15         [DllImport("user32.dll")]
16         public static extern bool SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);
17         public const int WM_SYSCOMMAND = 0x0112;
18         public const int SC_MOVE = 0xF010;
19         public const int HTCAPTION = 0x0002;
20     }
21 }
WindowsHelper
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace Wolfy.Cnblogs
 8 {
 9     /// <summary>
10     /// 自定义事件参数类
11     /// </summary>
12     public class GetBlogsEventArgs : EventArgs
13     {
14         private Blog blog;
15 
16         public Blog Blog
17         {
18             get { return blog; }
19             set { blog = value; }
20         }
21         public GetBlogsEventArgs(Blog blog)
22         {
23             this.blog = blog;
24         }
25     }
26 }
GetBlogsEventArgs
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace Wolfy.Cnblogs
 8 {
 9     public delegate void GetBlogsEventHandler(object sender, GetBlogsEventArgs e);
10 }
GetBlogsEventHandler

无码下载:链接:http://pan.baidu.com/s/1eQrdEwi 密码:8z4e

总结

做一个小工具,只是觉得好玩,可能因为太懒了,不想每次都打开浏览器,在公司逛博客园,打开个浏览器,网速太卡了,另外是因为大屏幕,被发现,虽然老大不说,总觉得.....

虽然用的东西不是多深奥的技术,一个小工具,功能多强大,就说明这个程序员有多懒,如果功能还不够强大,只是懒的不够厉害。

写的过程中,有考虑用观察者模式的,唉,太懒了,不想写那么多类。典型的观察者模式......

文章写到最后,有个新文章,弹出来了,截图记录一下:

晒一下自己的,文章。 

 

posted @ 2014-01-06 19:03  wolfy  阅读(2711)  评论(20编辑  收藏  举报