具体的问题是这样的,在自己做的ocx里面用到了media player,编程语言是delphi7(或6),但是有两个问题始终解决不了,
一是media player无法随parent做resize,即使把media player的align设成client;
二是对运行时生成的media player变换uimode时,得到的media player的窗口大小总是不正确。   其实这两个问题在delphi中还是具有一定的普遍性的,不只是media player,凡是ocx都会遇到的,比如flash的ocx.  

 对于问题一,在大富翁论坛上有一个解决方案,就是在media player的parent的resize事件对media player中调用setfocus,或者DoObjectVerb(-1). 3年之前我也一直是这么做的,不过这种做法却是有问题的。因为setfocus,或者DoObjectVerb(-1)这2个调用会使media player的parent失去焦点,也就是说,在winxp下当你在放大或缩小一个窗口的时候,会发现拖了一下就拖不动了。所以这种解决方法只适合拖动时不显示窗口内容的情况,比如win2000以前的系统,而winxp系统默认是拖动不显示窗口内容的。   至于问题二也是最近才发现的,因为以前不需要在运行时改变media player的uimode。现象是当运行时改变media player的uimode时,得到的media player的窗口大小不是符合原来的大小,似乎总是回到一个默认大小,而且在切换过程中窗口会闪2次,当你再次以同样的值调用uimode时(比如按一个按钮),media player的窗口才回到正确的位置。但是这个问题又不能通过在代码中连续2次调用
uiMode = xx来解决,即使两次调用之间加了applicaion.processmessage也不行. 关于这个问题在大富翁论坛没有提及.   那这两个问题归根结底是什么问题,造成该问题的原因又是什么呢?通过2天大量的试验发现,这两个问题都是delphi对ole容器的实现不当造成的,原因很简单,在vb6中就不会出现这样的问题。因此,问题归根结底不是微软的错,而是borland的错!   说到borland,有让我想起了vcl的另外一个bug,那就是控件的parent属性。在vcl中,当你改变一个控件的parent时,vcl会先把该控件的数据先保存到一个memory stream中,然后将这个控件的窗口销毁,从parent的list中删除对这个控件的引用,然后在新的parent的list中加入对该控件的引用,最后,如果需要再重新creat这个控件的窗口。我实在不能理解borland为什么要这样做,他凭什么要对控件的窗口下毒手?并且是否控件的所有状态都得以保存,从而可以正确的被恢复?我试过,比如listview,被选中的item在换了parent之后就没有正确的显示。至于第一条就更严重了,比如我用media player播放一段视频,在换了parent之后发现视频竟然停止播放了,实在令人匪夷所思。而同样的操作在vb6里面就完全没问题。更加令人发指的是,对于这两个臭名昭著的bug,borland竟然视而不见,随着delphi6, delphi7的发布,问题依旧。使得程序员只能绕开parent,使用widnows.setparent来解决问题,从而丢失了align带来的便利。
在回到本文主要讨论的2个问题中来,说说这2个问题的解决,也确实有趣。问题最终是通过google,而不是百度,由外国程序员而不是中国程序员解决的。通过不断的更换关键词,终于在google中找到了一个挪威语写的帖子,虽然挪威语看不懂,但是代码看的懂,加上论坛表情符号,基本可以了解大概,一试,果然不假,第一个问题就此解决。为了了解当事人到底说了什么,又到google上找了一个可以将挪威语翻译成英语的网站,还行,虽然语句基本不连贯,对于我们这种读英文以词度意,而不看布局谋篇的,也基本受用。感觉,那是"相当"好!!!   最后,第二个问题也在第一个问题的提示下顺利解决。
问题一解决:
type TLocOleCtrl=Class(TOleControl);
procedure TForm1.FormResize(Sender: TObject);
begin
TLocOleCtrl(WindowsMediaPlayer1).OnPosRectChange(Rect(0,0,ClientWidth, ClientHeight));
end;