关键词搜索

源码搜索 ×
×

C# 窗体视频控件进入全屏模式和退出全屏模式

发布2018-03-13浏览5975次

详情内容

窗体控件进入全屏模式和退出全屏模式,视频播放的时候用到此功能。

工具类代码

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Runtime.InteropServices;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using System.Windows.Forms;
  8. namespace CvNetVideo.Play
  9. {
  10. class FullScreenHelper
  11. {
  12. bool m_bFullScreen = false;
  13. IntPtr m_OldWndParent = IntPtr.Zero;
  14. WINDOWPLACEMENT m_OldWndPlacement = new WINDOWPLACEMENT();
  15. Control m_control = null;
  16. public FullScreenHelper(Control c)
  17. {
  18. m_control = c;
  19. }
  20. struct POINT
  21. {
  22. int x;
  23. int y;
  24. };
  25. struct RECT
  26. {
  27. public int left;
  28. public int top;
  29. public int right;
  30. public int bottom;
  31. };
  32. //锁定指定窗口,禁止它更新。同时只能有一个窗口处于锁定状态。锁定指定窗口,禁止它更新。同时只能有一个窗口处于锁定状态
  33.         [DllImport("User32.dll")]
  34.         public static extern bool LockWindowUpdate(IntPtr hWndLock);
  35.         //函数来设置弹出式窗口,层叠窗口或子窗口的父窗口。新的窗口与窗口必须属于同一应用程序
  36.         [DllImport("User32.dll")]
  37.         public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
  38.         //函数设置指定窗口的显示状态和恢复,最大化,最小化位置。函数功能: 函及原型  
  39.         [DllImport("User32.dll")]
  40.         public static extern bool SetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
  41.         //函数将创建指定窗口的线程设置到前台,并且激活该窗口。键盘输入转向该窗口,并为用户改各种可视的记号
  42.         [DllImport("User32.dll")]
  43.         public static extern bool SetForegroundWindow(IntPtr hWnd);
  44.         //该函数返回桌面窗口的句柄。桌面窗口覆盖整个屏幕。桌面窗口是一个要在其上绘制所有的图标和其他窗口的区域
  45.         [DllImport("User32.dll")]
  46.         public static extern IntPtr GetDesktopWindow();
  47.         //函数名。该函数返回指定窗口的显示状态以及被恢复的、最大化的和最小化的窗口位置
  48.         [DllImport("User32.dll")]
  49.         public static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
  50.         //是用于得到被定义的系统数据或者系统配置信息的一个专有名词 
  51.         [DllImport("User32.dll")]
  52.         public static extern int GetSystemMetrics(int nIndex);
  53.         [DllImport("user32.dll", EntryPoint = "GetParent", SetLastError = true)]
  54.         public static extern IntPtr GetParent(IntPtr hWnd);
  55.         [DllImport("user32.dll", CharSet = CharSet.Auto)]
  56.         public static extern int SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int y, int Width, int Height, int flags);
  57.         [DllImport("user32.dll", CharSet = CharSet.Auto)]
  58.         public static extern System.IntPtr GetForegroundWindow();
  59.         [DllImport("user32")]
  60.         public static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect);
  61.         [DllImport("user32.dll")]
  62.         public static extern uint ScreenToClient(IntPtr hwnd, ref POINT p);
  63.          public void FullScreen(bool flag)
  64. {
  65. m_bFullScreen = flag;
  66. if (!m_bFullScreen)
  67. {
  68. LockWindowUpdate(m_control.Handle);
  69. SetParent(m_control.Handle, m_OldWndParent);
  70. SetWindowPlacement(m_control.Handle, ref m_OldWndPlacement);
  71. SetForegroundWindow(m_OldWndParent);
  72. LockWindowUpdate(IntPtr.Zero);
  73. }
  74. else
  75. {
  76. GetWindowPlacement(m_control.Handle, ref m_OldWndPlacement);
  77. int nScreenWidth = GetSystemMetrics(0);
  78. int nScreenHeight = GetSystemMetrics(1);
  79. m_OldWndParent = GetParent(m_control.Parent.Handle);
  80. SetParent(m_control.Handle, GetDesktopWindow());
  81. WINDOWPLACEMENT wp1 = new WINDOWPLACEMENT();
  82. wp1.length = (uint)Marshal.SizeOf(wp1);
  83. wp1.showCmd = 1;
  84. wp1.rcNormalPosition.left = 0;
  85. wp1.rcNormalPosition.top = 0;
  86. wp1.rcNormalPosition.right = nScreenWidth;
  87. wp1.rcNormalPosition.bottom = nScreenHeight;
  88. SetWindowPlacement(m_control.Handle, ref wp1);
  89. SetForegroundWindow(GetDesktopWindow());
  90. SetForegroundWindow(m_control.Handle);
  91. }
  92. m_bFullScreen = !m_bFullScreen;
  93. }
  94. struct WINDOWPLACEMENT
  95. {
  96. public uint length;
  97. public uint flags;
  98. public uint showCmd;
  99. public POINT ptMinPosition;
  100. public POINT ptMaxPosition;
  101. public RECT rcNormalPosition;
  102. };
  103. }
  104. }

调用方式

  1. /// <summary>
  2. /// 全屏事件
  3. /// </summary>
  4. /// <param name="sender"></param>
  5. /// <param name="e"></param>
  6. private void UCVideo_DoubleClick(object sender, EventArgs e)
  7. {
  8. //全屏设置
  9. //sdlVideo.SDL_MaximizeWindow();
  10. fullScreenHelper = new CvNetVideo.Play.FullScreenHelper(this);
  11. fullScreenHelper.FullScreen(true);
  12. Console.WriteLine("Entrance FullScreen Mode");
  13. }
  14. /// <summary>
  15. /// 按键弹起事件
  16. /// </summary>
  17. private void UCVideo_KeyUp(object sender, KeyEventArgs e)
  18. {
  19. // ESC 退出全屏
  20. if (e.KeyCode == Keys.Escape&& fullScreenHelper!=null)
  21. {
  22. fullScreenHelper.FullScreen(false);
  23. fullScreenHelper = null;
  24. Console.WriteLine("Exit FullScreen Mode");
  25. }
  26. }

测试效果图



注意:在使用SDL的全屏操作过程中设置是无效的,播放视频过程中不能实现修改。代码如下:

  1. public void SDL_MaximizeWindow()
  2. {
  3. Console.WriteLine("设置全屏");
  4. SDL.SDL_MaximizeWindow(screen);
  5. SDL.SDL_SetWindowFullscreen(screen, SDL.SDL_GetWindowFlags(screen));
  6. SDL.SDL_ShowWindow(screen);
  7. //int width, height;
  8. 获取最大窗口值
  9. //SDL2.SDL.SDL_GetWindowMaximumSize(screen, out width, out height);
  10. 设置最大窗口值
  11. //if (width>0&&height>0)
  12. //{
  13. // SDL2.SDL.SDL_SetWindowMaximumSize(screen, width, height);
  14. // Console.WriteLine("设置全屏......成功!width=" + width + ",height=" + height);
  15. //}
  16. //else
  17. //{
  18. // Console.WriteLine("设置全屏......失败!width=" + width + ",height=" + height);
  19. // SDL2.SDL.SDL_SetWindowMaximumSize(screen, w, h);
  20. //}
  21. }

工具代码功能改进

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Runtime.InteropServices;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using System.Windows.Forms;
  8. namespace CvNetVideo.Play
  9. {
  10. /// <summary>
  11. /// 定义全屏抽象类
  12. /// </summary>
  13. public abstract class FullScreenObject
  14. {
  15. public abstract void FullScreen(bool flag);
  16. }
  17. /// <summary>
  18. /// 桌面全屏
  19. /// </summary>
  20. public unsafe class FullScreenHelper: FullScreenObject
  21. {
  22. bool m_bFullScreen = false;
  23. WINDOWPLACEMENT m_OldWndPlacement = new WINDOWPLACEMENT();
  24. UCVideo m_control = null;
  25. public FullScreenHelper(UCVideo control)
  26. {
  27. m_control = control;
  28. }
  29. private IntPtr m_OldWndParent = IntPtr.Zero;
  30. DockStyle old_docker_style;
  31. int old_left;
  32. int old_width;
  33. int old_height;
  34. int old_top;
  35. public override void FullScreen(bool flag)
  36. {
  37. m_bFullScreen = flag;
  38. if (!m_bFullScreen)
  39. {
  40. #region 方式一:窗体容积改变时不能全屏,未能解决IE全屏显示不全问题
  41. //ShellSDK.LockWindowUpdate(m_control.Handle);
  42. //ShellSDK.SetParent(m_control.Handle, m_OldWndParent);
  43. //ShellSDK.SetWindowPlacement(m_control.Handle, ref m_OldWndPlacement);
  44. //ShellSDK.SetForegroundWindow(m_OldWndParent);
  45. //ShellSDK.LockWindowUpdate(IntPtr.Zero);
  46. #endregion
  47. #region 方式二:在容器改变时可以实现全屏,未能解决IE全屏显示不全问题
  48. // 取消全屏设置
  49. m_control.Dock = old_docker_style;
  50. m_control.Left = old_left;
  51. m_control.Top = old_top;
  52. m_control.Width = old_width;
  53. m_control.Height = old_height;
  54. ShellSDK.SetParent(m_control.Handle, m_OldWndParent);
  55. #endregion
  56. }
  57. else
  58. {
  59. #region 方式一:窗体容积改变时不能全屏,未能解决IE全屏显示不全问题
  60. //ShellSDK.GetWindowPlacement(m_control.Handle, ref m_OldWndPlacement);
  61. //int nScreenWidth = ShellSDK.GetSystemMetrics(0);
  62. //int nScreenHeight = ShellSDK.GetSystemMetrics(1);
  63. //m_OldWndParent = ShellSDK.GetParent(m_control.Handle);
  64. //ShellSDK.SetParent(m_control.Handle, ShellSDK.GetDesktopWindow());
  65. //WINDOWPLACEMENT wp1 = new WINDOWPLACEMENT();
  66. //wp1.length = (uint)Marshal.SizeOf(wp1);
  67. //wp1.showCmd = 1;
  68. //wp1.rcNormalPosition.left = 0;
  69. //wp1.rcNormalPosition.top = 0;
  70. //wp1.rcNormalPosition.right = Screen.PrimaryScreen.Bounds.Width/*nScreenWidth*/;
  71. //wp1.rcNormalPosition.bottom = Screen.PrimaryScreen.WorkingArea.Height/* nScreenHeight*/;
  72. //ShellSDK.SetWindowPlacement(m_control.Handle, ref wp1);
  73. //ShellSDK.SetForegroundWindow(ShellSDK.GetDesktopWindow());
  74. //ShellSDK.SetForegroundWindow(m_control.Handle);
  75. #endregion
  76. #region 方式二:在容器改变时可以实现全屏,未能解决IE全屏显示不全问题
  77. // 记录原来的数据
  78. old_docker_style = m_control.Dock;
  79. old_left = m_control.Left;
  80. old_width = m_control.Width;
  81. old_height = m_control.Height;
  82. old_top = m_control.Top;
  83. m_OldWndParent = ShellSDK.GetParent(m_control.Handle);
  84. // 设置全屏数据
  85. int nScreenWidth = ShellSDK.GetSystemMetrics(0);
  86. int nScreenHeight = ShellSDK.GetSystemMetrics(1);
  87. m_control.Dock = DockStyle.None;
  88. m_control.Left = 0;
  89. m_control.Top = 0;
  90. m_control.Width = nScreenWidth;
  91. m_control.Height = nScreenHeight;
  92. ShellSDK.SetParent(m_control.Handle, ShellSDK.GetDesktopWindow());
  93. ShellSDK.SetWindowPos(m_control.Handle, -1, 0, 0, m_control.Right - m_control.Left, m_control.Bottom - m_control.Top, 0);
  94. #endregion
  95. }
  96. m_bFullScreen = !m_bFullScreen;
  97. }
  98. }
  99. /// <summary>
  100. /// 在容器内部全屏
  101. /// </summary>
  102. public class FullScreenInContainerHelper : FullScreenObject
  103. {
  104. bool m_bFullScreen = false;
  105. Control m_control = null;
  106. public FullScreenInContainerHelper(Control control)
  107. {
  108. m_control = control;
  109. }
  110. private IntPtr m_OldWndParent = IntPtr.Zero;
  111. private IntPtr m_father_hwnd;
  112. private RECT m_rect = new RECT();
  113. public override void FullScreen(bool flag)
  114. {
  115. m_bFullScreen = flag;
  116. if (!m_bFullScreen)
  117. {
  118. ShellSDK.SetParent(m_control.Handle, m_father_hwnd);
  119. 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);
  120. ShellSDK.SetForegroundWindow(m_father_hwnd);
  121. }
  122. else
  123. {
  124. m_father_hwnd = ShellSDK.GetParent(m_control.Handle);
  125. ShellSDK.GetWindowRect(m_control.Handle, out RECT rect);
  126. POINT pt = new POINT();
  127. pt.x = rect.left;
  128. pt.y = rect.top;
  129. ShellSDK.ScreenToClient(m_father_hwnd, ref pt);
  130. rect.right = rect.right - rect.left + pt.x;
  131. rect.bottom = rect.bottom - rect.top + pt.y;
  132. rect.left = pt.x;
  133. rect.top = pt.y;
  134. m_rect = rect;
  135. ShellSDK.GetWindowRect(m_father_hwnd, out RECT rect_fature);
  136. ShellSDK.SetWindowPos(m_control.Handle, 0, 0, 0, rect_fature.right - rect_fature.left, rect_fature.bottom - rect_fature.top, 0);
  137. }
  138. m_bFullScreen = !m_bFullScreen;
  139. }
  140. }
  141. /// <summary>
  142. /// Windows系统API-SDK
  143. /// </summary>
  144. public class ShellSDK
  145. {
  146. //锁定指定窗口,禁止它更新。同时只能有一个窗口处于锁定状态。锁定指定窗口,禁止它更新。同时只能有一个窗口处于锁定状态
  147. [DllImport("User32.dll")]
  148. public static extern bool LockWindowUpdate(IntPtr hWndLock);
  149. //函数来设置弹出式窗口,层叠窗口或子窗口的父窗口。新的窗口与窗口必须属于同一应用程序
  150. [DllImport("User32.dll")]
  151. public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
  152. //函数设置指定窗口的显示状态和恢复,最大化,最小化位置。函数功能: 函及原型   
  153. [DllImport("User32.dll")]
  154. public static extern bool SetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
  155. //函数将创建指定窗口的线程设置到前台,并且激活该窗口。键盘输入转向该窗口,并为用户改各种可视的记号
  156. [DllImport("User32.dll")]
  157. public static extern bool SetForegroundWindow(IntPtr hWnd);
  158. //该函数返回桌面窗口的句柄。桌面窗口覆盖整个屏幕。桌面窗口是一个要在其上绘制所有的图标和其他窗口的区域
  159. [DllImport("User32.dll")]
  160. public static extern IntPtr GetDesktopWindow();
  161. //函数名。该函数返回指定窗口的显示状态以及被恢复的、最大化的和最小化的窗口位置
  162. [DllImport("User32.dll")]
  163. public static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
  164. //是用于得到被定义的系统数据或者系统配置信息的一个专有名词  
  165. [DllImport("User32.dll")]
  166. public static extern int GetSystemMetrics(int nIndex);
  167. [DllImport("user32.dll", EntryPoint = "GetParent", SetLastError = true)]
  168. public static extern IntPtr GetParent(IntPtr hWnd);
  169. [DllImport("user32.dll", CharSet = CharSet.Auto)]
  170. public static extern int SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int y, int Width, int Height, int flags);
  171. [DllImport("user32.dll", CharSet = CharSet.Auto)]
  172. public static extern System.IntPtr GetForegroundWindow();
  173. [DllImport("user32")]
  174. public static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect);
  175. [DllImport("user32.dll")]
  176. public static extern uint ScreenToClient(IntPtr hwnd, ref POINT p);
  177. }
  178. /// <summary>
  179. /// 图像区域对象
  180. /// </summary>
  181. public struct RECT
  182. {
  183. public int left;
  184. public int top;
  185. public int right;
  186. public int bottom;
  187. }
  188. /// <summary>
  189. /// 图像点位位置
  190. /// </summary>
  191. public struct POINT
  192. {
  193. public int x;
  194. public int y;
  195. }
  196. /// <summary>
  197. /// 图像窗口对象
  198. /// </summary>
  199. public struct WINDOWPLACEMENT
  200. {
  201. public uint length;
  202. public uint flags;
  203. public uint showCmd;
  204. public POINT ptMinPosition;
  205. public POINT ptMaxPosition;
  206. public RECT rcNormalPosition;
  207. }
  208. }

更多sdl窗口操作参考:

SDL_Window :http://blog.csdn.net/leixiaohua1020/article/details/40701203

SDL 多线程窗口 : http://blog.csdn.net/x_iya/article/details/52198688

相关技术文章

点击QQ咨询
开通会员
返回顶部
×
微信扫码支付
微信扫码支付
确定支付下载
请使用微信描二维码支付
×

提示信息

×

选择支付方式

  • 微信支付
  • 支付宝付款
确定支付下载