source: trunk/Utilities/WindowsMediaCodecList/MainDialog.h @ 67

Last change on this file since 67 was 67, checked in by roman, 10 years ago
  • Property svn:keywords set to Id
File size: 46.6 KB
Line 
1////////////////////////////////////////////////////////////
2// Copyright (C) Roman Ryltsov, 2009-2012
3// Created by Roman Ryltsov roman@alax.info
4//
5// $Id: MainDialog.h 67 2012-05-25 20:31:49Z roman $
6
7#pragma once
8
9#include <wmsdk.h>
10#include "rodshow.h"
11#include "rocontrols.h"
12#include "rocrypt.h"
13#include "rowinhttp.h"
14#include "AboutDialog.h"
15
16#pragma comment(lib, "wmvcore.lib")
17
18////////////////////////////////////////////////////////////
19// CMainDialog
20
21class CMainDialog : 
22        public CDialogImpl<CMainDialog>,
23        public CDialogResize<CMainDialog>,
24        public CWindowWithPrivateMessagesT<CMainDialog>
25{
26public:
27        enum { IDD = IDD_MAIN };
28
29BEGIN_MSG_MAP_EX(CMainDialog)
30        //CHAIN_MSG_MAP(CDialogImpl<CMainDialog>)
31        CHAIN_MSG_MAP(CDialogResize<CMainDialog>)
32        CHAIN_MSG_MAP(CWindowWithPrivateMessagesT<CMainDialog>)
33        MSG_WM_INITDIALOG(OnInitDialog)
34        MSG_WM_SYSCOMMAND(OnSysCommand)
35        COMMAND_ID_HANDLER_EX(IDCANCEL, OnCancel)
36        MSG_TVN_GETINFOTIP(IDC_TREE, OnTreeGetInfoTip)
37        MSG_TVN_SELCHANGED(IDC_TREE, OnTreeViewSelChanged)
38        //COMMAND_ID_HANDLER_EX(ID_APP_ABOUT, OnAppAbout)
39        // SUGG: List view column sort
40        MSG_LVN_GETINFOTIP(IDC_LIST, OnListGetInfoTip)
41        COMMAND_ID_HANDLER_EX(IDC_COPY, OnCopyButtonClicked)
42        COMMAND_ID_HANDLER_EX(IDC_SUBMIT, OnSubmitButtonClicked)
43        REFLECT_NOTIFICATIONS()
44END_MSG_MAP()
45
46BEGIN_DLGRESIZE_MAP(CMainDialog)
47        DLGRESIZE_CONTROL(IDC_TREE, DLSZ_SIZE_Y)
48        DLGRESIZE_CONTROL(IDC_LIST, DLSZ_SIZE_X | DLSZ_SIZE_Y)
49        DLGRESIZE_CONTROL(IDCANCEL, DLSZ_MOVE_X)
50        DLGRESIZE_CONTROL(IDC_COPY, DLSZ_MOVE_X)
51        DLGRESIZE_CONTROL(IDC_SUBMIT, DLSZ_MOVE_X)
52        DLGRESIZE_CONTROL(IDC_OSVERSION, DLSZ_MOVE_X | DLSZ_MOVE_Y)
53END_DLGRESIZE_MAP()
54
55public:
56
57        ////////////////////////////////////////////////////
58        // CWmCodecInfo3
59
60        class CWmCodecInfo3 :
61                public CComQIPtr<IWMCodecInfo3>
62        {
63        public:
64        // CWmCodecInfo3
65                CWmCodecInfo3(IWMCodecInfo3* pWmCodecInfo3 = NULL) throw() :
66                        CComQIPtr<IWMCodecInfo3>(pWmCodecInfo3)
67                {
68                }
69                CWmCodecInfo3(IUnknown* pUnknown) throw() :
70                        CComQIPtr<IWMCodecInfo3>(pUnknown)
71                {
72                }
73                HRESULT GetDwordCodecProperty(const GUID& MajorType, DWORD nCodecIndex, LPCWSTR pszName, DWORD& nValue) const throw()
74                {
75                        _A(pszName);
76                        WMT_ATTR_DATATYPE nType = (WMT_ATTR_DATATYPE) -1;
77                        DWORD nValueSize = sizeof nValue;
78                        _C(p->GetCodecProp(MajorType, nCodecIndex, pszName, &nType, (BYTE*) &nValue, &nValueSize));
79                        _D(nType == WMT_TYPE_DWORD && nValueSize == sizeof nValue, E_UNNAMED);
80                        return S_OK;
81                }
82                DWORD GetDwordCodecProperty(const GUID& MajorType, DWORD nCodecIndex, LPCWSTR pszName) const
83                {
84                        DWORD nValue;
85                        __C(GetDwordCodecProperty(MajorType, nCodecIndex, pszName, nValue));
86                        return nValue;
87                }
88                HRESULT GetBoolCodecProperty(const GUID& MajorType, DWORD nCodecIndex, LPCWSTR pszName, BOOL& bValue) const throw()
89                {
90                        _A(pszName);
91                        WMT_ATTR_DATATYPE nType = (WMT_ATTR_DATATYPE) -1;
92                        DWORD nValueSize = sizeof bValue;
93                        _C(p->GetCodecProp(MajorType, nCodecIndex, pszName, &nType, (BYTE*) &bValue, &nValueSize));
94                        _D(nType == WMT_TYPE_BOOL && nValueSize == sizeof bValue, E_UNNAMED);
95                        return S_OK;
96                }
97                BOOL GetBoolCodecProperty(const GUID& MajorType, DWORD nCodecIndex, LPCWSTR pszName) const
98                {
99                        BOOL bValue;
100                        __C(GetBoolCodecProperty(MajorType, nCodecIndex, pszName, bValue));
101                        return bValue;
102                }
103                HRESULT GetDwordCodecEnumerationSetting(const GUID& MajorType, DWORD nCodecIndex, LPCWSTR pszName, DWORD& nValue) const throw()
104                {
105                        _A(pszName);
106                        WMT_ATTR_DATATYPE nType = (WMT_ATTR_DATATYPE) -1;
107                        DWORD nValueSize = sizeof nValue;
108                        _C(p->GetCodecEnumerationSetting(MajorType, nCodecIndex, pszName, &nType, (BYTE*) &nValue, &nValueSize));
109                        _D(nType == WMT_TYPE_DWORD && nValueSize == sizeof nValue, E_UNNAMED);
110                        return S_OK;
111                }
112                DWORD GetDwordCodecEnumerationSetting(const GUID& MajorType, DWORD nCodecIndex, LPCWSTR pszName) const
113                {
114                        DWORD nValue;
115                        __C(GetDwordCodecEnumerationSetting(MajorType, nCodecIndex, pszName, nValue));
116                        return nValue;
117                }
118                HRESULT GetBoolCodecEnumerationSetting(const GUID& MajorType, DWORD nCodecIndex, LPCWSTR pszName, BOOL& bValue) const throw()
119                {
120                        _A(pszName);
121                        WMT_ATTR_DATATYPE nType = (WMT_ATTR_DATATYPE) -1;
122                        DWORD nValueSize = sizeof bValue;
123                        _C(p->GetCodecEnumerationSetting(MajorType, nCodecIndex, pszName, &nType, (BYTE*) &bValue, &nValueSize));
124                        _D(nType == WMT_TYPE_BOOL && nValueSize == sizeof bValue, E_UNNAMED);
125                        return bValue;
126                }
127                BOOL GetBoolCodecEnumerationSetting(const GUID& MajorType, DWORD nCodecIndex, LPCWSTR pszName) const
128                {
129                        BOOL bValue;
130                        __C(GetBoolCodecEnumerationSetting(MajorType, nCodecIndex, pszName, bValue));
131                        return bValue;
132                }
133                HRESULT SetDwordCodecEnumerationSetting(const GUID& MajorType, DWORD nCodecIndex, LPCWSTR pszName, DWORD nValue) const throw()
134                {
135                        return p->SetCodecEnumerationSetting(MajorType, nCodecIndex, pszName, WMT_TYPE_DWORD, (const BYTE*) &nValue, sizeof nValue);
136                }
137                HRESULT SetBoolCodecEnumerationSetting(const GUID& MajorType, DWORD nCodecIndex, LPCWSTR pszName, BOOL nValue) const throw()
138                {
139                        return p->SetCodecEnumerationSetting(MajorType, nCodecIndex, pszName, WMT_TYPE_BOOL, (const BYTE*) &nValue, sizeof nValue);
140                }
141        };
142
143        ////////////////////////////////////////////////////
144        // CEnumerationSetting
145
146        class CEnumerationSetting
147        {
148        public:
149                CStringW m_sName;
150                WMT_ATTR_DATATYPE m_nType;
151                CHeapPtr<BYTE> m_pnData;
152                SIZE_T m_nDataSize;
153
154        public:
155        // CEnumerationSetting
156                CEnumerationSetting() throw()
157                {
158                }
159                explicit CEnumerationSetting(const CStringW& sName, DWORD nValue) :
160                        m_sName(sName)
161                {
162                        m_nType = WMT_TYPE_DWORD;
163                        m_nDataSize = sizeof (DWORD);
164                        __D(m_pnData.Allocate(m_nDataSize), E_OUTOFMEMORY);
165                        *((DWORD*) (BYTE*) m_pnData) = nValue;
166                }
167                explicit CEnumerationSetting(const CStringW& sName, BOOL bValue) :
168                        m_sName(sName)
169                {
170                        m_nType = WMT_TYPE_BOOL;
171                        m_nDataSize = sizeof (BOOL);
172                        __D(m_pnData.Allocate(m_nDataSize), E_OUTOFMEMORY);
173                        *((BOOL*) (BYTE*) m_pnData) = bValue;
174                }
175                CEnumerationSetting(const CEnumerationSetting& EnumerationSetting)
176                {
177                        m_sName = EnumerationSetting.m_sName;
178                        m_nType = EnumerationSetting.m_nType;
179                        if(EnumerationSetting.m_nDataSize)
180                        {
181                                __D(m_pnData.Allocate(EnumerationSetting.m_nDataSize), E_OUTOFMEMORY);
182                                CopyMemory(m_pnData, EnumerationSetting.m_pnData, EnumerationSetting.m_nDataSize);
183                        }
184                        m_nDataSize = EnumerationSetting.m_nDataSize;
185                }
186                CString GetValueString() const
187                {
188                        switch(m_nType)
189                        {
190                        case WMT_TYPE_DWORD:
191                                return AtlFormatString(_T("%d"), *((const DWORD*) (const BYTE*) m_pnData));
192                        case WMT_TYPE_BOOL:
193                                return AtlFormatString(_T("%d"), *((const BOOL*) (const BYTE*) m_pnData));
194                        default:
195                                _A(FALSE);
196                        }
197                        return (LPCTSTR) NULL;
198                }
199        };
200
201        ////////////////////////////////////////////////////
202        // CEnumerationSettingList
203
204        class CEnumerationSettingList :
205                public CAtlList<CEnumerationSetting>
206        {
207        public:
208                CString m_sName;
209
210        public:
211        // CEnumerationSettingList
212                CEnumerationSettingList& operator = (const CEnumerationSettingList& EnumerationSettingList)
213                {
214                        RemoveAll();
215                        for(POSITION Position = EnumerationSettingList.GetHeadPosition(); Position; EnumerationSettingList.GetNext(Position))
216                                AddTail(EnumerationSettingList.GetAt(Position));
217                        m_sName = EnumerationSettingList.m_sName;
218                        return *this;
219                }
220        };
221
222        ////////////////////////////////////////////////////
223        // CCodecFormatData
224
225        class CCodecFormatData
226        {
227        public:
228                DWORD m_nIndex;
229                CStringW m_sDescription;
230                CComPtr<IWMStreamConfig> m_pWmStreamConfig;
231                CMediaType m_pMediaType;
232
233        public:
234        // CCodecFormatData
235                CCodecFormatData() throw() :
236                        m_nIndex(0)
237                {
238                }
239                VOID Initialize(DWORD nIndex, const CStringW& sDescription, IWMStreamConfig* pWmStreamConfig, const CMediaType& pMediaType)
240                {
241                        m_nIndex = nIndex;
242                        m_sDescription = sDescription;
243                        m_pWmStreamConfig = pWmStreamConfig;
244                        m_pMediaType = pMediaType;
245                }
246                CString GetDescription() const
247                {
248                        if(m_sDescription.IsEmpty())
249                                return _T("(no description)");
250                        return CString(m_sDescription);
251                }
252        };
253
254        typedef CAtlList<CCodecFormatData> CCodecFormatDataList;
255
256        ////////////////////////////////////////////////////
257        // CCodecData
258
259        class CCodecData
260        {
261        public:
262                CComPtr<IWMCodecInfo2> m_pWmCodecInfo2;
263                GUID m_MajorType;
264                DWORD m_nIndex;
265                CStringW m_sName;
266                CCodecFormatDataList m_CodecFormatDataList;
267
268        public:
269        // CCodecData
270                CCodecData() throw() :
271                        m_MajorType(GUID_NULL)
272                {
273                }
274                VOID Initialize(IWMCodecInfo2* pWmCodecInfo2, const GUID& MajorType, DWORD nIndex, const CStringW& sName)
275                {
276                        _A(pWmCodecInfo2);
277                        m_pWmCodecInfo2 = pWmCodecInfo2;
278                        m_MajorType = MajorType;
279                        m_nIndex = nIndex;
280                        m_sName = sName;
281                        m_CodecFormatDataList.RemoveAll();
282                        DWORD nFormatCount = 0;
283                        __C(pWmCodecInfo2->GetCodecFormatCount(MajorType, nIndex, &nFormatCount));
284                        _Z4(atlTraceGeneral, 4, _T("nFormatCount %d\n"), nFormatCount);
285                        for(DWORD nFormatIndex = 0; nFormatIndex < nFormatCount; nFormatIndex++)
286                        {
287                                DWORD nCodecFormatDescriptionLength = 0;
288                                __C(pWmCodecInfo2->GetCodecFormatDesc(MajorType, nIndex, nFormatIndex, NULL, NULL, &nCodecFormatDescriptionLength));
289                                _A(nCodecFormatDescriptionLength > 0);
290                                CComPtr<IWMStreamConfig> pWmStreamConfig;
291                                CStringW sFormatDescription;
292                                __C(pWmCodecInfo2->GetCodecFormatDesc(MajorType, nIndex, nFormatIndex, &pWmStreamConfig, sFormatDescription.GetBufferSetLength(nCodecFormatDescriptionLength - 1), &nCodecFormatDescriptionLength));
293                                _Z4(atlTraceGeneral, 4, _T("nFormatIndex %d, sFormatDescription \"%ls\"\n"), nFormatIndex, sFormatDescription);
294                                CComQIPtr<IWMMediaProps> pWmMediaProps = pWmStreamConfig;
295                                __D(pWmMediaProps, E_NOINTERFACE);
296                                DWORD nMediaTypeSize = 0;
297                                pWmMediaProps->GetMediaType(NULL, &nMediaTypeSize);
298                                CTempBuffer<WM_MEDIA_TYPE> pMediaType;
299                                pMediaType.AllocateBytes(nMediaTypeSize);
300                                __C(pWmMediaProps->GetMediaType(pMediaType, &nMediaTypeSize));
301                                _Z4(atlTraceGeneral, 4, _T("pMediaType->subtype %ls\n"), _PersistHelper::StringFromIdentifier(pMediaType->subtype));
302                                POSITION Position = m_CodecFormatDataList.AddTail();
303                                _ATLTRY
304                                {
305                                        CCodecFormatData& CodecFormatData = m_CodecFormatDataList.GetAt(Position);
306                                        CodecFormatData.Initialize(nFormatIndex, sFormatDescription, pWmStreamConfig, (const AM_MEDIA_TYPE*) (const WM_MEDIA_TYPE*) pMediaType);
307                                }
308                                _ATLCATCHALL()
309                                {
310                                        m_CodecFormatDataList.RemoveAt(Position);
311                                        _ATLRETHROW;
312                                }
313                        }
314                }
315                CString GetTitle() const
316                {
317                        return CString(m_sName);
318                }
319        };
320
321        ////////////////////////////////////////////////////
322        // CCodecDataList
323
324        class CCodecDataList :
325                public CAtlList<CCodecData>
326        {
327        public:
328                GUID m_MajorType;
329                CEnumerationSettingList m_EnumerationSettingList;
330
331        public:
332        // CCodecDataList
333                CCodecDataList() throw() :
334                        m_MajorType(GUID_NULL)
335                {
336                }
337                CCodecDataList(IWMCodecInfo2* pWmCodecInfo2, const GUID& MajorType)
338                {
339                        Initialize(pWmCodecInfo2, MajorType);
340                }
341                VOID Initialize(IWMCodecInfo2* pWmCodecInfo2, const GUID& MajorType)
342                {
343                        _A(pWmCodecInfo2);
344                        RemoveAll();
345                        m_MajorType = MajorType;
346                        _A(m_EnumerationSettingList.IsEmpty() && m_EnumerationSettingList.m_sName.IsEmpty());
347                        DWORD nCodecCount = 0;
348                        __C(pWmCodecInfo2->GetCodecInfoCount(MajorType, &nCodecCount));
349                        for(DWORD nCodecIndex = 0; nCodecIndex < nCodecCount; nCodecIndex++)
350                                _ATLTRY
351                                {
352                                        DWORD nCodecNameLength = 0;
353                                        __C(pWmCodecInfo2->GetCodecName(MajorType, nCodecIndex, NULL, &nCodecNameLength));
354                                        _A(nCodecNameLength > 0);
355                                        CStringW sCodecName;
356                                        if(nCodecNameLength)
357                                                __C(pWmCodecInfo2->GetCodecName(MajorType, nCodecIndex, sCodecName.GetBufferSetLength(nCodecNameLength - 1), &nCodecNameLength));
358                                        _Z4(atlTraceGeneral, 4, _T("nCodecIndex %d, sCodecName \"%ls\"\n"), nCodecIndex, sCodecName);
359                                        POSITION Position = AddTail();
360                                        _ATLTRY
361                                        {
362                                                CCodecData& CodecData = GetAt(Position);
363                                                CodecData.Initialize(pWmCodecInfo2, MajorType, nCodecIndex, sCodecName);
364                                        }
365                                        _ATLCATCHALL()
366                                        {
367                                                RemoveAt(Position);
368                                                _ATLRETHROW;
369                                        }
370                                }
371                                _ATLCATCHALL()
372                                {
373                                        _Z_EXCEPTION();
374                                }
375                }
376                VOID Initialize(CWmCodecInfo3 pWmCodecInfo3, const GUID& MajorType, const CEnumerationSettingList& EnumerationSettingList)
377                {
378                        _A(pWmCodecInfo3);
379                        RemoveAll();
380                        m_MajorType = MajorType;
381                        m_EnumerationSettingList = EnumerationSettingList;
382                        DWORD nCodecCount = 0;
383                        __C(pWmCodecInfo3->GetCodecInfoCount(MajorType, &nCodecCount));
384                        for(DWORD nCodecIndex = 0; nCodecIndex < nCodecCount; nCodecIndex++)
385                                _ATLTRY
386                                {
387                                        DWORD nCodecNameLength = 0;
388                                        __C(pWmCodecInfo3->GetCodecName(MajorType, nCodecIndex, NULL, &nCodecNameLength));
389                                        _A(nCodecNameLength > 0);
390                                        CStringW sCodecName;
391                                        if(nCodecNameLength)
392                                                __C(pWmCodecInfo3->GetCodecName(MajorType, nCodecIndex, sCodecName.GetBufferSetLength(nCodecNameLength - 1), &nCodecNameLength));
393                                        _Z4(atlTraceGeneral, 4, _T("nCodecIndex %d, sCodecName \"%ls\"\n"), nCodecIndex, sCodecName);
394                                        POSITION Position = AddTail();
395                                        _ATLTRY
396                                        {
397                                                CCodecData& CodecData = GetAt(Position);
398                                                for(POSITION EnumerationSettingPosition = EnumerationSettingList.GetHeadPosition(); EnumerationSettingPosition; EnumerationSettingList.GetNext(EnumerationSettingPosition))
399                                                {
400                                                        const CEnumerationSetting& EnumerationSetting = EnumerationSettingList.GetAt(EnumerationSettingPosition);
401                                                        if(FAILED(pWmCodecInfo3->SetCodecEnumerationSetting(MajorType, nCodecIndex, EnumerationSetting.m_sName, EnumerationSetting.m_nType, EnumerationSetting.m_pnData, (DWORD) EnumerationSetting.m_nDataSize)))
402                                                        {
403                                                                RemoveAt(Position);
404                                                                Position = NULL;
405                                                                break;
406                                                        }
407                                                }
408                                                if(!Position)
409                                                        continue;
410                                                CodecData.Initialize(pWmCodecInfo3, MajorType, nCodecIndex, sCodecName);
411                                        }
412                                        _ATLCATCHALL()
413                                        {
414                                                RemoveAt(Position);
415                                                _ATLRETHROW;
416                                        }
417                                }
418                                _ATLCATCHALL()
419                                {
420                                        _Z_EXCEPTION();
421                                }
422                }
423                CString GetTitle() const
424                {
425                        if(!m_EnumerationSettingList.m_sName.IsEmpty())
426                                return m_EnumerationSettingList.m_sName;
427                        return _T("Default");
428                }
429        };
430
431        ////////////////////////////////////////////////////////
432        // CTreeViewItem
433
434        class CTreeViewItem
435        {
436        public:
437                GUID m_MajorType;
438                const CCodecDataList* m_pCodecDataList;
439                const CCodecData* m_pCodecData;
440
441        public:
442        // CTreeViewItem
443                CTreeViewItem() throw()
444                {
445                }
446                CTreeViewItem(const GUID& MajorType, const CCodecDataList* pCodecDataList = NULL, const CCodecData* pCodecData = NULL) throw() :
447                        m_MajorType(MajorType),
448                        m_pCodecDataList(pCodecDataList),
449                        m_pCodecData(pCodecData)
450                {
451                }
452        };
453
454        ////////////////////////////////////////////////////////
455        // CListViewItem
456
457        class CListViewItem
458        {
459        public:
460                const CCodecFormatData* m_pCodecFormatData;
461
462        public:
463        // CListViewItem
464                CListViewItem() throw() :
465                        m_pCodecFormatData(NULL)
466                {
467                }
468                CListViewItem(const CCodecFormatData* pCodecFormatData) throw() :
469                        m_pCodecFormatData(pCodecFormatData)
470                {
471                }
472                CString GetInfoTipText() const
473                {
474                        CString sText;
475                        if(m_pCodecFormatData)
476                        {
477                                if(!m_pCodecFormatData->m_sDescription.IsEmpty())
478                                        sText.AppendFormat(_T("Description: %ls\r\n"), m_pCodecFormatData->m_sDescription);
479                                if(m_pCodecFormatData->m_pMediaType)
480                                {
481                                        sText.Append(_T("\r\n"));
482                                        sText.Append(_T("AM_MEDIA_TYPE:\r\n"));
483                                        const CMediaType& pMediaType = reinterpret_cast<const CMediaType&>(m_pCodecFormatData->m_pMediaType);
484                                        //sText.AppendFormat(_T("  ...\r\n"), pMediaType->majortype);
485                                        if(memcmp(&pMediaType->subtype.Data2, &MEDIASUBTYPE_MJPG.Data2, sizeof (GUID) - offsetof(GUID, Data2)) == 0)
486                                                sText.AppendFormat(_T("  subtype: %ls (%s)\r\n"), _PersistHelper::StringFromIdentifier(pMediaType->subtype), _FilterGraphHelper::GetFourccCodeString(pMediaType->subtype.Data1));
487                                        else
488                                                sText.AppendFormat(_T("  subtype: %ls\r\n"), _PersistHelper::StringFromIdentifier(pMediaType->subtype));
489                                        sText.AppendFormat(_T("  bFixedSizeSamples: %s\r\n"), _StringHelper::FormatNumber((LONG) pMediaType->bFixedSizeSamples));
490                                        sText.AppendFormat(_T("  bTemporalCompression: %s\r\n"), _StringHelper::FormatNumber((LONG) pMediaType->bTemporalCompression));
491                                        sText.AppendFormat(_T("  lSampleSize: %s\r\n"), _StringHelper::FormatNumber((LONG) pMediaType->lSampleSize));
492                                        #pragma region Format
493                                        static const struct
494                                        {
495                                                GUID formattype;
496                                                LPCTSTR pszTitle;
497                                        } g_pMap[] =
498                                        {
499                                                { FORMAT_VideoInfo, _T("FORMAT_VideoInfo") },
500                                                { FORMAT_VideoInfo2, _T("FORMAT_VideoInfo2") },
501                                                { FORMAT_MPEG2_VIDEO, _T("FORMAT_MPEG2_VIDEO") },
502                                                { FORMAT_WaveFormatEx, _T("FORMAT_WaveFormatEx") },
503                                        };
504                                        BOOL bFound = FALSE;
505                                        for(SIZE_T nIndex = 0; nIndex < DIM(g_pMap); nIndex++)
506                                                if(pMediaType->formattype == g_pMap[nIndex].formattype)
507                                                {
508                                                        sText.AppendFormat(_T("  formattype: %ls (%s)\r\n"), _PersistHelper::StringFromIdentifier(pMediaType->formattype), g_pMap[nIndex].pszTitle);
509                                                        bFound = TRUE;
510                                                        break;
511                                                }
512                                        if(!bFound)
513                                                sText.AppendFormat(_T("  formattype: %ls\r\n"), _PersistHelper::StringFromIdentifier(pMediaType->formattype));
514                                        #pragma endregion
515                                        sText.AppendFormat(_T("  cbFormat: %s\r\n"), _StringHelper::FormatNumber((LONG) pMediaType->cbFormat));
516                                        if(pMediaType->formattype == FORMAT_VideoInfo)
517                                        {
518                                                sText.Append(_T("\r\n"));
519                                                sText.Append(_T("VIDEOINFOHEADER:\r\n"));
520                                                const CVideoInfoHeader* pVideoInfoHeader = pMediaType.GetVideoInfoHeader();
521                                                sText.AppendFormat(_T("  rcSource: %d, %d - %d, %d\r\n"), pVideoInfoHeader->rcSource);
522                                                sText.AppendFormat(_T("  rcTarget: %d, %d - %d, %d\r\n"), pVideoInfoHeader->rcTarget);
523                                                sText.AppendFormat(_T("  dwBitRate: %s\r\n"), _StringHelper::FormatNumber((LONG) pVideoInfoHeader->dwBitRate));
524                                                sText.AppendFormat(_T("  dwBitErrorRate: %s\r\n"), _StringHelper::FormatNumber((LONG) pVideoInfoHeader->dwBitErrorRate));
525                                                sText.AppendFormat(_T("  AvgTimePerFrame: %s\r\n"), _StringHelper::FormatNumber((LONG) pVideoInfoHeader->AvgTimePerFrame));
526                                                sText.Append(_T("\r\n"));
527                                                sText.Append(_T("BITMAPINFOHEADER:\r\n"));
528                                                const CBitmapInfoHeader* pBitmapInfoHeader = &pVideoInfoHeader->GetBitmapInfoHeader();
529                                                sText.AppendFormat(_T("  biSize: %s\r\n"), _StringHelper::FormatNumber((LONG) pBitmapInfoHeader->biSize));
530                                                sText.AppendFormat(_T("  biWidth: %s\r\n"), _StringHelper::FormatNumber((LONG) pBitmapInfoHeader->biWidth));
531                                                sText.AppendFormat(_T("  biHeight: %s\r\n"), _StringHelper::FormatNumber((LONG) pBitmapInfoHeader->biHeight));
532                                                sText.AppendFormat(_T("  biPlanes: %s\r\n"), _StringHelper::FormatNumber((LONG) pBitmapInfoHeader->biPlanes));
533                                                sText.AppendFormat(_T("  biBitCount: %s\r\n"), _StringHelper::FormatNumber((LONG) pBitmapInfoHeader->biBitCount));
534                                                sText.AppendFormat(_T("  biCompression: %s\r\n"), StringFromFourCharacterCode(pBitmapInfoHeader->biCompression));
535                                                sText.AppendFormat(_T("  biSizeImage: %s\r\n"), _StringHelper::FormatNumber((LONG) pBitmapInfoHeader->biSizeImage));
536                                                //biXPelsPerMeter;
537                                                //biYPelsPerMeter;
538                                                //biClrUsed;
539                                                //biClrImportant;
540                                        } else
541                                        if(pMediaType->formattype == FORMAT_VideoInfo2)
542                                        {
543                                                sText.Append(_T("\r\n"));
544                                                sText.Append(_T("VIDEOINFOHEADER2:\r\n"));
545                                                const CVideoInfoHeader2* pVideoInfoHeader2 = pMediaType.GetVideoInfoHeader2();
546                                                sText.AppendFormat(_T("  rcSource: %d, %d - %d, %d\r\n"), pVideoInfoHeader2->rcSource);
547                                                sText.AppendFormat(_T("  rcTarget: %d, %d - %d, %d\r\n"), pVideoInfoHeader2->rcTarget);
548                                                sText.AppendFormat(_T("  dwBitRate: %s\r\n"), _StringHelper::FormatNumber((LONG) pVideoInfoHeader2->dwBitRate));
549                                                sText.AppendFormat(_T("  dwBitErrorRate: %s\r\n"), _StringHelper::FormatNumber((LONG) pVideoInfoHeader2->dwBitErrorRate));
550                                                sText.AppendFormat(_T("  AvgTimePerFrame: %s\r\n"), _StringHelper::FormatNumber((LONG) pVideoInfoHeader2->AvgTimePerFrame));
551                                                sText.AppendFormat(_T("  dwInterlaceFlags: 0x%x\r\n"), pVideoInfoHeader2->dwInterlaceFlags);
552                                                sText.AppendFormat(_T("  dwCopyProtectFlags: 0x%x\r\n"), pVideoInfoHeader2->dwCopyProtectFlags);
553                                                if(pVideoInfoHeader2->dwPictAspectRatioX || pVideoInfoHeader2->dwPictAspectRatioY)
554                                                {
555                                                        sText.AppendFormat(_T("  dwPictAspectRatioX: %s\r\n"), _StringHelper::FormatNumber((LONG) pVideoInfoHeader2->dwPictAspectRatioX));
556                                                        sText.AppendFormat(_T("  dwPictAspectRatioY: %s\r\n"), _StringHelper::FormatNumber((LONG) pVideoInfoHeader2->dwPictAspectRatioY));
557                                                }
558                                                sText.AppendFormat(_T("  dwControlFlags: 0x%x\r\n"), pVideoInfoHeader2->dwControlFlags);
559                                                sText.Append(_T("\r\n"));
560                                                sText.Append(_T("BITMAPINFOHEADER:\r\n"));
561                                                const CBitmapInfoHeader* pBitmapInfoHeader = &pVideoInfoHeader2->GetBitmapInfoHeader();
562                                                sText.AppendFormat(_T("  biSize: %s\r\n"), _StringHelper::FormatNumber((LONG) pBitmapInfoHeader->biSize));
563                                                sText.AppendFormat(_T("  biWidth: %s\r\n"), _StringHelper::FormatNumber((LONG) pBitmapInfoHeader->biWidth));
564                                                sText.AppendFormat(_T("  biHeight: %s\r\n"), _StringHelper::FormatNumber((LONG) pBitmapInfoHeader->biHeight));
565                                                sText.AppendFormat(_T("  biPlanes: %s\r\n"), _StringHelper::FormatNumber((LONG) pBitmapInfoHeader->biPlanes));
566                                                sText.AppendFormat(_T("  biBitCount: %s\r\n"), _StringHelper::FormatNumber((LONG) pBitmapInfoHeader->biBitCount));
567                                                sText.AppendFormat(_T("  biCompression: %s\r\n"), StringFromFourCharacterCode(pBitmapInfoHeader->biCompression));
568                                                sText.AppendFormat(_T("  biSizeImage: %s\r\n"), _StringHelper::FormatNumber((LONG) pBitmapInfoHeader->biSizeImage));
569                                                //biXPelsPerMeter;
570                                                //biYPelsPerMeter;
571                                                //biClrUsed;
572                                                //biClrImportant;
573                                        } else
574                                        if(pMediaType->formattype == FORMAT_WaveFormatEx)
575                                        {
576                                                sText.Append(_T("\r\n"));
577                                                sText.Append(_T("WAVEFORMATEX:\r\n"));
578                                                const CWaveFormatEx* pWaveFormatEx = pMediaType.GetWaveFormatEx();
579                                                sText.AppendFormat(_T("  wFormatTag: 0x%04x\r\n"), pWaveFormatEx->wFormatTag);
580                                                sText.AppendFormat(_T("  nChannels: %s\r\n"), _StringHelper::FormatNumber((LONG) pWaveFormatEx->nChannels));
581                                                sText.AppendFormat(_T("  nSamplesPerSec: %s\r\n"), _StringHelper::FormatNumber((LONG) pWaveFormatEx->nSamplesPerSec));
582                                                sText.AppendFormat(_T("  nAvgBytesPerSec: %s\r\n"), _StringHelper::FormatNumber((LONG) pWaveFormatEx->nAvgBytesPerSec));
583                                                sText.AppendFormat(_T("  nBlockAlign: %s\r\n"), _StringHelper::FormatNumber((LONG) pWaveFormatEx->nBlockAlign));
584                                                sText.AppendFormat(_T("  wBitsPerSample: %s\r\n"), _StringHelper::FormatNumber((LONG) pWaveFormatEx->wBitsPerSample));
585                                                sText.AppendFormat(_T("  cbSize: %s\r\n"), _StringHelper::FormatNumber((LONG) pWaveFormatEx->cbSize));
586                                                if(pWaveFormatEx->wFormatTag == WAVE_FORMAT_EXTENSIBLE && sizeof *pWaveFormatEx + pWaveFormatEx->cbSize >= sizeof (WAVEFORMATEXTENSIBLE))
587                                                {
588                                                        sText.Append(_T("\r\n"));
589                                                        sText.Append(_T("WAVEFORMATEXTENSIBLE:\r\n"));
590                                                        const WAVEFORMATEXTENSIBLE* pWaveFormatExtensible = (const WAVEFORMATEXTENSIBLE*) (const WAVEFORMATEX*) pWaveFormatEx;
591                                                        sText.AppendFormat(_T("  wValidBitsPerSample/wSamplesPerBlock: %d\r\n"), _StringHelper::FormatNumber((LONG) pWaveFormatExtensible->Samples.wValidBitsPerSample));
592                                                        sText.AppendFormat(_T("  dwChannelMask: 0x%x\r\n"), pWaveFormatExtensible->dwChannelMask);
593                                                        sText.AppendFormat(_T("  SubFormat: %ls\r\n"), _PersistHelper::StringFromIdentifier(pWaveFormatExtensible->SubFormat));
594                                                } else
595                                                        if(pWaveFormatEx->cbSize)
596                                                                sText.AppendFormat(_T("  %s\r\n"), StringFromData((const BYTE*) (pWaveFormatEx + 1), pWaveFormatEx->cbSize));
597                                        }
598                                }
599                        }
600                        sText.Trim(_T("\t\n\r ."));
601                        return sText;
602                }
603        };
604
605private:
606        CComPtr<IWMProfileManager> m_pWmProfileManager;
607        CAtlList<CCodecDataList> m_VideoCodecDataListList;
608        CAtlList<CCodecDataList> m_AudioCodecDataListList;
609        CRoTreeViewT<CTreeViewItem, CRoListControlDataTraitsT> m_TreeView;
610        CRoListViewT<CListViewItem, CRoListControlDataTraitsT> m_ListView;
611        CRoHyperStatic m_OsVersionStatic;
612
613        static CString StringFromData(const BYTE* pnData, SIZE_T nDataSize)
614        {
615                CString sString;
616                for(SIZE_T nIndex = 0; nIndex < nDataSize; nIndex++)
617                        sString.AppendFormat(_T("%02X "), pnData[nIndex]);
618                sString.TrimRight();
619                return sString;
620        }
621        static CString StringFromFourCharacterCode(DWORD nCode)
622        {
623                BOOL bValid = TRUE;
624                CHAR pszString[5];
625                for(UINT nIndex = 0; bValid && nIndex < 4; nIndex++)
626                {
627                        pszString[nIndex] = (nCode >> (8 * nIndex)) & 0xFF;
628                        bValid &= pszString[nIndex] >= 0x20;
629                }
630                pszString[4] = 0;
631                if(bValid)
632                        return AtlFormatString(_T("%hs (0x%08x)"), pszString, nCode);
633                return AtlFormatString(_T("0x%08x"), nCode);
634        }
635        VOID InsertVideoListViewItem(const CCodecFormatData& CodecFormatData)
636        {
637                const INT nItem = m_ListView.InsertItem(m_ListView.GetItemCount(), CListViewItem(&CodecFormatData), CodecFormatData.GetDescription());
638                if(CodecFormatData.m_pMediaType->formattype == FORMAT_VideoInfo)
639                {
640                        _A(CodecFormatData.m_pMediaType->cbFormat >= sizeof (VIDEOINFOHEADER));
641                        const CVideoInfoHeader* pVideoInfoHeader = CodecFormatData.m_pMediaType.GetVideoInfoHeader();
642                        _W(m_ListView.SetItemText(nItem, 1, StringFromFourCharacterCode(pVideoInfoHeader->GetBitmapInfoHeader().biCompression)));
643                } else
644                if(CodecFormatData.m_pMediaType->formattype == FORMAT_VideoInfo2)
645                {
646                        _A(CodecFormatData.m_pMediaType->cbFormat >= sizeof (VIDEOINFOHEADER2));
647                        const CVideoInfoHeader2* pVideoInfoHeader = CodecFormatData.m_pMediaType.GetVideoInfoHeader2();
648                        _W(m_ListView.SetItemText(nItem, 1, StringFromFourCharacterCode(pVideoInfoHeader->GetBitmapInfoHeader().biCompression)));
649                }
650        }
651        VOID InsertAudioListViewItem(const CCodecFormatData& CodecFormatData)
652        {
653                const INT nItem = m_ListView.InsertItem(m_ListView.GetItemCount(), CListViewItem(&CodecFormatData), CodecFormatData.GetDescription());
654                if(CodecFormatData.m_pMediaType->formattype == FORMAT_WaveFormatEx)
655                {
656                        _A(CodecFormatData.m_pMediaType->cbFormat >= sizeof (WAVEFORMATEX));
657                        const CWaveFormatEx* pWaveFormatEx = CodecFormatData.m_pMediaType.GetWaveFormatEx();
658                        _W(m_ListView.SetItemText(nItem, 1, _StringHelper::FormatNumber((LONG) CodecFormatData.m_pMediaType->bFixedSizeSamples)));
659                        _W(m_ListView.SetItemText(nItem, 2, _StringHelper::FormatNumber((LONG) CodecFormatData.m_pMediaType->bTemporalCompression)));
660                        _W(m_ListView.SetItemText(nItem, 3, _StringHelper::FormatNumber((LONG) CodecFormatData.m_pMediaType->lSampleSize)));
661                        _W(m_ListView.SetItemText(nItem, 4, AtlFormatString(_T("0x%02x"), pWaveFormatEx->wFormatTag)));
662                        _W(m_ListView.SetItemText(nItem, 5, _StringHelper::FormatNumber((LONG) pWaveFormatEx->nChannels)));
663                        _W(m_ListView.SetItemText(nItem, 6, _StringHelper::FormatNumber((LONG) pWaveFormatEx->nSamplesPerSec)));
664                        _W(m_ListView.SetItemText(nItem, 7, _StringHelper::FormatNumber((LONG) pWaveFormatEx->nAvgBytesPerSec)));
665                        _W(m_ListView.SetItemText(nItem, 8, _StringHelper::FormatNumber((LONG) pWaveFormatEx->nBlockAlign)));
666                        _W(m_ListView.SetItemText(nItem, 9, _StringHelper::FormatNumber((LONG) pWaveFormatEx->wBitsPerSample)));
667                        _W(m_ListView.SetItemText(nItem, 10, _StringHelper::FormatNumber((LONG) pWaveFormatEx->cbSize)));
668                        _W(m_ListView.SetItemText(nItem, 11, StringFromData((const BYTE*) (pWaveFormatEx + 1), pWaveFormatEx->cbSize)));
669                }
670        }
671        VOID UpdateListView()
672        {
673                CWindowRedraw ListViewRedraw(m_ListView);
674                m_ListView.DeleteAllItems();
675                while(m_ListView.DeleteColumn(0))
676                        ;
677                HTREEITEM hTreeItem = m_TreeView.GetSelectedItem();
678                if(!hTreeItem)
679                        return;
680                CTreeViewItem& TreeViewItem = m_TreeView.GetItemData(hTreeItem);
681                // SUGG: List all codecs/formats in absense of .m_pCodecData
682                if(TreeViewItem.m_pCodecData)
683                {
684                        if(TreeViewItem.m_MajorType == WMMEDIATYPE_Video)
685                        {
686                                _W(m_ListView.InsertColumn(0, _T("Description"), LVCFMT_LEFT, 180) >= 0);
687                                _W(m_ListView.InsertColumn(1, _T("biCompression"), LVCFMT_LEFT, 120) >= 0);
688                                const CCodecFormatDataList& CodecFormatDataList = TreeViewItem.m_pCodecData->m_CodecFormatDataList;
689                                for(POSITION Position = CodecFormatDataList.GetHeadPosition(); Position; CodecFormatDataList.GetNext(Position))
690                                        InsertVideoListViewItem(CodecFormatDataList.GetAt(Position));
691                        }
692                        if(TreeViewItem.m_MajorType == WMMEDIATYPE_Audio)
693                        {
694                                _W(m_ListView.InsertColumn(0, _T("Description"), LVCFMT_LEFT, 210) >= 0);
695                                _W(m_ListView.InsertColumn(1, _T("bFixedSizeSamples"), LVCFMT_RIGHT, 60) >= 0);
696                                _W(m_ListView.InsertColumn(2, _T("bTemporalCompression"), LVCFMT_RIGHT, 60) >= 0);
697                                _W(m_ListView.InsertColumn(3, _T("lSampleSize"), LVCFMT_RIGHT, 60) >= 0);
698                                _W(m_ListView.InsertColumn(4, _T("wFormatTag"), LVCFMT_RIGHT, 90) >= 0);
699                                _W(m_ListView.InsertColumn(5, _T("nChannels"), LVCFMT_RIGHT, 60) >= 0);
700                                _W(m_ListView.InsertColumn(6, _T("nSamplesPerSec"), LVCFMT_RIGHT, 90) >= 0);
701                                _W(m_ListView.InsertColumn(7, _T("nAvgBytesPerSec"), LVCFMT_RIGHT, 90) >= 0);
702                                _W(m_ListView.InsertColumn(8, _T("nBlockAlign"), LVCFMT_RIGHT, 60) >= 0);
703                                _W(m_ListView.InsertColumn(9, _T("wBitsPerSample"), LVCFMT_RIGHT, 60) >= 0);
704                                _W(m_ListView.InsertColumn(10, _T("cbSize"), LVCFMT_RIGHT, 60) >= 0);
705                                _W(m_ListView.InsertColumn(11, _T("Extra Data"), LVCFMT_LEFT, 120) >= 0);
706                                const CCodecFormatDataList& CodecFormatDataList = TreeViewItem.m_pCodecData->m_CodecFormatDataList;
707                                for(POSITION Position = CodecFormatDataList.GetHeadPosition(); Position; CodecFormatDataList.GetNext(Position))
708                                        InsertAudioListViewItem(CodecFormatDataList.GetAt(Position));
709                                // SUGG: List g_wszSpeechCaps proeprty if/where available
710                        }
711                }
712        }
713        CString GetSubmissionText() const
714        {
715                CString sText;
716                #pragma region OS Version
717                {
718                        OSVERSIONINFOEX VersionInformation = { sizeof VersionInformation };
719                        _W(GetVersionEx((OSVERSIONINFO*) &VersionInformation));
720                        CAtlArray<CString> Array;
721                        _W(Array.Add(_T("OS Version")) >= 0);
722                        _W(Array.Add(AtlFormatString(_T("%d"), VersionInformation.dwMajorVersion)) >= 0);
723                        _W(Array.Add(AtlFormatString(_T("%d"), VersionInformation.dwMinorVersion)) >= 0);
724                        _W(Array.Add(AtlFormatString(_T("%d"), VersionInformation.dwBuildNumber)) >= 0);
725                        _W(Array.Add(AtlFormatString(_T("%d"), VersionInformation.dwPlatformId)) >= 0);
726                        _W(Array.Add(VersionInformation.szCSDVersion) >= 0);
727                        _W(Array.Add(AtlFormatString(_T("%d"), VersionInformation.wServicePackMajor)) >= 0);
728                        _W(Array.Add(AtlFormatString(_T("%d"), VersionInformation.wServicePackMinor)) >= 0);
729                        _W(Array.Add(AtlFormatString(_T("%d"), VersionInformation.wSuiteMask)) >= 0);
730                        _W(Array.Add(AtlFormatString(_T("%d"), VersionInformation.wProductType)) >= 0);
731                        #if defined(_WIN64)
732                        _W(Array.Add(_T("x64")) >= 0);
733                        #else
734                        _W(Array.Add(_T("Win32")) >= 0);
735                        #endif // defined(_WIN64)
736                        sText.Append(_StringHelper::GetCommaSeparatedValue(Array));
737                        sText.Append(_T("\r\n"));
738                }
739                #pragma endregion
740                #pragma region Windows Media Version
741                {
742                        CAtlArray<CString> Array;
743                        _W(Array.Add(_T("WMV Core Version")) >= 0);
744                        _W(Array.Add(_VersionInfoHelper::GetVersionString(_VersionInfoHelper::GetFileVersion(_T("wmvcore.dll")))) >= 0);
745                        sText.Append(_StringHelper::GetCommaSeparatedValue(Array));
746                        sText.Append(_T("\r\n"));
747                }
748                #pragma endregion
749                #pragma region Codecs
750                const CAtlList<CCodecDataList>* ppCodecDataListLists[] = { &m_VideoCodecDataListList, &m_AudioCodecDataListList };
751                for(SIZE_T nCodecDataListListIndex = 0; nCodecDataListListIndex < DIM(ppCodecDataListLists); nCodecDataListListIndex++)
752                {
753                        const CAtlList<CCodecDataList>& CodecDataListList = *ppCodecDataListLists[nCodecDataListListIndex];
754                        for(POSITION CodecDataListListPosition = CodecDataListList.GetHeadPosition(); CodecDataListListPosition; CodecDataListList.GetNext(CodecDataListListPosition))
755                        {
756                                const CCodecDataList& CodecDataList = CodecDataListList.GetAt(CodecDataListListPosition);
757                                {
758                                        CAtlArray<CString> Array;
759                                        _W(Array.Add(_T("Codec Enumeration")) >= 0);
760                                        _W(Array.Add(AtlFormatString(_T("%ls"), _PersistHelper::StringFromIdentifier(CodecDataList.m_MajorType))) >= 0);
761                                        _W(Array.Add(AtlFormatString(_T("%s"), CodecDataList.m_EnumerationSettingList.m_sName)) >= 0);
762                                        sText.Append(_StringHelper::GetCommaSeparatedValue(Array));
763                                        sText.Append(_T("\r\n"));
764                                        for(POSITION EnumerationSettingPosition = CodecDataList.m_EnumerationSettingList.GetHeadPosition(); EnumerationSettingPosition; CodecDataList.m_EnumerationSettingList.GetNext(EnumerationSettingPosition))
765                                        {
766                                                const CEnumerationSetting& EnumerationSetting = CodecDataList.m_EnumerationSettingList.GetAt(EnumerationSettingPosition);
767                                                CAtlArray<CString> Array;
768                                                _W(Array.Add(_T("Codec Enumeration Setting")) >= 0);
769                                                _W(Array.Add(AtlFormatString(_T("%ls"), EnumerationSetting.m_sName)) >= 0);
770                                                _W(Array.Add(AtlFormatString(_T("%s"), EnumerationSetting.GetValueString())) >= 0);
771                                                sText.Append(_StringHelper::GetCommaSeparatedValue(Array));
772                                                sText.Append(_T("\r\n"));
773                                        }
774                                }
775                                for(POSITION CodecDataListPosition = CodecDataList.GetHeadPosition(); CodecDataListPosition; CodecDataList.GetNext(CodecDataListPosition))
776                                {
777                                        const CCodecData& CodecData = CodecDataList.GetAt(CodecDataListPosition);
778                                        CAtlArray<CString> Array;
779                                        _W(Array.Add(_T("Codec")) >= 0);
780                                        _W(Array.Add(AtlFormatString(_T("%ls"), _PersistHelper::StringFromIdentifier(CodecData.m_MajorType))) >= 0);
781                                        _W(Array.Add(AtlFormatString(_T("%d"), CodecData.m_nIndex)) >= 0);
782                                        _W(Array.Add(AtlFormatString(_T("%ls"), CodecData.m_sName)) >= 0);
783                                        sText.Append(_StringHelper::GetCommaSeparatedValue(Array));
784                                        sText.Append(_T("\r\n"));
785                                        const CCodecFormatDataList& CodecFormatDataList = CodecData.m_CodecFormatDataList;
786                                        for(POSITION CodecFormatDataListPosition = CodecFormatDataList.GetHeadPosition(); CodecFormatDataListPosition; CodecFormatDataList.GetNext(CodecFormatDataListPosition))
787                                        {
788                                                const CCodecFormatData& CodecFormatData = CodecFormatDataList.GetAt(CodecFormatDataListPosition);
789                                                CAtlArray<CString> Array;
790                                                _W(Array.Add(_T("Codec Format")) >= 0);
791                                                _W(Array.Add(AtlFormatString(_T("%d"), CodecFormatData.m_nIndex)) >= 0);
792                                                _W(Array.Add(AtlFormatString(_T("%ls"), CodecFormatData.m_sDescription)) >= 0);
793                                                // TODO: Human friendly media type
794                                                _A(CodecFormatData.m_pMediaType);
795                                                _W(Array.Add(StringFromData((const BYTE*) (const AM_MEDIA_TYPE*) CodecFormatData.m_pMediaType, sizeof (AM_MEDIA_TYPE))) >= 0);
796                                                _W(Array.Add(StringFromData(CodecFormatData.m_pMediaType->pbFormat, CodecFormatData.m_pMediaType->cbFormat)) >= 0);
797                                                sText.Append(_StringHelper::GetCommaSeparatedValue(Array));
798                                                sText.Append(_T("\r\n"));
799                                        }
800                                }
801                        }
802                }
803                #pragma endregion
804                return sText;
805        }
806
807public:
808// CMainDialog
809        CMainDialog() throw()
810        {
811        }
812
813// Window message handlers
814        LRESULT OnInitDialog(HWND, LPARAM)
815        {
816                DlgResize_Init();
817                SetIcon(AtlLoadIconImage(IDR_MAINFRAME, LR_DEFAULTCOLOR, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON)), FALSE);
818                SetIcon(AtlLoadIconImage(IDR_MAINFRAME, LR_DEFAULTCOLOR, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON)), FALSE);
819                #if defined(_WIN64)
820                CString sCaption;
821                GetWindowText(sCaption);
822                sCaption += _T(" (x64)");
823                SetWindowText(sCaption);
824                #endif // defined(_WIN64)
825                {
826                        CWaitCursor WaitCursor;
827                        CComPtr<IWMProfileManager> pWmProfileManager;
828                        __C(WMCreateProfileManager(&pWmProfileManager));
829                        CComQIPtr<IWMProfileManager2> pWmProfileManager2 = pWmProfileManager;
830                        if(pWmProfileManager2)
831                                _V(pWmProfileManager2->SetSystemProfileVersion(WMT_VER_9_0));
832                        m_pWmProfileManager = pWmProfileManager;
833                        CComQIPtr<IWMCodecInfo2> pWmCodecInfo2 = pWmProfileManager;
834                        __D(pWmCodecInfo2, E_NOINTERFACE);
835                        CWmCodecInfo3 pWmCodecInfo3 = pWmCodecInfo2;
836                        // Video
837                        CCodecDataList& VideoCodecDataList = m_VideoCodecDataListList.GetAt(m_VideoCodecDataListList.AddTail());
838                        VideoCodecDataList.Initialize(pWmCodecInfo2, WMMEDIATYPE_Video);
839                        //if(pWmCodecInfo3)
840                        //      _ATLTRY
841                        //      {
842                        //              for(UINT nVbrMode = 0; nVbrMode <= 1; nVbrMode++)
843                        //                      for(UINT nPassCount = 1; nPassCount <= 2; nPassCount++)
844                        //                      {
845                        //                              CEnumerationSettingList EnumerationSettingList;
846                        //                              _W(EnumerationSettingList.AddTail(CEnumerationSetting(g_wszVBREnabled, (BOOL) (nVbrMode != 0))));
847                        //                              _W(EnumerationSettingList.AddTail(CEnumerationSetting(g_wszNumPasses, (DWORD) nPassCount)));
848                        //                              EnumerationSettingList.m_sName = AtlFormatString(_T("%s, %d passes"), nVbrMode ? _T("VBR") : _T("CBR"), nPassCount);
849                        //                              CCodecDataList& VideoCodecDataList = m_VideoCodecDataListList.GetAt(m_VideoCodecDataListList.AddTail());
850                        //                              VideoCodecDataList.Initialize(pWmCodecInfo3, WMMEDIATYPE_Video, EnumerationSettingList);
851                        //                      }
852                        //      }
853                        //      _ATLCATCHALL()
854                        //      {
855                        //              _Z_EXCEPTION();
856                        //      }
857                        // Audio
858                        CCodecDataList& AudioCodecDataList = m_AudioCodecDataListList.GetAt(m_AudioCodecDataListList.AddTail());
859                        AudioCodecDataList.Initialize(pWmCodecInfo2, WMMEDIATYPE_Audio);
860                        if(pWmCodecInfo3)
861                                _ATLTRY
862                                {
863                                        for(UINT nVbrMode = 0; nVbrMode <= 1; nVbrMode++)
864                                                for(UINT nPassCount = 1; nPassCount <= 2; nPassCount++)
865                                                {
866                                                        CEnumerationSettingList EnumerationSettingList;
867                                                        _W(EnumerationSettingList.AddTail(CEnumerationSetting(g_wszVBREnabled, (BOOL) (nVbrMode != 0))));
868                                                        _W(EnumerationSettingList.AddTail(CEnumerationSetting(g_wszNumPasses, (DWORD) nPassCount)));
869                                                        EnumerationSettingList.m_sName = AtlFormatString(_T("%s, %d passes"), nVbrMode ? _T("VBR") : _T("CBR"), nPassCount);
870                                                        CCodecDataList& AudioCodecDataList = m_AudioCodecDataListList.GetAt(m_AudioCodecDataListList.AddTail());
871                                                        AudioCodecDataList.Initialize(pWmCodecInfo3, WMMEDIATYPE_Audio, EnumerationSettingList);
872                                                }
873                                }
874                                _ATLCATCHALL()
875                                {
876                                        _Z_EXCEPTION();
877                                }
878                }
879                m_TreeView = GetDlgItem(IDC_TREE);
880                HTREEITEM hVideoItem = m_TreeView.InsertItem(NULL, NULL, CTreeViewItem(WMMEDIATYPE_Video), _T("Video"));
881                HTREEITEM hPreviousVideoCodecListItem = NULL;
882                for(POSITION ListPosition = m_VideoCodecDataListList.GetHeadPosition(); ListPosition; m_VideoCodecDataListList.GetNext(ListPosition))
883                {
884                        const CCodecDataList* pCodecDataList = &m_VideoCodecDataListList.GetAt(ListPosition);
885                        if(pCodecDataList->m_EnumerationSettingList.IsEmpty() && pCodecDataList->IsEmpty())
886                                continue;
887                        HTREEITEM hVideoCodecListItem = m_TreeView.InsertItem(hVideoItem, hPreviousVideoCodecListItem, CTreeViewItem(WMMEDIATYPE_Video, pCodecDataList), pCodecDataList->GetTitle());
888                        hPreviousVideoCodecListItem = hVideoCodecListItem;
889                        HTREEITEM hPreviousVideoCodecItem = NULL;
890                        for(POSITION Position = pCodecDataList->GetHeadPosition(); Position; pCodecDataList->GetNext(Position))
891                        {
892                                const CCodecData* pCodecData = &pCodecDataList->GetAt(Position);
893                                HTREEITEM hVideoCodecItem = m_TreeView.InsertItem(hVideoCodecListItem, hPreviousVideoCodecItem, CTreeViewItem(WMMEDIATYPE_Video, pCodecDataList, pCodecData), pCodecData->GetTitle());
894                                hPreviousVideoCodecItem = hVideoCodecItem;
895                        }
896                        if(pCodecDataList->m_EnumerationSettingList.IsEmpty())
897                                m_TreeView.Expand(hVideoCodecListItem);
898                }
899                m_TreeView.Expand(hVideoItem);
900                HTREEITEM hAudioItem = m_TreeView.InsertItem(NULL, NULL, CTreeViewItem(WMMEDIATYPE_Audio), _T("Audio"));
901                HTREEITEM hPreviousAudioCodecListItem = NULL;
902                for(POSITION ListPosition = m_AudioCodecDataListList.GetHeadPosition(); ListPosition; m_AudioCodecDataListList.GetNext(ListPosition))
903                {
904                        const CCodecDataList* pCodecDataList = &m_AudioCodecDataListList.GetAt(ListPosition);
905                        if(pCodecDataList->m_EnumerationSettingList.IsEmpty() && pCodecDataList->IsEmpty())
906                                continue;
907                        HTREEITEM hAudioCodecListItem = m_TreeView.InsertItem(hAudioItem, hPreviousAudioCodecListItem, CTreeViewItem(WMMEDIATYPE_Audio, pCodecDataList), pCodecDataList->GetTitle());
908                        hPreviousAudioCodecListItem = hAudioCodecListItem;
909                        HTREEITEM hPreviousAudioCodecItem = NULL;
910                        for(POSITION Position = pCodecDataList->GetHeadPosition(); Position; pCodecDataList->GetNext(Position))
911                        {
912                                const CCodecData* pCodecData = &pCodecDataList->GetAt(Position);
913                                HTREEITEM hAudioCodecItem = m_TreeView.InsertItem(hAudioCodecListItem, hPreviousAudioCodecItem, CTreeViewItem(WMMEDIATYPE_Audio, pCodecDataList, pCodecData), pCodecData->GetTitle());
914                                hPreviousAudioCodecItem = hAudioCodecItem;
915                        }
916                        if(pCodecDataList->m_EnumerationSettingList.IsEmpty())
917                                m_TreeView.Expand(hAudioCodecListItem);
918                }
919                m_TreeView.Expand(hAudioItem);
920                m_ListView = GetDlgItem(IDC_LIST);
921                m_ListView.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP | LVS_EX_LABELTIP);
922                CToolTipCtrl ListViewToolTip = m_ListView.GetToolTips();
923                ListViewToolTip.SetDelayTime(TTDT_AUTOMATIC, 2 * 60 * 1000); // 2 minutes
924                m_TreeView.SelectItem(m_TreeView.GetNextItem(hAudioItem, TVGN_CHILD));
925                UpdateListView();
926                _W(m_OsVersionStatic.SubclassWindow(GetDlgItem(IDC_OSVERSION)));
927                OSVERSIONINFOEX VersionInformation = { sizeof VersionInformation };
928                _W(GetVersionEx((OSVERSIONINFO*) &VersionInformation));
929                m_OsVersionStatic.SetWindowText(AtlFormatString(_T("<A TITLE=\"Version %d.%d, Build %d, %s (%d.%d)\">Win %d.%d.%d</A>"), 
930                        VersionInformation.dwMajorVersion, VersionInformation.dwMinorVersion, VersionInformation.dwBuildNumber,
931                        VersionInformation.szCSDVersion, VersionInformation.wServicePackMajor, VersionInformation.wServicePackMinor, 
932                        VersionInformation.dwMajorVersion, VersionInformation.dwMinorVersion, VersionInformation.dwBuildNumber));
933                {
934                        CMenuHandle Menu = GetSystemMenu(FALSE);
935                        _W(Menu.AppendMenu(MF_SEPARATOR));
936                        _W(Menu.AppendMenu(MF_STRING, ID_APP_ABOUT, _T("&About...")));
937                }
938                _W(CenterWindow());
939                return TRUE;
940        }
941        LRESULT OnSysCommand(UINT nCommand, CPoint)
942        {
943                switch(nCommand)
944                {
945                case ID_APP_ABOUT:
946                        {
947                                CAboutDialog Dialog;
948                                Dialog.DoModal(m_hWnd);
949                        }
950                        break;
951                default:
952                        SetMsgHandled(FALSE);
953                }
954                return 0;
955        }
956        LRESULT OnCancel(UINT, INT nIdentifier, HWND)
957        {
958                _W(EndDialog(nIdentifier));
959                return 0;
960        }
961        LRESULT OnTreeGetInfoTip(NMTVGETINFOTIP* pHeader)
962        {
963                if(pHeader->hItem)
964                {
965                        const CTreeViewItem& TreeViewItem = m_TreeView.DataFromParameter(pHeader->lParam);
966                        if(TreeViewItem.m_pCodecData)
967                        {
968                                CString sText;
969                                sText.AppendFormat(_T("Title: %s\r\n"), TreeViewItem.m_pCodecData->GetTitle());
970                                CWmCodecInfo3 pWmCodecInfo3 = TreeViewItem.m_pCodecData->m_pWmCodecInfo2;
971                                if(pWmCodecInfo3)
972                                        _ATLTRY
973                                        {
974                                                sText.Append(_T("\r\n"));
975                                                if(TreeViewItem.m_pCodecData->m_MajorType == WMMEDIATYPE_Video)
976                                                {
977                                                        DWORD nMaximalComplexity, nOfflineComplexity, nLiveComplexity;
978                                                        if(SUCCEEDED(pWmCodecInfo3.GetDwordCodecProperty(TreeViewItem.m_pCodecData->m_MajorType, TreeViewItem.m_pCodecData->m_nIndex, g_wszComplexityMax, nMaximalComplexity)))
979                                                                sText.AppendFormat(_T("g_wszComplexityMax: %d\r\n"), nMaximalComplexity);
980                                                        if(SUCCEEDED(pWmCodecInfo3.GetDwordCodecProperty(TreeViewItem.m_pCodecData->m_MajorType, TreeViewItem.m_pCodecData->m_nIndex, g_wszComplexityOffline, nOfflineComplexity)))
981                                                                sText.AppendFormat(_T("g_wszComplexityOffline: %d\r\n"), nOfflineComplexity);
982                                                        if(SUCCEEDED(pWmCodecInfo3.GetDwordCodecProperty(TreeViewItem.m_pCodecData->m_MajorType, TreeViewItem.m_pCodecData->m_nIndex, g_wszComplexityLive, nLiveComplexity)))
983                                                                sText.AppendFormat(_T("g_wszComplexityLive: %d\r\n"), nLiveComplexity);
984                                                }
985                                                BOOL bIsVbrSupported;
986                                                if(SUCCEEDED(pWmCodecInfo3.GetBoolCodecProperty(TreeViewItem.m_pCodecData->m_MajorType, TreeViewItem.m_pCodecData->m_nIndex, g_wszIsVBRSupported, bIsVbrSupported)))
987                                                        sText.AppendFormat(_T("g_wszIsVBRSupported: %d\r\n"), bIsVbrSupported);
988                                        }
989                                        _ATLCATCH(Exception)
990                                        {
991                                                _Z_ATLEXCEPTION(Exception);
992                                                sText.AppendFormat(_T("Error 0x%08x: %s\r\n"), (HRESULT) Exception, AtlFormatSystemMessage(Exception).TrimRight(_T("\t\n\r .")));
993                                        }
994                                        _ATLCATCHALL()
995                                        {
996                                                _Z_EXCEPTION();
997                                        }
998                                sText.TrimRight(_T("\t\n\r"));
999                                _tcscpy_s(pHeader->pszText, pHeader->cchTextMax, sText);
1000                                if(GetKeyState(VK_CONTROL) < 0 && GetKeyState(VK_SHIFT) < 0)
1001                                {
1002                                        SetClipboardText(m_hWnd, sText);
1003                                        MessageBeep(MB_OK);
1004                                }
1005                        }
1006                }
1007                return 0;
1008        }
1009        LRESULT OnTreeViewSelChanged(NMTREEVIEW*)
1010        {
1011                UpdateListView();
1012                return 0;
1013        }
1014        LRESULT OnListGetInfoTip(NMLVGETINFOTIP* pHeader)
1015        {
1016                CListViewItem& ListViewItem = m_ListView.GetItemData(pHeader->iItem);
1017                const CString sInfoTipText = ListViewItem.GetInfoTipText();
1018                _tcscpy_s(pHeader->pszText, pHeader->cchTextMax, sInfoTipText);
1019                if(GetKeyState(VK_CONTROL) < 0 && GetKeyState(VK_SHIFT) < 0)
1020                {
1021                        SetClipboardText(m_hWnd, sInfoTipText);
1022                        MessageBeep(MB_OK);
1023                }
1024                return 0;
1025        }
1026        LRESULT OnCopyButtonClicked(UINT, INT, HWND)
1027        {
1028                CStringW sText(GetSubmissionText());
1029                __E(OpenClipboard());
1030                _ATLTRY
1031                {
1032                        __E(EmptyClipboard());
1033                        CGlobalMemoryHandle TextHandle;
1034                        TextHandle.Alloc((sText.GetLength() + 1) * sizeof (WCHAR), GMEM_MOVEABLE | GMEM_SHARE);
1035                        wcscpy_s(CGlobalMemoryHandle::CLockT<WCHAR>(TextHandle), sText.GetLength() + 1, sText);
1036                        __E(SetClipboardData(CF_UNICODETEXT, TextHandle));
1037                        TextHandle.Detach();
1038                        MessageBeep(MB_OK);
1039                }
1040                _ATLCATCHALL()
1041                {
1042                        _W(CloseClipboard());
1043                        _ATLRETHROW;
1044                }
1045                _W(CloseClipboard());
1046                return 0;
1047        }
1048        LRESULT OnSubmitButtonClicked(UINT, INT, HWND)
1049        {
1050                CWaitCursor WaitCursor;
1051                CWinHttpPostData PostData;
1052                PostData.AddValue(_T("subj"), _T("Alax.Info Windows Media Codec List"));
1053                CStringA sTextA = Utf8StringFromString(GetSubmissionText());
1054                PostData.AddValue(_T("body"), _Base64Helper::Encode<CString>((const BYTE*) (LPCSTR) sTextA, sTextA.GetLength(), _Base64Helper::FLAG_NOPAD | _Base64Helper::FLAG_NOCRLF));
1055                CWinHttpSessionHandle Session = OpenWinHttpSessionHandle(AtlLoadString(IDS_PROJNAME));
1056                __E(Session);
1057                CWinHttpConnectionHandle Connection = Session.Connect(CStringW(_T("alax.info")));
1058                __E(Connection);
1059                CWinHttpRequestHandle Request = Connection.OpenRequest(CStringW(_T("POST")), CStringW(_T("/post.php")));
1060                __E(Request);
1061                CStringW sPostHeaders = PostData.GetHeaders();
1062                CStringA sPostData(PostData.GetValue());
1063                __E(Request.Send(sPostHeaders, -1, const_cast<LPSTR>((LPCSTR) sPostData), sPostData.GetLength(), sPostData.GetLength()));
1064                __E(Request.ReceiveResponse());
1065                DWORD nStatusCode = 0;
1066                __E(Request.QueryNumberHeader(WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, nStatusCode));
1067                __D(nStatusCode == HTTP_STATUS_OK, MAKE_HRESULT(SEVERITY_ERROR, FACILITY_HTTP, nStatusCode));
1068                AtlMessageBoxEx(m_hWnd, _T("Submission complete, thank you!"), IDS_INFORMATION, MB_ICONINFORMATION | MB_OK);
1069                return 0;
1070        }
1071};
Note: See TracBrowser for help on using the repository browser.