source: trunk/DirectShowSpy/FilterGraphHelper.h @ 302

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

Safer media type extra data extraction for bad/invalid media types

File size: 115.5 KB
Line 
1////////////////////////////////////////////////////////////
2// Copyright (C) Roman Ryltsov, 2008-2014
3// Created by Roman Ryltsov roman@alax.info, http://alax.info
4//
5// This source code is published to complement DirectShowSpy developer powertoy
6// and demonstrate the internal use of APIs and tricks powering the tool. It is
7// allowed to freely re-use the portions of the code in other projects, commercial
8// or otherwise (provided that you don’t pretend that you wrote the original tool).
9//
10// Please keep in mind that DirectShowSpy is a developer tool, it is strongly recommended
11// that it is not shipped with release grade software. It is allowed to distribute
12// DirectShowSpy if only it is not registered with Windows by default and either
13// used privately, or registered on specific throubleshooting request. The advice applies
14// to hooking methods used by DirectShowSpy in general as well.
15
16#pragma once
17
18#include "rofiles.h"
19#include "rodshow.h"
20#include "DirectShowSpy_i.h"
21#include "Common.h"
22#include "RunPropertyBag.h"
23#include "RunEvent.h"
24#include "AboutDialog.h"
25#include "..\..\Repository-Private\Utilities\EmailTools\Message.h"
26#define  BZ_NO_STDIO
27#include "..\..\Repository-Private\Utilities\DeflateTools\Bzip2Item.h"
28
29INT_PTR DoFilterGraphListPropertySheetModal(HWND hParentWindow);
30
31HRESULT FilterGraphHelper_DoPropertyFrameModal(LONG nParentWindowHandle);
32HRESULT FilterGraphHelper_DoFilterGraphListModal(LONG nParentWindowHandle);
33HRESULT FilterGraphHelper_OpenGraphStudioNext(LONG nParentWindowHandle, LPCWSTR pszMonikerDisplayName, VARIANT_BOOL* pbResult);
34HRESULT FilterGraphHelper_OpenGraphEdit(LONG nParentWindowHandle, LPCWSTR pszMonikerDisplayName, VARIANT_BOOL* pbResult);
35
36////////////////////////////////////////////////////////////
37// CRunPropertyBagPropertyPage
38
39class ATL_NO_VTABLE CRunPropertyBagPropertyPage :
40        public CComObjectRootEx<CComSingleThreadModel>,
41        public CComCoClass<CRunPropertyBagPropertyPage, &__uuidof(RunPropertyBagPropertyPage)>,
42        public COlePropertyPageT<CRunPropertyBagPropertyPage>,
43        public CDialogResize<CRunPropertyBagPropertyPage>
44{
45public:
46        enum { IDR = IDR_GENERIC_RUNPROPERTYBAG_PROPERTYPAGE };
47        enum { IDD = IDD_GENERIC_RUNPROPERTYBAG };
48
49BEGIN_COM_MAP(CRunPropertyBagPropertyPage)
50        COM_INTERFACE_ENTRY(IPropertyPage2)
51        COM_INTERFACE_ENTRY(IPropertyPage)
52END_COM_MAP()
53
54BEGIN_MSG_MAP_EX(CRunPropertyBagPropertyPage)
55        CHAIN_MSG_MAP(COlePropertyPage)
56        CHAIN_MSG_MAP(CDialogResize<CRunPropertyBagPropertyPage>)
57        MSG_WM_INITDIALOG(OnInitDialog)
58        MSG_WM_DESTROY(OnDestroy)
59        COMMAND_ID_HANDLER_EX(IDC_GENERIC_RUNPROPERTYBAG_REFRESH, OnRefresh)
60        REFLECT_NOTIFICATIONS()
61END_MSG_MAP()
62
63BEGIN_DLGRESIZE_MAP(CRunPropertyBagPropertyPage)
64        DLGRESIZE_CONTROL(IDC_GENERIC_RUNPROPERTYBAG_INTRODUCTION, DLSZ_SIZE_X)
65        DLGRESIZE_CONTROL(IDC_GENERIC_RUNPROPERTYBAG_TEXT, DLSZ_SIZE_X | DLSZ_SIZE_Y)
66        DLGRESIZE_CONTROL(IDC_GENERIC_RUNPROPERTYBAG_REFRESH, DLSZ_MOVE_Y)
67END_DLGRESIZE_MAP()
68
69private:
70        BOOL m_bActivating;
71        CRoEdit m_TextEdit;
72        CFont m_TextFont;
73        CRoMapT<INT_PTR, BOOL> m_ChangeMap;
74
75public:
76// CRunPropertyBagPropertyPage
77        static CString GetObjectFriendlyName()
78        {
79                return _StringHelper::GetLine(IDR, 2);
80        }
81        static HRESULT WINAPI UpdateRegistry(BOOL bRegister)
82        {
83                _Z2(atlTraceRegistrar, 2, _T("bRegister %d\n"), bRegister);
84                return DefaultUpdateRegistry(bRegister);
85        }
86        CRunPropertyBagPropertyPage()
87        {
88                _Z4_THIS();
89        }
90        ~CRunPropertyBagPropertyPage()
91        {
92                _Z4_THIS();
93        }
94        VOID UpdateControls()
95        {
96        }
97        VOID UpdateText()
98        {
99                CString sText;
100                _A(GetObjectCount() == 1);
101                m_TextEdit.SetValue(CRunPropertyBagHelper::GetPropertyBagText(GetObject(0)));
102        }
103
104// Window message handlers
105        LRESULT OnInitDialog(HWND, LPARAM)
106        {
107                m_bActivating = TRUE;
108                _ATLTRY
109                {
110                        CWaitCursor WaitCursor;
111                        m_TextEdit = GetDlgItem(IDC_GENERIC_RUNPROPERTYBAG_TEXT);
112                        CLogFont TextFont;
113                        CFontHandle(AtlGetDefaultGuiFont()).GetLogFont(TextFont);
114                        _tcsncpy_s(TextFont.lfFaceName, _T("Courier New"), _TRUNCATE);
115                        TextFont.SetHeight(8);
116                        m_TextFont = TextFont.CreateFontIndirect();
117                        m_TextEdit.SetFont(m_TextFont);
118                        DlgResize_Init(FALSE);
119                        _A(GetObjectCount() >= 1);
120                        //const CComQIPtr<IRunPropertyBagAware> pRunPropertyBagAware = GetObject(0);
121                        //__D(pRunPropertyBagAware, E_NOINTERFACE);
122                        UpdateText();
123                        UpdateControls();
124                        m_ChangeMap.RemoveAll();
125                        m_bActivating = FALSE;
126                }
127                _ATLCATCH(Exception)
128                {
129                        AtlExceptionMessageBox(m_hWnd, Exception);
130                        for(CWindow Window = GetWindow(GW_CHILD); Window.IsWindow(); Window = Window.GetWindow(GW_HWNDNEXT))
131                                Window.EnableWindow(FALSE);
132                }
133                return TRUE;
134        }
135        LRESULT OnDestroy()
136        {
137                return 0;
138        }
139        LRESULT OnRefresh(UINT, INT, HWND)
140        {
141                CWaitCursor WaitCursor;
142                UpdateText();
143                UpdateControls();
144                return 0;
145        }
146
147// COlePropertyPageT, IRoPropertyPageT, IPropertyPage2, IPropertyPage
148        STDMETHOD(Apply)()
149        {
150                _Z4(atlTraceCOM, 4, _T("...\n"));
151                _ATLTRY
152                {
153                        //if(!m_ChangeMap.IsEmpty())
154                        {
155                                //CWaitCursor WaitCursor;
156                                //m_ChangeMap.RemoveAll();
157                                SetDirty(FALSE);
158                        }
159                }
160                _ATLCATCH(Exception)
161                {
162                        _C(Exception);
163                }
164                return S_OK;
165        }
166};
167
168OBJECT_ENTRY_AUTO(__uuidof(RunPropertyBagPropertyPage), CRunPropertyBagPropertyPage)
169
170////////////////////////////////////////////////////////////
171// CRunEventPropertyPage
172
173class ATL_NO_VTABLE CRunEventPropertyPage :
174        public CComObjectRootEx<CComSingleThreadModel>,
175        public CComCoClass<CRunEventPropertyPage, &__uuidof(RunEventPropertyPage)>,
176        public COlePropertyPageT<CRunEventPropertyPage>,
177        public CDialogResize<CRunEventPropertyPage>
178{
179public:
180        enum { IDR = IDR_GENERIC_RUNEVENT_PROPERTYPAGE };
181        enum { IDD = IDD_GENERIC_RUNEVENT };
182
183BEGIN_COM_MAP(CRunEventPropertyPage)
184        COM_INTERFACE_ENTRY(IPropertyPage2)
185        COM_INTERFACE_ENTRY(IPropertyPage)
186END_COM_MAP()
187
188BEGIN_MSG_MAP_EX(CRunEventPropertyPage)
189        CHAIN_MSG_MAP(COlePropertyPage)
190        CHAIN_MSG_MAP(CDialogResize<CRunEventPropertyPage>)
191        MSG_WM_INITDIALOG(OnInitDialog)
192        MSG_WM_DESTROY(OnDestroy)
193        COMMAND_HANDLER_EX(IDC_GENERIC_RUNEVENT_CAPTURE, BN_CLICKED, OnCaptureButtonClicked)
194        COMMAND_ID_HANDLER_EX(IDC_GENERIC_RUNEVENT_REFRESH, OnRefresh)
195        REFLECT_NOTIFICATIONS()
196END_MSG_MAP()
197
198BEGIN_DLGRESIZE_MAP(CRunEventPropertyPage)
199        DLGRESIZE_CONTROL(IDC_GENERIC_RUNEVENT_CAPTURE, DLSZ_SIZE_X)
200        DLGRESIZE_CONTROL(IDC_GENERIC_RUNEVENT_TEXT, DLSZ_SIZE_X | DLSZ_SIZE_Y)
201        DLGRESIZE_CONTROL(IDC_GENERIC_RUNEVENT_REFRESH, DLSZ_MOVE_Y)
202END_DLGRESIZE_MAP()
203
204public:
205
206private:
207        BOOL m_bActivating;
208        CButton m_CaptureButton;
209        CRoEdit m_TextEdit;
210        CButton m_RefreshButton;
211        CRoMapT<INT_PTR, BOOL> m_ChangeMap;
212
213public:
214// CRunEventPropertyPage
215        static CString GetObjectFriendlyName()
216        {
217                return _StringHelper::GetLine(IDR, 2);
218        }
219        static HRESULT WINAPI UpdateRegistry(BOOL bRegister)
220        {
221                _Z2(atlTraceRegistrar, 2, _T("bRegister %d\n"), bRegister);
222                return DefaultUpdateRegistry(bRegister);
223        }
224        CRunEventPropertyPage()
225        {
226                _Z4_THIS();
227        }
228        ~CRunEventPropertyPage()
229        {
230                _Z4_THIS();
231        }
232        VOID UpdateControls()
233        {
234                const BOOL bCapture = m_CaptureButton.GetCheck();
235                //m_TextEdit.EnableWindow(bCapture);
236                m_RefreshButton.EnableWindow(bCapture);
237        }
238        VOID Refresh()
239        {
240                const CComQIPtr<IRunEventAware> pRunEventAware = GetObject(0);
241                if(!pRunEventAware)
242                        return;
243                CComVariantArray vValue;
244                __C(pRunEventAware->get_Value(&vValue));
245                CString sText;
246                _ATLTRY
247                {
248                        if(vValue.vt > VT_NULL)
249                        {
250                                CRoArrayT<CComVariantArray> Array;
251                                vValue.ToElementArray(Array);
252                                for(SIZE_T nIndex = 0; nIndex < Array.GetCount(); nIndex++)
253                                {
254                                        CRunEventHelper::CEvents::CItem Item;
255                                        if(!Item.SetAsVariant(Array[nIndex]))
256                                                continue;
257                                        sText.AppendFormat(_T("%d") _T("\t") _T("%hs"), (LONG) (Item.m_nTime / 10000i64), Item.m_pszText);
258                                        sText.Append(_T("\r\n"));
259                                }
260                        }
261                }
262                _ATLCATCHALL()
263                {
264                        _Z_EXCEPTION();
265                }
266                m_TextEdit.SetValue(sText);
267        }
268
269// Window message handlers
270        LRESULT OnInitDialog(HWND, LPARAM)
271        {
272                m_bActivating = TRUE;
273                _ATLTRY
274                {
275                        m_CaptureButton = GetDlgItem(IDC_GENERIC_RUNEVENT_CAPTURE);
276                        m_TextEdit = GetDlgItem(IDC_GENERIC_RUNEVENT_TEXT);
277                        m_RefreshButton = GetDlgItem(IDC_GENERIC_RUNEVENT_REFRESH);
278                        DlgResize_Init(FALSE);
279                        //m_OutputSampleTimeEdit = GetDlgItem(IDC_SUSPENSIONFILTER_SAMPLE_OUTPUTTIME);
280                        _A(GetObjectCount() >= 1);
281                        const CComQIPtr<IRunEventAware> pRunEventAware = GetObject(0);
282                        __D(pRunEventAware, E_NOINTERFACE);
283                        VARIANT_BOOL bCapture = ATL_VARIANT_FALSE;
284                        __C(pRunEventAware->get_Capture(&bCapture));
285                        m_CaptureButton.SetCheck(bCapture != ATL_VARIANT_FALSE);
286                        if(bCapture != ATL_VARIANT_FALSE)
287                                Refresh();
288                        UpdateControls();
289                        m_ChangeMap.RemoveAll();
290                        m_bActivating = FALSE;
291                }
292                _ATLCATCH(Exception)
293                {
294                        AtlExceptionMessageBox(m_hWnd, Exception);
295                        for(CWindow Window = GetWindow(GW_CHILD); Window.IsWindow(); Window = Window.GetWindow(GW_HWNDNEXT))
296                                Window.EnableWindow(FALSE);
297                }
298                return TRUE;
299        }
300        LRESULT OnDestroy()
301        {
302                return 0;
303        }
304        LRESULT OnCaptureButtonClicked(UINT, INT, HWND)
305        {
306                CWaitCursor WaitCursor;
307                const CComQIPtr<IRunEventAware> pRunEventAware = GetObject(0);
308                if(pRunEventAware)
309                        _ATLTRY
310                        {
311                                const BOOL bCapture = m_CaptureButton.GetCheck();
312                                __C(pRunEventAware->put_Capture(bCapture ? ATL_VARIANT_TRUE : ATL_VARIANT_FALSE));
313                        }
314                        _ATLCATCHALL()
315                        {
316                                _Z_EXCEPTION();
317                        }
318                UpdateControls();
319                return 0;
320        }
321        LRESULT OnRefresh(UINT, INT, HWND)
322        {
323                CWaitCursor WaitCursor;
324                Refresh();
325                UpdateControls();
326                return 0;
327        }
328
329// COlePropertyPageT, IRoPropertyPageT, IPropertyPage2, IPropertyPage
330        STDMETHOD(Apply)()
331        {
332                _Z4(atlTraceCOM, 4, _T("...\n"));
333                _ATLTRY
334                {
335                        //if(!m_ChangeMap.IsEmpty())
336                        {
337                                //CWaitCursor WaitCursor;
338                                //m_ChangeMap.RemoveAll();
339                                SetDirty(FALSE);
340                        }
341                }
342                _ATLCATCH(Exception)
343                {
344                        _C(Exception);
345                }
346                return S_OK;
347        }
348};
349
350OBJECT_ENTRY_AUTO(__uuidof(RunEventPropertyPage), CRunEventPropertyPage)
351
352////////////////////////////////////////////////////////////
353// CFilterGraphHelper
354
355class ATL_NO_VTABLE CFilterGraphHelper :
356        public CComObjectRootEx<CComMultiThreadModelNoCS>,
357        public CComCoClass<CFilterGraphHelper, &__uuidof(FilterGraphHelper)>,
358        public IProvideClassInfo2Impl<&__uuidof(FilterGraphHelper), &IID_NULL>,
359        public IDispatchImpl<IFilterGraphHelper>
360{
361public:
362        enum { IDR = IDR_FILTERGRAPHHELPER };
363
364//DECLARE_REGISTRY_RESOURCEID(IDR)
365
366BEGIN_COM_MAP(CFilterGraphHelper)
367        COM_INTERFACE_ENTRY(IFilterGraphHelper)
368        COM_INTERFACE_ENTRY(IDispatch)
369        COM_INTERFACE_ENTRY(IProvideClassInfo2)
370        COM_INTERFACE_ENTRY(IProvideClassInfo)
371END_COM_MAP()
372
373public:
374
375        ////////////////////////////////////////////////////////
376        // CProcessData
377
378        class CProcessData
379        {
380        public:
381                CStringW m_sDisplayName;
382                DWORD m_nIdentifier;
383                CPath m_sImagePath;
384
385        public:
386        // CProcessData
387                CProcessData() :
388                        m_nIdentifier(0)
389                {
390                }
391        };
392
393        ////////////////////////////////////////////////////////
394        // CPropertyFrameDialog
395
396        class CPropertyFrameDialog :
397                public CDialogImpl<CPropertyFrameDialog>,
398                public CDialogResize<CPropertyFrameDialog>,
399                public CDialogWithAcceleratorsT<CPropertyFrameDialog>
400        {
401        public:
402                enum { IDD = IDD_FILTERGRAPHHELPER_PROPERTYFRAME };
403
404        BEGIN_MSG_MAP_EX(CPropertyFrameDialog)
405                //CHAIN_MSG_MAP(CDialogImpl<CPropertyFrameDialog>)
406                CHAIN_MSG_MAP(CDialogResize<CPropertyFrameDialog>)
407                MSG_WM_INITDIALOG(OnInitDialog)
408                MSG_WM_DESTROY(OnDestroy)
409                MSG_TVN_GETINFOTIP(IDC_FILTERGRAPHHELPER_PROPERTYFRAME_TREE, OnTreeViewGetInfoTip)
410                MSG_TVN_SELCHANGED(IDC_FILTERGRAPHHELPER_PROPERTYFRAME_TREE, OnTreeViewSelChanged)
411                MSG_TVN_ITEMEXPANDING(IDC_FILTERGRAPHHELPER_PROPERTYFRAME_TREE, OnTreeViewItemExplanding)
412                MSG_TVN_DBLCLK(IDC_FILTERGRAPHHELPER_PROPERTYFRAME_TREE, OnTreeViewDblClk)
413                MSG_WM_SYSCOMMAND(OnSysCommand)
414                COMMAND_ID_HANDLER_EX(IDOK, OnOk)
415                COMMAND_ID_HANDLER_EX(IDCANCEL, OnCancel)
416                COMMAND_ID_HANDLER_EX(IDC_FILTERGRAPHHELPER_PROPERTYFRAME_APPLY, OnApply)
417                COMMAND_ID_HANDLER_EX(IDC_FILTERGRAPHHELPER_PROPERTYFRAME_TREE_WALKUP, OnTreeWalkUp)
418                COMMAND_ID_HANDLER_EX(IDC_FILTERGRAPHHELPER_ACTION_OPENGSN, OnActionCommand)
419                COMMAND_ID_HANDLER_EX(IDC_FILTERGRAPHHELPER_ACTION_OPENGE, OnActionCommand)
420                COMMAND_ID_HANDLER_EX(IDC_FILTERGRAPHHELPER_ACTION_OPENLIST, OnActionCommand)
421                REFLECT_NOTIFICATIONS()
422        END_MSG_MAP()
423
424        BEGIN_DLGRESIZE_MAP(CPropertyFrameDialog)
425                DLGRESIZE_CONTROL(IDC_FILTERGRAPHHELPER_PROPERTYFRAME_TREE, DLSZ_SIZE_Y)
426                DLGRESIZE_CONTROL(IDC_FILTERGRAPHHELPER_PROPERTYFRAME_TEXT, DLSZ_SIZE_X | DLSZ_SIZE_Y)
427                DLGRESIZE_CONTROL(IDOK, DLSZ_MOVE_X | DLSZ_MOVE_Y)
428                DLGRESIZE_CONTROL(IDCANCEL, DLSZ_MOVE_X | DLSZ_MOVE_Y)
429                DLGRESIZE_CONTROL(IDC_FILTERGRAPHHELPER_PROPERTYFRAME_APPLY, DLSZ_MOVE_X | DLSZ_MOVE_Y)
430        END_DLGRESIZE_MAP()
431
432        public:
433
434                ////////////////////////////////////////////////////
435                // CPropertyPageSite
436
437                class ATL_NO_VTABLE CPropertyPageSite :
438                        public CComObjectRootEx<CComSingleThreadModel>,
439                        public IPropertyPageSite
440                {
441                        friend class CPropertyFrameDialog;
442
443                public:
444
445                BEGIN_COM_MAP(CPropertyPageSite)
446                        COM_INTERFACE_ENTRY(IPropertyPageSite)
447                END_COM_MAP()
448
449                private:
450                        CPropertyFrameDialog* m_pOwner;
451                        CComPtr<IUnknown> m_pUnknown;
452                        CComPtr<IPropertyPage> m_pPropertyPage;
453                        CString m_sTitle;
454                        DWORD m_nStatus;
455
456                public:
457                // CPropertyPageSite
458                        CPropertyPageSite() :
459                                m_pOwner(NULL)
460                        {
461                        }
462                        VOID Initialize(CPropertyFrameDialog* pOwner, IUnknown* pUnknown, IPropertyPage* pPropertyPage)
463                        {
464                                _A(pOwner && pUnknown && pPropertyPage);
465                                _A(!m_pOwner);
466                                m_pOwner = pOwner;
467                                m_pUnknown = pUnknown;
468                                m_pPropertyPage = pPropertyPage;
469                                __C(pPropertyPage->SetObjects(1, &m_pUnknown.p));
470                                PROPPAGEINFO Information;
471                                ZeroMemory(&Information, sizeof Information);
472                                Information.cb = sizeof Information;
473                                __C(pPropertyPage->GetPageInfo(&Information));
474                                CStringW sTitle = Information.pszTitle;
475                                CoTaskMemFree(Information.pszTitle);
476                                CoTaskMemFree(Information.pszDocString);
477                                CoTaskMemFree(Information.pszHelpFile);
478                                m_sTitle = CString(sTitle);
479                                m_nStatus = 0;
480                                __C(pPropertyPage->SetPageSite(this));
481                        }
482                        VOID Terminate()
483                        {
484                                if(m_pPropertyPage)
485                                {
486                                        _V(m_pPropertyPage->SetPageSite(NULL));
487                                        m_pPropertyPage.Release();
488                                }
489                                m_pUnknown.Release();
490                                m_pOwner = NULL;
491                        }
492                        BOOL IsDirty()
493                        {
494                                return m_nStatus & PROPPAGESTATUS_DIRTY;
495                        }
496
497                // IPropertyPageSite
498                        STDMETHOD(OnStatusChange)(DWORD nFlags)
499                        {
500                                _Z4(atlTraceCOM, 4, _T("nFlags 0x%x\n"), nFlags);
501                                m_nStatus = nFlags;
502                                m_pOwner->HandleStatusChange(this);
503                                return S_OK;
504                        }
505                        STDMETHOD(GetLocaleID)(LCID* pLocaleIdentifier)
506                        {
507                                _Z4(atlTraceCOM, 4, _T("...\n"));
508                                pLocaleIdentifier;
509                                return E_NOTIMPL;
510                        }
511                        STDMETHOD(GetPageContainer)(IUnknown** ppUnknown)
512                        {
513                                _Z4(atlTraceCOM, 4, _T("...\n"));
514                                ppUnknown;
515                                return E_NOTIMPL;
516                        }
517                        STDMETHOD(TranslateAccelerator)(MSG* pMessage)
518                        {
519                                _Z4(atlTraceCOM, 4, _T("...\n"));
520                                pMessage;
521                                return E_NOTIMPL;
522                        }
523                };
524
525                ////////////////////////////////////////////////////
526                // CActionDialog
527
528                class CActionDialog :
529                        public CDialogImpl<CActionDialog>,
530                        public CDialogResize<CActionDialog>
531                {
532                public:
533                        enum { IDD = IDD_FILTERGRAPHHELPER_ACTION };
534
535                BEGIN_MSG_MAP_EX(CActionDialog)
536                        //CHAIN_MSG_MAP(CDialogImpl<CActionDialog>)
537                        CHAIN_MSG_MAP(CDialogResize<CActionDialog>)
538                        MSG_WM_INITDIALOG(OnInitDialog)
539                        COMMAND_ID_HANDLER_EX(IDC_FILTERGRAPHHELPER_ACTION_SAVEAS, OnSaveAs)
540                        COMMAND_ID_HANDLER_EX(IDC_FILTERGRAPHHELPER_ACTION_OPENGSN, OnOpenGsn)
541                        COMMAND_ID_HANDLER_EX(IDC_FILTERGRAPHHELPER_ACTION_OPENGE, OnOpenGe)
542                        COMMAND_ID_HANDLER_EX(IDC_FILTERGRAPHHELPER_ACTION_OPENLIST, OnOpenList)
543                        REFLECT_NOTIFICATIONS()
544                END_MSG_MAP()
545
546                BEGIN_DLGRESIZE_MAP(CActionDialog)
547                        //DLGRESIZE_CONTROL(IDC_FILTERGRAPHHELPER_ACTION_, DLSZ_SIZE_X | DLSZ_SIZE_Y)
548                END_DLGRESIZE_MAP()
549
550                private:
551                        CPropertyFrameDialog* m_pOwner;
552                        BOOL m_bActivating;
553                        CStatic m_TitleStatic;
554                        CFont m_TitleFont;
555                        CButton m_SaveAsButton;
556                        CRoHyperStatic m_SaveAsDescriptionStatic;
557                        CButton m_OpenGsnButton;
558                        CRoHyperStatic m_OpenGsnDescriptionStatic;
559                        CButton m_OpenGeButton;
560                        CRoHyperStatic m_OpenGeDescriptionStatic;
561                        CButton m_OpenListButton;
562                        CRoHyperStatic m_OpenListDescriptionStatic;
563                        CStringW m_sFilterGraphMonikerDisplayName;
564                        CRoMapT<INT_PTR, BOOL> m_ChangeMap;
565
566                public:
567                // CActionDialog
568
569                // Window Message Handler
570                        LRESULT OnInitDialog(HWND, LPARAM lParam)
571                        {
572                                m_pOwner = (CPropertyFrameDialog*) lParam;
573                                m_bActivating = TRUE;
574                                _ATLTRY
575                                {
576                                        CWaitCursor WaitCursor;
577                                        m_TitleStatic = GetDlgItem(IDC_FILTERGRAPHHELPER_ACTION_TITLE);
578                                        CreateTitleFont(m_TitleFont, m_TitleStatic);
579                                        m_SaveAsButton = GetDlgItem(IDC_FILTERGRAPHHELPER_ACTION_SAVEAS);
580                                        _W(m_SaveAsDescriptionStatic.SubclassWindow(GetDlgItem(IDC_FILTERGRAPHHELPER_ACTION_SAVEASDESCRIPTION)));
581                                        m_OpenGsnButton = GetDlgItem(IDC_FILTERGRAPHHELPER_ACTION_OPENGSN);
582                                        _W(m_OpenGsnDescriptionStatic.SubclassWindow(GetDlgItem(IDC_FILTERGRAPHHELPER_ACTION_OPENGSNDESCRIPTION)));
583                                        m_OpenGeButton = GetDlgItem(IDC_FILTERGRAPHHELPER_ACTION_OPENGE);
584                                        _W(m_OpenGeDescriptionStatic.SubclassWindow(GetDlgItem(IDC_FILTERGRAPHHELPER_ACTION_OPENGEDESCRIPTION)));
585                                        m_OpenListButton = GetDlgItem(IDC_FILTERGRAPHHELPER_ACTION_OPENLIST);
586                                        _W(m_OpenListDescriptionStatic.SubclassWindow(GetDlgItem(IDC_FILTERGRAPHHELPER_ACTION_OPENLISTDESCRIPTION)));
587                                        //DlgResize_Init(FALSE, FALSE);
588                                        _ATLTRY
589                                        {
590                                                m_sFilterGraphMonikerDisplayName.Empty();
591                                                const CComQIPtr<ISpy> pSpy = m_pOwner->m_Owner.GetFilterGraph();
592                                                if(pSpy)
593                                                {
594                                                        CComBSTR sFilterGraphMonikerDisplayName;
595                                                        __C(pSpy->get_MonikerDisplayName(&sFilterGraphMonikerDisplayName));
596                                                        m_sFilterGraphMonikerDisplayName = sFilterGraphMonikerDisplayName;
597                                                }
598                                        }
599                                        _ATLCATCHALL()
600                                        {
601                                                _Z_EXCEPTION();
602                                        }
603                                        const BOOL bMonikerDisplayNameAvailable = !m_sFilterGraphMonikerDisplayName.IsEmpty();
604                                        m_OpenGsnButton.EnableWindow(bMonikerDisplayNameAvailable);
605                                        m_OpenGsnDescriptionStatic.EnableWindow(bMonikerDisplayNameAvailable);
606                                        m_OpenGeButton.EnableWindow(bMonikerDisplayNameAvailable);
607                                        m_OpenGeDescriptionStatic.EnableWindow(bMonikerDisplayNameAvailable);
608                                        m_bActivating = FALSE;
609                                }
610                                _ATLCATCH(Exception)
611                                {
612                                        for(CWindow Window = GetWindow(GW_CHILD); Window; Window = Window.GetWindow(GW_HWNDNEXT))
613                                                Window.EnableWindow(FALSE);
614                                        AtlExceptionMessageBox(m_hWnd, Exception);
615                                }
616                                return TRUE;
617                        }
618                        LRESULT OnSaveAs(UINT, INT, HWND)
619                        {
620                                CPath sPath;
621                                static const COMDLG_FILTERSPEC g_pFilter[] = 
622                                {
623                                        { _T("GraphEdit Files"), _T("*.grf") },
624                                        { _T("All Files"), _T("*.*") },
625                                };
626                                if(GetOsVersion() >= GetWinVistaOsVersion())
627                                {
628                                        CShellFileSaveDialog Dialog(NULL, FOS_OVERWRITEPROMPT | FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST, _T("grf"), g_pFilter, DIM(g_pFilter));
629                                        if(Dialog.DoModal(m_hWnd) != IDOK)
630                                                return 0;
631                                        CString sPathString;
632                                        __C(Dialog.GetFilePath(sPathString));
633                                        sPath = (LPCTSTR) sPathString;
634                                } else
635                                {
636                                        CString sFilter;
637                                        CFileDialog Dialog(FALSE, _T("grf"), NULL, OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_EXPLORER | OFN_ENABLESIZING, GetLegacyFilter(g_pFilter, sFilter));
638                                        if(Dialog.DoModal(m_hWnd) != IDOK)
639                                                return 0;
640                                        sPath = Dialog.m_szFileName;
641                                }
642                                #pragma region Save
643                                // NOTE: See http://msdn.microsoft.com/en-us/library/windows/desktop/dd377551
644                                const CComQIPtr<IPersistStream> pPersistStream = m_pOwner->m_Owner.GetFilterGraph();
645                                __D(pPersistStream, E_NOINTERFACE);
646                                CComPtr<IStorage> pStorage;
647                                {
648                                        __C(StgCreateDocfile(CStringW(sPath), STGM_CREATE | STGM_TRANSACTED | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &pStorage));
649                                        CComPtr<IStream> pStream;
650                                        __C(pStorage->CreateStream(L"ActiveMovieGraph", STGM_WRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE, 0, 0, &pStream));
651                                        __C(pPersistStream->Save(pStream, TRUE));
652                                }
653                                __C(pStorage->Commit(STGC_DEFAULT));
654                                #pragma endregion
655                                MessageBeep(MB_OK);
656                                return 0;
657                        }
658                        LRESULT OnOpenGsn(UINT, INT, HWND)
659                        {
660                                OpenMonikerWithGsn(m_sFilterGraphMonikerDisplayName, m_hWnd);
661                                return 0;
662                        }
663                        LRESULT OnOpenGe(UINT, INT, HWND)
664                        {
665                                OpenMonikerWithGe(m_sFilterGraphMonikerDisplayName, m_hWnd);
666                                return 0;
667                        }
668                        LRESULT OnOpenList(UINT, INT, HWND)
669                        {
670                                DoFilterGraphListPropertySheetModal(m_hWnd);
671                                return 0;
672                        }
673                };
674
675                ////////////////////////////////////////////////////
676                // CEmailLogDialog
677
678                class CEmailLogDialog :
679                        public CDialogImpl<CEmailLogDialog>,
680                        public CDialogResize<CEmailLogDialog>
681                {
682                public:
683                        enum { IDD = IDD_FILTERGRAPHHELPER_EMAIL_LOG };
684
685                BEGIN_MSG_MAP_EX(CEmailLogDialog)
686                        //CHAIN_MSG_MAP(CDialogImpl<CEmailLogDialog>)
687                        CHAIN_MSG_MAP(CDialogResize<CEmailLogDialog>)
688                        MSG_WM_INITDIALOG(OnInitDialog)
689                        MSG_LVN_GETDISPINFO(IDC_FILTERGRAPHHELPER_EMAIL_LOG_FILE, OnFileListViewGetDispInfo)
690                        //MSG_LVN_GETINFOTIP()
691                        MSG_LVN_ITEMCHANGED(IDC_FILTERGRAPHHELPER_EMAIL_LOG_FILE, OnFileListViewItemChanged)
692                        //COMMAND_HANDLER_EX(IDC_FILTERGRAPHHELPER_EMAIL_LOG_TRUNCATE, CBN_CHANGE, OnChanged)
693                        //COMMAND_HANDLER_EX(IDC_FILTERGRAPHHELPER_EMAIL_LOG_DELETE, CBN_CHANGE, OnChanged)
694                        REFLECT_NOTIFICATIONS()
695                END_MSG_MAP()
696
697                BEGIN_DLGRESIZE_MAP(CEmailLogDialog)
698                        DLGRESIZE_CONTROL(IDC_FILTERGRAPHHELPER_EMAIL_LOG_FILE, DLSZ_SIZE_X | DLSZ_SIZE_Y)
699                        DLGRESIZE_CONTROL(IDC_FILTERGRAPHHELPER_EMAIL_LOG_TRUNCATETITLE, DLSZ_MOVE_Y)
700                        DLGRESIZE_CONTROL(IDC_FILTERGRAPHHELPER_EMAIL_LOG_TRUNCATE, DLSZ_MOVE_Y)
701                        DLGRESIZE_CONTROL(IDC_FILTERGRAPHHELPER_EMAIL_LOG_DELETETITLE, DLSZ_MOVE_Y)
702                        DLGRESIZE_CONTROL(IDC_FILTERGRAPHHELPER_EMAIL_LOG_DELETE, DLSZ_MOVE_Y)
703                END_DLGRESIZE_MAP()
704
705                public:
706
707                        ////////////////////////////////////////////////
708                        // CFileData
709
710                        class CFileData
711                        {
712                        public:
713                                UINT m_nLocation;
714                                CPath m_sPath;
715                                ULONGLONG m_nSize;
716                                FILETIME m_UpdateTime;
717
718                        public:
719                        // CFileData
720                                CFileData(UINT nLocation, LPCTSTR pszDirectory, WIN32_FIND_DATA FindData)
721                                {
722                                        m_nLocation = nLocation;
723                                        m_sPath.Combine(pszDirectory, FindData.cFileName);
724                                        m_nSize = ((ULONGLONG) FindData.nFileSizeHigh << 32) + FindData.nFileSizeLow;
725                                        m_UpdateTime = FindData.ftLastWriteTime;
726                                }
727                                FILETIME GetLocalUpdateTime() const
728                                {
729                                        FILETIME UpdateTime;
730                                        _W(FileTimeToLocalFileTime(&m_UpdateTime, &UpdateTime));
731                                        return UpdateTime;
732                                }
733                        };
734
735                        ////////////////////////////////////////////////
736                        // CFileDataSortTraits
737
738                        class CFileDataSortTraits :
739                                public CDefaultSortTraitsT<CFileData>
740                        {
741                        public:
742                        // CFileDataSortTraits
743                                static INT_PTR CompareElements(const CFileData& FileData1, const CFileData& FileData2, PARAMETERARGUMENT Parameter)
744                                {
745                                        const INT nLocation = FileData1.m_nLocation - FileData2.m_nLocation;
746                                        if(nLocation)
747                                                return nLocation;
748                                        return _tcsicmp(FindFileName(FileData1.m_sPath), FindFileName(FileData2.m_sPath));
749                                }
750                        };
751
752                        ////////////////////////////////////////////////
753                        // CFileDataArray
754
755                        class CFileDataArray :
756                                public CRoArrayT<CFileData>
757                        {
758                        public:
759                        // CFileDataArray
760                                static BOOL CompareLocation(const CFileData& FileData, UINT nLocation)
761                                {
762                                        return FileData.m_nLocation == nLocation;
763                                }
764                                SIZE_T GetCountForLocation(UINT nLocation)
765                                {
766                                        return GetCountThatT<UINT>(&CFileDataArray::CompareLocation, nLocation);
767                                }
768                        };
769
770                        ////////////////////////////////////////////////
771                        // CSelectedFileData
772
773                        class CSelectedFileData
774                        {
775                        public:
776                                CPath m_sPath;
777                                CString m_sName;
778
779                        public:
780                        // CSelectedFileData
781                        };
782
783                private:
784                        CPropertyFrameDialog* m_pOwner;
785                        BOOL m_bActivating;
786                        CStatic m_TitleStatic;
787                        CFont m_TitleFont;
788                        CRoListViewT<CFileData, CRoListControlDataTraitsT> m_FileListView;
789                        INT m_nFileListViewGroupViewEnabled;
790                        CRoComboBoxT<> m_TruncateComboBox;
791                        CRoComboBoxT<> m_DeleteComboBox;
792                        CRoMapT<INT_PTR, BOOL> m_ChangeMap;
793
794                public:
795                // CEmailLogDialog
796                        CEmailLogDialog()
797                        {
798                        }
799                        VOID UpdateControls()
800                        {
801                        }
802                        VOID InitializeFileListView()
803                        {
804                                CWindowRedraw FileListViewRedraw(m_FileListView);
805                                m_FileListView.DeleteAllItems();
806                                m_FileListView.RemoveAllGroups();
807                                #pragma region File
808                                CFileDataArray FileDataArray;
809                                static DWORD g_pnLocations[] = 
810                                {
811                                        CSIDL_COMMON_APPDATA,
812                                        CSIDL_APPDATA,
813                                };
814                                for(SIZE_T nLocationIndex = 0; nLocationIndex < DIM(g_pnLocations); nLocationIndex++)
815                                        _ATLTRY
816                                        {
817                                                TCHAR pszDirectory[MAX_PATH] = { 0 };
818                                                if(!SHGetSpecialFolderPath(NULL, pszDirectory, g_pnLocations[nLocationIndex], FALSE))
819                                                        continue;
820                                                CFindFiles FindFiles;
821                                                for(BOOL bFound = FindFiles.FindFirstFile(pszDirectory, _T("*.*")); bFound; bFound = FindFiles.FindNextFile())
822                                                {
823                                                        const WIN32_FIND_DATA& Data = FindFiles.GetFindData();
824                                                        if(Data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
825                                                                continue; // Directory
826                                                        LPCTSTR pszExtension = FindExtension(Data.cFileName);
827                                                        if(!pszExtension || !(_tcsicmp(pszExtension, _T(".log")) == 0 || _tcsicmp(pszExtension, _T(".dmp")) == 0))
828                                                                continue; // Extension Mismatch
829                                                        FileDataArray.Add(CFileData((UINT) nLocationIndex, pszDirectory, Data));
830                                                }
831                                        }
832                                        _ATLCATCHALL()
833                                        {
834                                                _Z_EXCEPTION();
835                                        }
836                                _SortHelper::QuickSort<CFileDataSortTraits>(FileDataArray);
837                                if(m_nFileListViewGroupViewEnabled >= 0)
838                                {
839                                        if(FileDataArray.GetCountForLocation(0))
840                                                m_FileListView.InsertGroup(0, 0, _T("Local Machine (Common AppData)"));
841                                        if(FileDataArray.GetCountForLocation(1))
842                                                m_FileListView.InsertGroup(1, 1, _T("Current User (AppData)"));
843                                }
844                                CPath sPrivateLogFileName = FindFileName(GetModulePath());
845                                sPrivateLogFileName.RenameExtension(_T(".log"));
846                                for(SIZE_T nIndex = 0; nIndex < FileDataArray.GetCount(); nIndex++)
847                                {
848                                        CFileData& FileData = FileDataArray[nIndex];
849                                        INT nItem;
850                                        if(m_nFileListViewGroupViewEnabled >= 0)
851                                                nItem = m_FileListView.InsertGroupItem(m_FileListView.GetItemCount(), FileData.m_nLocation, FileData);
852                                        else
853                                                nItem = m_FileListView.InsertItem(m_FileListView.GetItemCount(), FileData);
854                                        if(_tcsicmp(FindFileName(FileData.m_sPath), sPrivateLogFileName) == 0)
855                                                m_FileListView.SetCheckState(nItem, TRUE);
856                                }
857                        }
858                        SIZE_T GetFiles(CRoArrayT<CSelectedFileData>& Array)
859                        {
860                                _A(Array.IsEmpty());
861                                for(INT nItem = 0; nItem < m_FileListView.GetItemCount(); nItem++)
862                                {
863                                        if(!m_FileListView.GetCheckState(nItem))
864                                                continue;
865                                        const CFileData& FileData = m_FileListView.GetItemData(nItem);
866                                        CSelectedFileData SelectedFileData;
867                                        SelectedFileData.m_sPath = FileData.m_sPath;
868                                        CPath sName = FindFileName(FileData.m_sPath);
869                                        if(FileData.m_nLocation == 1)
870                                        {
871                                                CString sExtention = FindExtension(sName);
872                                                sName.RemoveExtension();
873                                                sName = (LPCTSTR) AtlFormatString(_T("%s (%s)%s"), sName, _T("Current User"), sExtention);
874                                        }
875                                        SelectedFileData.m_sName = (LPCTSTR) sName;
876                                        Array.Add(SelectedFileData);
877                                }
878                                return Array.GetCount();
879                        }
880                        ULONGLONG GetTruncateSize()
881                        {
882                                static const ULONGLONG g_pnTruncateSizes[] = 
883                                {
884                                         1i64 << 20, //  1 MB
885                                        10i64 << 20, // 10 MB
886                                        25i64 << 20, // 25 MB
887                                        50i64 << 20, // 50 MB
888                                };
889                                const INT nItem = m_TruncateComboBox.GetCurSel();
890                                _A(nItem >= 0 && nItem < DIM(g_pnTruncateSizes));
891                                return g_pnTruncateSizes[nItem];
892                        }
893                        BOOL GetDelete()
894                        {
895                                return m_DeleteComboBox.GetCurSel() == 1;
896                        }
897
898                // Window Message Handler
899                        LRESULT OnInitDialog(HWND, LPARAM lParam)
900                        {
901                                m_pOwner = (CPropertyFrameDialog*) lParam;
902                                m_bActivating = TRUE;
903                                _ATLTRY
904                                {
905                                        CWaitCursor WaitCursor;
906                                        m_TitleStatic = GetDlgItem(IDC_FILTERGRAPHHELPER_EMAIL_LOG_TITLE);
907                                        CreateTitleFont(m_TitleFont, m_TitleStatic);
908                                        m_FileListView.Initialize(GetDlgItem(IDC_FILTERGRAPHHELPER_EMAIL_LOG_FILE));
909                                        m_nFileListViewGroupViewEnabled = m_FileListView.EnableGroupView(TRUE);
910                                        m_TruncateComboBox.Initialize(GetDlgItem(IDC_FILTERGRAPHHELPER_EMAIL_LOG_TRUNCATE));
911                                        m_DeleteComboBox.Initialize(GetDlgItem(IDC_FILTERGRAPHHELPER_EMAIL_LOG_DELETE));
912                                        DlgResize_Init(FALSE, FALSE);
913                                        InitializeFileListView();
914                                        m_FileListView.SetColumnWidth(3, LVSCW_AUTOSIZE);
915                                        m_TruncateComboBox.SetCurSel(2);
916                                        m_DeleteComboBox.SetCurSel(0);
917                                        UpdateControls();
918                                        m_bActivating = FALSE;
919                                }
920                                _ATLCATCH(Exception)
921                                {
922                                        for(CWindow Window = GetWindow(GW_CHILD); Window; Window = Window.GetWindow(GW_HWNDNEXT))
923                                                Window.EnableWindow(FALSE);
924                                        AtlExceptionMessageBox(m_hWnd, Exception);
925                                }
926                                return TRUE;
927                        }
928                        LRESULT OnChanged(UINT, INT_PTR nIdentifier, HWND)
929                        {
930                                if(m_bActivating)
931                                        return 0;
932                                m_ChangeMap[nIdentifier] = TRUE;
933                                UpdateControls();
934                                return 0;
935                        }
936                        LRESULT OnChanged(NMHDR* pHeader)
937                        {
938                                return OnChanged(pHeader->code, pHeader->idFrom, pHeader->hwndFrom);
939                        }
940                        LRESULT OnFileListViewGetDispInfo(NMLVDISPINFO* pHeader)
941                        {
942                                const CFileData& FileData = m_FileListView.DataFromParameter(pHeader->item.lParam);
943                                if(pHeader->item.mask & LVIF_TEXT)
944                                {
945                                        CString& sTextBuffer = m_FileListView.GetTextBufferString(TRUE);
946                                        switch(pHeader->item.iSubItem)
947                                        {
948                                        case 1: // Size
949                                                sTextBuffer = _StringHelper::FormatNumber((LONGLONG) FileData.m_nSize);
950                                                break;
951                                        case 2: // Update Time
952                                                sTextBuffer = _StringHelper::FormatDateTime(FileData.GetLocalUpdateTime());
953                                                break;
954                                        case 3: // Directory
955                                                sTextBuffer = (LPCTSTR) GetPathDirectory(FileData.m_sPath);
956                                                break;
957                                        default: // File Name
958                                                sTextBuffer = FindFileName(FileData.m_sPath);
959                                        }
960                                        pHeader->item.pszText = m_FileListView.GetTextBuffer();
961                                }
962                                return 0;
963                        }
964                        LRESULT OnFileListViewItemChanged(NMLISTVIEW* pHeader)
965                        {
966                                return m_FileListView.OnReflectedItemChanged(pHeader);
967                        }
968                };
969
970                ////////////////////////////////////////////////////
971                // CEmailDialog
972
973                class CEmailDialog :
974                        public CDialogImpl<CEmailDialog>,
975                        public CDialogResize<CEmailDialog>
976                {
977                public:
978                        enum { IDD = IDD_FILTERGRAPHHELPER_EMAIL };
979
980                BEGIN_MSG_MAP_EX(CEmailDialog)
981                        //CHAIN_MSG_MAP(CDialogImpl<CEmailDialog>)
982                        CHAIN_MSG_MAP(CDialogResize<CEmailDialog>)
983                        MSG_WM_INITDIALOG(OnInitDialog)
984                        MSG_WM_DESTROY(OnDestroy)
985                        MSG_WM_SHOWWINDOW(OnShowWindow)
986                        COMMAND_HANDLER_EX(IDC_FILTERGRAPHHELPER_EMAIL_FROM, EN_CHANGE, OnChanged)
987                        COMMAND_HANDLER_EX(IDC_FILTERGRAPHHELPER_EMAIL_TO, EN_CHANGE, OnChanged)
988                        COMMAND_HANDLER_EX(IDC_FILTERGRAPHHELPER_EMAIL_METHOD, CBN_SELENDOK, OnChanged)
989                        COMMAND_HANDLER_EX(IDC_FILTERGRAPHHELPER_EMAIL_HOST, EN_CHANGE, OnChanged)
990                        COMMAND_HANDLER_EX(IDC_FILTERGRAPHHELPER_EMAIL_USERNAME, EN_CHANGE, OnChanged)
991                        COMMAND_HANDLER_EX(IDC_FILTERGRAPHHELPER_EMAIL_PASSWORD, EN_CHANGE, OnChanged)
992                        COMMAND_HANDLER_EX(IDC_FILTERGRAPHHELPER_EMAIL_BODY, EN_CHANGE, OnChanged)
993                        COMMAND_ID_HANDLER_EX(IDC_FILTERGRAPHHELPER_EMAIL_SEND, OnSend)
994                        NOTIFY_HANDLER_EX(IDC_FILTERGRAPHHELPER_EMAIL_CLEANUP, CRoHyperStatic::NC_ANCHORCLICKED, OnCleanupStaticAnchorClicked)
995                        REFLECT_NOTIFICATIONS()
996                ALT_MSG_MAP(IDC_FILTERGRAPHHELPER_EMAIL_FROM)
997                        MSG_WM_PASTE(OnFromEditPaste)
998                END_MSG_MAP()
999
1000                BEGIN_DLGRESIZE_MAP(CEmailDialog)
1001                        DLGRESIZE_CONTROL(IDC_FILTERGRAPHHELPER_EMAIL_BODY, DLSZ_SIZE_X | DLSZ_SIZE_Y)
1002                        DLGRESIZE_CONTROL(IDC_FILTERGRAPHHELPER_EMAIL_SEND, DLSZ_MOVE_X | DLSZ_MOVE_Y)
1003                        DLGRESIZE_CONTROL(IDC_FILTERGRAPHHELPER_EMAIL_CLEANUP, DLSZ_MOVE_Y)
1004                END_DLGRESIZE_MAP()
1005
1006                private:
1007                        CPropertyFrameDialog* m_pOwner;
1008                        BOOL m_bActivating;
1009                        CStatic m_TitleStatic;
1010                        CFont m_TitleFont;
1011                        CContainedWindowT<CRoEdit> m_FromEdit;
1012                        CRoEdit m_ToEdit;
1013                        CRoComboBoxT<> m_MethodComboBox;
1014                        CRoEdit m_HostEdit;
1015                        CRoEdit m_UsernameEdit;
1016                        CRoEdit m_PasswordEdit;
1017                        CRoEdit m_BodyEdit;
1018                        CButton m_SendButton;
1019                        CRoHyperStatic m_CleanupStatic;
1020                        CString m_sFilterGraphText;
1021                        CRoMapT<INT_PTR, BOOL> m_ChangeMap;
1022
1023                public:
1024                // CEmailDialog
1025                        CEmailDialog() :
1026                                m_FromEdit(this, IDC_FILTERGRAPHHELPER_EMAIL_FROM)
1027                        {
1028                        }
1029                        BOOL InitializeControlsFromMessageString(const CString& sMessageString)
1030                        {
1031                                _ATLTRY
1032                                {
1033                                        CObjectPtr<CMessage> pMessage;
1034                                        pMessage.Construct();
1035                                        pMessage->LoadTypeInfo(IDR_EMAILTOOLS);
1036                                        pMessage->SetAsString(CStringA(sMessageString));
1037                                        #pragma region Sender and Recipients
1038                                        CComBSTR sSender, sToRecipients;
1039                                        __C(pMessage->get_Sender(&sSender));
1040                                        __C(pMessage->get_ToRecipients(&sToRecipients));
1041                                        m_FromEdit.SetValue(CString(sSender));
1042                                        m_ToEdit.SetValue(CString(sToRecipients));
1043                                        #pragma endregion
1044                                        CComBSTR sAuthMethods;
1045                                        __C(pMessage->get_AuthMethods(&sAuthMethods));
1046                                        VARIANT_BOOL bSecureSocketsLayer, bTransportLayerSecurity;
1047                                        __C(pMessage->get_SecureSocketsLayer(&bSecureSocketsLayer));
1048                                        __C(pMessage->get_TransportLayerSecurity(&bTransportLayerSecurity));
1049                                        #pragma region Host and Port
1050                                        CComBSTR sHost;
1051                                        __C(pMessage->get_ServerHost(&sHost));
1052                                        LONG nPort = 0;
1053                                        __C(pMessage->get_ServerPort(&nPort));
1054                                        CString sHostT(sHost);
1055                                        if(nPort)
1056                                                sHostT += AtlFormatString(_T(":%d"), nPort);
1057                                        m_HostEdit.SetValue(sHostT);
1058                                        #pragma endregion
1059                                        #pragma region User Name and Password
1060                                        CComBSTR sAuthName, sAuthPassword;
1061                                        __C(pMessage->get_AuthName(&sAuthName));
1062                                        __C(pMessage->get_AuthPassword(&sAuthPassword));
1063                                        m_UsernameEdit.SetValue(CString(sAuthName));
1064                                        m_PasswordEdit.SetValue(CString(sAuthPassword));
1065                                        #pragma endregion
1066                                        m_MethodComboBox.SetCurSel(0);
1067                                        if(bTransportLayerSecurity != ATL_VARIANT_FALSE && sHostT.CompareNoCase(_T("smtp.gmail.com")) == 0)
1068                                        {
1069                                                //m_MethodComboBox.SetCurSel(0);
1070                                        } else
1071                                        {
1072                                                if(bTransportLayerSecurity != ATL_VARIANT_FALSE)
1073                                                        m_MethodComboBox.SetCurSel(1);
1074                                                else if(bSecureSocketsLayer != ATL_VARIANT_FALSE)
1075                                                        m_MethodComboBox.SetCurSel(2);
1076                                                else if(CString(sAuthMethods).CompareNoCase(_T("cram-md5")) == 0)
1077                                                        m_MethodComboBox.SetCurSel(3);
1078                                                else if(!CString(sAuthName).IsEmpty())
1079                                                        m_MethodComboBox.SetCurSel(4);
1080                                                else
1081                                                        m_MethodComboBox.SetCurSel(5);
1082                                        }
1083                                }
1084                                _ATLCATCHALL()
1085                                {
1086                                        _Z_EXCEPTION();
1087                                        return FALSE;
1088                                }
1089                                return TRUE;
1090                        }
1091                        VOID InitializeControlsFromRegistry()
1092                        {
1093                                const CString sMessageString = _RegKeyHelper::QueryStringValue(HKEY_CURRENT_USER, REGISTRY_ROOT, _T("Email Message Template"));
1094                                if(sMessageString.IsEmpty())
1095                                        return;
1096                                InitializeControlsFromMessageString(sMessageString);
1097                        }
1098                        VOID InitializeBody()
1099                        {
1100                                CString sText;
1101                                sText += _T("(add notes here; graph data will be appended below)") _T("\r\n") _T("\r\n");
1102                                sText += _T("* * *") _T("\r\n") _T("\r\n");
1103                                #define I FormatIdentifier
1104                                #pragma region System
1105                                {
1106                                        sText += _T("# System") _T("\r\n") _T("\r\n");
1107                                        OSVERSIONINFOEX Version;
1108                                        ZeroMemory(&Version, sizeof Version);
1109                                        Version.dwOSVersionInfoSize = sizeof Version;
1110                                        GetVersionEx((OSVERSIONINFO*) &Version);
1111                                        #pragma region Version
1112                                        CRoArrayT<CString> VersionArray;
1113                                        VersionArray.Add(AtlFormatString(_T("%s Build %s"), I(AtlFormatString(_T("%d.%d"), Version.dwMajorVersion, Version.dwMinorVersion)), I(Version.dwBuildNumber)));
1114                                        switch((Version.dwMajorVersion << 16) + Version.dwMinorVersion)
1115                                        {
1116                                        case 0x00050001: 
1117                                                VersionArray.Add(_T("Windows XP"));
1118                                                break;
1119                                        case 0x00050002: 
1120                                                if(Version.wProductType != VER_NT_WORKSTATION)
1121                                                        VersionArray.Add(_T("Windows Server 2003"));
1122                                                break;
1123                                        case 0x00060000: 
1124                                                if(Version.wProductType == VER_NT_WORKSTATION)
1125                                                        VersionArray.Add(_T("Windows Vista"));
1126                                                else
1127                                                        VersionArray.Add(_T("Windows Server 2008"));
1128                                                break;
1129                                        case 0x00060001: 
1130                                                if(Version.wProductType == VER_NT_WORKSTATION)
1131                                                        VersionArray.Add(_T("Windows 7"));
1132                                                else
1133                                                        VersionArray.Add(_T("Windows Server 2008 R2"));
1134                                                break;
1135                                        case 0x00060002: 
1136                                                if(Version.wProductType == VER_NT_WORKSTATION)
1137                                                        VersionArray.Add(_T("Windows 8"));
1138                                                else
1139                                                        VersionArray.Add(_T("Windows Server 2012"));
1140                                                break;
1141                                        }
1142                                        if(_tcslen(Version.szCSDVersion))
1143                                                VersionArray.Add(Version.szCSDVersion);
1144                                        if(Version.wServicePackMajor)
1145                                                VersionArray.Add(AtlFormatString(_T("Service Pack %s"), I(AtlFormatString(_T("%d.%d"), Version.wServicePackMajor, Version.wServicePackMinor))));
1146                                        //Version.wSuiteMask, Version.wProductType
1147                                        sText += AtlFormatString(_T(" * ") _T("Version: %s") _T("\r\n"), _StringHelper::Join(VersionArray, _T("; ")));
1148                                        #pragma endregion
1149                                        sText += AtlFormatString(_T(" * ") _T("Computer Name: %s") _T("\r\n"), I(GetComputerName()));
1150                                        TCHAR pszUserName[256] = { 0 };
1151                                        DWORD nUserNameLength = DIM(pszUserName);
1152                                        GetUserName(pszUserName, &nUserNameLength);
1153                                        CString sUserName(pszUserName);
1154                                        BOOL bAdministrator = FALSE;
1155                                        bool bIsMember = FALSE;
1156                                        if(CAccessToken().CheckTokenMembership(Sids::Admins(), &bIsMember) && bIsMember)
1157                                                bAdministrator = TRUE;
1158                                        sText += AtlFormatString(_T(" * ") _T("User Name: %s %s") _T("\r\n"), I(sUserName), bAdministrator ? _T("(Administrator)") : _T(""));
1159                                        SYSTEM_INFO SystemInformation;
1160                                        GetSystemInfo(&SystemInformation);
1161                                        #pragma region Architecture
1162                                        CString sArchitecture;
1163                                        switch(SystemInformation.wProcessorArchitecture)
1164                                        {
1165                                        case PROCESSOR_ARCHITECTURE_INTEL:
1166                                                sArchitecture = I(_T("x86"));
1167                                                break;
1168                                        case PROCESSOR_ARCHITECTURE_AMD64:
1169                                                sArchitecture = I(_T("AMD/Intel x64"));
1170                                                break;
1171                                        case PROCESSOR_ARCHITECTURE_IA64:
1172                                                sArchitecture = I(_T("Intel Itanium"));
1173                                                break;
1174                                        default:
1175                                                sArchitecture = I(SystemInformation.wProcessorArchitecture, _T("0x%04X"));
1176                                        }
1177                                        #if defined(_WIN64)
1178                                                sText += AtlFormatString(_T(" * ") _T("Architecture: %s (x64 Application)") _T("\r\n"), sArchitecture);
1179                                        #else
1180                                                sText += AtlFormatString(_T(" * ") _T("Architecture: %s") _T("\r\n"), sArchitecture);
1181                                        #endif // defined(_WIN64)
1182                                        #pragma endregion
1183                                        sText += AtlFormatString(_T(" * ") _T("Processors: %s, Active Mask %s") _T("\r\n"), I(SystemInformation.dwNumberOfProcessors), I((DWORD) SystemInformation.dwActiveProcessorMask, _T("0x%X")));
1184                                        sText += AtlFormatString(_T(" * ") _T("Page Size: %s") _T("\r\n"), I(SystemInformation.dwPageSize, _T("0x%X")));
1185                                        sText += AtlFormatString(_T(" * ") _T("Application Address Space: %s..%s") _T("\r\n"), I(SystemInformation.lpMinimumApplicationAddress), I(SystemInformation.lpMaximumApplicationAddress));
1186                                        #pragma region Memory
1187                                        MEMORYSTATUSEX MemoryStatus = { sizeof MemoryStatus };
1188                                        _W(GlobalMemoryStatusEx(&MemoryStatus));
1189                                        sText += AtlFormatString(_T(" * ") _T("Physical Memory: %s MB") _T("\r\n"), I(_StringHelper::FormatNumber((LONG) (MemoryStatus.ullTotalPhys >> 20))));
1190                                        sText += AtlFormatString(_T(" * ") _T("Committed Memory Limit: %s MB") _T("\r\n"), I(_StringHelper::FormatNumber((LONG) (MemoryStatus.ullTotalPageFile >> 20))));
1191                                        #pragma endregion
1192                                }
1193                                #pragma endregion
1194                                sText += AtlFormatString(_T(" * ") _T("Module Version: %s") _T("\r\n"), I(_VersionInfoHelper::GetVersionString(_VersionInfoHelper::GetFileVersion(_VersionInfoHelper::GetModulePath()))));
1195                                SYSTEMTIME LocalTime;
1196                                GetLocalTime(&LocalTime);
1197                                sText += AtlFormatString(_T(" * ") _T("Local Time: %s") _T("\r\n"), I(_StringHelper::FormatDateTime(&LocalTime)));
1198                                sText += _T("\r\n");
1199                                #undef I
1200                                m_BodyEdit.SetValue(sText);
1201                        }
1202                        VOID UpdateControls()
1203                        {
1204                                BOOL bAllowSend = TRUE;
1205                                if(m_ToEdit.GetValue().Trim().IsEmpty())
1206                                        bAllowSend = FALSE;
1207                                const INT nMethod = m_MethodComboBox.GetCurSel();
1208                                m_HostEdit.GetWindow(GW_HWNDPREV).EnableWindow(nMethod != 0); // Google Mail
1209                                m_HostEdit.EnableWindow(nMethod != 0); // Google Mail
1210                                m_UsernameEdit.GetWindow(GW_HWNDPREV).EnableWindow(nMethod != 5); // No Authentication
1211                                m_UsernameEdit.EnableWindow(nMethod != 5); // No Authentication
1212                                m_PasswordEdit.GetWindow(GW_HWNDPREV).EnableWindow(nMethod != 5); // No Authentication
1213                                m_PasswordEdit.EnableWindow(nMethod != 5); // No Authentication
1214                                if(nMethod != 0) // Google Mail
1215                                        if(m_HostEdit.GetValue().Trim().IsEmpty())
1216                                                bAllowSend = FALSE;
1217                                if(nMethod != 5) // No Authentication
1218                                {
1219                                        if(m_UsernameEdit.GetValue().Trim().IsEmpty())
1220                                                bAllowSend = FALSE;
1221                                        if(m_PasswordEdit.GetValue().Trim().IsEmpty())
1222                                                bAllowSend = FALSE;
1223                                }
1224                                m_SendButton.EnableWindow(bAllowSend);
1225                        }
1226                        static CString GetComputerName()
1227                        {
1228                                TCHAR pszComputerName[256] = { 0 };
1229                                DWORD nComputerNameLength = DIM(pszComputerName);
1230                                ::GetComputerName(pszComputerName, &nComputerNameLength);
1231                                return pszComputerName;
1232                        }
1233
1234                // Window Message Handler
1235                        LRESULT OnInitDialog(HWND, LPARAM lParam)
1236                        {
1237                                m_pOwner = (CPropertyFrameDialog*) lParam;
1238                                m_bActivating = TRUE;
1239                                _ATLTRY
1240                                {
1241                                        CWaitCursor WaitCursor;
1242                                        m_TitleStatic = GetDlgItem(IDC_FILTERGRAPHHELPER_EMAIL_TITLE);
1243                                        CreateTitleFont(m_TitleFont, m_TitleStatic);
1244                                        _W(m_FromEdit.SubclassWindow(GetDlgItem(IDC_FILTERGRAPHHELPER_EMAIL_FROM)));
1245                                        m_ToEdit = GetDlgItem(IDC_FILTERGRAPHHELPER_EMAIL_TO);
1246                                        m_MethodComboBox.Initialize(GetDlgItem(IDC_FILTERGRAPHHELPER_EMAIL_METHOD));
1247                                        m_MethodComboBox.SetCurSel(0);
1248                                        m_HostEdit = GetDlgItem(IDC_FILTERGRAPHHELPER_EMAIL_HOST);
1249                                        m_UsernameEdit = GetDlgItem(IDC_FILTERGRAPHHELPER_EMAIL_USERNAME);
1250                                        m_PasswordEdit = GetDlgItem(IDC_FILTERGRAPHHELPER_EMAIL_PASSWORD);
1251                                        m_BodyEdit = GetDlgItem(IDC_FILTERGRAPHHELPER_EMAIL_BODY);
1252                                        m_BodyEdit.SetFont(m_pOwner->m_TextFont);
1253                                        m_SendButton = GetDlgItem(IDC_FILTERGRAPHHELPER_EMAIL_SEND);
1254                                        _W(m_CleanupStatic.SubclassWindow(GetDlgItem(IDC_FILTERGRAPHHELPER_EMAIL_CLEANUP)));
1255                                        DlgResize_Init(FALSE, FALSE);
1256                                        InitializeControlsFromRegistry();
1257                                        InitializeBody();
1258                                        m_sFilterGraphText = m_pOwner->m_Owner.GetText();
1259                                        UpdateControls();
1260                                        m_bActivating = FALSE;
1261                                }
1262                                _ATLCATCH(Exception)
1263                                {
1264                                        for(CWindow Window = GetWindow(GW_CHILD); Window; Window = Window.GetWindow(GW_HWNDNEXT))
1265                                                Window.EnableWindow(FALSE);
1266                                        AtlExceptionMessageBox(m_hWnd, Exception);
1267                                }
1268                                return TRUE;
1269                        }
1270                        LRESULT OnDestroy()
1271                        {
1272                                return 0;
1273                        }
1274                        LRESULT OnShowWindow(BOOL bShowing, INT)
1275                        {
1276                                if(bShowing && !m_ChangeMap.Lookup(IDC_FILTERGRAPHHELPER_EMAIL_BODY))
1277                                        InitializeBody();
1278                                return 0;
1279                        }
1280                        LRESULT OnChanged(UINT, INT_PTR nIdentifier, HWND)
1281                        {
1282                                if(m_bActivating)
1283                                        return 0;
1284                                m_ChangeMap[nIdentifier] = TRUE;
1285                                UpdateControls();
1286                                return 0;
1287                        }
1288                        LRESULT OnChanged(NMHDR* pHeader)
1289                        {
1290                                return OnChanged(pHeader->code, pHeader->idFrom, pHeader->hwndFrom);
1291                        }
1292                        LRESULT OnFromEditPaste()
1293                        {
1294                                _ATLTRY
1295                                {
1296                                        CString sText;
1297                                        if(GetClipboardText(m_hWnd, sText))
1298                                        {
1299                                                const INT nLength = sText.GetLength();
1300                                                if(nLength >= 128 && nLength < 8192)
1301                                                {
1302                                                        sText.Trim();
1303                                                        const BOOL bResult = InitializeControlsFromMessageString(sText);
1304                                                        UpdateControls();
1305                                                        if(bResult)
1306                                                                return 0;
1307                                                }
1308                                        }
1309                                }
1310                                _ATLCATCHALL()
1311                                {
1312                                        MessageBeep(MB_ICONERROR);
1313                                }
1314                                return 0;
1315                        }
1316                        LRESULT OnSend(UINT, INT, HWND)
1317                        {
1318                                CWaitCursor WaitCursor;
1319                                CObjectPtr<CMessage> pMessage;
1320                                pMessage.Construct();
1321                                #pragma region Setup
1322                                pMessage->LoadTypeInfo(IDR_EMAILTOOLS);
1323                                __C(pMessage->put_Sender(CComBSTR(m_FromEdit.GetValue())));
1324                                __C(pMessage->put_ToRecipients(CComBSTR(m_ToEdit.GetValue())));
1325                                // NOTE:
1326                                // 0 Google Mail (SMTP, TLS Connection)
1327                                // 1 SMTP, TLS Connection, Plain Text Authentication (TLS, PLAIN)
1328                                // 2 SMTP, SSL Connection, Plain Text Authentication (SSL, PLAIN)
1329                                // 3 SMTP, Digest Authentication (CRAM-MD5)
1330                                // 4 SMTP, Plain Text Authentication (PLAIN)
1331                                // 5 SMTP, No Authentication
1332                                const INT nMethod = m_MethodComboBox.GetCurSel();
1333                                __C(pMessage->put_SecureSocketsLayer((nMethod == 2) ? ATL_VARIANT_TRUE : ATL_VARIANT_FALSE));
1334                                __C(pMessage->put_TransportLayerSecurity((nMethod < 2) ? ATL_VARIANT_TRUE : ATL_VARIANT_FALSE));
1335                                if(nMethod != 5)
1336                                {
1337                                        __C(pMessage->put_AuthMethods(CComBSTR(_T("plain"))));
1338                                        __C(pMessage->put_AuthName(CComBSTR(m_UsernameEdit.GetValue())));
1339                                        __C(pMessage->put_AuthPassword(CComBSTR(m_PasswordEdit.GetValue())));
1340                                }
1341                                switch(nMethod)
1342                                {
1343                                case 0:
1344                                        __C(pMessage->put_ServerHost(CComBSTR(_T("smtp.gmail.com"))));
1345                                        break;
1346                                default:
1347                                        CString sHost = m_HostEdit.GetValue();
1348                                        sHost.Trim();
1349                                        const INT nPortPosition = sHost.Find(_T(":"));
1350                                        if(nPortPosition >= 0)
1351                                        {
1352                                                INT nPort;
1353                                                __D(AtlStringToInteger(sHost.Mid(nPortPosition + 1), nPort), E_UNNAMED);
1354                                                __C(pMessage->put_ServerPort(nPort));
1355                                                sHost = sHost.Left(nPortPosition);
1356                                        }
1357                                        __C(pMessage->put_ServerHost(CComBSTR(sHost)));
1358                                        break;
1359                                }
1360                                switch(nMethod)
1361                                {
1362                                case 3:
1363                                        __C(pMessage->put_AuthMethods(CComBSTR(_T("cram-md5"))));
1364                                        break;
1365                                }
1366                                #pragma endregion
1367                                CStringA sMessageString = pMessage->GetAsString();
1368                                CString sText = m_BodyEdit.GetValue();
1369                                sText.TrimRight(_T("\t\n\r "));
1370                                sText += _T("\r\n") _T("\r\n") _T("* * *") _T("\r\n") _T("\r\n");
1371                                sText += m_sFilterGraphText;
1372                                __C(pMessage->put_Body(CComBSTR(sText)));
1373                                CString sSubject = AtlFormatString(_T("DirectShow Filter Graph from %s by %s"), GetComputerName(), AtlLoadString(IDS_PROJNAME));
1374                                __C(pMessage->put_Subject(CComBSTR(sSubject)));
1375                                #pragma region Attachment
1376                                CRoArrayT<CPath> DeletePathArray;
1377                                CRoArrayT<CString> FailurePathArray;
1378                                {
1379                                        CEmailLogDialog& EmailLogDialog = m_pOwner->m_EmailLogDialog;
1380                                        CRoArrayT<CEmailLogDialog::CSelectedFileData> Array;
1381                                        if(EmailLogDialog.GetFiles(Array))
1382                                        {
1383                                                const ULONGLONG nTruncateSize = EmailLogDialog.GetTruncateSize();
1384                                                const BOOL bDelete = EmailLogDialog.GetDelete();
1385                                                for(SIZE_T nIndex = 0; nIndex < Array.GetCount(); nIndex++)
1386                                                {
1387                                                        CEmailLogDialog::CSelectedFileData& FileData = Array[nIndex];
1388                                                        _ATLTRY
1389                                                        {
1390                                                                CLocalObjectPtr<CBzip2Item> pItem;
1391                                                                pItem->LoadFromFile(FileData.m_sPath, nTruncateSize);
1392                                                                CHeapPtr<BYTE> pnData;
1393                                                                SIZE_T nDataSize;
1394                                                                pItem->GetData(pnData, nDataSize);
1395                                                                if(nDataSize)
1396                                                                {
1397                                                                        CObjectPtr<CMessage::CComAttachment> pAttachment = pMessage->GetAttachments()->Add();
1398                                                                        _ATLTRY
1399                                                                        {
1400                                                                                pAttachment->SetType(L"application/bzip2");
1401                                                                                pAttachment->SetDisposition(L"attachment");
1402                                                                                pAttachment->SetName(CStringW(FileData.m_sName + _T(".bz2")));
1403                                                                                CLocalObjectPtr<CUnmanagedMemoryStream> pStream;
1404                                                                                pStream->Initialize(pnData, nDataSize);
1405                                                                                pAttachment->LoadFromStream(pStream);
1406                                                                        }
1407                                                                        _ATLCATCHALL()
1408                                                                        {
1409                                                                                _V(pMessage->GetAttachments()->Remove(pAttachment));
1410                                                                                _ATLRETHROW;
1411                                                                        }
1412                                                                }
1413                                                                if(bDelete)
1414                                                                        DeletePathArray.Add(FileData.m_sPath);
1415                                                        }
1416                                                        _ATLCATCHALL()
1417                                                        {
1418                                                                _Z_EXCEPTION();
1419                                                                FailurePathArray.Add((LPCTSTR) FileData.m_sPath);
1420                                                        }
1421                                                }
1422                                        }
1423                                }
1424                                #pragma endregion
1425                                __C(pMessage->Send());
1426                                for(SIZE_T nIndex = 0; nIndex < DeletePathArray.GetCount(); nIndex++)
1427                                        DeleteFile(DeletePathArray[nIndex]);
1428                                _RegKeyHelper::SetStringValue(HKEY_CURRENT_USER, REGISTRY_ROOT, _T("Email Message Template"), CString(sMessageString));
1429                                if(!FailurePathArray.IsEmpty())
1430                                {
1431                                        const CString sMessage = AtlFormatString(_T("It was unable to attach the following files:") _T("\r\n\r\n") _T("%s"), _StringHelper::Join(FailurePathArray, _T("\r\n")));
1432                                        AtlMessageBoxEx(m_hWnd, (LPCTSTR) sMessage, IDS_WARNING, MB_ICONWARNING | MB_OK);
1433                                }
1434                                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);
1435                                MessageBeep(MB_OK);
1436                                return 0;
1437                        }
1438                        LRESULT OnCleanupStaticAnchorClicked(NMHDR*)
1439                        {
1440                                _RegKeyHelper::DeleteValue(HKEY_CURRENT_USER, REGISTRY_ROOT, _T("Email Message Template"));
1441                                AtlOptionalMessageBoxEx(m_hWnd, _T("CFilterGraphHelper::CPropertyFrameDialog::CEmailDialog::SavedCredentialsDeleted"), _T("Cached email credentials were removed from registry."), IDS_INFORMATION, MB_ICONINFORMATION | MB_OK);
1442                                MessageBeep(MB_OK);
1443                                return 0;
1444                        }
1445                };
1446
1447                ////////////////////////////////////////////////////
1448                // CData
1449
1450                class CData
1451                {
1452                public:
1453
1454                        /////////////////////////////////////////////////////////
1455                        // TYPE
1456
1457                        typedef enum _TYPE
1458                        {
1459                                TYPE_UNKNOWN = 0,
1460                                TYPE_FILTERS,
1461                                TYPE_FILTER,
1462                                TYPE_FILTERPROPERTYPAGE,
1463                                TYPE_ACTION,
1464                                TYPE_EMAIL,
1465                                TYPE_EMAIL_LOG,
1466                        } TYPE;
1467
1468                public:
1469                        TYPE m_Type;
1470                        CComPtr<IBaseFilter> m_pBaseFilter;
1471                        CLSID m_BaseFilterClassIdentifier;
1472                        CString m_sBaseFilterClassDescription;
1473                        CString m_sBaseFilterModulePath;
1474                        CLSID m_PropertyPageClassIdentifier;
1475                        CComPtr<IPropertyPage> m_pPropertyPage;
1476                        CObjectPtr<CPropertyPageSite> m_pSite;
1477                        BOOL m_bSiteActivated;
1478
1479                public:
1480                // CData
1481                        CData(TYPE Type = TYPE_UNKNOWN) :
1482                                m_Type(Type),
1483                                m_BaseFilterClassIdentifier(CLSID_NULL),
1484                                m_PropertyPageClassIdentifier(CLSID_NULL)
1485                        {
1486                        }
1487                        CData(IBaseFilter* pBaseFilter) :
1488                                m_Type(TYPE_FILTER),
1489                                m_pBaseFilter(pBaseFilter),
1490                                m_BaseFilterClassIdentifier(CLSID_NULL),
1491                                m_PropertyPageClassIdentifier(CLSID_NULL)
1492                        {
1493                                _ATLTRY
1494                                {
1495                                        CLSID ClassIdentifier = CLSID_NULL;
1496                                        if(SUCCEEDED(pBaseFilter->GetClassID(&ClassIdentifier)) && ClassIdentifier != CLSID_NULL)
1497                                        {
1498                                                m_BaseFilterClassIdentifier = ClassIdentifier;
1499                                                const CString sClassIdentifier(_PersistHelper::StringFromIdentifier(ClassIdentifier));
1500                                                m_sBaseFilterClassDescription = _RegKeyHelper::QueryStringValue(HKEY_CLASSES_ROOT, AtlFormatString(_T("CLSID\\%s"), sClassIdentifier));
1501                                                m_sBaseFilterModulePath = _RegKeyHelper::QueryStringValue(HKEY_CLASSES_ROOT, AtlFormatString(_T("CLSID\\%s\\InprocServer32"), sClassIdentifier));
1502                                        }
1503                                }
1504                                _ATLCATCHALL()
1505                                {
1506                                        _Z_EXCEPTION();
1507                                }
1508                        }
1509                        CData(IBaseFilter* pBaseFilter, const CLSID& PropertyPageClassIdentifier, IPropertyPage* pPropertyPage) :
1510                                m_Type(TYPE_FILTERPROPERTYPAGE),
1511                                m_pBaseFilter(pBaseFilter),
1512                                m_BaseFilterClassIdentifier(CLSID_NULL),
1513                                m_PropertyPageClassIdentifier(PropertyPageClassIdentifier),
1514                                m_pPropertyPage(pPropertyPage),
1515                                m_bSiteActivated(FALSE)
1516                        {
1517                                _A(pPropertyPage);
1518                        }
1519                        CString GetPropertyPageTitle() const
1520                        {
1521                                if(!m_pPropertyPage)
1522                                        return _T("");
1523                                PROPPAGEINFO PageInformation;
1524                                ZeroMemory(&PageInformation, sizeof PageInformation);
1525                                PageInformation.cb = sizeof PageInformation;
1526                                __C(m_pPropertyPage->GetPageInfo(&PageInformation));
1527                                CString sTitle(PageInformation.pszTitle);
1528                                CoTaskMemFree(PageInformation.pszTitle);
1529                                CoTaskMemFree(PageInformation.pszDocString);
1530                                CoTaskMemFree(PageInformation.pszHelpFile);
1531                                return sTitle;
1532                        }
1533                };
1534
1535        private:
1536                CFilterGraphHelper& m_Owner;
1537                BOOL m_bActivating; 
1538                CRoTreeViewT<CData, CRoListControlDataTraitsT> m_TreeView;
1539                CTreeItem m_FiltersItem;
1540                CTreeItem m_ActionItem;
1541                CTreeItem m_EmailItem;
1542                CTreeItem m_EmailLogItem;
1543                CTabCtrl m_Tab;
1544                CRoEdit m_TextEdit;
1545                CRect m_TextPosition;
1546                CFont m_TextFont;
1547                CButton m_OkButton;
1548                CButton m_CancelButton;
1549                CButton m_ApplyButton;
1550                CObjectPtr<CPropertyPageSite> m_pCurrentSite;
1551                CActionDialog m_ActionDialog;
1552                CEmailDialog m_EmailDialog;
1553                CEmailLogDialog m_EmailLogDialog;
1554
1555                static VOID CreateTitleFont(CFont& Font, HWND hStaticWindow = NULL)
1556                {
1557                        _A(!Font);
1558                        CLogFont LogFont;
1559                        LogFont.SetHeight(12);
1560                        LogFont.lfWeight = FW_BOLD;
1561                        _tcsncpy_s(LogFont.lfFaceName, _T("Verdana"), _TRUNCATE);
1562                        _W(Font.CreateFontIndirect(&LogFont));
1563                        if(hStaticWindow)
1564                                CStatic(hStaticWindow).SetFont(Font);
1565                }
1566
1567        public:
1568        // CPropertyFrameDialog
1569                CPropertyFrameDialog(CFilterGraphHelper* pOwner) :
1570                        m_Owner(*pOwner)
1571                {
1572                }
1573                CRect GetTextEditPosition() const
1574                {
1575                        CRect Position;
1576                        _W(m_TextEdit.GetWindowRect(Position));
1577                        _W(ScreenToClient(Position));
1578                        return Position;
1579                }
1580                VOID UpdateTree()
1581                {
1582                        CWindowRedraw TreeViewRedraw(m_TreeView);
1583                        m_TreeView.DeleteAllItems();
1584                        #pragma region Filter
1585                        CTreeItem FiltersItem = m_TreeView.InsertItem(NULL, NULL, CData(CData::TYPE_FILTERS), _T("Filters"));
1586                        _FilterGraphHelper::CFilterArray FilterArray;
1587                        _FilterGraphHelper::GetGraphFilters(m_Owner.m_pFilterGraph, FilterArray);
1588                        CTreeItem PreviousFilterItem;
1589                        for(SIZE_T nIndex = 0; nIndex < FilterArray.GetCount(); nIndex++)
1590                        {
1591                                const CComPtr<IBaseFilter>& pBaseFilter = FilterArray[nIndex];
1592                                CData Data(pBaseFilter);
1593                                CString sText(_FilterGraphHelper::GetFilterName(pBaseFilter));
1594                                if(!Data.m_sBaseFilterClassDescription.IsEmpty() && sText.Find(Data.m_sBaseFilterClassDescription) < 0)
1595                                        sText += AtlFormatString(_T(" (%s)"), Data.m_sBaseFilterClassDescription);
1596                                CTreeItem FilterItem = m_TreeView.InsertItem(FiltersItem, PreviousFilterItem, Data, sText);
1597                                PreviousFilterItem = FilterItem;
1598                                #pragma region Property Page
1599                                const CComQIPtr<ISpecifyPropertyPages> pSpecifyPropertyPages = pBaseFilter;
1600                                if(!pSpecifyPropertyPages)
1601                                        continue;
1602                                _ATLTRY
1603                                {
1604                                        CAUUID Pages;
1605                                        ZeroMemory(&Pages, sizeof Pages);
1606                                        __C(pSpecifyPropertyPages->GetPages(&Pages));
1607                                        CComHeapPtr<CLSID> pClassIdentifiers;
1608                                        pClassIdentifiers.Attach(Pages.pElems);
1609                                        CTreeItem PreviousPageItem;
1610                                        for(UINT nPageIndex = 0; nPageIndex < Pages.cElems; nPageIndex++)
1611                                        {
1612                                                const CLSID& ClassIdentifier = pClassIdentifiers[nPageIndex];
1613                                                if(ClassIdentifier == CLSID_NULL)
1614                                                        continue;
1615                                                _ATLTRY
1616                                                {
1617                                                        CComPtr<IPropertyPage> pPropertyPage;
1618                                                        __C(pPropertyPage.CoCreateInstance(ClassIdentifier));
1619                                                        CData Data(pBaseFilter, ClassIdentifier, pPropertyPage);
1620                                                        Data.m_pSite.Construct()->Initialize(this, pBaseFilter, pPropertyPage);
1621                                                        CTreeItem PageItem = m_TreeView.InsertItem(FilterItem, PreviousPageItem, Data, Data.GetPropertyPageTitle());
1622                                                        PreviousPageItem = PageItem;
1623                                                }
1624                                                _ATLCATCHALL()
1625                                                {
1626                                                        _Z_EXCEPTION();
1627                                                }
1628                                        }
1629                                        m_TreeView.Expand(FilterItem);
1630                                }
1631                                _ATLCATCHALL()
1632                                {
1633                                        _Z_EXCEPTION();
1634                                }
1635                                #pragma endregion
1636                        }
1637                        m_TreeView.Expand(FiltersItem);
1638                        m_FiltersItem.m_hTreeItem = FiltersItem;
1639                        m_FiltersItem.m_pTreeView = &m_TreeView;
1640                        #pragma endregion
1641                        CTreeItem ActionItem = m_TreeView.InsertItem(NULL, FiltersItem, CData(CData::TYPE_ACTION), _T("Action"));
1642                        m_ActionItem.m_hTreeItem = ActionItem;
1643                        m_ActionItem.m_pTreeView = &m_TreeView;
1644                        CTreeItem EmailItem = m_TreeView.InsertItem(NULL, ActionItem, CData(CData::TYPE_EMAIL), _T("Email"));
1645                        m_EmailItem.m_hTreeItem = EmailItem;
1646                        m_EmailItem.m_pTreeView = &m_TreeView;
1647                        CTreeItem EmailLogItem = m_TreeView.InsertItem(EmailItem, NULL, CData(CData::TYPE_EMAIL_LOG), _T("Log Files"));
1648                        m_EmailLogItem.m_hTreeItem = EmailLogItem;
1649                        m_EmailLogItem.m_pTreeView = &m_TreeView;
1650                        m_TreeView.Expand(EmailItem);
1651                }
1652                VOID HideCurrentSite()
1653                {
1654                        if(!m_pCurrentSite)
1655                                return;
1656                        if(m_pCurrentSite->m_pPropertyPage)
1657                                __C(m_pCurrentSite->m_pPropertyPage->Show(SW_HIDE));
1658                        m_pCurrentSite.Release();
1659                }
1660                VOID HandleStatusChange(CPropertyPageSite* pPropertyPageSite)
1661                {
1662                        _A(pPropertyPageSite);
1663                        m_ApplyButton.EnableWindow(pPropertyPageSite->IsDirty());
1664                }
1665                VOID Apply()
1666                {
1667                        if(!m_pCurrentSite || !m_pCurrentSite->m_pPropertyPage)
1668                                return;
1669                        __C(m_pCurrentSite->m_pPropertyPage->Apply());
1670                        HandleStatusChange(m_pCurrentSite);
1671                }
1672                INT_PTR DoModal(HWND hParentWindow = GetActiveWindow())
1673                {
1674                        return CDialogWithAccelerators::DoModal(hParentWindow);
1675                }
1676
1677        // CDialogResize
1678                VOID DlgResize_UpdateLayout(INT nWidth, INT nHeight)
1679                {
1680                        __super::DlgResize_UpdateLayout(nWidth, nHeight);
1681                        const CRect Position = GetTextEditPosition();
1682                        if(m_pCurrentSite && m_pCurrentSite->m_pPropertyPage)
1683                                _V(m_pCurrentSite->m_pPropertyPage->Move(Position));
1684                        _W(m_ActionDialog.SetWindowPos(NULL, Position, SWP_NOZORDER | SWP_NOACTIVATE));
1685                        _W(m_EmailDialog.SetWindowPos(NULL, Position, SWP_NOZORDER | SWP_NOACTIVATE));
1686                        _W(m_EmailLogDialog.SetWindowPos(NULL, Position, SWP_NOZORDER | SWP_NOACTIVATE));
1687                }
1688
1689        // Window Message Handler
1690                LRESULT OnInitDialog(HWND, LPARAM)
1691                {
1692                        m_bActivating = TRUE;
1693                        _ATLTRY
1694                        {
1695                                CWaitCursor WaitCursor;
1696                                #pragma region Bitness Indication
1697                                CString sCaption;
1698                                _W(GetWindowText(sCaption));
1699                                #if defined(_WIN64)
1700                                        sCaption.Append(_T(" (64-bit)"));
1701                                #else
1702                                        if(SafeIsWow64Process())
1703                                                sCaption.Append(_T(" (32-bit)"));
1704                                #endif // defined(_WIN64)
1705                                _W(SetWindowText(sCaption));
1706                                #pragma endregion
1707                                #pragma region System Menu
1708                                CMenuHandle Menu = GetSystemMenu(FALSE);
1709                                _W(Menu.AppendMenu(MF_SEPARATOR));
1710                                _W(Menu.AppendMenu(MF_STRING, ID_APP_ABOUT, _T("&About...")));
1711                                #pragma endregion
1712                                #pragma region Icon
1713                                SetIcon(AtlLoadIconImage(IDI_MODULE, LR_COLOR, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON)), TRUE);
1714                                SetIcon(AtlLoadIconImage(IDI_MODULE, LR_COLOR, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON)), FALSE);
1715                                #pragma endregion
1716                                m_TreeView.Initialize(GetDlgItem(IDC_FILTERGRAPHHELPER_PROPERTYFRAME_TREE));
1717                                m_TextEdit = GetDlgItem(IDC_FILTERGRAPHHELPER_PROPERTYFRAME_TEXT);
1718                                CRect TextPosition;
1719                                _W(m_TextEdit.GetWindowRect(TextPosition));
1720                                _W(ScreenToClient(TextPosition));
1721                                m_TextPosition = TextPosition;
1722                                CLogFont TextFont;
1723                                CFontHandle(AtlGetDefaultGuiFont()).GetLogFont(TextFont);
1724                                _tcsncpy_s(TextFont.lfFaceName, _T("Courier New"), _TRUNCATE);
1725                                TextFont.SetHeight(8);
1726                                m_TextFont = TextFont.CreateFontIndirect();
1727                                m_TextEdit.SetFont(m_TextFont);
1728                                m_OkButton = GetDlgItem(IDOK);
1729                                m_CancelButton = GetDlgItem(IDCANCEL);
1730                                m_ApplyButton = GetDlgItem(IDC_FILTERGRAPHHELPER_PROPERTYFRAME_APPLY);
1731                                __E(m_ActionDialog.Create(m_hWnd, (LPARAM) this));
1732                                __E(m_EmailDialog.Create(m_hWnd, (LPARAM) this));
1733                                __E(m_EmailLogDialog.Create(m_hWnd, (LPARAM) this));
1734                                DlgResize_Init(TRUE);
1735                                UpdateTree();
1736                                m_FiltersItem.Select();
1737                                m_FiltersItem.EnsureVisible();
1738                                CRect Position;
1739                                _W(GetWindowRect(Position));
1740                                Position.right += Position.Width() / 2;
1741                                Position.bottom += Position.Width() / 4;
1742                                _W(SetWindowPos(NULL, Position, SWP_NOMOVE | SWP_NOZORDER));
1743                                _W(CenterWindow());
1744                                m_bActivating = FALSE;
1745                        }
1746                        _ATLCATCH(Exception)
1747                        {
1748                                for(CWindow Window = GetWindow(GW_CHILD); Window; Window = Window.GetWindow(GW_HWNDNEXT))
1749                                        Window.EnableWindow(FALSE);
1750                                AtlExceptionMessageBox(m_hWnd, Exception);
1751                        }
1752                        return TRUE;
1753                }
1754                LRESULT OnDestroy()
1755                {
1756                        #pragma region Deactivate and Terminate Sites
1757                        for(POSITION Position = m_TreeView.GetDataList().GetHeadPosition(); Position; m_TreeView.GetDataList().GetNext(Position))
1758                        {
1759                                CData& Data = m_TreeView.GetDataList().GetAt(Position);
1760                                if(!Data.m_pSite)
1761                                        continue;
1762                                if(Data.m_bSiteActivated)
1763                                {
1764                                        const HRESULT nDeactivateResult = Data.m_pPropertyPage->Deactivate();
1765                                        _Z35_DSHRESULT(nDeactivateResult);
1766                                        Data.m_bSiteActivated = FALSE;
1767                                }
1768                                Data.m_pSite->Terminate();
1769                        }
1770                        #pragma endregion
1771                        return 0;
1772                }
1773                LRESULT OnTreeViewGetInfoTip(NMTVGETINFOTIP* pHeader)
1774                {
1775                        _A(pHeader);
1776                        if(!pHeader->hItem) 
1777                                return 0;
1778                        CData& Data = m_TreeView.GetItemData(pHeader->hItem);
1779                        CString sInfoTip;
1780                        if(Data.m_pBaseFilter)
1781                        {
1782                                if(!Data.m_pPropertyPage)
1783                                {
1784                                        sInfoTip.AppendFormat(_T("Name: %ls") _T("\r\n"), _FilterGraphHelper::GetFilterName(Data.m_pBaseFilter));
1785                                        if(Data.m_BaseFilterClassIdentifier != CLSID_NULL)
1786                                                sInfoTip.AppendFormat(_T("Class Identifier: %ls") _T("\r\n"), _PersistHelper::StringFromIdentifier(Data.m_BaseFilterClassIdentifier));
1787                                        if(!Data.m_sBaseFilterClassDescription.IsEmpty())
1788                                                sInfoTip.AppendFormat(_T("Class Description: %s") _T("\r\n"), Data.m_sBaseFilterClassDescription);
1789                                        if(!Data.m_sBaseFilterModulePath.IsEmpty())
1790                                                sInfoTip.AppendFormat(_T("Module Path: %s") _T("\r\n"), Data.m_sBaseFilterModulePath);
1791                                } else
1792                                {
1793                                        // TODO: ...
1794                                }
1795                        }
1796                        sInfoTip.TrimRight(_T("\t\n\r "));
1797                        _tcsncpy_s(pHeader->pszText, pHeader->cchTextMax, sInfoTip, _TRUNCATE);
1798                        #pragma region Clipboard Copy
1799                        if(GetKeyState(VK_CONTROL) < 0 && GetKeyState(VK_SHIFT) < 0)
1800                                _ATLTRY
1801                                {
1802                                        SetClipboardText(m_hWnd, sInfoTip);
1803                                        MessageBeep(MB_OK);
1804                                }
1805                                _ATLCATCHALL()
1806                                {
1807                                        _Z_EXCEPTION();
1808                                        MessageBeep(MB_ICONERROR);
1809                                }
1810                        #pragma endregion
1811                        return 0;
1812                }
1813                LRESULT OnTreeViewSelChanged(NMTREEVIEW* pHeader)
1814                {
1815                        _A(pHeader);
1816                        CTreeItem TreeItem(pHeader->itemNew.hItem);
1817                        if(TreeItem)
1818                        {
1819                                CData& Data = m_TreeView.GetItemData(TreeItem);
1820                                if(Data.m_Type != CData::TYPE_ACTION)
1821                                        m_ActionDialog.ShowWindow(SW_HIDE);
1822                                if(Data.m_Type != CData::TYPE_EMAIL)
1823                                        m_EmailDialog.ShowWindow(SW_HIDE);
1824                                if(Data.m_Type != CData::TYPE_EMAIL_LOG)
1825                                        m_EmailLogDialog.ShowWindow(SW_HIDE);
1826                                if(Data.m_pBaseFilter)
1827                                {
1828                                        if(Data.m_pPropertyPage)
1829                                        {
1830                                                m_TextEdit.ShowWindow(SW_HIDE);
1831                                                if(Data.m_pSite != m_pCurrentSite)
1832                                                        HideCurrentSite();
1833                                                if(!Data.m_bSiteActivated)
1834                                                {
1835                                                        __C(Data.m_pPropertyPage->Activate(m_hWnd, GetTextEditPosition(), TRUE));
1836                                                        Data.m_bSiteActivated = TRUE;
1837                                                } else
1838                                                        __C(Data.m_pPropertyPage->Move(GetTextEditPosition()));
1839                                                __C(Data.m_pPropertyPage->Show(SW_SHOWNORMAL));
1840                                                m_pCurrentSite = Data.m_pSite;
1841                                                HandleStatusChange(m_pCurrentSite);
1842                                        } else
1843                                        {
1844                                                CWaitCursor WaitCursor;
1845                                                HideCurrentSite();
1846                                                m_TextEdit.ShowWindow(SW_SHOW);
1847                                                CString sText;
1848                                                sText += AtlFormatString(_T("## ") _T("Filter %ls") _T("\r\n") _T("\r\n"), _FilterGraphHelper::GetFilterName(Data.m_pBaseFilter));
1849                                                sText += m_Owner.GetFilterText(Data.m_pBaseFilter);
1850                                                sText += _T("\r\n");
1851                                                #pragma region Connection
1852                                                _FilterGraphHelper::CPinArray InputPinArray, OutputPinArray;
1853                                                _FilterGraphHelper::GetFilterPins(Data.m_pBaseFilter, PINDIR_INPUT, InputPinArray);
1854                                                _FilterGraphHelper::GetFilterPins(Data.m_pBaseFilter, PINDIR_OUTPUT, OutputPinArray);
1855                                                if(!InputPinArray.IsEmpty() || !OutputPinArray.IsEmpty())
1856                                                {
1857                                                        sText += AtlFormatString(_T("## ") _T("Connections") _T("\r\n") _T("\r\n"));
1858                                                        if(!InputPinArray.IsEmpty())
1859                                                        {
1860                                                                sText += AtlFormatString(_T("### ") _T("Input") _T("\r\n") _T("\r\n"));
1861                                                                for(SIZE_T nPinIndex = 0; nPinIndex < InputPinArray.GetCount(); nPinIndex++)
1862                                                                {
1863                                                                        const CComPtr<IPin>& pInputPin = InputPinArray[nPinIndex];
1864                                                                        const CComPtr<IPin> pOutputPin = _FilterGraphHelper::GetPeerPin(pInputPin);
1865                                                                        if(!pOutputPin)
1866                                                                                continue;
1867                                                                        sText += AtlFormatString(_T(" * ") _T("%s") _T("\r\n"), m_Owner.GetConnectionText(pOutputPin, pInputPin));
1868                                                                }
1869                                                                sText += _T("\r\n");
1870                                                        }
1871                                                        if(!OutputPinArray.IsEmpty())
1872                                                        {
1873                                                                sText += AtlFormatString(_T("### ") _T("Output") _T("\r\n") _T("\r\n"));
1874                                                                for(SIZE_T nPinIndex = 0; nPinIndex < OutputPinArray.GetCount(); nPinIndex++)
1875                                                                {
1876                                                                        const CComPtr<IPin>& pOutputPin = OutputPinArray[nPinIndex];
1877                                                                        const CComPtr<IPin> pInputPin = _FilterGraphHelper::GetPeerPin(pOutputPin);
1878                                                                        if(!pInputPin)
1879                                                                                continue;
1880                                                                        sText += AtlFormatString(_T(" * ") _T("%s") _T("\r\n"), m_Owner.GetConnectionText(pOutputPin, pInputPin));
1881                                                                }
1882                                                                sText += _T("\r\n");
1883                                                        }
1884                                                }
1885                                                #pragma endregion
1886                                                #pragma region Media Type
1887                                                _FilterGraphHelper::CPinArray PinArray;
1888                                                if(_FilterGraphHelper::GetFilterPins(Data.m_pBaseFilter, PinArray))
1889                                                {
1890                                                        sText += AtlFormatString(_T("## ") _T("Media Types") _T("\r\n") _T("\r\n"));
1891                                                        for(SIZE_T nPinIndex = 0; nPinIndex < PinArray.GetCount(); nPinIndex++)
1892                                                        {
1893                                                                const CComPtr<IPin>& pPin = PinArray[nPinIndex];
1894                                                                CString sPinText = AtlFormatString(_T("%s"), FormatIdentifier(_FilterGraphHelper::GetPinFullName(pPin)));
1895                                                                const CComPtr<IPin> pPeerPin = _FilterGraphHelper::GetPeerPin(pPin);
1896                                                                if(pPeerPin)
1897                                                                        sPinText += AtlFormatString(_T(", %s"), FormatIdentifier(_FilterGraphHelper::GetPinFullName(pPeerPin)));
1898                                                                sText += AtlFormatString(_T("%d. ") _T("%s") _T("\r\n"), 1 + nPinIndex, sPinText);
1899                                                                _ATLTRY
1900                                                                {
1901                                                                        CMediaType pMediaType;
1902                                                                        if(pPeerPin)
1903                                                                                pMediaType = _FilterGraphHelper::GetPinMediaType(pPin);
1904                                                                        else
1905                                                                                pMediaType = _FilterGraphHelper::EnumerateFirstPinMediaType(pPin);
1906                                                                        if(!pMediaType)
1907                                                                                continue;
1908                                                                        sText += m_Owner.GetMediaTypeText(pMediaType);
1909                                                                }
1910                                                                _ATLCATCHALL()
1911                                                                {
1912                                                                        _Z_EXCEPTION();
1913                                                                }
1914                                                        }
1915                                                        sText += _T("\r\n");
1916                                                }
1917                                                #pragma endregion
1918                                                #pragma region Runtime Property Bag
1919                                                _ATLTRY
1920                                                {
1921                                                        const CString sPropertyBagText = CRunPropertyBagHelper::GetPropertyBagText(Data.m_pBaseFilter, CComQIPtr<ISpy>(m_Owner.m_pFilterGraph));
1922                                                        if(!sPropertyBagText.IsEmpty())
1923                                                        {
1924                                                                sText += AtlFormatString(_T("## ") _T("Runtime Properties") _T("\r\n") _T("\r\n"));
1925                                                                sText += sPropertyBagText;
1926                                                                sText += _T("\r\n");
1927                                                        }
1928                                                }
1929                                                _ATLCATCHALL()
1930                                                {
1931                                                        _Z_EXCEPTION();
1932                                                }
1933                                                #pragma endregion
1934                                                m_TextEdit.SetValue(sText);
1935                                                m_ApplyButton.EnableWindow(FALSE);
1936                                        }
1937                                } else
1938                                {
1939                                        CWaitCursor WaitCursor;
1940                                        HideCurrentSite();
1941                                        switch(Data.m_Type)
1942                                        {
1943                                        #pragma region TYPE_ACTION
1944                                        case CData::TYPE_ACTION:
1945                                                m_TextEdit.ShowWindow(SW_HIDE);
1946                                                _W(m_ActionDialog.SetWindowPos(NULL, GetTextEditPosition(), SWP_NOZORDER | SWP_SHOWWINDOW));
1947                                                break;
1948                                        #pragma endregion
1949                                        #pragma region TYPE_EMAIL
1950                                        case CData::TYPE_EMAIL:
1951                                                m_TextEdit.ShowWindow(SW_HIDE);
1952                                                _W(m_EmailDialog.SetWindowPos(NULL, GetTextEditPosition(), SWP_NOZORDER | SWP_SHOWWINDOW));
1953                                                break;
1954                                        #pragma endregion
1955                                        #pragma region TYPE_EMAIL_LOG
1956                                        case CData::TYPE_EMAIL_LOG:
1957                                                m_TextEdit.ShowWindow(SW_HIDE);
1958                                                _W(m_EmailLogDialog.SetWindowPos(NULL, GetTextEditPosition(), SWP_NOZORDER | SWP_SHOWWINDOW));
1959                                                break;
1960                                        #pragma endregion
1961                                        default:
1962                                                m_TextEdit.ShowWindow(SW_SHOW);
1963                                                m_TextEdit.SetValue(m_Owner.GetText());
1964                                                m_ActionDialog.ShowWindow(SW_HIDE);
1965                                                m_EmailDialog.ShowWindow(SW_HIDE);
1966                                                m_EmailLogDialog.ShowWindow(SW_HIDE);
1967                                        }
1968                                        m_ApplyButton.EnableWindow(FALSE);
1969                                }
1970                        } else
1971                        {
1972                                HideCurrentSite();
1973                                m_TextEdit.ShowWindow(SW_HIDE);
1974                                m_ActionDialog.ShowWindow(SW_HIDE);
1975                                m_EmailDialog.ShowWindow(SW_HIDE);
1976                                m_EmailLogDialog.ShowWindow(SW_HIDE);
1977                                m_ApplyButton.EnableWindow(FALSE);
1978                        }
1979                        return 0;
1980                }
1981                LRESULT OnTreeViewItemExplanding(NMTREEVIEW* pHeader)
1982                {
1983                        if(pHeader->action == TVE_COLLAPSE)
1984                                return TRUE; // Prevent Collapsing
1985                        return 0;
1986                }
1987                LRESULT OnTreeViewDblClk(NMHDR*)
1988                {
1989                        CTreeItem TreeItem = m_TreeView.GetSelectedItem();
1990                        if(!TreeItem)
1991                                return 0;
1992                        CData& Data = m_TreeView.GetItemData(TreeItem);
1993                        if(!Data.m_pBaseFilter)
1994                                return 0;
1995                        COlePropertyFrameDialog Dialog(Data.m_pBaseFilter);
1996                        if(!Dialog.SetObjectPages())
1997                                return 0;
1998                        Dialog.DoModal(m_hWnd);
1999                        return 0;
2000                }
2001                LRESULT OnSysCommand(UINT nCommand, CPoint)
2002                {
2003                        switch(nCommand)
2004                        {
2005                        case ID_APP_ABOUT:
2006                                {
2007                                        CAboutDialog Dialog;
2008                                        Dialog.DoModal(m_hWnd);
2009                                }
2010                                break;
2011                        default:
2012                                SetMsgHandled(FALSE);
2013                        }
2014                        return 0;
2015                }
2016                LRESULT OnOk(UINT, INT nIdentifier, HWND)
2017                {
2018                        _ATLTRY
2019                        {
2020                                #pragma region Apply All
2021                                for(POSITION Position = m_TreeView.GetDataList().GetHeadPosition(); Position; m_TreeView.GetDataList().GetNext(Position))
2022                                {
2023                                        CData& Data = m_TreeView.GetDataList().GetAt(Position);
2024                                        if(!Data.m_pSite)
2025                                                continue;
2026                                        _A(Data.m_pPropertyPage);
2027                                        if(Data.m_bSiteActivated && Data.m_pSite->IsDirty())
2028                                                __C(Data.m_pPropertyPage->Apply());
2029                                }
2030                                #pragma endregion
2031                        }
2032                        _ATLCATCH(Exception)
2033                        {
2034                                _Z_ATLEXCEPTION(Exception);
2035                                AtlMessageBoxEx(m_hWnd, (LPCTSTR) Ds::FormatResult(Exception), IDS_ERROR, MB_ICONERROR | MB_OK);
2036                                return 0;
2037                        }
2038                        EndDialog(nIdentifier);
2039                        return 0;
2040                }
2041                LRESULT OnCancel(UINT, INT nIdentifier, HWND)
2042                {
2043                        EndDialog(nIdentifier);
2044                        return 0;
2045                }
2046                LRESULT OnApply(UINT, INT, HWND)
2047                {
2048                        _ATLTRY
2049                        {
2050                                Apply();
2051                        }
2052                        _ATLCATCH(Exception)
2053                        {
2054                                _Z_ATLEXCEPTION(Exception);
2055                                AtlMessageBoxEx(m_hWnd, (LPCTSTR) Ds::FormatResult(Exception), IDS_ERROR, MB_ICONERROR | MB_OK);
2056                        }
2057                        return 0;
2058                }
2059                LRESULT OnTreeWalkUp(UINT, INT, HWND)
2060                {
2061                        CTreeItem TreeItem = m_TreeView.GetSelectedItem();
2062                        CTreeItem ParentTreeItem = TreeItem.GetParent();
2063                        if(!ParentTreeItem)
2064                                return 0;
2065                        m_TreeView.SetFocus();
2066                        m_TreeView.Select(ParentTreeItem, TVGN_CARET);
2067                        return 0;
2068                }
2069                LRESULT OnActionCommand(UINT, INT nIdentifier, HWND)
2070                {
2071                        return m_ActionDialog.SendMessage(WM_COMMAND, nIdentifier);
2072                }
2073        };
2074
2075private:
2076        mutable CRoCriticalSection m_DataCriticalSection;
2077        CProcessData m_ProcessData;
2078        CComPtr<IFilterGraph> m_pFilterGraph;
2079
2080public:
2081// CFilterGraphHelper
2082        static HRESULT WINAPI UpdateRegistry(BOOL bRegister)
2083        {
2084                _Z2(atlTraceRegistrar, 2, _T("bRegister %d\n"), bRegister);
2085                _ATLTRY
2086                {
2087                        UpdateRegistryFromResource<CFilterGraphHelper>(bRegister);
2088                }
2089                _ATLCATCH(Exception)
2090                {
2091                        _C(Exception);
2092                }
2093                return S_OK;
2094        }
2095        CFilterGraphHelper()
2096        {
2097                _Z4_THIS();
2098        }
2099        ~CFilterGraphHelper()
2100        {
2101                _Z4_THIS();
2102        }
2103        static CString FormatIdentifier(LPCSTR pszValue)
2104        {
2105                CString sText;
2106                if(pszValue && *pszValue)
2107                {
2108                        sText = _T("``");
2109                        sText.Insert(1, CString(pszValue));
2110                }
2111                return sText;
2112        }
2113        static CString FormatIdentifier(LPCWSTR pszValue)
2114        {
2115                CString sText;
2116                if(pszValue && *pszValue)
2117                {
2118                        sText = _T("``");
2119                        sText.Insert(1, CString(pszValue));
2120                }
2121                return sText;
2122        }
2123        static CString FormatIdentifier(LONG nValue)
2124        {
2125                CString sText;
2126                sText = _T("``");
2127                sText.Insert(1, _StringHelper::FormatNumber(nValue));
2128                return sText;
2129        }
2130        static CString FormatIdentifier(ULONG nValue)
2131        {
2132                return FormatIdentifier((LONG) nValue);
2133        }
2134        static CString FormatIdentifier(BOOL nValue)
2135        {
2136                return FormatIdentifier((LONG) nValue);
2137        }
2138        static CString FormatIdentifier(LONGLONG nValue)
2139        {
2140                CString sText;
2141                sText = _T("``");
2142                sText.Insert(1, _StringHelper::FormatNumber(nValue));
2143                return sText;
2144        }
2145        static CString FormatIdentifier(LONG nValue, LPCTSTR pszFormat)
2146        {
2147                CString sText;
2148                sText = _T("``");
2149                sText.Insert(1, AtlFormatString(pszFormat, nValue));
2150                return sText;
2151        }
2152        static CString FormatIdentifier(const VOID* pvValue, LPCTSTR pszFormat = _T("0x%p"))
2153        {
2154                CString sText;
2155                sText = _T("``");
2156                sText.Insert(1, AtlFormatString(pszFormat, pvValue));
2157                return sText;
2158        }
2159        #define I FormatIdentifier
2160        static CString FormatPhysicalConnectorType(PhysicalConnectorType Value)
2161        {
2162                struct 
2163                {
2164                        PhysicalConnectorType Value;
2165                        LPCSTR pszName;
2166                } g_pMap[] = 
2167                {
2168                        #define A(x) { x, #x },
2169                        A(PhysConn_Video_Tuner)
2170                        A(PhysConn_Video_Composite)
2171                        A(PhysConn_Video_SVideo)
2172                        A(PhysConn_Video_RGB)
2173                        A(PhysConn_Video_YRYBY)
2174                        A(PhysConn_Video_SerialDigital)
2175                        A(PhysConn_Video_ParallelDigital)
2176                        A(PhysConn_Video_SCSI)
2177                        A(PhysConn_Video_AUX)
2178                        A(PhysConn_Video_1394)
2179                        A(PhysConn_Video_USB)
2180                        A(PhysConn_Video_VideoDecoder)
2181                        A(PhysConn_Video_VideoEncoder)
2182                        A(PhysConn_Video_SCART)
2183                        A(PhysConn_Video_Black)
2184                        A(PhysConn_Audio_Tuner)
2185                        A(PhysConn_Audio_Line)
2186                        A(PhysConn_Audio_Mic)
2187                        A(PhysConn_Audio_AESDigital)
2188                        A(PhysConn_Audio_SPDIFDigital)
2189                        A(PhysConn_Audio_SCSI)
2190                        A(PhysConn_Audio_AUX)
2191                        A(PhysConn_Audio_1394)
2192                        A(PhysConn_Audio_USB)
2193                        A(PhysConn_Audio_AudioDecoder)
2194                        #undef A
2195                };
2196                for(SIZE_T nIndex = 0; nIndex < DIM(g_pMap); nIndex++)
2197                        if(g_pMap[nIndex].Value == Value)
2198                                return CString(g_pMap[nIndex].pszName);
2199                return AtlFormatString(_T("0x%04X"), Value);
2200        }
2201        static CString FormatPins(_FilterGraphHelper::CPinArray& PinArray)
2202        {
2203                CRoArrayT<CString> Array;
2204                for(SIZE_T nIndex  = 0; nIndex < PinArray.GetCount(); nIndex++)
2205                {
2206                        const CComPtr<IPin>& pPin = PinArray[nIndex];
2207                        CString sText = I(_FilterGraphHelper::GetPinName(pPin));
2208                        const CComPtr<IPin> pPeerPin = _FilterGraphHelper::GetPeerPin(pPin);
2209                        if(pPeerPin)
2210                                sText += AtlFormatString(_T(" (%s)"), I(_FilterGraphHelper::GetPinFullName(pPeerPin)));
2211                        Array.Add(sText);
2212                }
2213                return _StringHelper::Join(Array, _T(", "));
2214        }
2215        static CString GetFilterText(IBaseFilter* pBaseFilter, const CProcessData* pProcessData, IReferenceClock* pFilterGraphReferenceClock = NULL)
2216        {
2217                CString sText;
2218                #pragma region COM
2219                CString sPath;
2220                const CStringW sClassIdentifierString = _FilterGraphHelper::GetFilterClassIdentifierString(pBaseFilter);
2221                if(!sClassIdentifierString.IsEmpty())
2222                {
2223                        CLSID ClassIdentifier = CLSID_NULL;
2224                        const BOOL bClassIdentifierAvailable = _PersistHelper::ClassIdentifierFromString(sClassIdentifierString, ClassIdentifier);
2225                        if(bClassIdentifierAvailable && ClassIdentifier != CLSID_NULL)
2226                        {
2227                                sText += AtlFormatString(_T(" * ") _T("Class: %s %s") _T("\r\n"), I(sClassIdentifierString), I(_FilterGraphHelper::GetFilterClassDescription(pBaseFilter)));
2228                                _ATLTRY
2229                                {
2230                                        sPath = _RegKeyHelper::QueryStringValue(HKEY_CLASSES_ROOT, AtlFormatString(_T("CLSID\\%ls\\InprocServer32"), sClassIdentifierString));
2231                                        if(!sPath.IsEmpty())
2232                                        {
2233                                                sText += AtlFormatString(_T(" * ") _T("Inproc Server: %s") _T("\r\n"), I(sPath));
2234                                                const ULONGLONG nProductVersion = _VersionInfoHelper::GetProductVersion(sPath);
2235                                                if(nProductVersion && (nProductVersion + 1))
2236                                                        sText += AtlFormatString(_T(" * ") _T("Product Version: %s") _T("\r\n"), I(_VersionInfoHelper::GetVersionString(nProductVersion)));
2237                                                const ULONGLONG nFileVersion = _VersionInfoHelper::GetFileVersion(sPath);
2238                                                if(nFileVersion && (nFileVersion + 1))
2239                                                        sText += AtlFormatString(_T(" * ") _T("File Version: %s") _T("\r\n"), I(_VersionInfoHelper::GetVersionString(nFileVersion)));
2240                                        }
2241                                }
2242                                _ATLCATCHALL()
2243                                {
2244                                        _Z_EXCEPTION();
2245                                }
2246                        }
2247                }
2248                if(_tcslen(sPath) == 0 && pProcessData && pProcessData->m_nIdentifier == GetCurrentProcessId())
2249                        _ATLTRY
2250                        {
2251                                const VOID* pvVirtualTable = *((const VOID**) pBaseFilter);
2252                                MEMORY_BASIC_INFORMATION Information;
2253                                if(VirtualQueryEx(GetCurrentProcess(), pvVirtualTable, &Information, sizeof Information))
2254                                {
2255                                        TCHAR pszPath[MAX_PATH] = { 0 };
2256                                        if(GetModuleFileName((HMODULE) Information.AllocationBase, pszPath, DIM(pszPath)))
2257                                        {
2258                                                sPath = pszPath;
2259                                                sText += AtlFormatString(_T(" * ") _T("Virtual Table Location: %s") _T("\r\n"), I(sPath));
2260                                                const ULONGLONG nProductVersion = _VersionInfoHelper::GetProductVersion(sPath);
2261                                                if(nProductVersion && (nProductVersion + 1))
2262                                                        sText += AtlFormatString(_T(" * ") _T("Product Version: %s") _T("\r\n"), I(_VersionInfoHelper::GetVersionString(nProductVersion)));
2263                                                const ULONGLONG nFileVersion = _VersionInfoHelper::GetFileVersion(sPath);
2264                                                if(nFileVersion && (nFileVersion + 1))
2265                                                        sText += AtlFormatString(_T(" * ") _T("File Version: %s") _T("\r\n"), I(_VersionInfoHelper::GetVersionString(nFileVersion)));
2266                                        }
2267                                }
2268                        }
2269                        _ATLCATCHALL()
2270                        {
2271                                _Z_EXCEPTION();
2272                        }
2273                #pragma endregion
2274                #pragma region Pin
2275                _FilterGraphHelper::CPinArray InputPinArray;
2276                if(_FilterGraphHelper::GetFilterPins(pBaseFilter, PINDIR_INPUT, InputPinArray))
2277                        sText += AtlFormatString(_T(" * ") _T("Input Pins: %s") _T("\r\n"), FormatPins(InputPinArray));
2278                _FilterGraphHelper::CPinArray OutputPinArray;
2279                if(_FilterGraphHelper::GetFilterPins(pBaseFilter, PINDIR_OUTPUT, OutputPinArray))
2280                        sText += AtlFormatString(_T(" * ") _T("Output Pins: %s") _T("\r\n"), FormatPins(OutputPinArray));
2281                #pragma endregion
2282                #pragma region IReferenceClock
2283                const CComQIPtr<IReferenceClock> pReferenceClock = pBaseFilter;
2284                if(pReferenceClock)
2285                {
2286                        CRoArrayT<CString> Array;
2287                        Array.Add(I(_T("Available")));
2288                        if(pReferenceClock == pFilterGraphReferenceClock)
2289                                Array.Add(I(_T("Selected")));
2290                        sText += AtlFormatString(_T(" * ") _T("Reference Clock: %s") _T("\r\n"), _StringHelper::Join(Array, _T(", ")));
2291                }
2292                #pragma endregion
2293                #pragma region IFileSourceFilter
2294                const CComQIPtr<IFileSourceFilter> pFileSourceFilter = pBaseFilter;
2295                if(pFileSourceFilter)
2296                        _ATLTRY
2297                        {
2298                                CComHeapPtr<OLECHAR> pszFileName;
2299                                CMediaType pMediaType;
2300                                pMediaType.Allocate(MEDIATYPE_NULL, MEDIASUBTYPE_NULL);
2301                                const HRESULT nGetCurFileResult = pFileSourceFilter->GetCurFile(&pszFileName, pMediaType);
2302                                _Z45_DSHRESULT(nGetCurFileResult);
2303                                if(SUCCEEDED(nGetCurFileResult))
2304                                        sText += AtlFormatString(_T(" * ") _T("File Source: %s") _T("\r\n"), I(pszFileName));
2305                        }
2306                        _ATLCATCHALL()
2307                        {
2308                                _Z_EXCEPTION();
2309                        }
2310                #pragma endregion
2311                #pragma region IFileSinkFilter
2312                const CComQIPtr<IFileSinkFilter> pFileSinkFilter = pBaseFilter;
2313                if(pFileSinkFilter)
2314                        _ATLTRY
2315                        {
2316                                CComHeapPtr<OLECHAR> pszFileName;
2317                                CMediaType pMediaType;
2318                                pMediaType.Allocate(MEDIATYPE_NULL, MEDIASUBTYPE_NULL);
2319                                const HRESULT nGetCurFileResult = pFileSinkFilter->GetCurFile(&pszFileName, pMediaType);
2320                                _Z45_DSHRESULT(nGetCurFileResult);
2321                                if(SUCCEEDED(nGetCurFileResult))
2322                                        sText += AtlFormatString(_T(" * ") _T("File Sink: %s") _T("\r\n"), I(pszFileName));
2323                        }
2324                        _ATLCATCHALL()
2325                        {
2326                                _Z_EXCEPTION();
2327                        }
2328                #pragma endregion
2329                #pragma region IMediaSeeking
2330                const CComQIPtr<IMediaSeeking> pMediaSeeking = pBaseFilter;
2331                if(pMediaSeeking)
2332                        _ATLTRY
2333                        {
2334                                sText += AtlFormatString(_T(" * ") _T("Media Seeking/Position") _T("\r\n"));
2335                                DWORD nCapabilities = 0;
2336                                if(SUCCEEDED(pMediaSeeking->GetCapabilities(&nCapabilities)))
2337                                        sText += AtlFormatString(_T("  * ") _T("Capabilities: %s") _T("\r\n"), I(AtlFormatString(_T("0x%X"), nCapabilities)));
2338                                LONGLONG nDuration = 0, nPosition = 0, nStopPosition = 0;
2339                                if(SUCCEEDED(pMediaSeeking->GetDuration(&nDuration)))
2340                                        sText += AtlFormatString(_T("  * ") _T("Duration: %s (%s seconds)") _T("\r\n"), I(_FilterGraphHelper::FormatSecondTime((DOUBLE) nDuration / 1E7)), I(_StringHelper::FormatNumber((DOUBLE) nDuration / 1E7, 3)));
2341                                if(SUCCEEDED(pMediaSeeking->GetCurrentPosition(&nPosition)))
2342                                        sText += AtlFormatString(_T("  * ") _T("Position: %s (%s seconds)") _T("\r\n"), I(_FilterGraphHelper::FormatSecondTime((DOUBLE) nPosition / 1E7)), I(_StringHelper::FormatNumber((DOUBLE) nPosition / 1E7, 3)));
2343                                if(SUCCEEDED(pMediaSeeking->GetStopPosition(&nStopPosition)))
2344                                        sText += AtlFormatString(_T("  * ") _T("Stop Position: %s (%s seconds)") _T("\r\n"), I(_FilterGraphHelper::FormatSecondTime((DOUBLE) nStopPosition / 1E7)), I(_StringHelper::FormatNumber((DOUBLE) nStopPosition / 1E7, 3)));
2345                                DOUBLE fRate = 1.0;
2346                                if(SUCCEEDED(pMediaSeeking->GetRate(&fRate)))
2347                                        sText += AtlFormatString(_T("  * ") _T("Rate: %s") _T("\r\n"), I(_StringHelper::FormatNumber(fRate, 3)));
2348                                LONGLONG nPreroll = 0;
2349                                if(SUCCEEDED(pMediaSeeking->GetPreroll(&nPreroll)) && nPreroll)
2350                                        sText += AtlFormatString(_T("  * ") _T("Preroll: %s seconds") _T("\r\n"), I(_StringHelper::FormatNumber((DOUBLE) nPreroll / 1E7, 3)));
2351                        }
2352                        _ATLCATCHALL()
2353                        {
2354                                _Z_EXCEPTION();
2355                        }
2356                #pragma endregion
2357                #pragma region IAMCrossbar
2358                const CComQIPtr<IAMCrossbar> pAmCrossbar = pBaseFilter;
2359                if(pAmCrossbar)
2360                        _ATLTRY
2361                        {
2362                                sText += AtlFormatString(_T(" * ") _T("Crossbar:") _T("\r\n"));
2363                                LONG nOutputPinCount = 0, nInputPinCount = 0;
2364                                __C(pAmCrossbar->get_PinCounts(&nOutputPinCount, &nInputPinCount));
2365                                sText += AtlFormatString(_T("  * ") _T("Pins: %s Input, %s Output") _T("\r\n"), I(nInputPinCount), I(nOutputPinCount));
2366                                #pragma region Input
2367                                for(LONG nInputPinIndex = 0; nInputPinIndex < nInputPinCount; nInputPinIndex++)
2368                                        _ATLTRY
2369                                        {
2370                                                CRoArrayT<CString> Array;
2371                                                LONG nRelatedPinIndex = -1;
2372                                                LONG nPhysicalType = 0; // PhysicalConnectorType
2373                                                __C(pAmCrossbar->get_CrossbarPinInfo(TRUE, nInputPinIndex, &nRelatedPinIndex, &nPhysicalType));
2374                                                if(nRelatedPinIndex >= 0)
2375                                                        Array.Add(AtlFormatString(_T("Related %s"), I(nRelatedPinIndex)));
2376                                                Array.Add(AtlFormatString(_T("Physical Type %s"), I(FormatPhysicalConnectorType((PhysicalConnectorType) nPhysicalType))));
2377                                                sText += AtlFormatString(_T("  * ") _T("Input Pin %s: %s") _T("\r\n"), I(nInputPinIndex), _StringHelper::Join(Array, _T("; ")));
2378                                        }
2379                                        _ATLCATCHALL()
2380                                        {
2381                                                _Z_EXCEPTION();
2382                                        }
2383                                #pragma endregion
2384                                #pragma region Output
2385                                for(LONG nOutputPinIndex = 0; nOutputPinIndex < nOutputPinCount; nOutputPinIndex++)
2386                                        _ATLTRY
2387                                        {
2388                                                CRoArrayT<CString> Array;
2389                                                LONG nRelatedPinIndex = -1;
2390                                                LONG nPhysicalType = 0; // PhysicalConnectorType
2391                                                __C(pAmCrossbar->get_CrossbarPinInfo(FALSE, nOutputPinIndex, &nRelatedPinIndex, &nPhysicalType));
2392                                                if(nRelatedPinIndex >= 0)
2393                                                        Array.Add(AtlFormatString(_T("Related %s"), I(nRelatedPinIndex)));
2394                                                if(nPhysicalType > 0)
2395                                                        Array.Add(AtlFormatString(_T("Physical Type %s"), I(FormatPhysicalConnectorType((PhysicalConnectorType) nPhysicalType))));
2396                                                LONG nRoutedInputPinIndex = -1;
2397                                                const HRESULT nGetIsRoutedToResult = pAmCrossbar->get_IsRoutedTo(nOutputPinIndex, &nRoutedInputPinIndex);
2398                                                _A(nGetIsRoutedToResult == S_OK || nRoutedInputPinIndex == -1);
2399                                                if(nRoutedInputPinIndex >= 0)
2400                                                        Array.Add(AtlFormatString(_T("Routed to Input Pin %s"), I(nRoutedInputPinIndex)));
2401                                                CRoArrayT<CString> PinArray;
2402                                                for(LONG nInputPinIndex = 0; nInputPinIndex < nInputPinCount; nInputPinIndex++)
2403                                                {
2404                                                        const HRESULT nCanRouteResult = pAmCrossbar->CanRoute(nOutputPinIndex, nInputPinIndex);
2405                                                        if(nCanRouteResult == S_OK)
2406                                                                PinArray.Add(I(nInputPinIndex));
2407                                                }
2408                                                if(!PinArray.IsEmpty())
2409                                                        Array.Add(AtlFormatString(_T("Routeable to Input Pins %s"), _StringHelper::Join(PinArray, _T(", "))));
2410                                                sText += AtlFormatString(_T("  * ") _T("Output Pin %s: %s") _T("\r\n"), I(nOutputPinIndex), _StringHelper::Join(Array, _T("; ")));
2411                                        }
2412                                        _ATLCATCHALL()
2413                                        {
2414                                                _Z_EXCEPTION();
2415                                        }
2416                                #pragma endregion
2417                        }
2418                        _ATLCATCHALL()
2419                        {
2420                                _Z_EXCEPTION();
2421                        }
2422                #pragma endregion
2423                return sText;
2424        }
2425        static CString GetConnectionText(IPin* pOutputPin, IPin* pInputPin)
2426        {
2427                _A(pOutputPin && pInputPin);
2428                CString sText = AtlFormatString(_T("%s - %s"), I(_FilterGraphHelper::GetPinFullName(pOutputPin)), I(_FilterGraphHelper::GetPinFullName(pInputPin)));
2429                _ATLTRY
2430                {
2431                        const CMediaType pMediaType = _FilterGraphHelper::GetPinMediaType(pOutputPin);
2432                        if(pMediaType)
2433                        {
2434                                CStringW sMajorType = _FilterGraphHelper::FormatMajorType(pMediaType->majortype);
2435                                CStringW sSubtype;
2436                                if(pMediaType->subtype != MEDIASUBTYPE_NULL)
2437                                        sSubtype = _FilterGraphHelper::FormatSubtype(pMediaType->majortype, pMediaType->subtype);
2438                                CRoArrayT<CString> Array;
2439                                Array.Add(I(sMajorType));
2440                                if(!sSubtype.IsEmpty())
2441                                        Array.Add(I(sSubtype));
2442                                #pragma region MEDIATYPE_Video
2443                                if(pMediaType->majortype == MEDIATYPE_Video)
2444                                {
2445                                        const CVideoInfoHeader2 VideoInfoHeader2 = pMediaType.GetCompatibleVideoInfoHeader2();
2446                                        const CSize Extent = VideoInfoHeader2.GetExtent();
2447                                        if(Extent.cx || Extent.cy)
2448                                                Array.Add(AtlFormatString(_T("%s x %s"), I(Extent.cx), I(Extent.cy)));
2449                                        if(VideoInfoHeader2.AvgTimePerFrame > 0)
2450                                                Array.Add(AtlFormatString(_T("%s frames/sec"), I(_StringHelper::FormatNumber(1E7 / VideoInfoHeader2.AvgTimePerFrame, 3))));
2451                                } else
2452                                #pragma endregion
2453                                #pragma region MEDIATYPE_Audio
2454                                if(pMediaType->majortype == MEDIATYPE_Audio)
2455                                {
2456                                        const CWaveFormatEx* pWaveFormatEx = pMediaType.GetWaveFormatEx();
2457                                        if(pWaveFormatEx)
2458                                        {
2459                                                if(pWaveFormatEx->nSamplesPerSec)
2460                                                        Array.Add(AtlFormatString(_T("%s Hz"), I(pWaveFormatEx->nSamplesPerSec)));
2461                                                if(pWaveFormatEx->nChannels)
2462                                                        Array.Add(AtlFormatString(_T("%s channels"), I(pWaveFormatEx->nChannels)));
2463                                                if(pWaveFormatEx->wBitsPerSample)
2464                                                        Array.Add(AtlFormatString(_T("%s bits"), I(pWaveFormatEx->wBitsPerSample)));
2465                                        }
2466                                }
2467                                #pragma endregion
2468                                sText += AtlFormatString(_T(" (%s)"), _StringHelper::Join(Array, _T(", ")));
2469                        }
2470                }
2471                _ATLCATCHALL()
2472                {
2473                        _Z_EXCEPTION();
2474                }
2475                return sText;
2476        }
2477        static CString GetMediaTypeText(const CMediaType& pMediaType)
2478        {
2479                CString sText;
2480                #pragma region AM_MEDIA_TYPE
2481                #define J(x) I(pMediaType->x)
2482                #define K1(x) sText += AtlFormatString(_T(" * `") _T(#x) _T("`: %s") _T("\r\n"), J(x))
2483                sText += AtlFormatString(_T(" * ") _T("Data: %s") _T("\r\n"), I(AtlFormatData((const BYTE*) (const AM_MEDIA_TYPE*) pMediaType, sizeof *pMediaType).TrimRight()));
2484                sText += AtlFormatString(_T(" * ") _T("`majortype`: %s") _T("\r\n"), I(_FilterGraphHelper::FormatMajorType(pMediaType->majortype)));
2485                if(pMediaType->subtype != MEDIASUBTYPE_NULL)
2486                        sText += AtlFormatString(_T(" * ") _T("`subtype`: %s") _T("\r\n"), I(_FilterGraphHelper::FormatSubtype(pMediaType->majortype, pMediaType->subtype)));
2487                K1(bFixedSizeSamples);
2488                K1(bTemporalCompression);
2489                K1(lSampleSize);
2490                if(pMediaType->formattype != GUID_NULL)
2491                        sText += AtlFormatString(_T(" * ") _T("`formattype`: %s") _T("\r\n"), I(_FilterGraphHelper::FormatFormatType(pMediaType->formattype)));
2492                if(pMediaType->pUnk)
2493                        sText += AtlFormatString(_T(" * ") _T("`pUnk`: %s") _T("\r\n"), I(AtlFormatString(_T("0x%p"), pMediaType->pUnk)));
2494                if(pMediaType->cbFormat)
2495                {
2496                        K1(cbFormat);
2497                        if(pMediaType->pbFormat)
2498                                sText += AtlFormatString(_T(" * ") _T("Format Data, `pbFormat`: %s") _T("\r\n"), I(AtlFormatData(pMediaType->pbFormat, pMediaType->cbFormat).TrimRight()));
2499                }
2500                #undef J
2501                #undef K1
2502                #pragma endregion
2503                const BYTE* pnExtraData = NULL;
2504                SIZE_T nExtraDataSize = 0;
2505                #pragma region FORMAT_VideoInfo
2506                if(pMediaType->formattype == FORMAT_VideoInfo)
2507                {
2508                        sText += AtlFormatString(_T(" * ") _T("As `VIDEOINFOHEADER`:") _T("\r\n"));
2509                        const VIDEOINFOHEADER* pVideoInfoHeader = (const VIDEOINFOHEADER*) pMediaType->pbFormat;
2510                        #define J(x) I(pVideoInfoHeader->x)
2511                        #define K1(x) sText += AtlFormatString(_T("  * `") _T(#x) _T("`: %s") _T("\r\n"), J(x))
2512                        sText += AtlFormatString(_T("  * ") _T("`rcSource`: (%s, %s) - (%s, %s)") _T("\r\n"), J(rcSource.left), J(rcSource.top), J(rcSource.right), J(rcSource.bottom));
2513                        sText += AtlFormatString(_T("  * ") _T("`rcTarget`: (%s, %s) - (%s, %s)") _T("\r\n"), J(rcTarget.left), J(rcTarget.top), J(rcTarget.right), J(rcTarget.bottom));
2514                        K1(dwBitRate);
2515                        K1(dwBitErrorRate);
2516                        sText += AtlFormatString(_T("  * ") _T("`AvgTimePerFrame`: %s units") _T("\r\n"), I(_FilterGraphHelper::FormatReferenceTime(pVideoInfoHeader->AvgTimePerFrame)));
2517                        K1(bmiHeader.biSize);
2518                        K1(bmiHeader.biWidth);
2519                        K1(bmiHeader.biHeight);
2520                        K1(bmiHeader.biPlanes);
2521                        K1(bmiHeader.biBitCount);
2522                        sText += AtlFormatString(_T("  * ") _T("`bmiHeader.biCompression`: %s") _T("\r\n"), I(_FilterGraphHelper::GetFourccCodeString(pVideoInfoHeader->bmiHeader.biCompression)));
2523                        K1(bmiHeader.biSizeImage);
2524                        K1(bmiHeader.biXPelsPerMeter);
2525                        K1(bmiHeader.biYPelsPerMeter);
2526                        K1(bmiHeader.biClrUsed);
2527                        K1(bmiHeader.biClrImportant);
2528                        #undef J
2529                        #undef K1
2530                        nExtraDataSize = pMediaType->cbFormat - sizeof *pVideoInfoHeader;
2531                } else
2532                #pragma endregion
2533                #pragma region FORMAT_VideoInfo2
2534                if(pMediaType->formattype == FORMAT_VideoInfo2)
2535                {
2536                        sText += AtlFormatString(_T(" * ") _T("As `VIDEOINFOHEADER2`:") _T("\r\n"));
2537                        const VIDEOINFOHEADER2* pVideoInfoHeader2 = (const VIDEOINFOHEADER2*) pMediaType->pbFormat;
2538                        #define J(x) I(pVideoInfoHeader2->x)
2539                        #define K1(x) sText += AtlFormatString(_T("  * `") _T(#x) _T("`: %s") _T("\r\n"), J(x))
2540                        #define K2(x, y) sText += AtlFormatString(_T("  * `") _T(#x) _T("`: %s") _T("\r\n"), I(pVideoInfoHeader2->x, y))
2541                        sText += AtlFormatString(_T("  * ") _T("rcSource: (%s, %s) - (%s, %s)") _T("\r\n"), J(rcSource.left), J(rcSource.top), J(rcSource.right), J(rcSource.bottom));
2542                        sText += AtlFormatString(_T("  * ") _T("rcTarget: (%s, %s) - (%s, %s)") _T("\r\n"), J(rcTarget.left), J(rcTarget.top), J(rcTarget.right), J(rcTarget.bottom));
2543                        K1(dwBitRate);
2544                        K1(dwBitErrorRate);
2545                        sText += AtlFormatString(_T("  * ") _T("`AvgTimePerFrame`: %s units") _T("\r\n"), I(_FilterGraphHelper::FormatReferenceTime(pVideoInfoHeader2->AvgTimePerFrame)));
2546                        K2(dwInterlaceFlags, _T("0x%X"));
2547                        K2(dwCopyProtectFlags, _T("0x%X"));
2548                        K1(dwPictAspectRatioX);
2549                        K1(dwPictAspectRatioY);
2550                        K2(dwControlFlags, _T("0x%X"));
2551                        K1(bmiHeader.biSize);
2552                        K1(bmiHeader.biWidth);
2553                        K1(bmiHeader.biHeight);
2554                        K1(bmiHeader.biPlanes);
2555                        K1(bmiHeader.biBitCount);
2556                        sText += AtlFormatString(_T("  * ") _T("`bmiHeader.biCompression`: %s") _T("\r\n"), I(_FilterGraphHelper::GetFourccCodeString(pVideoInfoHeader2->bmiHeader.biCompression)));
2557                        K1(bmiHeader.biSizeImage);
2558                        K1(bmiHeader.biXPelsPerMeter);
2559                        K1(bmiHeader.biYPelsPerMeter);
2560                        K1(bmiHeader.biClrUsed);
2561                        K1(bmiHeader.biClrImportant);
2562                        #undef J
2563                        #undef K1
2564                        #undef K2
2565                        nExtraDataSize = pMediaType->cbFormat - sizeof *pVideoInfoHeader2;
2566                        if(nExtraDataSize)
2567                        {
2568                                sText += AtlFormatString(_T("  * ") _T("Extra Data: (%d bytes)") _T("\r\n"), nExtraDataSize);
2569                                nExtraDataSize = 0;
2570                        }
2571                } else
2572                #pragma endregion
2573                #pragma region FORMAT_MPEG2Video
2574                if(pMediaType->formattype == FORMAT_MPEG2Video)
2575                {
2576                        sText += AtlFormatString(_T(" * ") _T("As `MPEG2VIDEOINFO`:") _T("\r\n"));
2577                        const MPEG2VIDEOINFO* pMpeg2VideoInfo = (const MPEG2VIDEOINFO*) pMediaType->pbFormat;
2578                        #define J(x) I(pMpeg2VideoInfo->x)
2579                        #define K1(x) sText += AtlFormatString(_T("  * `") _T(#x) _T("`: %s") _T("\r\n"), J(x))
2580                        #define K2(x, y) sText += AtlFormatString(_T("  * `") _T(#x) _T("`: %s") _T("\r\n"), I(pMpeg2VideoInfo->x, y))
2581                        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));
2582                        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));
2583                        K1(hdr.dwBitRate);
2584                        K1(hdr.dwBitErrorRate);
2585                        sText += AtlFormatString(_T("  * ") _T("`hdr.AvgTimePerFrame`: %s") _T("\r\n"), I(_FilterGraphHelper::FormatReferenceTime(pMpeg2VideoInfo->hdr.AvgTimePerFrame)));
2586                        K2(hdr.dwInterlaceFlags, _T("0x%X"));
2587                        K2(hdr.dwCopyProtectFlags, _T("0x%X"));
2588                        K1(hdr.dwPictAspectRatioX);
2589                        K1(hdr.dwPictAspectRatioY);
2590                        K2(hdr.dwControlFlags, _T("0x%X"));
2591                        K1(hdr.bmiHeader.biSize);
2592                        K1(hdr.bmiHeader.biWidth);
2593                        K1(hdr.bmiHeader.biHeight);
2594                        K1(hdr.bmiHeader.biPlanes);
2595                        K1(hdr.bmiHeader.biBitCount);
2596                        sText += AtlFormatString(_T("  * ") _T("`hdr.bmiHeader.biCompression`: %s") _T("\r\n"), I(_FilterGraphHelper::GetFourccCodeString(pMpeg2VideoInfo->hdr.bmiHeader.biCompression)));
2597                        K1(hdr.bmiHeader.biSizeImage);
2598                        K1(hdr.bmiHeader.biXPelsPerMeter);
2599                        K1(hdr.bmiHeader.biYPelsPerMeter);
2600                        K1(hdr.bmiHeader.biClrUsed);
2601                        K1(hdr.bmiHeader.biClrImportant);
2602                        K2(dwStartTimeCode, _T("0x%08X"));
2603                        K1(cbSequenceHeader);
2604                        K1(dwProfile);
2605                        K1(dwLevel);
2606                        K2(dwFlags, _T("0x%08X"));
2607                        #undef J
2608                        #undef K1
2609                        #undef K2
2610                        #undef J
2611                        nExtraDataSize = pMediaType->cbFormat - (sizeof *pMpeg2VideoInfo - sizeof pMpeg2VideoInfo->dwSequenceHeader);
2612                } else
2613                #pragma endregion
2614                #pragma region FORMAT_WaveFormatEx
2615                if(pMediaType->formattype == FORMAT_WaveFormatEx)
2616                {
2617                        const WAVEFORMATEX* pWaveFormatEx = (const WAVEFORMATEX*) pMediaType->pbFormat;
2618                        if(pWaveFormatEx->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
2619                        {
2620                                const WAVEFORMATEXTENSIBLE* pWaveFormatExtensible = (const WAVEFORMATEXTENSIBLE*) pMediaType->pbFormat;
2621                                #define J(x) I(pWaveFormatExtensible->x)
2622                                #define K1(x) sText += AtlFormatString(_T("  * `") _T(#x) _T("`: %s") _T("\r\n"), J(x))
2623                                #define K2(x, y) sText += AtlFormatString(_T("  * `") _T(#x) _T("`: %s") _T("\r\n"), I(pWaveFormatExtensible->x, y))
2624                                sText += AtlFormatString(_T(" * ") _T("As `WAVEFORMATEXTENSIBLE`:") _T("\r\n"));
2625                                K2(Format.wFormatTag, _T("0x%02X"));
2626                                K1(Format.nChannels);
2627                                K1(Format.nSamplesPerSec);
2628                                K1(Format.nAvgBytesPerSec);
2629                                K1(Format.nBlockAlign);
2630                                K1(Format.wBitsPerSample);
2631                                K1(Format.cbSize);
2632                                K1(Samples.wValidBitsPerSample);
2633                                K2(dwChannelMask, _T("0x%02X"));
2634                                sText += AtlFormatString(_T("  * ") _T("`SubFormat`: %s") _T("\r\n"), I(_PersistHelper::StringFromIdentifier(pWaveFormatExtensible->SubFormat)));
2635                                #undef J
2636                                #undef K1
2637                                #undef K2
2638                                nExtraDataSize = pWaveFormatEx->cbSize - (sizeof *pWaveFormatExtensible - sizeof *pWaveFormatEx);
2639                        } else
2640                        {
2641                                #define J(x) I(pWaveFormatEx->x)
2642                                #define K1(x) sText += AtlFormatString(_T("  * `") _T(#x) _T("`: %s") _T("\r\n"), J(x))
2643                                #define K2(x, y) sText += AtlFormatString(_T("  * `") _T(#x) _T("`: %s") _T("\r\n"), I(pWaveFormatEx->x, y))
2644                                K2(wFormatTag, _T("0x%02X"));
2645                                K1(nChannels);
2646                                K1(nSamplesPerSec);
2647                                K1(nAvgBytesPerSec);
2648                                K1(nBlockAlign);
2649                                K1(wBitsPerSample);
2650                                K1(cbSize);
2651                                #undef J
2652                                #undef K1
2653                                #undef K2
2654                                nExtraDataSize = pWaveFormatEx->cbSize;
2655                        }
2656                }
2657                #pragma endregion
2658                #pragma region Extra Data
2659                if(nExtraDataSize)
2660                {
2661                        if(!pnExtraData)
2662                        {
2663                                if(nExtraDataSize > pMediaType->cbFormat)
2664                                        nExtraDataSize = pMediaType->cbFormat;
2665                                pnExtraData = pMediaType->pbFormat + pMediaType->cbFormat - nExtraDataSize;
2666                        }
2667                        const SSIZE_T nExtraDataExcessSize = (pnExtraData + nExtraDataSize) - (pMediaType->pbFormat + pMediaType->cbFormat);
2668                        if(nExtraDataExcessSize > 0)
2669                                nExtraDataSize -= min((SIZE_T) nExtraDataExcessSize, nExtraDataSize);
2670                        sText += AtlFormatString(_T("  * ") _T("Extra Data: %s") _T("\r\n"), I(AtlFormatData(pnExtraData, nExtraDataSize).TrimRight()));
2671                }
2672                #pragma endregion
2673                return sText;
2674        }
2675        static CString GetText(IFilterGraph* pFilterGraph, const CProcessData* pProcessData = NULL)
2676        {
2677                if(!pFilterGraph)
2678                        return (LPCTSTR) NULL;
2679                const CComQIPtr<ISpy> pSpy = pFilterGraph;
2680                CString sText;
2681                sText += AtlFormatString(_T("# ") _T("Filter Graph") _T("\r\n") _T("\r\n"));
2682                #pragma region Graph Parameters
2683                if(pProcessData)
2684                        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)));
2685                #pragma region IMediaControl
2686                const CComQIPtr<IMediaControl> pMediaControl = pFilterGraph;
2687                if(pMediaControl)
2688                        _ATLTRY
2689                        {
2690                                OAFilterState State;
2691                                const HRESULT nGetStateResult = pMediaControl->GetState(0, &State);
2692                                _Z45_DSHRESULT(nGetStateResult);
2693                                static const LPCTSTR g_ppszStates[] = { _T("Stopped"), _T("Paused"), _T("Running"), };
2694                                if(SUCCEEDED(nGetStateResult) && (SIZE_T) State < DIM(g_ppszStates))
2695                                        sText += AtlFormatString(_T("* ") _T("State: %s") _T("\r\n"), I(g_ppszStates[(SIZE_T) State]));
2696                        }
2697                        _ATLCATCHALL()
2698                        {
2699                                _Z_EXCEPTION();
2700                        }
2701                #pragma endregion
2702                #pragma region IMediaPosition
2703                const CComQIPtr<IMediaPosition> pMediaPosition = pFilterGraph;
2704                if(pMediaPosition)
2705                        _ATLTRY
2706                        {
2707                                DOUBLE fDuration = 0, fPosition = 0;
2708                                const HRESULT nGetDurationResult = pMediaPosition->get_Duration(&fDuration);
2709                                _Z45_DSHRESULT(nGetDurationResult);
2710                                if(fDuration > 0)
2711                                {
2712                                        sText += AtlFormatString(_T("* ") _T("Duration: %s (%s seconds)") _T("\r\n"), I(_FilterGraphHelper::FormatSecondTime(fDuration)), I(_StringHelper::FormatNumber(fDuration, 3)));
2713                                        const HRESULT nCurrentPositionResult = pMediaPosition->get_CurrentPosition(&fPosition);
2714                                        _Z45_DSHRESULT(nCurrentPositionResult);
2715                                        if(SUCCEEDED(nCurrentPositionResult))
2716                                                sText += AtlFormatString(_T("* ") _T("Position: %s (%s seconds)") _T("\r\n"), I(_FilterGraphHelper::FormatSecondTime(fPosition)), I(_StringHelper::FormatNumber(fPosition, 3)));
2717                                }
2718                        }
2719                        _ATLCATCHALL()
2720                        {
2721                                _Z_EXCEPTION();
2722                        }
2723                #pragma endregion
2724                if(pProcessData)
2725                {
2726                        if(!pProcessData->m_sDisplayName.IsEmpty())
2727                                sText += AtlFormatString(_T("* ") _T("Display Name: %s") _T("\r\n"), I(pProcessData->m_sDisplayName));
2728                        if(_tcslen(pProcessData->m_sImagePath))
2729                        {
2730                                const CString sDirectory = (LPCTSTR) GetPathDirectory(pProcessData->m_sImagePath);
2731                                if(!sDirectory.IsEmpty())
2732                                        sText += AtlFormatString(_T("* ") _T("Process Directory: %s") _T("\r\n"), I(sDirectory));
2733                        }
2734                }
2735                const CComQIPtr<IMediaFilter> pMediaFilter = pFilterGraph;
2736                CComPtr<IReferenceClock> pFilterGraphReferenceClock;
2737                const HRESULT nGetSyncSourceResult = pMediaFilter->GetSyncSource(&pFilterGraphReferenceClock);
2738                _Z45_DSHRESULT(nGetSyncSourceResult);
2739                sText += _T("\r\n");
2740                #pragma endregion
2741                #pragma region Filter
2742                _FilterGraphHelper::CFilterArray FilterArray;
2743                _FilterGraphHelper::GetGraphFilters(pFilterGraph, FilterArray);
2744                if(!FilterArray.IsEmpty())
2745                {
2746                        sText += AtlFormatString(_T("## ") _T("Filters") _T("\r\n") _T("\r\n"));
2747                        for(SIZE_T nIndex = 0; nIndex < FilterArray.GetCount(); nIndex++)
2748                                _ATLTRY
2749                                {
2750                                        const CComPtr<IBaseFilter>& pBaseFilter = FilterArray[nIndex];
2751                                        sText += AtlFormatString(_T("%d. ") _T("%ls") _T("\r\n"), nIndex + 1, _FilterGraphHelper::GetFilterName(pBaseFilter));
2752                                        sText += GetFilterText(pBaseFilter, pProcessData, pFilterGraphReferenceClock);
2753                                }
2754                                _ATLCATCHALL()
2755                                {
2756                                        _Z_EXCEPTION();
2757                                }
2758                        sText += _T("\r\n");
2759                        #pragma region Connection
2760                        sText += AtlFormatString(_T("## ") _T("Connections") _T("\r\n") _T("\r\n"));
2761                        INT nConnectionIndex = 0;
2762                        for(SIZE_T nFilterIndex = 0; nFilterIndex < FilterArray.GetCount(); nFilterIndex++)
2763                        {
2764                                const CComPtr<IBaseFilter>& pBaseFilter = FilterArray[nFilterIndex];
2765                                _FilterGraphHelper::CPinArray PinArray;
2766                                _FilterGraphHelper::GetFilterPins(pBaseFilter, PINDIR_OUTPUT, PinArray);
2767                                for(SIZE_T nPinIndex = 0; nPinIndex < PinArray.GetCount(); nPinIndex++)
2768                                {
2769                                        const CComPtr<IPin>& pOutputPin = PinArray[nPinIndex];
2770                                        const CComPtr<IPin> pInputPin = _FilterGraphHelper::GetPeerPin(pOutputPin);
2771                                        if(!pInputPin)
2772                                                continue;
2773                                        sText += AtlFormatString(_T("%d. ") _T("%s") _T("\r\n"), ++nConnectionIndex, GetConnectionText(pOutputPin, pInputPin));
2774                                }
2775                        }
2776                        sText += _T("\r\n");
2777                        #pragma endregion
2778                        #pragma region Media Type
2779                        sText += AtlFormatString(_T("## ") _T("Media Types") _T("\r\n") _T("\r\n"));
2780                        INT nGlobalPinIndex = 0;
2781                        CRoListT<CComPtr<IPin>> PinList;
2782                        for(SIZE_T nFilterIndex = 0; nFilterIndex < FilterArray.GetCount(); nFilterIndex++)
2783                        {
2784                                const CComPtr<IBaseFilter>& pBaseFilter = FilterArray[nFilterIndex];
2785                                _FilterGraphHelper::CPinArray PinArray;
2786                                _FilterGraphHelper::GetFilterPins(pBaseFilter, PinArray);
2787                                for(SIZE_T nPinIndex = 0; nPinIndex < PinArray.GetCount(); nPinIndex++)
2788                                {
2789                                        const CComPtr<IPin>& pPin = PinArray[nPinIndex];
2790                                        if(PinList.FindFirst(pPin))
2791                                                continue;
2792                                        PinList.AddTail(pPin);
2793                                        CString sPinText = AtlFormatString(_T("%s"), I(_FilterGraphHelper::GetPinFullName(pPin)));
2794                                        const CComPtr<IPin> pPeerPin = _FilterGraphHelper::GetPeerPin(pPin);
2795                                        if(pPeerPin)
2796                                        {
2797                                                PinList.AddTail(pPeerPin);
2798                                                sPinText += AtlFormatString(_T(", %s"), I(_FilterGraphHelper::GetPinFullName(pPeerPin)));
2799                                        }
2800                                        sText += AtlFormatString(_T("%d. ") _T("%s") _T("\r\n"), ++nGlobalPinIndex, sPinText);
2801                                        _ATLTRY
2802                                        {
2803                                                CMediaType pMediaType;
2804                                                if(pPeerPin)
2805                                                        pMediaType = _FilterGraphHelper::GetPinMediaType(pPin);
2806                                                else
2807                                                        pMediaType = _FilterGraphHelper::EnumerateFirstPinMediaType(pPin);
2808                                                if(!pMediaType)
2809                                                        continue;
2810                                                sText += GetMediaTypeText(pMediaType);
2811                                        }
2812                                        _ATLCATCHALL()
2813                                        {
2814                                                _Z_EXCEPTION();
2815                                        }
2816                                }
2817                        }
2818                        sText += _T("\r\n");
2819                        #pragma endregion
2820                        #pragma region IMediaSeeking
2821                        BOOL bMediaSeekingHeaderAdded = FALSE;
2822                        for(SIZE_T nFilterIndex = 0; nFilterIndex < FilterArray.GetCount(); nFilterIndex++)
2823                        {
2824                                const CComPtr<IBaseFilter>& pBaseFilter = FilterArray[nFilterIndex];
2825                                _FilterGraphHelper::CPinArray PinArray;
2826                                _FilterGraphHelper::GetFilterPins(pBaseFilter, PINDIR_OUTPUT, PinArray);
2827                                for(SIZE_T nPinIndex = 0; nPinIndex < PinArray.GetCount(); nPinIndex++)
2828                                {
2829                                        const CComPtr<IPin>& pOutputPin = PinArray[nPinIndex];
2830                                        const CComQIPtr<IMediaSeeking> pMediaSeeking = pOutputPin;
2831                                        if(!pMediaSeeking)
2832                                                continue;
2833                                        if(!bMediaSeekingHeaderAdded)
2834                                        {
2835                                                sText += AtlFormatString(_T(" ## ") _T("Media Seeking/Position") _T("\r\n") _T("\r\n"));
2836                                                bMediaSeekingHeaderAdded = TRUE;
2837                                        }
2838                                        sText += AtlFormatString(_T(" * ") _T("Pin: %s") _T("\r\n"), I(_FilterGraphHelper::GetPinFullName(pOutputPin)));
2839                                        _ATLTRY
2840                                        {
2841                                                DWORD nCapabilities = 0;
2842                                                if(SUCCEEDED(pMediaSeeking->GetCapabilities(&nCapabilities)))
2843                                                        sText += AtlFormatString(_T("  * ") _T("Capabilities: %s") _T("\r\n"), I(AtlFormatString(_T("0x%X"), nCapabilities)));
2844                                                LONGLONG nDuration = 0, nPosition = 0, nStopPosition = 0;
2845                                                if(SUCCEEDED(pMediaSeeking->GetDuration(&nDuration)))
2846                                                        sText += AtlFormatString(_T("  * ") _T("Duration: %s (%s seconds)") _T("\r\n"), I(_FilterGraphHelper::FormatSecondTime((DOUBLE) nDuration / 1E7)), I(_StringHelper::FormatNumber((DOUBLE) nDuration / 1E7, 3)));
2847                                                if(SUCCEEDED(pMediaSeeking->GetCurrentPosition(&nPosition)))
2848                                                        sText += AtlFormatString(_T("  * ") _T("Position: %s (%s seconds)") _T("\r\n"), I(_FilterGraphHelper::FormatSecondTime((DOUBLE) nPosition / 1E7)), I(_StringHelper::FormatNumber((DOUBLE) nPosition / 1E7, 3)));
2849                                                if(SUCCEEDED(pMediaSeeking->GetStopPosition(&nStopPosition)))
2850                                                        sText += AtlFormatString(_T("  * ") _T("Stop Position: %s (%s seconds)") _T("\r\n"), I(_FilterGraphHelper::FormatSecondTime((DOUBLE) nStopPosition / 1E7)), I(_StringHelper::FormatNumber((DOUBLE) nStopPosition / 1E7, 3)));
2851                                                DOUBLE fRate = 1.0;
2852                                                if(SUCCEEDED(pMediaSeeking->GetRate(&fRate)))
2853                                                        sText += AtlFormatString(_T("  * ") _T("Rate: %s") _T("\r\n"), I(_StringHelper::FormatNumber(fRate, 3)));
2854                                                LONGLONG nPreroll = 0;
2855                                                if(SUCCEEDED(pMediaSeeking->GetPreroll(&nPreroll)) && nPreroll)
2856                                                        sText += AtlFormatString(_T("  * ") _T("Preroll: %s seconds") _T("\r\n"), I(_StringHelper::FormatNumber((DOUBLE) nPreroll / 1E7, 3)));
2857                                        }
2858                                        _ATLCATCHALL()
2859                                        {
2860                                                _Z_EXCEPTION();
2861                                        }
2862                                }
2863                        }
2864                        if(bMediaSeekingHeaderAdded)
2865                                sText += _T("\r\n");
2866                        #pragma endregion
2867                        #pragma region Runtime Property Bag
2868                        BOOL bRunPropertyBagHeaderAdded = FALSE;
2869                        for(SIZE_T nIndex = 0; nIndex < FilterArray.GetCount(); nIndex++)
2870                                _ATLTRY
2871                                {
2872                                        const CComPtr<IBaseFilter>& pBaseFilter = FilterArray[nIndex];
2873                                        //_Z4(atlTraceGeneral, 4, _T("pBaseFilter 0x%p \"%ls\"\n"), pBaseFilter, _FilterGraphHelper::GetFilterName(pBaseFilter));
2874                                        const CString sPropertyBagText = CRunPropertyBagHelper::GetPropertyBagText(pBaseFilter, pSpy);
2875                                        if(sPropertyBagText.IsEmpty())
2876                                                continue;
2877                                        if(!bRunPropertyBagHeaderAdded)
2878                                        {
2879                                                sText += AtlFormatString(_T("## ") _T("Runtime Properties") _T("\r\n") _T("\r\n"));
2880                                                bRunPropertyBagHeaderAdded = TRUE;
2881                                        }
2882                                        sText += AtlFormatString(_T("### ") _T("Filter: %ls") _T("\r\n") _T("\r\n"), _FilterGraphHelper::GetFilterName(pBaseFilter));
2883                                        sText += sPropertyBagText;
2884                                        sText += _T("\r\n");
2885                                }
2886                                _ATLCATCHALL()
2887                                {
2888                                        _Z_EXCEPTION();
2889                                }
2890                        #pragma endregion
2891                }
2892                #pragma endregion
2893                return sText;
2894        }
2895        #undef I
2896        CComPtr<IFilterGraph> GetFilterGraph() const
2897        {
2898                CRoCriticalSectionLock DataLock(m_DataCriticalSection);
2899                return m_pFilterGraph;
2900        }
2901        VOID SetFilterGraph(IFilterGraph* pFilterGraph, CProcessData* pProcessData = NULL) 
2902        {
2903                CRoCriticalSectionLock DataLock(m_DataCriticalSection);
2904                if(!pProcessData)
2905                {
2906                        m_ProcessData = CProcessData();
2907                        const CComQIPtr<ISpyEx> pSpyEx = pFilterGraph;
2908                        if(pSpyEx)
2909                                m_ProcessData.m_nIdentifier = GetCurrentProcessId();
2910                } else
2911                        m_ProcessData = *pProcessData;
2912                m_pFilterGraph = pFilterGraph;
2913        }
2914        BOOL SetFilterGraph(IUnknown* pFilterGraphUnknown, CProcessData* pProcessData = NULL) 
2915        {
2916                CComQIPtr<IFilterGraph> pFilterGraph;
2917                if(pFilterGraphUnknown)
2918                {
2919                        pFilterGraph = pFilterGraphUnknown;
2920                        if(!pFilterGraph)
2921                        {
2922                                const CComQIPtr<IBaseFilter> pBaseFilter = pFilterGraphUnknown;
2923                                if(!pBaseFilter)
2924                                {
2925                                        const CComQIPtr<IPin> pPin = pFilterGraphUnknown;
2926                                        if(pPin)
2927                                                pFilterGraph = _FilterGraphHelper::GetFilterGraph(_FilterGraphHelper::GetPinFilter(pPin));
2928                                } else
2929                                        pFilterGraph = _FilterGraphHelper::GetFilterGraph(pBaseFilter);
2930                        }
2931                }
2932                SetFilterGraph(pFilterGraph, pProcessData);
2933                return pFilterGraph != NULL;
2934        }
2935        CString GetFilterText(IBaseFilter* pBaseFilter) const
2936        {
2937                return GetFilterText(pBaseFilter, m_ProcessData.m_nIdentifier ? &m_ProcessData : NULL);
2938        }
2939        CString GetText() const
2940        {
2941                CRoCriticalSectionLock DataLock(m_DataCriticalSection);
2942                return GetText(m_pFilterGraph, m_ProcessData.m_nIdentifier ? &m_ProcessData : NULL);
2943        }
2944        static LPCTSTR GetPlatformName()
2945        {
2946                #if defined(_WIN64)
2947                        return _T("x64");
2948                #else
2949                        return _T("Win32");
2950                #endif // defined(_WIN64)
2951        }
2952        template <SIZE_T t_nItemCount>
2953        static CString& GetLegacyFilter(const COMDLG_FILTERSPEC (&pItems)[t_nItemCount], CString& sFilter)
2954        {
2955                _A(sFilter.IsEmpty());
2956                for(SIZE_T nIndex = 0; nIndex < t_nItemCount; nIndex++)
2957                {
2958                        const COMDLG_FILTERSPEC& Item = pItems[nIndex];
2959                        sFilter += AtlFormatString(_T("%s (%s)|%s|"), Item.pszName, Item.pszSpec, Item.pszSpec);
2960                }
2961                sFilter.Replace(_T('|'), 0);
2962                return sFilter;
2963        }
2964        static BOOL OpenMonikerWithGsn(LPCWSTR pszMonikerDisplayName, HWND hParentWindow = GetActiveWindow())
2965        {
2966                _A(pszMonikerDisplayName);
2967                static const LPCTSTR g_pszValueName = _T("GraphStudioNext Path");
2968                static const LPCTSTR g_pszFileName = _T("graphstudionext.exe");
2969                const CString sValueName = AtlFormatString(_T("%s (%s)"), g_pszValueName, GetPlatformName());
2970                CString sPath = _RegKeyHelper::QueryStringValue(HKEY_CURRENT_USER, REGISTRY_ROOT, sValueName);
2971                if(!FileExists(sPath))
2972                        sPath.Empty();
2973                #pragma region Current Directory
2974                if(sPath.IsEmpty())
2975                {
2976                        sPath = (LPCTSTR) Combine(GetPathDirectory(GetModulePath()), g_pszFileName);
2977                        if(!FileExists(sPath))
2978                                sPath.Empty();
2979                }
2980                #pragma endregion
2981                #pragma region Application Registry
2982                if(sPath.IsEmpty())
2983                {
2984                        #if defined(_WIN64)
2985                                static const LPCTSTR g_pszValueName = _T("exeLocation64");
2986                        #else
2987                                static const LPCTSTR g_pszValueName = _T("exeLocation");
2988                        #endif // defined(_WIN64)
2989                        sPath = _RegKeyHelper::QueryStringValue(HKEY_CURRENT_USER, _T("Software\\MONOGRAM\\GraphStudioNext"), g_pszValueName);
2990                        if(!FileExists(sPath))
2991                                sPath.Empty();
2992                }
2993                #pragma endregion
2994                if(sPath.IsEmpty())
2995                {
2996                        #pragma region Prompt
2997                        static const COMDLG_FILTERSPEC g_pFilter[] = 
2998                        {
2999                                { _T("Executable Files"), _T("*.exe") },
3000                                { _T("All Files"), _T("*.*") },
3001                        };
3002                        if(GetOsVersion() >= GetWinVistaOsVersion())
3003                        {
3004                                CShellFileOpenDialog Dialog(g_pszFileName, FOS_FORCEFILESYSTEM | FOS_FILEMUSTEXIST, _T("exe"), g_pFilter, DIM(g_pFilter));
3005                                if(Dialog.DoModal(hParentWindow) != IDOK)
3006                                        return FALSE;
3007                                __C(Dialog.GetFilePath(sPath));
3008                        } else
3009                        {
3010                                CString sFilter;
3011                                CFileDialog Dialog(TRUE, _T("exe"), NULL, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_EXPLORER | OFN_ENABLESIZING, GetLegacyFilter(g_pFilter, sFilter));
3012                                if(Dialog.DoModal(hParentWindow) != IDOK)
3013                                        return FALSE;
3014                                sPath = Dialog.m_szFileName;
3015                        }
3016                        #pragma endregion
3017                        _RegKeyHelper::SetStringValue(HKEY_CURRENT_USER, REGISTRY_ROOT, sValueName, sPath);
3018                }
3019                CWaitCursor WaitCursor;
3020                CString sParameters = AtlFormatString(_T("-a \"%ls\""), pszMonikerDisplayName);
3021                SHELLEXECUTEINFO Infomation;
3022                ZeroMemory(&Infomation, sizeof Infomation);
3023                Infomation.cbSize = sizeof Infomation;
3024                Infomation.lpFile = sPath;
3025                Infomation.lpParameters = sParameters;
3026                Infomation.nShow = SW_SHOWNORMAL;
3027                __E(ShellExecuteEx(&Infomation));
3028                return TRUE;
3029        }
3030        static BOOL OpenMonikerWithGe(LPCWSTR pszMonikerDisplayName, HWND hParentWindow = GetActiveWindow())
3031        {
3032                static const LPCTSTR g_pszValueName = _T("GraphEdit Path");
3033                static const LPCTSTR g_pszFileName = _T("graphedt.exe");
3034                const CString sValueName = AtlFormatString(_T("%s (%s)"), g_pszValueName, GetPlatformName());
3035                CString sPath = _RegKeyHelper::QueryStringValue(HKEY_CURRENT_USER, REGISTRY_ROOT, sValueName);
3036                if(!FileExists(sPath))
3037                        sPath.Empty();
3038                #pragma region Current Directory
3039                if(sPath.IsEmpty())
3040                {
3041                        sPath = (LPCTSTR) Combine(GetPathDirectory(GetModulePath()), g_pszFileName);
3042                        if(!FileExists(sPath))
3043                                sPath.Empty();
3044                }
3045                #pragma endregion
3046                // SUGG: Look for Windows SDK
3047                if(sPath.IsEmpty())
3048                {
3049                        #pragma region Prompt
3050                        static const COMDLG_FILTERSPEC g_pFilter[] = 
3051                        {
3052                                { _T("Executable Files"), _T("*.exe") },
3053                                { _T("All Files"), _T("*.*") },
3054                        };
3055                        if(GetOsVersion() >= GetWinVistaOsVersion())
3056                        {
3057                                CShellFileOpenDialog Dialog(g_pszFileName, FOS_FORCEFILESYSTEM | FOS_FILEMUSTEXIST, _T("exe"), g_pFilter, DIM(g_pFilter));
3058                                if(Dialog.DoModal(hParentWindow) != IDOK)
3059                                        return FALSE;
3060                                __C(Dialog.GetFilePath(sPath));
3061                        } else
3062                        {
3063                                CString sFilter;
3064                                CFileDialog Dialog(TRUE, _T("exe"), NULL, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_EXPLORER | OFN_ENABLESIZING, GetLegacyFilter(g_pFilter, sFilter));
3065                                if(Dialog.DoModal(hParentWindow) != IDOK)
3066                                        return FALSE;
3067                                sPath = Dialog.m_szFileName;
3068                        }
3069                        #pragma endregion
3070                        _RegKeyHelper::SetStringValue(HKEY_CURRENT_USER, REGISTRY_ROOT, sValueName, sPath);
3071                }
3072                CStringW sFilterGraphMonikerDisplayName = pszMonikerDisplayName;
3073                const INT nSeparatorPosition = sFilterGraphMonikerDisplayName.Find(L';');
3074                if(nSeparatorPosition >= 0)
3075                        sFilterGraphMonikerDisplayName = sFilterGraphMonikerDisplayName.Left(nSeparatorPosition);
3076                CWaitCursor WaitCursor;
3077                CString sParameters = AtlFormatString(_T("-a %ls"), sFilterGraphMonikerDisplayName);
3078                SHELLEXECUTEINFO Infomation;
3079                ZeroMemory(&Infomation, sizeof Infomation);
3080                Infomation.cbSize = sizeof Infomation;
3081                Infomation.lpFile = sPath;
3082                Infomation.lpParameters = sParameters;
3083                Infomation.nShow = SW_SHOWNORMAL;
3084                __E(ShellExecuteEx(&Infomation));
3085                return TRUE;
3086        }
3087
3088// IFilterGraphHelper
3089        STDMETHOD(get_FilterGraph)(IUnknown** ppFilterGraphUnknown)
3090        {
3091                _Z4(atlTraceCOM, 4, _T("...\n"));
3092                _ATLTRY
3093                {
3094                        __D(ppFilterGraphUnknown, E_POINTER);
3095                        *ppFilterGraphUnknown = GetFilterGraph().Detach();
3096                }
3097                _ATLCATCH(Exception)
3098                {
3099                        _C(Exception);
3100                }
3101                return S_OK;
3102        }
3103        STDMETHOD(put_FilterGraph)(IUnknown* pFilterGraphUnknown)
3104        {
3105                _Z4(atlTraceCOM, 4, _T("pFilterGraphUnknown 0x%p\n"), pFilterGraphUnknown);
3106                _ATLTRY
3107                {
3108                        if(!SetFilterGraph(pFilterGraphUnknown))
3109                                return S_FALSE;
3110                }
3111                _ATLCATCH(Exception)
3112                {
3113                        _C(Exception);
3114                }
3115                return S_OK;
3116        }
3117        STDMETHOD(get_Text)(BSTR* psText)
3118        {
3119                _Z4(atlTraceCOM, 4, _T("...\n"));
3120                _ATLTRY
3121                {
3122                        __D(psText, E_POINTER);
3123                        CRoCriticalSectionLock DataLock(m_DataCriticalSection);
3124                        *psText = CComBSTR(GetText(m_pFilterGraph)).Detach();
3125                }
3126                _ATLCATCH(Exception)
3127                {
3128                        _C(Exception);
3129                }
3130                return S_OK;
3131        }
3132        STDMETHOD(DoPropertyFrameModal)(LONG nParentWindowHandle)
3133        {
3134                _Z4(atlTraceCOM, 4, _T("nParentWindowHandle 0x%08X\n"), nParentWindowHandle);
3135                _ATLTRY
3136                {
3137                        CWindow ParentWindow = (HWND) (LONG_PTR) nParentWindowHandle;
3138                        if(!ParentWindow)
3139                                ParentWindow = GetActiveWindow();
3140                        //__D(!ParentWindow || ParentWindow.IsWindow(), E_INVALIDARG);
3141                        const CComQIPtr<IFilterGraph2> pFilterGraph2 = GetFilterGraph();
3142                        __D(pFilterGraph2, E_NOINTERFACE);
3143                        CPropertyFrameDialog PropertyFrameDialog(this);
3144                        PropertyFrameDialog.DoModal(ParentWindow);
3145                }
3146                _ATLCATCH(Exception)
3147                {
3148                        _C(Exception);
3149                }
3150                return S_OK;
3151        }
3152        STDMETHOD(DoFilterGraphListModal)(LONG nParentWindowHandle)
3153        {
3154                _Z4(atlTraceCOM, 4, _T("nParentWindowHandle 0x%08X\n"), nParentWindowHandle);
3155                _ATLTRY
3156                {
3157                        CWindow ParentWindow = (HWND) (LONG_PTR) nParentWindowHandle;
3158                        if(!ParentWindow)
3159                                ParentWindow = GetActiveWindow();
3160                        //__D(!ParentWindow || ParentWindow.IsWindow(), E_INVALIDARG);
3161                        DoFilterGraphListPropertySheetModal(ParentWindow);
3162                }
3163                _ATLCATCH(Exception)
3164                {
3165                        _C(Exception);
3166                }
3167                return S_OK;
3168        }
3169        STDMETHOD(OpenGraphStudioNext)(LONG nParentWindowHandle, BSTR sMonikerDisplayName, VARIANT_BOOL* pbResult)
3170        {
3171                _Z4(atlTraceCOM, 4, _T("nParentWindowHandle 0x%08X, sMonikerDisplayName \"%s\"\n"), nParentWindowHandle, CString(sMonikerDisplayName));
3172                _ATLTRY
3173                {
3174                        __D(sMonikerDisplayName && *sMonikerDisplayName, E_INVALIDARG);
3175                        CWindow ParentWindow = (HWND) (LONG_PTR) nParentWindowHandle;
3176                        if(!ParentWindow)
3177                                ParentWindow = GetActiveWindow();
3178                        //__D(!ParentWindow || ParentWindow.IsWindow(), E_INVALIDARG);
3179                        const BOOL bResult = OpenMonikerWithGsn(sMonikerDisplayName, ParentWindow);
3180                        if(pbResult)
3181                                *pbResult = bResult ? ATL_VARIANT_TRUE : ATL_VARIANT_FALSE;
3182                }
3183                _ATLCATCH(Exception)
3184                {
3185                        _C(Exception);
3186                }
3187                return S_OK;
3188        }
3189        STDMETHOD(OpenGraphEdit)(LONG nParentWindowHandle, BSTR sMonikerDisplayName, VARIANT_BOOL* pbResult)
3190        {
3191                _Z4(atlTraceCOM, 4, _T("nParentWindowHandle 0x%08X, sMonikerDisplayName \"%s\"\n"), nParentWindowHandle, CString(sMonikerDisplayName));
3192                _ATLTRY
3193                {
3194                        __D(sMonikerDisplayName && *sMonikerDisplayName, E_INVALIDARG);
3195                        CWindow ParentWindow = (HWND) (LONG_PTR) nParentWindowHandle;
3196                        if(!ParentWindow)
3197                                ParentWindow = GetActiveWindow();
3198                        //__D(!ParentWindow || ParentWindow.IsWindow(), E_INVALIDARG);
3199                        const BOOL bResult = OpenMonikerWithGe(sMonikerDisplayName, ParentWindow);
3200                        if(pbResult)
3201                                *pbResult = bResult ? ATL_VARIANT_TRUE : ATL_VARIANT_FALSE;
3202                }
3203                _ATLCATCH(Exception)
3204                {
3205                        _C(Exception);
3206                }
3207                return S_OK;
3208        }
3209};
3210
3211OBJECT_ENTRY_AUTO(__uuidof(FilterGraphHelper), CFilterGraphHelper)
3212
3213inline HRESULT FilterGraphHelper_DoPropertyFrameModal(LONG nParentWindowHandle, IUnknown* pFilterGraphUnknown)
3214{
3215        CLocalObjectPtr<CFilterGraphHelper> pFilterGraphHelper;
3216        pFilterGraphHelper->SetFilterGraph(pFilterGraphUnknown);
3217        return pFilterGraphHelper->DoPropertyFrameModal(nParentWindowHandle);
3218}
3219inline HRESULT FilterGraphHelper_DoFilterGraphListModal(LONG nParentWindowHandle)
3220{
3221        CLocalObjectPtr<CFilterGraphHelper> pFilterGraphHelper;
3222        return pFilterGraphHelper->DoFilterGraphListModal(nParentWindowHandle);
3223}
3224inline HRESULT FilterGraphHelper_OpenGraphStudioNext(LONG nParentWindowHandle, LPCWSTR pszMonikerDisplayName, VARIANT_BOOL* pbResult)
3225{
3226        CLocalObjectPtr<CFilterGraphHelper> pFilterGraphHelper;
3227        return pFilterGraphHelper->OpenGraphStudioNext(nParentWindowHandle, CComBSTR(pszMonikerDisplayName), pbResult);
3228}
3229inline HRESULT FilterGraphHelper_OpenGraphEdit(LONG nParentWindowHandle, LPCWSTR pszMonikerDisplayName, VARIANT_BOOL* pbResult)
3230{
3231        CLocalObjectPtr<CFilterGraphHelper> pFilterGraphHelper;
3232        return pFilterGraphHelper->OpenGraphEdit(nParentWindowHandle, CComBSTR(pszMonikerDisplayName), pbResult);
3233}
Note: See TracBrowser for help on using the repository browser.