MFC实现 获取其他应用程序窗口信息 .

时间:2022-02-25 14:41:23

最近上网时看到有获取QQ号的方法,自己实现了下,没能获取QQ密码(听说从QQ2009后就很难获取了),但能获取一般应用程序的窗口信息。下面给出实现的具体细节。

要使用到几个API函数FindWindow,FindWindowEx,WindowFromPoint,SendMessage,GetWindowRect等。

FindWindow:用于获取应用程序的窗口句柄

HWND FindWindow(

  LPCTSTR lpClassName,  // class name,窗口的类名称

  LPCTSTR lpWindowName  // window name,窗口标题名称

);

使用时,两者只要知道一个就可以定位到你想要的窗口上了,若两个参数都为NULL,则搜索所有启动的进程,这里,为了获取应用程序的窗口信息,可以下载Spy++,这个软件很好用,可以获得窗口类名称,标题等信息。

FindWindowEx:用于获取应用程序中指定子窗口的句柄

HWND FindWindowEx(

  HWND hwndParent,      // handle to parent window,应用程序窗口句柄

  HWND hwndChildAfter,  // handle to child window,子窗口的句柄

  LPCTSTR lpszClass,    // class name,子窗口类

  LPCTSTR lpszWindow    // window name,子窗口标题

);

同样通过Spy++可以获取子窗口的相关信息,但窗口句柄是会变化的,子窗口的标题也不是都有,比如该子窗口是一编辑框。这样,我们还可以通过点试探的方法找到想要的字窗口,比如我们要得到QQ登录框中输入的用户名+密码。可以先得到登录框、密码框的屏幕坐标位置,然后在其中取一个点,利用WindowFromPoint函数得到该点所在的窗口句柄,该句柄就是我们感兴趣的窗口句柄。

得到了窗口句柄后,如何得到窗口的内容,或是对他做点什么呢,呵呵,这里,就要用到消息发送的知识了。

LRESULT SendMessage(

  HWND hWnd,      // handle to destination window,接受消息的窗口句柄

  UINT Msg,       // message,消息类型

  WPARAM wParam,  // first message parameter,消息包含的附加信息

  LPARAM lParam   // second message parameter,消息包含的附加信息

);

下面贴上我的程序代码:

void CGetWindowTextView::OnUsername()

{

       // TODO: Add your command handler code here

       m_qqhWnd=::FindWindow(NULL,"QQ2009 正式版 SP1");

       if(m_qqhWnd)

       {

              //获取窗口句柄

              CRect rect;

              ::GetWindowRect(m_qqhWnd,rect);

              CString str;

       str.Format("qq登录框在屏幕的(%d,%d,%d,%d)位置/r/n宽:%d;高:%d",rect.left,rect.top,rect.right,rect.bottom,rect.Width(),rect.Height());

CPoint user_pt;

//将user_pt点定位到用户名框内

user_pt.x=rect.left+100;

user_pt.y=rect.top+120;

//获取用户名框的句柄

m_hUserWnd=::WindowFromPoint(user_pt);

str="用户名:";

char buf[10];

//获取用户名

::SendMessage(m_hUserWnd,WM_GETTEXT,(WPARAM)999,(LPARAM)buf);

str=str+buf+"/r/n";

::AfxMessageBox(str);

       //     ::SendMessage(m_qqhWnd,WM_CLOSE,0,0);//发送消息,关闭qqhWnd窗口

       }

       else

              MessageBox("查找窗口失败!");

}

密码获取要复杂些,因为密码框上都是***的东西,直接getText是不行的,分析知道,我们在创建编辑框是复选“密码”,显示时输入就是***了。这样,我们可以先修改密码框的样式,将“密码”复选去掉,再获取框中的内容就可以了,当然,得到想要的密码后,我们再将样式改回来,就神不知鬼不觉啦!

void CGetWindowTextView::OnGetPassword()

{

       // TODO: Add your command handler code here

       m_qqhWnd=::FindWindow(NULL,"QQ2009 正式版 SP1");

       if(m_qqhWnd)

       {

              if(!m_qqhWnd)

              return FALSE;

              CRect rect;

::GetWindowRect(m_qqhWnd,rect); m_pwdWnd=::FindWindowEx(m_qqhWnd,NULL,"Edit",NULL);

CPoint pwd_pt;

//密码框相对于登录框的位置可以试出来,取下面的点可以保证落在密码框内

pwd_pt.x=rect.left+100;

              pwd_pt.y=rect.top+150;

              //m_pwdWnd=::WindowFromPoint(pwd_pt);//或者通过点来得到

if(!m_pwdWnd)

              {

                     MessageBox("密码框获取失败!");

                     return FALSE;

              }

str=”密码:";

//得到窗口的样式

              LONG lstyle = ::GetWindowLong(m_pwdWnd,GWL_STYLE);

              if(lstyle & ES_PASSWORD)

              {

                     LONG PassToChar = ::SendMessage(m_pwdWnd,EM_GETPASSWORDCHAR,0,0);

                     ::PostMessage(m_pwdWnd,EM_SETPASSWORDCHAR,0,0);

                     ::SendMessage(m_pwdWnd,WM_GETTEXT,50,(LPARAM)buf);

                     ::PostMessage(m_pwdWnd,EM_SETPASSWORDCHAR,PassToChar,0);

              }

              str=str+buf+"/r/n";

              ::AfxMessageBox(str);

       //     ::SendMessage(m_qqhWnd,WM_CLOSE,0,0);

       }

       else

              MessageBox("查找窗口失败!");

}