home *** CD-ROM | disk | FTP | other *** search
/ The Net: Ultimate Internet Guide / WWLCD1.ISO / mac / SiteBldr / AMOVIE / SDK / _SETUP / COMMON.Z / textout.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-16  |  10.7 KB  |  361 lines

  1. //==========================================================================;
  2. //
  3. //  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  4. //  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  5. //  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  6. //  PURPOSE.
  7. //
  8. //  Copyright (c) 1992 - 1996  Microsoft Corporation.  All Rights Reserved.
  9. //
  10. //==========================================================================;
  11.  
  12. #include <streams.h>
  13. #include <initguid.h>
  14. #include "textout.h"
  15.  
  16. // setup data
  17. AMOVIESETUP_MEDIATYPE sudIpPinTypes =
  18. {
  19.   &MEDIATYPE_Text,              // MajorType
  20.   &MEDIASUBTYPE_NULL            // MintorType
  21. };
  22.  
  23. AMOVIESETUP_PIN sudIpPin =
  24. {
  25.   L"Input",                     // strName
  26.   FALSE,                        // bRendererd
  27.   FALSE,                        // bOutput
  28.   FALSE,                        // bZero
  29.   FALSE,                        // bMany
  30.   &CLSID_NULL,                  // connects to filter
  31.   NULL,                         // connects to pin
  32.   1,                            // nMediaTypes
  33.   &sudIpPinTypes                // lpMediaType
  34. };
  35.  
  36. AMOVIESETUP_FILTER sudTextoutAx =
  37. {
  38.   &CLSID_TextRender,            // clsID
  39.   L"Text Display Filter",       // strName
  40.   MERIT_NORMAL,                 // dwMerit
  41.   1,                            // nPins
  42.   &sudIpPin                     // lpPin
  43. };
  44.  
  45. // List of class IDs and creator functions for the class factory. This
  46. // provides the link between the OLE entry point in the DLL and an object
  47. // being created. The class factory will call the static CreateInstance
  48. // function when it is asked to create a CLSID_VideoRenderer object
  49.  
  50. CFactoryTemplate g_Templates[] = {
  51.     {L"Text Display filter", &CLSID_TextRender, CTextOutFilter::CreateInstance},
  52. };
  53. int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);
  54.  
  55.  
  56. // exported entry points for registration and
  57. // unregistration (in this case they only call
  58. // through to default implmentations).
  59. //
  60. HRESULT DllRegisterServer()
  61. {
  62.   return AMovieDllRegisterServer();
  63. }
  64.  
  65. HRESULT DllUnregisterServer()
  66. {
  67.   return AMovieDllUnregisterServer();
  68. }
  69.  
  70.  
  71.  
  72.  
  73. // Constructor for the text out renderer filter. After initialising the base
  74. // renderer class and our nested window handling class we have to pass our
  75. // input pin we have to the window class. The base class uses this to check
  76. // that the filter has a valid pin connection before allowing IVideoWindow
  77. // methods to be called (this is a stipulation of the interface set mainly
  78. // because most filters can't do anything before they know what data they
  79. // will be dealing with - an example being video renderers who can't really
  80. // support IVideoWindow fully until they know the size/format of the video)
  81.  
  82. #pragma warning(disable:4355)
  83.  
  84. CTextOutFilter::CTextOutFilter(LPUNKNOWN pUnk,HRESULT *phr) :
  85.     CBaseRenderer(CLSID_TextRender, NAME("TextOut Filter"), pUnk, phr),
  86.     m_TextWindow(NAME("Text properties"),GetOwner(),phr,&m_InterfaceLock,this)
  87. {
  88.     m_TextWindow.SetControlWindowPin( GetPin(0) );
  89. }
  90.  
  91.  
  92. // Destructor
  93.  
  94. CTextOutFilter::~CTextOutFilter()
  95. {
  96. }
  97.  
  98.  
  99. // This goes in the factory template table to create new instances
  100.  
  101. CUnknown *CTextOutFilter::CreateInstance(LPUNKNOWN pUnk, HRESULT *phr)
  102. {
  103.     CTextOutFilter *pTextOutFilter = new CTextOutFilter(pUnk,phr);
  104.     if (pTextOutFilter == NULL) {
  105.         return NULL;
  106.     }
  107.     return (CBaseMediaFilter *) pTextOutFilter;
  108. }
  109.  
  110.  
  111. //
  112. // GetSetupData
  113. //
  114. LPAMOVIESETUP_FILTER CTextOutFilter::GetSetupData()
  115. {
  116.   return &sudTextoutAx;
  117. }
  118. // Overriden to say what interfaces we support and where
  119.  
  120. STDMETHODIMP
  121. CTextOutFilter::NonDelegatingQueryInterface(REFIID riid,void **ppv)
  122. {
  123.     CheckPointer(ppv,E_POINTER);
  124.     if (riid == IID_IVideoWindow) {
  125.         return m_TextWindow.NonDelegatingQueryInterface(riid,ppv);
  126.     }
  127.     return CBaseRenderer::NonDelegatingQueryInterface(riid,ppv);
  128. }
  129.  
  130.  
  131. STDMETHODIMP CTextOutFilter::Pause()
  132. {
  133.   BOOL fStopToPause = (m_State == State_Stopped);
  134.  
  135.   HRESULT hr = CBaseRenderer::Pause();
  136.   if(FAILED(hr))
  137.     return hr;
  138.  
  139.   if(fStopToPause)
  140.   {
  141.     m_TextWindow.ActivateWindow();
  142.     m_TextWindow.DoShowWindow(SW_SHOWNORMAL);
  143.   }
  144.   return hr;
  145. }
  146.  
  147.  
  148. // Deactivate the text out rendering window
  149.  
  150. HRESULT CTextOutFilter::BreakConnect()
  151. {
  152.     m_TextWindow.InactivateWindow();
  153.     m_TextWindow.DoShowWindow(SW_HIDE);
  154.     return NOERROR;
  155. }
  156.  
  157.  
  158. // Check that we can support a given proposed type
  159.  
  160. HRESULT CTextOutFilter::CheckMediaType(const CMediaType *pmt)
  161. {
  162. #ifdef DEBUG
  163.  
  164.     const int iGUID_STRING = 128;
  165.     OLECHAR szGUIDName[iGUID_STRING];
  166.     DbgLog((LOG_TRACE,1,TEXT("Checking input media type....")));
  167.  
  168.     // Dump the GUID types
  169.  
  170.     if (pmt->majortype == MEDIATYPE_Text) {
  171.     DbgLog((LOG_TRACE,1,TEXT("Major type MEDIATYPE_Text")));
  172.     } else {
  173.     StringFromGUID2(pmt->majortype,szGUIDName,iGUID_STRING);
  174.     DbgLog((LOG_TRACE,1,TEXT("Major type %ls"),szGUIDName));
  175.     }
  176.  
  177.     StringFromGUID2(pmt->subtype,szGUIDName,iGUID_STRING);
  178.     DbgLog((LOG_TRACE,2,TEXT("Subtype %ls"),szGUIDName));
  179.  
  180. #endif
  181.  
  182.     // Reject non-Text type
  183.  
  184.     if (pmt->majortype != MEDIATYPE_Text) {
  185.     return E_INVALIDARG;
  186.     }
  187.     return NOERROR;
  188. }
  189.  
  190.  
  191. // This is called when the window thread receives a WM_PAINT message
  192.  
  193. BOOL CTextOutFilter::OnPaint(COLORREF WindowColour)
  194. {
  195.     CAutoLock cAutoLock(&m_RendererLock);
  196.     RECT ClientRect;
  197.     PAINTSTRUCT ps;
  198.  
  199.     BeginPaint(m_TextWindow.GetWindowHWND(),&ps);
  200.     EndPaint(m_TextWindow.GetWindowHWND(),&ps);
  201.  
  202.     // Display the text if we have a sample
  203.  
  204.     if (m_pMediaSample) {
  205.         DrawText(m_pMediaSample);
  206.         return TRUE;
  207.     }
  208.  
  209.     // Create a coloured brush to paint the window
  210.  
  211.     HBRUSH hBrush = CreateSolidBrush(WindowColour);
  212.     EXECUTE_ASSERT(GetClientRect(m_TextWindow.GetWindowHWND(),&ClientRect));
  213.     EXECUTE_ASSERT(FillRect(m_TextWindow.GetWindowHDC(),&ClientRect,hBrush));
  214.     EXECUTE_ASSERT(DeleteObject(hBrush));
  215.     return TRUE;
  216. }
  217.  
  218.  
  219. // This is called when a sample is ready for rendering
  220.  
  221. HRESULT CTextOutFilter::DoRenderSample(IMediaSample *pMediaSample)
  222. {
  223.     ASSERT(pMediaSample);
  224.     DrawText(pMediaSample);
  225.     return NOERROR;
  226. }
  227.  
  228. // display an image if not streaming
  229. void CTextOutFilter::OnReceiveFirstSample(IMediaSample *pMediaSample)
  230. {
  231.   if(IsStreaming() == FALSE)
  232.   {
  233.     ASSERT(pMediaSample);
  234.     DrawText(pMediaSample);
  235.   }
  236. }
  237.  
  238.  
  239. // This is called with an IMediaSample interface on the image to be drawn. We
  240. // are called from two separate code paths. The first is when we're signalled
  241. // that an image has become due for rendering, the second is when we need to
  242. // refresh a static window image. NOTE it is safe to check the type of buffer
  243. // allocator as to change it we must be inactive, which by definition means
  244. // we cannot have any samples available to render so we cannot be here
  245.  
  246. void CTextOutFilter::DrawText(IMediaSample *pMediaSample)
  247. {
  248.     BYTE *pText;        // Pointer to image data
  249.     RECT rcClip;        // window rectangle
  250.  
  251.     SetRect(&rcClip, (LONG) 0, (LONG) 0,
  252.             m_TextWindow.GetWindowWidth(),
  253.             m_TextWindow.GetWindowHeight());
  254.  
  255.     pMediaSample->GetPointer(&pText);
  256.     ASSERT(pText != NULL);
  257.  
  258.     // Ignore zero length samples
  259.  
  260.     if (pMediaSample->GetActualDataLength() == 0) {
  261.         return;
  262.     }
  263.  
  264.     // Remove trailing NULL from the text data
  265.  
  266.     ExtTextOut(m_TextWindow.GetWindowHDC(),
  267.            0, 0,
  268.            ETO_OPAQUE | ETO_CLIPPED,
  269.            &rcClip,
  270.            (char *) pText,
  271.            pMediaSample->GetActualDataLength() - 1,
  272.            NULL);
  273.  
  274.     GdiFlush();
  275. }
  276.  
  277.  
  278. // Derived class handling window interactions. We did have the main renderer
  279. // object inheriting from CBaseControlWindow so that we didn't have to have
  280. // a separate class but that means there are two many classes derived from
  281. // CUnknown, so when in the final text out filter class you call something
  282. // like GetOwner it gets really confusing to know who is actually going to
  283. // be called. So in the end we made it a separate class for the window. We
  284. // have to specialise the base class to provide the PURE virtual method that
  285. // returns the class and window information (GetClassWindowStyles). We are
  286. // also interested in certain window messages like WM_PAINT and WM_NCHITTEST
  287.  
  288. CTextOutWindow::CTextOutWindow(TCHAR *pName,                // Object string
  289.                                LPUNKNOWN pUnk,              // COM ownership
  290.                                HRESULT *phr,                // OLE code
  291.                                CCritSec *pLock,             // Interface lock
  292.                                CTextOutFilter *pRenderer) : // Main filter
  293.  
  294.     CBaseControlWindow(pRenderer,pLock,pName,pUnk,phr),
  295.     m_pRenderer(pRenderer)
  296. {
  297.     PrepareWindow();
  298. }
  299.  
  300.  
  301. // Destructor
  302.  
  303. CTextOutWindow::~CTextOutWindow()
  304. {
  305.     DoneWithWindow();
  306. }
  307.  
  308.  
  309. // This is a virtual method that does our derived class message handling
  310. // We should process the messages we are interested in and then call the
  311. // base class as appropriate - some messages we may not pass forward
  312.  
  313. LRESULT CTextOutWindow::OnReceiveMessage(HWND hwnd,         // Window handle
  314.                                          UINT uMsg,         // Message ID
  315.                                          WPARAM wParam,     // First parameter
  316.                                          LPARAM lParam)     // Other parameter
  317. {
  318.     switch (uMsg) {
  319.  
  320.         // This tells us some of the window's client area has become exposed
  321.         // If our connected filter is doing overlay work then we repaint the
  322.         // background so that it will pick up the window clipping changes
  323.  
  324.         case WM_PAINT:
  325.  
  326.             m_pRenderer->OnPaint(RGB(0,0,0));
  327.             return (LRESULT) 1;
  328.  
  329.     }
  330.     return CBaseControlWindow::OnReceiveMessage(hwnd,uMsg,wParam,lParam);
  331. }
  332.  
  333.  
  334. // Overriding the WM_CLOSE handling to also signal EC_USERABORT
  335.  
  336. BOOL CTextOutWindow::OnClose()
  337. {
  338.     CBaseControlWindow::OnClose();
  339.     m_pRenderer->NotifyEvent(EC_USERABORT,0,0);
  340.     return TRUE;
  341. }
  342.  
  343.  
  344. // When we call PrepareWindow in our constructor it will call this method as
  345. // it is going to create the window to get our window and class styles. The
  346. // return code is the class name and must be allocated in static storage. We
  347. // specify a normal window during creation although the window styles as well
  348. // as the extended styles may be changed by the application via IVideoWindow
  349.  
  350. LPTSTR CTextOutWindow::GetClassWindowStyles(DWORD *pClassStyles,
  351.                                             DWORD *pWindowStyles,
  352.                                             DWORD *pWindowStylesEx)
  353. {
  354.     *pClassStyles = TextClassStyles;
  355.     *pWindowStyles = TextWindowStyles;
  356.     *pWindowStylesEx = (DWORD) 0;
  357.     return TextClassName;
  358. }
  359.  
  360. 
  361.