所有ActiveX控件都会发生这种情况。如果我使用DeferWindowPos重新定位ActiveX控件
HDWP hdwp = BeginDeferWindowPos(1);
DeferWindowPos(hdwp, m_pActiveX->GetSafeHwnd(), NULL, left, top, width, height, SWP_NOZORDER);
EndDeferWindowPos(hdwp);
它去那里但是当你点击控件里面的任何地方后移动/调整大小到它的旧矩形。如果我改用MoveWindow
m_pActiveX->MoveWindow(left, top, width, height);
这不会发生。
任何其他类型的控件都不会发生这种情况,只能使用ActiveX控件,但它会发生在所有控件上。我做了一个测试,以确认这一点,创建一个新的ActiveX控件项目,并没有做任何更改,问题仍然存在。
答案 0 :(得分:6)
你从来没有得到合适的答案。我试着在这里帮忙。
问题是MFC隐藏了很多在其框架内托管ActiveX控件的技巧。具体来说,如果您进入MoveWindow调用,它不仅仅是Win32 MoveWindow函数的包装器。它调用OLE控件容器支持类。这基本上说,如果我们有一个控制站点接口,那么调用COleControlSite :: MoveWindow,否则调用标准的Win32 MoveWindow。 CWnd等处理的其他几个窗口函数也是如此。例如,COleControlSite :: SetWindowPos处理隐藏/显示控件,然后调用COleControlSite :: MoveWindow移动它,然后最后调用:: SetWindowPos(带有move / show标志)掩盖了其余部分。
在COleControlSite :: MoveWindow中,你会发现它做了几件事:它调用SetExtent,更新它的内部m_rect成员,然后调用SetObjectRects。
直接使用Win32 API绕过这些ActiveX控件(例如通过DeferWindowPos)会导致错过一些关键步骤。根据您的代码的布局方式,通常您可以自己处理。
答案 1 :(得分:1)
什么是 此 ActiveX控件?
除此之外,考虑DeferWindowPos用于同时定位多个窗口。这个概念是你输入begin语句,为新布局改变一堆窗口位置,然后结束实际移动并应用新的位置和大小。
如果您不更新多个窗口,请考虑使用SetWindowPos。
另请注意,在推迟时,您可能会收到移动,调整大小或更改窗口位置的消息。为了防止这种情况,如果发生这种情况,请在每次调用SWP_NOSENDCHANGING
时通过DeferWindowPos
标志,以便不发送或处理消息并清除收到的WINDOWPOS
结构中的所有位以防止不必要的变化。
此调用也可能失败......您是否正在检查返回值?