zoukankan      html  css  js  c++  java
  • 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();

    随笔到此结束

  • 相关阅读:
    夺命雷公狗—玩转SEO---64---高质量链接打造
    夺命雷公狗—玩转SEO---63---页面相似度算法原理
    夺命雷公狗—玩转SEO---62---TF-IDF核心算法与运用
    夺命雷公狗—玩转SEO---61---全站title与description深层次玩法,门户站和流量站
    夺命雷公狗—玩转SEO---60---全站title与description深层次玩法,企业站内容页
    夺命雷公狗—玩转SEO---59---全站title与description深层次玩法,企业站列表页
    夺命雷公狗—玩转SEO---58---全站title与description深层次玩法,企业站首页篇
    夺命雷公狗—玩转SEO---57---DEDE副标题大爆发
    夺命雷公狗—玩转SEO---56---query需求分析与搜索意图研究
    夺命雷公狗—玩转SEO---55---页面去重原理
  • 原文地址:https://www.cnblogs.com/Dinnerbone/p/14872611.html
Copyright © 2011-2022 走看看