如何向foxmail中的写邮件窗体中发送一段文字?(100分)

  • 主题发起人 主题发起人 lcl_003
  • 开始时间 开始时间
L

lcl_003

Unregistered / Unconfirmed
GUEST, unregistred user!
如题,foxmail中写邮件窗体的标题是动态的。
 
我几年前写过这样一段代码。当时是向另一套运行的软件界面自动填入数据。<br>那套软件是进行自动控制的,为了减轻操作者的工作量,写了一段小程序自动填入数据。<br>记得是这样做的,首先找到该窗口的句柄,然后找该输入框的名字,接下来发送消息到该输入框,就实现了数据自动填入。
 
提供一个思路:<br>用findwindow(nil,'窗口标题')找到一个窗口的HWND<br>然后用GetClassName取到类名。下次findwindow的时候就按类名查了。<br>取到handle之后再向这个窗口发消息就可以了。WM_CHAR之类的。
 
findwindow(nil,'窗口标题')找到一个窗口的HWND<br>foxmail的写邮件的窗口标题是动态变化的。刚打开的时候是“写邮件”,当收信人地址为aaa的时候标题就变城“写邮件(aaa)”
 
用SPY看了下,foxmail的邮件输入框有两个,一个是文本的,一个是Internet Explorer_Server的。句柄倒是容易找到,发送也正常。只是在发送文字的时候对窗口类是Internet Explorer_Server的输入框无效,不知道问题在哪。<br><br>测试的代码:<br><br>//这个函数是获取文本类输入框的句柄<br>Function TFrmMain.FindText(Handle:THandle):THandle;<br>var<br> &nbsp;Hwnd_Panel,<br> &nbsp;Hwnd_Panel2,<br> &nbsp;Hwnd_Panel3,<br> &nbsp;Hwnd_Panel4,<br> &nbsp;Hwnd_HtmlEdit,<br> &nbsp;Hwnd_Text:THandle;<br>begin<br> &nbsp;Result:=0;<br> &nbsp;Hwnd_Panel:=FindWindowEx(Handle,0,'TPanel','Panel_Back');<br> &nbsp;if Hwnd_Panel&lt;&gt;0 then<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp;Hwnd_Panel2:=FindWindowEx(Hwnd_Panel,0,'TPanel',nil);<br> &nbsp; &nbsp; &nbsp;Hwnd_Panel3:=FindWindowEx(Hwnd_Panel2,0,'TPanel','P_Content');<br> &nbsp; &nbsp; &nbsp;Hwnd_Panel4:=FindWindowEx(Hwnd_Panel3,0,'TPanel','P_HtmlText');<br> &nbsp; &nbsp; &nbsp;Hwnd_HtmlEdit:=FindWindowEx(Hwnd_Panel4,0,'TNewDHTMLEdit',nil);<br> &nbsp; &nbsp; &nbsp;Hwnd_Text:=FindWindowEx(Hwnd_HtmlEdit,0,'TZEditor',nil);<br> &nbsp; &nbsp; &nbsp;if (Hwnd_Text&lt;&gt;0) and (IsWindowVisible(Hwnd_Text)) then<br> &nbsp; &nbsp; &nbsp; &nbsp;Result:=Hwnd_Text;<br> &nbsp; &nbsp;end;<br>end;<br><br>//这个函数是获取Internet Explorer_Server窗口类输入框的句柄<br>Function TFrmMain.FindHtml(Handle:THandle):THandle;<br>var<br> &nbsp;Hwnd_Panel,<br> &nbsp;Hwnd_Panel2,<br> &nbsp;Hwnd_Panel3,<br> &nbsp;Hwnd_Panel4,<br> &nbsp;Hwnd_HtmlEdit,<br> &nbsp;Hwnd_Embedding,<br> &nbsp;Hwnd_DocObjectView,<br> &nbsp;Hwnd_IE:THandle;<br>begin<br> &nbsp;Result:=0;<br> &nbsp;Hwnd_Panel:=FindWindowEx(Handle,0,'TPanel','Panel_Back');<br> &nbsp;if Hwnd_Panel&lt;&gt;0 then<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp;Hwnd_Panel2:=FindWindowEx(Hwnd_Panel,0,'TPanel',nil);<br> &nbsp; &nbsp; &nbsp;Hwnd_Panel3:=FindWindowEx(Hwnd_Panel2,0,'TPanel','P_Content');<br> &nbsp; &nbsp; &nbsp;Hwnd_Panel4:=FindWindowEx(Hwnd_Panel3,0,'TPanel','P_HtmlText');<br> &nbsp; &nbsp; &nbsp;Hwnd_HtmlEdit:=FindWindowEx(Hwnd_Panel4,0,'TNewDHTMLEdit',nil);<br> &nbsp; &nbsp; &nbsp;Hwnd_Embedding:=FindWindowEx(Hwnd_HtmlEdit,0,'Shell Embedding',nil);<br> &nbsp; &nbsp; &nbsp;Hwnd_DocObjectView:=FindWindowEx(Hwnd_Embedding,0,'Shell DocObject View',nil);<br> &nbsp; &nbsp; &nbsp;Hwnd_IE:=FindWindowEx(Hwnd_DocObjectView,0,'Internet Explorer_Server',nil);<br> &nbsp; &nbsp; &nbsp;if (Hwnd_IE&lt;&gt;0) and (IsWindowVisible(Hwnd_IE)) then<br> &nbsp; &nbsp; &nbsp; &nbsp;Result:=Hwnd_IE;<br> &nbsp; &nbsp;end;<br>end;<br><br>Procedure TFrmMain.SendText(Handle:THandle);<br>begin<br> &nbsp;tex_send.SelectAll;<br> &nbsp;SendMessage(tex_send.Handle,WM_COPY,0,0);<br> &nbsp;SendMessage(Handle,WM_PASTE,0,0);<br> &nbsp;//这里对Internet Explorer_Server窗口无效,不知道怎么处理这类窗体<br>end;<br><br>procedure TFrmMain.bt_sendClick(Sender: TObject);<br>var<br> &nbsp;HwndText,HwndHtml,Hwnd:THandle;<br>begin<br> &nbsp;Hwnd:=FindWindowEx(0,0,'TF_compose',nil);//查找发邮件的窗体<br> &nbsp;if Hwnd&lt;&gt;0 then<br> &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; HwndText:=FindText(Hwnd);<br> &nbsp; &nbsp; &nbsp; HwndHtml:=FindHtml(Hwnd);<br> &nbsp; &nbsp; &nbsp; if HwndText&lt;&gt;0 then SendText(HwndText)<br> &nbsp; &nbsp; &nbsp; else if HwndHtml&lt;&gt;0 then SendText(HwndHtml);<br> &nbsp; &nbsp; end;<br>end;
 
应该只需要做一个小程序用Findwindow按标题找一次就可以了,目的是为了取到类名。窗口的标题会变,类名应该是不变的。在你的正式程序中,就应该是按类名来查找窗口了。
 
试了试mysirius得好像不行:(
 
哦文本格式得可以发送消息,Internet Explorer_Server确不行,为什么阿:(
 
把这篇也转过来,写得更有情趣哦,“钩子”真是让人爱恨交加啊,它就象女人一样奇妙! <br>转贴:让网页密码编辑框中的“星星”现身(附EXE) <br>(http://www.ccw.com.cn/htm/app/aprog/01_12_20_2.asp) <br><br>通常情况下,在密码编辑框中输入的字符都用**(这里呼之为“星星”)来代替,以达到保 <br>护密码的目的。但看“星星”的工具并不比“星星”的个数少,由于其原理比较简单,初学 <br>者很容易制作一个。然而,有时天公不作美,它会给晴朗的星空抹上一道乌云,这时你就无 <br>法寻觅那颗明亮的星。网页中的“星星”就是一颗被掩盖的星。 <br>透过密码编辑框看“星星”,主要是通过向密码编辑框发送WM_GETTEXT,获得密码编辑框的 <br>窗口文本,这种方法在Windows 9x/NT4/ME环境下屡试不爽,星星既属于你,又属于我,大 <br>家都可以看到。到了Windows 2K/XP环境,这招有些失灵,星星变聪明了,它只属于它中意 <br>的人,别的进程别想打它的主意。对于没有权限获得密码的进程,它会简单地返回一个 <br>ERROR_ACCESS_DENIED,来打发那些动机不纯或者别有用心的人们。但是还是有高手能够通 <br>过钩子函数,来笼络星星的心,钩子函数能够实现把一个动态连接库注入到另外一个进程, <br>获取窗口文本,再返回给另外一个进程,面对这个吃里扒外的东西,不明真相的星星姑娘, <br>居然听之任之,全抛一片心。 <br>网页中的星星是一颗特别的星,铁石心肠,然而它却是豆腐作的。你很难获得它的窗口句 <br>柄,通过Visual Studio提供的SPY++也很难获得它的窗口句柄和它收到的窗口消息。获 <br>得网页中的密码必须通过必须通过HTML中的MSHTML文档对象模型。你首先必须通过各种方 <br>法获得Internet Explorer浏览器(Mr Navigate,Sorry)窗口句柄,判断它的类名是否 <br>是&quot;Internet Explorer_Server&quot;,然后通过下述代码获得其文档对象模型指针,即 <br>IHTMLDocument2接口。 <br><br>HWND hw; &nbsp; <br>MSHTML::IHTMLDocument2Ptr doc; <br>MSHTML::IHTMLElementCollectionPtr col; <br>MSHTML::IHTMLElementPtr EL; <br>DWORD lRes; <br>HRESULT hres; <br><br>UINT MSG = RegisterWindowMessage(&quot;WM_HTML_GETOBJECT&quot;); <br><br>SendMessageTimeout(hw, MSG, 0, 0, SMTO_ABORTIFHUNG, 1000, &lRes); <br><br>hres=ObjectFromLresult(lRes, __uuidof(MSHTML::IHTMLDocument2), 0, (void**)&doc); <br><br>然后你必须获得鼠标屏幕坐标,把它转换成相对于客户区的坐标,然后根据坐标位置获得网 <br>页对对应的元素,查询IID_IHTMLInputTextElement接口指针,判断元素类型是否是一个密 <br>码编辑框,并获得对应密码。 <br><br>CString GetPassword(IHTMLDocument2 *pDoc2,POINT pt) <br>{ <br>if(pDoc2==NULL)return &quot;&quot;; <br>CComPtr&lt;IHTMLElement&gt; pElement; <br>HRESULT hr=pDoc2-&gt;elementFromPoint(pt.x,pt.y,&pElement); <br>if(SUCCEEDED(hr)){ <br>CComPtr&lt;IHTMLInputTextElement&gt; pPwdElement; <br>hr=pElement-&gt;QueryInterface(IID_IHTMLInputTextElement, <br>(void**)&pPwdElement); <br>if(SUCCEEDED(hr)){ <br>CComBSTR type; <br>hr=pPwdElement-&gt;get_type(&type); <br>if(SUCCEEDED(hr)){ <br>if(type==_T(&quot;password&quot;)){ <br>CComBSTR pwd; <br>hr=pPwdElement-&gt;get_value(&pwd); <br>if(SUCCEEDED(hr)){ <br>if(pwd.Length()!=0){ <br>CComBSTR msg; <br>msg=pwd; <br>CString str(msg); <br>return str; <br>} <br>else{ <br>return &quot;&quot;; <br>} <br>} <br>} <br>} <br>} <br>} <br>pDoc2-&gt;Release(); <br>return &quot;&quot;; <br>} <br>如果你想尝试一下如何在后台记录网页密码,你可以实现一个IE扩展的COM组件,由IE负责 <br>自动加载,在组件中你必须实现IOleObjectSite接口,在SetSite方法中得到一个指向IE <br>COM对象的Iunknown的指针,再通过它获得其它接口的指针。在程序中还需要创建一个线 <br>程负责对当前的网页所有元素实现轮询解析,判断元素的属性是否是一个编辑框(密码编 <br>辑框),然后把用户名和密码记录到一个文件中。 <br>本程序在Windows XP(IE6)环境下利用Visual Studio.net Beta 2调试通过
 
to lcl_003:<br> &nbsp; 你用的哪个版本的foxmail,我的是6beta3的,而且只能对文本模式的有用,<br>而默认是HTML模式,我也不知道对这个模式怎么搞。
 
我用的是5。对html模式也没用。就是Internet Explorer_Server的问题:(
 
好象是外挂技术。
 
后退
顶部