修改某个窗口的窗口消息函数

事件的缘由是要获取到Mt4客户端窗口的菜单绑定的ID号,使用spy++无果后,决定自己写程序实现。

方法一:                                                                                                                                            

        获取窗口HWND --> 获取主菜单 HMENU --> 获取子菜单 -->  获取菜单ID  失败告终。

方法二 就是本文的标题了。

        直接在程序 SetWindowLong(mtClientWnd, GWL_WNDPROC, long(NewWndProc)); 发现会失败,就连 GetWindowLong()函数调用也是失败的。 于是提升进程权限,以管理员运行,结果都失败。

       接下来就决定进一步提升权限了,把这代码让进程自己执行,那就没问题了吧。有代码注入和dll注入两种方式,dll注入比较简单我也比较熟悉,就用这一种吧。 dll注入成功却没有运行起来,发现Mt客户端是32位的,那么注入程序也只能是32位的,dll也只能是32位的。debug和release都可以,   dll代码如下:

   #include

WNDPROC mtClientWndFun;

LRESULT CALLBACK NewWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)

{

switch (message)

{

case WM_COMMAND:

CString commandId;

commandId.Format("%d", wParam);

AfxMessageBox(commandId);

break;

}

//继续调用原来的窗口过程函数 

return CallWindowProc(mtClientWndFun, hwnd, message, wParam, lParam);

}

BOOL CTestDllApp::InitInstance()

{

CWinApp::InitInstance();

HWND mtClientWnd = WndUtils::getWnd("DPSMarkets-test");

mtClientWndFun = (WNDPROC)GetWindowLong(mtClientWnd, GWL_WNDPROC);

if (mtClientWndFun == NULL)

{

AfxMessageBox("err");

}

else

{

AfxMessageBox("success");

}

SetWindowLong(mtClientWnd, GWL_WNDPROC, long(NewWndProc));

return TRUE;

}

注入程序代码:

HWND loginWnd = WndUtils::getWnd("DPSMarkets-test", true);

Process mtProcess(WndUtils::getWndProcessId(loginWnd));

mtProcess.injectionDll("E:\\project\\c++\\win32\\TestDll\\Release\\TestDll.dll");

--------------------------------------------------------------------------------------------------------

类库使用地址:https://github.com/huangshangbin/LibraryReconstruct

system/Process.hpp 有进程注入dll的接口。

使用Mt客户端点击菜单,就能弹出菜单ID了。

在其他程序通过 PostMessageA(a,WM_COMMAND,35429,0);就能调用响应的COMMAND ID绑定的消息函数了。

说明:
     1  上面方式只能在32位上使用。64位
          mtClientWndFun = (WNDPROC)GetWindowLong(mtClientWnd, GWL_WNDPROC);换成
          mtClientWndFun = (WNDPROC)GetWindowLongPtr(mtClientWnd, GWLP_WNDPROC);
    SetWindowLong(mtClientWnd, GWL_WNDPROC, long(NewWndProc));换成
   SetWindowLongPtr(mtClientWnd, GWLP_WNDPROC, reinterpret_cast(NewWndProc));
   64位的方式是通用的,未测试。

      2 dll获取窗口的通用方法
         HWND curWnd = NULL;
        deque wndInfoList = WndUtils::getAllWndInfoList();
         for (auto wndInfo : wndInfoList)
                if (WndUtils::getWndProcessId(wndInfo.m_hwnd) == ::GetCurrentProcessId())
                { curWnd = wndInfo.m_hwnd;   break;}
   
     3  找到需要注入的程序
        deque wndInfoList = WndUtils::getAllWndInfoList();
             for (auto& wndInfo : wndInfoList)
       {   Process wndProcess(WndUtils::getWndProcessId(wndInfo.m_hwnd));
             if (StringUtils::isExistStringInString(wndProcess.getPath(), "firefox.exe")){
          cout << wndInfo.m_text << endl;
       cout << wndProcess.getPath() << endl;}}

你可能感兴趣的:(修改某个窗口的窗口消息函数)