最近看到个很智能的聊天机器人,于是我也想着自己是不是也可以做一个
于是经过一番查询,我发现方法有很多(识图,买机器人服务之类的),比较麻烦。
然后这时候我蹦出了一个清奇的想法…
我可不可以直接右键聊天内容,复制到剪贴板,然后再对内容进行操作之后塞入剪贴板,再给贴回去从而达到目的呢?
经过一番操作后,发现可以!(我知道这个方法很取巧,是我太菜了23333)
然后写了写…
代码如下:
#include
#include
#include
#include
#include
#include
using namespace std;
bool live = true;
bool getn = false;
wifstream fp;//文件引导
void run() {
GetAsyncKeyState(VK_UP);
GetAsyncKeyState(VK_DOWN);
while (live) {
if (GetAsyncKeyState(VK_UP) & 1) {
getn = !getn;
wcout << (getn ?TEXT("开启\n") :TEXT("关闭\n"));
}
else if (GetAsyncKeyState(VK_DOWN) & 1)
live = false;
Sleep(30);
}
}
void gress() {
wstring str;
TCHAR str_get[600]{ 0 };
OpenClipboard(NULL);//打开剪贴板,成功了返回true
if (IsClipboardFormatAvailable(CF_UNICODETEXT)) {
str.insert(0, (TCHAR*)GetClipboardData(CF_UNICODETEXT));
wcout <<TEXT("发现句子:") << str << endl;
wcout <<TEXT("正在比对字符串...") << endl;
fp.seekg(0, ios::beg);//移到开头
fp.clear();
while (fp.good()) {
fp.getline(str_get, 600, TEXT('\n'));
if ((-1 != str.find(str_get)) && (lstrlen(str_get) > 0)) {//如果有
wcout <<TEXT("抓取的关键词是:") << str_get << endl;
fp.getline(str_get, 600, '\n');
wcout <<TEXT("反馈句子是:") << str_get << endl;
EmptyClipboard();//清空剪贴板
HGLOBAL h = GlobalAlloc(GMEM_DDESHARE, (lstrlen(str_get) + 1)*sizeof(TCHAR));//分配内存
if (!h) {//如果获取内存失败
CloseClipboard();//关闭剪贴板
return;
}
memcpy(GlobalLock(h), str_get, (lstrlen(str_get) + 1) * sizeof(TCHAR));
GlobalUnlock(h);
SetClipboardData(CF_UNICODETEXT, h);
break;
}
else {//如果没有
fp.getline(str_get, 600, TEXT('\n'));
fp.getline(str_get, 600, TEXT('\n'));
}
}
wcout <<TEXT("比对完成!") << endl;
}
CloseClipboard();//关闭剪贴板,成功了返回非0,否则返回0
}
int main() {
wcout.imbue(locale("chs"));
wcin.imbue(locale("chs"));
fp.imbue(locale("zh_CN.UTF-8"));
wcout << TEXT("使用提示:启动程序后请不要移动指定的QQ窗口\n方向键up启动/暂停,方向键down关闭程序\n");
wstring str;
COLORREF begin[2000], end[2000];
const int WX = 100;
const int WY = 100;
const int line = 543;
const int we = 74;
IMAGE img{ 100,20 };
int i, j;
HWND hwnd;
fp.open(TEXT("data.data"), ios::in);
if (!fp.is_open()) {
MessageBox(NULL,TEXT("必需文件不存在!"),TEXT("tip"), 0);
return 0;
}
do {
wcout <<TEXT("请输入已经打开了的QQ窗口的标题名:");
wcin >> str;
hwnd = FindWindow(NULL, str.c_str());//warma沃玛粉丝流浪窝
if (hwnd == NULL)
wcout <<endl<<TEXT("没找到!") << endl;
} while (hwnd == NULL);
wcout << TEXT("准备完毕!\n");
HDC srcDC = GetDC(NULL); // 获取桌面 DC
HDC dstDC = GetImageHDC(&img); // 获取 IMAGE 对象的 DC
BitBlt(dstDC, 0, 0, 100, 20, srcDC, WX + we, WY + line, SRCCOPY);
DWORD *p = GetImageBuffer(&img);
SetWindowPos(hwnd, NULL, WX, WY, 888, 758, SWP_NOSIZE);
for (i = 0; i < 20; ++i) {
for (j = 0; j < 100; ++j)
begin[i + j * 20] = end[i + j * 20] = p[i + j * 20];
}
thread var(run);
while (live)
{
if (getn) {
BitBlt(dstDC, 0, 0, 100, 20, srcDC, WX + we, WY + line, SRCCOPY);
for (i = 0; i < 20; ++i) {
for (j = 0; j < 100; ++j)
end[i + j * 20] = p[i + j * 20];
}
for (i = 0; i < 1000; ++i) {
if (begin[i] != end[i]) {
SetCursorPos(WX + we, WY + line); Sleep(2);
mouse_event(MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0); Sleep(2);
mouse_event(MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0); Sleep(300);
keybd_event('C', 0, 0, 0); Sleep(3);
keybd_event('C', 0, KEYEVENTF_KEYUP, 0); Sleep(300);
gress();
SetCursorPos(WX + we, WY + line + 120); Sleep(2);
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0); Sleep(2);
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0); Sleep(2);
PostMessage(hwnd, WM_PASTE, 0, 0); Sleep(200);
SendMessage(hwnd, WM_KEYDOWN, VK_RETURN, 0); Sleep(300);
BitBlt(dstDC, 0, 0, 100, 20, srcDC, WX + we, WY + line, SRCCOPY);
for (i = 0; i < 20; ++i) {
for (j = 0; j < 100; ++j)
begin[i + j * 20] = end[i + j * 20] = p[i + j * 20];
}
break;
}
}
}
else {
BitBlt(dstDC, 0, 0, 100, 20, srcDC, WX + we, WY + line, SRCCOPY);
for (i = 0; i < 20; ++i) {
for (j = 0; j < 100; ++j)
begin[i + j * 20] = p[i + j * 20];
}
}
Sleep(30);
}
fp.close();
var.join();
return 0;
}
之后只需要在程序旁边建立一个名为data.data的文件,并在里面按照如下格式写预设的对答就好了:
关键词1
关键词1的回复
空行
关键词2
关键词2的回复
空行
关键词3
关键词3的回复
空行
...
以下给出一个文档例子:
唱歌
我会唱好多歌?想听吗?
算了
那该怎么办?
有啊
真的有吗?
什么
不知道
猫
说喵星人干什么?
布吉岛
神马岛?
笨蛋
我是很笨哦,聪明的话就不跟你聊天了.
就是
我也说不清楚啊!
我的
没关系~我有着宽广的胸怀.
方式
什么方式?你喜欢什么方式
实际使用效果图(用的不是上面那个例子的data.data):
目前缺陷:
1.只能回答单个关键词的单个回答,暂时不能在同一个关键词的情况下,实现回答随机,或根据关键词出现次数出现特定回答的能力
2.在没有找到关键词的情况只会复读。
3.当对方发出的是语音消息是,会无法处理或错误处理。
其中,第一跟第二点都是通过更新代码实现相应逻辑来解决,第三点的话目前我还没想到什么法子解决_(:з」∠)_
注意事项:
只能获取独立出去了的QQ窗口的句柄,当QQ窗口时多窗口合并的时候,会无法获取窗口句柄
最后:
本文就介绍到这里了,原创的想法,原创的代码逻辑,供各位参考,也希望大佬多多包涵。