C# 强行锁定 第三方 外部 应用程序窗体窗口的分辨率尺寸大小 禁止鼠标拖拽改变窗口大小
我们也许会有一些奇怪的需求,比如说禁止一个外部程序的窗口大小更改。
如果我们没法修改外部程序的代码,那要怎么做呢?
当然,我们可以通过DLL注入目标程序的方式去Hook或registry一个事件来检测,但这也太麻烦了吧。
如果想做非侵入式的,那就需要用到Windows下的系统函数去完成工作。
查来查去,最好用的是MoveWindow函数
1 MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint)
可以看到,这个函数要求传入一个IntPtr类型的句柄、一组int类型的坐标、以及int类型的窗口的宽度和高度和最后的bool类型的是否刷新显示。
句柄大家应该都知道是什么,相当于是ID身份证一样的存在,坐标就是指你把窗口移动到屏幕上的那个坐标。高宽不必说,这就是我们要改的。至于刷新显示我们也无需过多理解,一个性能问题罢了。
首先我们要获取坐标,先写一个窗口枚举器
/*窗口句柄枚举器*/ public static class WindowsEnumerator { private delegate bool EnumWindowsProc(IntPtr windowHandle, IntPtr lParam); [DllImport("user32.dll", SetLastError = true)] private static extern bool EnumWindows(EnumWindowsProc callback, IntPtr lParam); [DllImport("user32.dll", SetLastError = true)] private static extern bool EnumChildWindows(IntPtr hWndStart, EnumWindowsProc callback, IntPtr lParam); [DllImport("user32.dll", SetLastError = true)] static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount); [DllImport("user32.dll", SetLastError = true)] static extern int GetWindowTextLength(IntPtr hWnd); private static List<IntPtr> handles = new List<IntPtr>(); private static string targetName; public static List<IntPtr> GetWindowHandles(string target) { targetName = target; EnumWindows(EnumWindowsCallback, IntPtr.Zero); return handles; } private static bool EnumWindowsCallback(IntPtr HWND, IntPtr includeChildren) { StringBuilder name = new StringBuilder(GetWindowTextLength(HWND) + 1); GetWindowText(HWND, name, name.Capacity); if (name.ToString() == targetName) handles.Add(HWND); EnumChildWindows(HWND, EnumWindowsCallback, IntPtr.Zero); return true; } }
调用方法是
WindowsEnumerator.GetWindowHandles("窗口名字")
然后这个方法返回的是一个数组,我们需要用到foreach去遍历里面的东西
foreach (var item in WindowsEnumerator.GetWindowHandles("窗口名字"))
这个item的数据类型是IntPtr,也就是moveWindow函数所需的第一个参数hWnd——句柄
我们接着看第二组参数,需要传入X和Y,也就是窗口移动到屏幕上的位置。
如果把这个写死,你的窗口就无法移动了,只会固定在一个地方。
所以我们需要动态的去获取窗口当前位置,然后把位置传入给moveWindow方法所需的X和Y参数。
我们需要用到GetWindowRect函数,需要传入hWnd和RECT
[DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect); [StructLayout(LayoutKind.Sequential)] public struct RECT //定位当前窗口位置 { public int x; //最左坐标 public int y; //最上坐标 }
然后我们需要在执行MoveWindow函数之前执行getWindowRect函数,放到上面写的foreach里就好了。
记得new一个RECT结构体出来。
Rect rect = new Rect();
GetWindowRect(item, ref rect);
因为我们禁止窗口修改不是一次性的,需要循环去检测,我们把检测方法写个死循环While(true)就好了,然后开辟新的线程去执行这个死循环。
因为C# 是有垃圾回收策略的,我们无需担心性能开支过大所造成的的问题,毕竟就是写着玩,学习学习(难道这有人有这个需求吗不会把不会把?)
总结一下就是如下代码:
RECT rect = new RECT(); //禁止修改窗口 public void Pck(){ while (true){ foreach (var item in WindowsEnumerator.GetWindowHandles("Minecraft 1.12.2")){ GetWindowRect(item, ref rect);//获取窗口在屏幕上的坐标 MoveWindow(item, rect.x, rect.y, 1024, 768, true); //锁定为1024*768分辨率 } Thread.Sleep(2000); //2秒检测一次 } }
然后调用的时候直接:
Thread thread = new Thread(new ThreadStart(Pck)); thread.Start();
随笔到此结束
- c#:winform鼠标拖动窗口大小时,设定窗口最小尺寸
- c#:winform鼠标拖动窗口大小时,设定窗口最小尺寸
- VC禁止或允许拖拽改变窗口尺寸
- C# WinForm中禁止改变窗口大小的方法
- C# 改变无边框窗体尺寸大小的方法
- C# 改变无边框窗体尺寸大小的方法
- D23_05_改变形状窗口的尺寸(自定义窗体大小改变)
- C#开发WinForm窗体程序时,如何禁止用户改变程序窗体的大小?
- C# 改变无边框窗体的尺寸大小
- MFC禁止窗口最大化按钮和禁止鼠标改变窗口大小的操作
- c#禁止通过拖动,双击标题栏改变窗体大小
- java中 实现无标题无边框的窗体能够用鼠标拖动改变窗口大小
- [Win32]只允许最大化最小化窗口,禁止双击标题栏、拖动窗体、点击复原按钮来改变窗口大小
- 如何设置C#窗体大小不能改变
- C# WinForm控件随窗体大小改变自动适应改变
- opencv--用鼠标动态改变显示图像窗口大小
- 禁止改变窗体大小以及图标Java
- c#禁止Form窗口调整大小,如何禁止combobox输入
- (VC/MFC)禁止对话框(窗口)的大小改变和移动
- win32应用禁止改变窗口大小方法