CCMP之播放列表(高仿千千静听)
这是本人第一次写博客,写的不好还请大家不要介意。好了废话不多说。我第一次接触千千是我大学的第一年,那时候我发现千千真的做的很好,由于我也是学编程,所有我就想自己也写个播放器出来。CCMP播放器是我的几个版本中的最后的一个版本,程序使用VS2005开发.仿照了很多千千的功能做的也比较好了。当然在高手中看来什么都不是。以下是播放的运行切图
迷你界面
以前做的系统,播放列表我继承的是ListBox然后再重写DrawItem,这一版本我直接基础Control基类列表全部自绘.
/// <summary> /// 初始化各项状态属性 /// </summary> /// <param name="e">为 System.Windows.Forms.Control.Paint 事件提供数据</param> private void PaintCell(PaintEventArgs e) { using (Brush b = new SolidBrush(lbackcolor)) { e.Graphics.FillRectangle(b, InnerRectangle); } Rectangle innerRect = InnerRectangle; if (items.Count * Font.Height > Height) { innerRect.Width -= scrollbar.Width; int visibleitems = Convert.ToInt32(Math.Floor((double)innerRect.Height / (double)Font.Height)); scrollbar.Height = Height; scrollbar.Maximum = items.Count - 1; scrollbar.LargeChange = visibleitems; scrollbar.Show(); } int top = innerRect.Top; for (int i = 0; i < items.Count; i++) { if (scrollbar.Visible && !IsIndexRangeVisible(i, i)) { continue; } Rectangle drawRect = new Rectangle(innerRect.Left, top, innerRect.Width,Font.Height); drawRect.Intersect(innerRect); DrawItemState state = DrawItemState.None; if (i == checkedindex) state |= DrawItemState.Selected; if (has_focus && (selectedindexs.Contains(i) || selectindex == i)) state |= DrawItemState.Focus; DrawItems(new DrawItemEventArgs(e.Graphics,Font, drawRect, i, state)); top +=Font.Height; } } /// <summary> /// 绘制列表项 /// </summary> /// <param name="e">为 DrawItem 事件提供数据</param> private void DrawItems(DrawItemEventArgs e) { Graphics g = e.Graphics; ListItem item = items[e.Index] as ListItem; string strcontext =(item == null ? items[e.Index].ToString() : item.ToString(formatstring)); string strindex = String.Format("♪{0:000}.",e.Index+1); string strduring =(item==null?"":item.During); SizeF sizecontext = g.MeasureString(strcontext, Font); float sizeindex = g.MeasureString(strindex, Font).Width; float sizeduring = g.MeasureString(strduring, Font).Width; int sizescroll = (scrollbar.Visible ? scrollbar.Width : 0); #region<-Draw Grill-> if (e.Index % 2 == 1) { using (Brush b = new SolidBrush(lbackcolor)) { g.FillRectangle(b, 0, e.Bounds.Top, Width, e.Bounds.Height); } } else { using (Brush b = new SolidBrush(lrbackcolor)) { g.FillRectangle(b, 0, e.Bounds.Top, Width, e.Bounds.Height); } } #endregion #region<-Draw All Items-> DrawContext(e, strindex, strcontext, strduring, sizecontext, sizeindex, sizeduring, sizescroll, lindexcolor, ltitlecolor, llenghtcolor); #endregion #region <-Draw Focus Item-> if ((e.State & DrawItemState.Focus) == DrawItemState.Focus) { DrawBorder(e, llightcolor, bordercolor, sizescroll); DrawContext(e, strindex, strcontext, strduring, sizecontext, sizeindex, sizeduring, sizescroll, bordercolor, bordercolor, bordercolor); } #endregion #region <-Draw Checked Item-> if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) { if ((e.State & DrawItemState.Focus) == DrawItemState.Focus) { DrawBorder(e, llightcolor, bordercolor, sizescroll); DrawContext(e, strindex, strcontext, strduring, sizecontext, sizeindex, sizeduring, sizescroll, bordercolor, bordercolor, bordercolor); } else { DrawContext(e, strindex, strcontext, strduring, sizecontext, sizeindex, sizeduring, sizescroll, lselectcolor, lselectcolor,llenghtcolor); } } #endregion #region <-Draw Search Items-> if (searchindex == e.Index) { DrawBorder(e, Color.Blue, Color.Yellow, sizescroll); DrawContext(e, strindex, strcontext, strduring, sizecontext, sizeindex, sizeduring, sizescroll, bordercolor, bordercolor, bordercolor); } #endregion #region<Draw Error Items> if (errorindex == e.Index) { DrawBorder(e, Color.Red, Color.Yellow, sizescroll); DrawContext(e, strindex, strcontext, strduring, sizecontext, sizeindex, sizeduring, sizescroll, bordercolor, bordercolor, bordercolor); } #endregion #region<-Begin Drag-> if (begindrag) { using (Pen pen = new Pen(bordercolor)) { e.Graphics.DrawLine(pen, new Point(0, e.Bounds.Top + e.Bounds.Height), new Point(Width, e.Bounds.Top + e.Bounds.Height)); } } #endregion } /// <summary> /// 绘制正文 /// </summary> /// <param name="e">为 DrawItem 事件提供数据</param> /// <param name="strindex">序号</param> /// <param name="strcontext">正文</param> /// <param name="strduring">长度</param> /// <param name="sizecontext">正文大小</param> /// <param name="sizeindex">序号宽度</param> /// <param name="sizeduring">长度宽度</param> /// <param name="sizescroll">滚动条宽度</param> /// <param name="indexcolor">序号颜色</param> /// <param name="titlecolor">正文颜色</param> /// <param name="lenghtcolor">长度颜色</param> private void DrawContext(DrawItemEventArgs e, string strindex, string strcontext, string strduring, SizeF sizecontext, float sizeindex, float sizeduring, int sizescroll, Color indexcolor, Color titlecolor, Color lenghtcolor) { Rectangle bound = e.Bounds; if (showindex) { using (Brush b = new SolidBrush(indexcolor)) { e.Graphics.DrawString(strindex, Font, b, new PointF(0, bound.Top)); } } else { sizeindex = 0; } using (Brush b = new SolidBrush(titlecolor)) { e.Graphics.DrawString(strcontext, Font, b, new RectangleF( sizeindex, bound.Top, Width - sizeindex - sizeduring - sizescroll - 5, sizecontext.Height)); } using(Brush b=new SolidBrush(lenghtcolor)) { e.Graphics.DrawString(strduring, Font, b, new PointF(Width -sizeduring- sizescroll, bound.Top)); } } /// <summary> /// 绘制边框 /// </summary> /// <param name="e">为 DrawItem 事件提供数据</param> /// <param name="lightcolor">高亮颜色</param> /// <param name="lbordercolor">外边框颜色</param> /// <param name="sizescroll">滚动条宽度</param> private void DrawBorder(DrawItemEventArgs e, Color lightcolor, Color lbordercolor, int sizescroll) { if (base.SkinBackImage == null) { using (LinearGradientBrush lg = new LinearGradientBrush( new Rectangle(0, e.Bounds.Top, base.Width - sizescroll - 1, e.Bounds.Height), Color.Empty, Color.Empty, LinearGradientMode.Vertical)) { ColorBlend cb = new ColorBlend(2); cb.Colors = new Color[] {lightcolor, lbackcolor}; cb.Positions = new float[] { 0f, 1f }; lg.InterpolationColors = cb; e.Graphics.FillRectangle(lg, lg.Rectangle); } } else { using (Bitmap bmp =(Bitmap)SkinBackImage.Clone()) { e.Graphics.DrawImage(bmp, new Rectangle( 1, e.Bounds.Top, base.Width - sizescroll - 1, e.Bounds.Height), 0, 0, bmp.Width, bmp.Height, GraphicsUnit.Pixel); } } if (selectedindexs.Count <1) { using (Pen pen = new Pen(lbordercolor)) { e.Graphics.DrawRectangle(pen, new Rectangle(1, e.Bounds.Top, Width - sizescroll - 2, e.Bounds.Height - 1)); } } } /// <summary> /// 绘制进度条 /// </summary> /// <param name="e">绘图对象</param> private void DrawProcess(Graphics e) { Pen pen = new Pen(Color.FromArgb(102, 102, 102)); Brush backbrush = new SolidBrush(Color.FromArgb(224, 224, 224)); e.FillRectangle(backbrush, new Rectangle(0, base.Height / 2, base.Width - scrollbar.Width, 22)); e.DrawRectangle(pen, new Rectangle(1, base.Height / 2 + 1, base.Width - scrollbar.Width - 2, 20)); pen.Dispose(); pen = null; backbrush.Dispose(); backbrush = null; double len = base.Width - scrollbar.Width - 8; len /= maximum; len *= values; if (((int)len) != 0) { Rectangle rect = new Rectangle(4, base.Height / 2 + 4, (int)len, 20 - 6); LinearGradientBrush lg = new LinearGradientBrush( rect, Color.FromArgb(188, 233, 143), Color.FromArgb(25, 127, 0), LinearGradientMode.Vertical); lg.GammaCorrection = true; e.FillRectangle(lg, lg.Rectangle); lg.Dispose(); lg = null; e.DrawRectangle(new Pen(Color.FromArgb(0, 102, 0)), rect); } double ind = 100; ind /= maximum; ind *= values; string str = string.Format("{0:00}%", (int)ind); SizeF f = e.MeasureString(str, base.Font); e.DrawString(str, base.Font, new SolidBrush(control.ForeColor), new PointF(base.Width / 2 - f.Width / 2, base.Height / 2 + 4)); }
列表项定位
/// <summary> /// 根据坐标查询列表项位置 /// </summary> /// <param name="p">需要查询的坐标点</param> /// <returns>该点的列表项位置</returns> private int HitIndex(Point p) { Rectangle innerRect = InnerRectangle; if (control.ClientRectangle.Contains(p)) { if (innerRect.Contains(p)) { int min = 0; int index = Convert.ToInt32(Math.Floor((double)(p.Y) / (double)control.Font.Height)) + scrollbar.Value; index = index < min ? min : index; if (index >= items.Count) { return items.Count - 1; } else { return index; } } } return SelectedIndex; }
实现点击选择事件
protected override void OnMouseMove(MouseEventArgs e) { int tipindex = HitIndex(e.X, e.Y); try { if (showtooltip && lasttipindex != tipindex) { ListItem item =items[tipindex] as ListItem; if (item != null) { string str = string.Format("标 题:{0}/r/n专 辑:{1}/r/n艺术家:{2}/r/n格 式:{3}/r/n长 度:{4}/r/n文件名:{5}", item.Title, item.Album, item.Author, item.Code, item.During, item.FileName); tooltip.SetToolTip(control, str); } lasttipindex = tipindex; } } catch { } if (e.Button == MouseButtons.Left) { if (selectindex < items.Count - 1) { selectindex = tipindex; selectedindexs.Add(selectindex); base.Invalidate(); tooltip.Hide(control); } } } protected override void OnMouseDown(MouseEventArgs e) { control.Focus(); if (e.Button == MouseButtons.Left) { begindrag = false; int index = HitIndex(e.X, e.Y); if (index == -1) return; bool shift_pressed = (Control.ModifierKeys & Keys.Shift) != 0; bool ctrl_pressed = (Control.ModifierKeys & Keys.Control) != 0; if (ctrl_pressed) { if (selectedindexs.Contains(index)) { selectedindexs.Remove(index); } else { selectedindexs.Add(index); } base.Invalidate(); return; } selectedindexs.Clear(); if (shift_pressed) { if (index > selectindex) { for (int i = selectindex; i < index + 1; i++) { selectedindexs.Add(i); } } else { for (int i = index; i < selectindex; i++) { selectedindexs.Add(i); } } } else { searchindex = -1; errorindex = -1; SelectedIndex = index; } base.Invalidate(); } } protected override void OnMouseDoubleClick(MouseEventArgs e) { if (e.Button == MouseButtons.Left) { checkedindex = HitIndex(e.X, e.Y); selectindex = checkedindex; if (doubleclickitem != null) { if (selectindex >= 0 && selectindex < items.Count) { ListItem item = items[selectindex] as ListItem; if (item == null || !File.Exists(item.FileName)) { errorindex = CheckedIndex; Invalidate(); return; } doubleclickitem(item, EventArgs.Empty); } } base.Invalidate(); } }
项目源码
CCMP之播放列表(高仿千千静听)相关推荐
- 2016年最经典的高仿系列源码打包下载4.84G
│ JAVAapk.com文件列表生成.bat │ 例子大全说明.txt │ 本例子永久更新地址~.url │ 目录列表2015.11.04更新.txt ...
- php仿微信语音条,html5的audio实现高仿微信语音播放效果
前言 之前做过一个微信的项目,专家回复可以录音,然后储存成mp3格式,前台可以获取mp3,客户可以在线试听mp3录音效果,今天就简单分享一下这个效果如何实现,及实现思路和方法! 效果图 前台大体呈现效 ...
- Vue3.0 + typescript 高仿网易云音乐 WebApp
Vue3.0 + typescript 高仿网易云音乐 WebApp 前言 Vue3.0 的正式发布,让我心动不已,于是尝试用 vue3 实现一个完整的项目,整个项目全部使用了 composition ...
- 【笔记-vue】《imooc-vue.js高仿饿了么》、《imooc-vue 音乐app》、《imooc-vue.js源码全方位解析》
20170709 - 20171128:<imooc-vue.js高仿饿了么> 一.第一章 课程简介 1-1课程简介 1.需求分析-脚手架工具-数据mock-架构设计-代码编写-自测-编译 ...
- Flutter+FishRedux高仿网易云音乐
flutter_netease_cloud_music 采用FishRedux框架与开源网易云音乐api开发的高仿网易云音乐APP,技术栈主要是:Flutter+FishRedux,目前主要是偏重AP ...
- html5的audio实现高仿微信语音播放效果
效果图 前台大体呈现效果图如下: 点击就可以播放mp3格式的录音.点击另外一个录音,当前录音停止! 思路 关于播放动画,这个很简单,我们可以用css3的逐帧动画来实现.关于逐帧动画,我之前的文章也写过 ...
- android如何展示富文本_android高仿今日头条富文本编辑(发布文章)
前言: 在经历了几个月的项目期限.我们遇到了前端发布文章,要用到富文本编辑的功能.在一番衡量下最终用到了richeditor-android第三方框架.实现原理就是通过webView和js实现前端富文 ...
- 盘点 Github 上的高仿 app 项目
点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 作者:水哥:来源:GitHubClub 学技术的,多多少少 ...
- ab plc编程软件_三菱PLC原装和高仿怎么区分?PLC仿真软件和编程软件一样吗?
点击↑↑技成培训 ,关注并置顶即可长期免费订阅 18万+工控人关注的微信平台:技术分享.学习交流.工控视频 今天不给大家讲具体的PLC具体的学习内容,今天我们要聊的是三菱PLC设备,首先看这个问题: ...
最新文章
- 如何让我们的vmware虚拟机上网!!
- 系统内存信息获取工具类
- python游戏脚本实例-python实现的简单文本类游戏实例
- 0基础入门,如何快速上手Python?
- 【每天读一遍,不久你就会变!】【送给迷茫的朋友】
- keepalived主从模式监测nginx
- 淘宝内部大量使用的开源系统监控工具
- fpga实战训练精粹pdf_tensorflow版PSENet 文本检测模型训练和测试
- [Windowns C]递归遍历指定目录下的子目录和文件
- 对于华为,英特尔与微软表示继续提供支持;亚马逊亲证云计算服务出现宕机;中国移动5G套餐曝光,每月都含200G流量……...
- [转载] $CF290F$ 题解
- .git文件过大,怎么删除
- python class 2
- 用欧拉角表示旋转(方位)heading pitch bank 含义,形象的图示
- vss服务器状态失败_Exchange快照错误,询问写入器状态失败
- extjs 中时间控件中 时分秒
- 常用的logo设计技巧
- 女大学生最爱不释手的网址
- Docker 安装、使用
- JavaWeb—Filter过滤器