home *** CD-ROM | disk | FTP | other *** search
- //==========================================================================;
- //
- // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
- // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
- // PURPOSE.
- //
- // Copyright (c) 1992 - 1996 Microsoft Corporation. All Rights Reserved.
- //
- //==========================================================================;
-
- #include <streams.h>
- #include <initguid.h>
- #include "textout.h"
-
- // setup data
- AMOVIESETUP_MEDIATYPE sudIpPinTypes =
- {
- &MEDIATYPE_Text, // MajorType
- &MEDIASUBTYPE_NULL // MintorType
- };
-
- AMOVIESETUP_PIN sudIpPin =
- {
- L"Input", // strName
- FALSE, // bRendererd
- FALSE, // bOutput
- FALSE, // bZero
- FALSE, // bMany
- &CLSID_NULL, // connects to filter
- NULL, // connects to pin
- 1, // nMediaTypes
- &sudIpPinTypes // lpMediaType
- };
-
- AMOVIESETUP_FILTER sudTextoutAx =
- {
- &CLSID_TextRender, // clsID
- L"Text Display Filter", // strName
- MERIT_NORMAL, // dwMerit
- 1, // nPins
- &sudIpPin // lpPin
- };
-
- // List of class IDs and creator functions for the class factory. This
- // provides the link between the OLE entry point in the DLL and an object
- // being created. The class factory will call the static CreateInstance
- // function when it is asked to create a CLSID_VideoRenderer object
-
- CFactoryTemplate g_Templates[] = {
- {L"Text Display filter", &CLSID_TextRender, CTextOutFilter::CreateInstance},
- };
- int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);
-
-
- // exported entry points for registration and
- // unregistration (in this case they only call
- // through to default implmentations).
- //
- HRESULT DllRegisterServer()
- {
- return AMovieDllRegisterServer();
- }
-
- HRESULT DllUnregisterServer()
- {
- return AMovieDllUnregisterServer();
- }
-
-
-
-
- // Constructor for the text out renderer filter. After initialising the base
- // renderer class and our nested window handling class we have to pass our
- // input pin we have to the window class. The base class uses this to check
- // that the filter has a valid pin connection before allowing IVideoWindow
- // methods to be called (this is a stipulation of the interface set mainly
- // because most filters can't do anything before they know what data they
- // will be dealing with - an example being video renderers who can't really
- // support IVideoWindow fully until they know the size/format of the video)
-
- #pragma warning(disable:4355)
-
- CTextOutFilter::CTextOutFilter(LPUNKNOWN pUnk,HRESULT *phr) :
- CBaseRenderer(CLSID_TextRender, NAME("TextOut Filter"), pUnk, phr),
- m_TextWindow(NAME("Text properties"),GetOwner(),phr,&m_InterfaceLock,this)
- {
- m_TextWindow.SetControlWindowPin( GetPin(0) );
- }
-
-
- // Destructor
-
- CTextOutFilter::~CTextOutFilter()
- {
- }
-
-
- // This goes in the factory template table to create new instances
-
- CUnknown *CTextOutFilter::CreateInstance(LPUNKNOWN pUnk, HRESULT *phr)
- {
- CTextOutFilter *pTextOutFilter = new CTextOutFilter(pUnk,phr);
- if (pTextOutFilter == NULL) {
- return NULL;
- }
- return (CBaseMediaFilter *) pTextOutFilter;
- }
-
-
- //
- // GetSetupData
- //
- LPAMOVIESETUP_FILTER CTextOutFilter::GetSetupData()
- {
- return &sudTextoutAx;
- }
- // Overriden to say what interfaces we support and where
-
- STDMETHODIMP
- CTextOutFilter::NonDelegatingQueryInterface(REFIID riid,void **ppv)
- {
- CheckPointer(ppv,E_POINTER);
- if (riid == IID_IVideoWindow) {
- return m_TextWindow.NonDelegatingQueryInterface(riid,ppv);
- }
- return CBaseRenderer::NonDelegatingQueryInterface(riid,ppv);
- }
-
-
- STDMETHODIMP CTextOutFilter::Pause()
- {
- BOOL fStopToPause = (m_State == State_Stopped);
-
- HRESULT hr = CBaseRenderer::Pause();
- if(FAILED(hr))
- return hr;
-
- if(fStopToPause)
- {
- m_TextWindow.ActivateWindow();
- m_TextWindow.DoShowWindow(SW_SHOWNORMAL);
- }
- return hr;
- }
-
-
- // Deactivate the text out rendering window
-
- HRESULT CTextOutFilter::BreakConnect()
- {
- m_TextWindow.InactivateWindow();
- m_TextWindow.DoShowWindow(SW_HIDE);
- return NOERROR;
- }
-
-
- // Check that we can support a given proposed type
-
- HRESULT CTextOutFilter::CheckMediaType(const CMediaType *pmt)
- {
- #ifdef DEBUG
-
- const int iGUID_STRING = 128;
- OLECHAR szGUIDName[iGUID_STRING];
- DbgLog((LOG_TRACE,1,TEXT("Checking input media type....")));
-
- // Dump the GUID types
-
- if (pmt->majortype == MEDIATYPE_Text) {
- DbgLog((LOG_TRACE,1,TEXT("Major type MEDIATYPE_Text")));
- } else {
- StringFromGUID2(pmt->majortype,szGUIDName,iGUID_STRING);
- DbgLog((LOG_TRACE,1,TEXT("Major type %ls"),szGUIDName));
- }
-
- StringFromGUID2(pmt->subtype,szGUIDName,iGUID_STRING);
- DbgLog((LOG_TRACE,2,TEXT("Subtype %ls"),szGUIDName));
-
- #endif
-
- // Reject non-Text type
-
- if (pmt->majortype != MEDIATYPE_Text) {
- return E_INVALIDARG;
- }
- return NOERROR;
- }
-
-
- // This is called when the window thread receives a WM_PAINT message
-
- BOOL CTextOutFilter::OnPaint(COLORREF WindowColour)
- {
- CAutoLock cAutoLock(&m_RendererLock);
- RECT ClientRect;
- PAINTSTRUCT ps;
-
- BeginPaint(m_TextWindow.GetWindowHWND(),&ps);
- EndPaint(m_TextWindow.GetWindowHWND(),&ps);
-
- // Display the text if we have a sample
-
- if (m_pMediaSample) {
- DrawText(m_pMediaSample);
- return TRUE;
- }
-
- // Create a coloured brush to paint the window
-
- HBRUSH hBrush = CreateSolidBrush(WindowColour);
- EXECUTE_ASSERT(GetClientRect(m_TextWindow.GetWindowHWND(),&ClientRect));
- EXECUTE_ASSERT(FillRect(m_TextWindow.GetWindowHDC(),&ClientRect,hBrush));
- EXECUTE_ASSERT(DeleteObject(hBrush));
- return TRUE;
- }
-
-
- // This is called when a sample is ready for rendering
-
- HRESULT CTextOutFilter::DoRenderSample(IMediaSample *pMediaSample)
- {
- ASSERT(pMediaSample);
- DrawText(pMediaSample);
- return NOERROR;
- }
-
- // display an image if not streaming
- void CTextOutFilter::OnReceiveFirstSample(IMediaSample *pMediaSample)
- {
- if(IsStreaming() == FALSE)
- {
- ASSERT(pMediaSample);
- DrawText(pMediaSample);
- }
- }
-
-
- // This is called with an IMediaSample interface on the image to be drawn. We
- // are called from two separate code paths. The first is when we're signalled
- // that an image has become due for rendering, the second is when we need to
- // refresh a static window image. NOTE it is safe to check the type of buffer
- // allocator as to change it we must be inactive, which by definition means
- // we cannot have any samples available to render so we cannot be here
-
- void CTextOutFilter::DrawText(IMediaSample *pMediaSample)
- {
- BYTE *pText; // Pointer to image data
- RECT rcClip; // window rectangle
-
- SetRect(&rcClip, (LONG) 0, (LONG) 0,
- m_TextWindow.GetWindowWidth(),
- m_TextWindow.GetWindowHeight());
-
- pMediaSample->GetPointer(&pText);
- ASSERT(pText != NULL);
-
- // Ignore zero length samples
-
- if (pMediaSample->GetActualDataLength() == 0) {
- return;
- }
-
- // Remove trailing NULL from the text data
-
- ExtTextOut(m_TextWindow.GetWindowHDC(),
- 0, 0,
- ETO_OPAQUE | ETO_CLIPPED,
- &rcClip,
- (char *) pText,
- pMediaSample->GetActualDataLength() - 1,
- NULL);
-
- GdiFlush();
- }
-
-
- // Derived class handling window interactions. We did have the main renderer
- // object inheriting from CBaseControlWindow so that we didn't have to have
- // a separate class but that means there are two many classes derived from
- // CUnknown, so when in the final text out filter class you call something
- // like GetOwner it gets really confusing to know who is actually going to
- // be called. So in the end we made it a separate class for the window. We
- // have to specialise the base class to provide the PURE virtual method that
- // returns the class and window information (GetClassWindowStyles). We are
- // also interested in certain window messages like WM_PAINT and WM_NCHITTEST
-
- CTextOutWindow::CTextOutWindow(TCHAR *pName, // Object string
- LPUNKNOWN pUnk, // COM ownership
- HRESULT *phr, // OLE code
- CCritSec *pLock, // Interface lock
- CTextOutFilter *pRenderer) : // Main filter
-
- CBaseControlWindow(pRenderer,pLock,pName,pUnk,phr),
- m_pRenderer(pRenderer)
- {
- PrepareWindow();
- }
-
-
- // Destructor
-
- CTextOutWindow::~CTextOutWindow()
- {
- DoneWithWindow();
- }
-
-
- // This is a virtual method that does our derived class message handling
- // We should process the messages we are interested in and then call the
- // base class as appropriate - some messages we may not pass forward
-
- LRESULT CTextOutWindow::OnReceiveMessage(HWND hwnd, // Window handle
- UINT uMsg, // Message ID
- WPARAM wParam, // First parameter
- LPARAM lParam) // Other parameter
- {
- switch (uMsg) {
-
- // This tells us some of the window's client area has become exposed
- // If our connected filter is doing overlay work then we repaint the
- // background so that it will pick up the window clipping changes
-
- case WM_PAINT:
-
- m_pRenderer->OnPaint(RGB(0,0,0));
- return (LRESULT) 1;
-
- }
- return CBaseControlWindow::OnReceiveMessage(hwnd,uMsg,wParam,lParam);
- }
-
-
- // Overriding the WM_CLOSE handling to also signal EC_USERABORT
-
- BOOL CTextOutWindow::OnClose()
- {
- CBaseControlWindow::OnClose();
- m_pRenderer->NotifyEvent(EC_USERABORT,0,0);
- return TRUE;
- }
-
-
- // When we call PrepareWindow in our constructor it will call this method as
- // it is going to create the window to get our window and class styles. The
- // return code is the class name and must be allocated in static storage. We
- // specify a normal window during creation although the window styles as well
- // as the extended styles may be changed by the application via IVideoWindow
-
- LPTSTR CTextOutWindow::GetClassWindowStyles(DWORD *pClassStyles,
- DWORD *pWindowStyles,
- DWORD *pWindowStylesEx)
- {
- *pClassStyles = TextClassStyles;
- *pWindowStyles = TextWindowStyles;
- *pWindowStylesEx = (DWORD) 0;
- return TextClassName;
- }
-
-