• [工具]类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

    总结

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

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

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

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

    晒一下自己的,文章。 

     

  • 相关阅读:
    HttpModule &amp; HttpHandler
    试图运行项目时出错:无法启动调试 没有正确安装调试器
    DataTable 手动排序 无效的问题解决方法??
    合并多个DLL文件
    恢复mysql方法
    在不同版本的IIS下使用ASP.NET MVC
    Enterprise Library 4.1 October 2008
    去除HTML标记
    Mac相关命令
    Mac常用快捷键
  • 原文地址:https://www.cnblogs.com/wolf-sun/p/3505750.html
Copyright © 2020-2023  润新知