赞
踩
窗口是Windows的核心组件,Windoows下的绝大部分应用都是利用Windows提供的原生窗口,通过一些GUI编程框架(如Qt,MFC)加以渲染来生成的。本质上讲,这些框架都是基于Windows提供的一些API函数作进一步封装来实现的。
对于一个应用程序最重要的功能就是与人的交互,使得我们可以通过键盘输入和鼠标输入来实现对应用程序的控制。
Windows是利用消息(Message)来实现窗口与用户的输入之间通信的,当应用程序在内存中初始化注册成功后,操作系统会为应用程序创建一个消息队列,应用程序通过在消息队列中取出消息来判断要执行的相应操作,具体如下:
这里主要是使用Windows提供的API,利用以上的消息机制,来模拟操作系统给某一个应用程序发送消息。
使用到的API函数在<Windows.h>头文件中,使用到了以下函数:
以上函数的具体方法可以查阅MSDN官方文档。
主要包括以下几个步骤:
#include <iostream> #include <Windows.h> using namespace std; int main() { HWND htext = FindWindow(NULL, L"无标题 - 记事本"); //找到记事本窗口的句柄 if (!htext) { cout << "not find text!" << endl; return 0; } HWND hchild = FindWindowEx(htext, NULL, L"Edit", NULL); //找到记事本的编辑区子窗口 if (!hchild) { cout << "not find child!" << endl; return 0; } /*像编辑区发送按键按下的消息,内容分别hello world*/ PostMessage(hchild, WM_KEYDOWN, 0x48, 0); PostMessage(hchild, WM_KEYDOWN, 0x45, 0); PostMessage(hchild, WM_KEYDOWN, 0x4c, 0); PostMessage(hchild, WM_KEYDOWN, 0x4c, 0); PostMessage(hchild, WM_KEYDOWN, 0x4f, 0); PostMessage(hchild, WM_KEYDOWN, VK_SPACE, 0); PostMessage(hchild, WM_KEYDOWN, 0x57, 0); PostMessage(hchild, WM_KEYDOWN, 0x4f, 0); PostMessage(hchild, WM_KEYDOWN, 0x52, 0); PostMessage(hchild, WM_KEYDOWN, 0x4c, 0); PostMessage(hchild, WM_KEYDOWN, 0x44, 0); return 1; }
运行结果如下:
可以看到在记事本中成功输入了hello world,完全由代码生成的。
除了以上利用FindWindowEx()函数查找子窗口外,还可以利用EnumChildWindows()函数来遍历所有窗口,对所有子窗口进行操作。以下是代码:
#include <iostream> #include <string.h> #include <Windows.h> using namespace std; //对枚举的子窗口进行操作 BOOL CALLBACK EnumChildProc(HWND hchild, LPARAM lparam) { wchar_t cls_name[50]; GetClassName(hchild, cls_name, 50); //获取子窗口的类名 wprintf(L"%s", cls_name); //将子窗口的类名打印到屏幕 wchar_t* p = wcsstr(cls_name, (wchar_t*)lparam); //判断查找到的子窗口是否是编辑区窗口 if (p == NULL) { return TRUE; } else { /*像编辑区发送按键按下的消息,内容分别hello world*/ PostMessage(hchild, WM_KEYDOWN, 0x48, 0); PostMessage(hchild, WM_KEYDOWN, 0x45, 0); PostMessage(hchild, WM_KEYDOWN, 0x4c, 0); PostMessage(hchild, WM_KEYDOWN, 0x4c, 0); PostMessage(hchild, WM_KEYDOWN, 0x4f, 0); PostMessage(hchild, WM_KEYDOWN, VK_SPACE, 0); PostMessage(hchild, WM_KEYDOWN, 0x57, 0); PostMessage(hchild, WM_KEYDOWN, 0x4f, 0); PostMessage(hchild, WM_KEYDOWN, 0x52, 0); PostMessage(hchild, WM_KEYDOWN, 0x4c, 0); PostMessage(hchild, WM_KEYDOWN, 0x44, 0); return TRUE; } } int main() { HWND htext = FindWindow(NULL, L"无标题 - 记事本"); //找到记事本窗口的句柄 if (!htext) { cout << "not find text!" << endl; return 0; } wchar_t class_name[] = { L"Edit" }; //设定要编辑区窗口的类名 EnumChildWindows(htext, EnumChildProc, (LPARAM)class_name); //枚举所有子窗口,在EnumChildProc函数中对这些窗口一一操作 return 1; }
以下是运行结果:
可以看到也得到了正确的结果,另外通过命令行发现输出了记事本的编辑区窗口的类名是:Editmsctls_statusbar32。
基于这种方法,可以编写一些软件的注册机。例如一些软件可能需要输入激活码,这时可以写一个注册机,通过穷举输入到窗口中,来暴力破解软件的激活码。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。