`

Media Player Classic - HC 源代码分析 4:核心类 (CMainFrame)(3)

 
阅读更多

 

注:写了一系列分析Media Player Classic - HC 源代码的文章,在此列一个列表:

Media Player Classic - HC 源代码分析 1:整体结构
Media Player Classic - HC 源代码分析 2:核心类 (CMainFrame)(1)
Media Player Classic - HC 源代码分析 3:核心类 (CMainFrame)(2)
Media Player Classic - HC 源代码分析 4:核心类 (CMainFrame)(3)
Media Player Classic - HC 源代码分析 5:关于对话框 (CAboutDlg)
Media Player Classic - HC 源代码分析 6:MediaInfo选项卡 (CPPageFileMediaInfo)
Media Player Classic - HC 源代码分析 7:详细信息选项卡(CPPageFileInfoDetails)


此前已经写了2篇文章介绍Media Player Classic - HC (mpc-hc)源代码中的核心类 CMainFrame:

Media Player Classic - HC 源代码分析 2:核心类 (CMainFrame)(1)

Media Player Classic - HC 源代码分析 3:核心类 (CMainFrame)(2)

此前的文章一直都是围绕着OpenMedia()以及其调用的函数进行分析的。研究的都是和文件打开有关系的功能。在这里再介绍一些其它函数。

在mpc-hc开始运行的时候,会调用OnCreate():

 

<span style="font-family:Arial;font-size:12px;">//刚打开的时候加载
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (__super::OnCreate(lpCreateStruct) == -1) {
        return -1;
    }
	//加载菜单
    m_popup.LoadMenu(IDR_POPUP);
    m_popupmain.LoadMenu(IDR_POPUPMAIN);

    // create a view to occupy the client area of the frame
	// 创建视频画面部分?
    if (!m_wndView.Create(nullptr, nullptr, AFX_WS_DEFAULT_VIEW,
                          CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, nullptr)) {
        TRACE(_T("Failed to create view window\n"));
        return -1;
    }
    // Should never be RTLed
    m_wndView.ModifyStyleEx(WS_EX_LAYOUTRTL, WS_EX_NOINHERITLAYOUT);

    // static bars
	//各种状态栏
    BOOL bResult = m_wndStatusBar.Create(this);
    if (bResult) {
        bResult = m_wndStatsBar.Create(this);
    }
    if (bResult) {
        bResult = m_wndInfoBar.Create(this);
    }
    if (bResult) {
        bResult = m_wndToolBar.Create(this);
    }
    if (bResult) {
        bResult = m_wndSeekBar.Create(this);
    }
    if (!bResult) {
        TRACE(_T("Failed to create all control bars\n"));
        return -1;      // fail to create
    }
	// 各种Bar
    m_pFullscreenWnd = DEBUG_NEW CFullscreenWnd(this);

    m_bars.AddTail(&m_wndSeekBar);
    m_bars.AddTail(&m_wndToolBar);
    m_bars.AddTail(&m_wndInfoBar);
    m_bars.AddTail(&m_wndStatsBar);
    m_bars.AddTail(&m_wndStatusBar);

    m_wndSeekBar.Enable(false);

    // dockable bars
	// 可停靠的
    EnableDocking(CBRS_ALIGN_ANY);

    m_dockingbars.RemoveAll();

    m_wndSubresyncBar.Create(this, AFX_IDW_DOCKBAR_TOP, &m_csSubLock);
    m_wndSubresyncBar.SetBarStyle(m_wndSubresyncBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
    m_wndSubresyncBar.EnableDocking(CBRS_ALIGN_ANY);
    m_wndSubresyncBar.SetHeight(200);
    m_dockingbars.AddTail(&m_wndSubresyncBar);

    m_wndPlaylistBar.Create(this, AFX_IDW_DOCKBAR_BOTTOM);
    m_wndPlaylistBar.SetBarStyle(m_wndPlaylistBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
    m_wndPlaylistBar.EnableDocking(CBRS_ALIGN_ANY);
    m_wndPlaylistBar.SetHeight(100);
    m_dockingbars.AddTail(&m_wndPlaylistBar);
    m_wndPlaylistBar.LoadPlaylist(GetRecentFile());

    m_wndEditListEditor.Create(this, AFX_IDW_DOCKBAR_RIGHT);
    m_wndEditListEditor.SetBarStyle(m_wndEditListEditor.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
    m_wndEditListEditor.EnableDocking(CBRS_ALIGN_ANY);
    m_dockingbars.AddTail(&m_wndEditListEditor);
    m_wndEditListEditor.SetHeight(100);

    m_wndCaptureBar.Create(this, AFX_IDW_DOCKBAR_LEFT);
    m_wndCaptureBar.SetBarStyle(m_wndCaptureBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
    m_wndCaptureBar.EnableDocking(CBRS_ALIGN_LEFT | CBRS_ALIGN_RIGHT);
    m_dockingbars.AddTail(&m_wndCaptureBar);

    m_wndNavigationBar.Create(this, AFX_IDW_DOCKBAR_LEFT);
    m_wndNavigationBar.SetBarStyle(m_wndNavigationBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
    m_wndNavigationBar.EnableDocking(CBRS_ALIGN_LEFT | CBRS_ALIGN_RIGHT);
    m_dockingbars.AddTail(&m_wndNavigationBar);

    m_wndShaderEditorBar.Create(this, AFX_IDW_DOCKBAR_TOP);
    m_wndShaderEditorBar.SetBarStyle(m_wndShaderEditorBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
    m_wndShaderEditorBar.EnableDocking(CBRS_ALIGN_ANY);
    m_dockingbars.AddTail(&m_wndShaderEditorBar);

    // Hide all dockable bars by default
    POSITION pos = m_dockingbars.GetHeadPosition();
    while (pos) {
        m_dockingbars.GetNext(pos)->ShowWindow(SW_HIDE);
    }

    m_fileDropTarget.Register(this);

    const CAppSettings& s = AfxGetAppSettings();

    // Load the controls
    m_nCS = s.nCS;
    ShowControls(m_nCS);
	//是否在最前?
    SetAlwaysOnTop(s.iOnTop);
	//显示系统托盘图标
    ShowTrayIcon(s.fTrayIcon);
	//焦点
    SetFocus();
	//创建CGraphThread类的线程
    m_pGraphThread = (CGraphThread*)AfxBeginThread(RUNTIME_CLASS(CGraphThread));
	//设置。。
    if (m_pGraphThread) {
        m_pGraphThread->SetMainFrame(this);
    }

    if (s.nCmdlnWebServerPort != 0) {
        if (s.nCmdlnWebServerPort > 0) {
            StartWebServer(s.nCmdlnWebServerPort);
        } else if (s.fEnableWebServer) {
            StartWebServer(s.nWebServerPort);
        }
    }

    // Casimir666 : reload Shaders
    {
        CString strList = s.strShaderList;
        CString strRes;
        int curPos = 0;

        strRes = strList.Tokenize(_T("|"), curPos);
        while (!strRes.IsEmpty()) {
            m_shaderlabels.AddTail(strRes);
            strRes = strList.Tokenize(_T("|"), curPos);
        }
    }
    {
        CString strList = s.strShaderListScreenSpace;
        CString strRes;
        int curPos = 0;

        strRes = strList.Tokenize(_T("|"), curPos);
        while (!strRes.IsEmpty()) {
            m_shaderlabelsScreenSpace.AddTail(strRes);
            strRes = strList.Tokenize(_T("|"), curPos);
        }
    }

    m_bToggleShader = s.fToggleShader;
    m_bToggleShaderScreenSpace = s.fToggleShaderScreenSpace;
	//标题
    m_strTitle.LoadString(IDR_MAINFRAME);

#ifdef MPCHC_LITE
    m_strTitle += _T(" Lite");
#endif
	//设置窗口标题
    SetWindowText(m_strTitle);
    m_Lcd.SetMediaTitle(LPCTSTR(m_strTitle));

    WTSRegisterSessionNotification();

    if (s.bNotifySkype) {
        m_pSkypeMoodMsgHandler.Attach(DEBUG_NEW SkypeMoodMsgHandler());
        m_pSkypeMoodMsgHandler->Connect(m_hWnd);
    }

    return 0;
}</span>


在mpc-hc关闭的时候,会调用OnDestroy():

 

 

<span style="font-family:Arial;font-size:12px;">//关闭的时候加载
void CMainFrame::OnDestroy()
{
    WTSUnRegisterSessionNotification();
	//关闭系统托盘图标
    ShowTrayIcon(false);
    m_fileDropTarget.Revoke();
	//线程还在运行的话
    if (m_pGraphThread) {
        CAMMsgEvent e;
		//退出
        m_pGraphThread->PostThreadMessage(CGraphThread::TM_EXIT, 0, (LPARAM)&e);
        if (!e.Wait(5000)) {
            TRACE(_T("ERROR: Must call TerminateThread() on CMainFrame::m_pGraphThread->m_hThread\n"));
            TerminateThread(m_pGraphThread->m_hThread, (DWORD) - 1);
        }
    }

    if (m_pFullscreenWnd) {
        if (m_pFullscreenWnd->IsWindow()) {
            m_pFullscreenWnd->DestroyWindow();
        }
        delete m_pFullscreenWnd;
    }

    __super::OnDestroy();
}</span>

 

在关闭一个媒体的时候,会调用OnClose():

 

//关闭的时候加载
void CMainFrame::OnClose()
{
	//获取设置
    CAppSettings& s = AfxGetAppSettings();
    // Casimir666 : save shaders list
    {
        POSITION pos;
        CString strList = "";

        pos = m_shaderlabels.GetHeadPosition();
        while (pos) {
            strList += m_shaderlabels.GetAt(pos) + "|";
            m_dockingbars.GetNext(pos);
        }
        s.strShaderList = strList;
    }
    {
        POSITION pos;
        CString  strList = "";

        pos = m_shaderlabelsScreenSpace.GetHeadPosition();
        while (pos) {
            strList += m_shaderlabelsScreenSpace.GetAt(pos) + "|";
            m_dockingbars.GetNext(pos);
        }
        s.strShaderListScreenSpace = strList;
    }

    s.fToggleShader = m_bToggleShader;
    s.fToggleShaderScreenSpace = m_bToggleShaderScreenSpace;

    s.dZoomX = m_ZoomX;
    s.dZoomY = m_ZoomY;
	//存储播放列表
    m_wndPlaylistBar.SavePlaylist();
	//存储控制条
    SaveControlBars();

    ShowWindow(SW_HIDE);
	//关闭媒体(非private)
    CloseMedia();

    s.WinLircClient.DisConnect();
    s.UIceClient.DisConnect();

    SendAPICommand(CMD_DISCONNECT, L"\0");  // according to CMD_NOTIFYENDOFSTREAM (ctrl+f it here), you're not supposed to send NULL here
    //调用父类onclose
	__super::OnClose();
}


同时还有一个定时器函数OnTimer()。根据不同的nIDEvent做不同的处理操作。

 

 

//定时刷新的操作
void CMainFrame::OnTimer(UINT_PTR nIDEvent)
{
    switch (nIDEvent) {
		//当前播放到的位置
        case TIMER_STREAMPOSPOLLER:
            if (m_iMediaLoadState == MLS_LOADED) {
                REFERENCE_TIME rtNow = 0, rtDur = 0;
				//播放方式是文件的时候(还可以是DVD或者摄像头)
                if (GetPlaybackMode() == PM_FILE) {
					//当前位置
                    m_pMS->GetCurrentPosition(&rtNow);
					//时常
                    m_pMS->GetDuration(&rtDur);

                    // Casimir666 : autosave subtitle sync after play
                    if ((m_nCurSubtitle >= 0) && (m_rtCurSubPos != rtNow)) {
                        if (m_lSubtitleShift != 0) {
                            if (m_wndSubresyncBar.SaveToDisk()) {
                                m_OSD.DisplayMessage(OSD_TOPLEFT, ResStr(IDS_AG_SUBTITLES_SAVED), 500);
                            } else {
                                m_OSD.DisplayMessage(OSD_TOPLEFT, ResStr(IDS_MAINFRM_4));
                            }
                        }
                        m_nCurSubtitle   = -1;
                        m_lSubtitleShift = 0;
                    }

                    if (!m_fEndOfStream) {
                        CAppSettings& s = AfxGetAppSettings();

                        if (m_bRememberFilePos) {
                            FILE_POSITION* filePosition = s.filePositions.GetLatestEntry();

                            if (filePosition) {
                                filePosition->llPosition = rtNow;

                                LARGE_INTEGER time;
                                QueryPerformanceCounter(&time);
                                LARGE_INTEGER freq;
                                QueryPerformanceFrequency(&freq);
                                if ((time.QuadPart - m_liLastSaveTime.QuadPart) >= 30 * freq.QuadPart) { // save every half of minute
                                    m_liLastSaveTime = time;
                                    s.filePositions.SaveLatestEntry();
                                }
                            }
                        }
                    }

                    if (m_rtDurationOverride >= 0) {
                        rtDur = m_rtDurationOverride;
                    }
					//设置滑动条控件的参数(位置等。。。)
                    g_bNoDuration = rtDur <= 0;
                    m_wndSeekBar.Enable(rtDur > 0);
                    m_wndSeekBar.SetRange(0, rtDur);
                    m_wndSeekBar.SetPos(rtNow);
                    m_OSD.SetRange(0, rtDur);
                    m_OSD.SetPos(rtNow);
                    m_Lcd.SetMediaRange(0, rtDur);
                    m_Lcd.SetMediaPos(rtNow);
                } else if (GetPlaybackMode() == PM_CAPTURE) {
					//如果是摄像头的话,就没有时长信息了
                    m_pMS->GetCurrentPosition(&rtNow);
                    if (m_fCapturing && m_wndCaptureBar.m_capdlg.m_pMux) {
                        CComQIPtr<IMediaSeeking> pMuxMS = m_wndCaptureBar.m_capdlg.m_pMux;
                        if (!pMuxMS || FAILED(pMuxMS->GetCurrentPosition(&rtNow))) {
                            rtNow = 0;
                        }
                    }

                    if (m_rtDurationOverride >= 0) {
                        rtDur = m_rtDurationOverride;
                    }

                    g_bNoDuration = rtDur <= 0;
                    m_wndSeekBar.Enable(false);
                    m_wndSeekBar.SetRange(0, rtDur);
                    m_wndSeekBar.SetPos(rtNow);
                    m_OSD.SetRange(0, rtDur);
                    m_OSD.SetPos(rtNow);
                    m_Lcd.SetMediaRange(0, rtDur);
                    m_Lcd.SetMediaPos(rtNow);
                }

                if (m_pCAP && GetPlaybackMode() != PM_FILE) {
                    g_bExternalSubtitleTime = true;
                    if (m_pDVDI) {
                        DVD_PLAYBACK_LOCATION2 Location;
                        if (m_pDVDI->GetCurrentLocation(&Location) == S_OK) {
                            double fps = Location.TimeCodeFlags == DVD_TC_FLAG_25fps ? 25.0
                                         : Location.TimeCodeFlags == DVD_TC_FLAG_30fps ? 30.0
                                         : Location.TimeCodeFlags == DVD_TC_FLAG_DropFrame ? 29.97
                                         : 25.0;

                            REFERENCE_TIME rtTimeCode = HMSF2RT(Location.TimeCode, fps);
                            m_pCAP->SetTime(rtTimeCode);
                        } else {
                            m_pCAP->SetTime(/*rtNow*/m_wndSeekBar.GetPos());
                        }
                    } else {
                        // Set rtNow to support DVB subtitle
                        m_pCAP->SetTime(rtNow);
                    }
                } else {
                    g_bExternalSubtitleTime = false;
                }
            }
            break;
        case TIMER_STREAMPOSPOLLER2:
            if (m_iMediaLoadState == MLS_LOADED) {
                __int64 start, stop, pos;
                m_wndSeekBar.GetRange(start, stop);
                pos = m_wndSeekBar.GetPosReal();

                GUID tf;
                m_pMS->GetTimeFormat(&tf);

                if (GetPlaybackMode() == PM_CAPTURE && !m_fCapturing) {
                    CString str = ResStr(IDS_CAPTURE_LIVE);

                    long lChannel = 0, lVivSub = 0, lAudSub = 0;
                    if (m_pAMTuner
                            && m_wndCaptureBar.m_capdlg.IsTunerActive()
                            && SUCCEEDED(m_pAMTuner->get_Channel(&lChannel, &lVivSub, &lAudSub))) {
                        CString ch;
                        ch.Format(_T(" (ch%d)"), lChannel);
                        str += ch;
                    }

                    m_wndStatusBar.SetStatusTimer(str);
                } else {
                    m_wndStatusBar.SetStatusTimer(pos, stop, !!m_wndSubresyncBar.IsWindowVisible(), &tf);
                    if (m_bRemainingTime) {
                        m_OSD.DisplayMessage(OSD_TOPLEFT, m_wndStatusBar.GetStatusTimer());
                    }
                }

                m_wndSubresyncBar.SetTime(pos);

                if (m_pCAP && GetMediaState() == State_Paused) {
                    m_pCAP->Paint(false);
                }
            }
            break;
        case TIMER_FULLSCREENCONTROLBARHIDER: {
            CPoint p;
            GetCursorPos(&p);

            CRect r;
            GetWindowRect(r);
            bool fCursorOutside = !r.PtInRect(p);

            CWnd* pWnd = WindowFromPoint(p);
            if (pWnd && (m_wndView == *pWnd || m_wndView.IsChild(pWnd) || fCursorOutside)) {
                if (AfxGetAppSettings().nShowBarsWhenFullScreenTimeOut >= 0) {
                    ShowControls(CS_NONE);
                }
            }
        }
        break;
        case TIMER_FULLSCREENMOUSEHIDER: {
            CPoint p;
            GetCursorPos(&p);

            CRect r;
            GetWindowRect(r);
            bool fCursorOutside = !r.PtInRect(p);
            CWnd* pWnd = WindowFromPoint(p);
            if (IsD3DFullScreenMode()) {
                if (pWnd && !m_bInOptions && *pWnd == *m_pFullscreenWnd) {
                    m_pFullscreenWnd->ShowCursor(false);
                }
                KillTimer(TIMER_FULLSCREENMOUSEHIDER);
            } else {
                if (pWnd && !m_bInOptions && (m_wndView == *pWnd || m_wndView.IsChild(pWnd) || fCursorOutside)) {
                    m_fHideCursor = true;
                    SetCursor(nullptr);
                }
            }
        }
        break;
		//统计量
        case TIMER_STATS: {
			//接收端质量信息:抖动,抖动,视音频同步情况等。。。
            if (m_pQP) {
                CString rate;
                rate.Format(_T("%.2f"), m_dSpeedRate);
                rate = _T("(") + rate + _T("x)");
				//信息
                CString info;
                int val = 0;
				//平均帧率
                m_pQP->get_AvgFrameRate(&val); // We hang here due to a lock that never gets released.
                info.Format(_T("%d.%02d %s"), val / 100, val % 100, rate);
                m_wndStatsBar.SetLine(ResStr(IDS_AG_FRAMERATE), info);

                int avg, dev;
				//抖动
                m_pQP->get_AvgSyncOffset(&avg);
                m_pQP->get_DevSyncOffset(&dev);
                info.Format(ResStr(IDS_STATSBAR_SYNC_OFFSET_FORMAT), avg, dev);
                m_wndStatsBar.SetLine(ResStr(IDS_STATSBAR_SYNC_OFFSET), info);
				//掉帧
                int drawn, dropped;
                m_pQP->get_FramesDrawn(&drawn);
                m_pQP->get_FramesDroppedInRenderer(&dropped);
                info.Format(IDS_MAINFRM_6, drawn, dropped);
                m_wndStatsBar.SetLine(ResStr(IDS_AG_FRAMES), info);
				//抖动
                m_pQP->get_Jitter(&val);
                info.Format(_T("%d ms"), val);
                m_wndStatsBar.SetLine(ResStr(IDS_STATSBAR_JITTER), info);
            }
			//缓存信息
            if (m_pBI) {
                CAtlList<CString> sl;
				//获取数量
                for (int i = 0, j = m_pBI->GetCount(); i < j; i++) {
                    int samples, size;
					//获取缓存状态
                    if (S_OK == m_pBI->GetStatus(i, samples, size)) {
                        CString str;
                        str.Format(_T("[%d]: %03d/%d KB"), i, samples, size / 1024);
                        sl.AddTail(str);
                    }
                }

                if (!sl.IsEmpty()) {
                    CString str;
                    str.Format(_T("%s (p%u)"), Implode(sl, ' '), m_pBI->GetPriority());

                    m_wndStatsBar.SetLine(ResStr(IDS_AG_BUFFERS), str);
                }
            }
			//比特率信息
            CInterfaceList<IBitRateInfo> pBRIs;

            BeginEnumFilters(m_pGB, pEF, pBF) {
                BeginEnumPins(pBF, pEP, pPin) {
                    if (CComQIPtr<IBitRateInfo> pBRI = pPin) {
                        pBRIs.AddTail(pBRI);
                    }
                }
                EndEnumPins;

                if (!pBRIs.IsEmpty()) {
                    CAtlList<CString> sl;

                    POSITION pos = pBRIs.GetHeadPosition();
                    for (int i = 0; pos; i++) {
						//比特率接口
                        IBitRateInfo* pBRI = pBRIs.GetNext(pos);
						//当前比特率
                        DWORD cur = pBRI->GetCurrentBitRate() / 1000;
						//平均比特率
                        DWORD avg = pBRI->GetAverageBitRate() / 1000;

                        if (avg == 0) {
                            continue;
                        }
						//添加到字符串
                        CString str;
                        if (cur != avg) {
                            str.Format(_T("[%d]: %u/%u Kb/s"), i, avg, cur);
                        } else {
                            str.Format(_T("[%d]: %u Kb/s"), i, avg);
                        }
						//加入
                        sl.AddTail(str);
                    }

                    if (!sl.IsEmpty()) {
                        m_wndStatsBar.SetLine(ResStr(IDS_STATSBAR_BITRATE), Implode(sl, ' ') + ResStr(IDS_STATSBAR_BITRATE_AVG_CUR));
                    }

                    break;
                }
            }
            EndEnumFilters;

            if (GetPlaybackMode() == PM_DVD) { // we also use this timer to update the info panel for DVD playback
                ULONG ulAvailable, ulCurrent;

                // Location

                CString Location('-');

                DVD_PLAYBACK_LOCATION2 loc;
                ULONG ulNumOfVolumes, ulVolume;
                DVD_DISC_SIDE Side;
                ULONG ulNumOfTitles;
                ULONG ulNumOfChapters;

                if (SUCCEEDED(m_pDVDI->GetCurrentLocation(&loc))
                        && SUCCEEDED(m_pDVDI->GetNumberOfChapters(loc.TitleNum, &ulNumOfChapters))
                        && SUCCEEDED(m_pDVDI->GetDVDVolumeInfo(&ulNumOfVolumes, &ulVolume, &Side, &ulNumOfTitles))) {
                    Location.Format(IDS_MAINFRM_9,
                                    ulVolume, ulNumOfVolumes,
                                    loc.TitleNum, ulNumOfTitles,
                                    loc.ChapterNum, ulNumOfChapters);
                    ULONG tsec = (loc.TimeCode.bHours * 3600)
                                 + (loc.TimeCode.bMinutes * 60)
                                 + (loc.TimeCode.bSeconds);
                    /* This might not always work, such as on resume */
                    if (loc.ChapterNum != m_lCurrentChapter) {
                        m_lCurrentChapter = loc.ChapterNum;
                        m_lChapterStartTime = tsec;
                    } else {
                        /* If a resume point was used, and the user chapter jumps,
                        then it might do some funky time jumping.  Try to 'fix' the
                        chapter start time if this happens */
                        if (m_lChapterStartTime > tsec) {
                            m_lChapterStartTime = tsec;
                        }
                    }
                }

                m_wndInfoBar.SetLine(ResStr(IDS_INFOBAR_LOCATION), Location);

                // Video

                CString Video('-');

                DVD_VideoAttributes VATR;

                if (SUCCEEDED(m_pDVDI->GetCurrentAngle(&ulAvailable, &ulCurrent))
                        && SUCCEEDED(m_pDVDI->GetCurrentVideoAttributes(&VATR))) {
                    Video.Format(IDS_MAINFRM_10,
                                 ulCurrent, ulAvailable,
                                 VATR.ulSourceResolutionX, VATR.ulSourceResolutionY, VATR.ulFrameRate,
                                 VATR.ulAspectX, VATR.ulAspectY);
                }

                m_wndInfoBar.SetLine(ResStr(IDS_INFOBAR_VIDEO), Video);

                // Audio

                CString Audio('-');

                DVD_AudioAttributes AATR;

                if (SUCCEEDED(m_pDVDI->GetCurrentAudio(&ulAvailable, &ulCurrent))
                        && SUCCEEDED(m_pDVDI->GetAudioAttributes(ulCurrent, &AATR))) {
                    CString lang;
                    if (AATR.Language) {
                        int len = GetLocaleInfo(AATR.Language, LOCALE_SENGLANGUAGE, lang.GetBuffer(64), 64);
                        lang.ReleaseBufferSetLength(max(len - 1, 0));
                    } else {
                        lang.Format(IDS_AG_UNKNOWN, ulCurrent + 1);
                    }

                    switch (AATR.LanguageExtension) {
                        case DVD_AUD_EXT_NotSpecified:
                        default:
                            break;
                        case DVD_AUD_EXT_Captions:
                            lang += _T(" (Captions)");
                            break;
                        case DVD_AUD_EXT_VisuallyImpaired:
                            lang += _T(" (Visually Impaired)");
                            break;
                        case DVD_AUD_EXT_DirectorComments1:
                            lang += _T(" (Director Comments 1)");
                            break;
                        case DVD_AUD_EXT_DirectorComments2:
                            lang += _T(" (Director Comments 2)");
                            break;
                    }

                    CString format = GetDVDAudioFormatName(AATR);

                    Audio.Format(IDS_MAINFRM_11,
                                 lang,
                                 format,
                                 AATR.dwFrequency,
                                 AATR.bQuantization,
                                 AATR.bNumberOfChannels,
                                 (AATR.bNumberOfChannels > 1 ? ResStr(IDS_MAINFRM_13) : ResStr(IDS_MAINFRM_12)));

                    m_wndStatusBar.SetStatusBitmap(
                        AATR.bNumberOfChannels == 1 ? IDB_AUDIOTYPE_MONO
                        : AATR.bNumberOfChannels >= 2 ? IDB_AUDIOTYPE_STEREO
                        : IDB_AUDIOTYPE_NOAUDIO);
                }

                m_wndInfoBar.SetLine(ResStr(IDS_INFOBAR_AUDIO), Audio);

                // Subtitles

                CString Subtitles('-');

                BOOL bIsDisabled;
                DVD_SubpictureAttributes SATR;

                if (SUCCEEDED(m_pDVDI->GetCurrentSubpicture(&ulAvailable, &ulCurrent, &bIsDisabled))
                        && SUCCEEDED(m_pDVDI->GetSubpictureAttributes(ulCurrent, &SATR))) {
                    CString lang;
                    int len = GetLocaleInfo(SATR.Language, LOCALE_SENGLANGUAGE, lang.GetBuffer(64), 64);
                    lang.ReleaseBufferSetLength(max(len - 1, 0));

                    switch (SATR.LanguageExtension) {
                        case DVD_SP_EXT_NotSpecified:
                        default:
                            break;
                        case DVD_SP_EXT_Caption_Normal:
                            lang += _T("");
                            break;
                        case DVD_SP_EXT_Caption_Big:
                            lang += _T(" (Big)");
                            break;
                        case DVD_SP_EXT_Caption_Children:
                            lang += _T(" (Children)");
                            break;
                        case DVD_SP_EXT_CC_Normal:
                            lang += _T(" (CC)");
                            break;
                        case DVD_SP_EXT_CC_Big:
                            lang += _T(" (CC Big)");
                            break;
                        case DVD_SP_EXT_CC_Children:
                            lang += _T(" (CC Children)");
                            break;
                        case DVD_SP_EXT_Forced:
                            lang += _T(" (Forced)");
                            break;
                        case DVD_SP_EXT_DirectorComments_Normal:
                            lang += _T(" (Director Comments)");
                            break;
                        case DVD_SP_EXT_DirectorComments_Big:
                            lang += _T(" (Director Comments, Big)");
                            break;
                        case DVD_SP_EXT_DirectorComments_Children:
                            lang += _T(" (Director Comments, Children)");
                            break;
                    }

                    if (bIsDisabled) {
                        lang = _T("-");
                    }

                    Subtitles.Format(_T("%s"),
                                     lang);
                }

                m_wndInfoBar.SetLine(ResStr(IDS_INFOBAR_SUBTITLES), Subtitles);
            } else if (GetPlaybackMode() == PM_CAPTURE && AfxGetAppSettings().iDefaultCaptureDevice == 1) {
                CComQIPtr<IBDATuner> pTun = m_pGB;
                BOOLEAN bPresent;
                BOOLEAN bLocked;
                LONG lDbStrength;
                LONG lPercentQuality;
                CString Signal;

                if (SUCCEEDED(pTun->GetStats(bPresent, bLocked, lDbStrength, lPercentQuality)) && bPresent) {
                    Signal.Format(ResStr(IDS_STATSBAR_SIGNAL_FORMAT), (int)lDbStrength, lPercentQuality);
                    m_wndStatsBar.SetLine(ResStr(IDS_STATSBAR_SIGNAL), Signal);
                }
            } else if (GetPlaybackMode() == PM_FILE) {
                UpdateChapterInInfoBar();
            }

            if (GetMediaState() == State_Running && !m_fAudioOnly) {
                BOOL fActive = FALSE;
                if (SystemParametersInfo(SPI_GETSCREENSAVEACTIVE, 0,       &fActive, 0)) {
                    SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, FALSE,   nullptr,     SPIF_SENDWININICHANGE); // this might not be needed at all...
                    SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, fActive, nullptr,     SPIF_SENDWININICHANGE);
                }

                fActive = FALSE;
                if (SystemParametersInfo(SPI_GETPOWEROFFACTIVE, 0,       &fActive, 0)) {
                    SystemParametersInfo(SPI_SETPOWEROFFACTIVE, FALSE,   nullptr,     SPIF_SENDWININICHANGE); // this might not be needed at all...
                    SystemParametersInfo(SPI_SETPOWEROFFACTIVE, fActive, nullptr,     SPIF_SENDWININICHANGE);
                }
                // prevent screensaver activate, monitor sleep/turn off after playback
                SetThreadExecutionState(ES_SYSTEM_REQUIRED | ES_DISPLAY_REQUIRED);
            }
        }
        break;
        case TIMER_STATUSERASER: {
            KillTimer(TIMER_STATUSERASER);
            m_playingmsg.Empty();
        }
        break;
        case TIMER_DVBINFO_UPDATER:
            KillTimer(TIMER_DVBINFO_UPDATER);
            ShowCurrentChannelInfo(false, false);
            break;
    }

    __super::OnTimer(nIDEvent);
}



 

 

分享到:
评论

相关推荐

    利用c++开发的一款小游戏开发报告.docx

    ### 八、游戏执行程序代码分析 - **文件名**:tiger1view.cpp - **主要内容**: - 实现了`Ctiger1View`类。 - 定义了宏变量,如颜色定义(WHITE、BLACK、BLUE)。 - 包含消息映射,处理各种事件,如键盘事件、...

    VC++ ,在不同类中的MFC各种指针获取方式

    `CWinApp` 类是MFC应用程序的核心,用于管理整个应用程序的生命周期。获取 `CWinApp` 对象的主要方法包括: - **全局函数**: - `AfxGetApp()`:返回当前活动的应用程序对象指针。 - `AfxGetMainWnd()`:返回指向...

    MFC程序设计试卷

    - **CMainFrame**: 主窗口类。 - **CMyPrjApp**: 应用程序类,负责应用程序的全局管理。 - **CMyPrjDoc**: 文档类,用于存储和管理应用程序中的数据。 - **CMyPrjView**: 视图类,用于显示文档数据并接收用户事件。 ...

    达内C++资料

    #### 四、MFC的核心类 **1. CObject类** `CObject`是MFC中最基本的类,几乎所有其他MFC类都直接或间接地继承自它。它提供了以下功能: - **内存管理**: 使用`new`和`delete`进行对象的动态分配和释放。 - **断言*...

    深入编程内幕——Visual C++

    - **CMainFrame 类**:主框架窗口类,通常用于显示菜单栏和工具栏。 - **CMyView 和 CMyDoc 类**: - **CMyView**:视图类,负责显示文档内容和响应用户交互。 - **CMyDoc**:文档类,存储数据并支持序列化功能,...

    Visual C++制作自己的资源管理器.zip

    - `StdAfx.cpp`:预编译头文件的源代码,通常包括对MFC库的引用。 - `DriveExplorer.dsp`, `DriveExplorer.dsw`:项目文件,存储了工程设置、编译选项等信息,用于Visual Studio打开和管理项目。 3. **关键组件**...

    MFC菜单-工具条-状态条详细讲解及示例

    3. **示例代码**: ```cpp CMenu* pMenu = new CMenu(); pMenu-&gt;LoadMenu(IDR_MY_MENU); CMenu* pSubMenu = pMenu-&gt;GetSubMenu(0); pSubMenu-&gt;TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, GetCursorPos()...

    vc入门教程-从入门到精通.doc

    - **CMYAPP 类:** 应用程序的核心类,负责初始化和管理整个应用程序。 - **CMAINFRAME 类:** 主框架窗口类,通常包含主菜单和工具栏。 - **CMyView 类:** 视图类,负责绘制和显示文档数据。 - **CMyDoc 类:** ...

    深入浅出MFC笔记 配合原书的好笔记 doc

    CMainFrame和CTChildFrame是这两个类的具体实现,分别对应主框架窗口和文档边框窗口。 类的关系图(图1-1)展示了信息流从CWinApp到CDocument,再到CView,然后到CMDIFrameWnd和CMDIChildWnd。这些类都是从CObject...

    数据结构课程设计实验报告-.pdf

    程序源代码中,`C试验品View`类包含了大部分与用户交互的逻辑。`OnCreate()`函数用于初始化界面,`OnLButtonDown()`处理鼠标点击事件,`OnDraw()`绘制桌面和牌的图形,而`OnButton1Clicked()`和`OnButton2Clicked()`...

    VC MFC类中各种类的指针的获取和应用.doc

    在MFC中,应用程序的结构通常基于文档/视图架构,涉及到多个核心类如`CWinApp`、`CMainFrame`、`CChildFrame`、`CDocument`和`CView`等。本文将详细介绍如何在MFC类中获取不同类型的指针及其应用场景。 #### 获取`...

    MFC 俄罗斯方块源代码

    3. **4_1.cpp**:可能包含主窗口类`C4_1App`的实现,负责整个程序的启动、关闭以及其他应用程序级别的操作。 4. **MainFrm.cpp**:`CMainFrame`类的实现,定义了主框架窗口,可能包含了菜单、工具栏等界面元素的...

    VC++的应用程序框架

    本文将详细介绍 MFC 应用程序中的几个核心概念:应用类、主框架窗口类、文档类、视图类以及文档模板类之间的关系。 #### 1. 应用类 (CWinApp) - **定义**:每个 MFC 应用程序都有一个继承自 `CWinApp` 的应用类。...

    MFC向导示例

    - `CMainFrame` 类:主框架窗口类,通常继承自`CFrameWnd`或`CMDIFrameWnd`,定义了主窗口的行为。 - `CDocument` 和 `CView` 类:文档和视图类,负责数据处理和显示。 - `.rc` 文件:资源脚本文件,包含了菜单、...

    MFC应用程序向导生成关键类.pdf

    总结来说,`CWinApp`、`CMainFrame`、`CView` 和 `CDocument` 是 MFC 应用程序中四个核心类,它们分别对应着应用程序管理、主窗口框架、视图显示以及文档数据管理。通过这些类及其成员函数,开发者可以构建出复杂且...

    MFC句柄、指针总结(转)

    在MFC(Microsoft Foundation Classes)编程中,句柄和指针是两个非常关键的概念。...在实际编程中,应根据具体需求灵活运用这些方法,同时注意处理好线程同步和类型转换等问题,以确保代码的稳定性和正确性。

    Filezilla 源码实现分析

    FileZilla的源代码根据功能的不同被分为几个主要类别: - **Kernel**:这部分包含了客户端的核心逻辑处理文件,如`CommandQueue.cpp`、`FileZilla.cpp`等。 - **定义与配置**:这部分文件包含了各种常量定义和配置...

Global site tag (gtag.js) - Google Analytics