📄 formrenderer.pas
字号:
(*********************************************************************
* *
* The contents of this file are used with permission, subject to *
* the Mozilla Public License Version 1.1 (the "License"); you may *
* not use this file except in compliance with the License. You may *
* obtain a copy of the License at *
* http://www.mozilla.org/MPL/MPL-1.1.html *
* *
* Software distributed under the License is distributed on an *
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or *
* implied. See the License for the specific language governing *
* rights and limitations under the License. *
* *
* (C) 2004 Milenko Mitrovic <dcoder@dsp-worx.de> *
* *
*********************************************************************)
{.$DEFINE DEBUG}
unit formRenderer;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, BaseClass, Direct3D9, DirectShow9, StdCtrls;
type
TfrmRenderer = class(TForm)
procedure FormCreate(Sender: TObject);
private
fWidth : integer;
fHeight : integer;
fFormat : TVideoInfoHeader;
fMessageDrain : hWnd;
protected
procedure WndProc(var Message: TMessage); override;
public
property MessageDrain : hWnd read fMessageDrain write fMessageDrain;
function DoSetWindowStyle(Style, WindowLong : LongInt) : HRESULT;
function DoGetWindowStyle(out Style : LongInt; WindowLong : LongInt) : HRESULT;
function DoShowWindow(ShowCmd: Longint): HResult;
procedure DoPaintWindow(Erase : Boolean);
procedure DoRenderSample(Sample : IMediaSample);
procedure DoInitializeDirectDraw(Info : PVideoInfoHeader);
end;
var
frmRenderer: TfrmRenderer;
implementation
{$R *.dfm}
function PossiblyEatMessage(hwndDrain : hWnd; Msg : Cardinal; wParam : WPARAM; lParam : LPARAM) : Boolean; stdcall;
begin
if ((hwndDrain <> 0) and not InSendMessage) then
begin
case Msg of
WM_CHAR,
WM_DEADCHAR,
WM_KEYDOWN,
WM_KEYUP,
WM_LBUTTONDBLCLK,
WM_LBUTTONDOWN,
WM_LBUTTONUP,
WM_MBUTTONDBLCLK,
WM_MBUTTONDOWN,
WM_MBUTTONUP,
WM_MOUSEACTIVATE,
WM_MOUSEMOVE,
// If we pass this on we don't get any mouse clicks
// WM_NCHITTEST,
WM_NCLBUTTONDBLCLK,
WM_NCLBUTTONDOWN,
WM_NCLBUTTONUP,
WM_NCMBUTTONDBLCLK,
WM_NCMBUTTONDOWN,
WM_NCMBUTTONUP,
WM_NCMOUSEMOVE,
WM_NCRBUTTONDBLCLK,
WM_NCRBUTTONDOWN,
WM_NCRBUTTONUP,
WM_RBUTTONDBLCLK,
WM_RBUTTONDOWN,
WM_RBUTTONUP,
WM_SYSCHAR,
WM_SYSDEADCHAR,
WM_SYSKEYDOWN,
WM_SYSKEYUP:
begin
{$IFDEF DEBUG}
DbgLog('Delphi Video Renderer: Forwarding Message $' + inttohex(Msg,8) + ' drain');
{$ENDIF}
PostMessage(hwndDrain, Msg, wParam, lParam);
Result := True;
Exit;
end;
end;
end;
Result := False;
end;
procedure TfrmRenderer.WndProc(var Message: TMessage);
begin
if PossiblyEatMessage(fMessageDrain,Message.Msg,Message.WParam,Message.LParam) then Exit;
case Message.Msg of
WM_ERASEBKGND:
begin
Message.Result := 0;
Exit;
end;
end;
inherited WndProc(Message);
end;
function TfrmRenderer.DoSetWindowStyle(Style, WindowLong : LongInt) : HRESULT;
var
WindowRect : TRect;
WindowFlags : Cardinal;
begin
// Set the new style flags for the window
SetWindowLong(Handle,WindowLong,Style);
WindowFlags := SWP_SHOWWINDOW or SWP_FRAMECHANGED or SWP_NOACTIVATE;
WindowFlags := WindowFlags or SWP_NOZORDER or SWP_NOSIZE or SWP_NOMOVE;
// Show the window again in the current position
if Visible then
begin
SetWindowPos(Handle, // Base window handle
HWND_TOP, // Just a place holder
0,0,0,0, // Leave size and position
WindowFlags); // Just draw it again
Result := NOERROR;
Exit;
end;
// Move the window offscreen so the user doesn't see the changes
MoveWindow(Handle, // Base window handle
GetSystemMetrics(SM_CXSCREEN), // Current desktop width
GetSystemMetrics(SM_CYSCREEN), // Likewise it's height
Width, // Use the same width
Height, // Keep height same to
True); // May as well repaint
// Now show the previously hidden window
SetWindowPos(Handle, // Base window handle
HWND_TOP, // Just a place holder
0,0,0,0, // Leave size and position
WindowFlags); // Just draw it again
ShowWindow(Handle,SW_HIDE);
if (ParentWindow > 0) then MapWindowPoints(HWND_DESKTOP,ParentWindow,WindowRect,2);
MoveWindow(Handle, // Base window handle
WindowRect.left, // Existing x coordinate
WindowRect.top, // Existing y coordinate
Width, // Use the same width
Height, // Keep height same to
True); // May as well repaint
Result := NOERROR;
end;
function TfrmRenderer.DoGetWindowStyle(out Style : LongInt; WindowLong : LongInt) : HRESULT;
begin
Style := GetWindowLong(Handle,WindowLong);
Result := NOERROR;
end;
function TfrmRenderer.DoShowWindow(ShowCmd: Longint): HResult;
begin
ShowWindow(Handle,ShowCmd);
Result := NOERROR;
end;
procedure TfrmRenderer.DoPaintWindow(Erase : Boolean);
begin
InvalidateRect(Handle,nil,Erase);
end;
procedure TfrmRenderer.DoRenderSample(Sample : IMediaSample);
var
Bits: PByte;
begin
Sample.GetPointer(Bits);
Canvas.Lock;
StretchDIBits(Canvas.Handle,
0, 0, ClientWidth, ClientHeight,
0, 0, FWidth, FHeight,
Bits, PBitmapInfo(@fFormat.bmiHeader)^,
DIB_RGB_COLORS, SRCCOPY);
Canvas.Unlock;
end;
procedure TfrmRenderer.DoInitializeDirectDraw(Info : PVideoInfoHeader);
begin
fFormat := Info^;
fWidth := Info.bmiHeader.biWidth;
fHeight := Info.bmiHeader.biHeight;
ClientWidth := fWidth;
ClientHeight := fHeight;
end;
procedure TfrmRenderer.FormCreate(Sender: TObject);
begin
fMessageDrain := 0;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -