C#窗体程序实现全屏及取消全屏步骤
作者:影_汐 发布时间:2023-02-18 11:48:38
标签:C#,全屏,窗体
由于项目需要,需要用vs窗体程序实现播放视频的窗口的全屏和取消全屏。
具体实现界面如图:
这是初始状态,视频框的右上角就是控制全屏的按钮
这是全屏后的状态,此时全屏按钮变成了取消全屏的样式
注:为了界面的美观我的全屏并没有把左边的那些控件也盖住,但是是可以设置的,下边代码部分我会进行讲解。
1、首先说明一下我所用的控件及我的项目中控件的名称,以便大家理解。
显示视频的黑框是一个picturebox即代码中的VideoPlayWnd,全屏/取消全屏是一个button即代码中的button4
2、具体代码如下:
全屏和取消全屏是一个按钮即button4
private Int16 zoom = -1;//用来控制点击此button4的时候,是需要全屏还是取消全屏
//视频窗口的缩放代码
private void button4_Click(object sender, EventArgs e)
{
if(zoom<0)
{
float w = this.Width - 210; //为了保证左边的控件不被挡上减了一个210
float h = this.Height - 50;//为了底下的按钮不被挡上,因为还要用到,因此减了50
this.VideoPlayWnd.Size = Size.Ceiling(new SizeF(w, h));//重新部署视频框即这个picturebox空间的长宽
VideoPlayWnd.Location = new System.Drawing.Point(210, 0);//视频框的左上角坐标,会发现与我上边减去的210一致(大家肯定都理解为什么我就不说了)
button4.Location = new System.Drawing.Point(795, 0);//不能只有picturebox变了,这个button的位置也要保证和视频框同步,所以需要重设坐标
// button4.BackgroundImage = Image.FromFile(@"E:\lwj\addpersoninfo\addpersoninfo\Resources\退出全屏.png");//绝对路径(这是我测试的时候用的)
button4.BackgroundImage = Image.FromFile(AppDomain.CurrentDomain.BaseDirectory + @"退出全屏.png");//AppDomain.CurrentDomain.BaseDirectory语句可以获取到你当前项目的bin目录,所以需要把图片放到对应目录下
zoom = 1;//全屏之后,再点击需要取消全屏,因此要改变zoom的值
}
else
{ //以下为取消全屏,即还原自己的视频框和按钮,具体操作类似全屏,就不细致注释了
VideoPlayWnd.Location = new System.Drawing.Point(495, 360);
this.VideoPlayWnd.Size = Size.Ceiling(new SizeF(323, 271));
button4.Location = new System.Drawing.Point(795, 360);
button4.BackgroundImage = Image.FromFile(AppDomain.CurrentDomain.BaseDirectory + @"全屏.png");
zoom = -1;//取消全屏后再点击就要进行全屏,因此继续设为-1(保证小于0,以满足全屏操作的if条件)
}
}
以上代码中的按钮是给它加了一个全屏样式的背景图片,并在点击时切换背景图片。
补充知识:C# 窗体视频控件进入全屏模式和退出全屏模式
窗体控件进入全屏模式和退出全屏模式,视频播放的时候用到此功能。
工具类代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace CvNetVideo.Play
{
class FullScreenHelper
{
bool m_bFullScreen = false;
IntPtr m_OldWndParent = IntPtr.Zero;
WINDOWPLACEMENT m_OldWndPlacement = new WINDOWPLACEMENT();
Control m_control = null;
public FullScreenHelper(Control c)
{
m_control = c;
}
struct POINT
{
int x;
int y;
};
struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
};
//锁定指定窗口,禁止它更新。同时只能有一个窗口处于锁定状态。锁定指定窗口,禁止它更新。同时只能有一个窗口处于锁定状态
[DllImport("User32.dll")]
public static extern bool LockWindowUpdate(IntPtr hWndLock);
//函数来设置弹出式窗口,层叠窗口或子窗口的父窗口。新的窗口与窗口必须属于同一应用程序
[DllImport("User32.dll")]
public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
//函数设置指定窗口的显示状态和恢复,最大化,最小化位置。函数功能: 函及原型
[DllImport("User32.dll")]
public static extern bool SetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
//函数将创建指定窗口的线程设置到前台,并且激活该窗口。键盘输入转向该窗口,并为用户改各种可视的记号
[DllImport("User32.dll")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
//该函数返回桌面窗口的句柄。桌面窗口覆盖整个屏幕。桌面窗口是一个要在其上绘制所有的图标和其他窗口的区域
[DllImport("User32.dll")]
public static extern IntPtr GetDesktopWindow();
//函数名。该函数返回指定窗口的显示状态以及被恢复的、最大化的和最小化的窗口位置
[DllImport("User32.dll")]
public static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
//是用于得到被定义的系统数据或者系统配置信息的一个专有名词
[DllImport("User32.dll")]
public static extern int GetSystemMetrics(int nIndex);
[DllImport("user32.dll", EntryPoint = "GetParent", SetLastError = true)]
public static extern IntPtr GetParent(IntPtr hWnd);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int y, int Width, int Height, int flags);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern System.IntPtr GetForegroundWindow();
[DllImport("user32")]
public static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect);
[DllImport("user32.dll")]
public static extern uint ScreenToClient(IntPtr hwnd, ref POINT p);
public void FullScreen(bool flag)
{
m_bFullScreen = flag;
if (!m_bFullScreen)
{
LockWindowUpdate(m_control.Handle);
SetParent(m_control.Handle, m_OldWndParent);
SetWindowPlacement(m_control.Handle, ref m_OldWndPlacement);
SetForegroundWindow(m_OldWndParent);
LockWindowUpdate(IntPtr.Zero);
}
else
{
GetWindowPlacement(m_control.Handle, ref m_OldWndPlacement);
int nScreenWidth = GetSystemMetrics(0);
int nScreenHeight = GetSystemMetrics(1);
m_OldWndParent = GetParent(m_control.Parent.Handle);
SetParent(m_control.Handle, GetDesktopWindow());
WINDOWPLACEMENT wp1 = new WINDOWPLACEMENT();
wp1.length = (uint)Marshal.SizeOf(wp1);
wp1.showCmd = 1;
wp1.rcNormalPosition.left = 0;
wp1.rcNormalPosition.top = 0;
wp1.rcNormalPosition.right = nScreenWidth;
wp1.rcNormalPosition.bottom = nScreenHeight;
SetWindowPlacement(m_control.Handle, ref wp1);
SetForegroundWindow(GetDesktopWindow());
SetForegroundWindow(m_control.Handle);
}
m_bFullScreen = !m_bFullScreen;
}
struct WINDOWPLACEMENT
{
public uint length;
public uint flags;
public uint showCmd;
public POINT ptMinPosition;
public POINT ptMaxPosition;
public RECT rcNormalPosition;
};
}
}
调用方式
/// <summary>
/// 全屏事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void UCVideo_DoubleClick(object sender, EventArgs e)
{
//全屏设置
//sdlVideo.SDL_MaximizeWindow();
fullScreenHelper = new CvNetVideo.Play.FullScreenHelper(this);
fullScreenHelper.FullScreen(true);
Console.WriteLine("Entrance FullScreen Mode");
}
/// <summary>
/// 按键弹起事件
/// </summary>
private void UCVideo_KeyUp(object sender, KeyEventArgs e)
{
// ESC 退出全屏
if (e.KeyCode == Keys.Escape&& fullScreenHelper!=null)
{
fullScreenHelper.FullScreen(false);
fullScreenHelper = null;
Console.WriteLine("Exit FullScreen Mode");
}
}
测试效果图
注意:在使用SDL的全屏操作过程中设置是无效的,播放视频过程中不能实现修改。代码如下:
public void SDL_MaximizeWindow()
{
Console.WriteLine("设置全屏");
SDL.SDL_MaximizeWindow(screen);
SDL.SDL_SetWindowFullscreen(screen, SDL.SDL_GetWindowFlags(screen));
SDL.SDL_ShowWindow(screen);
//int width, height;
获取最大窗口值
//SDL2.SDL.SDL_GetWindowMaximumSize(screen, out width, out height);
设置最大窗口值
//if (width>0&&height>0)
//{
// SDL2.SDL.SDL_SetWindowMaximumSize(screen, width, height);
// Console.WriteLine("设置全屏......成功!width=" + width + ",height=" + height);
//}
//else
//{
// Console.WriteLine("设置全屏......失败!width=" + width + ",height=" + height);
// SDL2.SDL.SDL_SetWindowMaximumSize(screen, w, h);
//}
}
工具代码功能改进
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace CvNetVideo.Play
{
/// <summary>
/// 定义全屏抽象类
/// </summary>
public abstract class FullScreenObject
{
public abstract void FullScreen(bool flag);
}
/// <summary>
/// 桌面全屏
/// </summary>
public unsafe class FullScreenHelper: FullScreenObject
{
bool m_bFullScreen = false;
WINDOWPLACEMENT m_OldWndPlacement = new WINDOWPLACEMENT();
UCVideo m_control = null;
public FullScreenHelper(UCVideo control)
{
m_control = control;
}
private IntPtr m_OldWndParent = IntPtr.Zero;
DockStyle old_docker_style;
int old_left;
int old_width;
int old_height;
int old_top;
public override void FullScreen(bool flag)
{
m_bFullScreen = flag;
if (!m_bFullScreen)
{
#region 方式一:窗体容积改变时不能全屏,未能解决IE全屏显示不全问题
//ShellSDK.LockWindowUpdate(m_control.Handle);
//ShellSDK.SetParent(m_control.Handle, m_OldWndParent);
//ShellSDK.SetWindowPlacement(m_control.Handle, ref m_OldWndPlacement);
//ShellSDK.SetForegroundWindow(m_OldWndParent);
//ShellSDK.LockWindowUpdate(IntPtr.Zero);
#endregion
#region 方式二:在容器改变时可以实现全屏,未能解决IE全屏显示不全问题
// 取消全屏设置
m_control.Dock = old_docker_style;
m_control.Left = old_left;
m_control.Top = old_top;
m_control.Width = old_width;
m_control.Height = old_height;
ShellSDK.SetParent(m_control.Handle, m_OldWndParent);
#endregion
}
else
{
#region 方式一:窗体容积改变时不能全屏,未能解决IE全屏显示不全问题
//ShellSDK.GetWindowPlacement(m_control.Handle, ref m_OldWndPlacement);
//int nScreenWidth = ShellSDK.GetSystemMetrics(0);
//int nScreenHeight = ShellSDK.GetSystemMetrics(1);
//m_OldWndParent = ShellSDK.GetParent(m_control.Handle);
//ShellSDK.SetParent(m_control.Handle, ShellSDK.GetDesktopWindow());
//WINDOWPLACEMENT wp1 = new WINDOWPLACEMENT();
//wp1.length = (uint)Marshal.SizeOf(wp1);
//wp1.showCmd = 1;
//wp1.rcNormalPosition.left = 0;
//wp1.rcNormalPosition.top = 0;
//wp1.rcNormalPosition.right = Screen.PrimaryScreen.Bounds.Width/*nScreenWidth*/;
//wp1.rcNormalPosition.bottom = Screen.PrimaryScreen.WorkingArea.Height/* nScreenHeight*/;
//ShellSDK.SetWindowPlacement(m_control.Handle, ref wp1);
//ShellSDK.SetForegroundWindow(ShellSDK.GetDesktopWindow());
//ShellSDK.SetForegroundWindow(m_control.Handle);
#endregion
#region 方式二:在容器改变时可以实现全屏,未能解决IE全屏显示不全问题
// 记录原来的数据
old_docker_style = m_control.Dock;
old_left = m_control.Left;
old_width = m_control.Width;
old_height = m_control.Height;
old_top = m_control.Top;
m_OldWndParent = ShellSDK.GetParent(m_control.Handle);
// 设置全屏数据
int nScreenWidth = ShellSDK.GetSystemMetrics(0);
int nScreenHeight = ShellSDK.GetSystemMetrics(1);
m_control.Dock = DockStyle.None;
m_control.Left = 0;
m_control.Top = 0;
m_control.Width = nScreenWidth;
m_control.Height = nScreenHeight;
ShellSDK.SetParent(m_control.Handle, ShellSDK.GetDesktopWindow());
ShellSDK.SetWindowPos(m_control.Handle, -1, 0, 0, m_control.Right - m_control.Left, m_control.Bottom - m_control.Top, 0);
#endregion
}
m_bFullScreen = !m_bFullScreen;
}
}
/// <summary>
/// 在容器内部全屏
/// </summary>
public class FullScreenInContainerHelper : FullScreenObject
{
bool m_bFullScreen = false;
Control m_control = null;
public FullScreenInContainerHelper(Control control)
{
m_control = control;
}
private IntPtr m_OldWndParent = IntPtr.Zero;
private IntPtr m_father_hwnd;
private RECT m_rect = new RECT();
public override void FullScreen(bool flag)
{
m_bFullScreen = flag;
if (!m_bFullScreen)
{
ShellSDK.SetParent(m_control.Handle, m_father_hwnd);
ShellSDK.SetWindowPos(m_control.Handle, 0, m_rect.left, m_rect.top, m_rect.right - m_rect.left, m_rect.bottom - m_rect.top, 0);
ShellSDK.SetForegroundWindow(m_father_hwnd);
}
else
{
m_father_hwnd = ShellSDK.GetParent(m_control.Handle);
ShellSDK.GetWindowRect(m_control.Handle, out RECT rect);
POINT pt = new POINT();
pt.x = rect.left;
pt.y = rect.top;
ShellSDK.ScreenToClient(m_father_hwnd, ref pt);
rect.right = rect.right - rect.left + pt.x;
rect.bottom = rect.bottom - rect.top + pt.y;
rect.left = pt.x;
rect.top = pt.y;
m_rect = rect;
ShellSDK.GetWindowRect(m_father_hwnd, out RECT rect_fature);
ShellSDK.SetWindowPos(m_control.Handle, 0, 0, 0, rect_fature.right - rect_fature.left, rect_fature.bottom - rect_fature.top, 0);
}
m_bFullScreen = !m_bFullScreen;
}
}
/// <summary>
/// Windows系统API-SDK
/// </summary>
public class ShellSDK
{
//锁定指定窗口,禁止它更新。同时只能有一个窗口处于锁定状态。锁定指定窗口,禁止它更新。同时只能有一个窗口处于锁定状态
[DllImport("User32.dll")]
public static extern bool LockWindowUpdate(IntPtr hWndLock);
//函数来设置弹出式窗口,层叠窗口或子窗口的父窗口。新的窗口与窗口必须属于同一应用程序
[DllImport("User32.dll")]
public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
//函数设置指定窗口的显示状态和恢复,最大化,最小化位置。函数功能: 函及原型
[DllImport("User32.dll")]
public static extern bool SetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
//函数将创建指定窗口的线程设置到前台,并且激活该窗口。键盘输入转向该窗口,并为用户改各种可视的记号
[DllImport("User32.dll")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
//该函数返回桌面窗口的句柄。桌面窗口覆盖整个屏幕。桌面窗口是一个要在其上绘制所有的图标和其他窗口的区域
[DllImport("User32.dll")]
public static extern IntPtr GetDesktopWindow();
//函数名。该函数返回指定窗口的显示状态以及被恢复的、最大化的和最小化的窗口位置
[DllImport("User32.dll")]
public static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
//是用于得到被定义的系统数据或者系统配置信息的一个专有名词
[DllImport("User32.dll")]
public static extern int GetSystemMetrics(int nIndex);
[DllImport("user32.dll", EntryPoint = "GetParent", SetLastError = true)]
public static extern IntPtr GetParent(IntPtr hWnd);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int y, int Width, int Height, int flags);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern System.IntPtr GetForegroundWindow();
[DllImport("user32")]
public static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect);
[DllImport("user32.dll")]
public static extern uint ScreenToClient(IntPtr hwnd, ref POINT p);
}
/// <summary>
/// 图像区域对象
/// </summary>
public struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}
/// <summary>
/// 图像点位位置
/// </summary>
public struct POINT
{
public int x;
public int y;
}
/// <summary>
/// 图像窗口对象
/// </summary>
public struct WINDOWPLACEMENT
{
public uint length;
public uint flags;
public uint showCmd;
public POINT ptMinPosition;
public POINT ptMaxPosition;
public RECT rcNormalPosition;
}
}
来源:https://blog.csdn.net/weixin_39638351/article/details/81512795


猜你喜欢
- 我们知道,在 Python 里面,如果你要运行一段 JavaScript,你可以使用execJS这种第三方库。那么在 Golang 里面,你
- 今天要介绍一个概念,对象的克隆。本篇有一定难度,请先做好心理准备。看不懂的话可以多看两遍,还是不懂的话,可以在下方留言,我会看情况进行修改和
- 本文实例讲述了Android TextView实现带链接文字事件监听的三种常用方式。分享给大家供大家参考,具体如下:/** * TextVi
- JAVA中去掉空格 1. String.trim() trim()是去掉首尾空格 2.str
- 本文实例讲述了C#获取web.config配置文件内容的方法。分享给大家供大家参考。具体实现方法如下:1.ConfigurationMana
- 本文实例为大家分享了Android实现可复用的筛选页面的具体代码,供大家参考,具体内容如下窗口代码/** * 筛选页面 * 1.将用户的输入
- 一、前言如何通过Java发送HTTP请求,通俗点讲,如何通过Java(模拟浏览器)发送HTTP请求。Java有原生的API可用于发送HTTP
- 前言当大家使用mybatis作为持久层框架时,在存储和查询数据时,只需要在mapper.xml文件中配置好对应字段的JdbcType和Jav
- 前言这几天琢磨着开发个个人作品的时候,发现原来Unity3D官方没有提供圆锥体的创建功能,就自己做了个编辑器扩展。鉴于之前搜索Mesh编程的
- 本文实例为大家分享了C#实现围棋游戏的具体代码,供大家参考,具体内容如下之所以选择围棋作为大作业一方面是想挑战一下,另一方面是由于从6岁学围
- 今天给大家介绍下用Java swing开发一款音乐播放器, * 酷狗音乐播放器,完整源码地址在最下方,本文只列出部分源码,因为源码很多,全部贴
- 在考虑类初始化时,我们都知道进行子类初始化时,如果父类没有初始化要先初始化子类。然而事情并没有一句话这么简单。首先看看Java中初始化触发的
- 1) 要及时回收Bitmap的内存Bitmap类有一个方法recycle(),从方法名可以看出意思是回收。这里就有疑问了,Android系统
- 第一种给容器中的组件加上@ConfigurationProperties注解即可测试:@Component@ConfigurationPro
- 微信公众平台对信息做了比较清晰的分类,最基本的包括请求(Request)和响应(Response)两大类信息,这两类信息有分为文字、语音、图
- 游戏中有时候会见到图片轮播的效果,那么这里就自己封装了一个,包括自动轮播、切页按钮控制、页码下标更新、滑动轮播、切页后的回调等等 。下面,先
- 在Android开发中,定时器一般有以下3种实现方法:一、采用Handler与线程的sleep(long)方法二、采用Handler的pos
- 要想使Java运行,我们可以设计一个面向Java语言特性的虚拟机,并通过编译器将Java程序转换为它可以识别的指令序列,也称为Java字节码
- 引言这一篇文章我们就通过介绍滑动冲突的规则和一个实例来更加深入的学习View的事件分发机制。1、外部滑动方向和内部滑动方向不一致考虑这样一种
- 介绍原型模式(Prototype Pattern):使用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。原型模式是一种对象创建