C#窗體程式實現全屏及取消全屏步驟
阿新 • • 發佈:2020-12-09
由於專案需要,需要用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,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,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,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,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; } }
以上這篇C#窗體程式實現全屏及取消全屏步驟就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。