最近上网时看到有获取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("查找窗口失败!");
}