norains的专栏

只专注于WINCE开发

用户操作
[即时聊天] [发私信] [加为好友]
norainsID:norains
142907次访问,排名598,好友0人,关注者53人。
代码其实是一种乐趣
norains的文章
原创 189 篇
翻译 0 篇
转载 10 篇
评论 274 篇
norains的公告
联系方式请看置顶文章
最近评论
dfdf:讨厌MFC!我觉得MFC就是太乱了!看似无用的代码不要不行,MD微软啥都给我们做完了,原理性的东西我们却永远没法搞懂了!
ironox:有个地方 我觉得很别扭,不知道怎么办好

比如说 CReg reg(HKEY_CURRENT_USER,TEXT("ControlPanel\Volume"));
ControlPanel\Volume 有可能不存在呀,这个该怎么处理哦?对象虽然创建了,出错了也没提示
szterry:呵呵,果然工作狂技术狂,同感,一样的感觉……不过我才刚毕业一年……搞IT就是玩……
jinlking:这个botton的实现只是在主窗口画了一块区域,对于事件的处理还要放在主窗口的窗口处理函数之中,在对应的消息处理上调用CheckTap来判断是否是此“按钮”,问一下,这种方法与把按钮封装在子窗口中有什么区别,二者使用那个更好?
KUODY:博主真是好人
文章分类
收藏
    相册
    动漫
    文章图片
    程序交流
    xumercury的BLOG
    狗友们的博客
    清蒸石斑鱼
    美女如刀锋
    茁茁的BLOG
    魅力老姐的窝
    存档
    软件项目交易
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    原创 CMedia更新至v1.4.3收藏

    新一篇: IImage和链接错误 | 旧一篇: WinCE实时获取电源状态变化

    //========================================================================
    //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); &