原来写的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楼源码找不到了。这里已经有核心部分不。可以写出来了。
-
站点信息
- 文章2300
- 用户1336
- 访客10859735
每日一句
True success inspires others to act.
真正的成功是激励他人行动。
真正的成功是激励他人行动。
语法错误: 意外的令牌“标识符”
全面理解Gradle - 定义Task
Motrix全能下载工具 (支持 BT / 磁力链 / 百度网盘)
谷歌Pixel正在开始起飞?
获取ElementUI Table排序后的数据
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is
亲测!虚拟机VirtualBox安装MAC OS 10.12图文教程
华为手机app闪退重启界面清空log日志问题
android ndk开发之asm/page.h: not found
手机屏幕碎了怎么备份操作?
免ROOT实现模拟点击任意位置
新手必看修改DSDT教程
thinkpad t470p装黑苹果系统10.13.2
新会员