ReKeyDlg.cpp
上传用户:jinbin898
上传日期:2022-06-24
资源大小:89k
文件大小:18k
源码类别:

外挂编程

开发平台:

Visual C++

  1. // ReKeyDlg.cpp : 实现文件
  2. //
  3. #include "stdafx.h"
  4. #include "ReKey.h"
  5. #include "ReKeyDlg.h"
  6. #include "tlhelp32.h"
  7. #ifdef _DEBUG
  8. #define new DEBUG_NEW
  9. #endif
  10. // 用于应用程序“关于”菜单项的 CAboutDlg 对话框
  11. class CAboutDlg : public CDialog
  12. {
  13. public:
  14. CAboutDlg();
  15. // 对话框数据
  16. enum { IDD = IDD_ABOUTBOX };
  17. protected:
  18. virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
  19. // 实现
  20. protected:
  21. DECLARE_MESSAGE_MAP()
  22. };
  23. CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
  24. {
  25. }
  26. void CAboutDlg::DoDataExchange(CDataExchange* pDX)
  27. {
  28. CDialog::DoDataExchange(pDX);
  29. }
  30. BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
  31. END_MESSAGE_MAP()
  32. // CReKeyDlg 对话框
  33. #define WM_SHOWTASK WM_USER+101
  34. TCHAR g_szConfigFile[MAX_PATH];
  35. HWND hWar3;
  36. HHOOK hHook;
  37. void* g_GameDllbase; //进程war3中Game.dll的加载地址
  38. CString g_war3InstallPath;
  39. TCHAR g_szOutDebugFile[MAX_PATH] = _T("Rekey_OutDebug.txt");
  40. CStdioFile g_DebugFile;
  41. unsigned char g_numPAD[6][2] = {
  42. 0,VK_NUMPAD1,
  43. 0,VK_NUMPAD2,
  44. 0,VK_NUMPAD4,
  45. 0,VK_NUMPAD5,
  46. 0,VK_NUMPAD7,
  47. 0,VK_NUMPAD8};
  48. void WriteDebugFile(const CString& str);
  49. void* GetProcessDllBase(DWORD dwPID, const CString& moduleName);
  50. LRESULT CALLBACK LowKeyboardHookProc(          int code,
  51.   WPARAM wParam,
  52.   LPARAM lParam
  53.   )
  54. {
  55. HWND topWnd = ::GetForegroundWindow();
  56. DWORD processid;
  57. /*DWORD threadid = */::GetWindowThreadProcessId(hWar3,&processid);
  58. HANDLE hProcess = ::OpenProcess(PROCESS_ALL_ACCESS,false,processid);
  59. //  War3 各版本聊天判别地址如下
  60. //  1.20、1.21:
  61. //  0x0045CB8C
  62. // 
  63. //  1.22:
  64. //  0x6FABDFE0
  65. // 
  66. //  1.23:
  67. //  0x6FAD6E30
  68. // 
  69. //  1.24
  70. //  0x6FAE8450
  71. //
  72. // 其中,后三个的 6F 是 Game.dll 的基址。但是 DLL 的基址并不是总是固定不变的,
  73. // 所以实际中,可靠的方法是获取 hDll,然后加上 0x00XXXXXX
  74. BOOL bchatSuccess = FALSE;
  75. LPCVOID pchatbase = (LPCVOID)0x0045CB8C; //判断当前是否为聊天状态
  76. int chatStatus=0;
  77. bchatSuccess = ::ReadProcessMemory(hProcess,pchatbase,&chatStatus,4,NULL);
  78. CloseHandle(hProcess);
  79. if (topWnd == hWar3)
  80. {
  81. //对话框上开启debug的情况下,输出debug信息
  82. CReKeyDlg *dlg = (CReKeyDlg*)AfxGetMainWnd();
  83. if (dlg->m_bIsDebug && WM_KEYDOWN==(DWORD)wParam)
  84. {
  85. CString outLog;
  86. TCHAR keyname[10];
  87. DWORD param = ((PKBDLLHOOKSTRUCT)lParam)->scanCode<<16;
  88. GetKeyNameText(param,keyname,_countof(keyname));
  89. outLog.Format(_T(" -- War3=0x%08X bChat=[%d]%d Key=[%s]n"),hProcess,bchatSuccess,chatStatus,keyname);
  90. WriteDebugFile(outLog);
  91. }
  92. //聊天状态,不做改建。
  93. if ( bchatSuccess && chatStatus!=0 )
  94. {
  95. TRACE0("chating...n");
  96. return CallNextHookEx(hHook,code,wParam,lParam);
  97. }
  98. //根据键映射更改按键
  99. PKBDLLHOOKSTRUCT kbStruct;
  100. if (WM_KEYDOWN==(DWORD)wParam)
  101. {
  102. kbStruct = (PKBDLLHOOKSTRUCT)lParam;
  103. for (int i=0;i<6;i++)
  104. {
  105. //TRACE2("g[i][0] = %d, vkCode = %dn", g_numPAD[i][0], kbStruct->vkCode);
  106. if (g_numPAD[i][0] == kbStruct->vkCode)
  107. {
  108. keybd_event(g_numPAD[i][1],0,0,0);
  109. keybd_event(g_numPAD[i][1],0,KEYEVENTF_KEYUP,0);
  110. return 1;
  111. }
  112. }
  113. }
  114. }
  115. return CallNextHookEx(hHook,code,wParam,lParam);
  116. }
  117. CReKeyDlg::CReKeyDlg(CWnd* pParent /*=NULL*/)
  118. : CDialog(CReKeyDlg::IDD, pParent)
  119. , m_bIsDebug(FALSE)
  120. {
  121. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  122. }
  123. void CReKeyDlg::DoDataExchange(CDataExchange* pDX)
  124. {
  125. CDialog::DoDataExchange(pDX);
  126. DDX_Control(pDX, IDC_STATUS, m_status);
  127. DDX_Control(pDX, IDC_EDIT7, m_edit7);
  128. DDX_Control(pDX, IDC_EDIT8, m_edit8);
  129. DDX_Control(pDX, IDC_EDIT4, m_edit4);
  130. DDX_Control(pDX, IDC_EDIT5, m_edit5);
  131. DDX_Control(pDX, IDC_EDIT1, m_edit1);
  132. DDX_Control(pDX, IDC_EDIT2, m_edit2);
  133. DDX_Control(pDX, IDC_WAR3TOOLTIP, m_staticTooltip);
  134. DDX_Check(pDX, IDC_DEBUGSWITCH, m_bIsDebug);
  135. DDX_Control(pDX, IDC_STARTWARIII, m_StartWar3Ctrl);
  136. }
  137. BEGIN_MESSAGE_MAP(CReKeyDlg, CDialog)
  138. ON_WM_SYSCOMMAND()
  139. ON_WM_PAINT()
  140. ON_WM_QUERYDRAGICON()
  141. //}}AFX_MSG_MAP
  142. ON_WM_CLOSE()
  143. ON_WM_TIMER()
  144. ON_EN_CHANGE(IDC_EDIT1, &CReKeyDlg::OnEnChangeEdit1)
  145. ON_EN_CHANGE(IDC_EDIT2, &CReKeyDlg::OnEnChangeEdit2)
  146. ON_EN_CHANGE(IDC_EDIT4, &CReKeyDlg::OnEnChangeEdit4)
  147. ON_EN_CHANGE(IDC_EDIT5, &CReKeyDlg::OnEnChangeEdit5)
  148. ON_EN_CHANGE(IDC_EDIT7, &CReKeyDlg::OnEnChangeEdit7)
  149. ON_EN_CHANGE(IDC_EDIT8, &CReKeyDlg::OnEnChangeEdit8)
  150. ON_MESSAGE(WM_SHOWTASK,&CReKeyDlg::OnShowTask)
  151. ON_STN_CLICKED(IDC_STARTWARIII, &CReKeyDlg::OnStnClickedStartwariii)
  152. ON_COMMAND(IDM_NF_MENU_EXIT,&CReKeyDlg::OnNFMenuExit)
  153. ON_COMMAND(IDM_SETWAR3PATH,&CReKeyDlg::OnSetWar3Path)
  154. ON_BN_CLICKED(IDC_DEBUGSWITCH, &CReKeyDlg::OnBnClickedDebugswitch)
  155. END_MESSAGE_MAP()
  156. // CReKeyDlg 消息处理程序
  157. BOOL CReKeyDlg::OnInitDialog()
  158. {
  159. CDialog::OnInitDialog();
  160. // 将“关于...”菜单项添加到系统菜单中。
  161. // IDM_ABOUTBOX 必须在系统命令范围内。
  162. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
  163. ASSERT(IDM_ABOUTBOX < 0xF000);
  164. CMenu* pSysMenu = GetSystemMenu(FALSE);
  165. if (pSysMenu != NULL)
  166. {
  167. BOOL bNameValid;
  168. CString strAboutMenu;
  169. bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
  170. ASSERT(bNameValid);
  171. if (!strAboutMenu.IsEmpty())
  172. {
  173. pSysMenu->AppendMenu(MF_SEPARATOR);
  174. pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  175. }
  176. }
  177. // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
  178. //  执行此操作
  179. SetIcon(m_hIcon, TRUE); // 设置大图标
  180. SetIcon(m_hIcon, FALSE); // 设置小图标
  181. // TODO: 在此添加额外的初始化代码
  182. //输出调试信息 --开关
  183. //提升权限
  184. HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,GetCurrentProcessId());
  185. if (hProcess)
  186. {
  187. HANDLE hToken;
  188. if (OpenProcessToken(hProcess,TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken))
  189. {
  190. LUID luid;
  191. if (LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&luid))
  192. {
  193. TOKEN_PRIVILEGES tp;
  194. tp.PrivilegeCount = 1;
  195. tp.Privileges[0].Luid = luid;
  196. tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  197. if(!AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(TOKEN_PRIVILEGES),NULL,NULL)) //AdjustTokenPrivileges
  198. MessageBox(_T("AdjustTokenPrivileges失败。"),_T("提升权限"));
  199. }
  200. else //LookupPrivilegeValue
  201. {
  202. MessageBox(_T("LookupPrivilegeValue失败。"),_T("提升权限"));
  203. }
  204. CloseHandle(hToken);
  205. }
  206. else //OpenProcessToken
  207. {
  208. MessageBox(_T("OpenProcessToken失败。"),_T("提升权限"));
  209. }
  210. }
  211. //得到应用程序全路径
  212. TCHAR fullPath[MAX_PATH];
  213. GetModuleFileName(NULL,fullPath,MAX_PATH);
  214. //解析路径,得到应用程序目录
  215. TCHAR drive[_MAX_DRIVE];
  216. TCHAR dir[_MAX_DIR];
  217. _tsplitpath_s(fullPath,drive,_countof(drive),dir,_countof(dir),NULL,0,NULL,0);
  218. CString strAppPath;
  219. strAppPath.Format(_T("%s%s"),drive,dir);
  220. //生成配置路径
  221. CString configFile = _T("ReKey.conf"); //配置文件名
  222. CString configPath = strAppPath+configFile;
  223. TCHAR* szConfigFile = configPath.GetBuffer(configPath.GetLength());
  224. _tcscpy_s(g_szConfigFile,_countof(g_szConfigFile),szConfigFile);
  225. configPath.ReleaseBuffer();
  226. m_nid.cbSize = sizeof(NOTIFYICONDATA);
  227. m_nid.hWnd = this->m_hWnd;
  228. m_nid.uID = IDR_MAINFRAME;
  229. m_nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
  230. m_nid.uCallbackMessage = WM_SHOWTASK;  //user defined
  231. m_nid.hIcon = LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_MAINFRAME));
  232. _tcscpy_s(m_nid.szTip,_countof(m_nid.szTip),L"War3改键工具");
  233. Shell_NotifyIcon(NIM_ADD,&m_nid);
  234. m_edit1.SetLimitText(1);
  235. m_edit2.SetLimitText(1);
  236. m_edit4.SetLimitText(1);
  237. m_edit5.SetLimitText(1);
  238. m_edit7.SetLimitText(1);
  239. m_edit8.SetLimitText(1);
  240. m_hTimer = SetTimer(1,2000,NULL);
  241. CFile fileRead;
  242. if (fileRead.Open(g_szConfigFile,CFile::modeRead))
  243. {
  244. CArchive arLoad(&fileRead,CArchive::load);
  245. arLoad>>g_war3InstallPath;
  246. for (int i=0;i<6;i++)
  247. {
  248. arLoad>>g_numPAD[i][0];
  249. }
  250. fileRead.Close();
  251. m_edit1.SetWindowText(CString((char)g_numPAD[0][0]));
  252. m_edit2.SetWindowText(CString((char)g_numPAD[1][0]));
  253. m_edit4.SetWindowText(CString((char)g_numPAD[2][0]));
  254. m_edit5.SetWindowText(CString((char)g_numPAD[3][0]));
  255. m_edit7.SetWindowText(CString((char)g_numPAD[4][0]));
  256. m_edit8.SetWindowText(CString((char)g_numPAD[5][0]));
  257. }
  258. if ( 0 == g_war3InstallPath.GetLength() )
  259. {
  260. m_staticTooltip.SetWindowText(_T("<-点击图标设置War3路径"));
  261. }
  262. else
  263. {
  264. m_staticTooltip.SetWindowText(_T("<-点击图标启动War3"));
  265. }
  266. //设置war3图标
  267. CWar3Container *war3IconContainer =  (CWar3Container*)GetDlgItem(IDC_STARTWARIII);
  268. HICON icon = (HICON)LoadImage(theApp.m_hInstance,MAKEINTRESOURCE(IDI_WAR3X),IMAGE_ICON,48,48,LR_DEFAULTCOLOR);
  269. war3IconContainer->SetIcon(icon);
  270. GetDlgItem(IDC_DEBUGSWITCH)->ShowWindow(SW_HIDE);
  271. if (__argc == 2)
  272. {
  273. CString debugFlag = _T("/debug");
  274. LPCTSTR flag= __targv[1];
  275. if (0 == debugFlag.CompareNoCase(flag)) //有debug参数
  276. {
  277. GetDlgItem(IDC_DEBUGSWITCH)->ShowWindow(SW_SHOW);
  278. }
  279. }
  280. return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
  281. }
  282. void CReKeyDlg::OnSysCommand(UINT nID, LPARAM lParam)
  283. {
  284. if ((nID & 0xFFF0) == IDM_ABOUTBOX)
  285. {
  286. CAboutDlg dlgAbout;
  287. dlgAbout.DoModal();
  288. }
  289. //  else if ((nID & 0xFFF0) == SC_CLOSE/*SC_ICON*/)
  290. //  {
  291. //  ShowWindow(SW_HIDE);
  292. //  }
  293. else
  294. {
  295. CDialog::OnSysCommand(nID, lParam);
  296. }
  297. }
  298. // 如果向对话框添加最小化按钮,则需要下面的代码
  299. //  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
  300. //  这将由框架自动完成。
  301. void CReKeyDlg::OnPaint()
  302. {
  303. if (IsIconic())
  304. {
  305. CPaintDC dc(this); // 用于绘制的设备上下文
  306. SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
  307. // 使图标在工作区矩形中居中
  308. int cxIcon = GetSystemMetrics(SM_CXICON);
  309. int cyIcon = GetSystemMetrics(SM_CYICON);
  310. CRect rect;
  311. GetClientRect(&rect);
  312. int x = (rect.Width() - cxIcon + 1) / 2;
  313. int y = (rect.Height() - cyIcon + 1) / 2;
  314. // 绘制图标
  315. dc.DrawIcon(x, y, m_hIcon);
  316. }
  317. else
  318. {
  319. CDialog::OnPaint();
  320. }
  321. }
  322. //当用户拖动最小化窗口时系统调用此函数取得光标
  323. //显示。
  324. HCURSOR CReKeyDlg::OnQueryDragIcon()
  325. {
  326. return static_cast<HCURSOR>(m_hIcon);
  327. }
  328. void CReKeyDlg::OnClose()
  329. {
  330. // TODO: 在此添加消息处理程序代码和/或调用默认值
  331. if (hHook)
  332. {
  333. if (!UnhookWindowsHookEx(hHook))
  334. {
  335. MessageBox(L"UnHook Failed!");
  336. }
  337. }
  338. if ( g_DebugFile.m_pStream )
  339. {
  340. g_DebugFile.Close();
  341. }
  342. Shell_NotifyIcon(NIM_DELETE,&m_nid);
  343. //序列化设置
  344. CFile fileStroe;
  345. if (!fileStroe.Open(g_szConfigFile,CFile::modeWrite|CFile::modeCreate))
  346. {
  347. MessageBox(_T("序列化失败,文件没有找到!"));
  348. CDialog::OnClose();
  349. return ;
  350. }
  351. CArchive arStore(&fileStroe,CArchive::store);
  352. //保存war3运行路径
  353. arStore<<g_war3InstallPath;
  354. //保存按键设置
  355. for (int i=0;i<6;i++)
  356. {
  357. arStore<<g_numPAD[i][0];
  358. }
  359. arStore.Flush(); //不flush总是出现错误
  360. fileStroe.Flush();
  361. fileStroe.Close();
  362. CDialog::OnClose();
  363. }
  364. void CReKeyDlg::OnTimer(UINT_PTR nIDEvent)
  365. {
  366. // TODO: 在此添加消息处理程序代码和/或调用默认值
  367. hWar3 = ::FindWindow(NULL,L"Warcraft III");
  368. if (hWar3)
  369. {
  370. ::SendMessage(hWar3,WM_KEYDOWN,VK_OEM_4,0);
  371. ::SendMessage(hWar3,WM_KEYDOWN,VK_OEM_6,0);
  372. m_status.SetWindowText(L"War3状态:运行中");
  373. if (hHook == NULL)
  374. {
  375. hHook = SetWindowsHookEx(WH_KEYBOARD_LL,LowKeyboardHookProc,GetModuleHandle(NULL),0);
  376. HWND topWnd = ::GetForegroundWindow();
  377. DWORD processid;
  378. ::GetWindowThreadProcessId(hWar3,&processid);
  379. CString str = L"Game.dll";
  380. g_GameDllbase = ::GetProcessDllBase(processid,str);
  381. }
  382. }
  383. else
  384. {
  385. m_status.SetWindowText(L"War3状态:未启动");
  386. if (hHook != NULL)
  387. {
  388. if (UnhookWindowsHookEx(hHook))
  389. {
  390. hHook = NULL;
  391. }
  392. }
  393. }
  394. CDialog::OnTimer(nIDEvent);
  395. }
  396. void CReKeyDlg::OnEnChangeEdit1()
  397. {
  398. UniFormKey(m_edit1);
  399. CString key;
  400. m_edit1.GetWindowText(key);
  401. char *str = (char*)(LPCTSTR)key;
  402. g_numPAD[0][0] = *str;
  403. }
  404. void CReKeyDlg::OnEnChangeEdit2()
  405. {
  406. UniFormKey(m_edit2);
  407. CString key;
  408. m_edit2.GetWindowText(key);
  409. char *str = (char*)(LPCTSTR)key;
  410. g_numPAD[1][0] = *str;
  411. }
  412. void CReKeyDlg::OnEnChangeEdit4()
  413. {
  414. UniFormKey(m_edit4);
  415. CString key;
  416. m_edit4.GetWindowText(key);
  417. char *str = (char*)(LPCTSTR)key;
  418. g_numPAD[2][0] = *str;
  419. }
  420. void CReKeyDlg::OnEnChangeEdit5()
  421. {
  422. UniFormKey(m_edit5);
  423. CString key;
  424. m_edit5.GetWindowText(key);
  425. char *str = (char*)(LPCTSTR)key;
  426. g_numPAD[3][0] = *str;
  427. }
  428. void CReKeyDlg::OnEnChangeEdit7()
  429. {
  430. UniFormKey(m_edit7);
  431. CString key;
  432. m_edit7.GetWindowText(key);
  433. char *str = (char*)(LPCTSTR)key;
  434. g_numPAD[4][0] = *str;
  435. }
  436. void CReKeyDlg::OnEnChangeEdit8()
  437. {
  438. // TODO:  如果该控件是 RICHEDIT 控件,它将不
  439. // 发送此通知,除非重写 CDialog::OnInitDialog()
  440. // 函数并调用 CRichEditCtrl().SetEventMask(),
  441. // 同时将 ENM_CHANGE 标志“或”运算到掩码中。
  442. // TODO:  在此添加控件通知处理程序代码
  443. UniFormKey(m_edit8);
  444. CString key;
  445. m_edit8.GetWindowText(key);
  446. char *str = (char*)(LPCTSTR)key;
  447. g_numPAD[5][0] = *str;
  448. }
  449. //使各键不至于重复
  450. bool CReKeyDlg::UniFormKey(CEdit& edit)
  451. {
  452. CString strc;
  453. edit.GetWindowText(strc);
  454. //空表示无设置,此时不应检查其唯一性,这是可能还有好几个按键是无设置的呢
  455. if (strc.Compare(_T(""))==0)
  456. {
  457. return true;
  458. }
  459. //由于TCHAR字符是2位,而且它按小尾的字节顺序排列,所以第一字节是char值
  460. //考虑 TCHAR tc = 'T';
  461. // char c = (char)(int)tc;
  462. char * c= (char*)(LPCTSTR)strc;
  463. HWND hWndEdit = edit.GetSafeHwnd();
  464. int iEdit = -1;
  465. if (hWndEdit == m_edit1.GetSafeHwnd())
  466. {
  467. iEdit = 0;
  468. }else if (hWndEdit == m_edit2.GetSafeHwnd())
  469. {
  470. iEdit = 1;
  471. }else if (hWndEdit == m_edit4.GetSafeHwnd())
  472. {
  473. iEdit = 2;
  474. }else if (hWndEdit == m_edit5.GetSafeHwnd())
  475. {
  476. iEdit = 3;
  477. }else if (hWndEdit == m_edit7.GetSafeHwnd())
  478. {
  479. iEdit = 4;
  480. }else if (hWndEdit == m_edit8.GetSafeHwnd())
  481. {
  482. iEdit = 5;
  483. }
  484. if (iEdit==-1)
  485. {
  486. return false;
  487. }
  488. int i=0;
  489. for (;i<6;i++)
  490. {
  491. if (*c == g_numPAD[i][0])
  492. {
  493. if (iEdit==i)
  494. continue;
  495. else
  496. break;
  497. }
  498. }
  499. switch (i)
  500. {
  501. case 0:
  502. m_edit1.SetWindowText(_T(""));
  503. break;
  504. case 1:
  505. m_edit2.SetWindowText(_T(""));
  506. break;
  507. case 2:
  508. m_edit4.SetWindowText(_T(""));
  509. break;
  510. case 3:
  511. m_edit5.SetWindowText(_T(""));
  512. break;
  513. case 4:
  514. m_edit7.SetWindowText(_T(""));
  515. break;
  516. case 5:
  517. m_edit8.SetWindowText(_T(""));
  518. break;
  519. default:
  520. break;
  521. }
  522. return true;
  523. }
  524. LRESULT CReKeyDlg::OnShowTask(WPARAM wParam, LPARAM lParam)
  525. {
  526. if(wParam != IDR_MAINFRAME)
  527. return 1;
  528. CMenu menu;
  529. LPPOINT lpoint;
  530. switch (lParam)
  531. {
  532. case WM_RBUTTONUP:
  533. lpoint = new tagPOINT;
  534. ::GetCursorPos(lpoint);
  535. menu.CreatePopupMenu();
  536. menu.AppendMenu(MF_STRING,IDM_NF_MENU_EXIT,L"退出ReKey");
  537. menu.TrackPopupMenu(TPM_LEFTALIGN,lpoint->x,lpoint->y,this);
  538. menu.Detach();
  539. menu.DestroyMenu();
  540. delete lpoint;
  541. break;
  542. case WM_LBUTTONDBLCLK:
  543. this->ShowWindow(SW_SHOWNORMAL);
  544. SetForegroundWindow();
  545. break;
  546. default:
  547. break;
  548. }
  549. return 0;
  550. }
  551. //托盘菜单退出选项处理
  552. void CReKeyDlg::OnNFMenuExit()
  553. {
  554. this->SendMessage(WM_CLOSE);
  555. }
  556. void CReKeyDlg::OnSetWar3Path()
  557. {
  558. CFileDialog fileDLg(TRUE,NULL,NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,_T("可执行文件(*.exe)|*.exe||"));
  559. if (fileDLg.DoModal() == IDOK)
  560. {
  561. //更改war3路径
  562. m_staticTooltip.SetWindowText(_T("<-点击图标启动War3"));
  563. g_war3InstallPath = fileDLg.GetPathName();
  564. }
  565. //维持g_war3InstallPath不变
  566. }
  567. void* GetProcessDllBase(DWORD dwPID, const CString& moduleName)
  568. {
  569. HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
  570. MODULEENTRY32 me32;
  571. hModuleSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,dwPID);
  572. if (hModuleSnap == INVALID_HANDLE_VALUE)
  573. {
  574. DWORD dwErr = GetLastError();
  575. return 0;
  576. }
  577. me32.dwSize = sizeof(MODULEENTRY32);
  578. if (!Module32First(hModuleSnap,&me32))
  579. {
  580. CloseHandle(hModuleSnap);
  581. return 0;
  582. }
  583. CString strModule;
  584. void* base=0;
  585. do 
  586. {
  587. strModule = CString(me32.szModule);
  588. if (moduleName == strModule)
  589. {
  590. base = (void*)me32.modBaseAddr;
  591. break;
  592. }
  593. } while (Module32Next(hModuleSnap,&me32));
  594. CloseHandle(hModuleSnap);
  595. return base;
  596. }
  597. void CReKeyDlg::OnStnClickedStartwariii()
  598. {
  599. // 检查war3路径并设置
  600. if ( !g_war3InstallPath.GetLength() )
  601. {
  602. CFileDialog fileDLg(TRUE,NULL,NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,_T("可执行文件(*.exe)|*.exe||"));
  603. if (fileDLg.DoModal() == IDOK)
  604. {
  605. m_staticTooltip.SetWindowText(_T("<-点击图标启动War3"));
  606. g_war3InstallPath = fileDLg.GetPathName();
  607. return ; //设置完毕不直接启动war3,感觉这样好些
  608. }
  609. else
  610. {
  611. return ; //没有设置路径,返回
  612. }
  613. }
  614. //war3已经启动,切换过去
  615. hWar3 = ::FindWindow(NULL,L"Warcraft III");
  616. if (hWar3)
  617. {
  618. ::ShowWindow(hWar3,SW_SHOWNORMAL);
  619. ::SetForegroundWindow(hWar3);
  620. return ;
  621. }
  622. //启动war3
  623. //g_war3InstallPath += _T(" -window");
  624. TCHAR szPath[MAX_PATH];
  625. TCHAR *pathBuff = g_war3InstallPath.GetBuffer(g_war3InstallPath.GetLength());
  626. _tcscpy_s(szPath,_countof(szPath),pathBuff);
  627. g_war3InstallPath.ReleaseBuffer();
  628. STARTUPINFO si;
  629. PROCESS_INFORMATION ppiProcess;
  630. memset(&si,0,sizeof(STARTUPINFO));
  631. si.cb = sizeof(STARTUPINFO);
  632. si.wShowWindow = SW_SHOWNORMAL;
  633. si.lpDesktop = NULL;
  634. si.dwFlags = STARTF_USESHOWWINDOW;
  635. if(!CreateProcess(NULL,szPath,NULL,NULL,TRUE,0,NULL,NULL,&si,&ppiProcess))
  636. {
  637. MessageBox(_T("War3进程创建失败!n"));
  638. return ;
  639. }
  640. CloseHandle(ppiProcess.hThread);
  641. CloseHandle(ppiProcess.hProcess);
  642. }
  643. void CReKeyDlg::OnBnClickedDebugswitch()
  644. {
  645. // TODO: 在此添加控件通知处理程序代码
  646. UpdateData(TRUE);
  647. //取得系统当前时间
  648. CString sTime;
  649. SYSTEMTIME st;
  650. GetLocalTime(&st);
  651. sTime.Format(_T("%d-%d-%d %d:%d:%d   "),st.wYear,st.wMonth,st.wDay,st.wHour,st.wMinute,st.wSecond);
  652. CString outLog;
  653. CString strValue;
  654. //创建输出信息
  655. if ( m_bIsDebug )
  656. {
  657. outLog = sTime + _T("Start Debug Outputn");
  658. strValue.Format(_T("%20s: 0x%08Xn%20s: 0x%08Xn%20s: 0x%08Xn"),
  659. _T("War3 Window Handle"),hWar3,
  660. _T("Hook Handle"),hHook,
  661. _T("Game.dll Addr"),(DWORD)g_GameDllbase);
  662. outLog += strValue;
  663. //负责打开文件
  664. g_DebugFile.Open(g_szOutDebugFile,CFile::modeWrite|CFile::modeCreate|CFile::modeNoTruncate|CFile::shareDenyWrite);
  665. g_DebugFile.SeekToEnd();
  666. //写入信息
  667. //g_DebugFile.WriteString((LPCTSTR)outLog);
  668. WriteDebugFile(outLog);
  669. }
  670. else
  671. {
  672. outLog = sTime + _T("Stop Debug Output.nn");
  673. //写入信息
  674. //g_DebugFile.WriteString((LPCTSTR)outLog);
  675. WriteDebugFile(outLog);
  676. //负责关闭文件
  677. if (g_DebugFile.m_pStream)
  678. {
  679. g_DebugFile.Close();
  680. }
  681. }
  682. }
  683. void WriteDebugFile(const CString &str)
  684. {
  685. //没有打开文件,返回
  686. if (NULL == g_DebugFile.m_pStream)
  687. return ;
  688. g_DebugFile.WriteString((LPCTSTR)str);
  689. g_DebugFile.Flush();
  690. }