原来写的HOOK住QQ取聊天内容,还有简单的回复,测试是OK的。现在直接贴上代码……
#include#include #include #include "QMsgSender.h" #pragma comment(lib,"GDI32.lib") #pragma comment(lib,"SHELL32.lib") #pragma comment(lib,"USER32.lib") #define FILESIZE 1024*1024 #define FILENAME "TEXT_CACHE" #define QQ_STYLE 0x960F0000 #define QQ_EDIT_LEFT 0 #define QQ_EDIT_TOP 0 #define QQ_EDIT_RIGHT 539 // QQ RIGHT #define QQ_EDIT_BOTTOM 518 //QQ BOTTOM struct QQ_Time { char _name[MAX_PATH]; char _date[MAX_PATH]; char _time[MAX_PATH]; }; typedef QQ_Time QTime; #define LOG_NAME "c:\\hookapi.log" //////////定义要跳转函数的函数类型及函数指针 //------------------------inline hook SetForegroundWindow------------------------- BOOL WINAPI MySetForegroundWindow(HWND hWnd); typedef BOOL (WINAPI *PFNSetForegroundWindow)(HWND); //---------------inline hook Shell_NotifyIconW-------------------------- BOOL WINAPI MyShell_NotifyIconW(DWORD dwMessage,PNOTIFYICONDATAW lpdata); typedef BOOL (WINAPI *PFNMyShell_NotifyIconW)(DWORD,PNOTIFYICONDATAW); //------------------------inline hook ShowWindow------------------------- BOOL WINAPI MyShowWindow(HWND hWnd,int nCmdShow); typedef BOOL (WINAPI *PFNShowWindow)(HWND,int); //------------------------inline hook ExtTextOutW--------------------------------- BOOL WINAPI MyExtTextOutW(HDC hdc,int X,int Y,UINT fuOptions,CONST RECT* lprc,LPCWSTR lpString,UINT cbCount,CONST INT* lpDx); typedef BOOL (WINAPI *PFNExtTextOutW)(HDC hdc,int X,int Y,UINT fuOptions,CONST RECT* lprc,LPCWSTR lpString,UINT cbCount,CONST INT* lpDx); ////////申明要用的函数 void Process_Attach(); void Process_Detach(); void AppendText(char *text); void WriteLog(char *fmt,...); void ResetLog(); char* WCharToChar(const wchar_t *wstr); wchar_t* CharToWChar(const char *str); void ParseQQMsgTime(char *_time_,QTime *qTime); HANDLE t001(); HANDLE t002(); HANDLE t003(); HANDLE t004(); HANDLE t005(); HANDLE t006(); HANDLE t007(); HANDLE t008(); HANDLE t009(); static int IndexOf(char *str1,const char *str2) { char tmp[MAX_PATH]; strncpy_s(tmp,MAX_PATH,str1,strlen(str1)); char *pSplit = NULL; char *pNext = NULL; int nCount = 0; pSplit = strtok_s(tmp,str2,&pNext); if(pSplit != NULL) nCount = strlen(pSplit); return nCount; } static int LastIndexOf(char *str1,const char *str2) { char tmp[MAX_PATH]; strncpy_s(tmp,MAX_PATH,str1,strlen(str1)); char *pSplit = NULL; char *pNext = NULL; int nCount = 0; int _length = strlen(str2); pSplit = strtok_s(tmp,str2,&pNext); int pLength = 0; while(pSplit != NULL) { pLength = strlen(pSplit) + _length;//符号的长度 pSplit = strtok_s(NULL,str2,&pNext); if(pSplit != NULL) nCount += pLength; } return nCount - 1; }
// dllmain.cpp : 定义 DLL 应用程序的入口点。 #include "stdafx.h" #include "dllmain.h" char szOldSetForegroundWindow[5] = {0}; char szJmpMySetForegroundWindow[5] = {(char)0xe9}; PFNSetForegroundWindow pSetForegroundWindow = NULL; char szOldShell_NotifyIconW[5] = {0}; char szJmpMyShell_NotifyIconW[5] = {(char)0xE9}; PFNMyShell_NotifyIconW pShell_NotifyIconW = NULL; char szOldShowWindow[5] = {0}; char szJmpMyShowWindow[5] = {(char)0xE9}; PFNShowWindow pShowWindow = NULL; char szOldExtTextOutW[5] = {0}; char szJmpMyExtTextOutW[5] = {(char)0xE9}; PFNExtTextOutW pExtTextOutW= NULL; HWND g_hWnd = NULL;//弹出的窗口句柄 int qq_msg_bottom = 0;//最后一条消息的底部坐标 char qq_last_time[MAX_PATH] = {0};//最后一条消息时间(先时间后内容) BOOL qq_format = FALSE;//是否是QQ聊天内容格式 BOOL g_getText = FALSE;//控制是否取QQ内容 BOOL g_getTextDone = FALSE;//是否取完消息准备放到向量中等待发送 HANDLE hEvent = NULL;//同步ExtTextOutW函数 char appName[MAX_PATH];//加载程序的名字 QQ.exe和TMQQ.exe char tempMsg[QQ_MSG_LENGTH]; CQMsgSender g_msgSender;//消息发送器 #pragma data_seg(".sdata") HANDLE g_hFile = NULL;//共享内存块 #pragma data_seg() #pragma comment(linker,"/SECTION:.sdata,RWS") void Process_Attach() { //ResetLog(); //WriteLog("Process_Attach\r\n"); g_hFile = CreateFileMappingA(INVALID_HANDLE_VALUE,0,PAGE_READWRITE, 0,FILESIZE,FILENAME); //inline hook ExtTextOutW 得到聊天内容,和聊天对象QQ号 DWORD dwJmpAddr = 0; HMODULE hModule = LoadLibrary("Gdi32.Dll"); pExtTextOutW = (PFNExtTextOutW)GetProcAddress(hModule, "ExtTextOutW"); if(pExtTextOutW != NULL) { dwJmpAddr = (DWORD)MyExtTextOutW - (DWORD)pExtTextOutW - 5; memcpy(szJmpMyExtTextOutW + 1, &dwJmpAddr, 4); FreeLibrary(hModule); ReadProcessMemory(INVALID_HANDLE_VALUE, pExtTextOutW, szOldExtTextOutW, 5, NULL);//读出原来的前5个字节 WriteProcessMemory(INVALID_HANDLE_VALUE, pExtTextOutW, szJmpMyExtTextOutW, 5, NULL);//写入我们处理后的5个字节 } //inline hook Shell_NotifyIconW 得到本机QQ信息 /*dwJmpAddr = 0; hModule = LoadLibrary("Shell32.Dll"); pShell_NotifyIconW = (PFNMyShell_NotifyIconW)GetProcAddress(hModule, "Shell_NotifyIconW"); if(pShell_NotifyIconW != NULL) { dwJmpAddr = (DWORD)MyShell_NotifyIconW - (DWORD)pShell_NotifyIconW - 5; memcpy(szJmpMyShell_NotifyIconW + 1, &dwJmpAddr, 4); FreeLibrary(hModule); ReadProcessMemory(INVALID_HANDLE_VALUE, pShell_NotifyIconW, szOldShell_NotifyIconW, 5, NULL);//读出原来的前5个字节 WriteProcessMemory(INVALID_HANDLE_VALUE, pShell_NotifyIconW, szJmpMyShell_NotifyIconW, 5, NULL);//写入我们处理后的5个字节 } //inline hook SetForegroundWindow dwJmpAddr = 0; hModule = LoadLibrary("User32.Dll"); pSetForegroundWindow = (PFNSetForegroundWindow)GetProcAddress(hModule, "SetForegroundWindow"); if(pSetForegroundWindow) { dwJmpAddr = (DWORD)MySetForegroundWindow - (DWORD)pSetForegroundWindow - 5; memcpy(szJmpMySetForegroundWindow + 1, &dwJmpAddr, 4); FreeLibrary(hModule); ReadProcessMemory(INVALID_HANDLE_VALUE, pSetForegroundWindow, szOldSetForegroundWindow, 5, NULL);//读出原来的前5个字节 WriteProcessMemory(INVALID_HANDLE_VALUE, pSetForegroundWindow, szJmpMySetForegroundWindow, 5, NULL);// }*/ //inline hook ShowWindow dwJmpAddr = 0; hModule = LoadLibrary("User32.Dll"); pShowWindow = (PFNShowWindow)GetProcAddress(hModule, "ShowWindow"); if(pShowWindow != NULL) { dwJmpAddr = (DWORD)MyShowWindow - (DWORD)pShowWindow - 5; memcpy(szJmpMyShowWindow + 1, &dwJmpAddr, 4); FreeLibrary(hModule); ReadProcessMemory(INVALID_HANDLE_VALUE, pShowWindow, szOldShowWindow, 5, NULL);//读出原来的前5个字节 WriteProcessMemory(INVALID_HANDLE_VALUE, pShowWindow, szJmpMyShowWindow, 5, NULL);//写入我们处理后的5个字节 } hEvent = CreateEventA(NULL,FALSE,TRUE,NULL); g_msgSender.StartThread(); } void Process_Detach() { //WriteLog("Process_Detach\r\n"); g_msgSender.StopThread(); if(pExtTextOutW != NULL) WriteProcessMemory(INVALID_HANDLE_VALUE, pExtTextOutW, szOldExtTextOutW, 5, NULL); if(pShell_NotifyIconW != NULL) WriteProcessMemory(INVALID_HANDLE_VALUE, pShell_NotifyIconW, szOldShell_NotifyIconW, 5, NULL); if(pShowWindow != NULL) WriteProcessMemory(INVALID_HANDLE_VALUE, pShowWindow, szOldShowWindow, 5, NULL); if(pSetForegroundWindow != NULL) WriteProcessMemory(INVALID_HANDLE_VALUE, pSetForegroundWindow, szOldSetForegroundWindow, 5, NULL); if(hEvent != NULL) CloseHandle(hEvent); if(g_hFile != NULL) { char* ptr = (char*) MapViewOfFile(g_hFile,FILE_MAP_ALL_ACCESS,0,0,FILESIZE); memset(ptr,0,FILESIZE); CloseHandle(g_hFile); } } BOOL APIENTRY DllMain(HMODULE hModule,DWORD ul_reason_for_call,LPVOID lpReserved) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: GetModuleFileName(NULL,appName,sizeof(appName)); if(strstr(appName,"QQ.exe") != NULL || strstr(appName,"TM.exe") != NULL)//是QQ或者TM Process_Attach(); break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: if(strstr(appName,"QQ.exe") != NULL || strstr(appName,"TM.exe") != NULL)//是QQ或者TM Process_Detach(); break; } return TRUE; } BOOL WINAPI MySetForegroundWindow(HWND hWnd) { char szClassName[MAX_PATH]={0}; GetClassName(hWnd,szClassName,MAX_PATH); if(_stricmp(szClassName,"TXGuiFoundation")==0) { long lstyle = GetWindowLong(hWnd,GWL_STYLE); if(lstyle == QQ_STYLE) { char szTitle[MAX_PATH]={0}; GetWindowText(hWnd,szTitle,MAX_PATH); } } WriteProcessMemory(INVALID_HANDLE_VALUE, pSetForegroundWindow, szOldSetForegroundWindow, 5, NULL); BOOL bRet = SetForegroundWindow(hWnd); WriteProcessMemory(INVALID_HANDLE_VALUE, pSetForegroundWindow, szJmpMySetForegroundWindow, 5, NULL); return bRet; } BOOL WINAPI MyShell_NotifyIconW(DWORD dwMessage,PNOTIFYICONDATAW lpdata) { if(g_hWnd != lpdata->hWnd && wcslen(lpdata->szTip) > 10) { char *szTip = WCharToChar(lpdata->szTip); WriteLog(szTip); WriteLog("\r\n"); g_hWnd = lpdata->hWnd; delete[] szTip; } WriteProcessMemory(INVALID_HANDLE_VALUE, pShell_NotifyIconW, szOldShell_NotifyIconW, 5, NULL); BOOL bRet = Shell_NotifyIconW(dwMessage,lpdata); WriteProcessMemory(INVALID_HANDLE_VALUE, pShell_NotifyIconW, szJmpMyShell_NotifyIconW, 5, NULL); return bRet; } BOOL WINAPI MyShowWindow(HWND hWnd,int nCmdShow) { //为了,如果有多个QQ聊天窗口同时弹出,就慢慢的显示,这样QQ聊天对象和QQ号不会混淆 //判断是否是QQ聊天窗口 char szClassName[MAX_PATH]={0}; GetClassName(hWnd,szClassName,MAX_PATH); if(_stricmp(szClassName,"TXGuiFoundation")==0) { long lstyle = GetWindowLong(hWnd,GWL_STYLE); if(lstyle == QQ_STYLE) { //弹出来的是QQ聊天窗口 cmd:9显示 0是关闭 SW_RESTORE=9 if(nCmdShow == SW_RESTORE) { g_getText = TRUE; g_hWnd = hWnd; } else { g_getText = FALSE; g_hWnd = NULL; } } } WriteProcessMemory(INVALID_HANDLE_VALUE, pShowWindow, szOldShowWindow, 5, NULL); BOOL bRet = ShowWindow(hWnd,nCmdShow); WriteProcessMemory(INVALID_HANDLE_VALUE, pShowWindow, szJmpMyShowWindow, 5, NULL); return bRet; } BOOL WINAPI MyExtTextOutW(HDC hdc,int X,int Y,UINT fuOptions,CONST RECT* lprc,LPCWSTR lpString,UINT cbCount,CONST INT* lpDx) { WaitForSingleObject(hEvent,INFINITE); /*if(cbCount > 0 && lprc != NULL) { char *pstr = new char[cbCount*2+1];//unicode字符2个char(字节)加上一个结束符\0 int len = WideCharToMultiByte(CP_ACP, 0, lpString, cbCount, pstr, cbCount*2, NULL, NULL); pstr[len] = 0;//最后一个\0结束符 WriteLog("0.%s [%d,%d,%d,%d]\r\n",pstr,lprc->left,lprc->top,lprc->right,lprc->bottom); delete[] pstr; }*/ BOOL bRet = FALSE; //取QQ聊天消息内容 if(cbCount>0 && g_getText && lprc != NULL && lprc->left>=QQ_EDIT_LEFT&&lprc->right<=QQ_EDIT_RIGHT &&lprc->top>=QQ_EDIT_TOP&&lprc->bottom<=QQ_EDIT_BOTTOM) { int _length = cbCount<<1; char *pstr = new char[_length+1];//unicode字符2个char(字节)加上一个结束符\0 int len = WideCharToMultiByte(CP_ACP, 0, lpString, cbCount, pstr, _length, NULL, NULL); pstr[len] = 0;//最后一个\0结束符 //////////用坐标的问题///////// /*当其它坐标也符合QQ窗口坐标的时候,也会绘制进来 所以导致有乱码或者其它界面的内容也被抓进来。只能根据 内容里面的昵称和时间的格式确定内容是QQ聊天内容而不是其它窗口的内容*/ int firstIndex = IndexOf(pstr,":"); int lastIndex = LastIndexOf(pstr,":"); int offset = lastIndex-firstIndex; //检测聊天内容是不是时间 如 //昵称 22:40:33 //昵称 2013/12/5 22:34:37 //根据聊天时间格式来确定是聊天内容 if((firstIndex != -1)&&(lastIndex != -1)&&(offset == 3)) { if(strlen(qq_last_time) == 0) { //复制第一条聊天纪录 strcpy_s(qq_last_time,MAX_PATH,pstr); qq_format = TRUE; g_getTextDone = FALSE; qq_msg_bottom = lprc->bottom; } else if(strcmp(qq_last_time,pstr) == 0) { //检测到重复的时间文字证明内容结束 memset(qq_last_time,0,sizeof(char)*MAX_PATH); qq_format = FALSE; g_getText = FALSE; g_getTextDone = TRUE; } //写入聊天内容的时间 if (g_getText) { //昵称和时间 //AppendText(pstr); //AppendText("-"); } } else if(qq_format && g_getText) { if (qq_msg_bottom < lprc->bottom) { qq_msg_bottom = lprc->bottom; //QQ聊天纪录 //AppendText(pstr); //AppendText("|"); strcat_s(tempMsg,QQ_MSG_LENGTH,pstr); } } delete[] pstr; } WriteProcessMemory(INVALID_HANDLE_VALUE, pExtTextOutW, szOldExtTextOutW, 5, NULL); bRet = ExtTextOutW(hdc,X,Y,fuOptions,lprc,lpString,cbCount,lpDx); WriteProcessMemory(INVALID_HANDLE_VALUE, pExtTextOutW, szJmpMyExtTextOutW, 5, NULL); SetEvent(hEvent);//要放在上面,不然无响应,下面的SEND没有完成 if(g_getTextDone) { g_getTextDone = FALSE; QMsg msg; msg.Init(g_hWnd,tempMsg); memset(tempMsg,0,QQ_MSG_LENGTH); g_msgSender.AddMsg(msg); g_msgSender.NotifyThread();//唤醒线程工作 } return bRet; } char* WCharToChar(const wchar_t *wstr) { //第四个参数-1表示求长度 int _length = WideCharToMultiByte(CP_OEMCP, 0, wstr, -1, NULL, 0, NULL, FALSE); char *pstr = new char[_length+1]; _length = WideCharToMultiByte(CP_OEMCP, 0, wstr, -1, pstr, _length, NULL, FALSE); pstr[_length] = 0; return pstr; } wchar_t* CharToWChar(const char *str) { //第四个参数-1表示求长度 int _length = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0); wchar_t *pwText = new wchar_t[_length+1]; _length = MultiByteToWideChar(CP_ACP,0,str,-1,pwText,_length); pwText[_length] = 0; return pwText; } void ResetLog() { DeleteFileA(LOG_NAME); } void AppendText(char *text) { char* ptr = (char*) MapViewOfFile(g_hFile,FILE_MAP_ALL_ACCESS,0,0,FILESIZE); strcat_s(ptr,FILESIZE,text); UnmapViewOfFile(ptr); } void WriteLog(char *fmt,...) { char temp[1024]; HANDLE hFile = CreateFileA(LOG_NAME, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if(hFile == NULL) return; //设置文件中进行读写的当前位置 _llseek((HFILE)hFile,0, SEEK_END); DWORD dw; va_list args; va_start(args,fmt); vsprintf_s(temp,fmt,args); va_end(args); WriteFile(hFile, temp, strlen(temp), &dw, NULL); //将一系列的字符和数值输入到缓冲区 /*wsprintfA(temp, "\n"); WriteFile(hFile, temp, strlen(temp), &dw, NULL);*/ _lclose((HFILE)hFile); } void ParseQQMsgTime(char *_time_,QTime *qTime) { //copy会覆盖原来内存,不用使用memset char tmp[MAX_PATH]; strncpy_s(tmp,MAX_PATH,_time_,strlen(_time_)); char *pSplit = NULL; char *pNext = NULL; int nCount = 0; const char *delim = " "; pSplit = strtok_s(tmp,delim,&pNext); while(pSplit != NULL) { nCount++; if(nCount == 1) { strncpy_s(qTime->_name,MAX_PATH,pSplit,strlen(pSplit)); } else if(nCount == 2) { if(strlen(pNext) == 0) strncpy_s(qTime->_time,MAX_PATH,pSplit,strlen(pSplit)); else strncpy_s(qTime->_date,MAX_PATH,pSplit,strlen(pSplit)); } else if(nCount == 3) { strncpy_s(qTime->_time,MAX_PATH,pSplit,strlen(pSplit)); } pSplit = strtok_s(NULL,delim,&pNext); } } HANDLE t001(){ExtTextOutA(NULL,0,0,0,NULL,NULL,0,NULL); return (HANDLE)0x12345678;} HANDLE t002(){TextOutA(NULL,0,0,0,NULL); return (HANDLE)0x23456781;} HANDLE t003(){TextOutW(NULL,0,0,0,NULL); return (HANDLE)0x34567812;} HANDLE t004(){SendMessageA(NULL,NULL,NULL,NULL); return (HANDLE)0x45678123;} HANDLE t005(){SendMessageW(NULL,NULL,NULL,NULL); return (HANDLE)0x56781234;} HANDLE t006(){::AdjustWindowRect(NULL,0,FALSE); return (HANDLE)0x67812345;} HANDLE t007(){g_getText = TRUE; return (HANDLE)0x00321263;} HANDLE t008(){BeginPaint(NULL,NULL); return (HANDLE)0x78123456;} HANDLE t009(){EndPaint(NULL,NULL); return (HANDLE)0x81234567;}结构体
#pragma once #include#define QQ_BTN_SEND_X 333 #define QQ_BTN_SEND_Y 500 #define QQ_MSG_LENGTH 10240 struct QQ_Msg { char _recvMsg[QQ_MSG_LENGTH];//接收的信息用于查询最佳回复内容用 char _sendMsg[QQ_MSG_LENGTH];//用于发送给别人 HWND _hWnd; QQ_Msg() { _hWnd = NULL; } void Init(HWND hWnd,char *msg) { this->_hWnd = hWnd; SetMsg(msg); } void SetMsg(char *msg) { strcpy_s(_recvMsg,QQ_MSG_LENGTH,msg); } }; typedef QQ_Msg QMsg; class CQMsgSender { public: CQMsgSender(void); virtual ~CQMsgSender(void); static UINT SendMsgThread(LPVOID pVoid);//线程要静态访问权限才行 void SendMouse(HWND hWnd,WPARAM wParam,LPARAM lParam); void SendMsg(HWND hWnd,CHAR *msg); private: bool mRun; std::vector g_vmsg; HANDLE hSendEvent; public: void StartThread(void); void StopThread(void); void AddMsg(QMsg _msg); void NotifyThread(void); LPARAM lParam; };
#include "StdAfx.h" #include "QMsgSender.h" CQMsgSender::CQMsgSender(void) : mRun(false) { g_vmsg.reserve(1000); lParam = MAKELONG(QQ_BTN_SEND_X,QQ_BTN_SEND_Y); } CQMsgSender::~CQMsgSender(void) { } void CQMsgSender::SendMsg(HWND hWnd,CHAR *msg) { int _length = strlen(msg); for(int i=0;i<_length;i++) { WPARAM cChar = (BYTE)msg[i]; if(cChar > 122)//是占2字节 cChar = (cChar<<8) | (BYTE)msg[++i]; SendMessageA(hWnd,WM_IME_CHAR,cChar,NULL); } } void CQMsgSender::SendMouse(HWND hWnd,WPARAM wParam,LPARAM lParam) { SendMessageA(hWnd,WM_MOUSEMOVE,wParam,lParam); SendMessageA(hWnd,WM_LBUTTONDOWN,wParam,lParam); SendMessageA(hWnd,WM_LBUTTONUP,wParam,lParam); SendMessageA(hWnd,WM_MOUSEMOVE,NULL,MAKELONG(0,0)); } UINT CQMsgSender::SendMsgThread(LPVOID pVoid) { CQMsgSender *thiz = (CQMsgSender*)pVoid; while(thiz->mRun) { WaitForSingleObject(thiz->hSendEvent,INFINITE); if(!thiz->mRun) break;//退出线程 //接收完毕通知关闭窗口 int _size = thiz->g_vmsg.size(); for (int i=_size-1;i>=0;i--) { QMsg msg = thiz->g_vmsg.at(i); thiz->g_vmsg.pop_back(); if(strstr(msg._recvMsg,"你好") != NULL) { //查找到了回复内容 strcpy_s(msg._sendMsg,QQ_MSG_LENGTH,"你好,请问有什么可以帮到你的吗?"); } else if(strstr(msg._recvMsg,"在吗") != NULL) { //查找到了回复内容 strcpy_s(msg._sendMsg,QQ_MSG_LENGTH,"亲,在的!"); } else { //查找不到回复内容 strcpy_s(msg._sendMsg,QQ_MSG_LENGTH,"555,我还不能理解你的意思!"); } thiz->SendMsg(msg._hWnd,msg._sendMsg); thiz->SendMouse(msg._hWnd,NULL,thiz->lParam);//发送 PostMessageA(msg._hWnd,WM_CLOSE,NULL,NULL); } } CloseHandle(thiz->hSendEvent); return 0; } void CQMsgSender::StartThread(void) { mRun = true; hSendEvent = CreateEventA(NULL,FALSE,FALSE,NULL); HANDLE threadHandle = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)SendMsgThread,this,0,NULL); if(threadHandle != NULL) CloseHandle(threadHandle); } void CQMsgSender::StopThread(void) { mRun = false; SetEvent(hSendEvent); } void CQMsgSender::AddMsg(QMsg _msg) { this->g_vmsg.push_back(_msg); } void CQMsgSender::NotifyThread(void) { SetEvent(hSendEvent); }
收藏的用户(0) X
正在加载信息~
推荐阅读
最新回复 (5)
- QQ2D5327839B47104E75038300E1D73A 2016-7-16引用 2楼能不能给一个调用的方法,不知该如何调用咱们这个库程序qq1325670735
-
-
- DennyLeija 2016-8-3引用 5楼源码找不到了。这里已经有核心部分不。可以写出来了。
-
站点信息
- 文章2305
- 用户1336
- 访客11455187
每日一句
Talent without working hard is nothing.
没有努力,天份不代表什么。
没有努力,天份不代表什么。
MySQL 数据库优化
This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its de
免ROOT实现模拟点击任意位置
Mobaxterm终端神器
CreateProcessW要注意的细节问题
Autonomous NAT Traversal
【教程】win10 彻底卸载edge浏览器
eclipse工程基于Xposed的一个简单Hook
排名前5的开源在线机器学习
Mac OS最简单及(Karabiner)快捷键设置
发一款C++编写的麻将
VMware NAT端口映射外网访问虚拟机linux
独家发布最新可用My-AutoPost——wordpress 采集器
新会员