解决Win7OCX内部无法发送自定义消息的debug

来源:互联网 发布:产品外观设计软件 编辑:程序博客网 时间:2024/06/16 12:10

PRB: ActiveX 控件窗口才创建在 Internet Explorer 中可见

  • Email
  • Print
注意:这篇文章是由无人工介入的微软自动的机器翻译软件翻译完成。微软很高兴能同时提供给您由人工翻译的和由机器翻译的文章, 以使您能使用您的语言访问所有的知识库文章。然而由机器翻译的文章并不总是完美的。它可能存在词汇,语法或文法的问题,就像是一个外国人在说中文时总是可能犯这样的错误。虽然我们经常升级机器翻译软件以提高翻译质量,但是我们不保证机器翻译的正确度,也不对由于内容的误译或者客户对它的错误使用所引起的任何直接的, 或间接的可能的问题负责。

点击这里察看该文章的英文版: 195188
本文已归档。它按“原样”提供,并且不再更新。
症状
ActiveX 控件的 WM_CREATE 调用处理程序不在 Internet Explorer 4.01 直到控件滚动到视图中 (在 MFC 中,OnCreate() 是 WM_CREATE 处理程序)。如果该控件具有一个大小为 0,0,将出现同样的问题。如果您将创建子窗口在 WM_CREATE 处理程序,它们将不会存在。如果您有从脚本 (例如 Window_Onload) 操纵控件的 HWND 或其子窗口调用自动化方法,则会断言在调试模式下在 MFC 中读取以下行 ︰
   ASSERT(::IsWindow(m_hWnd));
或在 ATL 中 ︰
   ATLASSERT(::IsWindow(m_hWnd));
原因
Internet Explorer 4.01 does 非就地激活控件才可见。这是一种优化,以减少内存占用和使用 ActiveX 控件中加速网页加载时间。MFC 和 ATL 之类的大多数 ActiveX 控件框架在就地激活过程中创建其控件窗口。因此,控件是可见的除非它将就地激活。如果不是在就地激活,将不会创建它。如果不创建它,则不会调用 WM_CREATE 处理程序。
解决方案
您可以解决方法这通过在 IOleObject::SetClientSite(),总是无论如何如果称为就地激活控件时创建控件窗口。

MFC

MFC 提供调用 COleControl::CreateControlWindow() 来创建控件的窗口的函数。MFC 的 IOleObject::SetClientSite() 实现调用 COleControl::OnSetClientSite()。向您 COleControl 派生的类中添加以下项 ︰
   // CMyControl is derived from COleControl.   void CMyControl::OnSetClientSite()   {      if (m_pClientSite)         // It doesn't matter who the parent window is or what the size of         // the window is because the control's window will be reparented         // and resized correctly later when it's in-place activated.         VERIFY (CreateControlWindow (::GetDesktopWindow(), CRect(0,0,0,0),                                      CRect(0,0,0,0)));      COleControl::OnSetClientSite();   }

ATL

ATL 还提供了一个名为 CComControl::CreateControlWindow() 的函数。
   // CMyControl is derived from CComControl   STDMETHOD(SetClientSite)(IOleClientSite *pClientSite)   {      if (pClientSite)      {         RECT rc = {0,0,0,0};         // Don't have access to the container's window so just use the         // desktop.  Window will be resized correctly during in-place         // activation.         HWND hWnd = CreateControlWindow(::GetDesktopWindow(), rc);         _ASSERT (hWnd);      }      return IOleObjectImpl<CMyControl>::SetClientSite (pClientSite);   }   HRESULT InPlaceActivate(LONG iVerb, const RECT* prcPosRect)   {      // Get the container's window.      _ASSERT (m_spClientSite);      LPOLEINPLACESITE pInPlaceSite = NULL;      HRESULT hr = m_spClientSite->QueryInterface(IID_IOleInPlaceSite,                                                  (void       **)&pInPlaceSite);      _ASSERT (SUCCEEDED (hr) && pInPlaceSite);      HWND hParent = NULL;      hr = pInPlaceSite->GetWindow (&hParent);      _ASSERT (SUCCEEDED (hr) && hParent);      pInPlaceSite->Release ();      // Set container window as our parent window      SetParent (hParent);      return CComControlBase::InPlaceActivate(iVerb, prcPosRect);   }
状态
此行为是设计使然。
更多信息
ActiveX 控件可以重新设计,可在任何时候需要一个窗口。

无窗口控件、 窗体控件在 Internet Explorer 中支持的 4.x 和 Visual C++ 4.2 或更高版本,采用第一种方法。

但是,它可能是极难或不可能重新设计现有的控件,在这些情况中工作。某些控制措施可能需要太多额外的代码来有效地不在窗口。对于此类控件,可以在解决方法部分中使用此替代方法。

如果 ActiveX 控件定位上的可见部分的 HTML 页,但控件的窗口仍未创建了,则从本文中讨论的一个不同的问题。该控件可能无窗口控件的默认值。
引用
有关为 Microsoft Internet Explorer 开发基于 Web 的解决方案的详细信息,请访问下面的 Microsoft 网站 ︰
http://msdn.microsoft.com/ie/

http://support.microsoft.com/iep

Warning: This article has been translated automatically

0 0
原创粉丝点击