`
java-mans
  • 浏览: 11428322 次
文章分类
社区版块
存档分类
最新评论

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

 
阅读更多

学生时代做的一个非常低级的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,做好当前事。


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics