//========================================================================
//TITLE:
// CMedia更新至v1.4.3
//AUTHOR:
// norains
//DATE:
// Friday 27-July-2007
//Environment:
// EVC4.0 + Windows CE 5.0 Standard SDK
//========================================================================
相对v1.2.0版本进行的改进:
1.增加GetMediaProperty函数获得的属性,增加如下属性:llDuration,llAvailableEarliest,llAvailableLatest.
2.增加如下函数:SetRate(),GetRate(),GetPositionCurrent(),SetPositionCurrent() ,GetDisplayMode()
3.改进之前一些函数的HRESULT值返回BOOL值的判定方法
4.增加SetVideoWindow()一个参数,以设置可以在窗口的任意位置为起点播放视频
5.改进SetDisplayMode()函数,当窗口句柄为空时,设置播放区域为0,并返回FALSE
6.改进SetNotifyWindow()函数,令其能够接收普通的窗口消息
7.Open()的参数改为const类型,更符合实际意义
v1.2.0版本及相关用法见:http://blog.csdn.net/norains/archive/2007/05/14/1609118.aspx
我们来看看具体更新了哪些功能:
1.MEDIAPROPERTY
增加了llDuration,llAvailableEarliest,llAvailableLatest属性,分别代表影片的时间长度,最早的可拖拽的时间位置,最早的可拖拽的时间位置.这个属性可以用在GetMediaProperty()函数中.
2.SetRate(),GetRate()
SetRate()设置当前的播放速率,"1"为正常速率,"2"即为两倍速,以此类推.
GetRate()获取当前播放的速率.
3.GetPositionCurrent(),SetPositionCurrent()
GetPositionCurrent():获取当前的时间位置,返回的时间值以100ns为基本单位.
SetPositionCurrent():设置播放的时间位置,该范围必须是llAvailableEarliest和llAvailableLatest之间的数值.
4.GetDisplayMode()
该函数用来获取当前的播放模式.
v1.4.3的完整代码如下:
/////////////////////////////////////////////////////////////////////// //Media.h: interface for the CMedia class. // //Version: // 1.4.3 //Date: // 2007.07.19 ////////////////////////////////////////////////////////////////////// #ifndef MEDIA_H #define MEDIA_H #include <mmsystem.h> #include <streams.h> //-------------------------------------------------------------------- //Macro define //The volume value #define MAX_VOLUME 0 #define MIN_VOLUME -10000 //The balance value #define MAX_BALANCE 10000 #define MIN_BALANCE -10000 //The flag means that the area is the whole window const RECT RC_WHOLE_WINDOWN_AREA = {0,0,0,0}; //-------------------------------------------------------------------- //Enum value enum DISPLAYMODE { //Fit to the play window size. How wide (height) the window is, how //is the move. Keep aspect ratio. DISP_FIT, //Not support.Stretch to the play window size. Don't keep the aspect ratio. DISP_STRETCH, //Full screen play. DISP_FULLSCREEN, //When the size of video is smaller than the play window, it displayes //as the video size. If it's bigger , it just like the DISP_FIT mode. DISP_NATIVE }; //-------------------------------------------------------------------- //The media file property typedef struct { //The volume range is –10,000 to 0. //Divide by 100 to get equivalent decibel value (for example –10,000 = –100 dB). LONG lVolume; //The value from –10,000 to 10,000 indicating the stereo balance //As with the Volume property, units correspond to .01 decibels (multiplied by –1 when plBalance is a positive value). //For example, a value of 1000 indicates –10 dB on the right channel and –90 dB on the left channel. LONG lBalance; //Width of the video LONG lWidth; //Height of the video LONG lHeight; //Approximate bit rate LONG lBitRate; //The length of time that the media stream will play. //The duration assumes normal playback speed, and it is therefore unaffected by the rate LONGLONG llDuration; //Earliest time that can be efficiently seeked to. LONGLONG llAvailableEarliest; //Latest time that can be efficiently seeked to LONGLONG llAvailableLatest; }MEDIAPROPERTY,*PMEDIAPROPERTY; //-------------------------------------------------------------------- class CMedia { public: DISPLAYMODE GetDisplayMode(); BOOL SetPositionCurrent(LONGLONG llPos); BOOL GetPositionCurrent(LONGLONG *pllPos); BOOL GetRate(double *pdRate); BOOL SetRate(double dRate); BOOL GetEvent(LONG *plEvCode, LONG *plParam1, LONG *plParam2); BOOL SetNotifyWindow(HWND hWnd, UINT wMsg,long lInstanceData); BOOL SetVolume(LONG lVolume, LONG lBalance = 0); BOOL SetDisplayMode(DISPLAYMODE mode); BOOL GetMediaProperty(PMEDIAPROPERTY pOutProperty); static CMedia * GetInstance(); void Close(); BOOL CheckVisibility(); BOOL SetVideoWindow(HWND hWndVideo,const RECT &rcDisp = RC_WHOLE_WINDOWN_AREA); BOOL Open(const TCHAR *pcszFileName); BOOL Stop(); BOOL Pause(); BOOL Play(); virtual ~CMedia(); protected: CMedia(); // Collection of interfaces IGraphBuilder *m_pGB; IMediaControl *m_pMC; IMediaEventEx *m_pME; IVideoWindow *m_pVW; IBasicAudio *m_pBA; IBasicVideo *m_pBV; IMediaSeeking *m_pMS; TCHAR m_szFileName[MAX_PATH]; HWND m_hWndVideo; //The window play video HWND m_hWndNotify; //The window notify BOOL m_bExitThrd; BOOL m_bThrdRunning; static CMedia * m_pInstance; DISPLAYMODE m_DispMode; DWORD m_dwCapability; RECT m_rcDisp; }; #endif //#ifndef MEDIA_H /////////////////////////////////////////////////////////////////////// // Media.cpp: implementation of the CMedia class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "Media.h" //======================================================================================================== //Link the .lib //The lib also is copy from "(InstallDir)WINCE500PUBLICDIRECTXSDKLIB" #pragma comment (lib,"Ole32.lib") #ifdef CPU_X86EM #pragma comment (lib,"./lib/X86em/Strmiids.lib") #pragma comment (lib,"./lib/X86em/Strmbase.lib") #endif #ifdef CPU_MIPSII #pragma comment (lib,"./lib/MIPSII/Strmiids.lib") #pragma comment (lib,"./lib/MIPSII/Strmbase.lib") #endif #ifdef CPU_ARM4I #pragma comment (lib,"./lib/ARM4I/Strmiids.lib") #pragma comment (lib,"./lib/ARM4I/Strmbase.lib") #endif //======================================================================================================== //---------------------------------------------------------------------------------------------- //Macro define //Default play mode #define DEFAULT_DISPLAY_MODE DISP_NATIVE //---------------------------------------------------------------------- //Initialize CMedia *CMedia::m_pInstance = NULL; //------------------------------------------------------------------------ ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CMedia::CMedia(): m_pGB(NULL), m_pMC(NULL), m_pME(NULL), m_pVW(NULL), m_pBA(NULL), m_pBV(NULL), m_pMS(NULL), m_hWndVideo(NULL), m_bExitThrd(TRUE), m_bThrdRunning(FALSE), m_DispMode(DEFAULT_DISPLAY_MODE), m_hWndNotify(NULL), m_rcDisp(RC_WHOLE_WINDOWN_AREA) { memset(m_szFileName,0,sizeof(m_szFileName)); } CMedia::~CMedia() { if(m_pInstance != NULL) { delete m_pInstance; m_pInstance = NULL; } } //------------------------------------------------------------ //Description: // Play the media file // When you call the function,you should call Open() before. // //------------------------------------------------------------- BOOL CMedia::Play() { // Run the graph to play the media file if(m_pMC == NULL) { return FALSE; } return SUCCEEDED(m_pMC->Run()); } //------------------------------------------------------------ //Description: // Pause. // When you call the function,you should call Open() before. // //------------------------------------------------------------- BOOL CMedia::Pause() { if(m_pMC == NULL) { return FALSE; } return SUCCEEDED(m_pMC->Pause()); } //------------------------------------------------------------ //Description: // Stop. // When you call the function,you should call Open() before. // //------------------------------------------------------------- BOOL CMedia::Stop() { if(m_pMC == NULL || m_pMS == NULL) { return FALSE; } HRESULT hr; hr = m_pMC->Stop(); SetPositionCurrent(0); return SUCCEEDED(hr); } //-------------------------------------------------------------------------- //Description: // Open the media file. When succeed in calling the function , //you should call the Close() to release the resource // //------------------------------------------------------------------------- BOOL CMedia::Open(const TCHAR *pcszFileName) { BOOL bResult = FALSE; if(_tcslen(pcszFileName) >= MAX_PATH) { goto END; } else { _tcscpy(m_szFileName,pcszFileName); //Check the file existing HANDLE hdFile = CreateFile(m_szFileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,NULL,NULL); if(hdFile == INVALID_HANDLE_VALUE) { //The file doesn't exist goto END; } else { CloseHandle(hdFile); } } // Initialize COM if(CoInitializeEx(NULL, COINIT_MULTITHREADED) != S_OK) { goto END; } // Get the interface for DirectShow's GraphBuilder if(CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&m_pGB) != S_OK) { goto END; } // Have the graph construct its the appropriate graph automatically if(m_pGB->RenderFile(m_szFileName, NULL) != NOERROR) { goto END; } // QueryInterface for DirectShow interfaces if(m_pGB->QueryInterface(IID_IMediaControl, (void **)&m_pMC) != NOERROR) { goto END; } if(m_pGB->QueryInterface(IID_IMediaEventEx, (void **)&m_pME) != NOERROR) { goto END; } if(m_pGB->QueryInterface(IID_IMediaSeeking, (void **)&m_pMS) != NOERROR) { goto END; } // Query for video interfaces, which may not be relevant for audio files if(m_pGB->QueryInterface(IID_IVideoWindow, (void **)&m_pVW) != NOERROR) { goto END; } if(m_pGB->QueryInterface(IID_IBasicVideo, (void **)&m_pBV) != NOERROR) { goto END; } if(CheckVisibility() == FALSE) { //It just be the audio file, and don't need video filter. // Relinquish ownership (IMPORTANT!) after hiding if(m_pVW != NULL) { m_pVW->put_Visible(OAFALSE); m_pVW->put_Owner(NULL); } if(m_pBV != NULL) { m_pBV->Release(); m_pBV = NULL; } if(m_pVW != NULL) { m_pVW->Release(); m_pVW = NULL; } } // Query for audio interfaces, which may not be relevant for video-only files if(m_pGB->QueryInterface(IID_IBasicAudio, (void **)&m_pBA) != NOERROR) { goto END; } //Set play mode SetDisplayMode(m_DispMode); //Get the capabilities of the media file. m_pMS->GetCapabilities(&m_dwCapability); bResult = TRUE; END: if(bResult == FALSE) { //Release the resource Close(); } return bResult; } //------------------------------------------------------------ //Description: // This method sets an owning parent for the video window. // //Parameters: // hWnd : [in] Handle of new owner window. // rcDisp: [in] The display area. If the parameter is not set, // it will be set as RC_WHOLE_WINDOWN_AREA which means thai // the whole window is for displaying the video. // //---------------------------------------------------------- BOOL CMedia::SetVideoWindow(HWND hWndVideo,const RECT &rcDisp) { m_hWndVideo = hWndVideo; m_rcDisp = rcDisp; if(m_pVW == NULL) { return FALSE; } if(FAILED(m_pVW->put_Owner((OAHWND)hWndVideo))) { return FALSE; } if(FAILED(m_pVW->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN))) { return FALSE; } //Set play mode in order to notify the displayed area return SetDisplayMode(m_DispMode); } //------------------------------------------------------------ //Description: // Check the file visibility // When you call the function,you should call Open() before. // //Parameters: // TRUE: Video // FALSE: It's not the video // //------------------------------------------------------------ BOOL CMedia::CheckVisibility() { if (!m_pVW) { //No VideoWindow interface. Assuming audio/MIDI file or unsupported video codec return FALSE; } if (!m_pBV) { //No BasicVideo interface. Assuming audio/MIDI file or unsupported video codec. return FALSE; } // If this is an audio-only clip, get_Visible() won't work. // // Also, if this video is encoded with an unsupported codec, // we won't see any video, although the audio will work if it is // of a supported format. long lVisible; return SUCCEEDED(m_pVW->get_Visible(&lVisible)); } //------------------------------------------------------------ //Description: // Release the resource which opened in the Open() // //------------------------------------------------------------ void CMedia::Close() { // Relinquish ownership (IMPORTANT!) after hiding if(m_pVW != NULL) { m_pVW->put_Visible(OAFALSE); m_pVW->put_Owner(NULL); } if(m_pMC != NULL) { m_pMC->Release(); m_pMC = NULL; } if(m_pME != NULL) { m_pME->SetNotifyWindow(NULL,NULL,NULL); m_pME->Release(); m_pME = NULL; } if(m_pMS != NULL) { m_pMS->Release(); m_pMS = NULL; } if(m_pBV != NULL) { m_pBV->Release(); m_pBV = NULL; } if(m_pBA != NULL) { m_pBA->Release(); m_pBA = NULL; } if(m_pVW != NULL) { m_pVW->Release(); m_pVW = NULL; } if(m_pGB != NULL) { m_pGB->Release(); m_pGB = NULL; } // Finished with COM memset(m_szFileName,0,sizeof(m_szFileName)); CoUninitialize(); } //------------------------------------------------------------ //Description: // Get the instance of object // //------------------------------------------------------------ CMedia * CMedia::GetInstance() { if(m_pInstance == NULL) { m_pInstance = new CMedia(); } return m_pInstance; } //------------------------------------------------------------ //Description: // Get the media file property. // When you call the function,you should call Open() before. // //------------------------------------------------------------ BOOL CMedia::GetMediaProperty(PMEDIAPROPERTY pOutProperty) { MEDIAPROPERTY prop = {0}; if(m_pBA == NULL && m_pBV == NULL && m_pMS == NULL) { return FALSE; } //Get the audio property if(m_pBA != NULL) { m_pBA->get_Volume(&prop.lVolume); m_pBA->get_Balance(&prop.lBalance); } //Get the video property if(CheckVisibility() == TRUE && m_pBV != NULL) { m_pBV->get_BitRate(&prop.lBitRate); m_pBV->GetVideoSize(&prop.lWidth,&prop.lHeight); } //Get the seeking property if(m_pMS != NULL) { m_pMS->GetDuration(&prop.llDuration); m_pMS->GetAvailable(&prop.llAvailableEarliest,&prop.llAvailableLatest); } *pOutProperty = prop; return TRUE; } //------------------------------------------------------------ //Description: // Set the display mode. // When you call the function,you should call SetVideoWindow() before. //If the parent windows (m_hWndVideo) is NULL, the display area would be set to zero. // //------------------------------------------------------------ BOOL CMedia::SetDisplayMode(DISPLAYMODE mode) { if(m_pVW == NULL) { return FALSE; } if(m_hWndVideo == NULL) { m_pVW->put_Left(0); m_pVW->put_Top(0); m_pVW->put_Width(0); m_pVW->put_Height(0); return FALSE; } m_DispMode = mode; if(mode == DISP_FULLSCREEN) { m_pVW->put_FullScreenMode(OATRUE); } else { //Restore to the normal mode m_pVW->put_FullScreenMode(OAFALSE); RECT rcWnd = m_rcDisp; if(rcWnd.left == RC_WHOLE_WINDOWN_AREA.left && rcWnd.top == RC_WHOLE_WINDOWN_AREA.top && rcWnd.right == RC_WHOLE_WINDOWN_AREA.right && rcWnd.bottom == RC_WHOLE_WINDOWN_AREA.bottom ) { GetClientRect(m_hWndVideo,&rcWnd); } LONG lWndWidth = rcWnd.right - rcWnd.left; LONG lWndHeight = rcWnd.bottom - rcWnd.top; MEDIAPROPERTY prop = {0}; GetMediaProperty(&prop); if(mode == DISP_FIT || mode == DISP_NATIVE) { LONG lDispLeft,lDispTop,lDispWidth,lDispHeight; if(mode == DISP_NATIVE && lWndWidth >= prop.lWidth && lWndHeight >= prop.lHeight) { lDispLeft = (lWndWidth - prop.lWidth) / 2 + rcWnd.left; lDispTop = (lWndHeight - prop.lHeight) / 2 + rcWnd.top; lDispWidth = prop.lWidth ; lDispHeight = prop.lHeight ; } else { if(prop.lWidth * lWndHeight > lWndWidth * prop.lHeight) { lDispWidth = lWndWidth; lDispHeight = (LONG)((float)lDispWidth / (float)prop.lWidth * prop.lHeight); lDispLeft = rcWnd.left; lDispTop = (lWndHeight - lDispHeight) / 2 + rcWnd.top; } else if(prop.lWidth * lWndHeight < lWndWidth * prop.lHeight) { lDispHeight = lWndHeight; lDispWidth = (LONG)((float)lDispHeight / (float)prop.lHeight * prop.lWidth); lDispLeft = (lWndWidth - lDispWidth) / 2 + rcWnd.left; lDispTop = rcWnd.top; } else { lDispWidth = lWndWidth; lDispHeight = lWndHeight; lDispLeft = rcWnd.left; lDispTop = rcWnd.top; } } m_pVW->put_Left(lDispLeft); m_pVW->put_Top(lDispTop); m_pVW->put_Width(lDispWidth); m_pVW->put_Height(lDispHeight); } else if(mode == DISP_STRETCH) { m_pVW->put_Left(rcWnd.left); m_pVW->put_Top(rcWnd.top); m_pVW->put_Width(lWndWidth); m_pVW->put_Height(lWndHeight); } } return TRUE; } //------------------------------------------------------------ //Description: // Set the volume. // When you call the function,you should call Open() before. // //Parameters: // lVolume:[in] The volume (amplitude) of the audio signal. // Range is –10,000 to 0. // lBalance:[in] The balance for the audio signal. Default value is 0. // The value from –10,000 to 10,000 indicating the stereo balance. // //------------------------------------------------------------ BOOL CMedia::SetVolume(LONG lVolume, LONG lBalance) { if(m_pBA == NULL) { return FALSE; } if(lVolume < MIN_VOLUME && lVolume > MAX_VOLUME && lBalance < MIN_BALANCE && lBalance > MAX_BALANCE) { return FALSE; } m_pBA->put_Volume(lVolume); m_pBA->put_Balance(lBalance); return TRUE; } //---------------------------------------------------------------------- //Description: // Registers a window that will handle the notified message when a specified event occurs and some window message // //Parameters: // hWnd:[in] Handle of window to notify. Pass NULL to stop notification. // wMsg:[in] Window message to be passed as the notification. // lInstanceData:[in] Value (instance data) to be passed as the lParam parameter for the lMsg message. // //Remarks: // When the notified window receive the wMsg as the notification, you could get the event code. // The follow codes show that process: // // //"WM_GRAPHNOTIFY" is the user-define notified message // case WM_GRAPHNOTIFY: // { // LONG evCode,evParam1,evParam2; // // //"m_pMedia" is the instance of the CMedia // if(m_pMedia->GetEvent(&evCode,&evParam1,&evParam2) == TRUE) // { // //Check the event code // if(evCode == EC_COMPLETE) // { // //Do something // } // } // return 0; // } // // The event code is as follow: // EC_ACTIVATE An audio or video renderer is losing or gaining activation. // EC_BUFFERING_DATA The buffering status is changing. // EC_CLOCK_CHANGED The filter graph has changed from one reference clock to another. // EC_COMPLETE All data has been rendered. // EC_DRM_LEVEL Notifies when content protected by digital rights management (DRM) requests some form of analog content protection. // EC_END_OF_SEGMENT Notifies that a segment end has been reached. // EC_ERROR_STILLPLAYING At least one call to Run failed in an active filter graph. // The current state of any underlying filter graph or graphs is indeterminate; they might be running, but some are almost certainly not. // EC_ERRORABORT An error forced the termination of a requested operation. // EC_FULLSCREEN_LOST The video renderer is switching out of full-screen mode. // EC_NEED_RESTART The current graph must be stopped and restarted. // EC_NOTIFY_WINDOW Pass the window handle around during pin connection. // EC_OLE_EVENT A filter is passing a text string to the application. // EC_OPENING_FILE The open file status is changing. // EC_PALETTE_CHANGED The video palette has changed. // EC_QUALITY_CHANGE The playback quality has changed. // EC_REPAINT A repaint is required. // EC_SEGMENT_STARTED Notifies that a new segment has been started. // EC_SHUTTING_DOWN The filter graph is starting to shut down. // DirectShow passes this notification to any plug-in distributors that support the IMediaEventSink interface. // EC_STARVATION One of the filters (usually a parser or file source filter) is not receiving enough data. // By default, the filter graph manager will pause all running filters and then return to normal operation when enough data is available. // EC_STREAM_CONTROL_STARTED The starting reference time from an earlier call to IAMStreamControl::StartAt passed. // EC_STREAM_CONTROL_STOPPED The stopping reference time from an earlier call to IAMStreamControl::StopAt passed. // EC_STREAM_ERROR_STILLPLAYING The stream is still playing, but should not be playing. // EC_STREAM_ERROR_STOPPED The stream has stopped, but should not have stopped. // EC_TIME The requested reference time occurred. // EC_USERABORT A user has forced the termination of a requested operation. // EC_VIDEO_SIZE_AR_CHANGED The size or aspect ratio of the native video has changed. // EC_VIDEO_SIZE_CHANGED The size of the native video has changed. // EC_WINDOW_DESTROYED The video renderer's filter is being removed or destroyed. // // // // DirectShow passes the following messages to the window specified by the hWnd parameter, //if and when the application generates them: // WM_KEYDOWN // WM_KEYUP // WM_LBUTTONDBLCLK // WM_LBUTTONDOWN // WM_LBUTTONUP // WM_MBUTTONDBLCLK // WM_MBUTTONDOWN // WM_MBUTTONUP // WM_MOUSEACTIVATE // WM_MOUSEMOVE // WM_RBUTTONDBLCLK // WM_RBUTTONDOWN // WM_RBUTTONUP //----------------------------------------------------------------------------- BOOL CMedia::SetNotifyWindow(HWND hWnd, UINT wMsg,long lInstanceData) { if(m_pME == NULL) { return FALSE; } HRESULT hr; hr = m_pME->SetNotifyWindow((OAHWND)hWnd,wMsg,lInstanceData); if(FAILED(hr)) { return FALSE; } if(CheckVisibility() == TRUE && m_pVW != NULL) { hr = m_pVW->put_MessageDrain((OAHWND)hWnd); } return SUCCEEDED(hr); } //---------------------------------------------------------------------- //Description: // This method retrieves the notification event. // //----------------------------------------------------------------------- BOOL CMedia::GetEvent(LONG *plEvCode, LONG *plParam1, LONG *plParam2) { if(m_pME == NULL) { return FALSE; } LONG evCode, evParam1, evParam2; if(SUCCEEDED(m_pME->GetEvent(&evCode, &evParam1, &evParam2, 0)) == TRUE) { *plEvCode = evCode; *plParam1 = evParam1; *plParam2 = evParam2; // Spin through the events m_pME->FreeEventParams(evCode, evParam1, evParam2); } else { return FALSE; } return TRUE; } //---------------------------------------------------------------------- //Description: // This method sets a new playback rate. // //Parameters // dRate:[in] New rate, where 1 is the normal rate, 2 is twice as fast, and so on. //----------------------------------------------------------------------- BOOL CMedia::SetRate(double dRate) { if(m_pMS == NULL) { return FALSE; } return SUCCEEDED(m_pMS->SetRate(dRate)); } //---------------------------------------------------------------------- //Description: // This method retrieves the current rate. // //Parameters: // pdRate:[out] The rate //----------------------------------------------------------------------- BOOL CMedia::GetRate(double *pdRate) { if(m_pMS == NULL) { return FALSE; } return SUCCEEDED(m_pMS->GetRate(pdRate)); } //---------------------------------------------------------------------- //Description: // This method retrieves the current position in terms of the total length of the media stream // //Parameters: // pllPos:[out]Current position. //----------------------------------------------------------------------- BOOL CMedia::GetPositionCurrent(LONGLONG *pllPos) { if(m_pMS == NULL) { return FALSE; } if(m_dwCapability & AM_SEEKING_CanGetCurrentPos == 0) { return FALSE; } return SUCCEEDED(m_pMS->GetCurrentPosition(pllPos)); } //---------------------------------------------------------------------- //Description: // This method sets current positions // //Parameters: // llPos:[in]Start position if stopped, or position from which to continue if paused. //----------------------------------------------------------------------- BOOL CMedia::SetPositionCurrent(LONGLONG llPos) { if(m_pMS == NULL) { return FALSE; } LONGLONG llCur = 0; if(GetPositionCurrent(&llCur) == TRUE) { if((llCur > llPos) && (m_dwCapability & AM_SEEKING_CanSeekBackwards == 0)) { return FALSE; } else if((llCur < llPos) && (m_dwCapability & AM_SEEKING_CanSeekForwards == 0)) { return FALSE; } else if(llCur == llPos) { //It's the current positon, needn't set return TRUE; } } else if((m_dwCapability & AM_SEEKING_CanSeekBackwards == 0) || (m_dwCapability & AM_SEEKING_CanSeekForwards == 0)) { return FALSE; } return SUCCEEDED(m_pMS->SetPositions(&llPos,AM_SEEKING_AbsolutePositioning,NULL,AM_SEEKING_NoPositioning)); } //---------------------------------------------------------------------- //Description: // This method get current display mode // //---------------------------------------------------------------------- DISPLAYMODE CMedia::GetDisplayMode() { return m_DispMode; }