哈罗大家好,我是你们最喜欢的蒟蒻君~
从今天开始,蒟蒻君要和大家一起学习C++黑客啦!!
注:代码在DEV-C++这些针对算法编程的编译器上是编译不了的,需要用vscode或者vc才行。
Windows中应用是基于消息机制哒~ 消息,就是系统生成的一个32位(相当于int类型)的值,这个值就想系统说明了一个事件 (不会重复)。比如用户点了一下鼠标,敲了一下键盘,或者拖动了一下窗口,这些都会报告给Windows。
了解完什么是Windows的消息机制,大家可能会想:Windows是怎么生成这样的一个数呢?一个操作有那么多属性,又怎么能保证任意两个消息均不相同呢?
相信句柄(HWND)大家都吉岛,布吉岛的小伙伴可以看这篇文章。
先看看消息在windows中的定义叭(消息就是MSG哦)~
struct tagMsg {
HWND hwnd; // 窗口句柄
UINT message; // 消息的值
WPARAM wParam; // 用于保证消息各不相同的东东
LPARAM lParam; // 同上一个
DWORD time; // 这个消息是什么时候创建的
POINT pt; // 创建消息的时候光标在哪里(坐标)
} MSG;
小伙伴们懂了叭~
一个小小的消息也是包含了很多属性,所以不可能有两个消息相同啦~~
真正有用的消息值在0x0000在0x03ff之间(0x就是用16进制表示)。而且,程序不能用这些消息指值给自己的消息(这些都是系统要用的)。
应用程序用的消息是从0x0400到0x7fff,或者从0xc000到0xffff的(电脑不一样这个就不一样)。
下一步,我们要认识一些消息类型(看不懂可以忽略)。
消息类型 | 值的范围 |
---|---|
空哒 | WM_NULL到0x0000 |
关于 | 0x0001至0x0087 |
系统 | 0x00A0至0x00A9 |
键盘 | 0x0100至0x0108 |
菜单 | 0x0111至0x0126 |
颜色控制 | 0x0132至0x0138 |
鼠标 | 0x0200至0x020A |
菜单循环 | 0x0211至0x0213 |
多文档 | 0x0220至0x0230 |
决策系统 | 0x0400 |
客户端 | 0x8000 |
应用自定义 | 0x0400至0x7FFF |
好啦~大功告成!作为一个小白白 (大佬忽略),我们就先认识这些关于消息的东东叭,剩下的以后就会学到。
API函数就是接口函数,为了方便我们编写接口公开的。
那么我们的第一个黑客程序需要用到什么函数呢?
Let’s go~~
作用:
通过窗口名找到窗口句柄。
定义:
LPCSTR = const TCHAR*
HWND FindWindow(
LPCTSTR lpClassName, // 窗口类的名称
LPCTSTR lpWindowsName // 窗口的名称(窗口标题)
);
程序中的运用:
在代码里面,因为窗口的名称会改变(这里我们写了一个编辑窗口标题的函数edit),所以只能用窗口类名来找句柄啦~
作用:
通过句柄确定窗口,然后将消息发过去。
定义:
UINT = unsigned int
WPARAM = UINT
LPARAM = LONG
LRESULT SendMessage(
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam
};
补充:几个消息的具体含义
WM_CLOSE:拿到这个消息的窗口必须关闭(最后两个参数莫有用处,为NULL)
WM_SETTEXT:拿到这个消息的窗口必须设置下里面的文字(不用用wParam,lParam指向结尾为NULL的文本)
WM_GETTEXT:拿到这个消息的窗口里面的文本会被copy下来(wParam是要复制前多少个字符,lParam是复制到哪里)
#include
// 获取记事本标题
void get_name() {
HWND h = ::FindWindow(L"Notepad", NULL);
if (h == NULL) {
MessageBox(NULL, L"莫有记事本哦~", L"蒟蒻君提示", MB_OK);
return;
}
char s[MAXBYTE] = {
0};
::SendMessage(h, WM_SETTEXT, (WPARAM)0, (LPARAM)s);
MessageBox(NULL, (LPCWSTR)s, L"蒟蒻君提示", MB_OK);
}
// 编辑记事本标题
void edit() {
HWND h = ::FindWindow(NULL, L"无标题 - 记事本");
if (h == NULL) {
MessageBox(NULL, L"莫有记事本哦~", L"蒟蒻君提示", MB_OK);
return;
}
::SendMessage(h, WM_SETTEXT, (WPARAM)0, (LPARAM)"调试");
}
// 运行记事本
void run() {
WinExec("notepad.exe", SW_SHOW);
}
// 关闭记事本
void close() {
HWND h = ::FindWindow(L"Notepad", NULL);
if (h == NULL) {
MessageBox(NULL, L"莫有记事本哦~", L"蒟蒻君提示", MB_OK);
return;
}
::SendMessage(h, WM_CLOSE, NULL, NULL);
}