C#窗體程序?qū)崿F(xiàn)全屏及取消全屏步驟
由于項(xiàng)目需要,需要用vs窗體程序?qū)崿F(xiàn)播放視頻的窗口的全屏和取消全屏。
具體實(shí)現(xiàn)界面如圖:


這是初始狀態(tài),視頻框的右上角就是控制全屏的按鈕
這是全屏后的狀態(tài),此時(shí)全屏按鈕變成了取消全屏的樣式
注:為了界面的美觀我的全屏并沒有把左邊的那些控件也蓋住,但是是可以設(shè)置的,下邊代碼部分我會進(jìn)行講解。
1、首先說明一下我所用的控件及我的項(xiàng)目中控件的名稱,以便大家理解。
顯示視頻的黑框是一個(gè)picturebox即代碼中的VideoPlayWnd,全屏/取消全屏是一個(gè)button即代碼中的button4
2、具體代碼如下:
全屏和取消全屏是一個(gè)按鈕即button4
private Int16 zoom = -1;//用來控制點(diǎn)擊此button4的時(shí)候,是需要全屏還是取消全屏
//視頻窗口的縮放代碼
private void button4_Click(object sender, EventArgs e)
{
if(zoom<0)
{
float w = this.Width - 210; //為了保證左邊的控件不被擋上減了一個(gè)210
float h = this.Height - 50;//為了底下的按鈕不被擋上,因?yàn)檫€要用到,因此減了50
this.VideoPlayWnd.Size = Size.Ceiling(new SizeF(w, h));//重新部署視頻框即這個(gè)picturebox空間的長寬
VideoPlayWnd.Location = new System.Drawing.Point(210, 0);//視頻框的左上角坐標(biāo),會發(fā)現(xiàn)與我上邊減去的210一致(大家肯定都理解為什么我就不說了)
button4.Location = new System.Drawing.Point(795, 0);//不能只有picturebox變了,這個(gè)button的位置也要保證和視頻框同步,所以需要重設(shè)坐標(biāo)
// button4.BackgroundImage = Image.FromFile(@"E:\lwj\addpersoninfo\addpersoninfo\Resources\退出全屏.png");//絕對路徑(這是我測試的時(shí)候用的)
button4.BackgroundImage = Image.FromFile(AppDomain.CurrentDomain.BaseDirectory + @"退出全屏.png");//AppDomain.CurrentDomain.BaseDirectory語句可以獲取到你當(dāng)前項(xiàng)目的bin目錄,所以需要把圖片放到對應(yīng)目錄下
zoom = 1;//全屏之后,再點(diǎn)擊需要取消全屏,因此要改變zoom的值
}
else
{ //以下為取消全屏,即還原自己的視頻框和按鈕,具體操作類似全屏,就不細(xì)致注釋了
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;//取消全屏后再點(diǎn)擊就要進(jìn)行全屏,因此繼續(xù)設(shè)為-1(保證小于0,以滿足全屏操作的if條件)
}
}
以上代碼中的按鈕是給它加了一個(gè)全屏樣式的背景圖片,并在點(diǎn)擊時(shí)切換背景圖片。
補(bǔ)充知識:C# 窗體視頻控件進(jìn)入全屏模式和退出全屏模式
窗體控件進(jìn)入全屏模式和退出全屏模式,視頻播放的時(shí)候用到此功能。
工具類代碼
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;
};
//鎖定指定窗口,禁止它更新。同時(shí)只能有一個(gè)窗口處于鎖定狀態(tài)。鎖定指定窗口,禁止它更新。同時(shí)只能有一個(gè)窗口處于鎖定狀態(tài)
[DllImport("User32.dll")]
public static extern bool LockWindowUpdate(IntPtr hWndLock);
//函數(shù)來設(shè)置彈出式窗口,層疊窗口或子窗口的父窗口。新的窗口與窗口必須屬于同一應(yīng)用程序
[DllImport("User32.dll")]
public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
//函數(shù)設(shè)置指定窗口的顯示狀態(tài)和恢復(fù),最大化,最小化位置。函數(shù)功能: 函及原型
[DllImport("User32.dll")]
public static extern bool SetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
//函數(shù)將創(chuàng)建指定窗口的線程設(shè)置到前臺,并且激活該窗口。鍵盤輸入轉(zhuǎn)向該窗口,并為用戶改各種可視的記號
[DllImport("User32.dll")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
//該函數(shù)返回桌面窗口的句柄。桌面窗口覆蓋整個(gè)屏幕。桌面窗口是一個(gè)要在其上繪制所有的圖標(biāo)和其他窗口的區(qū)域
[DllImport("User32.dll")]
public static extern IntPtr GetDesktopWindow();
//函數(shù)名。該函數(shù)返回指定窗口的顯示狀態(tài)以及被恢復(fù)的、最大化的和最小化的窗口位置
[DllImport("User32.dll")]
public static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
//是用于得到被定義的系統(tǒng)數(shù)據(jù)或者系統(tǒng)配置信息的一個(gè)專有名詞
[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;
};
}
}
調(diào)用方式
/// <summary>
/// 全屏事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void UCVideo_DoubleClick(object sender, EventArgs e)
{
//全屏設(shè)置
//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的全屏操作過程中設(shè)置是無效的,播放視頻過程中不能實(shí)現(xiàn)修改。代碼如下:
public void SDL_MaximizeWindow()
{
Console.WriteLine("設(shè)置全屏");
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);
設(shè)置最大窗口值
//if (width>0&&height>0)
//{
// SDL2.SDL.SDL_SetWindowMaximumSize(screen, width, height);
// Console.WriteLine("設(shè)置全屏......成功!width=" + width + ",height=" + height);
//}
//else
//{
// Console.WriteLine("設(shè)置全屏......失敗!width=" + width + ",height=" + height);
// SDL2.SDL.SDL_SetWindowMaximumSize(screen, w, h);
//}
}
工具代碼功能改進(jìn)
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 方式一:窗體容積改變時(shí)不能全屏,未能解決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 方式二:在容器改變時(shí)可以實(shí)現(xiàn)全屏,未能解決IE全屏顯示不全問題
// 取消全屏設(shè)置
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 方式一:窗體容積改變時(shí)不能全屏,未能解決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 方式二:在容器改變時(shí)可以實(shí)現(xiàn)全屏,未能解決IE全屏顯示不全問題
// 記錄原來的數(shù)據(jù)
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);
// 設(shè)置全屏數(shù)據(jù)
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>
/// 在容器內(nèi)部全屏
/// </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系統(tǒng)API-SDK
/// </summary>
public class ShellSDK
{
//鎖定指定窗口,禁止它更新。同時(shí)只能有一個(gè)窗口處于鎖定狀態(tài)。鎖定指定窗口,禁止它更新。同時(shí)只能有一個(gè)窗口處于鎖定狀態(tài)
[DllImport("User32.dll")]
public static extern bool LockWindowUpdate(IntPtr hWndLock);
//函數(shù)來設(shè)置彈出式窗口,層疊窗口或子窗口的父窗口。新的窗口與窗口必須屬于同一應(yīng)用程序
[DllImport("User32.dll")]
public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
//函數(shù)設(shè)置指定窗口的顯示狀態(tài)和恢復(fù),最大化,最小化位置。函數(shù)功能: 函及原型
[DllImport("User32.dll")]
public static extern bool SetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
//函數(shù)將創(chuàng)建指定窗口的線程設(shè)置到前臺,并且激活該窗口。鍵盤輸入轉(zhuǎn)向該窗口,并為用戶改各種可視的記號
[DllImport("User32.dll")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
//該函數(shù)返回桌面窗口的句柄。桌面窗口覆蓋整個(gè)屏幕。桌面窗口是一個(gè)要在其上繪制所有的圖標(biāo)和其他窗口的區(qū)域
[DllImport("User32.dll")]
public static extern IntPtr GetDesktopWindow();
//函數(shù)名。該函數(shù)返回指定窗口的顯示狀態(tài)以及被恢復(fù)的、最大化的和最小化的窗口位置
[DllImport("User32.dll")]
public static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
//是用于得到被定義的系統(tǒng)數(shù)據(jù)或者系統(tǒng)配置信息的一個(gè)專有名詞
[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>
/// 圖像區(qū)域?qū)ο?
/// </summary>
public struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}
/// <summary>
/// 圖像點(diǎn)位位置
/// </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;
}
}
以上這篇C#窗體程序?qū)崿F(xiàn)全屏及取消全屏步驟就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
C#通過標(biāo)簽軟件Bartender的ZPL命令打印條碼
這篇文章介紹了C#通過標(biāo)簽軟件Bartender的ZPL命令打印條碼,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-01-01
C#設(shè)置程序開機(jī)啟動(dòng)的實(shí)現(xiàn)示例
本文主要介紹了C#設(shè)置程序開機(jī)啟動(dòng)的實(shí)現(xiàn)示例,可以通過修改注冊表將啟動(dòng)信息寫入注冊表來實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2024-01-01
C#實(shí)現(xiàn)HTTP訪問類HttpHelper的示例詳解
在項(xiàng)目開發(fā)過程中,我們經(jīng)常會訪問第三方接口,如我們需要接入的第三方接口是Web API,這時(shí)候我們就需要使用HttpHelper調(diào)用遠(yuǎn)程接口了。本文為大家介紹了C#實(shí)現(xiàn)HTTP訪問類HttpHelper的示例代碼,需要的可以參考一下2022-09-09
C# ListView 點(diǎn)擊表頭對數(shù)據(jù)進(jìn)行排序功能的實(shí)現(xiàn)代碼
這篇文章主要介紹了C# ListView 點(diǎn)擊表頭對數(shù)據(jù)進(jìn)行排序功能的實(shí)現(xiàn)代碼,需要的朋友可以參考下2017-04-04
C#調(diào)用dll報(bào)錯(cuò):無法加載dll,找不到指定模塊的解決
這篇文章主要介紹了C#調(diào)用dll報(bào)錯(cuò):無法加載dll,找不到指定模塊的解決問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-01-01
Unity學(xué)習(xí)之FSM有限狀態(tài)機(jī)
這篇文章主要介紹了Unity學(xué)習(xí)之FSM有限狀態(tài)機(jī),通過詳細(xì)的代碼案例來進(jìn)行解析說明,希望這篇文章對你有所幫助2021-06-06

