我们也许会有一些奇怪的需求,比如说禁止一个外部程序的窗口大小更改。

如果我们没法修改外部程序的代码,那要怎么做呢?

当然,我们可以通过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# 强行锁定 第三方 外部 应用程序窗体窗口的分辨率尺寸大小 禁止鼠标拖拽改变窗口大小的更多相关文章

  1. Winform拖拽改变无边框窗体大小

    大家在进行Winform开发过程中,很容易就可以完成一个窗口的布局工作,但现在的软件界面美化效果一个比一个好,很多软件都是无边框的,于是乎,你是不是也感叹:winform的带边框的窗体如此丑陋,我一定 ...

  2. Delphi:窗体自适应屏幕分辨率(根据预设值的比例改变)

    delphi 程序适应屏幕分辨率,先在表单单元的Interface部分定义两个常量, 表示设计时的屏幕的宽度和高度(以像素为单位). 在表单的Create事件中先判断 当前分辨率是否与设计分辨率相同, ...

  3. WPF 窗体中的 Canvas 限定范围拖动 鼠标滚轴改变大小

    xaml代码: <Canvas Name="movBg"> <Canvas.Background> <LinearGradientBrush EndP ...

  4. JD . 简单的网站构成、引入图标、去除 图片间距/加粗/倾斜/下划线/蓝色外边框 禁止文本拖拽、文字居中、做logo、模拟鼠标 、不使用hover外部css样式实现hover鼠标悬停改变样式

    模拟京东案例准备: 截图(效果图PSD文件) 搭建项目环境     (结构样式行为分离)   HTML 核心文件     index.html CSS       控制样式 base.css(基础样式 ...

  5. Qt无边框窗体-最大化时支持拖拽还原

    目录 一.概述 二.效果展示 三.demo制作 1.设计窗体 2.双击放大 四.拖拽 五.相关文章 原文链接:Markdown模板 一.概述 用Qt进行开发界面时,既想要实现友好的用户交互又想界面漂亮 ...

  6. WPF实现无边框窗体拖拽右下角▲ 改变窗体大小【framwork4.0】 谢谢大家关注

    效果图:(右下角拖拽改变窗体大小) 第一步:添加xaml代码: <Border Name="ResizeBottomRight" MouseMove="Resize ...

  7. Qt应用程序主窗口之二:拖放操作与打印文档

    一.拖放操作 对于一个实用的应用程序,不仅希望能从文件菜单中打开一个文件,更希望可以通过拖动直接将桌面上的文件拖入程序界面上来打开,就像可以将.pro文件拖入Creator中来打开整个项目一样.Qt中 ...

  8. C++调用外部应用程序

    很多时候,我们的程序需要调用DOS命令,通过Dos命令调用其他程序从而完成所需要完成的功能.比如,调用Dos程序PKZIP完成ZIP包的解压缩,调用SVN完成文件的更新或者上传.但是在程序运行时又要求 ...

  9. 在winform嵌入外部应用程序

    应朋友要求,需要将一个第三方应用程序嵌入到本程序WinForm窗口,以前在VB6时代做过类似的功能,其原理就是利用Windows API中FindWindow函数找到第三方应用程序句柄,再利用SetP ...

随机推荐

  1. android安全学习、工具库、框架

    在介绍android工具之前,先理清android中出现的文件格式: java:android源码 class:java编译后生成: dex: 由dx工具编译class而成,由dalvik执行: sm ...

  2. 深入浅出带你玩转sqlilabs(一)

    一.MySQL数据库结构分层 1.1库名,表名,列名,数据库用户等 Mysql数据库结构示例: 数据库A zblog = www.zblog.com 表名 列名(字段) 数据 数据库B dede = ...

  3. 【pytest系列】- mark标记功能详细介绍

    如果想从头学起pytest,可以去看看这个系列的文章! https://www.cnblogs.com/miki-peng/category/1960108.html mark标记 ​ 在实际工作中, ...

  4. java之try catch finally

    try{ }catch(Exception e){ }finally{ } java异常处理在编程中很常见,将可能抛出异常的语句放在try{}中,若有异常抛出,则try{}中抛出异常语句之后的语句不再 ...

  5. Web端直传数据至OSS

    官方文档 最佳实践 小程序直传实践 支付宝小程序直传实践 微信小程序直传实践 Web端PostObject直传实践 Web端PostObject直传实践简介 JavaScript客户端签名直传 服务端 ...

  6. Object划分

    Object划分 1.PO(persistantobject)持久对象 PO就是对应数据库中某个表中的一条记录,多个记录可以用PO的集合.PO中应该不包 含任何对数据库的操作. 2.DO(Domain ...

  7. 电脑进入bios和u盘启动快捷键

    参考:http://www.jb51.net/os/78638.html 一:联想系列 1:联想笔记本电脑 Thinkpad idea 520  :关机状态下,在左下角用回形针捅小孔,知道出现bios ...

  8. Vulkan移植GPUImage(五)从P到Z的滤镜

    现aoce_vulkan_extra把GPUImage里从P到Z的大部分滤镜用vulkan的ComputeShader实现了,也就是最后一部分的移植,整个过程相对前面来说比较简单,大部分我都是直接复制 ...

  9. C++ string的size()和length()函数没有区别

    C++标准库中的string中两者的源代码如下:      size_type   __CLR_OR_THIS_CALL   length()   const     { //   return   ...

  10. Spring Cloud Alibaba Nacos Discovery 实战

    Nacos 作为服务注册中心,可以快速简单的将服务自动注册到 Nacos 服务端,并且能够动态无感知的刷新某个服务实例的服务列表,为分布式系统提供服务注册与发现功能 一.创建服务 1.创建项目 pom ...