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

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

当然,我们可以通过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 ...

  10. windows下调用外部exe程序 SHELLEXECUTEINFO

    本文主要介绍两种在windows下调用外部exe程序的方法: 1.使用SHELLEXECUTEINFO 和 ShellExecuteEx SHELLEXECUTEINFO 结构体的定义如下: type ...

随机推荐

  1. MyEclipse编码设置及字体设置等

    原文: http://wenku.baidu.com/link?url=GTo5q8E1iVRYIYa-AiDP6_PJ4sQk7j1SPTr-CthVBw9hTGLPgR4TOeq9o8Sg0yEJ ...

  2. GTAC 2015 Schedule

    之前发的GTAC 2015将于11月10号和11号召开 现在时刻表也出来啦 https://developers.google.com/google-test-automation-conferenc ...

  3. 实战Centos系统部署Codis集群服务

    导读 Codis 是一个分布式 Redis 解决方案, 对于上层的应用来说, 连接到 Codis Proxy 和连接原生的 Redis Server 没有明显的区别 (不支持的命令列表), 上层应用可 ...

  4. js网页滚动条滚动事件实例分析

    本文实例讲述了js网页滚动条滚动事件用法.分享给大家供大家参考.具体分析如下: 在做js返回顶部的效果时,要监听网页滚动条滚动事件,这个事件就是:window.onscroll.当onscroll事件 ...

  5. 结构体定义 typedef struct 用法详解和用法小结

    typedef是类型定义的意思.typedef struct 是为了使用这个结构体方便.具体区别在于:若struct node {}这样来定义结构体的话.在申请node 的变量时,需要这样写,stru ...

  6. Netty In Action中文版 - 第一章:Netty介绍

    本章介绍 Netty介绍 为什么要使用non-blocking IO(NIO) 堵塞IO(blocking IO)和非堵塞IO(non-blocking IO)对照 Java NIO的问题和在Nett ...

  7. 笔记-64位dump转32位dump

    下图是从测试拷64位windbg抓的dump文件拖到32位windbg查看线程堆栈信息的效果. 那么我们加载一下wow64exts模块,因为需要这个模块帮助把64位的dump,转换成32位的dump. ...

  8. 从golang-gin-realworld-example-app项目学写httpapi (八)

    https://github.com/gothinkster/golang-gin-realworld-example-app/blob/master/common/unit_test.go 单元测试 ...

  9. Bootstrap3的输入框数字点击修改效果

    <div class="container"><div class="page-header"><h3>Bootstrap ...

  10. C语言实现全排列和回溯法总结

    一.递归实现全排列 #include"cstdio" ]; void print_permutation(int n,int *A,int cur){ if(cur==n){ ;i ...