//////////////////////////////////////////////////////////// // Copyright (C) Roman Ryltsov, 2009 // Created by Roman Ryltsov roman@alax.info // // $Id$ #pragma once #include #include "rodshow.h" #include "rocontrols.h" #include "rocrypt.h" #include "rowinhttp.h" #include "AboutDialog.h" #pragma comment(lib, "wmvcore.lib") //////////////////////////////////////////////////////////// // CMainDialog class CMainDialog : public CDialogImpl, public CDialogResize, public CWindowWithPrivateMessagesT { public: enum { IDD = IDD_MAIN }; BEGIN_MSG_MAP_EX(CMainDialog) //CHAIN_MSG_MAP(CDialogImpl) CHAIN_MSG_MAP(CDialogResize) CHAIN_MSG_MAP(CWindowWithPrivateMessagesT) MSG_WM_INITDIALOG(OnInitDialog) MSG_WM_SYSCOMMAND(OnSysCommand) COMMAND_ID_HANDLER_EX(IDCANCEL, OnCancel) // SUGG: Tree view info tips MSG_TVN_SELCHANGED(IDC_TREE, OnTreeViewSelChanged) //COMMAND_ID_HANDLER_EX(ID_APP_ABOUT, OnAppAbout) // SUGG: List view column sort // SUGG: List view info tips COMMAND_ID_HANDLER_EX(IDC_SUBMIT, OnSubmitButtonClicked) REFLECT_NOTIFICATIONS() END_MSG_MAP() BEGIN_DLGRESIZE_MAP(CMainDialog) DLGRESIZE_CONTROL(IDC_TREE, DLSZ_SIZE_Y) DLGRESIZE_CONTROL(IDC_LIST, DLSZ_SIZE_X | DLSZ_SIZE_Y) DLGRESIZE_CONTROL(IDCANCEL, DLSZ_MOVE_X) DLGRESIZE_CONTROL(IDC_SUBMIT, DLSZ_MOVE_X) DLGRESIZE_CONTROL(IDC_OSVERSION, DLSZ_MOVE_X | DLSZ_MOVE_Y) END_DLGRESIZE_MAP() public: //////////////////////////////////////////////////// // CCodecFormatData class CCodecFormatData { public: DWORD m_nIndex; CStringW m_sDescription; CComPtr m_pWmStreamConfig; CMediaType m_pMediaType; public: // CCodecFormatData CCodecFormatData() throw() : m_nIndex(0) { } VOID Initialize(DWORD nIndex, const CStringW& sDescription, IWMStreamConfig* pWmStreamConfig, const CMediaType& pMediaType) { m_nIndex = nIndex; m_sDescription = sDescription; m_pWmStreamConfig = pWmStreamConfig; m_pMediaType = pMediaType; } CString GetDescription() const { if(m_sDescription.IsEmpty()) return _T("(no description)"); return CString(m_sDescription); } }; typedef CAtlList CCodecFormatDataList; //////////////////////////////////////////////////// // CCodecData class CCodecData { public: GUID m_MajorType; DWORD m_nCodecIndex; CStringW m_sCodecName; CCodecFormatDataList m_CodecFormatDataList; public: // CCodecData CCodecData() throw() : m_MajorType(GUID_NULL) { } VOID Initialize(IWMCodecInfo2* pWmCodecInfo2, const GUID& MajorType, DWORD nCodecIndex, const CStringW& sCodecName) { _A(pWmCodecInfo2); m_MajorType = MajorType; m_nCodecIndex = nCodecIndex; m_sCodecName = sCodecName; m_CodecFormatDataList.RemoveAll(); DWORD nFormatCount = 0; __C(pWmCodecInfo2->GetCodecFormatCount(MajorType, nCodecIndex, &nFormatCount)); _Z4(atlTraceGeneral, 4, _T("nFormatCount %d\n"), nFormatCount); for(DWORD nFormatIndex = 0; nFormatIndex < nFormatCount; nFormatIndex++) { DWORD nCodecFormatDescriptionLength = 0; __C(pWmCodecInfo2->GetCodecFormatDesc(MajorType, nCodecIndex, nFormatIndex, NULL, NULL, &nCodecFormatDescriptionLength)); _A(nCodecFormatDescriptionLength > 0); CComPtr pWmStreamConfig; CStringW sFormatDescription; __C(pWmCodecInfo2->GetCodecFormatDesc(MajorType, nCodecIndex, nFormatIndex, &pWmStreamConfig, sFormatDescription.GetBufferSetLength(nCodecFormatDescriptionLength - 1), &nCodecFormatDescriptionLength)); _Z4(atlTraceGeneral, 4, _T("nFormatIndex %d, sFormatDescription \"%ls\"\n"), nFormatIndex, sFormatDescription); CComQIPtr pWmMediaProps = pWmStreamConfig; __D(pWmMediaProps, E_NOINTERFACE); DWORD nMediaTypeSize = 0; pWmMediaProps->GetMediaType(NULL, &nMediaTypeSize); CTempBuffer pMediaType; pMediaType.AllocateBytes(nMediaTypeSize); __C(pWmMediaProps->GetMediaType(pMediaType, &nMediaTypeSize)); _Z4(atlTraceGeneral, 4, _T("pMediaType->subtype %ls\n"), _PersistHelper::StringFromIdentifier(pMediaType->subtype)); POSITION Position = m_CodecFormatDataList.AddTail(); _ATLTRY { CCodecFormatData& CodecFormatData = m_CodecFormatDataList.GetAt(Position); CodecFormatData.Initialize(nFormatIndex, sFormatDescription, pWmStreamConfig, (const AM_MEDIA_TYPE*) (const WM_MEDIA_TYPE*) pMediaType); } _ATLCATCHALL() { m_CodecFormatDataList.RemoveAt(Position); _ATLRETHROW; } } } CString GetTitle() const { return CString(m_sCodecName); } }; //////////////////////////////////////////////////// // CCodecDataList class CCodecDataList : public CAtlList { public: GUID m_MajorType; public: // CCodecDataList CCodecDataList() throw() : m_MajorType(GUID_NULL) { } CCodecDataList(IWMCodecInfo2* pWmCodecInfo2, const GUID& MajorType) { Initialize(pWmCodecInfo2, MajorType); } VOID Initialize(IWMCodecInfo2* pWmCodecInfo2, const GUID& MajorType) { _A(pWmCodecInfo2); RemoveAll(); DWORD nCodecCount = 0; __C(pWmCodecInfo2->GetCodecInfoCount(MajorType, &nCodecCount)); for(DWORD nCodecIndex = 0; nCodecIndex < nCodecCount; nCodecIndex++) _ATLTRY { DWORD nCodecNameLength = 0; __C(pWmCodecInfo2->GetCodecName(MajorType, nCodecIndex, NULL, &nCodecNameLength)); _A(nCodecNameLength > 0); CStringW sCodecName; if(nCodecNameLength) __C(pWmCodecInfo2->GetCodecName(MajorType, nCodecIndex, sCodecName.GetBufferSetLength(nCodecNameLength - 1), &nCodecNameLength)); _Z4(atlTraceGeneral, 4, _T("nCodecIndex %d, sCodecName \"%ls\"\n"), nCodecIndex, sCodecName); POSITION Position = AddTail(); _ATLTRY { CCodecData& CodecData = GetAt(Position); CodecData.Initialize(pWmCodecInfo2, MajorType, nCodecIndex, sCodecName); } _ATLCATCHALL() { RemoveAt(Position); _ATLRETHROW; } } _ATLCATCHALL() { _Z_EXCEPTION(); } } }; //////////////////////////////////////////////////////// // CTreeViewItem class CTreeViewItem { public: GUID m_MajorType; const CCodecData* m_pCodecData; public: // CTreeViewItem CTreeViewItem() throw() { } CTreeViewItem(const GUID& MajorType, const CCodecData* pCodecData = NULL) throw() : m_MajorType(MajorType), m_pCodecData(pCodecData) { } }; //////////////////////////////////////////////////////// // CListViewItem class CListViewItem { public: // CListViewItem }; private: CComPtr m_pWmProfileManager; CCodecDataList m_VideoCodecDataList; CCodecDataList m_AudioCodecDataList; CRoTreeViewT m_TreeView; CRoListViewT m_ListView; CRoHyperStatic m_OsVersionStatic; VOID InsertAudioListViewItem(const CCodecFormatData& CodecFormatData) { const INT nItem = m_ListView.InsertItem(m_ListView.GetItemCount(), CListViewItem(), CodecFormatData.GetDescription()); if(CodecFormatData.m_pMediaType->formattype == FORMAT_WaveFormatEx) { _A(CodecFormatData.m_pMediaType->cbFormat >= sizeof (WAVEFORMATEX)); const WAVEFORMATEX* pWaveFormatEx = (const WAVEFORMATEX*) CodecFormatData.m_pMediaType->pbFormat; _W(m_ListView.SetItemText(nItem, 1, _StringHelper::FormatNumber((LONG) CodecFormatData.m_pMediaType->bFixedSizeSamples))); _W(m_ListView.SetItemText(nItem, 2, _StringHelper::FormatNumber((LONG) CodecFormatData.m_pMediaType->bTemporalCompression))); _W(m_ListView.SetItemText(nItem, 3, _StringHelper::FormatNumber((LONG) CodecFormatData.m_pMediaType->lSampleSize))); _W(m_ListView.SetItemText(nItem, 4, AtlFormatString(_T("0x%02x"), pWaveFormatEx->wFormatTag))); _W(m_ListView.SetItemText(nItem, 5, _StringHelper::FormatNumber((LONG) pWaveFormatEx->nChannels))); _W(m_ListView.SetItemText(nItem, 6, _StringHelper::FormatNumber((LONG) pWaveFormatEx->nSamplesPerSec))); _W(m_ListView.SetItemText(nItem, 7, _StringHelper::FormatNumber((LONG) pWaveFormatEx->nAvgBytesPerSec))); _W(m_ListView.SetItemText(nItem, 8, _StringHelper::FormatNumber((LONG) pWaveFormatEx->nBlockAlign))); _W(m_ListView.SetItemText(nItem, 9, _StringHelper::FormatNumber((LONG) pWaveFormatEx->wBitsPerSample))); _W(m_ListView.SetItemText(nItem, 10, _StringHelper::FormatNumber((LONG) pWaveFormatEx->cbSize))); CString sExtraData; for(WORD nIndex = 0; nIndex < pWaveFormatEx->cbSize; nIndex++) sExtraData.AppendFormat(_T("%02X "), ((const BYTE*) (pWaveFormatEx + 1))[nIndex]); sExtraData.TrimRight(); _W(m_ListView.SetItemText(nItem, 11, sExtraData)); } } VOID UpdateListView() { CWindowRedraw ListViewRedraw(m_ListView); m_ListView.DeleteAllItems(); while(m_ListView.DeleteColumn(0)) ; HTREEITEM hTreeItem = m_TreeView.GetSelectedItem(); if(!hTreeItem) return; CTreeViewItem& TreeViewItem = m_TreeView.GetItemData(hTreeItem); // SUGG: List all codecs/formats in absense of .m_pCodecData if(TreeViewItem.m_pCodecData) { if(TreeViewItem.m_MajorType == WMMEDIATYPE_Video) { _W(m_ListView.InsertColumn(0, _T("Description"), LVCFMT_LEFT, 240) >= 0); const CCodecFormatDataList& CodecFormatDataList = TreeViewItem.m_pCodecData->m_CodecFormatDataList; for(POSITION Position = CodecFormatDataList.GetHeadPosition(); Position; CodecFormatDataList.GetNext(Position)) { const CCodecFormatData& CodecFormatData = CodecFormatDataList.GetAt(Position); const INT nItem = m_ListView.InsertItem(m_ListView.GetItemCount(), CListViewItem(), CodecFormatData.GetDescription()); CodecFormatData.m_pMediaType; } } if(TreeViewItem.m_MajorType == WMMEDIATYPE_Audio) { _W(m_ListView.InsertColumn(0, _T("Description"), LVCFMT_LEFT, 210) >= 0); _W(m_ListView.InsertColumn(1, _T("bFixedSizeSamples"), LVCFMT_RIGHT, 60) >= 0); _W(m_ListView.InsertColumn(2, _T("bTemporalCompression"), LVCFMT_RIGHT, 60) >= 0); _W(m_ListView.InsertColumn(3, _T("lSampleSize"), LVCFMT_RIGHT, 60) >= 0); _W(m_ListView.InsertColumn(4, _T("wFormatTag"), LVCFMT_RIGHT, 90) >= 0); _W(m_ListView.InsertColumn(5, _T("nChannels"), LVCFMT_RIGHT, 60) >= 0); _W(m_ListView.InsertColumn(6, _T("nSamplesPerSec"), LVCFMT_RIGHT, 90) >= 0); _W(m_ListView.InsertColumn(7, _T("nAvgBytesPerSec"), LVCFMT_RIGHT, 90) >= 0); _W(m_ListView.InsertColumn(8, _T("nBlockAlign"), LVCFMT_RIGHT, 60) >= 0); _W(m_ListView.InsertColumn(9, _T("wBitsPerSample"), LVCFMT_RIGHT, 60) >= 0); _W(m_ListView.InsertColumn(10, _T("cbSize"), LVCFMT_RIGHT, 60) >= 0); _W(m_ListView.InsertColumn(11, _T("Extra Data"), LVCFMT_LEFT, 120) >= 0); const CCodecFormatDataList& CodecFormatDataList = TreeViewItem.m_pCodecData->m_CodecFormatDataList; for(POSITION Position = CodecFormatDataList.GetHeadPosition(); Position; CodecFormatDataList.GetNext(Position)) InsertAudioListViewItem(CodecFormatDataList.GetAt(Position)); } } } CString GetSubmissionText() const { return _T("TODO"); } public: // CMainDialog CMainDialog() throw() { } // Window message handlers LRESULT OnInitDialog(HWND, LPARAM) { DlgResize_Init(); SetIcon(AtlLoadIconImage(IDR_MAINFRAME, LR_DEFAULTCOLOR, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON)), FALSE); SetIcon(AtlLoadIconImage(IDR_MAINFRAME, LR_DEFAULTCOLOR, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON)), FALSE); { CWaitCursor WaitCursor; CComPtr pWmProfileManager; __C(WMCreateProfileManager(&pWmProfileManager)); CComQIPtr pWmProfileManager2 = pWmProfileManager; if(pWmProfileManager2) _V(pWmProfileManager2->SetSystemProfileVersion(WMT_VER_9_0)); m_pWmProfileManager = pWmProfileManager; CComQIPtr pWmCodecInfo2 = pWmProfileManager; __D(pWmCodecInfo2, E_NOINTERFACE); m_VideoCodecDataList.Initialize(pWmCodecInfo2, WMMEDIATYPE_Video); m_AudioCodecDataList.Initialize(pWmCodecInfo2, WMMEDIATYPE_Audio); } m_TreeView = GetDlgItem(IDC_TREE); HTREEITEM hVideoItem = m_TreeView.InsertItem(NULL, NULL, CTreeViewItem(WMMEDIATYPE_Video), _T("Video")); HTREEITEM hPreviousVideoCodecItem = NULL; for(POSITION Position = m_VideoCodecDataList.GetHeadPosition(); Position; m_VideoCodecDataList.GetNext(Position)) { const CCodecData* pCodecData = &m_VideoCodecDataList.GetAt(Position); HTREEITEM hVideoCodecItem = m_TreeView.InsertItem(hVideoItem, hPreviousVideoCodecItem, CTreeViewItem(WMMEDIATYPE_Video, pCodecData), pCodecData->GetTitle()); hPreviousVideoCodecItem = hVideoCodecItem; } m_TreeView.Expand(hVideoItem); HTREEITEM hAudioItem = m_TreeView.InsertItem(NULL, NULL, CTreeViewItem(WMMEDIATYPE_Audio), _T("Audio")); HTREEITEM hPreviousAudioCodecItem = NULL; for(POSITION Position = m_AudioCodecDataList.GetHeadPosition(); Position; m_AudioCodecDataList.GetNext(Position)) { const CCodecData* pCodecData = &m_AudioCodecDataList.GetAt(Position); HTREEITEM hAudioCodecItem = m_TreeView.InsertItem(hAudioItem, hPreviousAudioCodecItem, CTreeViewItem(WMMEDIATYPE_Audio, pCodecData), pCodecData->GetTitle()); hPreviousAudioCodecItem = hAudioCodecItem; } m_TreeView.Expand(hAudioItem); m_ListView = GetDlgItem(IDC_LIST); UpdateListView(); _W(m_OsVersionStatic.SubclassWindow(GetDlgItem(IDC_OSVERSION))); OSVERSIONINFOEX VersionInformation = { sizeof VersionInformation }; _W(GetVersionEx((OSVERSIONINFO*) &VersionInformation)); m_OsVersionStatic.SetWindowText(AtlFormatString(_T("Win %d.%d.%d"), VersionInformation.dwMajorVersion, VersionInformation.dwMinorVersion, VersionInformation.dwBuildNumber, VersionInformation.szCSDVersion, VersionInformation.wServicePackMajor, VersionInformation.wServicePackMinor, VersionInformation.dwMajorVersion, VersionInformation.dwMinorVersion, VersionInformation.dwBuildNumber)); { CMenuHandle Menu = GetSystemMenu(FALSE); _W(Menu.AppendMenu(MF_SEPARATOR)); _W(Menu.AppendMenu(MF_STRING, ID_APP_ABOUT, _T("&About..."))); } _W(CenterWindow()); return TRUE; } LRESULT OnSysCommand(UINT nCommand, CPoint) { switch(nCommand) { case ID_APP_ABOUT: { CAboutDialog Dialog; Dialog.DoModal(m_hWnd); } break; default: SetMsgHandled(FALSE); } return 0; } LRESULT OnCancel(UINT, INT nIdentifier, HWND) { _W(EndDialog(nIdentifier)); return 0; } LRESULT OnTreeViewSelChanged(NMTREEVIEW*) { UpdateListView(); return 0; } LRESULT OnSubmitButtonClicked(UINT, INT, HWND) { CWaitCursor WaitCursor; CWinHttpPostData PostData; PostData.AddValue(_T("subj"), _T("Alax.Info Windows Media Codec List")); CStringA sTextA = Utf8StringFromString(GetSubmissionText()); PostData.AddValue(_T("body"), _Base64Helper::Encode((const BYTE*) (LPCSTR) sTextA, sTextA.GetLength(), _Base64Helper::FLAG_NOPAD | _Base64Helper::FLAG_NOCRLF)); CWinHttpSessionHandle Session = OpenWinHttpSessionHandle(AtlLoadString(IDS_PROJNAME)); __E(Session); CWinHttpConnectionHandle Connection = Session.Connect(CStringW(_T("alax.info"))); __E(Connection); CWinHttpRequestHandle Request = Connection.OpenRequest(CStringW(_T("POST")), CStringW(_T("/post.php"))); __E(Request); CStringW sPostHeaders = PostData.GetHeaders(); CStringA sPostData(PostData.GetValue()); __E(Request.Send(sPostHeaders, -1, const_cast((LPCSTR) sPostData), sPostData.GetLength(), sPostData.GetLength())); __E(Request.ReceiveResponse()); DWORD nStatusCode = 0; __E(Request.QueryNumberHeader(WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, nStatusCode)); __D(nStatusCode == HTTP_STATUS_OK, MAKE_HRESULT(SEVERITY_ERROR, FACILITY_HTTP, nStatusCode)); AtlMessageBoxEx(m_hWnd, _T("Submission complete, thank you!"), IDS_INFORMATION, MB_ICONINFORMATION | MB_OK); return 0; } };