windows使用FindWindow函数查找窗口句柄-CSDN博客

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

理解什么是句柄

对于“句柄”之前一直停留在一知半解的认识层面也说不清具体概念只知道它是一个标识符用来标记对象或者说某个东西的。只知其名不知其意。目前学习windows编程对“句柄”做一个完整的认。

现在先看一张图这张图是从其他博主博文扒下来的
在这里插入图片描述
在这里插入图片描述
图1是程序运行到某时刻时的内存快照图2是程序往后运行到另一时刻时的内存快照。红色部分标出了两次的变化。

【解释一下】
windows是一个以虚拟内存为基础的操作系统很多时候进程的代码和数据并不是全部装入内存进程某一段装入内存之后可能会被换出到外存。当再次需要时会重新装入内存。两次装入内存那么很多时候装入的地址是不一样的。也就是说同一个对象在内存中的地址会变化。那么程序怎么才能准确的访问到对象呢这时候就引入了句柄。

系统为每个进程在内存中分配一定的区域用来存放各个句柄即一个个32位无符号整型值32位操作系统中。每个32位无符号整型值相当于一个指针指向内存中的另一个区域我们不妨称之为区域A。而区域A中存放的正是对象在内存中的地址。当对象在内存中的位置发生变化时区域A的值被更新变为当前时刻对象在内存中的地址而在这个过程中区域A的位置以及对应句柄的值是不发生变化的。这种机制用一种形象的说法可以表述为有一个固定的地址句柄指向一个固定的位置区域A而区域A中的值可以动态地变化它时刻记录着当前时刻对象在内存中的地址。这样无论对象的位置在内存中如何变化只要我们掌握了句柄的值就可以找到区域A进而找到该对象。而句柄的值在程序本次运行期间是绝对不变的我们即系统当然可以掌握它。这就是以不变应万变按图索骥顺藤摸瓜。

所以我们可以这样理解句柄
  • 数值上是一个32位的unsigned int;
  • 逻辑上相当于一个二级指针。指向对象在内存中的地址。理解上这个指针的值不可变的普通指针的值可以变得。
  • 作用上是windwos使用句柄来标识诸多资源或者对象。比如窗口画笔进程线程等等。

【回到开头windows下我们如何拿到一个窗口句柄】
使用FindWindow函数可以根据窗口的类名和窗口名拿到句柄

HWND FindWindowLPCTSTR IpClassNameLPCTSTR IpWindowName;
//IpClassName 指向一个指定了类名的空结束字符串
//pWindowName指向一个指定了窗口名窗口标题的空结束字符串。如果该参数为空则为所有窗口全匹配。
//返回值如果函数成功返回值为具有指定类名和窗口名的窗口句柄如果函数失败返回值为NULL。

[那么我们如何获取到窗口的 类名 和 窗口名呢]
我们可以使用vs自带的工具spy++.exe;
通过搜索–>查找窗口拖到要查询的窗口就行。
在这里插入图片描述
现在我们写一个简单的例子用记事本打开一个文件。我这里打开的是cfg.ini文件。然后找到记事本窗口然后通过查找到的记事本窗口句柄将记事本窗口进行移动位置并且改变大小。

//根据类名和窗口名查找窗口句柄
HWND GetWindowHandle(std::string className, std::string windowName)
{
	HWND hwnd = FindWindowA(className.c_str(), windowName.c_str());
	return hwnd;
}

int main()
{
	HWND notePadWHND = GetWindowHandle("Notepad", "cfg.ini - 记事本");
	if (notePadWHND) {
		RECT rect;
		GetWindowRect(notePadWHND, &rect); //获取记事本窗口的位置
		MoveWindow(notePadWHND, rect.left + 500, rect.top + 300, 300, 300, TRUE);//移动记事本窗口
	}
	return 0;
}
阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: windows