winform中背景播放视频以及透明控件附于其上的相关问题

__Meow 2013-06-26 11:10:23
如题,先上图,这是我之前的UI
,我现在想实现动态背景,由于GIF最高只支持256色,所以决定用DirectShow播放视频文件。
但问题也随之来了,控件(比如Label)的透明色为Transparent,之前静态背景的时候是透到窗体,现在我要在Panel上播放视频,结果就变成了
还请各位大神指点一下,多谢了……附上DirectShow相关调用代码:

public partial class FrmGraph : Form
{
// DirectShow stuff
private IFilterGraph2 graphBuilder = null;
private IMediaControl mediaControl = null;
private IBaseFilter vmr9 = null;
public static IVMRWindowlessControl9 windowlessCtrl = null;
private bool handlersAdded = false;
private string m_filename = null;
private Panel m_Panel = null;

public FrmGraph(string filename, Panel panel)
{
m_filename = filename;
m_Panel = panel;
MBuildGraph(m_filename);
RunGraph();
}

private void CloseInterfaces()
{
if (mediaControl != null)
mediaControl.Stop();

if (handlersAdded)
RemoveHandlers();

if (vmr9 != null)
{
Marshal.ReleaseComObject(vmr9);
vmr9 = null;
windowlessCtrl = null;
}

if (graphBuilder != null)
{
Marshal.ReleaseComObject(graphBuilder);
graphBuilder = null;
mediaControl = null;
}

}

public void MBuildGraph(string fileName)//通过文件名建立Graph
{
int hr = 0;

try
{
graphBuilder = (IFilterGraph2) new FilterGraph();
mediaControl = (IMediaControl) graphBuilder;

vmr9 = (IBaseFilter) new VideoMixingRenderer9();

ConfigureVMR9InWindowlessMode();

hr = graphBuilder.AddFilter(vmr9, "Video Mixing Renderer 9");
DsError.ThrowExceptionForHR(hr);

hr = graphBuilder.RenderFile(fileName, null);
DsError.ThrowExceptionForHR(hr);
}
catch(Exception e)
{
CloseInterfaces();
MessageBox.Show("An error occured during the graph building : \r\n\r\n"
+ e.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}

private void ConfigureVMR9InWindowlessMode()
{
int hr = 0;

IVMRFilterConfig9 filterConfig = (IVMRFilterConfig9) vmr9;

// Not really needed for VMR9 but don't forget calling it with VMR7
hr = filterConfig.SetNumberOfStreams(1);
DsError.ThrowExceptionForHR(hr);

// Change VMR9 mode to Windowless
hr = filterConfig.SetRenderingMode(VMR9Mode.Windowless);
DsError.ThrowExceptionForHR(hr);

windowlessCtrl = (IVMRWindowlessControl9) vmr9;

// Set "Parent" window
hr = windowlessCtrl.SetVideoClippingWindow(m_Panel.Handle);
DsError.ThrowExceptionForHR(hr);

// Set Aspect-Ratio
hr = windowlessCtrl.SetAspectRatioMode(VMR9AspectRatioMode.LetterBox);
DsError.ThrowExceptionForHR(hr);

// Add delegates for Windowless operations
AddHandlers();

// Call the resize handler to configure the output size
BuildGraph_ResizeMove(null, null);
}

private void AddHandlers()
{
// Add handlers for VMR purpose
this.Paint += new PaintEventHandler(BuildGraph_Paint); // for WM_PAINT
this.Resize += new EventHandler(BuildGraph_ResizeMove); // for WM_SIZE
this.Move += new EventHandler(BuildGraph_ResizeMove); // for WM_MOVE
SystemEvents.DisplaySettingsChanged += new EventHandler(SystemEvents_DisplaySettingsChanged); // for WM_DISPLAYCHANGE
handlersAdded = true;
}

private void RemoveHandlers()
{
// remove handlers when they are no more needed
handlersAdded = false;
this.Paint -= new PaintEventHandler(BuildGraph_Paint);
this.Resize -= new EventHandler(BuildGraph_ResizeMove);
this.Move -= new EventHandler(BuildGraph_ResizeMove);
SystemEvents.DisplaySettingsChanged -= new EventHandler(SystemEvents_DisplaySettingsChanged);
}

private void RunGraph()
{
if (mediaControl != null)
{
int hr = mediaControl.Run();
DsError.ThrowExceptionForHR(hr);
}
}

private void StopGraph()
{
if (mediaControl != null)
{
int hr = mediaControl.Stop();
DsError.ThrowExceptionForHR(hr);
}
}

private void BuildGraph_Paint(object sender, PaintEventArgs e)
{
if (windowlessCtrl != null)
{
IntPtr hdc = e.Graphics.GetHdc();
int hr = windowlessCtrl.RepaintVideo(m_Panel.Handle, hdc);
e.Graphics.ReleaseHdc(hdc);
}
}

private void BuildGraph_ResizeMove(object sender, EventArgs e)
{
if (windowlessCtrl != null)
{
int hr = windowlessCtrl.SetVideoPosition(null, DsRect.FromRectangle(m_Panel.ClientRectangle));
}
}

private void SystemEvents_DisplaySettingsChanged(object sender, EventArgs e)
{
if (windowlessCtrl != null)
{
int hr = windowlessCtrl.DisplayModeChanged();
}
}

protected override void WndProc(ref Message m)
{
const int WM_SYSCOMMAND = 0x0112;
const int SC_CLOSE = 0xF060;
if (m.Msg == WM_SYSCOMMAND && (int)m.WParam == SC_CLOSE)
{
StopGraph();
}
base.WndProc(ref m);
}



public void stop()
{
if (mediaControl != null)
{
int hr = mediaControl.Stop();
StopGraph();
DsError.ThrowExceptionForHR(hr);
}
}

public void play()
{
if (mediaControl != null)
{
int hr = mediaControl.Run();
DsError.ThrowExceptionForHR(hr);
}
}

public void pause()
{
if (mediaControl != null)
{
int hr = mediaControl.Pause();
DsError.ThrowExceptionForHR(hr);
}
}
}
//主窗体调用处(FrmGraph m_graph;)
m_graph = new FrmGraph(Application.StartupPath + "\\WeatherBG\\sunny_night.avi", this.pnlBG);
m_graph.play();
...全文
395 3 打赏 收藏 举报
写回复
3 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
__Meow 2013-07-02
引用 2 楼 kimizhou_blog 的回复:
背景色很难调的,如果实在不行,只能换控件了
还望湿胸不吝赐教……
  • 打赏
  • 举报
回复
Kimizhou_blog 2013-07-01
背景色很难调的,如果实在不行,只能换控件了
  • 打赏
  • 举报
回复
__Meow 2013-06-27
不要沉啊……自己顶……
  • 打赏
  • 举报
回复
相关推荐
package com.vai; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.util.AttributeSet; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.SurfaceHolder.Callback; /** * * @author Himi * */ public class MySurfaceView extends SurfaceView implements Callback, Runnable { public MySurfaceView(Context context, AttributeSet attrs) { super(context, attrs); sfh = this.getHolder(); sfh.addCallback(this); paint = new Paint(); paint.setColor(Color.WHITE); paint.setAntiAlias(true); setFocusable(true); } private SurfaceHolder sfh; private Paint paint; private Thread th; private boolean flag; private Canvas canvas; private int screenW, screenH; // /** * SurfaceView初始化函数 */ /** * SurfaceView视图创建,响应此函数 */ @Override public void surfaceCreated(SurfaceHolder holder) { screenW = this.getWidth(); screenH = this.getHeight(); flag = true; //实例线程 th = new Thread(this); //启动线程 th.start(); } /** * 游戏绘图 */ public void myDraw() { try { canvas = sfh.lockCanvas(); if (canvas != null) { canvas.drawColor(Color.BLACK); paint.setTextSize(15); canvas.drawText("这里是游戏视图-SurfaceView", 40, 40, paint); } } catch (Exception e) { // TODO: handle exception } finally { if (canvas != null) sfh.unlockCanvasAndPost(canvas); } } /** * 触屏事件监听 */ @Override public boolean onTouchEvent(MotionEvent event) { return true; } /** * 按键事件监听 */ @Override public boolean onKeyDown(int keyCode, KeyEvent event) { return super.onKeyDown(keyCode, event); } /** * 游戏逻辑 */ private void logic() { } @Override public void run() { while (flag) { long start = System.currentTimeMillis(); myDraw(); logic(); long end = System.currentTimeMillis(); try { if (end - start < 50) { Thread.sleep(50 - (end - start)); } } catch (InterruptedException e) { e.printStackTrace(); } } } /** * SurfaceView视图状态发生改变,响应此函数 */ @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } /** * SurfaceView视图消亡时,响应此函数 */ @Override public void surfaceDestroyed(SurfaceHolder holder) { flag = false; } }
这篇文章我们重点需要实现的是(3)、(4)两项功能,下面我们来介绍具体实现的方法。 第一步,实现ImageComboBoxItem类。 要实现显示图标,当然要给每个项添加与图标相关的信息了,ImageComboBoxItem类应该包括以下内容:文本(Text)、缩进的级别(Level)、图标的索引(ImageIndex、ImageKey),用户数据(Tag)。ImageComboBoxItem类实现了ISerializable接口,实现自定义序列化。ImageComboBoxItem类的类视图如下: 图3 ImageComboxItem类视图 ImageComboBoxItem类的代码如下: [Serializable] [DefaultProperty("Text")] [TypeConverter( typeof(ExpandableObjectConverter))] public class ImageComboBoxItem : IDisposable, ISerializable ...{ Fields#region Fields private ImageComboBox _imageComboBox; private string _text = "ImageComboBoxItem"; private ImageComboBoxItemImageIndexer _imageIndexer; private object _tag; private int _level; #endregion Constructors#region Constructors public ImageComboBoxItem() ...{ } public ImageComboBoxItem(string text) : this(text, -1, 0) ...{ } public ImageComboBoxItem( string text, int imageIndex) : this(text, imageIndex, 0) ...{ } public ImageComboBoxItem( string text, string imageKey) : this(text, imageKey, 0) ...{ } public ImageComboBoxItem( string text, int imageIndex, int level) : this() ...{ _text = text; ImageIndexer.Index = imageIndex; _level = level; } public ImageComboBoxItem( string text, string imageKey, int level) : this() ...{ _text = text; ImageIndexer.Key = imageKey; _level = level; } protected ImageComboBoxItem( SerializationInfo info, StreamingContext context) : this() ...{ Deserialize(info, context); } #endregion Properties#region Properties [Localizable(true)]
using system; using system.web.ui; using system.web.ui.webcontrols; using system.componentmodel; using system.web.ui.htmlcontrols; using system.io; using system.drawing; using system.drawing.design; namespace yingnet.common { /// /// fileupload 的摘要说明。e:\program\common\fileupload.bmp /// [toolboxbitmap(typeof(yingnet.common.fileupload), "fileupload.bmp"), defaultproperty("text"), defaultevent("click"), toolboxdata("<{0}:fileupload runat=server>")] public class fileupload : system.web.ui.webcontrols.webcontrol { /// /// 传按钮 /// private button button=new button(); /// /// 传文件个数 /// private int filenum=1; /// /// file对象 /// private htmlinputfile[] file; /// /// 保存路径,默认为系统的临时目录 /// private string path=system.io.path.gettemppath(); /// /// 传的文件名组 /// private string[] filename; /// /// 后缀文件名组 /// private string[] suffix; /// ///过滤器,写法是.txt;.abc /// private string filter=""; /// /// 限制文件传大小,为0是不限制,单位是字节 /// private int size=0;//system.componentmodel.defaulteventattribute /// /// 传事件 /// [bindable(true),category("事件"),description("传后激发的事件") ] public event eventhandler click; /// /// 传文件数 /// [bindable(true), category("参数"),description("设定传文件的个数"), defaultvalue("1")] public int filenum{ set{ if(value<1){ value=1; } filenum=value; this.controls.clear(); file=new htmlinputfile[filenum]; filename=new string[filenum]; suffix=new string[filenum]; for(int i=0;i /// 传按钮的文本 /// [bindable(true), category("参数"), description("设定传文件的路径"), defaultvalue("1")] /// /// 传路径 /// public string uploadpath { set{ if("".equals(value)||value==null){ value=system.io.path.gettemppath(); } path=value; } get{ return path; } } /// /// 得到文件名 /// public string[] filename{ get{ return filename; } } /// /// 得到后缀 /// public string[] suffix{ get{ return suffix; } } /// /// 过滤器 /// public string filter{ set{ filter=value; } get{ return filter; } } /// /// 限制大小 /// public int filesize{ set{ size=value; } get{ return size; } } /// /// 快捷键 /// public override string accesskey{ get{ return button.accesskey; } set{ button.accesskey=value; } } /// /// 背景 /// public override system.drawing.color backcolor{ get{ return button.backcolor; } set{ button.backcolor=value; } } /// /// 边框颜色 /// public override system.drawing.color bordercolor{ get{ return button.bordercolor; } set{ button.bordercolor=value; } } /// /// 边框风格 /// public override borderstyle borderstyle{ get{ return button.borderstyle; } set{ button.borderstyle=value; } } /// /// 文本 /// [bindable(true), category("appearance"), defaultvalue("")] public string text { get { return button.text; } set { button.text = value; } } public fileupload():base(){ filenum=1; button.click+=new eventhandler(this.button_click); this.controls.add(button); } /// /// 按钮事件 /// /// /// private void button_click(object sender, eventargs e){ upload(); ///添加你的代码 if(click!=null) click(sender,e); ///抛处事件 } /// /// 传 /// private void upload(){ system.web.httppostedfile postedfile; for(int i=0;isize && size!=0){ break; } string suf=getsuffix(postedfile.filename); if(filter!=null && filter.indexof(suf)>-1){ break; } filename[i]=datetime.now.ticks.tostring(); suffix[i]=suf; postedfile.saveas(system.io.path.combine(path,filename[i]+suf)); } }finally{ filename[i]=""; } } } /// /// 获取后缀名 /// /// 文件名 /// 返回带.的后缀名 private string getsuffix(string filename){ int index=filename.lastindexof("."); if(index>0){ return filename.substring(index); } return ""; } } }
FadingActionBar 仿美团背景渐变,默认背景透明,下拉bar完全隐藏  。开发者使用此依赖,只需要2个方法就可以实现美团外卖拉titlebar背景渐变,下拉titlebar隐藏效果。效果图:准备工作:1.注意actionbar的依赖库,目前仅支持import android.app.ActionBar;2.actionbar背景渐变需要监听headerview的位置,放在添加headerview后调用该方法     private void initScroll() {         //设置动态改变         mlistview.setOnScrollListener(new AbsListView.OnScrollListener() {             @Override             public void onScrollStateChanged(AbsListView view, int scrollState) {             }             @Override             public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {                 // [0]代表x坐标,location [1] 代表y坐标。                 int[] location = new int[2];                 // 实时设置actionbar透明度,监听header位置(必须是移除屏幕会产生负数的view)                 llheaderview.getLocationInWindow(location);                 helper.setActionBarAlpha(location[1] - XMSettings.getStatusBarHeight(mContext));                 Log.i("tag", "onScroll: "   (location[1] - XMSettings.getStatusBarHeight(mContext)));             }         });      }3.注意activity对应的theme添加属性<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">      true      @null </style>使用1.添加Gradle依赖dependencies {     compile 'com.github.ximencx.fadeactionbar:library:1.0.1'     }2.activity获取actionbar对象,初始化XMFadeBarHelper类    private void initbar() {         //获取actionbar对象         mActionBar = getActionBar();         mActionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);         mActionBar.setCustomView(R.layout.ab_title);         /**          * actionbar辅助类          * parameter1:action对象          * parameter2:acitonbar背景          * parameter3:初始透明度          */         helper = new XMFadeBarHelper(mActionBar, getResources().getDrawable(R.drawable.bg_actionbar), 0) {             /**              * 设置需要隐藏view的透明度              * 注意:是否设置background的区别              *              * @param customView  actionbar布局对象              * @param alpha 回调的alpha              */             @Override             public void setViewAlpha(View customView, int alpha) {                 ButterKnife.findById(customView, R.id.tv_info).setAlpha(alpha);                 ButterKnife.findById(customView, R.id.rl_bg).getBackground().setAlpha(alpha);             }             /**              * 设置隐藏速度              * 默认返回actionbar布局的高度,当然也可以以它view为参照物              * @param customView actionbar布局              * @return              */             @Override             public int setHeight(View customView) {                 return customView.getHeight();             }         };     }3.listview的监听调用helper.setActionBarAlpha(),注意减去状态栏的高度    private void initScroll() {         //设置动态改变         mlistview.setOnScrollListener(new AbsListView.OnScrollListener() {             @Override             public void onScrollStateChanged(AbsListView view, int scrollState) {             }             @Override             public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {                 // [0]代表x坐标,location [1] 代表y坐标。                 int[] location = new int[2];                 // 实时设置actionbar透明度,监听header位置(必须是移除屏幕会产生负数的view)                 llheaderview.getLocationInWindow(location);                 helper.setActionBarAlpha(location[1] - XMSettings.getStatusBarHeight(mContext));                 Log.i("tag", "onScroll: "   (location[1] - XMSettings.getStatusBarHeight(mContext)));             }         });      }sample使用到的第三方库:BGAAdapterBGARefreshLayout-Android
using System; using System.Drawing; using System.Windows.Forms; using System.Collections.Generic; namespace WindowsFormsApplication1 { class DragItemListView:ListView { public DragItemListView() { SetStyle(ControlStyles.DoubleBuffer | ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true); UpdateStyles(); this.MultiSelect = false; this.ListViewItemSorter = new ListViewIndexComparer(); if (OSFeature.Feature.IsPresent(OSFeature.Themes)) { this.AllowDrop = true; this.ItemDrag += new ItemDragEventHandler(DragItemListView_ItemDrag); this.DragEnter += new DragEventHandler(DragItemListView_DragEnter); this.DragLeave += new EventHandler(DragItemListView_DragLeave); this.DragOver += new DragEventHandler(DragItemListView_DragOver); this.DragDrop += new DragEventHandler(DragItemListView_DragDrop); } } void DragItemListView_DragDrop(object sender, DragEventArgs e) { // Retrieve the index of the insertion mark; int targetIndex = this.InsertionMark.Index; // If the insertion mark is not visible, exit the method. if (targetIndex == -1) { return; } // If the insertion mark is to the right of the item with // the corresponding index, increment the target index. // Retrieve the dragged item. ListViewItem draggedItem = (ListViewItem)e.Data.GetData(typeof(ListViewItem)); // Insert a copy of the dragged item at the target index. // A copy must be inserted before the original item is removed // to preserve item index values. ListViewItem NewItem = (ListViewItem)draggedItem.Clone(); if (draggedItem.Index < targetIndex) { if (targetIndex - draggedItem.Index > 1) NewItem.Group = this.Items[targetIndex - 1].Group; else NewItem.Group = this.Items[targetIndex].Group; } else { if (draggedItem.Index - targetIndex > 1) NewItem.Group = this.Items[targetIndex].Group; else NewItem.Group = this.Items[targetIndex - 1].Group; } if (this.InsertionMark.AppearsAfterItem) { targetIndex++; } this.Items.Insert(targetIndex, NewItem); // Remove the original copy of the dragged item. this.Items.Remove(draggedItem); } void DragItemListView_DragOver(object sender, DragEventArgs e) { // Retrieve the client coordinates of the mouse pointer. Point targetPoint = this.PointToClient(new Point(e.X, e.Y)); // Retrieve the index of the item closest to the mouse pointer. //int targetIndex = this.InsertionMark.NearestIndex(targetPoint); int targetIndex = GetNearItem(targetPoint).Index; // Confirm that the mouse pointer is not over the dragged item. if (targetIndex > -1) { // Determine whether the mouse pointer is to the left or // the right of the midpoint of the closest item and set // the InsertionMark.AppearsAfterItem property accordingly. Rectangle itemBounds = this.GetItemRect(targetIndex); if (targetPoint.X > itemBounds.Left + (itemBounds.Width / 2)) { this.InsertionMark.AppearsAfterItem = true; } else { this.InsertionMark.AppearsAfterItem = false; } } // Set the location of the insertion mark. If the mouse is // over the dragged item, the targetIndex value is -1 and // the insertion mark disappears. this.InsertionMark.Index = targetIndex; } void DragItemListView_DragLeave(object sender, EventArgs e) { this.InsertionMark.Index = -1; } void DragItemListView_ItemDrag(object sender, ItemDragEventArgs e) { this.DoDragDrop(e.Item, DragDropEffects.Move); } void DragItemListView_DragEnter(object sender, DragEventArgs e) { e.Effect = e.AllowedEffect; } private class ListViewIndexComparer : System.Collections.IComparer { public int Compare(object x, object y) { return ((ListViewItem)x).Index - ((ListViewItem)y).Index; } } /// /// 搜索最近的ListViewItem /// /// 工作区坐标 /// public ListViewItem GetNearItem(Point ClientPoint) { ListViewItem lvt = this.GetItemAt(ClientPoint.X, ClientPoint.Y); if (lvt != null) return lvt; List vt = new List(); for (int i = 1; i < 10; i++) { lvt = this.GetItemAt(ClientPoint.X, ClientPoint.Y + i); if (lvt != null) vt.Add(lvt); lvt = this.GetItemAt(ClientPoint.X, ClientPoint.Y - i); if (lvt != null) vt.Add(lvt); lvt = this.GetItemAt(ClientPoint.X + i, ClientPoint.Y); if (lvt != null) vt.Add(lvt); lvt = this.GetItemAt(ClientPoint.X + i, ClientPoint.Y + i); if (lvt != null) vt.Add(lvt); lvt = this.GetItemAt(ClientPoint.X + i, ClientPoint.Y - i); if (lvt != null) vt.Add(lvt); lvt = this.GetItemAt(ClientPoint.X - i, ClientPoint.Y); if (lvt != null) vt.Add(lvt); lvt = this.GetItemAt(ClientPoint.X - i, ClientPoint.Y + i); if (lvt != null) vt.Add(lvt); lvt = this.GetItemAt(ClientPoint.X - i, ClientPoint.Y - i); if (lvt != null) vt.Add(lvt); if (vt.Count > 0) break; } if (vt.Count == 0) { return null; } else if (vt.Count == 1) { return vt[0]; } else { double HisDis = 0; int i = 0; foreach (ListViewItem item in vt) { double dis = GetDistince(ClientPoint, item.Position); if (i == 0 || dis < HisDis) { lvt = item; HisDis = dis; } i++; } return lvt; } } /// /// 两点间的距离 /// /// 起点 /// 终点 /// private double GetDistince(Point start, Point end) { double distince2 = Math.Pow((start.X - end.X), 2) + Math.Pow((start.Y - end.Y), 2); return Math.Abs(Math.Sqrt(distince2)); } } }
发帖
.NET Framework

1.7w+

社区成员

.NET技术 .NET Framework
社区管理员
  • .NET Framework社区
加入社区
帖子事件
创建了帖子
2013-06-26 11:10
社区公告
暂无公告