学生时代做的一个非常低级的卡拉OK播放器

来源:互联网 发布:mac开发android 编辑:程序博客网 时间:2024/05/17 03:11

学生时代做的一个非常低级的C#卡拉OK播放器。

实现了桌面卡拉OK[单行,双行],繁简转换,歌曲搜索,3种播放模式[单首,循环,随机],全屏歌词,全局快捷键,XML配置,指定歌词文件夹,等等一些简单的功能。

源码点击下载

无意中翻出来了,看看,听听歌,有别有一番乐趣,想当初做这个的时候才接触编程1年。里面用了太多的集合,歌词判断也非常不准备。呵呵。算是用一种非常笨的方法实现的吧。里面没什么高深的技术。主要就是用到了双缓冲[一种防止歌词刷新时屏幕闪烁的技术]、注册全局快捷键等。

已经好久没有接触C#了,虽然这是曾经非常感兴趣的东西,却为了学习编程思想选择了JAVA。如果现在再让我做,我一定会把里面的代码简化简化再简化吧。看着那些乱七八糟的代码,想想自己当年的何其的菜鸟水平的作品。也是一种人生的乐趣。

主界面:


窗体卡拉OK


桌面卡拉OK显示[支持单行,双行]:



配置:



歌词配置[当时我还没有学XML,实现来源于网上]:

<configuration>  <appSettings>    <add key="lrcDir" value="E:\music\AIRPLAY.DAT\Lyrics" />    <add key="playState" value="2" />    <add key="sound" value="28" />    <add key="DeskIsDoubleline" value="true" />    <add key="DeskFontFamily" value="英章楷书" />    <add key="DeskFontSize" value="27.75" />    <add key="DeskFontStyle" value="bold" />    <add key="DeskNormalColor" value="-65536" />    <add key="DeskLightColor" value="-16711936" />    <add key="FontSize" value="15" />    <add key="NormalColor" value="-4144960" />    <add key="LightColor" value="-16711872" />    <add key="BackColor" value="-16777216" />    <add key="FontStyle" value="bold" />    <add key="FontFamily" value="英章楷书" />    <add key="DeskBackColor" value="-16777216" />  </appSettings></configuration>

读取配置文件的核心处理类:

using System;using System.Collections.Generic;using System.Text;using System.Xml;namespace LrcCollection{    internal class Config    {        public static string GetValue(string AppKey)        {            try            {                XmlDocument document = new XmlDocument();                document.Load(System.AppDomain.CurrentDomain.BaseDirectory + "LrcSet.xml");                XmlElement element = (XmlElement)document.SelectSingleNode("//appSettings").SelectSingleNode("//add[@key='" + AppKey + "']");                if (element != null)                {                    return element.GetAttribute("value");                }                return null;            }            catch            {                return null;            }        }        public static void SetValue(string AppKey, string AppValue)        {            try            {                XmlDocument document = new XmlDocument();                document.Load(System.AppDomain.CurrentDomain.BaseDirectory + "LrcSet.xml");                XmlNode node = document.SelectSingleNode("//appSettings");                XmlElement element = (XmlElement)node.SelectSingleNode("//add[@key='" + AppKey + "']");                if (element != null)                {                    element.SetAttribute("value", AppValue);                }                else                {                    XmlElement newChild = document.CreateElement("add");                    newChild.SetAttribute("key", AppKey);                    newChild.SetAttribute("value", AppValue);                    node.AppendChild(newChild);                }                document.Save(System.AppDomain.CurrentDomain.BaseDirectory + "LrcSet.xml");            }            catch            {                SetValue(AppKey, AppValue, true);            }        }        public static void SetValue(string AppKey, string AppValue, bool tt)        {            XmlDocument document = new XmlDocument();            XmlNode node = document.CreateNode(XmlNodeType.Element, "configuration", "");            document.AppendChild(node);            XmlNode node2 = document.CreateNode(XmlNodeType.Element, "appSettings", "");            node.AppendChild(node2);            XmlElement newChild = document.CreateElement("add");            newChild.SetAttribute("key", AppKey);            newChild.SetAttribute("value", AppValue);            node2.AppendChild(newChild);            document.Save(System.AppDomain.CurrentDomain.BaseDirectory + "LrcSet.xml");        }    }}

下面是画歌词的处理类[现在自己都看不懂当初是如何实现的了,贴在这里吧。]:

说一说主要的思想:

画歌词的面板一定要继承UserControl类,然后重写其protected override void OnPaint(PaintEventArgs pe)方法,实现双缓冲,在这里面画歌词。

画卡拉OK歌词的原理是:先画背景[底层],再画你要显示的所有歌词[中间层],每行歌词都是顺序向下的,中间有间距,然后再你画好的歌词上面,画卡拉OK歌词,也就是高亮显示的那一行歌词[最上层],这一行歌词会覆盖之前画的中间层歌词的那一行,当然这样它还不是卡拉OK显示的,卡拉OK显示就要取出当前这句歌词和下一句歌词之间的时间,然后从左至右,匀速的画上高亮显示的这一行,看起来就是卡拉OK显示出来了。像酷狗这种歌词是经过精准处理的。

桌面歌词就很简单了,主要是一个无标题的窗体,做上鼠标移动事件即可拖动,单行,双行歌词也只不过是多了一层判断。双行就是每次唱完一句就取出下一句画在面板上。单行就是唱一句画一句。

using System;using System.Collections.Generic;using System.ComponentModel;using System.Drawing;using System.Data;using System.Linq;using System.Text;using System.Windows.Forms;using System.Drawing.Text;using System.Drawing.Drawing2D;using System.IO;using System.Runtime.Serialization.Formatters.Binary;using System.Collections;using LrcCollection;namespace MediaPlayer{    public partial class DeskLrcControl : UserControl    {        public DeskLrcControl()        {            InitializeComponent();            Size1(this.Size);            Components();            this.DoubleBuffered = true;        }        #region 字段        public LrcPanel lrcPanel = null;        private ArrayList lrcConfig = new ArrayList();        int width = 0;        Bitmap imgBack;        Bitmap imgLrc;        int middleTime = 0;        public string currentPosition = null;        int minute;        int second;                public Dictionary<int, string> lrcSortedList = new Dictionary<int, string>();//用来保存歌词和时间排序后的集合        private SolidBrush backBrush;        private SolidBrush lightBrush;        private Color backColor;        private Font fontStyle;        private StringFormat stringFormatter;        [Description("普通歌词颜色"), Category("歌词样式设置")]        public SolidBrush BackBrush        {            get { return backBrush; }            set { backBrush = value; }        }        [Description("高亮歌词颜色"), Category("歌词样式设置")]        public SolidBrush LightBrush        {            get { return lightBrush; }            set { lightBrush = value; }        }        [Description("歌词背景颜色"), Category("歌词样式设置")]        public Color BackColors        {            get { return backColor; }            set { backColor = value; }        }        [Description("当前歌曲时间"), Category("歌词样式设置")]        public string CurrentPosition        {            get { return currentPosition; }            set { currentPosition = value; }        }        [Description("歌词字体样式"), Category("歌词样式设置")]        public Font FontSty        {            get { return fontStyle; }            set { fontStyle = value; }        }        [Description("歌词字体排序"), Category("歌词样式设置")]        public StringFormat StringFormatter        {            get { return stringFormatter; }            set { stringFormatter = value; }        }        public override Color BackColor        {            get            {                return backColor;            }            set            {                base.BackColor = value;            }        }        public void Size1(Size s)        {            if (imgBack != null)            {                imgBack.Dispose();            }            if (imgLrc != null)            {                imgLrc.Dispose();            }            imgBack = new Bitmap(s.Width, s.Height);            imgLrc = new Bitmap(s.Width, s.Height);            //maxWidth = 0;            //lrcSortedList.Clear();            //Graphics g = Graphics.FromHwnd(this.contextMenuStrip1.Handle);            //for (int i = 0; i < tempTime.Length; i++)            //{            //    if (i + 1 < tempTime.Length)            //    {            //        if (g.MeasureString(lrcList.ElementAt(i).Value, fontStyle).Width > maxWidth)            //        {            //            maxWidth = (int)g.MeasureString(lrcList.ElementAt(i).Value, fontStyle).Width;            //        }            //    }            //    lrcSortedList.Add(tempTime[i], lrcList[tempTime[i]]);            //}            //g.Dispose();            //imgBack = new Bitmap(maxWidth + 2, this.Height);            //imgLrc = new Bitmap(maxWidth + 2, this.Height);             //this.Refresh();        }        public override Size MinimumSize        {            get            {                return new Size(200, 20);            }            set            {                base.MinimumSize = value;            }        }        #endregion        protected override void OnPaint(PaintEventArgs pe)        {            if (currentPosition != null)            {                if (load == false)                {                    Components();                    load = true;                }                DrawString(currentPosition, pe.Graphics, BackBrush, LightBrush, this.fontStyle, this.BackColor, stringFormatter);                pe.Dispose();            }        }        bool load = false;        #region //初始化        public void Components()        {            try            {                backBrush = new SolidBrush(Color.FromArgb(Convert.ToInt32(Config.GetValue("DeskNormalColor"))));                lightBrush = new SolidBrush(Color.FromArgb(Convert.ToInt32(Config.GetValue("DeskLightColor"))));                backColor = Color.FromArgb(Convert.ToInt32(Config.GetValue("DeskBackColor")));                FontStyle f = FontStyle.Regular;                if (Config.GetValue("DeskFontStyle") == "bold")                {                    f = FontStyle.Bold;                }                else if (Config.GetValue("DeskFontStyle") == "italic")                {                    f = FontStyle.Italic;                }                else if (Config.GetValue("DeskFontStyle") == "strikeout")                {                    f = FontStyle.Strikeout;                }                else if (Config.GetValue("DeskFontStyle") == "underline")                {                    f = FontStyle.Underline;                }                else                {                    f = FontStyle.Regular;                }                fontStyle = new Font(Config.GetValue("DeskFontFamily"), float.Parse(Config.GetValue("DeskFontSize")),f);                if (Config.GetValue("DeskIsDoubleline") != null)                {                    isDoubleLine = Convert.ToBoolean(Config.GetValue("DeskIsDoubleline"));                }                stringFormatter = new StringFormat();                stringFormatter.Alignment = StringAlignment.Center;                stringFormatter.LineAlignment = StringAlignment.Center;                stringFormatter.Trimming = StringTrimming.Character;            }            catch            {                backBrush = new SolidBrush(Color.Blue);                lightBrush = new SolidBrush(Color.Red);                backColor = Color.Black;                fontStyle = new Font("幼圆", 34f);                stringFormatter = new StringFormat();                stringFormatter.Alignment = StringAlignment.Center;                stringFormatter.LineAlignment = StringAlignment.Center;                stringFormatter.Trimming = StringTrimming.Character;            }        }        #endregion        #region 画歌词        public bool isKana = true;        public bool isTranKey = true;        public bool isDoubleLine = true;        SizeF imgSize = SizeF.Empty;        SizeF img1 = SizeF.Empty;        public string DrawString(string nowTime, Graphics g, SolidBrush backBrush, SolidBrush lightBrush, Font f, Color backColor, StringFormat format)        {            if (isTranKey == true)            {                this.BackColors = Color.Transparent;                this.FindForm().BackColor = Color.Turquoise;                this.FindForm().TransparencyKey = Color.Turquoise;            }            if (lrcSortedList.Count > 0 && LrcConnections.lrcPath != null)            {                Size1(this.FindForm().Size);//歌词居中                imgLrc = DrawLrcImg(nowTime, lightBrush, backBrush, f, backColor, format);                if (isKana == true)                {                    imgBack = ShowLrc(backBrush, f, backColor, format);//画背景歌词                    g.CompositingQuality = CompositingQuality.HighQuality;                    g.SmoothingMode = SmoothingMode.AntiAlias;                    g.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit;                    if (imgLrc != null && imgBack != null)                    {                        Rectangle rec = new Rectangle(0, 0, width, this.imgLrc.Height);                        g.DrawImage(imgBack, 0, 0);                        //画当前高亮显示的歌词,其实就是画歌词图像的一部分,以像素显示会呈现卡拉OK歌词                        g.DrawImage(imgLrc, 0, 0, rec, GraphicsUnit.Pixel);                        //g.Flush();                    }                }                else if (imgLrc != null)                {                    g.DrawImage(imgLrc, 0, 0);                    //g.Flush();                }            }            else            {                if (LrcConnections.lrcPath == null)                {                    Graphics gg = Graphics.FromImage(imgBack);                    gg.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit;                    gg.CompositingQuality = CompositingQuality.HighQuality;                    gg.SmoothingMode = SmoothingMode.AntiAlias;                    SizeF imgSize = gg.MeasureString("对不起,没有找到歌词,您可以手动指定歌词", f);//当前歌词长度                    this.FindForm().Size = new Size((int)imgSize.Width, (int)imgSize.Height);                    Size1(this.Size);                    gg.Dispose();                    gg = Graphics.FromImage(imgBack);                    gg.DrawString("对不起,没有找到歌词,您可以手动指定歌词", f, backBrush, 0, 0);                    gg.Dispose();                    g.DrawImage(imgBack, 0, 0);                }            }            return null;        }        #endregion        #region 显示高亮歌词的方法        private Bitmap DrawLrcImg(string currentTime, SolidBrush lightBrush, SolidBrush backBrush, Font f, Color backColor, StringFormat format)        {            if (currentTime == "" || currentTime == null)            {                return null;            }            if (imgLrc == null)            {                return null;            }            Graphics gra = Graphics.FromImage(imgLrc);            gra.Clear(backColor);            minute = Convert.ToInt32(currentTime.Substring(0, 2)) * 60;//分钟转为秒            second = Convert.ToInt32(currentTime.Substring(3));            for (int i = 0; i < lrcSortedList.Count - 1; i++)            {                if (lrcSortedList.ElementAt(i).Key == (minute + second))//高亮显示当前歌词                {                    //float lrcWidth = g.MeasureString(lrcSortedList.ElementAt(i).Value, f).Width;                    UserHelper.currentLrcIndex = i;                    width = 0;                    break;                }            }            if ((UserHelper.currentLrcIndex + 1) <= lrcSortedList.Count)            {                middleTime = lrcSortedList.ElementAt(UserHelper.currentLrcIndex + 1).Key - lrcSortedList.ElementAt(UserHelper.currentLrcIndex).Key;            }            imgSize = gra.MeasureString(lrcSortedList.ElementAt(UserHelper.currentLrcIndex).Value, f);//当前歌词长度            if (isDoubleLine == false)            {                this.FindForm().Size = new Size((int)imgSize.Width, (int)imgSize.Height);                Size1(this.Size);            }            else//如果是双行的话            {                if (UserHelper.currentLrcIndex < lrcSortedList.Count - 1)                {                    img1 = gra.MeasureString(lrcSortedList.ElementAt(UserHelper.currentLrcIndex + 1).Value, f);                }                if (imgSize.Width > img1.Width)                {                    this.FindForm().Size = new Size((int)imgSize.Width, (int)imgSize.Height * 2);                    Size1(this.Size);                }                else                {                    this.FindForm().Size = new Size((int)img1.Width, (int)img1.Height * 2);                    Size1(this.Size);                }                gra.Dispose();            }            if (width == 0)            {                width++;            }            else            {                width += (int)(imgSize.Width / (middleTime * 6));//歌词匀速以卡拉OK形式前进,毫秒化为秒            }            Graphics g = Graphics.FromImage(imgLrc);            g.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit;            g.CompositingQuality = CompositingQuality.HighQuality;            g.SmoothingMode = SmoothingMode.AntiAlias;            if (isDoubleLine == false)            {                g.DrawString(lrcSortedList.ElementAt(UserHelper.currentLrcIndex).Value, f, lightBrush, 0, 0);            }            else            {                if (UserHelper.currentLrcIndex % 2 == 0)                {                    g.DrawString(lrcSortedList.ElementAt(UserHelper.currentLrcIndex).Value, f, lightBrush, 0, 0);                    if (UserHelper.currentLrcIndex < lrcSortedList.Count - 1)                    {                        g.DrawString(lrcSortedList.ElementAt(UserHelper.currentLrcIndex + 1).Value, f, backBrush, 0, f.Height);                    }                }                else                {                    if (UserHelper.currentLrcIndex < lrcSortedList.Count - 1)                    {                        g.DrawString(lrcSortedList.ElementAt(UserHelper.currentLrcIndex + 1).Value, f, backBrush, 0, 0);                    }                    g.DrawString(lrcSortedList.ElementAt(UserHelper.currentLrcIndex).Value, f, lightBrush, 0, f.Height);                }            }            //g.Flush();            g.Dispose();            return imgLrc;        }        #endregion        #region 显示背景歌词的方法        public Bitmap ShowLrc(SolidBrush backBrush, Font f, Color backColor, StringFormat format)        {            Graphics gra = Graphics.FromImage(imgBack);            gra.Clear(backColor);            //Font f1 = new Font(f.FontFamily, f.Size + 0.2f, FontStyle.Regular);            //for (int index = 0; index < lrcSortedList.Count - 1; index++)            //{            //    Graphics g = Graphics.FromImage(imgBack);            //    g.SmoothingMode = SmoothingMode.AntiAlias;            //    g.DrawString(lrcSortedList.ElementAt(index).Value, f1, new SolidBrush(Color.Blue), this.imgBack.Width / 2, f.Height * (index + space + 1 + lines), format);            //    g.Dispose();            //}            //f1.Dispose();            //显示歌词            Graphics g = Graphics.FromImage(imgBack);            g.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit;            g.CompositingQuality = CompositingQuality.HighQuality;            g.SmoothingMode = SmoothingMode.AntiAlias;            if (isDoubleLine == false)            {                g.DrawString(lrcSortedList.ElementAt(UserHelper.currentLrcIndex).Value, f, backBrush, 0, 0);            }            else            {                if (UserHelper.currentLrcIndex % 2 == 0)                {                    g.DrawString(lrcSortedList.ElementAt(UserHelper.currentLrcIndex).Value, f, backBrush, 0, 0);                    if (UserHelper.currentLrcIndex < lrcSortedList.Count - 1)                    {                        g.DrawString(lrcSortedList.ElementAt(UserHelper.currentLrcIndex + 1).Value, f, backBrush, 0, f.Height);                    }                }                else                {                    g.DrawString(lrcSortedList.ElementAt(UserHelper.currentLrcIndex + 1).Value, f, backBrush, 0, 0);                    g.DrawString(lrcSortedList.ElementAt(UserHelper.currentLrcIndex).Value, f, backBrush, 0, f.Height);                }            }            //g.Flush();            g.Dispose();            return imgBack;        }        #endregion    }}




歌词繁简转换也很容易:

 /// <summary>        /// 简体到繁体转换        /// </summary>        /// <param name="simplifiedChinese">简体</param>        /// <returns>繁体</returns>        private string SimplifiedToTraditional(string simplifiedChinese)        {            string traditionalChinese = string.Empty;            System.Globalization.CultureInfo vCultureInfo = new System.Globalization.CultureInfo("zh-CN", false);            traditionalChinese = Microsoft.VisualBasic.Strings.StrConv(simplifiedChinese, Microsoft.VisualBasic.VbStrConv.TraditionalChinese, vCultureInfo.LCID);            return traditionalChinese;        }        /// <summary>        /// 繁体到简体转换        /// </summary>        /// <param name="traditionalChinese">繁体</param>        /// <returns>简体</returns>        private string TraditionalToSimplified(string traditionalChinese)        {            string simplifiedChinese = string.Empty;            System.Globalization.CultureInfo vCultureInfo = new System.Globalization.CultureInfo("zh-CN", false);            simplifiedChinese = Microsoft.VisualBasic.Strings.StrConv(traditionalChinese, Microsoft.VisualBasic.VbStrConv.SimplifiedChinese, vCultureInfo.LCID);            return simplifiedChinese;        }



歌词窗体出现时是动态显示的,以及全局快捷键的[当时只知道使用系统的user32.dll实现的]代码如下:

using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using System.Threading;using System.Runtime.InteropServices;using System.Collections;using System.IO;using System.Runtime.Serialization.Formatters.Binary;namespace MediaPlayer{    public partial class LrcFrm : Form    {        public AxWMPLib.AxWindowsMediaPlayer axWmplayer;        public System.Windows.Forms.Timer timer;        //动画窗体调用        [System.Runtime.InteropServices.DllImport("user32")]        private static extern bool AnimateWindow(IntPtr hwnd, int dwTime, int dwFlags);        const int AW_HOR_POSITIVE = 0x0002;        const int AW_HOR_NEGATIVE = 0x0004;        const int AW_VER_POSITIVE = 0x0008;        const int AW_VER_NEGATIVE = 0x00016;        const int AW_CENTER = 0x0010;        const int AW_HIDE = 0x10000;        const int AW_ACTIVATE = 0x20000;        const int AW_SLIDE = 0x20000;        const int AW_BLEND = 0x80000;        public LrcFrm(AxWMPLib.AxWindowsMediaPlayer axWmplayer,System.Windows.Forms.Timer timer)        {            InitializeComponent();            this.DoubleBuffered = true;            LrcConnections.lrcfrm = this;            LrcConnections.lrcPanel = this.lrcPanel1;            this.axWmplayer = axWmplayer;            this.timer = timer;        }        #region 字段        public override Size MinimumSize        {            get            {                return new Size(100, 100);            }            set            {                base.MinimumSize = value;            }        }        #endregion        #region //注册热键        [DllImport("user32.dll", SetLastError = true)]        public static extern bool RegisterHotKey(                IntPtr hWnd, // handle to window                  int id, // hot key identifier                  KeyModifiers fsModifiers, // key-modifier options                  System.Windows.Forms.Keys vk // virtual-key code          );        [DllImport("user32.dll", SetLastError = true)]        public static extern bool UnregisterHotKey(            IntPtr hWnd, // handle to window              int id // hot key identifier          );        [Flags]        public enum KeyModifiers        {            None = 0,            Alt = 1,            Control = 2,            Shift = 4,            Windows = 8        }        private const int WM_HOTKEY = 0x312; //窗口消息-热键        private const int WM_CREATE = 0x1; //窗口消息-创建        private const int WM_DESTROY = 0x2; //窗口消息-销毁        private const int MOD_ALT = 0x1; //ALT        private const int MOD_CONTROL = 0x2; //CTRL        private const int MOD_SHIFT = 0x4; //SHIFT        private const int VK_SPACE = 0x20; //SPACE         protected override void WndProc(ref Message m)        {            //base.WndProc(ref m);            switch (m.Msg)            {                case WM_HOTKEY: //窗口消息-热键                    switch (m.WParam.ToString())                    {                        case "1989":                            this.lrcPanel1.showFullScreen();                            break;                        case "11": //热键ID                            this.lrcPanel1.KanaOK();                            break;                        case "12":                            this.lrcPanel1.showLrcSetFrm();                            break;                        case "13":                            this.lrcPanel1.showLrc();                            break;                        case "14":                            this.lrcPanel1.showFullScreen();                            break;                        case "15": //热键ID                            Helper.main.PlayNext();                            break;                        case "16":                            Helper.main.playPre();                            break;                        //case "17":                        //    this.lrcPanel1.showLrc();                        //    break;                        //case "18":                        //    this.lrcPanel1.showFullScreen();                        //    break;                        default:                            break;                    }                    break;                case WM_CREATE: //窗口消息-创建                    RegisterHotKey(this.Handle, 1989, KeyModifiers.None, Keys.Escape);                    RegisterHotKey(this.Handle, 11, KeyModifiers.Control | KeyModifiers.Alt, Keys.K);                    RegisterHotKey(this.Handle, 12, KeyModifiers.Control | KeyModifiers.Alt, Keys.G);                    RegisterHotKey(this.Handle, 13, KeyModifiers.Control | KeyModifiers.Alt, Keys.D);                    RegisterHotKey(this.Handle, 14, KeyModifiers.Control | KeyModifiers.Alt, Keys.F);                    //播放控制                    //下一首                    RegisterHotKey(this.Handle, 15, KeyModifiers.Control | KeyModifiers.Alt, Keys.Right);                    //上一首                    RegisterHotKey(this.Handle, 16, KeyModifiers.Control | KeyModifiers.Alt, Keys.Left);                    //音量加                   // RegisterHotKey(this.Handle, 17, KeyModifiers.Control | KeyModifiers.Alt, Keys.Up);                    //音量减                  //  RegisterHotKey(this.Handle, 18, KeyModifiers.Control | KeyModifiers.Alt, Keys.Down);                                      break;                case WM_DESTROY: //窗口消息-销毁                    UnregisterHotKey(this.Handle, 1989);                    UnregisterHotKey(this.Handle, 11); //销毁热键                    UnregisterHotKey(this.Handle, 12);                    UnregisterHotKey(this.Handle, 13);                    UnregisterHotKey(this.Handle, 14);                    UnregisterHotKey(this.Handle, 15);                    UnregisterHotKey(this.Handle, 16);                  //  UnregisterHotKey(this.Handle, 17);                   // UnregisterHotKey(this.Handle, 18);                    break;                default:                    break;            }            base.WndProc(ref m);        }        #endregion        private void LrcFrm_Load(object sender, EventArgs e)        {            Thread t = new Thread(loadLrc);            t.IsBackground = true;            t.Start();            //动画由小渐大,现在取消            AnimateWindow(this.Handle, 2000, AW_CENTER | AW_ACTIVATE);        }        private void loadLrc()        {            int i = 0;            while (LrcConnections.isReading == true)            {                Thread.Sleep(1000);                i++;                if (LrcConnections.isReading == false || i == 5)                {                    break;                }            }            if (LrcConnections.isReading == false)            {                this.lrcPanel1.lrcSortedList = LrcConnections.lrcSortedList;            }            Thread.CurrentThread.Abort();        }        #region//改变窗体大小时  歌词面板改变        private void LrcFrm_Resize(object sender, EventArgs e)        {            this.lrcPanel1.Size1(this.Size);//歌词居中            this.lrcPanel1.ChangeSize();        }        #endregion        private void LrcFrm_FormClosing(object sender, FormClosingEventArgs e)        {            this.Visible = false;            e.Cancel = true;            //存储当前状态        }    }}

如果你想单独试试双缓冲,可以试试这个,你可以拿它和没有使用双缓冲的timer比较下:

using System;using System.Collections.Generic;using System.ComponentModel;using System.Drawing;using System.Data;using System.Linq;using System.Text;using System.Windows.Forms;namespace MediaPlayer{    public partial class myLabel : UserControl    {         public myLabel()        {            InitializeComponent();            Timer t = new Timer();            this.DoubleBuffered = true;            t.Interval = 1000;            t.Tick += new EventHandler(t_Tick);            t.Enabled = true;        }        protected override void OnPaint(PaintEventArgs pe)        {            Draw(pe.Graphics);            pe.Dispose();        }        //程序人生 人生如戏 戏如人生 却不能游戏人生        void t_Tick(object sender, EventArgs e)        {            this.Refresh();        }        private void Draw(Graphics g)        {            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;            Font f = new Font("华文行楷", 35F, FontStyle.Italic);            SolidBrush fontB = new SolidBrush(Color.Gray);            SolidBrush fontA = new SolidBrush(Color.Red);            //先画阴影,坐标偏移5            g.DrawString("程序", f, fontB, 15, 30);            g.DrawString("人生", f, fontB, 15, this.Size.Height / 2 + 15);            //再画字体            g.DrawString("程序", f, fontA, 0, 15);            g.DrawString("人生", f, fontA, 0, this.Size.Height / 2);        }            //Font f1 = new Font("幼圆", 15F, FontStyle.Regular);            //SolidBrush fontC = new SolidBrush(Color.LightGray);            //for (int i = 0; i <= 360; i += 60)            //{            //    //平移Graphics对象到窗体中心            //    g.TranslateTransform(this.Width / 2, this.Height / 2);            //    //设置Graphics对象的输出角度            //    g.RotateTransform(i);            //    //设置文字填充颜色            //    //旋转显示文字            //    g.DrawString("土豆水印", f1, fontC, 10, 10);            //    //恢复全局变换矩阵            //    g.ResetTransform();            //}    }}

搜索歌词的方法,一种很笨的方法:

 string song = null;        List<int> songIndex = new List<int>();        private void btnFind_Click(object sender, EventArgs e)        {            if (song != null && song != txtSong.Text.Trim())            {                songIndex.Clear();                song = txtSong.Text.Trim();            }            else if (song == null)            {                song = txtSong.Text.Trim();            }            if (song != null && song != "")            {                for (int flag = 0; flag < lbPlayerList.Items.Count; flag++)                {                    if (songIndex.Contains(flag))                    {                        continue;                    }                    if (lbPlayerList.Items[flag].ToString().Contains(txtSong.Text.Trim()))                    {                        songIndex.Add(flag);                        lbPlayerList.SelectedIndex = flag;                        break;                    }                    else                    {                        //如果到了末尾,清空集合。下次从新开始                        if (flag == lbPlayerList.Items.Count - 1)                        {                            MessageBox.Show("已经到了末尾...");                            songIndex.Clear();                        }                    }                }            }        }

如果你看到了关于窗体,你可能找不到上面显示的文字从哪来,事实上里面有2个dll文件,它描述的版本,作者,制作时间等信息,只有用特性和反射机制才可能读出来。

特性:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using AttributeTudou;namespace AttributeReflection{    /// <summary>    /// 特性,更新版本时可用反射读取此程序的信息    ///     /// 作者,创建时间,最后修改时间,公司名称,产品名称,版本,声明    /// </summary>    [AttibuteTuDou("很拽の土豆", "2009年12月", "2011年2月", "土豆工作室", "雅风随风", "1.0.0", "CopyRight 2011 很拽の土豆 All Rights Reserved", "以上一切信息版权归原作者所有\r\n\r\n郑重声明:版权所有,翻版不究\r\n\r\n\r\t\r\t2009.12\r\t很拽の土豆\r\nQQ:475589699\r\n邮箱:yaerfeng1989@163.com")]    public class Tudou    {    }}

using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace AttributeTudou{    [AttributeUsage(AttributeTargets.All, AllowMultiple = true)]//允许多个访问,可以对任何应用程序的元素应用此特性    public class AttibuteTuDou : Attribute    {        public AttibuteTuDou()        {        }        public AttibuteTuDou(string author,string createDate,string lastUpDate,string comp,string producter,string version,string copyRight,string otherDesc)        {            this.Author = author;            this.CreateDate = createDate;            this.LastUpTime = lastUpDate;            this.Company = comp;            this.Producter = producter;            this.Version = version;            this.CopyRight = copyRight;            this.OtherDesc =otherDesc;        }        private string author;        public string Author        {            get { return author; }            set { author = value; }        }        private string createDate;        public string CreateDate        {            get { return createDate; }            set { createDate = value; }        }        private string lastUpTime;        public string LastUpTime        {            get { return lastUpTime; }            set { lastUpTime = value; }        }        private string version;        public string Version        {            get { return version; }            set { version = value; }        }        private string company;        public string Company        {            get { return company; }            set { company = value; }        }        private string producter;        public string Producter        {            get { return producter; }            set { producter = value; }        }        private string otherDesc;        public string OtherDesc        {            get { return otherDesc; }            set { otherDesc = value; }        }        private string copyRight;        public string CopyRight        {            get { return copyRight; }            set { copyRight = value; }        }    }}


如何读取:

如果你眼睛好,你会发现这里面还有2个方法

1个是用记事本打开歌词的,1个是定位文件[给一个路经它,它会自动在电脑上帮你定位这个文件]的。前者可能简单,但后者却更实用。

实现方法分别为:

System.Diagnostics.Process.Start("NOTEPAD.EXE", 文本的路径);

System.Diagnostics.Process.Start("explorer.exe", "/select," + 文本的路径);

整体代码如下:

using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using System.IO;using System.Runtime.Serialization.Formatters.Binary;using LrcCollection;using AttributeTudou;using System.Reflection;namespace MediaPlayer{    public partial class LrcSetFrm : Form    {        //private Font fontStyle;        private Color normalColor;        private Color lightColor;        private Color backColor;        private LrcPanel lrcPanel;        public LrcSetFrm(LrcPanel lrcPanel)        {            InitializeComponent();            this.lrcPanel = lrcPanel;            tudou = AssemblyTitle;            this.Text = String.Format("关于 {0}", AssemblyProduct);            this.labelProductName.Text = AssemblyProduct;            this.labelVersion.Text = String.Format("版本 {0}", AssemblyVersion);            this.labelCopyright.Text = AssemblyCopyright;            this.labelCompanyName.Text = AssemblyCompany;            this.textBoxDescription.Text = AssemblyDescription;        }        private void btnOpenLrc_Click(object sender, EventArgs e)        {            if (txtPath.Text.Trim() != "" && txtPath.Text.Trim() != null)            {                if (File.Exists(txtPath.Text))                {                    System.Diagnostics.Process.Start("NOTEPAD.EXE", txtPath.Text);                }                else                {                    MessageBox.Show("对不起,不存在该文件!");                }            }        }        private void btnOpenLrcFile_Click(object sender, EventArgs e)        {            if (textBox1.Text.Trim() != "" && textBox1.Text.Trim() != null)            {                if (Directory.Exists(textBox1.Text))                {                    System.Diagnostics.Process.Start("explorer.exe", "/select," + textBox1.Text);                }                else                {                    MessageBox.Show("对不起,不存在该文件夹,请重新指定文件夹!");                }            }        }        AttibuteTuDou tudou = null;        #region 程序集属性访问器        public AttibuteTuDou AssemblyTitle        {            get            {                Assembly ass = Assembly.Load("AttributeReflection");                Type[] t = ass.GetTypes();                foreach (Type type in t)                {                    Attribute[] attributes = Attribute.GetCustomAttributes(type);                    if (attributes.Length > 0)                    {                        foreach (Attribute a in attributes)                        {                            tudou = (AttibuteTuDou)a;                            return tudou;                        }                    }                }                return null;            }        }        public string AssemblyVersion        {            get            {                if (tudou != null)                {                    return tudou.Version;                }                return "1.0.0";            }        }        public string AssemblyDescription        {            get            {                if (tudou != null)                {                    return tudou.OtherDesc;                }                return "支持作者 支持原创";            }        }        public string AssemblyProduct        {            get            {                if (tudou != null)                {                    return tudou.Producter;                }                return "土豆作品";            }        }        public string AssemblyCopyright        {            get            {                if (tudou != null)                {                    return tudou.CopyRight;                }                return "CopyRights  € 2010";            }        }        public string AssemblyCompany        {            get            {                if (tudou != null)                {                    return tudou.Company;                }                return "土豆工作室";            }        }        public string CreateDate        {            get            {                if (tudou != null)                {                    return tudou.CreateDate;                }                return null;            }        }        public string LastUpDate        {            get            {                if (tudou != null)                {                    return tudou.LastUpTime;                }                return null;            }        }        public string author        {            get            {                if (tudou != null)                {                    return tudou.Author;                }                return "很拽の土豆";            }        }        #endregion        private void btnDel_Click(object sender, EventArgs e)        {            if (this.txtPath.Text != null)            {                FileInfo f = new FileInfo(this.txtPath.Text);                if (f.Exists)                {                    if (MessageBox.Show("确认永久删除歌词" + f.FullName + "?","警告",MessageBoxButtons.OKCancel,MessageBoxIcon.Warning) == DialogResult.OK)                    {                        f.Delete();                    }                }            }        }    }}

想想曾经为做这个付出的心血,不得不自己苦笑一下,兴趣吧,也许只是因为曾经的兴趣,有机会,我会再研究一下C#的。等我快老了吧。

一个非常简单的东西我却会用到高级特性,反射,系统热键注册,双缓冲,也许是因为有了需求,才有了结果吧。

先学好JAVA,做好当前事。


原创粉丝点击