TMediaPlay中有一個Display屬性,它是TWinControl類型,TWinControl是第一個擁有窗口句柄(Handle)的VCL類,TMediaPlay就是利用這個Handle所Handle的窗口區域播放。
如果我們把Handle指向桌面,哪TMediaPlay將會在桌面播放。與TCanvas不同的是,TWinControl的Handle的屬性是只讀的,並且GetHandle方法是靜態方法,這說明,我們要Handle指向桌面只有兩種方法
修改TWinControl,讓Handle可寫。
建立TWinControl子類,並隱藏TWinControl.GetHandle方法,在新方法中返回桌面句柄。
其中第二種方法比較好.
TSurpriseDisplay=class(TWinControl)
protected
function GetHandle:HWnd;virtual;
public
property Handle: HWnd read GetHandle;
end;
其中GetHandle被定義為virtual,這樣可以方便繼承。因為這裡只是隱藏了TWinControl.GetHandle方法,所以當把這個子類賦給TMediaPlay.Display時,它會被強制轉換成父類,並調用其GetHandle方法,這樣達不到我們的目的。所以我對TMediaPlay作了一點修改,增強其功能,修改後的TMediaPlay完全與原來的兼容.
原代碼:
{setting a TWinControl to display video devices' output}
procedure TMediaPlayer.SetDisplay( Value: TWinControl );
var
AWindowParm: TMCI_Anim_Window_Parms;
begin
if (Value <> nil) and MCIOpened and FHasVideo then
begin
FFlags := mci_Wait or mci_Anim_Window_hWnd;
AWindowParm.Wnd := Longint(Value.Handle);
................
end;
修改後
{setting a TWinControl to display video devices' output}
procedure TMediaPlayer.SetDisplay( Value: TWinControl );
var
AWindowParm: TMCI_Anim_Window_Parms;
wnd:HWND;
begin
if (Value <> nil) and MCIOpened and FHasVideo then
begin
FFlags := mci_Wait or mci_Anim_Window_hWnd;
//************************************************************
if Value is TSurpriseDisplay then
wnd:=TSurpriseDisplay(Value).Handle
else
wnd:=Value.Handle;
//************************************************************
AWindowParm.Wnd := Longint(wnd);
............
end;
雖然這種修改並不優美,但能最大限度地保證兼容。別一種修改方法是把TMediaPlay.Display改成TSurpriseDisplay類型,這樣可以保證安全。
使用方法:
使用桌面播放
只要在GetHandle中返回桌面句柄,並賦值給Display.
function TSurpriseDisplay.GetHandle:HWnd;
begin
Result:=GetDesktopWindow;
end;
mp.Display:=TSurpriseDisplay.Create(self);
用記事本播放
記得我在TSurpriseDisplay的GetHandle中聲明為virtual嗎,現在開始發揮它的威力了,寫一個類繼承自TSurpriseDisplay,覆蓋GetHandle方法,返回記事本句柄。
TNotepadDisplay=class(TSurpriseDisplay)
private
wnd:Hwnd;
protected
function GetHandle:HWnd;override;
end;
function TNotepadDisplay.GetHandle:HWnd;
begin
if wnd=0 then
begin
Winexec('notepad.exe',1);
wnd:=FindWindow('Notepad','無標題 - 記事本');
end;
result:=wnd;
end;
mp.Display:=TNotepadDisplay.Create(self);
類似地還可以實現各種播放方式。