2013-01-21 2 views
0

일부 오래된 응용 프로그램에 대해 DCOM 확장을 생성하고 있습니다. 기본 응용 프로그램 내부에 IE 컨트롤이 있습니다.IHTMLDocument2 - iframe 내부 버튼 클릭

사용하여 C#을 나는 다음과 같이 그 IE 컨트롤에 대한 처리기를 얻을 수있었습니다 :

Process pr = Process.GetCurrentProcess(); 

var title = pr.MainWindowTitle; 
if(title.IndexOf("My old application -")<0) 
{ 
    MessageBox.Show("No such window"); 
    return; 
} 
var wlwWindow = pr.MainWindowHandle; 
var ieWindow = PI.FindWindowRecursive(wlwWindow, "Internet Explorer_Server", null); 
if (ieWindow == IntPtr.Zero) 
{ 
    MessageBox.Show("Unable to locate IE window."); 
    return; 
} 
var myDocument= PI.GetIEDocumentFromWindowHandle(ieWindow); 
MessageBox.Show(myDocument.url); 

그리고 여기 내 도우미 방법은 다음과 같습니다

public static IntPtr FindWindowRecursive(IntPtr parent, string windowClass, string windowCaption) 
    { 
     var found = FindWindowEx(parent, IntPtr.Zero, windowClass, windowCaption); 
     if (found != IntPtr.Zero) 
     { 
      return found; 
     } 

     var child = FindWindowEx(parent, IntPtr.Zero, null, null); 
     while (child != IntPtr.Zero) 
     { 
      found = FindWindowRecursive(child, windowClass, windowCaption); 
      if (found != IntPtr.Zero) 
      { 
       return found; 
      } 
      child = GetNextWindow(child, 2); 
     } 
     return IntPtr.Zero; 
    } 

    public static IHTMLDocument2 GetIEDocumentFromWindowHandle(IntPtr hWnd) 
    { 
     IHTMLDocument2 htmlDocument = null; 
     if (hWnd != IntPtr.Zero) 
     { 
      uint lMsg = RegisterWindowMessage("WM_HTML_GETOBJECT"); 
      UIntPtr lResult; 
      SendMessageTimeout(hWnd, lMsg, UIntPtr.Zero, UIntPtr.Zero, 
       SendMessageTimeoutFlags.SMTO_ABORTIFHUNG, 1000, out lResult); 
      if (lResult != UIntPtr.Zero) 
      { 
       htmlDocument = ObjectFromLresult(lResult, typeof(IHTMLDocument).GUID, IntPtr.Zero) as IHTMLDocument2; 
       if (htmlDocument == null) 
       { 
        throw new COMException("Unable to cast to an object of type IHTMLDocument"); 
       } 
      } 
     } 
     return htmlDocument; 
    } 

이 부분은 잘 작동하고 내가 얻을 수있었습니다 온도에서 해당 HTML 페이지의 내용 :

<body id="state" class="saveFavorite" onload="load()" onunload="RUIMaster.Destroy()" style="margin: 0px; padding: 0px; overflow: hidden;"> 
<p style="display: none;"> 
<object classid="clsid:22FD36F1-A133-11d4-A0E4-005056E2D8AA" height="0" width="0" id="RUIMaster"> 
</object> 
</object> 
<form> 
<input id="id" type="hidden" value="" /> 
</form> 
</p> 
<iframe name="AAMain" style="margin: 0px; border: 0px; padding: 0px;" id="contents" src="rdaui_frame.htm" width="100%" height="100%" frameborder="0" /> 
</body> 

나는 이름 AAMain로 iframe을 액세스해야합니다 .

<frameset cols="135,*" border="0" frameborder="no" framespacing="0"> 
    <frame name="Menu" scrolling="no" noresize marginwidth="0" marginheight="0" src="blank.htm"> 
    <frameset rows="310,*,31"> 
     <frame name="Top" noresize marginwidth="0" marginheight="0" src="blank.htm"> 
     <frame name="Centre" noresize marginwidth="0" marginheight="0" src="blank.htm"> 
     <frame name="Bottom" noresize marginwidth="0" marginheight="0" src="blank.htm"> 
    </frameset> 
</frameset> 

그래서 기본적으로 내가 AAMain

myDocument 이름 iframe을 내부 프레임 이름 센터에 액세스해야합니다 -> iframe을 (AAMain) - :과 같이 그 iframe이 문서의
콘텐츠 보인다 > 프레임 (센터) -> 이미지를 클릭하십시오.

이상의 프레임을 반복하려고했습니다.하지만 잘못된 캐스트 예외가 발생합니다. 이 같은

try 
{ 
    FramesCollection frames = myDocument.frames; 
    object index = 0; 
    IHTMLWindow2 frame = (IHTMLWindow2)frames.item(ref index); 
    var xx = (HTMLDocument)frame.document; 
    MessageBox.Show(xx.body.innerHTML); 
} 
catch (Exception ex) 
{ 
    MessageBox.Show(ex.Message); 
} 

도 코드 :

MessageBox.Show(myDocument.frames.length.ToString()); 

나에게 같은 캐스트 예외를 제공합니다.

답변

0

http://www.w3schools.com/jsref/prop_frame_contentwindow.asp에 따라 가지고있는 IE 버전에 따라 iframe 요소의 contentWindow 또는 contentDocument 속성을 통해 가능해야합니다. 그러나 작동시키지 못했지만 contentWindow는 일부 요소를 반환하지만 문서 속성이 없습니다. (내 경우에는 IE9).

잠시 전에이 질문이 게시되었으므로이 문제를 해결할 수 있었으면 좋겠습니까?

0

단일 스레드 아키텍처 (STA 스레드)를 사용하여 프레임 모음에 액세스 해보십시오. 그것은 프레임 내용을 확인한 기능적인 nunit 테스트에서 저에게 도움이되었습니다. 쓰레드 모델을 전환 할 때까지 동일한 캐스팅 오류가 발생했습니다.