source: trunk/Utilities/CaptureClock/MainDialog.h @ 105

Last change on this file since 105 was 105, checked in by roman, 10 years ago

online result submission

  • Property svn:keywords set to Id
File size: 23.9 KB
Line 
1////////////////////////////////////////////////////////////
2// Copyright (C) Roman Ryltsov, 2012
3// Created by Roman Ryltsov roman@alax.info
4//
5// $Id: MainDialog.h 105 2012-08-26 18:05:22Z roman $
6
7#pragma once
8
9#include "rodshow.h"
10#include "rowinhttp.h"
11#include "rocrypt.h"
12#include "AboutDialog.h"
13
14////////////////////////////////////////////////////////////
15// CFilterData
16
17class CFilterData
18{
19public:
20        CComPtr<IMoniker> m_pMoniker;
21        CStringW m_sMonikerDisplayName;
22        CComPtr<IPropertyBag> m_pPropertyBag;
23        CStringW m_sFriendlyName;
24
25        const CComPtr<IPropertyBag>& PropertyBagNeeded()
26        {
27                if(!m_pPropertyBag)
28                {
29                        _A(m_pMoniker);
30                        __C(m_pMoniker->BindToStorage(NULL, NULL, __uuidof(IPropertyBag), (VOID**) &m_pPropertyBag));
31                        _A(m_pPropertyBag);
32                }
33                return m_pPropertyBag;
34        }
35
36public:
37// CFilterData
38        CFilterData() throw()
39        {
40        }
41        CFilterData(IMoniker* pMoniker) throw() :
42                m_pMoniker(pMoniker)
43        {
44        }
45        const CComPtr<IMoniker>& GetMoniker() const throw()
46        {
47                return m_pMoniker;
48        }
49        CStringW GetMonikerDisplayName()
50        {
51                _A(m_pMoniker);
52                if(m_sMonikerDisplayName.IsEmpty())
53                        m_sMonikerDisplayName = _FilterGraphHelper::GetMonikerDisplayName(m_pMoniker);
54                return m_sMonikerDisplayName;
55        }
56        CStringW GetFriendlyName()
57        {
58                if(m_sFriendlyName.IsEmpty())
59                        m_sFriendlyName = _FilterGraphHelper::ReadPropertyBagString(PropertyBagNeeded(), L"FriendlyName");
60                return m_sFriendlyName;
61        }
62        CComPtr<IBaseFilter> CreateBaseFilterInstance() const
63        {
64                _A(m_pMoniker);
65                CComPtr<IBaseFilter> pBaseFilter;
66                __C(m_pMoniker->BindToObject(NULL, NULL, __uuidof(IBaseFilter), (VOID**) &pBaseFilter));
67                return pBaseFilter;
68        }
69};
70
71////////////////////////////////////////////////////////////
72// CFilterDataListT
73
74template <typename _FilterData, const GUID* t_pCategory>
75class CFilterDataListT :
76        public CRoListT<_FilterData>
77{
78public:
79        typedef _FilterData CFilterData;
80
81public:
82// CFilterDataListT
83        VOID Initialize()
84        {
85                RemoveAll();
86                CComPtr<ICreateDevEnum> pCreateDevEnum;
87                __C(pCreateDevEnum.CoCreateInstance(CLSID_SystemDeviceEnum));
88                CComPtr<IEnumMoniker> pEnumMoniker;
89                __C(pCreateDevEnum->CreateClassEnumerator(*t_pCategory, &pEnumMoniker, 0));
90                CComPtr<IMoniker> pMoniker;
91                while(pEnumMoniker->Next(1, &pMoniker, NULL) == S_OK)
92                {
93                        _W(AddTail(_FilterData(pMoniker)));
94                        pMoniker.Release();
95                }
96                #pragma region Duplicate Suffixes
97                CRoMapT<CStringW, CRoArrayT<_FilterData*>, CStringElementTraitsI<CStringW>> FriendlyNameMap;
98                for(POSITION Position = GetHeadPosition(); Position; GetNext(Position))
99                {
100                        _FilterData& FilterData = GetAt(Position);
101                        const CStringW sFriendlyName = FilterData.GetFriendlyName();
102                        _W(FriendlyNameMap[sFriendlyName].Add(&FilterData) >= 0);
103                }
104                for(POSITION Position = FriendlyNameMap.GetStartPosition(); Position; FriendlyNameMap.GetNext(Position))
105                {
106                        const CStringW& sFriendlyName = FriendlyNameMap.GetKeyAt(Position);
107                        CRoArrayT<_FilterData*>& Array = FriendlyNameMap.GetValueAt(Position);
108                        if(Array.GetCount() <= 1)
109                                continue;
110                        for(SIZE_T nIndex = 0; nIndex < Array.GetCount(); nIndex++)
111                                Array[nIndex]->m_sFriendlyName = AtlFormatStringT<CStringW>(L"%s #%d", sFriendlyName, nIndex + 1);
112                }
113                #pragma endregion
114        }
115        POSITION LookupMonikerDisplayName(LPCWSTR pszMonikerDisplayName)
116        {
117                _A(pszMonikerDisplayName);
118                for(POSITION Position = GetHeadPosition(); Position; GetNext(Position))
119                        if(GetAt(Position).GetMonikerDisplayName().CompareNoCase(pszMonikerDisplayName) == 0)
120                                return Position;
121                return NULL;
122        }
123        POSITION LookupMonikerDisplayName(CAtlRegExp<CAtlRECharTraitsW>& Expression)
124        {
125                CAtlREMatchContext<CAtlRECharTraitsW> MatchContext;
126                for(POSITION Position = GetHeadPosition(); Position; GetNext(Position))
127                        if(Expression.Match(GetAt(Position).GetMonikerDisplayName(), &MatchContext))
128                                return Position;
129                return NULL;
130        }
131        POSITION LookupFriendlyName(LPCWSTR pszFriendlyName)
132        {
133                _A(pszFriendlyName);
134                for(POSITION Position = GetHeadPosition(); Position; GetNext(Position))
135                        if(GetAt(Position).GetFriendlyName().Compare(pszFriendlyName) == 0)
136                                return Position;
137                return NULL;
138        }
139        POSITION LookupFriendlyName(CAtlRegExp<CAtlRECharTraitsW>& Expression)
140        {
141                CAtlREMatchContext<CAtlRECharTraitsW> MatchContext;
142                for(POSITION Position = GetHeadPosition(); Position; GetNext(Position))
143                        if(Expression.Match(GetAt(Position).GetFriendlyName(), &MatchContext))
144                                return Position;
145                return NULL;
146        }
147        POSITION LookupGenericName(LPCWSTR pszGenericName)
148        {
149                _A(pszGenericName);
150                POSITION Position;
151                Position = LookupMonikerDisplayName(pszGenericName);
152                if(Position)
153                        return Position;
154                Position = LookupFriendlyName(pszGenericName);
155                if(Position)
156                        return Position;
157                CAtlRegExp<CAtlRECharTraitsW> Expression;
158                if(Expression.Parse(pszGenericName, TRUE) == REPARSE_ERROR_OK)
159                {
160                        Position = LookupMonikerDisplayName(Expression);
161                        if(Position)
162                                return Position;
163                        Position = LookupFriendlyName(Expression);
164                        if(Position)
165                                return Position;
166                }
167                return NULL;
168        }
169};
170
171////////////////////////////////////////////////////////////
172// CAudioCaptureSourceData, CAudioCaptureSourceDataList
173
174typedef CFilterData CAudioCaptureSourceData;
175typedef CFilterDataListT<CAudioCaptureSourceData, &CLSID_AudioInputDeviceCategory> CAudioCaptureSourceDataList;
176
177////////////////////////////////////////////////////////////
178// CVideoCaptureSourceData, CVideoCaptureSourceDataList
179
180typedef CFilterData CVideoCaptureSourceData;
181typedef CFilterDataListT<CVideoCaptureSourceData, &CLSID_VideoInputDeviceCategory> CVideoCaptureSourceDataList;
182
183////////////////////////////////////////////////////////////
184// CMainDialog
185
186class CMainDialog : 
187        public CAxDialogImpl<CMainDialog>
188{
189public:
190        enum { IDD = IDD_MAIN };
191
192BEGIN_MSG_MAP_EX(CMainDialog)
193        CHAIN_MSG_MAP(CAxDialogImpl<CMainDialog>)
194        MSG_WM_INITDIALOG(OnInitDialog)
195        MSG_WM_DESTROY(OnDestroy)
196        MSG_WM_TIMER(OnTimer)
197        MSG_WM_SYSCOMMAND(OnSysCommand)
198        COMMAND_ID_HANDLER_EX(IDCANCEL, OnCommand)
199        COMMAND_HANDLER_EX(IDC_START, BN_CLICKED, OnStartClicked)
200        COMMAND_HANDLER_EX(IDC_STOP, BN_CLICKED, OnStopClicked)
201        REFLECT_NOTIFICATIONS()
202END_MSG_MAP()
203
204public:
205
206        ////////////////////////////////////////////////////////
207        // Timer Identifiers
208
209        enum 
210        {
211                TIMER_FIRST,
212                TIMER_UPDATE
213        };
214
215        ////////////////////////////////////////////////////////
216        // CRendererFilter
217
218        class ATL_NO_VTABLE CRendererFilter :
219                public CComObjectRootEx<CComMultiThreadModelNoCS>,
220                public CBaseFilterT<CRendererFilter>,
221                public CBasePersistT<CRendererFilter>,
222                public CAmFilterMiscFlagsT<CRendererFilter, AM_FILTER_MISC_FLAGS_IS_RENDERER>
223        {
224        public:
225                //enum { IDR = IDR_RENDERERFILTER };
226
227        DECLARE_NO_REGISTRY() //DECLARE_REGISTRY_RESOURCEID(IDR)
228
229        DECLARE_PROTECT_FINAL_CONSTRUCT()
230
231        //DECLARE_QI_TRACE(CRendererFilter)
232
233        BEGIN_COM_MAP(CRendererFilter)
234                COM_INTERFACE_ENTRY(IBaseFilter)
235                COM_INTERFACE_ENTRY(IMediaFilter)
236                COM_INTERFACE_ENTRY_IID(__uuidof(IPersist), IBaseFilter)
237                COM_INTERFACE_ENTRY(IAMFilterMiscFlags)
238        END_COM_MAP()
239
240                ////////////////////////////////////////////////////////
241                // CInputPin
242
243                class ATL_NO_VTABLE CInputPin :
244                        public CComObjectRootEx<CComMultiThreadModelNoCS>,
245                        public CInputPinT<CInputPin, CRendererFilter>
246                {
247                public:
248
249                //DECLARE_QI_TRACE(CRendererFilter::CInputPin)
250
251                BEGIN_COM_MAP(CInputPin)
252                        COM_INTERFACE_ENTRY(IPin)
253                        COM_INTERFACE_ENTRY(IMemInputPin)
254                END_COM_MAP()
255
256                private:
257                        GUID m_MajorType;
258
259                public:
260                // CInputPin
261                        CInputPin() throw() :
262                                m_MajorType(MEDIATYPE_NULL)
263                        {
264                                _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
265                        }
266                        ~CInputPin() throw()
267                        {
268                                _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
269                        }
270                        VOID EnumerateMediaTypes(CAtlList<CMediaType>& MediaTypeList) const
271                        {
272                                CRoCriticalSectionLock DataLock(GetDataCriticalSection());
273                                _A(m_MajorType != MEDIATYPE_NULL);
274                                AM_MEDIA_TYPE MediaType;
275                                ZeroMemory(&MediaType, sizeof MediaType);
276                                MediaType.majortype = m_MajorType;
277                                _W(MediaTypeList.AddTail(&MediaType));
278                        }
279                        BOOL CheckMediaType(const CMediaType& pMediaType) const throw()
280                        {
281                                _A(pMediaType);
282                                CRoCriticalSectionLock DataLock(GetDataCriticalSection());
283                                if(GetMediaTypeReference())
284                                        return GetMediaTypeReference().Compare(pMediaType);
285                                return pMediaType->majortype == m_MajorType;
286                        }
287                        VOID SetMajorType(const GUID& MajorType) throw()
288                        {
289                                CRoCriticalSectionLock DataLock(GetDataCriticalSection());
290                                _A(!GetMediaTypeReference());
291                                m_MajorType = MajorType;
292                        }
293                };
294
295        private:
296                CObjectPtr<CInputPin> m_pInputPin;
297                SIZE_T m_nMediaSampleCount;
298                REFERENCE_TIME m_nLastMediaSampleTime;
299
300        public:
301        // CRendererFilter
302                CRendererFilter() throw() :
303                        CBasePersistT<CRendererFilter>(GetDataCriticalSection())
304                {
305                        _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
306                }
307                ~CRendererFilter() throw()
308                {
309                        _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
310                }
311                HRESULT FinalConstruct() throw()
312                {
313                        _ATLTRY
314                        {
315                                m_pInputPin.Construct()->Initialize(this, L"Input");
316                                AddPin(m_pInputPin);
317                        }
318                        _ATLCATCH(Exception)
319                        {
320                                _C(Exception);
321                        }
322                        return S_OK;
323                }
324                VOID FinalRelease()
325                {
326                        m_pInputPin = NULL;
327                }
328                VOID CueFilter()
329                {
330                        CRoCriticalSectionLock DataLock(GetDataCriticalSection());
331                        m_nMediaSampleCount = 0;
332                        m_nLastMediaSampleTime = 0;
333                }
334                VOID ReceiveMediaSample(IPin* pPin, IMediaSample2* pMediaSample, HRESULT& nReceiveResult)
335                {
336                        _A(pPin && pMediaSample); 
337                        _A(nReceiveResult == S_OK);
338                        CMediaSampleProperties Properties(pMediaSample);
339                        CRoCriticalSectionLock DataLock(GetDataCriticalSection());
340                        m_nMediaSampleCount++;
341                        if(Properties.dwSampleFlags & AM_SAMPLE_TIMEVALID)
342                                m_nLastMediaSampleTime = Properties.tStart;
343                }
344                const CObjectPtr<CInputPin>& GetInputPin() const throw()
345                {
346                        return m_pInputPin;
347                }
348                VOID Initialize(const GUID& MajorType)
349                {
350                        GetInputPin()->SetMajorType(MajorType);
351                }
352                VOID GetData(SIZE_T& nMediaSampleCount, REFERENCE_TIME& nLastMediaSampleTime) const throw()
353                {
354                        CRoCriticalSectionLock DataLock(GetDataCriticalSection());
355                        nMediaSampleCount = m_nMediaSampleCount;
356                        nLastMediaSampleTime = m_nLastMediaSampleTime;
357                }
358        };
359
360private:
361        CRoComboBoxT<CFilterData, CRoListControlDataTraitsT> m_VideoDeviceComboBox;
362        CRoEdit m_VideoTimeEdit;
363        CRoComboBoxT<CFilterData, CRoListControlDataTraitsT> m_AudioDeviceComboBox;
364        CRoEdit m_AudioTimeEdit;
365        CRoEdit m_SystemTimeEdit;
366        CButton m_StartButton;
367        CButton m_StopButton;
368        CGenericFilterGraph m_FilterGraph;
369        CObjectPtr<CRendererFilter> m_pVideoRendererFilter;
370        CObjectPtr<CRendererFilter> m_pAudioRendererFilter;
371        CComPtr<IReferenceClock> m_pReferenceClock;
372        REFERENCE_TIME m_nAnchorTime;
373        CString m_sLog;
374        UINT m_nTimerEventIndex;
375
376public:
377// CMainDialog
378        CMainDialog()
379        {
380        }
381        VOID ReleaseFilterGraph()
382        {
383                if(m_FilterGraph.m_pMediaControl)
384                        _V(m_FilterGraph.m_pMediaControl->Stop());
385                m_FilterGraph.Release();
386                m_pVideoRendererFilter.Release();
387                m_pAudioRendererFilter.Release();
388                m_pReferenceClock.Release();
389        }
390        static CComPtr<IPin> GetCapturePin(IBaseFilter* pBaseFilter)
391        {
392                _A(pBaseFilter);
393                _FilterGraphHelper::CPinArray PinArray;
394                _FilterGraphHelper::GetFilterPins(pBaseFilter, PINDIR_OUTPUT, PinArray);
395                CComPtr<IPin> pCapturePin, pAssumedCapturePin;
396                for(SIZE_T nIndex = 0; nIndex < PinArray.GetCount(); nIndex++)
397                {
398                        const CComPtr<IPin>& pPin = PinArray[nIndex];
399                        if(!pAssumedCapturePin)
400                        {
401                                pAssumedCapturePin = pPin;
402                                // SUGG: Check Media Type
403                        }
404                        const CComQIPtr<IKsPropertySet> pKsPropertySet = pPin;
405                        if(pKsPropertySet)
406                        {
407                                GUID PinCategory = GUID_NULL;
408                                DWORD nPinCategorySize = 0;
409                                const HRESULT nGetResult = pKsPropertySet->Get(AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY, NULL, 0, &PinCategory, sizeof PinCategory, &nPinCategorySize);
410                                _Z4(atlTraceGeneral, 4, _T("nGetResult 0x%08x, nPinCategorySize %d, PinCategory %ls\n"), nGetResult, nPinCategorySize, _PersistHelper::StringFromIdentifier(PinCategory));
411                                if(SUCCEEDED(nGetResult))
412                                        if(nPinCategorySize == sizeof PinCategory && PinCategory == PIN_CATEGORY_CAPTURE)
413                                        {
414                                                pCapturePin = pPin;
415                                                break;
416                                        }
417                        }
418                }
419                return pCapturePin ? pCapturePin : pAssumedCapturePin;
420        }
421        VOID UpdateControls()
422        {
423                m_VideoDeviceComboBox.EnableWindow(m_FilterGraph.m_pFilterGraph == NULL);
424                m_VideoDeviceComboBox.GetWindow(GW_HWNDPREV).EnableWindow(m_VideoDeviceComboBox.IsWindowEnabled());
425                m_AudioDeviceComboBox.EnableWindow(m_FilterGraph.m_pFilterGraph == NULL);
426                m_AudioDeviceComboBox.GetWindow(GW_HWNDPREV).EnableWindow(m_AudioDeviceComboBox.IsWindowEnabled());
427                m_StartButton.EnableWindow(m_FilterGraph.m_pFilterGraph == NULL);
428                m_StopButton.EnableWindow(m_FilterGraph.m_pFilterGraph != NULL);
429        }
430
431// Window Message Handelrs
432        LRESULT OnInitDialog(HWND, LPARAM)
433        {
434                SetIcon(AtlLoadIconImage(IDI_MODULE, LR_DEFAULTCOLOR, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON)), TRUE);
435                SetIcon(AtlLoadIconImage(IDI_MODULE, LR_DEFAULTCOLOR, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON)), FALSE);
436                CMenuHandle Menu = GetSystemMenu(FALSE);
437                _W(Menu.AppendMenu(MF_SEPARATOR));
438                _W(Menu.AppendMenu(MF_STRING, ID_APP_ABOUT, _T("&About...")));
439                m_VideoDeviceComboBox = GetDlgItem(IDC_VIDEO_DEVICE);
440                CVideoCaptureSourceDataList VideoCaptureSourceDataList;
441                VideoCaptureSourceDataList.Initialize();
442                for(POSITION Position = VideoCaptureSourceDataList.GetHeadPosition(); Position; VideoCaptureSourceDataList.GetNext(Position))
443                {
444                        CFilterData& FilterData = VideoCaptureSourceDataList.GetAt(Position);
445                        m_VideoDeviceComboBox.AddString(CW2CT(FilterData.GetFriendlyName()), FilterData);
446                }
447                m_VideoDeviceComboBox.SetCurSel(0);
448                m_VideoTimeEdit = GetDlgItem(IDC_VIDEO_TIME);
449                m_AudioDeviceComboBox = GetDlgItem(IDC_AUDIO_DEVICE);
450                CAudioCaptureSourceDataList AudioCaptureSourceDataList;
451                AudioCaptureSourceDataList.Initialize();
452                for(POSITION Position = AudioCaptureSourceDataList.GetHeadPosition(); Position; AudioCaptureSourceDataList.GetNext(Position))
453                {
454                        CFilterData& FilterData = AudioCaptureSourceDataList.GetAt(Position);
455                        m_AudioDeviceComboBox.AddString(CW2CT(FilterData.GetFriendlyName()), FilterData);
456                }
457                m_AudioDeviceComboBox.SetCurSel(0);
458                m_AudioTimeEdit = GetDlgItem(IDC_AUDIO_TIME);
459                m_SystemTimeEdit = GetDlgItem(IDC_SYSTEM_TIME);
460                m_StartButton = GetDlgItem(IDC_START);
461                m_StopButton = GetDlgItem(IDC_STOP);
462                m_StopButton.EnableWindow(FALSE);
463                _W(CenterWindow());
464                UpdateControls();
465                #if _DEVELOPMENT
466                // TODO: ...
467                #endif // _DEVELOPMENT
468                return TRUE;
469        }
470        LRESULT OnDestroy() throw()
471        {
472                CWaitCursor WaitCursor;
473                ReleaseFilterGraph();
474                return 0;
475        }
476        LRESULT OnTimer(UINT_PTR nEvent)
477        {
478                switch(nEvent)
479                {
480                case TIMER_UPDATE:
481                        {
482                                // NOTE: A log item every half a minute
483                                const BOOL bLog = ++m_nTimerEventIndex % 30 == 0;
484                                CRoArrayT<CString> Array;
485                                REFERENCE_TIME nSystemTime;
486                                if(m_pReferenceClock)
487                                {
488                                        _V(m_pReferenceClock->GetTime(&nSystemTime));
489                                        nSystemTime -= m_nAnchorTime;
490                                        m_SystemTimeEdit.SetValue(AtlFormatString(_T("%s"), _FilterGraphHelper::FormatReferenceTime(nSystemTime)));
491                                        if(bLog)
492                                                Array.Add(AtlFormatString(_T("%I64d"), (nSystemTime + 5000i64 - 1) / 10000i64));
493                                }
494                                if(m_pVideoRendererFilter)
495                                {
496                                        SIZE_T nCount;
497                                        REFERENCE_TIME nTime;
498                                        m_pVideoRendererFilter->GetData(nCount, nTime);
499                                        m_VideoTimeEdit.SetValue(AtlFormatString(_T("%s (%s samples)"), _FilterGraphHelper::FormatReferenceTime(nTime), _StringHelper::FormatNumber((INT) nCount)));
500                                        if(bLog)
501                                        {
502                                                Array.Add(AtlFormatString(_T("%d"), nCount));
503                                                Array.Add(AtlFormatString(_T("%I64d"), (nTime + 5000i64 - 1) / 10000i64));
504                                                Array.Add(AtlFormatString(_T("%I64d"), ((nTime - nSystemTime) + 5000i64 - 1) / 10000i64));
505                                        }
506                                }
507                                if(m_pAudioRendererFilter)
508                                {
509                                        SIZE_T nCount;
510                                        REFERENCE_TIME nTime;
511                                        m_pAudioRendererFilter->GetData(nCount, nTime);
512                                        m_AudioTimeEdit.SetValue(AtlFormatString(_T("%s (%s samples)"), _FilterGraphHelper::FormatReferenceTime(nTime), _StringHelper::FormatNumber((INT) nCount)));
513                                        if(bLog)
514                                        {
515                                                Array.Add(AtlFormatString(_T("%d"), nCount));
516                                                Array.Add(AtlFormatString(_T("%I64d"), (nTime + 5000i64 - 1) / 10000i64));
517                                                Array.Add(AtlFormatString(_T("%I64d"), ((nTime - nSystemTime) + 5000i64 - 1) / 10000i64));
518                                        }
519                                }
520                                if(bLog && Array.GetCount() == 1 + 3 + 3)
521                                {
522                                        if(m_sLog.IsEmpty())
523                                        {
524                                                static LPCTSTR g_ppszHeader[] = 
525                                                {
526                                                        _T("System Time"),
527                                                        _T("Video Sample Count"),
528                                                        _T("Video Sample Time"),
529                                                        _T("Relative Video Sample Time"),
530                                                        _T("Audio Sample Count"),
531                                                        _T("Audio Sample Time"),
532                                                        _T("Relative Audio Sample Time"),
533                                                };
534                                                m_sLog.Append(_StringHelper::Join(g_ppszHeader, _T("\t")) + _T("\r\n"));
535                                        }
536                                        m_sLog.Append(_StringHelper::Join(Array, _T("\t")) + _T("\r\n"));
537                                }
538                        }
539                        break;
540                default:
541                        SetMsgHandled(FALSE);
542                }
543                return 0;
544        }
545        LRESULT OnSysCommand(UINT nCommand, CPoint)
546        {
547                switch(nCommand)
548                {
549                case ID_APP_ABOUT:
550                        {
551                                CAboutDialog Dialog;
552                                Dialog.DoModal(m_hWnd);
553                        }
554                        break;
555                default:
556                        SetMsgHandled(FALSE);
557                }
558                return 0;
559        }
560        LRESULT OnCommand(UINT, INT nIdentifier, HWND)
561        {
562                _W(EndDialog(nIdentifier));
563                return 0;
564        }
565        LRESULT OnStartClicked(UINT, INT, HWND)
566        {
567                CWaitCursor WaitCursor;
568                m_StartButton.EnableWindow(FALSE);
569                _ATLTRY
570                {
571                        ReleaseFilterGraph();
572                        m_FilterGraph.CoCreateInstance();
573                        m_FilterGraph.SetShowDestructorMessageBox(TRUE);
574                        // SUGG: Video/Audio Only Capture?
575                        _A(m_VideoDeviceComboBox.GetCurSel() >= 0 && m_AudioDeviceComboBox.GetCurSel() >= 0);
576                        #pragma region Video
577                        {
578                                CFilterData& VideoFilterData = m_VideoDeviceComboBox.GetItemData(m_VideoDeviceComboBox.GetCurSel());
579                                const CComPtr<IBaseFilter> pSourceBaseFilter = VideoFilterData.CreateBaseFilterInstance();
580                                __C(m_FilterGraph->AddFilter(pSourceBaseFilter, CT2CW(_T("Video Source"))));
581                                CObjectPtr<CRendererFilter> pRendererFilter;
582                                pRendererFilter.Construct();
583                                pRendererFilter->Initialize(MEDIATYPE_Video);
584                                __C(m_FilterGraph->AddFilter(pRendererFilter, CT2CW(_T("Video Renderer"))));
585                                __C(m_FilterGraph->Connect(GetCapturePin(pSourceBaseFilter), pRendererFilter->GetInputPin()));
586                                m_pVideoRendererFilter = pRendererFilter;
587                        }
588                        #pragma endregion
589                        #pragma region Audio
590                        {
591                                CFilterData& AudioFilterData = m_AudioDeviceComboBox.GetItemData(m_AudioDeviceComboBox.GetCurSel());
592                                const CComPtr<IBaseFilter> pSourceBaseFilter = AudioFilterData.CreateBaseFilterInstance();
593                                __C(m_FilterGraph->AddFilter(pSourceBaseFilter, CT2CW(_T("Audio Source"))));
594                                CObjectPtr<CRendererFilter> pRendererFilter;
595                                pRendererFilter.Construct();
596                                pRendererFilter->Initialize(MEDIATYPE_Audio);
597                                __C(m_FilterGraph->AddFilter(pRendererFilter, CT2CW(_T("Audio Renderer"))));
598                                const CComPtr<IPin> pCapturePin = GetCapturePin(pSourceBaseFilter);
599                                _ATLTRY
600                                {
601                                        const CComQIPtr<IAMBufferNegotiation> pAmBufferNegotiation = pCapturePin;
602                                        __D(pAmBufferNegotiation, E_NOINTERFACE);
603                                        const CComQIPtr<IAMStreamConfig> pAmStreamConfig = pCapturePin;
604                                        __D(pAmStreamConfig, E_NOINTERFACE);
605                                        CMediaType pMediaType;
606                                        __C(pAmStreamConfig->GetFormat(&pMediaType));
607                                        const CWaveFormatEx* pWaveFormatEx = pMediaType.GetWaveFormatEx();
608                                        __D(pWaveFormatEx, E_UNNAMED);
609                                        ALLOCATOR_PROPERTIES Properties;
610                                        Properties.cbAlign = -1;
611                                        Properties.cbBuffer = pWaveFormatEx->nAvgBytesPerSec / 10; // 100 millisecond
612                                        Properties.cbPrefix = -1;
613                                        Properties.cBuffers = 50; // 50 buffers (5 seconds in total)
614                                        __C(pAmBufferNegotiation->SuggestAllocatorProperties(&Properties));
615                                }
616                                _ATLCATCHALL()
617                                {
618                                        _Z_EXCEPTION();
619                                }
620                                __C(m_FilterGraph->Connect(pCapturePin, pRendererFilter->GetInputPin()));
621                                m_pAudioRendererFilter = pRendererFilter;
622                        }
623                        #pragma endregion
624                        m_FilterGraph.SetShowDestructorMessageBox(FALSE);
625                        __C(m_pReferenceClock.CoCreateInstance(CLSID_SystemClock));
626                        __C(m_pReferenceClock->GetTime(&m_nAnchorTime));
627                        __C(m_FilterGraph.m_pMediaControl->Run());
628                        m_sLog.Empty();
629                        m_nTimerEventIndex = 0;
630                        SetTimer(TIMER_UPDATE, 1000);
631                }
632                _ATLCATCHALL()
633                {
634                        ReleaseFilterGraph();
635                        UpdateControls();
636                        _ATLRETHROW;
637                }
638                UpdateControls();
639                return 0;
640        }
641        LRESULT OnStopClicked(UINT, INT, HWND)
642        {
643                CWaitCursor WaitCursor;
644                m_StopButton.EnableWindow(FALSE);
645                _ATLTRY
646                {
647                        KillTimer(TIMER_UPDATE);
648                        ReleaseFilterGraph();
649                }
650                _ATLCATCHALL()
651                {
652                        UpdateControls();
653                        _ATLRETHROW;
654                }
655                UpdateControls();
656                #if !_DEVELOPMENT
657                        if(m_sLog.IsEmpty())
658                                return 0; // No Effective Log
659                #endif // !_DEVELOPMENT
660                #pragma region Log
661                CString sLog;
662                TCHAR pszComputerName[256] = { 0 };
663                DWORD nComputerNameLength = DIM(pszComputerName);
664                _W(GetComputerName(pszComputerName, &nComputerNameLength));
665                sLog += AtlFormatString(_T("Computer Name") _T("\t") _T("%s") _T("\r\n"), pszComputerName);
666                OSVERSIONINFO VersionInformation = { sizeof VersionInformation };
667                _W(GetVersionEx(&VersionInformation));
668                _A(VersionInformation.dwPlatformId == VER_PLATFORM_WIN32_NT);
669                sLog += AtlFormatString(_T("Windows Version") _T("\t") _T("%d.%d.%d %s") _T("\r\n"), VersionInformation.dwMajorVersion, VersionInformation.dwMinorVersion, VersionInformation.dwBuildNumber, VersionInformation.szCSDVersion);
670                CFilterData& VideoFilterData = m_VideoDeviceComboBox.GetItemData(m_VideoDeviceComboBox.GetCurSel());
671                sLog += AtlFormatString(_T("Video Device") _T("\t") _T("%ls") _T("\t") _T("%ls") _T("\r\n"), VideoFilterData.GetFriendlyName(), VideoFilterData.GetMonikerDisplayName());
672                CFilterData& AudioFilterData = m_AudioDeviceComboBox.GetItemData(m_AudioDeviceComboBox.GetCurSel());
673                sLog += AtlFormatString(_T("Audio Device") _T("\t") _T("%ls") _T("\t") _T("%ls") _T("\r\n"), AudioFilterData.GetFriendlyName(), AudioFilterData.GetMonikerDisplayName());
674                sLog += _T("\r\n");
675                sLog += m_sLog;
676                #pragma endregion
677                SetClipboardText(m_hWnd, sLog);
678                MessageBeep(MB_OK);
679                #if !_DEVELOPMENT
680                        if(AtlMessageBoxEx(m_hWnd, 
681                                        _T("The runtime execution data was placed onto clipboard in tab separated value format, you can paste it into a text or a spreadsheet document for further processing or analysis.") _T("\r\n")
682                                        _T("\r\n")
683                                        _T("Would you also like to share the results and post them to the website?"), IDS_CONFIRMATION, MB_ICONINFORMATION | MB_YESNO | ((m_nTimerEventIndex < 60) ? MB_DEFBUTTON2 : 0))  != IDYES)
684                                return 0; // No Submission
685                #else
686                        return 0; // No Submission
687                #endif // !_DEVELOPMENT
688                #pragma region HTTP POST
689                CWinHttpPostData PostData;
690                PostData.AddValue(_T("s"), AtlLoadString(IDS_PROJNAME));
691                CStringA sTextA = Utf8StringFromString(sLog);
692                PostData.AddValue(_T("b"), _Base64Helper::Encode<CString>((const BYTE*) (LPCSTR) sTextA, sTextA.GetLength(), _Base64Helper::FLAG_NOPAD | _Base64Helper::FLAG_NOCRLF));
693                CWinHttpSessionHandle Session = OpenWinHttpSessionHandle(AtlLoadString(IDS_PROJNAME));
694                __E(Session);
695                CWinHttpConnectionHandle Connection = Session.Connect(CStringW(_T("alax.info")));
696                __E(Connection);
697                CWinHttpRequestHandle Request = Connection.OpenRequest(CStringW(_T("POST")), CStringW(_T("/post.php")));
698                __E(Request);
699                CStringW sPostHeaders = PostData.GetHeaders();
700                CStringA sPostData(PostData.GetValue());
701                __E(Request.Send(sPostHeaders, -1, const_cast<LPSTR>((LPCSTR) sPostData), sPostData.GetLength(), sPostData.GetLength()));
702                __E(Request.ReceiveResponse());
703                DWORD nStatusCode = 0;
704                __E(Request.QueryNumberHeader(WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, nStatusCode));
705                __D(nStatusCode == HTTP_STATUS_OK, MAKE_HRESULT(SEVERITY_ERROR, FACILITY_HTTP, nStatusCode));
706                #pragma endregion
707                AtlMessageBoxEx(m_hWnd, _T("The results were posted to the website, thank you for sharing them!"), IDS_INFORMATION, MB_ICONINFORMATION | MB_OK);
708                return 0;
709        }
710};
Note: See TracBrowser for help on using the repository browser.