home *** CD-ROM | disk | FTP | other *** search
/ ...taking it to the Macs! / ...taking it to the Macs!.iso / Extras / ActiveX Mac SDK / ActiveX SDK / Sample Controls / MoviePlayer / CMovieControl.cpp next >
Encoding:
Text File  |  1996-12-14  |  9.4 KB  |  410 lines  |  [TEXT/????]

  1. // =================================================================================
  2. //
  3. //    CMovieControl.cpp                ©1996 Microsoft Corporation All rights reserved.
  4. //
  5. // =================================================================================
  6.  
  7. #include "ocheaders.h"
  8. #include "CMovieControl.h"
  9.  
  10. const Int32        DefaultIdleTime        = IdleAfterAllEvents;
  11. const Uint32    DefaultIdleRefCon    = 1;
  12.  
  13. OLECHAR g_szBSCBHolder[] = "_BSCB_Holder";
  14. OLECHAR g_szEnumFORMATETC[] = "_EnumFORMATETC_";
  15.  
  16.  
  17. #pragma mark === CBaseControl::Construction & Destruction ===
  18.  
  19. //
  20. //  CMovieControl::CMovieControl
  21. //
  22.  
  23. CMovieControl::CMovieControl(void)
  24. {
  25.     mMovie = NULL;
  26.     mEnterMoviesCount = 0;
  27.     mDrawnOnce = false;
  28.     mMovieState = MovieLoading;
  29.     mPosterPict = NULL;
  30. }
  31.  
  32.  
  33. //
  34. //  CMovieControl::~CMovieControl
  35. //
  36.  
  37. CMovieControl::~CMovieControl()
  38. {
  39.     if (mUnkForRelease)
  40.         mUnkForRelease->Release();
  41.     mContainerSiteP->SetIdleTime(RemoveIdler, DefaultIdleRefCon);
  42.     while (mEnterMoviesCount--)
  43.         ::ExitMovies();
  44. }
  45.  
  46.  
  47. #pragma mark === CMovieControl::IUnknown ===
  48.  
  49. //
  50. //  CMovieControl::IUnknown::QueryInterface
  51. //
  52. //  Returns a pointer to the specified interface on a component to which a
  53. //  client currently holds an interface pointer.
  54. //
  55.  
  56. STDMETHODIMP
  57. CMovieControl::QueryInterface(REFIID inRefID, void** outObj)
  58. {
  59.     if ( inRefID == IID_IBindStatusCallback ) 
  60.         return CBaseBindStatusCallback::QueryInterface(inRefID, outObj);
  61.     else
  62.         return CBaseControl::QueryInterface(inRefID, outObj);
  63. }
  64.  
  65.  
  66. #pragma mark === CMovieControl::IControl ===
  67.  
  68. //
  69. //  CMovieControl::IControl::Draw
  70. //
  71.  
  72. STDMETHODIMP
  73. CMovieControl::Draw(DrawContext* inContext)
  74. {
  75.     if (inContext->DrawAspect != DVASPECT_CONTENT)
  76.         return DV_E_DVASPECT;
  77.  
  78.     ::FrameRect(&inContext->Location);
  79.     if ( mMovie && ((mMovieState == MovieReady) || 
  80.             ((inContext->ContextID != mActiveContext->GetContextID()) && (mMovieState == MoviePlaying)) ))
  81.         DrawMovie(inContext->Port, &inContext->Location);
  82.     
  83.     mDrawnOnce = true;    // Flag that we have been drawn at least once
  84.     
  85.     return S_OK;
  86. }
  87.  
  88.  
  89. //
  90. //  CMovieControl::IControl::DoMouse
  91. //
  92.  
  93. STDMETHODIMP
  94. CMovieControl::DoMouse(MouseEventType inMouseET, PlatformEvent* Event)
  95. {
  96. #pragma unused(Event)
  97.  
  98.     switch (inMouseET) 
  99.     {
  100.         case MouseDown:
  101.             // if the movie has been loaded, process the click
  102.             if ( mMovieState == MovieReady )
  103.                 StartIdling();
  104.             break;
  105.     }
  106.  
  107.     return S_OK;
  108. }
  109.  
  110.  
  111.  
  112. //
  113. //  CMovieControl::IControl::DoIdle
  114. //
  115.  
  116. STDMETHODIMP
  117. CMovieControl::DoIdle(Uint32 IdleRefCon)
  118. {
  119.     DrawContext Context = {BeginPortType};
  120.     
  121. #pragma unused(IdleRefCon)
  122.  
  123.     if (mContainerSiteP->AcquireContext(mActiveContext->GetContextID(), &Context) == S_OK)
  124.     {
  125.         switch ( mMovieState )
  126.         {
  127.             case MovieLoaded:    // Movie is loaded, initialize the movie
  128.                 InitMovie(&mMovieSpec, &mMovieSize, &Context.Location);
  129.             
  130.             case MovieReady:    // Movie is ready to play
  131.                 if ( mDrawnOnce )    // wait until we've been drawn at least once
  132.                 {
  133.                     ::SetMovieClipRgn (mMovie, Context.Port->clipRgn);
  134.  
  135.                     // Go to beginning of movie and play it
  136.                     ::GoToBeginningOfMovie(mMovie);
  137.                     ::StartMovie(mMovie);
  138.                     
  139.                     mMovieState = MoviePlaying;
  140.                 }
  141.                 break;
  142.             
  143.             case MoviePlaying:
  144.                 // Give the movie time
  145.                 ::MoviesTask(mMovie, DoTheRightThing);
  146.                 
  147.                 // if we're at the end of the movie, unschedule ourselves
  148.                 if ( IsMovieDone(mMovie) )
  149.                 {
  150.                     mMovieState = MovieReady;
  151.                     DrawMovie(Context.Port, &Context.Location);
  152.                     StopIdling();
  153.                 }
  154.  
  155.                 break;
  156.                 
  157.         }
  158.         
  159.         mContainerSiteP->ReleaseContext(&Context);
  160.     }
  161.  
  162.     return S_OK;
  163. }
  164.  
  165.  
  166.  
  167. #pragma mark === CMovieControl::IPersistPropertyBag ===
  168.  
  169. //
  170. //  CMovieControl::IPersistPropertyBag::Load
  171. //
  172.  
  173. STDMETHODIMP
  174. CMovieControl::Load(IPropertyBag* PropertyBag, IErrorLog* ErrorLog)
  175. {
  176.     ErrorCode            ErrCode = E_FAIL;
  177.  
  178.     LoadTextState(PropertyBag, ErrorLog);
  179.     
  180.     ErrCode = OpenStream(mContainerSiteP, (char*)mDataURL, TRUE);
  181.     return ErrCode;
  182. }
  183.  
  184.  
  185. //=--------------------------------------------------------------------------=
  186. // CPictControl::LoadTextState
  187. //=--------------------------------------------------------------------------=
  188. // load in our text state for this control.
  189. //
  190. // Parameters:
  191. //    IPropertyBag *        - [in] property bag to read from
  192. //    IErrorLog *           - [in] errorlog object to use with proeprty bag
  193. //
  194. // Output:
  195. //    ErrorCode
  196. //
  197. STDMETHODIMP CMovieControl::LoadTextState(IPropertyBag *PropertyBag, IErrorLog *ErrorLog)
  198. {
  199.     VARIANT        v;
  200.     Uint32        length;
  201.  
  202. //    VariantInit(&v);
  203.  
  204.     v.vt = VT_BSTR;
  205.     v.bstrVal = NULL;
  206.  
  207.     // try to load in the property.  if we can't get it, then leave
  208.     // things at their default.
  209.     //
  210.     PropertyBag->Read("data", &v, ErrorLog);
  211.     if (v.bstrVal)
  212.     {
  213.         length = *((Uint32*) v.bstrVal) ;
  214.         strcpy((Char8*)mDataURL, v.bstrVal + sizeof(Uint32));
  215.         CoTaskMemFree(v.bstrVal);
  216. //        VariantInit(&v);
  217.     }
  218.  
  219.     return S_OK;
  220. }
  221.  
  222.  
  223. #pragma mark === CMovieControl::IBindStatusCallback ===
  224.  
  225. //
  226. //  CMovieControl::OnDataAvailable
  227. //
  228.  
  229. STDMETHODIMP
  230. CMovieControl::OnDataAvailable(Uint32 BSCF, Uint32 Size, FORMATETC* FormatEtc, STGMEDIUM* StgMedium)
  231. {
  232.     OSErr Err = noErr;
  233.     
  234.     CBaseBindStatusCallback::OnDataAvailable(BSCF, Size, FormatEtc, StgMedium);
  235.     
  236.     if (StgMedium->tymed == TYMED_FILE)
  237.     {
  238.         Str255 FileName;
  239.         
  240.         FileName[0] = strlen(StgMedium->lpszFileName);
  241.         strncpy((Char8*)&FileName[1], StgMedium->lpszFileName, FileName[0]);
  242.         FSMakeFSSpec(0, 0, FileName, &mMovieSpec);
  243.         mMovieState = MovieLoaded;
  244.         
  245.         CoTaskMemFree(StgMedium->lpszFileName);
  246.     }
  247.     else if (StgMedium->tymed == TYMED_FSP)
  248.     {
  249.         BlockMove(StgMedium->pFSSpec, &mMovieSpec, sizeof(FSSpec));
  250.         CoTaskMemFree(StgMedium->pFSSpec);
  251.         mMovieState = MovieLoaded;
  252.     }
  253.     #ifdef _DEBUG
  254.     else if (StgMedium->tymed == TYMED_ISTREAM)
  255.     {
  256.         Debugger();
  257.     }
  258.     #endif
  259.     
  260.     mUnkForRelease = StgMedium->pUnkForRelease;
  261.  
  262.     //    if we have what we think is a valid movie file then play it right away
  263.     if (mMovieState == MovieLoaded)
  264.         mContainerSiteP->SetIdleTime(DefaultIdleTime, DefaultIdleRefCon);
  265.  
  266.     return S_OK;
  267. }
  268.  
  269.  
  270. #pragma mark === CMovieControl::CBaseControl overrides ===
  271.  
  272. //
  273. //    CMovieControl::CBaseControl::StartIdling [virtual]
  274. //
  275.  
  276. Boolean8
  277. CMovieControl::StartIdling(void)
  278. {
  279.     Boolean8    Result = false;
  280.  
  281.     if (mMovieState == MovieReady)
  282.         Result = mContainerSiteP->SetIdleTime(DefaultIdleTime, DefaultIdleRefCon) == S_OK;
  283.  
  284.     return Result;
  285. }
  286.  
  287.  
  288. //
  289. //    CMovieControl::CBaseControl::StopIdling [virtual]
  290. //
  291.  
  292. Boolean8
  293. CMovieControl::StopIdling(void)
  294. {
  295.     Boolean8    Result = false;
  296.  
  297.     if (mMovieState == MoviePlaying)
  298.         ::StopMovie(mMovie);
  299.     
  300.     return CBaseControl::StopIdling();
  301. }
  302.  
  303.  
  304. #pragma mark === CMovieControl ===
  305.  
  306. //
  307. //  CMovieControl::InitMovie
  308. //
  309.  
  310. Boolean8 CMovieControl::InitMovie(FSSpec* MovieSpec, Point* outMovieSizeP, Rect* inLocationP)
  311. {
  312.     Int16                movieResRefNum;
  313.     Int16                 actualResId;
  314.     OSErr                 err = noErr;
  315.     Rect                theRect;
  316.  
  317.     if ((err = ::EnterMovies()) == noErr)
  318.     {
  319.         mEnterMoviesCount++;
  320.         if ((err = ::OpenMovieFile(MovieSpec, &movieResRefNum, fsRdPerm)) == noErr && movieResRefNum != 0)
  321.         {
  322.             actualResId = DoTheRightThing;
  323.             if ((err = ::NewMovieFromFile(&mMovie, movieResRefNum, &actualResId, NULL, newMovieActive, (Boolean *)0)) == noErr)
  324.             {
  325.                 if ( (err = ::CloseMovieFile(movieResRefNum)) == noErr)
  326.                 {
  327.                     ::GetMovieBox(mMovie, &theRect);
  328.                     outMovieSizeP->h = theRect.right - theRect.left;
  329.                     outMovieSizeP->v = theRect.bottom - theRect.top;
  330.  
  331.                     theRect.top = inLocationP->top;
  332.                     theRect.left = inLocationP->left;
  333.                     theRect.bottom = inLocationP->top + outMovieSizeP->v;
  334.                     theRect.right = inLocationP->left + outMovieSizeP->h;
  335.                     ::SetMovieGWorld(mMovie, nil, 0);
  336.                     ::SetMovieBox(mMovie, &theRect);
  337.                     if ((err = ::GetMoviesError()) == noErr)
  338.                     {
  339.                         mMovieState = MovieReady;
  340.                         mPosterPict = ::GetMoviePosterPict(mMovie);
  341.                     }
  342.                 }
  343.             }
  344.         }
  345.     }
  346.  
  347.     return mMovie != NULL;
  348. }
  349.  
  350.  
  351. //
  352. //  CMovieControl::DrawMovie
  353. //
  354.  
  355. void     CMovieControl::DrawMovie(GrafPtr DrawPort, Rect* inLocationP)
  356. {
  357. #pragma unused (DrawPort)
  358.     if (mPosterPict)
  359.     {
  360.         Rect theRect;
  361.  
  362.         theRect.top = inLocationP->top;
  363.         theRect.left = inLocationP->left;
  364.         theRect.bottom = inLocationP->top + mMovieSize.v;
  365.         theRect.right = inLocationP->left + mMovieSize.h;
  366.  
  367.         ::DrawPicture(mPosterPict, &theRect);
  368.     }
  369. }
  370.  
  371. //=--------------------------------------------------------------------------=
  372. //  CMovieContextInfo::CMovieControl::NewContext    
  373. //=--------------------------------------------------------------------------=
  374. CBaseContextInfo*
  375. CMovieControl::NewContext(Uint32 inContextID)
  376. {
  377.     CMovieContextInfo*    ContextInfo = new CMovieContextInfo(this, inContextID);
  378.  
  379.     return ContextInfo;
  380. }
  381.  
  382. //=--------------------------------------------------------------------------=
  383. //    CMovieContextInfo::CMovieContextInfo    
  384. //=--------------------------------------------------------------------------=
  385. CMovieContextInfo::CMovieContextInfo(CMovieControl* inControlP, Uint32 inContextID) :
  386.         CBaseContextInfo (inControlP, inContextID)
  387. {
  388.     mMovieControl = inControlP;
  389. }
  390.  
  391. //=--------------------------------------------------------------------------=
  392. //    CMovieContextInfo::Update    
  393. //=--------------------------------------------------------------------------=
  394. ErrorCode
  395. CMovieContextInfo::Update(Boolean8 Acquired)
  396. {
  397. #pragma unused (Acquired)
  398.     if(mMovieControl->mMovieState == MoviePlaying && mContextID == mMovieControl->mActiveContext->GetContextID())
  399.     {
  400.         DrawContext Context = {BeginPortType};
  401.         
  402.         if (mMovieControl->mContainerSiteP->AcquireContext(mContextID, &Context) == S_OK)
  403.         {
  404.             ::SetMovieClipRgn (mMovieControl->mMovie, Context.Port->clipRgn);
  405.             mMovieControl->mContainerSiteP->ReleaseContext(&Context);
  406.         }
  407.     }
  408.     return S_OK;
  409. }
  410.