source: trunk/DirectShowSpy/FilterGraphHelper.h @ 249

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

Added even more ISpy methods

File size: 83.0 KB
Line 
1////////////////////////////////////////////////////////////
2// Copyright (C) Roman Ryltsov, 2008-2014
3// Created by Roman Ryltsov roman@alax.info
4
5#pragma once
6
7#include "rofiles.h"
8#include "rodshow.h"
9#include "DirectShowSpy_i.h"
10#include "Common.h"
11#include "AboutDialog.h"
12#include "..\..\Repository-Private\Utilities\EmailTools\Message.h"
13
14INT_PTR DoFilterGraphListPropertySheetModal(HWND hParentWindow);
15
16HRESULT FilterGraphHelper_DoPropertyFrameModal(LONG nParentWindowHandle);
17HRESULT FilterGraphHelper_DoFilterGraphListModal(LONG nParentWindowHandle);
18HRESULT FilterGraphHelper_OpenGraphStudioNext(LONG nParentWindowHandle, LPCWSTR pszMonikerDisplayName, VARIANT_BOOL* pbResult);
19HRESULT FilterGraphHelper_OpenGraphEdit(LONG nParentWindowHandle, LPCWSTR pszMonikerDisplayName, VARIANT_BOOL* pbResult);
20
21////////////////////////////////////////////////////////////
22// CFilterGraphHelper
23
24class ATL_NO_VTABLE CFilterGraphHelper :
25        public CComObjectRootEx<CComMultiThreadModelNoCS>,
26        public CComCoClass<CFilterGraphHelper, &__uuidof(FilterGraphHelper)>,
27        public IProvideClassInfo2Impl<&__uuidof(FilterGraphHelper), &IID_NULL>,
28        public IDispatchImpl<IFilterGraphHelper>
29{
30public:
31        enum { IDR = IDR_FILTERGRAPHHELPER };
32
33//DECLARE_REGISTRY_RESOURCEID(IDR)
34
35BEGIN_COM_MAP(CFilterGraphHelper)
36        COM_INTERFACE_ENTRY(IFilterGraphHelper)
37        COM_INTERFACE_ENTRY(IDispatch)
38        COM_INTERFACE_ENTRY(IProvideClassInfo2)
39        COM_INTERFACE_ENTRY(IProvideClassInfo)
40END_COM_MAP()
41
42public:
43
44        ////////////////////////////////////////////////////////
45        // CProcessData
46
47        class CProcessData
48        {
49        public:
50                CStringW m_sDisplayName;
51                DWORD m_nIdentifier;
52                CPath m_sImagePath;
53        };
54
55        ////////////////////////////////////////////////////////
56        // CPropertyFrameDialog
57
58        class CPropertyFrameDialog :
59                public CDialogImpl<CPropertyFrameDialog>,
60                public CDialogResize<CPropertyFrameDialog>,
61                public CDialogWithAcceleratorsT<CPropertyFrameDialog>
62        {
63        public:
64                enum { IDD = IDD_FILTERGRAPHHELPER_PROPERTYFRAME };
65
66        BEGIN_MSG_MAP_EX(CPropertyFrameDialog)
67                //CHAIN_MSG_MAP(CDialogImpl<CPropertyFrameDialog>)
68                CHAIN_MSG_MAP(CDialogResize<CPropertyFrameDialog>)
69                MSG_WM_INITDIALOG(OnInitDialog)
70                MSG_WM_DESTROY(OnDestroy)
71                MSG_TVN_GETINFOTIP(IDC_FILTERGRAPHHELPER_PROPERTYFRAME_TREE, OnTreeViewGetInfoTip)
72                MSG_TVN_SELCHANGED(IDC_FILTERGRAPHHELPER_PROPERTYFRAME_TREE, OnTreeViewSelChanged)
73                MSG_TVN_ITEMEXPANDING(IDC_FILTERGRAPHHELPER_PROPERTYFRAME_TREE, OnTreeViewItemExplanding)
74                MSG_TVN_DBLCLK(IDC_FILTERGRAPHHELPER_PROPERTYFRAME_TREE, OnTreeViewDblClk)
75                MSG_WM_SYSCOMMAND(OnSysCommand)
76                COMMAND_ID_HANDLER_EX(IDOK, OnOk)
77                COMMAND_ID_HANDLER_EX(IDCANCEL, OnCancel)
78                COMMAND_ID_HANDLER_EX(IDC_FILTERGRAPHHELPER_PROPERTYFRAME_APPLY, OnApply)
79                COMMAND_ID_HANDLER_EX(IDC_FILTERGRAPHHELPER_ACTION_OPENGSN, OnActionCommand)
80                COMMAND_ID_HANDLER_EX(IDC_FILTERGRAPHHELPER_ACTION_OPENGE, OnActionCommand)
81                COMMAND_ID_HANDLER_EX(IDC_FILTERGRAPHHELPER_ACTION_OPENLIST, OnActionCommand)
82                REFLECT_NOTIFICATIONS()
83        END_MSG_MAP()
84
85        BEGIN_DLGRESIZE_MAP(CPropertyFrameDialog)
86                DLGRESIZE_CONTROL(IDC_FILTERGRAPHHELPER_PROPERTYFRAME_TREE, DLSZ_SIZE_Y)
87                DLGRESIZE_CONTROL(IDC_FILTERGRAPHHELPER_PROPERTYFRAME_TEXT, DLSZ_SIZE_X | DLSZ_SIZE_Y)
88                DLGRESIZE_CONTROL(IDOK, DLSZ_MOVE_X | DLSZ_MOVE_Y)
89                DLGRESIZE_CONTROL(IDCANCEL, DLSZ_MOVE_X | DLSZ_MOVE_Y)
90                DLGRESIZE_CONTROL(IDC_FILTERGRAPHHELPER_PROPERTYFRAME_APPLY, DLSZ_MOVE_X | DLSZ_MOVE_Y)
91        END_DLGRESIZE_MAP()
92
93        public:
94
95                ////////////////////////////////////////////////////
96                // CPropertyPageSite
97
98                class ATL_NO_VTABLE CPropertyPageSite :
99                        public CComObjectRootEx<CComSingleThreadModel>,
100                        public IPropertyPageSite
101                {
102                        friend class CPropertyFrameDialog;
103
104                public:
105
106                BEGIN_COM_MAP(CPropertyPageSite)
107                        COM_INTERFACE_ENTRY(IPropertyPageSite)
108                END_COM_MAP()
109
110                private:
111                        CPropertyFrameDialog* m_pOwner;
112                        CComPtr<IUnknown> m_pUnknown;
113                        CComPtr<IPropertyPage> m_pPropertyPage;
114                        CString m_sTitle;
115                        DWORD m_nStatus;
116
117                public:
118                // CPropertyPageSite
119                        CPropertyPageSite() :
120                                m_pOwner(NULL)
121                        {
122                        }
123                        VOID Initialize(CPropertyFrameDialog* pOwner, IUnknown* pUnknown, IPropertyPage* pPropertyPage)
124                        {
125                                _A(pOwner && pUnknown && pPropertyPage);
126                                _A(!m_pOwner);
127                                m_pOwner = pOwner;
128                                m_pUnknown = pUnknown;
129                                m_pPropertyPage = pPropertyPage;
130                                __C(pPropertyPage->SetObjects(1, &m_pUnknown.p));
131                                PROPPAGEINFO Information;
132                                ZeroMemory(&Information, sizeof Information);
133                                Information.cb = sizeof Information;
134                                __C(pPropertyPage->GetPageInfo(&Information));
135                                CStringW sTitle = Information.pszTitle;
136                                CoTaskMemFree(Information.pszTitle);
137                                CoTaskMemFree(Information.pszDocString);
138                                CoTaskMemFree(Information.pszHelpFile);
139                                m_sTitle = CString(sTitle);
140                                m_nStatus = 0;
141                                __C(pPropertyPage->SetPageSite(this));
142                        }
143                        VOID Terminate()
144                        {
145                                if(m_pPropertyPage)
146                                {
147                                        _V(m_pPropertyPage->SetPageSite(NULL));
148                                        m_pPropertyPage.Release();
149                                }
150                                m_pUnknown.Release();
151                                m_pOwner = NULL;
152                        }
153                        BOOL IsDirty()
154                        {
155                                return m_nStatus & PROPPAGESTATUS_DIRTY;
156                        }
157
158                // IPropertyPageSite
159                        STDMETHOD(OnStatusChange)(DWORD nFlags)
160                        {
161                                _Z4(atlTraceCOM, 4, _T("nFlags 0x%x\n"), nFlags);
162                                m_nStatus = nFlags;
163                                m_pOwner->HandleStatusChange(this);
164                                return S_OK;
165                        }
166                        STDMETHOD(GetLocaleID)(LCID* pLocaleIdentifier)
167                        {
168                                _Z4(atlTraceCOM, 4, _T("...\n"));
169                                pLocaleIdentifier;
170                                return E_NOTIMPL;
171                        }
172                        STDMETHOD(GetPageContainer)(IUnknown** ppUnknown)
173                        {
174                                _Z4(atlTraceCOM, 4, _T("...\n"));
175                                ppUnknown;
176                                return E_NOTIMPL;
177                        }
178                        STDMETHOD(TranslateAccelerator)(MSG* pMessage)
179                        {
180                                _Z4(atlTraceCOM, 4, _T("...\n"));
181                                pMessage;
182                                return E_NOTIMPL;
183                        }
184                };
185
186                ////////////////////////////////////////////////////
187                // CActionDialog
188
189                class CActionDialog :
190                        public CDialogImpl<CActionDialog>,
191                        public CDialogResize<CActionDialog>
192                {
193                public:
194                        enum { IDD = IDD_FILTERGRAPHHELPER_ACTION };
195
196                BEGIN_MSG_MAP_EX(CActionDialog)
197                        //CHAIN_MSG_MAP(CDialogImpl<CActionDialog>)
198                        CHAIN_MSG_MAP(CDialogResize<CActionDialog>)
199                        MSG_WM_INITDIALOG(OnInitDialog)
200                        COMMAND_ID_HANDLER_EX(IDC_FILTERGRAPHHELPER_ACTION_SAVEAS, OnSaveAs)
201                        COMMAND_ID_HANDLER_EX(IDC_FILTERGRAPHHELPER_ACTION_OPENGSN, OnOpenGsn)
202                        COMMAND_ID_HANDLER_EX(IDC_FILTERGRAPHHELPER_ACTION_OPENGE, OnOpenGe)
203                        COMMAND_ID_HANDLER_EX(IDC_FILTERGRAPHHELPER_ACTION_OPENLIST, OnOpenList)
204                        REFLECT_NOTIFICATIONS()
205                END_MSG_MAP()
206
207                BEGIN_DLGRESIZE_MAP(CActionDialog)
208                        //DLGRESIZE_CONTROL(IDC_FILTERGRAPHHELPER_ACTION_, DLSZ_SIZE_X | DLSZ_SIZE_Y)
209                END_DLGRESIZE_MAP()
210
211                private:
212                        CPropertyFrameDialog* m_pOwner;
213                        BOOL m_bActivating;
214                        CStatic m_TitleStatic;
215                        CFont m_TitleFont;
216                        CButton m_SaveAsButton;
217                        CRoHyperStatic m_SaveAsDescriptionStatic;
218                        CButton m_OpenGsnButton;
219                        CRoHyperStatic m_OpenGsnDescriptionStatic;
220                        CButton m_OpenGeButton;
221                        CRoHyperStatic m_OpenGeDescriptionStatic;
222                        CButton m_OpenListButton;
223                        CRoHyperStatic m_OpenListDescriptionStatic;
224                        CStringW m_sFilterGraphMonikerDisplayName;
225                        CRoMapT<INT_PTR, BOOL> m_ChangeMap;
226
227                public:
228                // CActionDialog
229
230                // Window Message Handler
231                        LRESULT OnInitDialog(HWND, LPARAM lParam)
232                        {
233                                m_pOwner = (CPropertyFrameDialog*) lParam;
234                                m_bActivating = TRUE;
235                                _ATLTRY
236                                {
237                                        CWaitCursor WaitCursor;
238                                        m_TitleStatic = GetDlgItem(IDC_FILTERGRAPHHELPER_ACTION_TITLE);
239                                        CreateTitleFont(m_TitleFont, m_TitleStatic);
240                                        m_SaveAsButton = GetDlgItem(IDC_FILTERGRAPHHELPER_ACTION_SAVEAS);
241                                        _W(m_SaveAsDescriptionStatic.SubclassWindow(GetDlgItem(IDC_FILTERGRAPHHELPER_ACTION_SAVEASDESCRIPTION)));
242                                        m_OpenGsnButton = GetDlgItem(IDC_FILTERGRAPHHELPER_ACTION_OPENGSN);
243                                        _W(m_OpenGsnDescriptionStatic.SubclassWindow(GetDlgItem(IDC_FILTERGRAPHHELPER_ACTION_OPENGSNDESCRIPTION)));
244                                        m_OpenGeButton = GetDlgItem(IDC_FILTERGRAPHHELPER_ACTION_OPENGE);
245                                        _W(m_OpenGeDescriptionStatic.SubclassWindow(GetDlgItem(IDC_FILTERGRAPHHELPER_ACTION_OPENGEDESCRIPTION)));
246                                        m_OpenListButton = GetDlgItem(IDC_FILTERGRAPHHELPER_ACTION_OPENLIST);
247                                        _W(m_OpenListDescriptionStatic.SubclassWindow(GetDlgItem(IDC_FILTERGRAPHHELPER_ACTION_OPENLISTDESCRIPTION)));
248                                        //DlgResize_Init(FALSE, FALSE);
249                                        _ATLTRY
250                                        {
251                                                m_sFilterGraphMonikerDisplayName.Empty();
252                                                const CComQIPtr<ISpy> pSpy = m_pOwner->m_Owner.GetFilterGraph();
253                                                if(pSpy)
254                                                {
255                                                        CComBSTR sFilterGraphMonikerDisplayName;
256                                                        __C(pSpy->get_MonikerDisplayName(&sFilterGraphMonikerDisplayName));
257                                                        m_sFilterGraphMonikerDisplayName = sFilterGraphMonikerDisplayName;
258                                                }
259                                        }
260                                        _ATLCATCHALL()
261                                        {
262                                                _Z_EXCEPTION();
263                                        }
264                                        const BOOL bMonikerDisplayNameAvailable = !m_sFilterGraphMonikerDisplayName.IsEmpty();
265                                        m_OpenGsnButton.EnableWindow(bMonikerDisplayNameAvailable);
266                                        m_OpenGsnDescriptionStatic.EnableWindow(bMonikerDisplayNameAvailable);
267                                        m_OpenGeButton.EnableWindow(bMonikerDisplayNameAvailable);
268                                        m_OpenGeDescriptionStatic.EnableWindow(bMonikerDisplayNameAvailable);
269                                        m_bActivating = FALSE;
270                                }
271                                _ATLCATCH(Exception)
272                                {
273                                        for(CWindow Window = GetWindow(GW_CHILD); Window; Window = Window.GetWindow(GW_HWNDNEXT))
274                                                Window.EnableWindow(FALSE);
275                                        AtlExceptionMessageBox(m_hWnd, Exception);
276                                }
277                                return TRUE;
278                        }
279                        LRESULT OnSaveAs(UINT, INT, HWND)
280                        {
281                                CPath sPath;
282                                static const COMDLG_FILTERSPEC g_pFilter[] = 
283                                {
284                                        { _T("GraphEdit Files"), _T("*.grf") },
285                                        { _T("All Files"), _T("*.*") },
286                                };
287                                if(GetOsVersion() >= GetWinVistaOsVersion())
288                                {
289                                        CShellFileSaveDialog Dialog(NULL, FOS_OVERWRITEPROMPT | FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST, _T("grf"), g_pFilter, DIM(g_pFilter));
290                                        if(Dialog.DoModal(m_hWnd) != IDOK)
291                                                return 0;
292                                        CString sPathString;
293                                        __C(Dialog.GetFilePath(sPathString));
294                                        sPath = (LPCTSTR) sPathString;
295                                } else
296                                {
297                                        CString sFilter;
298                                        CFileDialog Dialog(FALSE, _T("grf"), NULL, OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_EXPLORER | OFN_ENABLESIZING, GetLegacyFilter(g_pFilter, sFilter));
299                                        if(Dialog.DoModal(m_hWnd) != IDOK)
300                                                return 0;
301                                        sPath = Dialog.m_szFileName;
302                                }
303                                #pragma region Save
304                                // NOTE: See http://msdn.microsoft.com/en-us/library/windows/desktop/dd377551
305                                const CComQIPtr<IPersistStream> pPersistStream = m_pOwner->m_Owner.GetFilterGraph();
306                                __D(pPersistStream, E_NOINTERFACE);
307                                CComPtr<IStorage> pStorage;
308                                {
309                                        __C(StgCreateDocfile(CStringW(sPath), STGM_CREATE | STGM_TRANSACTED | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &pStorage));
310                                        CComPtr<IStream> pStream;
311                                        __C(pStorage->CreateStream(L"ActiveMovieGraph", STGM_WRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE, 0, 0, &pStream));
312                                        __C(pPersistStream->Save(pStream, TRUE));
313                                }
314                                __C(pStorage->Commit(STGC_DEFAULT));
315                                #pragma endregion
316                                MessageBeep(MB_OK);
317                                return 0;
318                        }
319                        LRESULT OnOpenGsn(UINT, INT, HWND)
320                        {
321                                OpenMonikerWithGsn(m_sFilterGraphMonikerDisplayName, m_hWnd);
322                                return 0;
323                        }
324                        LRESULT OnOpenGe(UINT, INT, HWND)
325                        {
326                                OpenMonikerWithGe(m_sFilterGraphMonikerDisplayName, m_hWnd);
327                                return 0;
328                        }
329                        LRESULT OnOpenList(UINT, INT, HWND)
330                        {
331                                DoFilterGraphListPropertySheetModal(m_hWnd);
332                                return 0;
333                        }
334                };
335
336                ////////////////////////////////////////////////////
337                // CEmailDialog
338
339                class CEmailDialog :
340                        public CDialogImpl<CEmailDialog>,
341                        public CDialogResize<CEmailDialog>
342                {
343                public:
344                        enum { IDD = IDD_FILTERGRAPHHELPER_EMAIL };
345
346                BEGIN_MSG_MAP_EX(CEmailDialog)
347                        //CHAIN_MSG_MAP(CDialogImpl<CEmailDialog>)
348                        CHAIN_MSG_MAP(CDialogResize<CEmailDialog>)
349                        MSG_WM_INITDIALOG(OnInitDialog)
350                        MSG_WM_DESTROY(OnDestroy)
351                        MSG_WM_SHOWWINDOW(OnShowWindow)
352                        COMMAND_HANDLER_EX(IDC_FILTERGRAPHHELPER_EMAIL_FROM, EN_CHANGE, OnChanged)
353                        COMMAND_HANDLER_EX(IDC_FILTERGRAPHHELPER_EMAIL_TO, EN_CHANGE, OnChanged)
354                        COMMAND_HANDLER_EX(IDC_FILTERGRAPHHELPER_EMAIL_METHOD, CBN_SELENDOK, OnChanged)
355                        COMMAND_HANDLER_EX(IDC_FILTERGRAPHHELPER_EMAIL_HOST, EN_CHANGE, OnChanged)
356                        COMMAND_HANDLER_EX(IDC_FILTERGRAPHHELPER_EMAIL_USERNAME, EN_CHANGE, OnChanged)
357                        COMMAND_HANDLER_EX(IDC_FILTERGRAPHHELPER_EMAIL_PASSWORD, EN_CHANGE, OnChanged)
358                        COMMAND_HANDLER_EX(IDC_FILTERGRAPHHELPER_EMAIL_BODY, EN_CHANGE, OnChanged)
359                        COMMAND_ID_HANDLER_EX(IDC_FILTERGRAPHHELPER_EMAIL_SEND, OnSend)
360                        NOTIFY_HANDLER_EX(IDC_FILTERGRAPHHELPER_EMAIL_CLEANUP, CRoHyperStatic::NC_ANCHORCLICKED, OnCleanupStaticAnchorClicked)
361                        REFLECT_NOTIFICATIONS()
362                END_MSG_MAP()
363
364                BEGIN_DLGRESIZE_MAP(CEmailDialog)
365                        DLGRESIZE_CONTROL(IDC_FILTERGRAPHHELPER_EMAIL_BODY, DLSZ_SIZE_X | DLSZ_SIZE_Y)
366                        DLGRESIZE_CONTROL(IDC_FILTERGRAPHHELPER_EMAIL_SEND, DLSZ_MOVE_X | DLSZ_MOVE_Y)
367                        DLGRESIZE_CONTROL(IDC_FILTERGRAPHHELPER_EMAIL_CLEANUP, DLSZ_MOVE_Y)
368                END_DLGRESIZE_MAP()
369
370                private:
371                        CPropertyFrameDialog* m_pOwner;
372                        BOOL m_bActivating;
373                        CStatic m_TitleStatic;
374                        CFont m_TitleFont;
375                        CRoEdit m_FromEdit;
376                        CRoEdit m_ToEdit;
377                        CRoComboBoxT<> m_MethodComboBox;
378                        CRoEdit m_HostEdit;
379                        CRoEdit m_UsernameEdit;
380                        CRoEdit m_PasswordEdit;
381                        CRoEdit m_BodyEdit;
382                        CButton m_SendButton;
383                        CRoHyperStatic m_CleanupStatic;
384                        CString m_sFilterGraphText;
385                        CRoMapT<INT_PTR, BOOL> m_ChangeMap;
386
387                public:
388                // CEmailDialog
389                        VOID InitializeControlsFromRegistry()
390                        {
391                                const CString sMessageString = _RegKeyHelper::QueryStringValue(HKEY_CURRENT_USER, REGISTRY_ROOT, _T("Email Message Template"));
392                                if(sMessageString.IsEmpty())
393                                        return;
394                                _ATLTRY
395                                {
396                                        CObjectPtr<CMessage> pMessage;
397                                        pMessage.Construct();
398                                        pMessage->LoadTypeInfo(IDR_EMAILTOOLS);
399                                        pMessage->SetAsString(CStringA(sMessageString));
400                                        #pragma region Sender and Recipients
401                                        CComBSTR sSender, sToRecipients;
402                                        __C(pMessage->get_Sender(&sSender));
403                                        __C(pMessage->get_ToRecipients(&sToRecipients));
404                                        m_FromEdit.SetValue(CString(sSender));
405                                        m_ToEdit.SetValue(CString(sToRecipients));
406                                        #pragma endregion
407                                        CComBSTR sAuthMethods;
408                                        __C(pMessage->get_AuthMethods(&sAuthMethods));
409                                        VARIANT_BOOL bSecureSocketsLayer, bTransportLayerSecurity;
410                                        __C(pMessage->get_SecureSocketsLayer(&bSecureSocketsLayer));
411                                        __C(pMessage->get_TransportLayerSecurity(&bTransportLayerSecurity));
412                                        #pragma region Host and Port
413                                        CComBSTR sHost;
414                                        __C(pMessage->get_ServerHost(&sHost));
415                                        LONG nPort = 0;
416                                        __C(pMessage->get_ServerPort(&nPort));
417                                        CString sHostT(sHost);
418                                        if(nPort)
419                                                sHostT += AtlFormatString(_T(":%d"), nPort);
420                                        m_HostEdit.SetValue(sHostT);
421                                        #pragma endregion
422                                        #pragma region User Name and Password
423                                        CComBSTR sAuthName, sAuthPassword;
424                                        __C(pMessage->get_AuthName(&sAuthName));
425                                        __C(pMessage->get_AuthPassword(&sAuthPassword));
426                                        m_UsernameEdit.SetValue(CString(sAuthName));
427                                        m_PasswordEdit.SetValue(CString(sAuthPassword));
428                                        #pragma endregion
429                                        m_MethodComboBox.SetCurSel(0);
430                                        if(bTransportLayerSecurity != ATL_VARIANT_FALSE && sHostT.CompareNoCase(_T("smtp.gmail.com")) == 0)
431                                        {
432                                                //m_MethodComboBox.SetCurSel(0);
433                                        } else
434                                        {
435                                                if(bTransportLayerSecurity != ATL_VARIANT_FALSE)
436                                                        m_MethodComboBox.SetCurSel(1);
437                                                else if(bSecureSocketsLayer != ATL_VARIANT_FALSE)
438                                                        m_MethodComboBox.SetCurSel(2);
439                                                else if(CString(sAuthMethods).CompareNoCase(_T("cram-md5")) == 0)
440                                                        m_MethodComboBox.SetCurSel(3);
441                                                else if(!CString(sAuthName).IsEmpty())
442                                                        m_MethodComboBox.SetCurSel(4);
443                                                else
444                                                        m_MethodComboBox.SetCurSel(5);
445                                        }
446                                }
447                                _ATLCATCHALL()
448                                {
449                                        _Z_EXCEPTION();
450                                }
451                        }
452                        VOID InitializeBody()
453                        {
454                                CString sText;
455                                sText += _T("(add notes here; graph data will be appended below)") _T("\r\n") _T("\r\n");
456                                sText += _T("* * *") _T("\r\n") _T("\r\n");
457                                #define I FormatIdentifier
458                                #pragma region System
459                                {
460                                        sText += _T("# System") _T("\r\n") _T("\r\n");
461                                        OSVERSIONINFOEX Version;
462                                        ZeroMemory(&Version, sizeof Version);
463                                        Version.dwOSVersionInfoSize = sizeof Version;
464                                        GetVersionEx((OSVERSIONINFO*) &Version);
465                                        #pragma region Version
466                                        CRoArrayT<CString> VersionArray;
467                                        VersionArray.Add(AtlFormatString(_T("%s Build %s"), I(AtlFormatString(_T("%d.%d"), Version.dwMajorVersion, Version.dwMinorVersion)), I(Version.dwBuildNumber)));
468                                        switch((Version.dwMajorVersion << 16) + Version.dwMinorVersion)
469                                        {
470                                        case 0x00050001: 
471                                                VersionArray.Add(_T("Windows XP"));
472                                                break;
473                                        case 0x00050002: 
474                                                if(Version.wProductType != VER_NT_WORKSTATION)
475                                                        VersionArray.Add(_T("Windows Server 2003"));
476                                                break;
477                                        case 0x00060000: 
478                                                if(Version.wProductType == VER_NT_WORKSTATION)
479                                                        VersionArray.Add(_T("Windows Vista"));
480                                                else
481                                                        VersionArray.Add(_T("Windows Server 2008"));
482                                                break;
483                                        case 0x00060001: 
484                                                if(Version.wProductType == VER_NT_WORKSTATION)
485                                                        VersionArray.Add(_T("Windows 7"));
486                                                else
487                                                        VersionArray.Add(_T("Windows Server 2008 R2"));
488                                                break;
489                                        case 0x00060002: 
490                                                if(Version.wProductType == VER_NT_WORKSTATION)
491                                                        VersionArray.Add(_T("Windows 8"));
492                                                else
493                                                        VersionArray.Add(_T("Windows Server 2012"));
494                                                break;
495                                        }
496                                        if(_tcslen(Version.szCSDVersion))
497                                                VersionArray.Add(Version.szCSDVersion);
498                                        if(Version.wServicePackMajor)
499                                                VersionArray.Add(AtlFormatString(_T("Service Pack %s"), I(AtlFormatString(_T("%d.%d"), Version.wServicePackMajor, Version.wServicePackMinor))));
500                                        //Version.wSuiteMask, Version.wProductType
501                                        sText += AtlFormatString(_T(" * ") _T("Version: %s") _T("\r\n"), _StringHelper::Join(VersionArray, _T("; ")));
502                                        #pragma endregion
503                                        TCHAR pszComputerName[256] = { 0 };
504                                        DWORD nComputerNameLength = DIM(pszComputerName);
505                                        GetComputerName(pszComputerName, &nComputerNameLength);
506                                        sText += AtlFormatString(_T(" * ") _T("Computer Name: %s") _T("\r\n"), I(pszComputerName));
507                                        TCHAR pszUserName[256] = { 0 };
508                                        DWORD nUserNameLength = DIM(pszUserName);
509                                        GetUserName(pszUserName, &nUserNameLength);
510                                        CString sUserName(pszUserName);
511                                        BOOL bAdministrator = FALSE;
512                                        bool bIsMember = FALSE;
513                                        if(CAccessToken().CheckTokenMembership(Sids::Admins(), &bIsMember) && bIsMember)
514                                                bAdministrator = TRUE;
515                                        sText += AtlFormatString(_T(" * ") _T("User Name: %s %s") _T("\r\n"), I(sUserName), bAdministrator ? _T("(Administrator)") : _T(""));
516                                        SYSTEM_INFO SystemInformation;
517                                        GetSystemInfo(&SystemInformation);
518                                        #pragma region Architecture
519                                        CString sArchitecture;
520                                        switch(SystemInformation.wProcessorArchitecture)
521                                        {
522                                        case PROCESSOR_ARCHITECTURE_INTEL:
523                                                sArchitecture = I(_T("x86"));
524                                                break;
525                                        case PROCESSOR_ARCHITECTURE_AMD64:
526                                                sArchitecture = I(_T("AMD/Intel x64"));
527                                                break;
528                                        case PROCESSOR_ARCHITECTURE_IA64:
529                                                sArchitecture = I(_T("Intel Itanium"));
530                                                break;
531                                        default:
532                                                sArchitecture = I(SystemInformation.wProcessorArchitecture, _T("0x%04X"));
533                                        }
534                                        #if defined(_WIN64)
535                                                sText += AtlFormatString(_T(" * ") _T("Architecture: %s (x64 Application)") _T("\r\n"), sArchitecture);
536                                        #else
537                                                sText += AtlFormatString(_T(" * ") _T("Architecture: %s") _T("\r\n"), sArchitecture);
538                                        #endif // defined(_WIN64)
539                                        #pragma endregion
540                                        sText += AtlFormatString(_T(" * ") _T("Processors: %s, Active Mask %s") _T("\r\n"), I(SystemInformation.dwNumberOfProcessors), I((DWORD) SystemInformation.dwActiveProcessorMask, _T("0x%X")));
541                                        sText += AtlFormatString(_T(" * ") _T("Page Size: %s") _T("\r\n"), I(SystemInformation.dwPageSize, _T("0x%X")));
542                                        sText += AtlFormatString(_T(" * ") _T("Application Address Space: %s..%s") _T("\r\n"), I(SystemInformation.lpMinimumApplicationAddress), I(SystemInformation.lpMaximumApplicationAddress));
543                                        #pragma region Memory
544                                        MEMORYSTATUSEX MemoryStatus = { sizeof MemoryStatus };
545                                        _W(GlobalMemoryStatusEx(&MemoryStatus));
546                                        sText += AtlFormatString(_T(" * ") _T("Physical Memory: %s MB") _T("\r\n"), I(_StringHelper::FormatNumber((LONG) (MemoryStatus.ullTotalPhys >> 20))));
547                                        sText += AtlFormatString(_T(" * ") _T("Committed Memory Limit: %s MB") _T("\r\n"), I(_StringHelper::FormatNumber((LONG) (MemoryStatus.ullTotalPageFile >> 20))));
548                                        #pragma endregion
549                                }
550                                #pragma endregion
551                                sText += AtlFormatString(_T(" * ") _T("Module Version: %s") _T("\r\n"), I(_VersionInfoHelper::GetVersionString(_VersionInfoHelper::GetFileVersion(_VersionInfoHelper::GetModulePath()))));
552                                SYSTEMTIME LocalTime;
553                                GetLocalTime(&LocalTime);
554                                sText += AtlFormatString(_T(" * ") _T("Local Time: %s") _T("\r\n"), I(_StringHelper::FormatDateTime(&LocalTime)));
555                                sText += _T("\r\n");
556                                #undef I
557                                m_BodyEdit.SetValue(sText);
558                        }
559                        VOID UpdateControls()
560                        {
561                                BOOL bAllowSend = TRUE;
562                                if(m_ToEdit.GetValue().Trim().IsEmpty())
563                                        bAllowSend = FALSE;
564                                const INT nMethod = m_MethodComboBox.GetCurSel();
565                                m_HostEdit.GetWindow(GW_HWNDPREV).EnableWindow(nMethod != 0); // Google Mail
566                                m_HostEdit.EnableWindow(nMethod != 0); // Google Mail
567                                m_UsernameEdit.GetWindow(GW_HWNDPREV).EnableWindow(nMethod != 5); // No Authentication
568                                m_UsernameEdit.EnableWindow(nMethod != 5); // No Authentication
569                                m_PasswordEdit.GetWindow(GW_HWNDPREV).EnableWindow(nMethod != 5); // No Authentication
570                                m_PasswordEdit.EnableWindow(nMethod != 5); // No Authentication
571                                if(nMethod != 0) // Google Mail
572                                        if(m_HostEdit.GetValue().Trim().IsEmpty())
573                                                bAllowSend = FALSE;
574                                if(nMethod != 5) // No Authentication
575                                {
576                                        if(m_UsernameEdit.GetValue().Trim().IsEmpty())
577                                                bAllowSend = FALSE;
578                                        if(m_PasswordEdit.GetValue().Trim().IsEmpty())
579                                                bAllowSend = FALSE;
580                                }
581                                m_SendButton.EnableWindow(bAllowSend);
582                        }
583
584                // Window Message Handler
585                        LRESULT OnInitDialog(HWND, LPARAM lParam)
586                        {
587                                m_pOwner = (CPropertyFrameDialog*) lParam;
588                                m_bActivating = TRUE;
589                                _ATLTRY
590                                {
591                                        CWaitCursor WaitCursor;
592                                        m_TitleStatic = GetDlgItem(IDC_FILTERGRAPHHELPER_EMAIL_TITLE);
593                                        CreateTitleFont(m_TitleFont, m_TitleStatic);
594                                        m_FromEdit = GetDlgItem(IDC_FILTERGRAPHHELPER_EMAIL_FROM);
595                                        m_ToEdit = GetDlgItem(IDC_FILTERGRAPHHELPER_EMAIL_TO);
596                                        m_MethodComboBox.Initialize(GetDlgItem(IDC_FILTERGRAPHHELPER_EMAIL_METHOD));
597                                        m_MethodComboBox.SetCurSel(0);
598                                        m_HostEdit = GetDlgItem(IDC_FILTERGRAPHHELPER_EMAIL_HOST);
599                                        m_UsernameEdit = GetDlgItem(IDC_FILTERGRAPHHELPER_EMAIL_USERNAME);
600                                        m_PasswordEdit = GetDlgItem(IDC_FILTERGRAPHHELPER_EMAIL_PASSWORD);
601                                        m_BodyEdit = GetDlgItem(IDC_FILTERGRAPHHELPER_EMAIL_BODY);
602                                        m_BodyEdit.SetFont(m_pOwner->m_TextFont);
603                                        m_SendButton = GetDlgItem(IDC_FILTERGRAPHHELPER_EMAIL_SEND);
604                                        _W(m_CleanupStatic.SubclassWindow(GetDlgItem(IDC_FILTERGRAPHHELPER_EMAIL_CLEANUP)));
605                                        DlgResize_Init(FALSE, FALSE);
606                                        InitializeControlsFromRegistry();
607                                        InitializeBody();
608                                        m_sFilterGraphText = m_pOwner->m_Owner.GetText();
609                                        UpdateControls();
610                                        m_bActivating = FALSE;
611                                }
612                                _ATLCATCH(Exception)
613                                {
614                                        for(CWindow Window = GetWindow(GW_CHILD); Window; Window = Window.GetWindow(GW_HWNDNEXT))
615                                                Window.EnableWindow(FALSE);
616                                        AtlExceptionMessageBox(m_hWnd, Exception);
617                                }
618                                return TRUE;
619                        }
620                        LRESULT OnDestroy()
621                        {
622                                return 0;
623                        }
624                        LRESULT OnShowWindow(BOOL bShowing, INT)
625                        {
626                                if(bShowing && !m_ChangeMap.Lookup(IDC_FILTERGRAPHHELPER_EMAIL_BODY))
627                                        InitializeBody();
628                                return 0;
629                        }
630                        LRESULT OnChanged(UINT, INT_PTR nIdentifier, HWND)
631                        {
632                                if(m_bActivating)
633                                        return 0;
634                                m_ChangeMap[nIdentifier] = TRUE;
635                                UpdateControls();
636                                return 0;
637                        }
638                        LRESULT OnChanged(NMHDR* pHeader)
639                        {
640                                return OnChanged(pHeader->code, pHeader->idFrom, pHeader->hwndFrom);
641                        }
642                        LRESULT OnSend(UINT, INT, HWND)
643                        {
644                                CWaitCursor WaitCursor;
645                                CObjectPtr<CMessage> pMessage;
646                                pMessage.Construct();
647                                #pragma region Setup
648                                pMessage->LoadTypeInfo(IDR_EMAILTOOLS);
649                                __C(pMessage->put_Sender(CComBSTR(m_FromEdit.GetValue())));
650                                __C(pMessage->put_ToRecipients(CComBSTR(m_ToEdit.GetValue())));
651                                // NOTE:
652                                // 0 Google Mail (SMTP, TLS Connection)
653                                // 1 SMTP, TLS Connection, Plain Text Authentication (TLS, PLAIN)
654                                // 2 SMTP, SSL Connection, Plain Text Authentication (SSL, PLAIN)
655                                // 3 SMTP, Digest Authentication (CRAM-MD5)
656                                // 4 SMTP, Plain Text Authentication (PLAIN)
657                                // 5 SMTP, No Authentication
658                                const INT nMethod = m_MethodComboBox.GetCurSel();
659                                __C(pMessage->put_SecureSocketsLayer((nMethod == 2) ? ATL_VARIANT_TRUE : ATL_VARIANT_FALSE));
660                                __C(pMessage->put_TransportLayerSecurity((nMethod < 2) ? ATL_VARIANT_TRUE : ATL_VARIANT_FALSE));
661                                if(nMethod != 5)
662                                {
663                                        __C(pMessage->put_AuthMethods(CComBSTR(_T("plain"))));
664                                        __C(pMessage->put_AuthName(CComBSTR(m_UsernameEdit.GetValue())));
665                                        __C(pMessage->put_AuthPassword(CComBSTR(m_PasswordEdit.GetValue())));
666                                }
667                                switch(nMethod)
668                                {
669                                case 0:
670                                        __C(pMessage->put_ServerHost(CComBSTR(_T("smtp.gmail.com"))));
671                                        break;
672                                default:
673                                        CString sHost = m_HostEdit.GetValue();
674                                        sHost.Trim();
675                                        const INT nPortPosition = sHost.Find(_T(":"));
676                                        if(nPortPosition >= 0)
677                                        {
678                                                INT nPort;
679                                                __D(AtlStringToInteger(sHost.Mid(nPortPosition + 1), nPort), E_UNNAMED);
680                                                __C(pMessage->put_ServerPort(nPort));
681                                                sHost = sHost.Left(nPortPosition);
682                                        }
683                                        __C(pMessage->put_ServerHost(CComBSTR(sHost)));
684                                        break;
685                                }
686                                switch(nMethod)
687                                {
688                                case 3:
689                                        __C(pMessage->put_AuthMethods(CComBSTR(_T("cram-md5"))));
690                                        break;
691                                }
692                                #pragma endregion
693                                CStringA sMessageString = pMessage->GetAsString();
694                                CString sText = m_BodyEdit.GetValue();
695                                sText.TrimRight(_T("\t\n\r "));
696                                sText += _T("\r\n") _T("\r\n") _T("* * *") _T("\r\n") _T("\r\n");
697                                sText += m_sFilterGraphText;
698                                __C(pMessage->put_Body(CComBSTR(sText)));
699                                CString sSubject = AtlFormatString(_T("DirectShow Filter Graph by %s"), AtlLoadString(IDS_PROJNAME));
700                                __C(pMessage->put_Subject(CComBSTR(sSubject)));
701                                __C(pMessage->Send());
702                                _RegKeyHelper::SetStringValue(HKEY_CURRENT_USER, REGISTRY_ROOT, _T("Email Message Template"), CString(sMessageString));
703                                AtlOptionalMessageBoxEx(m_hWnd, _T("CFilterGraphHelper::CPropertyFrameDialog::CEmailDialog::CredentialsSaved"), _T("The email was sent") _T("\r\n\r\n") _T("The credentials were written into registry for further reuse. Use Erase Cached Credentials link to delete them from registry."), IDS_INFORMATION, MB_ICONINFORMATION | MB_OK);
704                                MessageBeep(MB_OK);
705                                return 0;
706                        }
707                        LRESULT OnCleanupStaticAnchorClicked(NMHDR*)
708                        {
709                                _RegKeyHelper::DeleteValue(HKEY_CURRENT_USER, REGISTRY_ROOT, _T("Email Message Template"));
710                                AtlOptionalMessageBoxEx(m_hWnd, _T("CFilterGraphHelper::CPropertyFrameDialog::CEmailDialog::SavedCredentialsDeleted"), _T("Cached email credentials are removed from registry."), IDS_INFORMATION, MB_ICONINFORMATION | MB_OK);
711                                MessageBeep(MB_OK);
712                                return 0;
713                        }
714                };
715
716                ////////////////////////////////////////////////////
717                // CData
718
719                class CData
720                {
721                public:
722
723                        /////////////////////////////////////////////////////////
724                        // TYPE
725
726                        typedef enum _TYPE
727                        {
728                                TYPE_UNKNOWN = 0,
729                                TYPE_FILTERS,
730                                TYPE_FILTER,
731                                TYPE_FILTERPROPERTYPAGE,
732                                TYPE_ACTION,
733                                TYPE_EMAIL,
734                        } TYPE;
735
736                public:
737                        TYPE m_Type;
738                        CComPtr<IBaseFilter> m_pBaseFilter;
739                        CLSID m_BaseFilterClassIdentifier;
740                        CString m_sBaseFilterClassDescription;
741                        CString m_sBaseFilterModulePath;
742                        CLSID m_PropertyPageClassIdentifier;
743                        CComPtr<IPropertyPage> m_pPropertyPage;
744                        CObjectPtr<CPropertyPageSite> m_pSite;
745                        BOOL m_bSiteActivated;
746
747                public:
748                // CData
749                        CData(TYPE Type = TYPE_UNKNOWN) :
750                                m_Type(Type),
751                                m_BaseFilterClassIdentifier(CLSID_NULL),
752                                m_PropertyPageClassIdentifier(CLSID_NULL)
753                        {
754                        }
755                        CData(IBaseFilter* pBaseFilter) :
756                                m_Type(TYPE_FILTER),
757                                m_pBaseFilter(pBaseFilter),
758                                m_BaseFilterClassIdentifier(CLSID_NULL),
759                                m_PropertyPageClassIdentifier(CLSID_NULL)
760                        {
761                                _ATLTRY
762                                {
763                                        CLSID ClassIdentifier = CLSID_NULL;
764                                        if(SUCCEEDED(pBaseFilter->GetClassID(&ClassIdentifier)) && ClassIdentifier != CLSID_NULL)
765                                        {
766                                                m_BaseFilterClassIdentifier = ClassIdentifier;
767                                                const CString sClassIdentifier(_PersistHelper::StringFromIdentifier(ClassIdentifier));
768                                                m_sBaseFilterClassDescription = _RegKeyHelper::QueryStringValue(HKEY_CLASSES_ROOT, AtlFormatString(_T("CLSID\\%s"), sClassIdentifier));
769                                                m_sBaseFilterModulePath = _RegKeyHelper::QueryStringValue(HKEY_CLASSES_ROOT, AtlFormatString(_T("CLSID\\%s\\InprocServer32"), sClassIdentifier));
770                                        }
771                                }
772                                _ATLCATCHALL()
773                                {
774                                        _Z_EXCEPTION();
775                                }
776                        }
777                        CData(IBaseFilter* pBaseFilter, const CLSID& PropertyPageClassIdentifier, IPropertyPage* pPropertyPage) :
778                                m_Type(TYPE_FILTERPROPERTYPAGE),
779                                m_pBaseFilter(pBaseFilter),
780                                m_BaseFilterClassIdentifier(CLSID_NULL),
781                                m_PropertyPageClassIdentifier(PropertyPageClassIdentifier),
782                                m_pPropertyPage(pPropertyPage),
783                                m_bSiteActivated(FALSE)
784                        {
785                                _A(pPropertyPage);
786                        }
787                        CString GetPropertyPageTitle() const
788                        {
789                                if(!m_pPropertyPage)
790                                        return _T("");
791                                PROPPAGEINFO PageInformation;
792                                ZeroMemory(&PageInformation, sizeof PageInformation);
793                                PageInformation.cb = sizeof PageInformation;
794                                __C(m_pPropertyPage->GetPageInfo(&PageInformation));
795                                CString sTitle(PageInformation.pszTitle);
796                                CoTaskMemFree(PageInformation.pszTitle);
797                                CoTaskMemFree(PageInformation.pszDocString);
798                                CoTaskMemFree(PageInformation.pszHelpFile);
799                                return sTitle;
800                        }
801                };
802
803        private:
804                CFilterGraphHelper& m_Owner;
805                BOOL m_bActivating; 
806                CRoTreeViewT<CData, CRoListControlDataTraitsT> m_TreeView;
807                CTreeItem m_FiltersItem;
808                CTreeItem m_ActionItem;
809                CTreeItem m_EmailItem;
810                CTabCtrl m_Tab;
811                CRoEdit m_TextEdit;
812                CRect m_TextPosition;
813                CFont m_TextFont;
814                CButton m_OkButton;
815                CButton m_CancelButton;
816                CButton m_ApplyButton;
817                CObjectPtr<CPropertyPageSite> m_pCurrentSite;
818                CActionDialog m_ActionDialog;
819                CEmailDialog m_EmailDialog;
820
821                static VOID CreateTitleFont(CFont& Font, HWND hStaticWindow = NULL)
822                {
823                        _A(!Font);
824                        CLogFont LogFont;
825                        LogFont.SetHeight(12);
826                        LogFont.lfWeight = FW_BOLD;
827                        _tcsncpy_s(LogFont.lfFaceName, _T("Verdana"), _TRUNCATE);
828                        _W(Font.CreateFontIndirect(&LogFont));
829                        if(hStaticWindow)
830                                CStatic(hStaticWindow).SetFont(Font);
831                }
832
833        public:
834        // CPropertyFrameDialog
835                CPropertyFrameDialog(CFilterGraphHelper* pOwner) :
836                        m_Owner(*pOwner)
837                {
838                }
839                CRect GetTextEditPosition() const
840                {
841                        CRect Position;
842                        _W(m_TextEdit.GetWindowRect(Position));
843                        _W(ScreenToClient(Position));
844                        return Position;
845                }
846                VOID UpdateTree()
847                {
848                        CWindowRedraw TreeViewRedraw(m_TreeView);
849                        m_TreeView.DeleteAllItems();
850                        #pragma region Filter
851                        CTreeItem FiltersItem = m_TreeView.InsertItem(NULL, NULL, CData(CData::TYPE_FILTERS), _T("Filters"));
852                        _FilterGraphHelper::CFilterArray FilterArray;
853                        _FilterGraphHelper::GetGraphFilters(m_Owner.m_pFilterGraph, FilterArray);
854                        CTreeItem PreviousFilterItem;
855                        for(SIZE_T nIndex = 0; nIndex < FilterArray.GetCount(); nIndex++)
856                        {
857                                const CComPtr<IBaseFilter>& pBaseFilter = FilterArray[nIndex];
858                                CData Data(pBaseFilter);
859                                CString sText(_FilterGraphHelper::GetFilterName(pBaseFilter));
860                                if(!Data.m_sBaseFilterClassDescription.IsEmpty() && sText.Find(Data.m_sBaseFilterClassDescription) < 0)
861                                        sText += AtlFormatString(_T(" (%s)"), Data.m_sBaseFilterClassDescription);
862                                CTreeItem FilterItem = m_TreeView.InsertItem(FiltersItem, PreviousFilterItem, Data, sText);
863                                PreviousFilterItem = FilterItem;
864                                #pragma region Property Page
865                                const CComQIPtr<ISpecifyPropertyPages> pSpecifyPropertyPages = pBaseFilter;
866                                if(!pSpecifyPropertyPages)
867                                        continue;
868                                _ATLTRY
869                                {
870                                        CAUUID Pages;
871                                        ZeroMemory(&Pages, sizeof Pages);
872                                        __C(pSpecifyPropertyPages->GetPages(&Pages));
873                                        CComHeapPtr<CLSID> pClassIdentifiers;
874                                        pClassIdentifiers.Attach(Pages.pElems);
875                                        CTreeItem PreviousPageItem;
876                                        for(UINT nPageIndex = 0; nPageIndex < Pages.cElems; nPageIndex++)
877                                        {
878                                                const CLSID& ClassIdentifier = pClassIdentifiers[nPageIndex];
879                                                if(ClassIdentifier == CLSID_NULL)
880                                                        continue;
881                                                _ATLTRY
882                                                {
883                                                        CComPtr<IPropertyPage> pPropertyPage;
884                                                        __C(pPropertyPage.CoCreateInstance(ClassIdentifier));
885                                                        CData Data(pBaseFilter, ClassIdentifier, pPropertyPage);
886                                                        Data.m_pSite.Construct()->Initialize(this, pBaseFilter, pPropertyPage);
887                                                        CTreeItem PageItem = m_TreeView.InsertItem(FilterItem, PreviousPageItem, Data, Data.GetPropertyPageTitle());
888                                                        PreviousPageItem = PageItem;
889                                                }
890                                                _ATLCATCHALL()
891                                                {
892                                                        _Z_EXCEPTION();
893                                                }
894                                        }
895                                        m_TreeView.Expand(FilterItem);
896                                }
897                                _ATLCATCHALL()
898                                {
899                                        _Z_EXCEPTION();
900                                }
901                                #pragma endregion
902                        }
903                        m_TreeView.Expand(FiltersItem);
904                        m_FiltersItem.m_hTreeItem = FiltersItem;
905                        m_FiltersItem.m_pTreeView = &m_TreeView;
906                        #pragma endregion
907                        CTreeItem ActionItem = m_TreeView.InsertItem(NULL, FiltersItem, CData(CData::TYPE_ACTION), _T("Action"));
908                        m_ActionItem.m_hTreeItem = ActionItem;
909                        m_ActionItem.m_pTreeView = &m_TreeView;
910                        CTreeItem EmailItem = m_TreeView.InsertItem(NULL, ActionItem, CData(CData::TYPE_EMAIL), _T("Email"));
911                        m_EmailItem.m_hTreeItem = EmailItem;
912                        m_EmailItem.m_pTreeView = &m_TreeView;
913                }
914                VOID HideCurrentSite()
915                {
916                        if(!m_pCurrentSite)
917                                return;
918                        if(m_pCurrentSite->m_pPropertyPage)
919                                __C(m_pCurrentSite->m_pPropertyPage->Show(SW_HIDE));
920                        m_pCurrentSite.Release();
921                }
922                VOID HandleStatusChange(CPropertyPageSite* pPropertyPageSite)
923                {
924                        _A(pPropertyPageSite);
925                        m_ApplyButton.EnableWindow(pPropertyPageSite->IsDirty());
926                }
927                VOID Apply()
928                {
929                        if(!m_pCurrentSite || !m_pCurrentSite->m_pPropertyPage)
930                                return;
931                        __C(m_pCurrentSite->m_pPropertyPage->Apply());
932                        HandleStatusChange(m_pCurrentSite);
933                }
934                INT_PTR DoModal(HWND hParentWindow = GetActiveWindow())
935                {
936                        return CDialogWithAccelerators::DoModal(hParentWindow);
937                }
938
939        // CDialogResize
940                VOID DlgResize_UpdateLayout(INT nWidth, INT nHeight)
941                {
942                        __super::DlgResize_UpdateLayout(nWidth, nHeight);
943                        const CRect Position = GetTextEditPosition();
944                        if(m_pCurrentSite && m_pCurrentSite->m_pPropertyPage)
945                                _V(m_pCurrentSite->m_pPropertyPage->Move(Position));
946                        _W(m_ActionDialog.SetWindowPos(NULL, Position, SWP_NOZORDER | SWP_NOACTIVATE));
947                        _W(m_EmailDialog.SetWindowPos(NULL, Position, SWP_NOZORDER | SWP_NOACTIVATE));
948                }
949
950        // Window Message Handler
951                LRESULT OnInitDialog(HWND, LPARAM)
952                {
953                        m_bActivating = TRUE;
954                        _ATLTRY
955                        {
956                                CWaitCursor WaitCursor;
957                                #pragma region Bitness Indication
958                                CString sCaption;
959                                _W(GetWindowText(sCaption));
960                                #if defined(_WIN64)
961                                        sCaption.Append(_T(" (64-bit)"));
962                                #else
963                                        if(SafeIsWow64Process())
964                                                sCaption.Append(_T(" (32-bit)"));
965                                #endif // defined(_WIN64)
966                                _W(SetWindowText(sCaption));
967                                #pragma endregion
968                                #pragma region System Menu
969                                CMenuHandle Menu = GetSystemMenu(FALSE);
970                                _W(Menu.AppendMenu(MF_SEPARATOR));
971                                _W(Menu.AppendMenu(MF_STRING, ID_APP_ABOUT, _T("&About...")));
972                                #pragma endregion
973                                #pragma region Icon
974                                SetIcon(AtlLoadIconImage(IDI_MODULE, LR_COLOR, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON)), TRUE);
975                                SetIcon(AtlLoadIconImage(IDI_MODULE, LR_COLOR, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON)), FALSE);
976                                #pragma endregion
977                                m_TreeView.Initialize(GetDlgItem(IDC_FILTERGRAPHHELPER_PROPERTYFRAME_TREE));
978                                m_TextEdit = GetDlgItem(IDC_FILTERGRAPHHELPER_PROPERTYFRAME_TEXT);
979                                CRect TextPosition;
980                                _W(m_TextEdit.GetWindowRect(TextPosition));
981                                _W(ScreenToClient(TextPosition));
982                                m_TextPosition = TextPosition;
983                                CLogFont TextFont;
984                                CFontHandle(AtlGetDefaultGuiFont()).GetLogFont(TextFont);
985                                _tcsncpy_s(TextFont.lfFaceName, _T("Courier New"), _TRUNCATE);
986                                TextFont.SetHeight(8);
987                                m_TextFont = TextFont.CreateFontIndirect();
988                                m_TextEdit.SetFont(m_TextFont);
989                                m_OkButton = GetDlgItem(IDOK);
990                                m_CancelButton = GetDlgItem(IDCANCEL);
991                                m_ApplyButton = GetDlgItem(IDC_FILTERGRAPHHELPER_PROPERTYFRAME_APPLY);
992                                __E(m_ActionDialog.Create(m_hWnd, (LPARAM) this));
993                                __E(m_EmailDialog.Create(m_hWnd, (LPARAM) this));
994                                DlgResize_Init(TRUE);
995                                UpdateTree();
996                                m_FiltersItem.Select();
997                                m_FiltersItem.EnsureVisible();
998                                CRect Position;
999                                _W(GetWindowRect(Position));
1000                                Position.right += Position.Width() / 2;
1001                                Position.bottom += Position.Width() / 4;
1002                                _W(SetWindowPos(NULL, Position, SWP_NOMOVE | SWP_NOZORDER));
1003                                _W(CenterWindow());
1004                                m_bActivating = FALSE;
1005                        }
1006                        _ATLCATCH(Exception)
1007                        {
1008                                for(CWindow Window = GetWindow(GW_CHILD); Window; Window = Window.GetWindow(GW_HWNDNEXT))
1009                                        Window.EnableWindow(FALSE);
1010                                AtlExceptionMessageBox(m_hWnd, Exception);
1011                        }
1012                        return TRUE;
1013                }
1014                LRESULT OnDestroy()
1015                {
1016                        #pragma region Deactivate and Terminate Sites
1017                        for(POSITION Position = m_TreeView.GetDataList().GetHeadPosition(); Position; m_TreeView.GetDataList().GetNext(Position))
1018                        {
1019                                CData& Data = m_TreeView.GetDataList().GetAt(Position);
1020                                if(!Data.m_pSite)
1021                                        continue;
1022                                if(Data.m_bSiteActivated)
1023                                {
1024                                        const HRESULT nDeactivateResult = Data.m_pPropertyPage->Deactivate();
1025                                        _Z35_DSHRESULT(nDeactivateResult);
1026                                        Data.m_bSiteActivated = FALSE;
1027                                }
1028                                Data.m_pSite->Terminate();
1029                        }
1030                        #pragma endregion
1031                        return 0;
1032                }
1033                LRESULT OnTreeViewGetInfoTip(NMTVGETINFOTIP* pHeader)
1034                {
1035                        _A(pHeader);
1036                        if(!pHeader->hItem) 
1037                                return 0;
1038                        CData& Data = m_TreeView.GetItemData(pHeader->hItem);
1039                        CString sInfoTip;
1040                        if(Data.m_pBaseFilter)
1041                        {
1042                                if(!Data.m_pPropertyPage)
1043                                {
1044                                        sInfoTip.AppendFormat(_T("Name: %ls") _T("\r\n"), _FilterGraphHelper::GetFilterName(Data.m_pBaseFilter));
1045                                        if(Data.m_BaseFilterClassIdentifier != CLSID_NULL)
1046                                                sInfoTip.AppendFormat(_T("Class Identifier: %ls") _T("\r\n"), _PersistHelper::StringFromIdentifier(Data.m_BaseFilterClassIdentifier));
1047                                        if(!Data.m_sBaseFilterClassDescription.IsEmpty())
1048                                                sInfoTip.AppendFormat(_T("Class Description: %s") _T("\r\n"), Data.m_sBaseFilterClassDescription);
1049                                        if(!Data.m_sBaseFilterModulePath.IsEmpty())
1050                                                sInfoTip.AppendFormat(_T("Module Path: %s") _T("\r\n"), Data.m_sBaseFilterModulePath);
1051                                } else
1052                                {
1053                                        // TODO: ...
1054                                }
1055                        }
1056                        sInfoTip.TrimRight(_T("\t\n\r "));
1057                        _tcsncpy_s(pHeader->pszText, pHeader->cchTextMax, sInfoTip, _TRUNCATE);
1058                        #pragma region Clipboard Copy
1059                        if(GetKeyState(VK_CONTROL) < 0 && GetKeyState(VK_SHIFT) < 0)
1060                                _ATLTRY
1061                                {
1062                                        SetClipboardText(m_hWnd, sInfoTip);
1063                                        MessageBeep(MB_OK);
1064                                }
1065                                _ATLCATCHALL()
1066                                {
1067                                        _Z_EXCEPTION();
1068                                        MessageBeep(MB_ICONERROR);
1069                                }
1070                        #pragma endregion
1071                        return 0;
1072                }
1073                LRESULT OnTreeViewSelChanged(NMTREEVIEW* pHeader)
1074                {
1075                        _A(pHeader);
1076                        CTreeItem TreeItem(pHeader->itemNew.hItem);
1077                        if(TreeItem)
1078                        {
1079                                CData& Data = m_TreeView.GetItemData(TreeItem);
1080                                if(Data.m_Type != CData::TYPE_ACTION)
1081                                        m_ActionDialog.ShowWindow(SW_HIDE);
1082                                if(Data.m_Type != CData::TYPE_EMAIL)
1083                                        m_EmailDialog.ShowWindow(SW_HIDE);
1084                                if(Data.m_pBaseFilter)
1085                                {
1086                                        if(Data.m_pPropertyPage)
1087                                        {
1088                                                m_TextEdit.ShowWindow(SW_HIDE);
1089                                                if(Data.m_pSite != m_pCurrentSite)
1090                                                        HideCurrentSite();
1091                                                if(!Data.m_bSiteActivated)
1092                                                {
1093                                                        __C(Data.m_pPropertyPage->Activate(m_hWnd, GetTextEditPosition(), TRUE));
1094                                                        Data.m_bSiteActivated = TRUE;
1095                                                } else
1096                                                        __C(Data.m_pPropertyPage->Move(GetTextEditPosition()));
1097                                                __C(Data.m_pPropertyPage->Show(SW_SHOWNORMAL));
1098                                                m_pCurrentSite = Data.m_pSite;
1099                                                HandleStatusChange(m_pCurrentSite);
1100                                        } else
1101                                        {
1102                                                CWaitCursor WaitCursor;
1103                                                HideCurrentSite();
1104                                                m_TextEdit.ShowWindow(SW_SHOW);
1105                                                CString sText;
1106                                                sText += AtlFormatString(_T("## ") _T("Filter %ls") _T("\r\n") _T("\r\n"), _FilterGraphHelper::GetFilterName(Data.m_pBaseFilter));
1107                                                sText += m_Owner.GetFilterText(Data.m_pBaseFilter);
1108                                                sText += _T("\r\n");
1109                                                #pragma region Connection
1110                                                _FilterGraphHelper::CPinArray InputPinArray, OutputPinArray;
1111                                                _FilterGraphHelper::GetFilterPins(Data.m_pBaseFilter, PINDIR_INPUT, InputPinArray);
1112                                                _FilterGraphHelper::GetFilterPins(Data.m_pBaseFilter, PINDIR_OUTPUT, OutputPinArray);
1113                                                if(!InputPinArray.IsEmpty() || !OutputPinArray.IsEmpty())
1114                                                {
1115                                                        sText += AtlFormatString(_T("## ") _T("Connections") _T("\r\n") _T("\r\n"));
1116                                                        if(!InputPinArray.IsEmpty())
1117                                                        {
1118                                                                sText += AtlFormatString(_T("### ") _T("Input") _T("\r\n") _T("\r\n"));
1119                                                                for(SIZE_T nPinIndex = 0; nPinIndex < InputPinArray.GetCount(); nPinIndex++)
1120                                                                {
1121                                                                        const CComPtr<IPin>& pInputPin = InputPinArray[nPinIndex];
1122                                                                        const CComPtr<IPin> pOutputPin = _FilterGraphHelper::GetPeerPin(pInputPin);
1123                                                                        if(!pOutputPin)
1124                                                                                continue;
1125                                                                        sText += AtlFormatString(_T(" * ") _T("%s") _T("\r\n"), m_Owner.GetConnectionText(pOutputPin, pInputPin));
1126                                                                }
1127                                                                sText += _T("\r\n");
1128                                                        }
1129                                                        if(!OutputPinArray.IsEmpty())
1130                                                        {
1131                                                                sText += AtlFormatString(_T("### ") _T("Output") _T("\r\n") _T("\r\n"));
1132                                                                for(SIZE_T nPinIndex = 0; nPinIndex < OutputPinArray.GetCount(); nPinIndex++)
1133                                                                {
1134                                                                        const CComPtr<IPin>& pOutputPin = OutputPinArray[nPinIndex];
1135                                                                        const CComPtr<IPin> pInputPin = _FilterGraphHelper::GetPeerPin(pOutputPin);
1136                                                                        if(!pInputPin)
1137                                                                                continue;
1138                                                                        sText += AtlFormatString(_T(" * ") _T("%s") _T("\r\n"), m_Owner.GetConnectionText(pOutputPin, pInputPin));
1139                                                                }
1140                                                                sText += _T("\r\n");
1141                                                        }
1142                                                }
1143                                                #pragma endregion
1144                                                #pragma region Media Type
1145                                                _FilterGraphHelper::CPinArray PinArray;
1146                                                if(_FilterGraphHelper::GetFilterPins(Data.m_pBaseFilter, PinArray))
1147                                                {
1148                                                        sText += AtlFormatString(_T("## ") _T("Media Types") _T("\r\n") _T("\r\n"));
1149                                                        for(SIZE_T nPinIndex = 0; nPinIndex < PinArray.GetCount(); nPinIndex++)
1150                                                        {
1151                                                                const CComPtr<IPin>& pPin = PinArray[nPinIndex];
1152                                                                CString sPinText = AtlFormatString(_T("%s"), FormatIdentifier(_FilterGraphHelper::GetPinFullName(pPin)));
1153                                                                const CComPtr<IPin> pPeerPin = _FilterGraphHelper::GetPeerPin(pPin);
1154                                                                if(pPeerPin)
1155                                                                        sPinText += AtlFormatString(_T(", %s"), FormatIdentifier(_FilterGraphHelper::GetPinFullName(pPeerPin)));
1156                                                                sText += AtlFormatString(_T("%d. ") _T("%s") _T("\r\n"), 1 + nPinIndex, sPinText);
1157                                                                _ATLTRY
1158                                                                {
1159                                                                        CMediaType pMediaType;
1160                                                                        if(pPeerPin)
1161                                                                                pMediaType = _FilterGraphHelper::GetPinMediaType(pPin);
1162                                                                        else
1163                                                                                pMediaType = _FilterGraphHelper::EnumerateFirstPinMediaType(pPin);
1164                                                                        if(!pMediaType)
1165                                                                                continue;
1166                                                                        sText += m_Owner.GetMediaTypeText(pMediaType);
1167                                                                }
1168                                                                _ATLCATCHALL()
1169                                                                {
1170                                                                        _Z_EXCEPTION();
1171                                                                }
1172                                                        }
1173                                                        sText += _T("\r\n");
1174                                                }
1175                                                #pragma endregion
1176                                                m_TextEdit.SetValue(sText);
1177                                                m_ApplyButton.EnableWindow(FALSE);
1178                                        }
1179                                } else
1180                                {
1181                                        CWaitCursor WaitCursor;
1182                                        HideCurrentSite();
1183                                        switch(Data.m_Type)
1184                                        {
1185                                        #pragma region TYPE_ACTION
1186                                        case CData::TYPE_ACTION:
1187                                                m_TextEdit.ShowWindow(SW_HIDE);
1188                                                _W(m_ActionDialog.SetWindowPos(NULL, GetTextEditPosition(), SWP_NOZORDER | SWP_SHOWWINDOW));
1189                                                break;
1190                                        #pragma endregion
1191                                        #pragma region TYPE_EMAIL
1192                                        case CData::TYPE_EMAIL:
1193                                                m_TextEdit.ShowWindow(SW_HIDE);
1194                                                _W(m_EmailDialog.SetWindowPos(NULL, GetTextEditPosition(), SWP_NOZORDER | SWP_SHOWWINDOW));
1195                                                break;
1196                                        #pragma endregion
1197                                        default:
1198                                                m_TextEdit.ShowWindow(SW_SHOW);
1199                                                m_TextEdit.SetValue(m_Owner.GetText());
1200                                                m_ActionDialog.ShowWindow(SW_HIDE);
1201                                                m_EmailDialog.ShowWindow(SW_HIDE);
1202                                        }
1203                                        m_ApplyButton.EnableWindow(FALSE);
1204                                }
1205                        } else
1206                        {
1207                                HideCurrentSite();
1208                                m_TextEdit.ShowWindow(SW_HIDE);
1209                                m_ActionDialog.ShowWindow(SW_HIDE);
1210                                m_EmailDialog.ShowWindow(SW_HIDE);
1211                                m_ApplyButton.EnableWindow(FALSE);
1212                        }
1213                        return 0;
1214                }
1215                LRESULT OnTreeViewItemExplanding(NMTREEVIEW* pHeader)
1216                {
1217                        if(pHeader->action == TVE_COLLAPSE)
1218                                return TRUE; // Prevent Collapsing
1219                        return 0;
1220                }
1221                LRESULT OnTreeViewDblClk(NMHDR*)
1222                {
1223                        CTreeItem TreeItem = m_TreeView.GetSelectedItem();
1224                        if(!TreeItem)
1225                                return 0;
1226                        CData& Data = m_TreeView.GetItemData(TreeItem);
1227                        if(!Data.m_pBaseFilter)
1228                                return 0;
1229                        COlePropertyFrameDialog Dialog(Data.m_pBaseFilter);
1230                        if(!Dialog.SetObjectPages())
1231                                return 0;
1232                        Dialog.DoModal(m_hWnd);
1233                        return 0;
1234                }
1235                LRESULT OnSysCommand(UINT nCommand, CPoint)
1236                {
1237                        switch(nCommand)
1238                        {
1239                        case ID_APP_ABOUT:
1240                                {
1241                                        CAboutDialog Dialog;
1242                                        Dialog.DoModal(m_hWnd);
1243                                }
1244                                break;
1245                        default:
1246                                SetMsgHandled(FALSE);
1247                        }
1248                        return 0;
1249                }
1250                LRESULT OnOk(UINT, INT nIdentifier, HWND)
1251                {
1252                        _ATLTRY
1253                        {
1254                                #pragma region Apply All
1255                                for(POSITION Position = m_TreeView.GetDataList().GetHeadPosition(); Position; m_TreeView.GetDataList().GetNext(Position))
1256                                {
1257                                        CData& Data = m_TreeView.GetDataList().GetAt(Position);
1258                                        if(!Data.m_pSite)
1259                                                continue;
1260                                        _A(Data.m_pPropertyPage);
1261                                        if(Data.m_bSiteActivated && Data.m_pSite->IsDirty())
1262                                                __C(Data.m_pPropertyPage->Apply());
1263                                }
1264                                #pragma endregion
1265                        }
1266                        _ATLCATCH(Exception)
1267                        {
1268                                _Z_ATLEXCEPTION(Exception);
1269                                AtlMessageBoxEx(m_hWnd, (LPCTSTR) Ds::FormatResult(Exception), IDS_ERROR, MB_ICONERROR | MB_OK);
1270                                return 0;
1271                        }
1272                        EndDialog(nIdentifier);
1273                        return 0;
1274                }
1275                LRESULT OnCancel(UINT, INT nIdentifier, HWND)
1276                {
1277                        EndDialog(nIdentifier);
1278                        return 0;
1279                }
1280                LRESULT OnApply(UINT, INT, HWND)
1281                {
1282                        _ATLTRY
1283                        {
1284                                Apply();
1285                        }
1286                        _ATLCATCH(Exception)
1287                        {
1288                                _Z_ATLEXCEPTION(Exception);
1289                                AtlMessageBoxEx(m_hWnd, (LPCTSTR) Ds::FormatResult(Exception), IDS_ERROR, MB_ICONERROR | MB_OK);
1290                        }
1291                        return 0;
1292                }
1293                LRESULT OnActionCommand(UINT, INT nIdentifier, HWND)
1294                {
1295                        return m_ActionDialog.SendMessage(WM_COMMAND, nIdentifier);
1296                }
1297        };
1298
1299private:
1300        mutable CRoCriticalSection m_DataCriticalSection;
1301        CComPtr<IFilterGraph> m_pFilterGraph;
1302
1303public:
1304// CFilterGraphHelper
1305        static HRESULT WINAPI UpdateRegistry(BOOL bRegister)
1306        {
1307                _Z2(atlTraceRegistrar, 2, _T("bRegister %d\n"), bRegister);
1308                _ATLTRY
1309                {
1310                        UpdateRegistryFromResource<CFilterGraphHelper>(bRegister);
1311                }
1312                _ATLCATCH(Exception)
1313                {
1314                        _C(Exception);
1315                }
1316                return S_OK;
1317        }
1318        CFilterGraphHelper()
1319        {
1320                _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
1321        }
1322        ~CFilterGraphHelper()
1323        {
1324                _Z4(atlTraceRefcount, 4, _T("this 0x%p\n"), this);
1325        }
1326        static CString FormatIdentifier(LPCSTR pszValue)
1327        {
1328                CString sText;
1329                if(pszValue && *pszValue)
1330                {
1331                        sText = _T("``");
1332                        sText.Insert(1, CString(pszValue));
1333                }
1334                return sText;
1335        }
1336        static CString FormatIdentifier(LPCWSTR pszValue)
1337        {
1338                CString sText;
1339                if(pszValue && *pszValue)
1340                {
1341                        sText = _T("``");
1342                        sText.Insert(1, CString(pszValue));
1343                }
1344                return sText;
1345        }
1346        static CString FormatIdentifier(LONG nValue)
1347        {
1348                CString sText;
1349                sText = _T("``");
1350                sText.Insert(1, _StringHelper::FormatNumber(nValue));
1351                return sText;
1352        }
1353        static CString FormatIdentifier(ULONG nValue)
1354        {
1355                return FormatIdentifier((LONG) nValue);
1356        }
1357        static CString FormatIdentifier(BOOL nValue)
1358        {
1359                return FormatIdentifier((LONG) nValue);
1360        }
1361        static CString FormatIdentifier(LONGLONG nValue)
1362        {
1363                CString sText;
1364                sText = _T("``");
1365                sText.Insert(1, _StringHelper::FormatNumber(nValue));
1366                return sText;
1367        }
1368        static CString FormatIdentifier(LONG nValue, LPCTSTR pszFormat)
1369        {
1370                CString sText;
1371                sText = _T("``");
1372                sText.Insert(1, AtlFormatString(pszFormat, nValue));
1373                return sText;
1374        }
1375        static CString FormatIdentifier(const VOID* pvValue, LPCTSTR pszFormat = _T("0x%p"))
1376        {
1377                CString sText;
1378                sText = _T("``");
1379                sText.Insert(1, AtlFormatString(pszFormat, pvValue));
1380                return sText;
1381        }
1382        #define I FormatIdentifier
1383        static CString FormatPhysicalConnectorType(PhysicalConnectorType Value)
1384        {
1385                struct 
1386                {
1387                        PhysicalConnectorType Value;
1388                        LPCSTR pszName;
1389                } g_pMap[] = 
1390                {
1391                        #define A(x) { x, #x },
1392                        A(PhysConn_Video_Tuner)
1393                        A(PhysConn_Video_Composite)
1394                        A(PhysConn_Video_SVideo)
1395                        A(PhysConn_Video_RGB)
1396                        A(PhysConn_Video_YRYBY)
1397                        A(PhysConn_Video_SerialDigital)
1398                        A(PhysConn_Video_ParallelDigital)
1399                        A(PhysConn_Video_SCSI)
1400                        A(PhysConn_Video_AUX)
1401                        A(PhysConn_Video_1394)
1402                        A(PhysConn_Video_USB)
1403                        A(PhysConn_Video_VideoDecoder)
1404                        A(PhysConn_Video_VideoEncoder)
1405                        A(PhysConn_Video_SCART)
1406                        A(PhysConn_Video_Black)
1407                        A(PhysConn_Audio_Tuner)
1408                        A(PhysConn_Audio_Line)
1409                        A(PhysConn_Audio_Mic)
1410                        A(PhysConn_Audio_AESDigital)
1411                        A(PhysConn_Audio_SPDIFDigital)
1412                        A(PhysConn_Audio_SCSI)
1413                        A(PhysConn_Audio_AUX)
1414                        A(PhysConn_Audio_1394)
1415                        A(PhysConn_Audio_USB)
1416                        A(PhysConn_Audio_AudioDecoder)
1417                        #undef A
1418                };
1419                for(SIZE_T nIndex = 0; nIndex < DIM(g_pMap); nIndex++)
1420                        if(g_pMap[nIndex].Value == Value)
1421                                return CString(g_pMap[nIndex].pszName);
1422                return AtlFormatString(_T("0x%04X"), Value);
1423        }
1424        static CString FormatPins(_FilterGraphHelper::CPinArray& PinArray)
1425        {
1426                CRoArrayT<CString> Array;
1427                for(SIZE_T nIndex  = 0; nIndex < PinArray.GetCount(); nIndex++)
1428                {
1429                        const CComPtr<IPin>& pPin = PinArray[nIndex];
1430                        CString sText = I(_FilterGraphHelper::GetPinName(pPin));
1431                        const CComPtr<IPin> pPeerPin = _FilterGraphHelper::GetPeerPin(pPin);
1432                        if(pPeerPin)
1433                                sText += AtlFormatString(_T(" (%s)"), I(_FilterGraphHelper::GetPinFullName(pPeerPin)));
1434                        Array.Add(sText);
1435                }
1436                return _StringHelper::Join(Array, _T(", "));
1437        }
1438        static CString GetFilterText(IBaseFilter* pBaseFilter, IReferenceClock* pFilterGraphReferenceClock = NULL)
1439        {
1440                CString sText;
1441                const CStringW sClassIdentifierString = _FilterGraphHelper::GetFilterClassIdentifierString(pBaseFilter);
1442                if(!sClassIdentifierString.IsEmpty())
1443                        sText += AtlFormatString(_T(" * ") _T("Class: %s %s") _T("\r\n"), I(sClassIdentifierString), I(_FilterGraphHelper::GetFilterClassDescription(pBaseFilter)));
1444                _FilterGraphHelper::CPinArray InputPinArray;
1445                if(_FilterGraphHelper::GetFilterPins(pBaseFilter, PINDIR_INPUT, InputPinArray))
1446                        sText += AtlFormatString(_T(" * ") _T("Input Pins: %s") _T("\r\n"), FormatPins(InputPinArray));
1447                _FilterGraphHelper::CPinArray OutputPinArray;
1448                if(_FilterGraphHelper::GetFilterPins(pBaseFilter, PINDIR_OUTPUT, OutputPinArray))
1449                        sText += AtlFormatString(_T(" * ") _T("Output Pins: %s") _T("\r\n"), FormatPins(OutputPinArray));
1450                #pragma region IReferenceClock
1451                const CComQIPtr<IReferenceClock> pReferenceClock = pBaseFilter;
1452                if(pReferenceClock)
1453                {
1454                        CRoArrayT<CString> Array;
1455                        Array.Add(I(_T("Available")));
1456                        if(pReferenceClock == pFilterGraphReferenceClock)
1457                                Array.Add(I(_T("Selected")));
1458                        sText += AtlFormatString(_T(" * ") _T("Reference Clock: %s") _T("\r\n"), _StringHelper::Join(Array, _T(", ")));
1459                }
1460                #pragma endregion
1461                #pragma region IFileSourceFilter
1462                const CComQIPtr<IFileSourceFilter> pFileSourceFilter = pBaseFilter;
1463                if(pFileSourceFilter)
1464                        _ATLTRY
1465                        {
1466                                CComHeapPtr<OLECHAR> pszFileName;
1467                                CMediaType pMediaType;
1468                                pMediaType.Allocate(MEDIATYPE_NULL, MEDIASUBTYPE_NULL);
1469                                const HRESULT nGetCurFileResult = pFileSourceFilter->GetCurFile(&pszFileName, pMediaType);
1470                                _Z45_DSHRESULT(nGetCurFileResult);
1471                                if(SUCCEEDED(nGetCurFileResult))
1472                                        sText += AtlFormatString(_T(" * ") _T("File Source: %s") _T("\r\n"), I(pszFileName));
1473                        }
1474                        _ATLCATCHALL()
1475                        {
1476                                _Z_EXCEPTION();
1477                        }
1478                #pragma endregion
1479                #pragma region IFileSinkFilter
1480                const CComQIPtr<IFileSinkFilter> pFileSinkFilter = pBaseFilter;
1481                if(pFileSinkFilter)
1482                        _ATLTRY
1483                        {
1484                                CComHeapPtr<OLECHAR> pszFileName;
1485                                CMediaType pMediaType;
1486                                pMediaType.Allocate(MEDIATYPE_NULL, MEDIASUBTYPE_NULL);
1487                                const HRESULT nGetCurFileResult = pFileSinkFilter->GetCurFile(&pszFileName, pMediaType);
1488                                _Z45_DSHRESULT(nGetCurFileResult);
1489                                if(SUCCEEDED(nGetCurFileResult))
1490                                        sText += AtlFormatString(_T(" * ") _T("File Sink: %s") _T("\r\n"), I(pszFileName));
1491                        }
1492                        _ATLCATCHALL()
1493                        {
1494                                _Z_EXCEPTION();
1495                        }
1496                #pragma endregion
1497                #pragma region IAMCrossbar
1498                const CComQIPtr<IAMCrossbar> pAmCrossbar = pBaseFilter;
1499                if(pAmCrossbar)
1500                        _ATLTRY
1501                        {
1502                                sText += AtlFormatString(_T(" * ") _T("Crossbar:") _T("\r\n"));
1503                                LONG nOutputPinCount = 0, nInputPinCount = 0;
1504                                __C(pAmCrossbar->get_PinCounts(&nOutputPinCount, &nInputPinCount));
1505                                sText += AtlFormatString(_T("  * ") _T("Pins: %s Input, %s Output") _T("\r\n"), I(nInputPinCount), I(nOutputPinCount));
1506                                #pragma region Input
1507                                for(LONG nInputPinIndex = 0; nInputPinIndex < nInputPinCount; nInputPinIndex++)
1508                                        _ATLTRY
1509                                        {
1510                                                CRoArrayT<CString> Array;
1511                                                LONG nRelatedPinIndex = -1;
1512                                                LONG nPhysicalType = 0; // PhysicalConnectorType
1513                                                __C(pAmCrossbar->get_CrossbarPinInfo(TRUE, nInputPinIndex, &nRelatedPinIndex, &nPhysicalType));
1514                                                if(nRelatedPinIndex >= 0)
1515                                                        Array.Add(AtlFormatString(_T("Related %s"), I(nRelatedPinIndex)));
1516                                                Array.Add(AtlFormatString(_T("Physical Type %s"), I(FormatPhysicalConnectorType((PhysicalConnectorType) nPhysicalType))));
1517                                                sText += AtlFormatString(_T("  * ") _T("Input Pin %s: %s") _T("\r\n"), I(nInputPinIndex), _StringHelper::Join(Array, _T("; ")));
1518                                        }
1519                                        _ATLCATCHALL()
1520                                        {
1521                                                _Z_EXCEPTION();
1522                                        }
1523                                #pragma endregion
1524                                #pragma region Output
1525                                for(LONG nOutputPinIndex = 0; nOutputPinIndex < nOutputPinCount; nOutputPinIndex++)
1526                                        _ATLTRY
1527                                        {
1528                                                CRoArrayT<CString> Array;
1529                                                LONG nRelatedPinIndex = -1;
1530                                                LONG nPhysicalType = 0; // PhysicalConnectorType
1531                                                __C(pAmCrossbar->get_CrossbarPinInfo(FALSE, nOutputPinIndex, &nRelatedPinIndex, &nPhysicalType));
1532                                                if(nRelatedPinIndex >= 0)
1533                                                        Array.Add(AtlFormatString(_T("Related %s"), I(nRelatedPinIndex)));
1534                                                if(nPhysicalType > 0)
1535                                                        Array.Add(AtlFormatString(_T("Physical Type %s"), I(FormatPhysicalConnectorType((PhysicalConnectorType) nPhysicalType))));
1536                                                LONG nRoutedInputPinIndex = -1;
1537                                                const HRESULT nGetIsRoutedToResult = pAmCrossbar->get_IsRoutedTo(nOutputPinIndex, &nRoutedInputPinIndex);
1538                                                _A(nGetIsRoutedToResult == S_OK || nRoutedInputPinIndex == -1);
1539                                                if(nRoutedInputPinIndex >= 0)
1540                                                        Array.Add(AtlFormatString(_T("Routed to Input Pin %s"), I(nRoutedInputPinIndex)));
1541                                                CRoArrayT<CString> PinArray;
1542                                                for(LONG nInputPinIndex = 0; nInputPinIndex < nInputPinCount; nInputPinIndex++)
1543                                                {
1544                                                        const HRESULT nCanRouteResult = pAmCrossbar->CanRoute(nOutputPinIndex, nInputPinIndex);
1545                                                        if(nCanRouteResult == S_OK)
1546                                                                PinArray.Add(I(nInputPinIndex));
1547                                                }
1548                                                if(!PinArray.IsEmpty())
1549                                                        Array.Add(AtlFormatString(_T("Routeable to Input Pins %s"), _StringHelper::Join(PinArray, _T(", "))));
1550                                                sText += AtlFormatString(_T("  * ") _T("Output Pin %s: %s") _T("\r\n"), I(nOutputPinIndex), _StringHelper::Join(Array, _T("; ")));
1551                                        }
1552                                        _ATLCATCHALL()
1553                                        {
1554                                                _Z_EXCEPTION();
1555                                        }
1556                                #pragma endregion
1557                        }
1558                        _ATLCATCHALL()
1559                        {
1560                                _Z_EXCEPTION();
1561                        }
1562                #pragma endregion
1563                return sText;
1564        }
1565        static CString GetConnectionText(IPin* pOutputPin, IPin* pInputPin)
1566        {
1567                _A(pOutputPin && pInputPin);
1568                CString sText = AtlFormatString(_T("%s - %s"), I(_FilterGraphHelper::GetPinFullName(pOutputPin)), I(_FilterGraphHelper::GetPinFullName(pInputPin)));
1569                _ATLTRY
1570                {
1571                        const CMediaType pMediaType = _FilterGraphHelper::GetPinMediaType(pOutputPin);
1572                        if(pMediaType)
1573                        {
1574                                CStringW sMajorType = _FilterGraphHelper::FormatMajorType(pMediaType->majortype);
1575                                CStringW sSubtype;
1576                                if(pMediaType->subtype != MEDIASUBTYPE_NULL)
1577                                        sSubtype = _FilterGraphHelper::FormatSubtype(pMediaType->majortype, pMediaType->subtype);
1578                                CRoArrayT<CString> Array;
1579                                Array.Add(I(sMajorType));
1580                                Array.Add(I(sSubtype));
1581                                #pragma region MEDIATYPE_Video
1582                                if(pMediaType->majortype == MEDIATYPE_Video)
1583                                {
1584                                        const CVideoInfoHeader2 VideoInfoHeader2 = pMediaType.GetCompatibleVideoInfoHeader2();
1585                                        const CSize Extent = VideoInfoHeader2.GetExtent();
1586                                        if(Extent.cx || Extent.cy)
1587                                                Array.Add(AtlFormatString(_T("%s x %s"), I(Extent.cx), I(Extent.cy)));
1588                                } else
1589                                #pragma endregion
1590                                #pragma region MEDIATYPE_Audio
1591                                if(pMediaType->majortype == MEDIATYPE_Audio)
1592                                {
1593                                        const CWaveFormatEx* pWaveFormatEx = pMediaType.GetWaveFormatEx();
1594                                        if(pWaveFormatEx)
1595                                        {
1596                                                if(pWaveFormatEx->nSamplesPerSec)
1597                                                        Array.Add(AtlFormatString(_T("%s Hz"), I(pWaveFormatEx->nSamplesPerSec)));
1598                                                if(pWaveFormatEx->nChannels)
1599                                                        Array.Add(AtlFormatString(_T("%s channels"), I(pWaveFormatEx->nChannels)));
1600                                                if(pWaveFormatEx->wBitsPerSample)
1601                                                        Array.Add(AtlFormatString(_T("%s bits"), I(pWaveFormatEx->wBitsPerSample)));
1602                                        }
1603                                }
1604                                #pragma endregion
1605                                sText += AtlFormatString(_T(" (%s)"), _StringHelper::Join(Array, _T(", ")));
1606                        }
1607                }
1608                _ATLCATCHALL()
1609                {
1610                        _Z_EXCEPTION();
1611                }
1612                return sText;
1613        }
1614        static CString GetMediaTypeText(const CMediaType& pMediaType)
1615        {
1616                CString sText;
1617                #pragma region AM_MEDIA_TYPE
1618                #define J(x) I(pMediaType->x)
1619                #define K1(x) sText += AtlFormatString(_T(" * `") _T(#x) _T("`: %s") _T("\r\n"), J(x))
1620                sText += AtlFormatString(_T(" * ") _T("Data: %s") _T("\r\n"), I(AtlFormatData((const BYTE*) (const AM_MEDIA_TYPE*) pMediaType, sizeof *pMediaType).TrimRight()));
1621                sText += AtlFormatString(_T(" * ") _T("`majortype`: %s") _T("\r\n"), I(_FilterGraphHelper::FormatMajorType(pMediaType->majortype)));
1622                if(pMediaType->subtype != MEDIASUBTYPE_NULL)
1623                        sText += AtlFormatString(_T(" * ") _T("`subtype`: %s") _T("\r\n"), I(_FilterGraphHelper::FormatSubtype(pMediaType->majortype, pMediaType->subtype)));
1624                K1(bFixedSizeSamples);
1625                K1(bTemporalCompression);
1626                K1(lSampleSize);
1627                if(pMediaType->formattype != GUID_NULL)
1628                        sText += AtlFormatString(_T(" * ") _T("`formattype`: %s") _T("\r\n"), I(_FilterGraphHelper::FormatFormatType(pMediaType->formattype)));
1629                if(pMediaType->pUnk)
1630                        sText += AtlFormatString(_T(" * ") _T("`pUnk`: %s") _T("\r\n"), I(AtlFormatString(_T("0x%p"), pMediaType->pUnk)));
1631                if(pMediaType->cbFormat)
1632                {
1633                        K1(cbFormat);
1634                        if(pMediaType->pbFormat)
1635                                sText += AtlFormatString(_T(" * ") _T("Format Data, `pbFormat`: %s") _T("\r\n"), I(AtlFormatData(pMediaType->pbFormat, pMediaType->cbFormat).TrimRight()));
1636                }
1637                #undef J
1638                #undef K1
1639                #pragma endregion
1640                const BYTE* pnExtraData = NULL;
1641                SIZE_T nExtraDataSize = 0;
1642                #pragma region FORMAT_VideoInfo
1643                if(pMediaType->formattype == FORMAT_VideoInfo)
1644                {
1645                        sText += AtlFormatString(_T(" * ") _T("As `VIDEOINFOHEADER`:") _T("\r\n"));
1646                        const VIDEOINFOHEADER* pVideoInfoHeader = (const VIDEOINFOHEADER*) pMediaType->pbFormat;
1647                        #define J(x) I(pVideoInfoHeader->x)
1648                        #define K1(x) sText += AtlFormatString(_T("  * `") _T(#x) _T("`: %s") _T("\r\n"), J(x))
1649                        sText += AtlFormatString(_T("  * ") _T("`rcSource`: (%s, %s) - (%s, %s)") _T("\r\n"), J(rcSource.left), J(rcSource.top), J(rcSource.right), J(rcSource.bottom));
1650                        sText += AtlFormatString(_T("  * ") _T("`rcTarget`: (%s, %s) - (%s, %s)") _T("\r\n"), J(rcTarget.left), J(rcTarget.top), J(rcTarget.right), J(rcTarget.bottom));
1651                        K1(dwBitRate);
1652                        K1(dwBitErrorRate);
1653                        sText += AtlFormatString(_T("  * ") _T("`AvgTimePerFrame`: %s units") _T("\r\n"), I(_FilterGraphHelper::FormatReferenceTime(pVideoInfoHeader->AvgTimePerFrame)));
1654                        K1(bmiHeader.biSize);
1655                        K1(bmiHeader.biWidth);
1656                        K1(bmiHeader.biHeight);
1657                        K1(bmiHeader.biPlanes);
1658                        K1(bmiHeader.biBitCount);
1659                        sText += AtlFormatString(_T("  * ") _T("`bmiHeader.biCompression`: %s") _T("\r\n"), I(_FilterGraphHelper::GetFourccCodeString(pVideoInfoHeader->bmiHeader.biCompression)));
1660                        K1(bmiHeader.biSizeImage);
1661                        K1(bmiHeader.biXPelsPerMeter);
1662                        K1(bmiHeader.biYPelsPerMeter);
1663                        K1(bmiHeader.biClrUsed);
1664                        K1(bmiHeader.biClrImportant);
1665                        #undef J
1666                        #undef K1
1667                        nExtraDataSize = pMediaType->cbFormat - sizeof *pVideoInfoHeader;
1668                } else
1669                #pragma endregion
1670                #pragma region FORMAT_VideoInfo2
1671                if(pMediaType->formattype == FORMAT_VideoInfo2)
1672                {
1673                        sText += AtlFormatString(_T(" * ") _T("As `VIDEOINFOHEADER2`:") _T("\r\n"));
1674                        const VIDEOINFOHEADER2* pVideoInfoHeader2 = (const VIDEOINFOHEADER2*) pMediaType->pbFormat;
1675                        #define J(x) I(pVideoInfoHeader2->x)
1676                        #define K1(x) sText += AtlFormatString(_T("  * `") _T(#x) _T("`: %s") _T("\r\n"), J(x))
1677                        #define K2(x, y) sText += AtlFormatString(_T("  * `") _T(#x) _T("`: %s") _T("\r\n"), I(pVideoInfoHeader2->x, y))
1678                        sText += AtlFormatString(_T("  * ") _T("rcSource: (%s, %s) - (%s, %s)") _T("\r\n"), J(rcSource.left), J(rcSource.top), J(rcSource.right), J(rcSource.bottom));
1679                        sText += AtlFormatString(_T("  * ") _T("rcTarget: (%s, %s) - (%s, %s)") _T("\r\n"), J(rcTarget.left), J(rcTarget.top), J(rcTarget.right), J(rcTarget.bottom));
1680                        K1(dwBitRate);
1681                        K1(dwBitErrorRate);
1682                        sText += AtlFormatString(_T("  * ") _T("`AvgTimePerFrame`: %s units") _T("\r\n"), I(_FilterGraphHelper::FormatReferenceTime(pVideoInfoHeader2->AvgTimePerFrame)));
1683                        K2(dwInterlaceFlags, _T("0x%X"));
1684                        K2(dwCopyProtectFlags, _T("0x%X"));
1685                        K1(dwPictAspectRatioX);
1686                        K1(dwPictAspectRatioY);
1687                        K2(dwControlFlags, _T("0x%X"));
1688                        K1(bmiHeader.biSize);
1689                        K1(bmiHeader.biWidth);
1690                        K1(bmiHeader.biHeight);
1691                        K1(bmiHeader.biPlanes);
1692                        K1(bmiHeader.biBitCount);
1693                        sText += AtlFormatString(_T("  * ") _T("`bmiHeader.biCompression`: %s") _T("\r\n"), I(_FilterGraphHelper::GetFourccCodeString(pVideoInfoHeader2->bmiHeader.biCompression)));
1694                        K1(bmiHeader.biSizeImage);
1695                        K1(bmiHeader.biXPelsPerMeter);
1696                        K1(bmiHeader.biYPelsPerMeter);
1697                        K1(bmiHeader.biClrUsed);
1698                        K1(bmiHeader.biClrImportant);
1699                        #undef J
1700                        #undef K1
1701                        #undef K2
1702                        nExtraDataSize = pMediaType->cbFormat - sizeof *pVideoInfoHeader2;
1703                        if(nExtraDataSize)
1704                        {
1705                                sText += AtlFormatString(_T("  * ") _T("Extra Data: (%d bytes)") _T("\r\n"), nExtraDataSize);
1706                                nExtraDataSize = 0;
1707                        }
1708                } else
1709                #pragma endregion
1710                #pragma region FORMAT_MPEG2Video
1711                if(pMediaType->formattype == FORMAT_MPEG2Video)
1712                {
1713                        sText += AtlFormatString(_T(" * ") _T("As `MPEG2VIDEOINFO`:") _T("\r\n"));
1714                        const MPEG2VIDEOINFO* pMpeg2VideoInfo = (const MPEG2VIDEOINFO*) pMediaType->pbFormat;
1715                        #define J(x) I(pMpeg2VideoInfo->x)
1716                        #define K1(x) sText += AtlFormatString(_T("  * `") _T(#x) _T("`: %s") _T("\r\n"), J(x))
1717                        #define K2(x, y) sText += AtlFormatString(_T("  * `") _T(#x) _T("`: %s") _T("\r\n"), I(pMpeg2VideoInfo->x, y))
1718                        sText += AtlFormatString(_T("  * ") _T("`hdr.rcSource`: (%s, %s) - (%s, %s)") _T("\r\n"), J(hdr.rcSource.left), J(hdr.rcSource.top), J(hdr.rcSource.right), J(hdr.rcSource.bottom));
1719                        sText += AtlFormatString(_T("  * ") _T("`hdr.rcTarget`: (%s, %s) - (%s, %s)") _T("\r\n"), J(hdr.rcTarget.left), J(hdr.rcTarget.top), J(hdr.rcTarget.right), J(hdr.rcTarget.bottom));
1720                        K1(hdr.dwBitRate);
1721                        K1(hdr.dwBitErrorRate);
1722                        sText += AtlFormatString(_T("  * ") _T("`hdr.AvgTimePerFrame`: %s") _T("\r\n"), I(_FilterGraphHelper::FormatReferenceTime(pMpeg2VideoInfo->hdr.AvgTimePerFrame)));
1723                        K2(hdr.dwInterlaceFlags, _T("0x%X"));
1724                        K2(hdr.dwCopyProtectFlags, _T("0x%X"));
1725                        K1(hdr.dwPictAspectRatioX);
1726                        K1(hdr.dwPictAspectRatioY);
1727                        K2(hdr.dwControlFlags, _T("0x%X"));
1728                        K1(hdr.bmiHeader.biSize);
1729                        K1(hdr.bmiHeader.biWidth);
1730                        K1(hdr.bmiHeader.biHeight);
1731                        K1(hdr.bmiHeader.biPlanes);
1732                        K1(hdr.bmiHeader.biBitCount);
1733                        sText += AtlFormatString(_T("  * ") _T("`hdr.bmiHeader.biCompression`: %s") _T("\r\n"), I(_FilterGraphHelper::GetFourccCodeString(pMpeg2VideoInfo->hdr.bmiHeader.biCompression)));
1734                        K1(hdr.bmiHeader.biSizeImage);
1735                        K1(hdr.bmiHeader.biXPelsPerMeter);
1736                        K1(hdr.bmiHeader.biYPelsPerMeter);
1737                        K1(hdr.bmiHeader.biClrUsed);
1738                        K1(hdr.bmiHeader.biClrImportant);
1739                        K2(dwStartTimeCode, _T("0x%08X"));
1740                        K1(cbSequenceHeader);
1741                        K1(dwProfile);
1742                        K1(dwLevel);
1743                        K2(dwFlags, _T("0x%08X"));
1744                        #undef J
1745                        #undef K1
1746                        #undef K2
1747                        #undef J
1748                        nExtraDataSize = pMediaType->cbFormat - (sizeof *pMpeg2VideoInfo - sizeof pMpeg2VideoInfo->dwSequenceHeader);
1749                } else
1750                #pragma endregion
1751                #pragma region FORMAT_WaveFormatEx
1752                if(pMediaType->formattype == FORMAT_WaveFormatEx)
1753                {
1754                        const WAVEFORMATEX* pWaveFormatEx = (const WAVEFORMATEX*) pMediaType->pbFormat;
1755                        if(pWaveFormatEx->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
1756                        {
1757                                const WAVEFORMATEXTENSIBLE* pWaveFormatExtensible = (const WAVEFORMATEXTENSIBLE*) pMediaType->pbFormat;
1758                                #define J(x) I(pWaveFormatExtensible->x)
1759                                #define K1(x) sText += AtlFormatString(_T("  * `") _T(#x) _T("`: %s") _T("\r\n"), J(x))
1760                                #define K2(x, y) sText += AtlFormatString(_T("  * `") _T(#x) _T("`: %s") _T("\r\n"), I(pWaveFormatExtensible->x, y))
1761                                sText += AtlFormatString(_T(" * ") _T("As `WAVEFORMATEXTENSIBLE`:") _T("\r\n"));
1762                                K2(Format.wFormatTag, _T("0x%02X"));
1763                                K1(Format.nChannels);
1764                                K1(Format.nSamplesPerSec);
1765                                K1(Format.nAvgBytesPerSec);
1766                                K1(Format.nBlockAlign);
1767                                K1(Format.wBitsPerSample);
1768                                K1(Format.cbSize);
1769                                K1(Samples.wValidBitsPerSample);
1770                                K2(dwChannelMask, _T("0x%02X"));
1771                                sText += AtlFormatString(_T("  * ") _T("`SubFormat`: %s") _T("\r\n"), I(_PersistHelper::StringFromIdentifier(pWaveFormatExtensible->SubFormat)));
1772                                #undef J
1773                                #undef K1
1774                                #undef K2
1775                                nExtraDataSize = pWaveFormatEx->cbSize - (sizeof *pWaveFormatExtensible - sizeof *pWaveFormatEx);
1776                        } else
1777                        {
1778                                #define J(x) I(pWaveFormatEx->x)
1779                                #define K1(x) sText += AtlFormatString(_T("  * `") _T(#x) _T("`: %s") _T("\r\n"), J(x))
1780                                #define K2(x, y) sText += AtlFormatString(_T("  * `") _T(#x) _T("`: %s") _T("\r\n"), I(pWaveFormatEx->x, y))
1781                                K2(wFormatTag, _T("0x%02X"));
1782                                K1(nChannels);
1783                                K1(nSamplesPerSec);
1784                                K1(nAvgBytesPerSec);
1785                                K1(nBlockAlign);
1786                                K1(wBitsPerSample);
1787                                K1(cbSize);
1788                                #undef J
1789                                #undef K1
1790                                #undef K2
1791                                nExtraDataSize = pWaveFormatEx->cbSize;
1792                        }
1793                }
1794                #pragma endregion
1795                #pragma region Extra Data
1796                if(nExtraDataSize)
1797                {
1798                        if(!pnExtraData)
1799                                pnExtraData = pMediaType->pbFormat + pMediaType->cbFormat - nExtraDataSize;
1800                        sText += AtlFormatString(_T("  * ") _T("Extra Data: %s") _T("\r\n"), I(AtlFormatData(pnExtraData, nExtraDataSize).TrimRight()));
1801                }
1802                #pragma endregion
1803                return sText;
1804        }
1805        static CString GetText(IFilterGraph* pFilterGraph, const CProcessData* pProcessData = NULL)
1806        {
1807                if(!pFilterGraph)
1808                        return (LPCTSTR) NULL;
1809                CString sText;
1810                sText += AtlFormatString(_T("# ") _T("Filter Graph") _T("\r\n") _T("\r\n"));
1811                #pragma region Graph Parameters
1812                if(pProcessData)
1813                        sText += AtlFormatString(_T("* ") _T("Process: %s (%s) %s") _T("\r\n"), I(pProcessData->m_nIdentifier), I(pProcessData->m_nIdentifier, _T("0x%X")), I(FindFileName(pProcessData->m_sImagePath)));
1814                #pragma region IMediaControl
1815                const CComQIPtr<IMediaControl> pMediaControl = pFilterGraph;
1816                if(pMediaControl)
1817                        _ATLTRY
1818                        {
1819                                OAFilterState State;
1820                                const HRESULT nGetStateResult = pMediaControl->GetState(0, &State);
1821                                _Z45_DSHRESULT(nGetStateResult);
1822                                static const LPCTSTR g_ppszStates[] = { _T("Stopped"), _T("Paused"), _T("Running"), };
1823                                if(SUCCEEDED(nGetStateResult) && (SIZE_T) State < DIM(g_ppszStates))
1824                                        sText += AtlFormatString(_T("* ") _T("State: %s") _T("\r\n"), I(g_ppszStates[(SIZE_T) State]));
1825                        }
1826                        _ATLCATCHALL()
1827                        {
1828                                _Z_EXCEPTION();
1829                        }
1830                #pragma endregion
1831                #pragma region IMediaPosition
1832                const CComQIPtr<IMediaPosition> pMediaPosition = pFilterGraph;
1833                if(pMediaPosition)
1834                        _ATLTRY
1835                        {
1836                                DOUBLE fDuration = 0, fPosition = 0;
1837                                const HRESULT nGetDurationResult = pMediaPosition->get_Duration(&fDuration);
1838                                _Z45_DSHRESULT(nGetDurationResult);
1839                                if(fDuration > 0)
1840                                {
1841                                        sText += AtlFormatString(_T("* ") _T("Duration: %s (%s seconds)") _T("\r\n"), I(_FilterGraphHelper::FormatSecondTime(fDuration)), I(_StringHelper::FormatNumber(fDuration, 3)));
1842                                        const HRESULT nCurrentPositionResult = pMediaPosition->get_CurrentPosition(&fPosition);
1843                                        _Z45_DSHRESULT(nCurrentPositionResult);
1844                                        if(SUCCEEDED(nCurrentPositionResult))
1845                                                sText += AtlFormatString(_T("* ") _T("Position: %s (%s seconds)") _T("\r\n"), I(_FilterGraphHelper::FormatSecondTime(fPosition)), I(_StringHelper::FormatNumber(fPosition, 3)));
1846                                }
1847                        }
1848                        _ATLCATCHALL()
1849                        {
1850                                _Z_EXCEPTION();
1851                        }
1852                #pragma endregion
1853                if(pProcessData)
1854                {
1855                        if(!pProcessData->m_sDisplayName.IsEmpty())
1856                                sText += AtlFormatString(_T("* ") _T("Display Name: %s") _T("\r\n"), I(pProcessData->m_sDisplayName));
1857                        const CString sDirectory = (LPCTSTR) GetPathDirectory(pProcessData->m_sImagePath);
1858                        if(!sDirectory.IsEmpty())
1859                                sText += AtlFormatString(_T("* ") _T("Process Directory: %s") _T("\r\n"), I(sDirectory));
1860                }
1861                const CComQIPtr<IMediaFilter> pMediaFilter = pFilterGraph;
1862                CComPtr<IReferenceClock> pFilterGraphReferenceClock;
1863                const HRESULT nGetSyncSourceResult = pMediaFilter->GetSyncSource(&pFilterGraphReferenceClock);
1864                _Z45_DSHRESULT(nGetSyncSourceResult);
1865                sText += _T("\r\n");
1866                #pragma endregion
1867                #pragma region Filter
1868                _FilterGraphHelper::CFilterArray FilterArray;
1869                _FilterGraphHelper::GetGraphFilters(pFilterGraph, FilterArray);
1870                if(!FilterArray.IsEmpty())
1871                {
1872                        sText += AtlFormatString(_T("## ") _T("Filters") _T("\r\n") _T("\r\n"));
1873                        for(SIZE_T nIndex = 0; nIndex < FilterArray.GetCount(); nIndex++)
1874                                _ATLTRY
1875                                {
1876                                        const CComPtr<IBaseFilter>& pBaseFilter = FilterArray[nIndex];
1877                                        sText += AtlFormatString(_T("%d. ") _T("%ls") _T("\r\n"), nIndex + 1, _FilterGraphHelper::GetFilterName(pBaseFilter));
1878                                        sText += GetFilterText(pBaseFilter, pFilterGraphReferenceClock);
1879                                }
1880                                _ATLCATCHALL()
1881                                {
1882                                        _Z_EXCEPTION();
1883                                }
1884                        sText += _T("\r\n");
1885                        #pragma region Connection
1886                        sText += AtlFormatString(_T("## ") _T("Connections") _T("\r\n") _T("\r\n"));
1887                        INT nConnectionIndex = 0;
1888                        for(SIZE_T nFilterIndex = 0; nFilterIndex < FilterArray.GetCount(); nFilterIndex++)
1889                        {
1890                                const CComPtr<IBaseFilter>& pBaseFilter = FilterArray[nFilterIndex];
1891                                _FilterGraphHelper::CPinArray PinArray;
1892                                _FilterGraphHelper::GetFilterPins(pBaseFilter, PINDIR_OUTPUT, PinArray);
1893                                for(SIZE_T nPinIndex = 0; nPinIndex < PinArray.GetCount(); nPinIndex++)
1894                                {
1895                                        const CComPtr<IPin>& pOutputPin = PinArray[nPinIndex];
1896                                        const CComPtr<IPin> pInputPin = _FilterGraphHelper::GetPeerPin(pOutputPin);
1897                                        if(!pInputPin)
1898                                                continue;
1899                                        sText += AtlFormatString(_T("%d. ") _T("%s") _T("\r\n"), ++nConnectionIndex, GetConnectionText(pOutputPin, pInputPin));
1900                                }
1901                        }
1902                        sText += _T("\r\n");
1903                        #pragma endregion
1904                        #pragma region Media Type
1905                        sText += AtlFormatString(_T("## ") _T("Media Types") _T("\r\n") _T("\r\n"));
1906                        INT nGlobalPinIndex = 0;
1907                        CRoListT<CComPtr<IPin>> PinList;
1908                        for(SIZE_T nFilterIndex = 0; nFilterIndex < FilterArray.GetCount(); nFilterIndex++)
1909                        {
1910                                const CComPtr<IBaseFilter>& pBaseFilter = FilterArray[nFilterIndex];
1911                                _FilterGraphHelper::CPinArray PinArray;
1912                                _FilterGraphHelper::GetFilterPins(pBaseFilter, PinArray);
1913                                for(SIZE_T nPinIndex = 0; nPinIndex < PinArray.GetCount(); nPinIndex++)
1914                                {
1915                                        const CComPtr<IPin>& pPin = PinArray[nPinIndex];
1916                                        if(PinList.FindFirst(pPin))
1917                                                continue;
1918                                        PinList.AddTail(pPin);
1919                                        CString sPinText = AtlFormatString(_T("%s"), I(_FilterGraphHelper::GetPinFullName(pPin)));
1920                                        const CComPtr<IPin> pPeerPin = _FilterGraphHelper::GetPeerPin(pPin);
1921                                        if(pPeerPin)
1922                                        {
1923                                                PinList.AddTail(pPeerPin);
1924                                                sPinText += AtlFormatString(_T(", %s"), I(_FilterGraphHelper::GetPinFullName(pPeerPin)));
1925                                        }
1926                                        sText += AtlFormatString(_T("%d. ") _T("%s") _T("\r\n"), ++nGlobalPinIndex, sPinText);
1927                                        _ATLTRY
1928                                        {
1929                                                CMediaType pMediaType;
1930                                                if(pPeerPin)
1931                                                        pMediaType = _FilterGraphHelper::GetPinMediaType(pPin);
1932                                                else
1933                                                        pMediaType = _FilterGraphHelper::EnumerateFirstPinMediaType(pPin);
1934                                                if(!pMediaType)
1935                                                        continue;
1936                                                sText += GetMediaTypeText(pMediaType);
1937                                        }
1938                                        _ATLCATCHALL()
1939                                        {
1940                                                _Z_EXCEPTION();
1941                                        }
1942                                }
1943                        }
1944                        sText += _T("\r\n");
1945                        #pragma endregion
1946                }
1947                #pragma endregion
1948                return sText;
1949        }
1950        #undef I
1951        CComPtr<IFilterGraph> GetFilterGraph() const
1952        {
1953                CRoCriticalSectionLock DataLock(m_DataCriticalSection);
1954                return m_pFilterGraph;
1955        }
1956        VOID SetFilterGraph(IFilterGraph* pFilterGraph) 
1957        {
1958                CRoCriticalSectionLock DataLock(m_DataCriticalSection);
1959                m_pFilterGraph = pFilterGraph;
1960        }
1961        BOOL SetFilterGraph(IUnknown* pFilterGraphUnknown) 
1962        {
1963                CComQIPtr<IFilterGraph> pFilterGraph;
1964                if(pFilterGraphUnknown)
1965                {
1966                        pFilterGraph = pFilterGraphUnknown;
1967                        if(!pFilterGraph)
1968                        {
1969                                const CComQIPtr<IBaseFilter> pBaseFilter = pFilterGraphUnknown;
1970                                if(!pBaseFilter)
1971                                {
1972                                        const CComQIPtr<IPin> pPin = pFilterGraphUnknown;
1973                                        if(pPin)
1974                                                pFilterGraph = _FilterGraphHelper::GetFilterGraph(_FilterGraphHelper::GetPinFilter(pPin));
1975                                } else
1976                                        pFilterGraph = _FilterGraphHelper::GetFilterGraph(pBaseFilter);
1977                        }
1978                }
1979                CRoCriticalSectionLock DataLock(m_DataCriticalSection);
1980                m_pFilterGraph = pFilterGraph;
1981                return m_pFilterGraph != NULL;
1982        }
1983        CString GetText() const
1984        {
1985                CRoCriticalSectionLock DataLock(m_DataCriticalSection);
1986                return GetText(m_pFilterGraph);
1987        }
1988        static LPCTSTR GetPlatformName()
1989        {
1990                #if defined(_WIN64)
1991                        return _T("x64");
1992                #else
1993                        return _T("Win32");
1994                #endif // defined(_WIN64)
1995        }
1996        template <SIZE_T t_nItemCount>
1997        static CString& GetLegacyFilter(const COMDLG_FILTERSPEC (&pItems)[t_nItemCount], CString& sFilter)
1998        {
1999                _A(sFilter.IsEmpty());
2000                for(SIZE_T nIndex = 0; nIndex < t_nItemCount; nIndex++)
2001                {
2002                        const COMDLG_FILTERSPEC& Item = pItems[nIndex];
2003                        sFilter += AtlFormatString(_T("%s (%s)|%s|"), Item.pszName, Item.pszSpec, Item.pszSpec);
2004                }
2005                sFilter.Replace(_T('|'), 0);
2006                return sFilter;
2007        }
2008        static BOOL OpenMonikerWithGsn(LPCWSTR pszMonikerDisplayName, HWND hParentWindow = GetActiveWindow())
2009        {
2010                _A(pszMonikerDisplayName);
2011                static const LPCTSTR g_pszValueName = _T("GraphStudioNext Path");
2012                static const LPCTSTR g_pszFileName = _T("graphstudionext.exe");
2013                const CString sValueName = AtlFormatString(_T("%s (%s)"), g_pszValueName, GetPlatformName());
2014                CString sPath = _RegKeyHelper::QueryStringValue(HKEY_CURRENT_USER, REGISTRY_ROOT, sValueName);
2015                if(!FileExists(sPath))
2016                        sPath.Empty();
2017                #pragma region Current Directory
2018                if(sPath.IsEmpty())
2019                {
2020                        sPath = (LPCTSTR) Combine(GetPathDirectory(GetModulePath()), g_pszFileName);
2021                        if(!FileExists(sPath))
2022                                sPath.Empty();
2023                }
2024                #pragma endregion
2025                #pragma region Application Registry
2026                if(sPath.IsEmpty())
2027                {
2028                        #if defined(_WIN64)
2029                                static const LPCTSTR g_pszValueName = _T("exeLocation64");
2030                        #else
2031                                static const LPCTSTR g_pszValueName = _T("exeLocation");
2032                        #endif // defined(_WIN64)
2033                        sPath = _RegKeyHelper::QueryStringValue(HKEY_CURRENT_USER, _T("Software\\MONOGRAM\\GraphStudioNext"), g_pszValueName);
2034                        if(!FileExists(sPath))
2035                                sPath.Empty();
2036                }
2037                #pragma endregion
2038                if(sPath.IsEmpty())
2039                {
2040                        #pragma region Prompt
2041                        static const COMDLG_FILTERSPEC g_pFilter[] = 
2042                        {
2043                                { _T("Executable Files"), _T("*.exe") },
2044                                { _T("All Files"), _T("*.*") },
2045                        };
2046                        if(GetOsVersion() >= GetWinVistaOsVersion())
2047                        {
2048                                CShellFileOpenDialog Dialog(g_pszFileName, FOS_FORCEFILESYSTEM | FOS_FILEMUSTEXIST, _T("exe"), g_pFilter, DIM(g_pFilter));
2049                                if(Dialog.DoModal(hParentWindow) != IDOK)
2050                                        return FALSE;
2051                                __C(Dialog.GetFilePath(sPath));
2052                        } else
2053                        {
2054                                CString sFilter;
2055                                CFileDialog Dialog(TRUE, _T("exe"), NULL, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_EXPLORER | OFN_ENABLESIZING, GetLegacyFilter(g_pFilter, sFilter));
2056                                if(Dialog.DoModal(hParentWindow) != IDOK)
2057                                        return FALSE;
2058                                sPath = Dialog.m_szFileName;
2059                        }
2060                        #pragma endregion
2061                        _RegKeyHelper::SetStringValue(HKEY_CURRENT_USER, REGISTRY_ROOT, sValueName, sPath);
2062                }
2063                CWaitCursor WaitCursor;
2064                CString sParameters = AtlFormatString(_T("-a \"%ls\""), pszMonikerDisplayName);
2065                SHELLEXECUTEINFO Infomation;
2066                ZeroMemory(&Infomation, sizeof Infomation);
2067                Infomation.cbSize = sizeof Infomation;
2068                Infomation.lpFile = sPath;
2069                Infomation.lpParameters = sParameters;
2070                Infomation.nShow = SW_SHOWNORMAL;
2071                __E(ShellExecuteEx(&Infomation));
2072                return TRUE;
2073        }
2074        static BOOL OpenMonikerWithGe(LPCWSTR pszMonikerDisplayName, HWND hParentWindow = GetActiveWindow())
2075        {
2076                static const LPCTSTR g_pszValueName = _T("GraphEdit Path");
2077                static const LPCTSTR g_pszFileName = _T("graphedt.exe");
2078                const CString sValueName = AtlFormatString(_T("%s (%s)"), g_pszValueName, GetPlatformName());
2079                CString sPath = _RegKeyHelper::QueryStringValue(HKEY_CURRENT_USER, REGISTRY_ROOT, sValueName);
2080                if(!FileExists(sPath))
2081                        sPath.Empty();
2082                #pragma region Current Directory
2083                if(sPath.IsEmpty())
2084                {
2085                        sPath = (LPCTSTR) Combine(GetPathDirectory(GetModulePath()), g_pszFileName);
2086                        if(!FileExists(sPath))
2087                                sPath.Empty();
2088                }
2089                #pragma endregion
2090                // SUGG: Look for Windows SDK
2091                if(sPath.IsEmpty())
2092                {
2093                        #pragma region Prompt
2094                        static const COMDLG_FILTERSPEC g_pFilter[] = 
2095                        {
2096                                { _T("Executable Files"), _T("*.exe") },
2097                                { _T("All Files"), _T("*.*") },
2098                        };
2099                        if(GetOsVersion() >= GetWinVistaOsVersion())
2100                        {
2101                                CShellFileOpenDialog Dialog(g_pszFileName, FOS_FORCEFILESYSTEM | FOS_FILEMUSTEXIST, _T("exe"), g_pFilter, DIM(g_pFilter));
2102                                if(Dialog.DoModal(hParentWindow) != IDOK)
2103                                        return FALSE;
2104                                __C(Dialog.GetFilePath(sPath));
2105                        } else
2106                        {
2107                                CString sFilter;
2108                                CFileDialog Dialog(TRUE, _T("exe"), NULL, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_EXPLORER | OFN_ENABLESIZING, GetLegacyFilter(g_pFilter, sFilter));
2109                                if(Dialog.DoModal(hParentWindow) != IDOK)
2110                                        return FALSE;
2111                                sPath = Dialog.m_szFileName;
2112                        }
2113                        #pragma endregion
2114                        _RegKeyHelper::SetStringValue(HKEY_CURRENT_USER, REGISTRY_ROOT, sValueName, sPath);
2115                }
2116                CStringW sFilterGraphMonikerDisplayName = pszMonikerDisplayName;
2117                const INT nSeparatorPosition = sFilterGraphMonikerDisplayName.Find(L';');
2118                if(nSeparatorPosition >= 0)
2119                        sFilterGraphMonikerDisplayName = sFilterGraphMonikerDisplayName.Left(nSeparatorPosition);
2120                CWaitCursor WaitCursor;
2121                CString sParameters = AtlFormatString(_T("-a %ls"), sFilterGraphMonikerDisplayName);
2122                SHELLEXECUTEINFO Infomation;
2123                ZeroMemory(&Infomation, sizeof Infomation);
2124                Infomation.cbSize = sizeof Infomation;
2125                Infomation.lpFile = sPath;
2126                Infomation.lpParameters = sParameters;
2127                Infomation.nShow = SW_SHOWNORMAL;
2128                __E(ShellExecuteEx(&Infomation));
2129                return TRUE;
2130        }
2131
2132// IFilterGraphHelper
2133        STDMETHOD(get_FilterGraph)(IUnknown** ppFilterGraphUnknown)
2134        {
2135                _Z4(atlTraceCOM, 4, _T("...\n"));
2136                _ATLTRY
2137                {
2138                        __D(ppFilterGraphUnknown, E_POINTER);
2139                        *ppFilterGraphUnknown = GetFilterGraph().Detach();
2140                }
2141                _ATLCATCH(Exception)
2142                {
2143                        _C(Exception);
2144                }
2145                return S_OK;
2146        }
2147        STDMETHOD(put_FilterGraph)(IUnknown* pFilterGraphUnknown)
2148        {
2149                _Z4(atlTraceCOM, 4, _T("pFilterGraphUnknown 0x%p\n"), pFilterGraphUnknown);
2150                _ATLTRY
2151                {
2152                        if(!SetFilterGraph(pFilterGraphUnknown))
2153                                return S_FALSE;
2154                }
2155                _ATLCATCH(Exception)
2156                {
2157                        _C(Exception);
2158                }
2159                return S_OK;
2160        }
2161        STDMETHOD(get_Text)(BSTR* psText)
2162        {
2163                _Z4(atlTraceCOM, 4, _T("...\n"));
2164                _ATLTRY
2165                {
2166                        __D(psText, E_POINTER);
2167                        CRoCriticalSectionLock DataLock(m_DataCriticalSection);
2168                        *psText = CComBSTR(GetText(m_pFilterGraph)).Detach();
2169                }
2170                _ATLCATCH(Exception)
2171                {
2172                        _C(Exception);
2173                }
2174                return S_OK;
2175        }
2176        STDMETHOD(DoPropertyFrameModal)(LONG nParentWindowHandle)
2177        {
2178                _Z4(atlTraceCOM, 4, _T("nParentWindowHandle 0x%08X\n"), nParentWindowHandle);
2179                _ATLTRY
2180                {
2181                        CWindow ParentWindow = (HWND) (LONG_PTR) nParentWindowHandle;
2182                        if(!ParentWindow)
2183                                ParentWindow = GetActiveWindow();
2184                        //__D(!ParentWindow || ParentWindow.IsWindow(), E_INVALIDARG);
2185                        const CComQIPtr<IFilterGraph2> pFilterGraph2 = GetFilterGraph();
2186                        __D(pFilterGraph2, E_NOINTERFACE);
2187                        CPropertyFrameDialog PropertyFrameDialog(this);
2188                        PropertyFrameDialog.DoModal(ParentWindow);
2189                }
2190                _ATLCATCH(Exception)
2191                {
2192                        _C(Exception);
2193                }
2194                return S_OK;
2195        }
2196        STDMETHOD(DoFilterGraphListModal)(LONG nParentWindowHandle)
2197        {
2198                _Z4(atlTraceCOM, 4, _T("nParentWindowHandle 0x%08X\n"), nParentWindowHandle);
2199                _ATLTRY
2200                {
2201                        CWindow ParentWindow = (HWND) (LONG_PTR) nParentWindowHandle;
2202                        if(!ParentWindow)
2203                                ParentWindow = GetActiveWindow();
2204                        //__D(!ParentWindow || ParentWindow.IsWindow(), E_INVALIDARG);
2205                        DoFilterGraphListPropertySheetModal(ParentWindow);
2206                }
2207                _ATLCATCH(Exception)
2208                {
2209                        _C(Exception);
2210                }
2211                return S_OK;
2212        }
2213        STDMETHOD(OpenGraphStudioNext)(LONG nParentWindowHandle, BSTR sMonikerDisplayName, VARIANT_BOOL* pbResult)
2214        {
2215                _Z4(atlTraceCOM, 4, _T("nParentWindowHandle 0x%08X, sMonikerDisplayName \"%s\"\n"), nParentWindowHandle, CString(sMonikerDisplayName));
2216                _ATLTRY
2217                {
2218                        __D(sMonikerDisplayName && *sMonikerDisplayName, E_INVALIDARG);
2219                        CWindow ParentWindow = (HWND) (LONG_PTR) nParentWindowHandle;
2220                        if(!ParentWindow)
2221                                ParentWindow = GetActiveWindow();
2222                        //__D(!ParentWindow || ParentWindow.IsWindow(), E_INVALIDARG);
2223                        const BOOL bResult = OpenMonikerWithGsn(sMonikerDisplayName, ParentWindow);
2224                        if(pbResult)
2225                                *pbResult = bResult ? ATL_VARIANT_TRUE : ATL_VARIANT_FALSE;
2226                }
2227                _ATLCATCH(Exception)
2228                {
2229                        _C(Exception);
2230                }
2231                return S_OK;
2232        }
2233        STDMETHOD(OpenGraphEdit)(LONG nParentWindowHandle, BSTR sMonikerDisplayName, VARIANT_BOOL* pbResult)
2234        {
2235                _Z4(atlTraceCOM, 4, _T("nParentWindowHandle 0x%08X, sMonikerDisplayName \"%s\"\n"), nParentWindowHandle, CString(sMonikerDisplayName));
2236                _ATLTRY
2237                {
2238                        __D(sMonikerDisplayName && *sMonikerDisplayName, E_INVALIDARG);
2239                        CWindow ParentWindow = (HWND) (LONG_PTR) nParentWindowHandle;
2240                        if(!ParentWindow)
2241                                ParentWindow = GetActiveWindow();
2242                        //__D(!ParentWindow || ParentWindow.IsWindow(), E_INVALIDARG);
2243                        const BOOL bResult = OpenMonikerWithGe(sMonikerDisplayName, ParentWindow);
2244                        if(pbResult)
2245                                *pbResult = bResult ? ATL_VARIANT_TRUE : ATL_VARIANT_FALSE;
2246                }
2247                _ATLCATCH(Exception)
2248                {
2249                        _C(Exception);
2250                }
2251                return S_OK;
2252        }
2253};
2254
2255OBJECT_ENTRY_AUTO(__uuidof(FilterGraphHelper), CFilterGraphHelper)
2256
2257inline HRESULT FilterGraphHelper_DoPropertyFrameModal(LONG nParentWindowHandle, IUnknown* pFilterGraphUnknown)
2258{
2259        CLocalObjectPtr<CFilterGraphHelper> pFilterGraphHelper;
2260        pFilterGraphHelper->SetFilterGraph(pFilterGraphUnknown);
2261        return pFilterGraphHelper->DoPropertyFrameModal(nParentWindowHandle);
2262}
2263inline HRESULT FilterGraphHelper_DoFilterGraphListModal(LONG nParentWindowHandle)
2264{
2265        CLocalObjectPtr<CFilterGraphHelper> pFilterGraphHelper;
2266        return pFilterGraphHelper->DoFilterGraphListModal(nParentWindowHandle);
2267}
2268inline HRESULT FilterGraphHelper_OpenGraphStudioNext(LONG nParentWindowHandle, LPCWSTR pszMonikerDisplayName, VARIANT_BOOL* pbResult)
2269{
2270        CLocalObjectPtr<CFilterGraphHelper> pFilterGraphHelper;
2271        return pFilterGraphHelper->OpenGraphStudioNext(nParentWindowHandle, CComBSTR(pszMonikerDisplayName), pbResult);
2272}
2273inline HRESULT FilterGraphHelper_OpenGraphEdit(LONG nParentWindowHandle, LPCWSTR pszMonikerDisplayName, VARIANT_BOOL* pbResult)
2274{
2275        CLocalObjectPtr<CFilterGraphHelper> pFilterGraphHelper;
2276        return pFilterGraphHelper->OpenGraphEdit(nParentWindowHandle, CComBSTR(pszMonikerDisplayName), pbResult);
2277}
Note: See TracBrowser for help on using the repository browser.