#include "stdafx.h" #include "WxMgr.h" #include "Global.h" #include "resource.h" HBITMAP LoadImgFromFile(LPCTSTR lpPath) { if (!PathFileExists(lpPath)) return NULL; Bitmap *pBitmap = NULL; #ifdef UNICODE *pBitmap = Bitmap::FromFile(lpPath); #else BSTR strtmp = _bstr_t(lpPath); pBitmap = Bitmap::FromFile(strtmp, TRUE); SysFreeString(strtmp); #endif HBITMAP hBitmap = NULL; Status status = pBitmap->GetLastStatus(); if (Ok == status) { status = pBitmap->GetHBITMAP(Color(0, 0, 0), &hBitmap); if (Ok == status) { // enjoy of bitmap; } } if (pBitmap) delete pBitmap; return hBitmap; } TCHAR CWxMgr::m_szWeChatPath[MAX_PATH] = { 0 }; CWxMgr::CWxMgr(CWnd *pMainWnd) :m_pMainWnd(pMainWnd) { InitButtonIds(); GetWeChatPath(); } CWxMgr::~CWxMgr() { } CRect CWxMgr::CalcRect() { CRect rc; int nCount = m_mapWx.size(); // 高固定大小; rc.left = m_rcWxList.left + 2; rc.top = 100 * nCount + m_rcWxList.top + 20; rc.right = m_rcWxList.right - 2; rc.bottom = rc.top + 100; return rc; } // 获取空闲的id; DWORD CWxMgr::GetFreeButtonId(DWORD dwProcId) { for (pair ids : m_mapIds) { // 判断进程id是否为0; if ( ids.second == 0 ) { //ids.second = dwProcId;// 赋值无效; m_mapIds[ids.first] = dwProcId; return ids.first; } } return -1; } VOID CWxMgr::ReSetButtonKey(DWORD dwProcId) { for (pair ids : m_mapIds) { if (ids.second == dwProcId) { ids.second = 0; break; } } } void CWxMgr::InitButtonIds() { DWORD dwStartId = 10000; for ( int i = 0; i < 10; i++) { m_mapIds.insert(pair(dwStartId + i, 0)); } } CButtonST * CWxMgr::GetButton(DWORD dwProcId) { CButtonST *pButton = NULL; for (pair wxinfo : m_mapWx) { if (wxinfo.first == dwProcId) { pButton = wxinfo.second.pWxButton; break; } } return pButton; } CStatic * CWxMgr::GetWxChatWnd(DWORD dwProcId) { CStatic *pWxChatWnd = NULL; for (pair wxinfo : m_mapWx) { if (wxinfo.first == dwProcId) { pWxChatWnd = wxinfo.second.pWxChatWnd; break; } } return pWxChatWnd; } CWxObject * CWxMgr::GetWxObject(DWORD dwProcId) { CWxObject *pWxObject = NULL; for (pair wxinfo : m_mapWx) { if (wxinfo.first == dwProcId) { pWxObject = wxinfo.second.pWxObject; break; } } return pWxObject; } BOOL CWxMgr::AttachUnMgrWxProc(CWnd *pWnd) { vector vtWxProcId = FindAllProcess(WECHAT); for (DWORD pid : vtWxProcId) { if (m_mapWx.count(pid) == 0) { AddMapItem(pid, NULL); } } return TRUE; } BOOL CWxMgr::AttachWx() { return 0; } VOID CWxMgr::AddMapItem(DWORD dwProcId, LPCTSTR lpItemName) { WXOBJINFO wxObjInfo; // 创建微信对象; wxObjInfo.pWxObject = new CWxObject(dwProcId, g_szDynamicLibraryPath); // 创建按钮;//id使用自建的; wxObjInfo.pWxButton = new CButtonST(); wxObjInfo.pWxButton->Create(lpItemName, WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX, CalcRect(), m_pMainWnd, GetFreeButtonId(dwProcId)); wxObjInfo.pWxButton->OffsetColor(CButtonST::BTNST_COLOR_BK_IN, 60); //wxObjInfo.pWxButton->DrawTransparent(); //wxObjInfo.pWxButton->SetIcon(ICON_CHECK); #ifdef DEBUG //HBITMAP hBitmapIn = (HBITMAP)::LoadImage(NULL, _T("E:\\bin\\WeChats2017\\image\\132.jpg"), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); HBITMAP hBitmapIn = LoadImgFromFile(_T("E:\\bin\\WeChats2017\\image\\132.jpg")); if (hBitmapIn) wxObjInfo.pWxButton->SetBitmaps(hBitmapIn, COLORREF(0)); #endif // DEBUG wxObjInfo.pWxButton->ShowWindow(SW_SHOW); wxObjInfo.pWxButton->SetCheck(FALSE); // 创建聊天窗口;//Id使用进程id; wxObjInfo.pWxChatWnd = new CStatic(); wxObjInfo.pWxChatWnd->Create(lpItemName, WS_CHILD | WS_VISIBLE | WS_TABSTOP | SS_GRAYRECT, m_rcWxShow, m_pMainWnd, dwProcId); wxObjInfo.pWxChatWnd->ShowWindow(SW_HIDE); // 附加到窗口; wxObjInfo.pWxObject->InjectDynamicLibrary(); if (wxObjInfo.pWxObject->FindWxMainWnd()) { wxObjInfo.pWxObject->Attach2MainWnd(wxObjInfo.pWxChatWnd, FALSE); } else if (wxObjInfo.pWxObject->FindWxLoginWnd()) { wxObjInfo.pWxObject->Attach2MainWnd(wxObjInfo.pWxChatWnd, TRUE); } m_mapWx.insert(pair(dwProcId, wxObjInfo)); } VOID CWxMgr::RemoveMapItem(DWORD dwProcId) { for (pair wxinfo : m_mapWx) { if (wxinfo.first == dwProcId) { wxinfo.second.pWxObject->DetachWxWnd(); delete wxinfo.second.pWxObject; delete wxinfo.second.pWxButton; delete wxinfo.second.pWxChatWnd; // 重转按钮关联的进程id; ReSetButtonKey(dwProcId); // 下方的WxButton向上移动; // ... break; } } // 移除key; m_mapWx.erase(dwProcId); } VOID CWxMgr::DetachAllWxProc() { for (pair wxinfo : m_mapWx) { wxinfo.second.pWxObject->DetachWxWnd(); delete wxinfo.second.pWxObject; delete wxinfo.second.pWxButton; delete wxinfo.second.pWxChatWnd; // 重转按钮关联的进程id; ReSetButtonKey(wxinfo.first); // 下方的WxButton向上移动; // ... } m_mapWx.clear(); } BOOL CWxMgr::OpenWeChat() { // 关闭互斥句柄; PatchWeChat(); STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); ZeroMemory(&pi, sizeof(pi)); si.dwFlags = STARTF_USESHOWWINDOW; // 指定wShowWindow成员有效 si.wShowWindow = SW_HIDE; // 设置创建进程时,窗口不显示, // 为FALSE的话则不显示 BOOL bRet = ::CreateProcess( m_szWeChatPath, // 不在此指定可执行文件的文件名 NULL, // 命令行参数 NULL, // 默认进程安全性 NULL, // 默认线程安全性 FALSE, // 指定当前进程内的句柄不可以被子进程继承 NULL, NULL, // 使用本进程的环境变量 NULL, // 使用本进程的驱动器和目录 &si, &pi); if (bRet) { //WaitForSingleObject(pi.hProcess, INFINITE); //WaitForInputIdle(pi.hProcess, INFINITE); //Sleep(1500); // 启动微信需要1秒左右; // 既然我们不使用两个句柄,最好是立刻将它们关闭 ::CloseHandle(pi.hThread); ::CloseHandle(pi.hProcess); // 当进程挂起时,是无法修改关闭微信句柄; AddMapItem(pi.dwProcessId, NULL); } return 0; } BOOL CWxMgr::GetWeChatPath() { static BOOL bGotPath = FALSE; if (!bGotPath) { // 通过注册表获取微信安装目录; HKEY hKey = NULL; if (ERROR_SUCCESS != RegOpenKey(HKEY_CURRENT_USER, _T("Software\\Tencent\\WeChat"), &hKey)) { return FALSE; } DWORD Type = REG_SZ; DWORD cbData = MAX_PATH * sizeof(WCHAR); if (ERROR_SUCCESS != RegQueryValueEx(hKey, _T("InstallPath"), 0, &Type, (LPBYTE)m_szWeChatPath, &cbData)) { RegCloseKey(hKey); return FALSE; } PathAppend(m_szWeChatPath, _T("WeChat.exe")); bGotPath = TRUE; } return bGotPath; }