source: trunk/DirectShowSpy/FilterGraphHelper.h @ 290

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

Added runtime event interface and generic property page

File size: 115.2 KB
RevLine 
[199]1////////////////////////////////////////////////////////////
[231]2// Copyright (C) Roman Ryltsov, 2008-2014
[276]3// Created by Roman Ryltsov roman@alax.info, http://alax.info
[267]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
[276]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).
[267]9//
10// Please keep in mind that DirectShowSpy is a developer tool, it is strongly recommended
[276]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.
[199]15
16#pragma once
17
18#include "rofiles.h"
19#include "rodshow.h"
20#include "DirectShowSpy_i.h"
21#include "Common.h"
[290]22#include "RunPropertyBag.h"
23#include "RunEvent.h"
[231]24#include "AboutDialog.h"
[233]25#include "..\..\Repository-Private\Utilities\EmailTools\Message.h"
[256]26#define  BZ_NO_STDIO
27#include "..\..\Repository-Private\Utilities\DeflateTools\Bzip2Item.h"
[199]28
[242]29INT_PTR DoFilterGraphListPropertySheetModal(HWND hParentWindow);
30
[249]31HRESULT FilterGraphHelper_DoPropertyFrameModal(LONG nParentWindowHandle);
32HRESULT FilterGraphHelper_DoFilterGraphListModal(LONG nParentWindowHandle);
[247]33HRESULT FilterGraphHelper_OpenGraphStudioNext(LONG nParentWindowHandle, LPCWSTR pszMonikerDisplayName, VARIANT_BOOL* pbResult);
34HRESULT FilterGraphHelper_OpenGraphEdit(LONG nParentWindowHandle, LPCWSTR pszMonikerDisplayName, VARIANT_BOOL* pbResult);
35
[199]36////////////////////////////////////////////////////////////
[265]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:
[290]46        enum { IDR = IDR_GENERIC_RUNPROPERTYBAG_PROPERTYPAGE };
[265]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        {
[290]88                _Z4_THIS();
[265]89        }
90        ~CRunPropertyBagPropertyPage()
91        {
[290]92                _Z4_THIS();
[265]93        }
94        VOID UpdateControls()
95        {
96        }
97        VOID UpdateText()
98        {
99                CString sText;
100                _A(GetObjectCount() == 1);
[290]101                m_TextEdit.SetValue(CRunPropertyBagHelper::GetPropertyBagText(GetObject(0)));
[265]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////////////////////////////////////////////////////////////
[290]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////////////////////////////////////////////////////////////
[265]353// CFilterGraphHelper
354
[199]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;
[285]384
385        public:
386        // CProcessData
387                CProcessData() :
388                        m_nIdentifier(0)
389                {
390                }
[199]391        };
392
[231]393        ////////////////////////////////////////////////////////
394        // CPropertyFrameDialog
395
396        class CPropertyFrameDialog :
397                public CDialogImpl<CPropertyFrameDialog>,
[242]398                public CDialogResize<CPropertyFrameDialog>,
399                public CDialogWithAcceleratorsT<CPropertyFrameDialog>
[231]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)
[247]409                MSG_TVN_GETINFOTIP(IDC_FILTERGRAPHHELPER_PROPERTYFRAME_TREE, OnTreeViewGetInfoTip)
[231]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)
[258]417                COMMAND_ID_HANDLER_EX(IDC_FILTERGRAPHHELPER_PROPERTYFRAME_TREE_WALKUP, OnTreeWalkUp)
[242]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)
[231]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                ////////////////////////////////////////////////////
[242]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);
[247]605                                        m_OpenGsnDescriptionStatic.EnableWindow(bMonikerDisplayNameAvailable);
[242]606                                        m_OpenGeButton.EnableWindow(bMonikerDisplayNameAvailable);
[247]607                                        m_OpenGeDescriptionStatic.EnableWindow(bMonikerDisplayNameAvailable);
[242]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                ////////////////////////////////////////////////////
[256]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();
[270]806                                m_FileListView.RemoveAllGroups();
[256]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;
[258]821                                                for(BOOL bFound = FindFiles.FindFirstFile(pszDirectory, _T("*.*")); bFound; bFound = FindFiles.FindNextFile())
[256]822                                                {
823                                                        const WIN32_FIND_DATA& Data = FindFiles.GetFindData();
[258]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
[256]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                ////////////////////////////////////////////////////
[233]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)
[247]994                        NOTIFY_HANDLER_EX(IDC_FILTERGRAPHHELPER_EMAIL_CLEANUP, CRoHyperStatic::NC_ANCHORCLICKED, OnCleanupStaticAnchorClicked)
[233]995                        REFLECT_NOTIFICATIONS()
[256]996                ALT_MSG_MAP(IDC_FILTERGRAPHHELPER_EMAIL_FROM)
997                        MSG_WM_PASTE(OnFromEditPaste)
[233]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)
[247]1003                        DLGRESIZE_CONTROL(IDC_FILTERGRAPHHELPER_EMAIL_CLEANUP, DLSZ_MOVE_Y)
[233]1004                END_DLGRESIZE_MAP()
1005
1006                private:
1007                        CPropertyFrameDialog* m_pOwner;
1008                        BOOL m_bActivating;
1009                        CStatic m_TitleStatic;
1010                        CFont m_TitleFont;
[256]1011                        CContainedWindowT<CRoEdit> m_FromEdit;
[233]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;
[247]1019                        CRoHyperStatic m_CleanupStatic;
[233]1020                        CString m_sFilterGraphText;
1021                        CRoMapT<INT_PTR, BOOL> m_ChangeMap;
1022
1023                public:
1024                // CEmailDialog
[256]1025                        CEmailDialog() :
1026                                m_FromEdit(this, IDC_FILTERGRAPHHELPER_EMAIL_FROM)
[233]1027                        {
[256]1028                        }
1029                        BOOL InitializeControlsFromMessageString(const CString& sMessageString)
1030                        {
[233]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();
[256]1087                                        return FALSE;
[233]1088                                }
[256]1089                                return TRUE;
[233]1090                        }
[256]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                        }
[233]1098                        VOID InitializeBody()
1099                        {
1100                                CString sText;
[236]1101                                sText += _T("(add notes here; graph data will be appended below)") _T("\r\n") _T("\r\n");
[233]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
[256]1149                                        sText += AtlFormatString(_T(" * ") _T("Computer Name: %s") _T("\r\n"), I(GetComputerName()));
[233]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
[236]1183                                        sText += AtlFormatString(_T(" * ") _T("Processors: %s, Active Mask %s") _T("\r\n"), I(SystemInformation.dwNumberOfProcessors), I((DWORD) SystemInformation.dwActiveProcessorMask, _T("0x%X")));
[233]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                        }
[256]1226                        static CString GetComputerName()
1227                        {
1228                                TCHAR pszComputerName[256] = { 0 };
1229                                DWORD nComputerNameLength = DIM(pszComputerName);
1230                                ::GetComputerName(pszComputerName, &nComputerNameLength);
1231                                return pszComputerName;
1232                        }
[233]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);
[242]1243                                        CreateTitleFont(m_TitleFont, m_TitleStatic);
[256]1244                                        _W(m_FromEdit.SubclassWindow(GetDlgItem(IDC_FILTERGRAPHHELPER_EMAIL_FROM)));
[233]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);
[247]1254                                        _W(m_CleanupStatic.SubclassWindow(GetDlgItem(IDC_FILTERGRAPHHELPER_EMAIL_CLEANUP)));
[240]1255                                        DlgResize_Init(FALSE, FALSE);
[233]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                        }
[256]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                        }
[233]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)));
[256]1373                                CString sSubject = AtlFormatString(_T("DirectShow Filter Graph from %s by %s"), GetComputerName(), AtlLoadString(IDS_PROJNAME));
[233]1374                                __C(pMessage->put_Subject(CComBSTR(sSubject)));
[256]1375                                #pragma region Attachment
[261]1376                                CRoArrayT<CPath> DeletePathArray;
1377                                CRoArrayT<CString> FailurePathArray;
[256]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++)
[261]1386                                                {
1387                                                        CEmailLogDialog::CSelectedFileData& FileData = Array[nIndex];
[256]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)
[261]1414                                                                        DeletePathArray.Add(FileData.m_sPath);
[256]1415                                                        }
1416                                                        _ATLCATCHALL()
1417                                                        {
[261]1418                                                                _Z_EXCEPTION();
1419                                                                FailurePathArray.Add((LPCTSTR) FileData.m_sPath);
[256]1420                                                        }
[261]1421                                                }
[256]1422                                        }
1423                                }
1424                                #pragma endregion
[233]1425                                __C(pMessage->Send());
[261]1426                                for(SIZE_T nIndex = 0; nIndex < DeletePathArray.GetCount(); nIndex++)
1427                                        DeleteFile(DeletePathArray[nIndex]);
[247]1428                                _RegKeyHelper::SetStringValue(HKEY_CURRENT_USER, REGISTRY_ROOT, _T("Email Message Template"), CString(sMessageString));
[261]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                                }
[256]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);
[233]1435                                MessageBeep(MB_OK);
1436                                return 0;
1437                        }
[247]1438                        LRESULT OnCleanupStaticAnchorClicked(NMHDR*)
1439                        {
1440                                _RegKeyHelper::DeleteValue(HKEY_CURRENT_USER, REGISTRY_ROOT, _T("Email Message Template"));
[256]1441                                AtlOptionalMessageBoxEx(m_hWnd, _T("CFilterGraphHelper::CPropertyFrameDialog::CEmailDialog::SavedCredentialsDeleted"), _T("Cached email credentials were removed from registry."), IDS_INFORMATION, MB_ICONINFORMATION | MB_OK);
[247]1442                                MessageBeep(MB_OK);
1443                                return 0;
1444                        }
[233]1445                };
1446
1447                ////////////////////////////////////////////////////
[231]1448                // CData
1449
1450                class CData
1451                {
1452                public:
[233]1453
1454                        /////////////////////////////////////////////////////////
1455                        // TYPE
1456
1457                        typedef enum _TYPE
1458                        {
1459                                TYPE_UNKNOWN = 0,
1460                                TYPE_FILTERS,
1461                                TYPE_FILTER,
1462                                TYPE_FILTERPROPERTYPAGE,
[242]1463                                TYPE_ACTION,
[233]1464                                TYPE_EMAIL,
[256]1465                                TYPE_EMAIL_LOG,
[233]1466                        } TYPE;
1467
1468                public:
1469                        TYPE m_Type;
[231]1470                        CComPtr<IBaseFilter> m_pBaseFilter;
[247]1471                        CLSID m_BaseFilterClassIdentifier;
1472                        CString m_sBaseFilterClassDescription;
1473                        CString m_sBaseFilterModulePath;
1474                        CLSID m_PropertyPageClassIdentifier;
[231]1475                        CComPtr<IPropertyPage> m_pPropertyPage;
1476                        CObjectPtr<CPropertyPageSite> m_pSite;
1477                        BOOL m_bSiteActivated;
1478
1479                public:
1480                // CData
[233]1481                        CData(TYPE Type = TYPE_UNKNOWN) :
1482                                m_Type(Type),
[247]1483                                m_BaseFilterClassIdentifier(CLSID_NULL),
1484                                m_PropertyPageClassIdentifier(CLSID_NULL)
[231]1485                        {
1486                        }
1487                        CData(IBaseFilter* pBaseFilter) :
[233]1488                                m_Type(TYPE_FILTER),
[231]1489                                m_pBaseFilter(pBaseFilter),
[247]1490                                m_BaseFilterClassIdentifier(CLSID_NULL),
1491                                m_PropertyPageClassIdentifier(CLSID_NULL)
[231]1492                        {
[247]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                                }
[231]1508                        }
[247]1509                        CData(IBaseFilter* pBaseFilter, const CLSID& PropertyPageClassIdentifier, IPropertyPage* pPropertyPage) :
[233]1510                                m_Type(TYPE_FILTERPROPERTYPAGE),
[231]1511                                m_pBaseFilter(pBaseFilter),
[247]1512                                m_BaseFilterClassIdentifier(CLSID_NULL),
1513                                m_PropertyPageClassIdentifier(PropertyPageClassIdentifier),
[231]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;
[242]1540                CTreeItem m_ActionItem;
[233]1541                CTreeItem m_EmailItem;
[256]1542                CTreeItem m_EmailLogItem;
[231]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;
[242]1551                CActionDialog m_ActionDialog;
[233]1552                CEmailDialog m_EmailDialog;
[256]1553                CEmailLogDialog m_EmailLogDialog;
[231]1554
[242]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
[231]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();
[233]1584                        #pragma region Filter
1585                        CTreeItem FiltersItem = m_TreeView.InsertItem(NULL, NULL, CData(CData::TYPE_FILTERS), _T("Filters"));
[231]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];
[247]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);
[231]1597                                PreviousFilterItem = FilterItem;
[233]1598                                #pragma region Property Page
[231]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                                }
[233]1635                                #pragma endregion
[231]1636                        }
1637                        m_TreeView.Expand(FiltersItem);
1638                        m_FiltersItem.m_hTreeItem = FiltersItem;
1639                        m_FiltersItem.m_pTreeView = &m_TreeView;
[233]1640                        #pragma endregion
[242]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"));
[233]1645                        m_EmailItem.m_hTreeItem = EmailItem;
1646                        m_EmailItem.m_pTreeView = &m_TreeView;
[256]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);
[231]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                }
[242]1672                INT_PTR DoModal(HWND hParentWindow = GetActiveWindow())
1673                {
1674                        return CDialogWithAccelerators::DoModal(hParentWindow);
1675                }
[231]1676
1677        // CDialogResize
1678                VOID DlgResize_UpdateLayout(INT nWidth, INT nHeight)
1679                {
1680                        __super::DlgResize_UpdateLayout(nWidth, nHeight);
[240]1681                        const CRect Position = GetTextEditPosition();
[231]1682                        if(m_pCurrentSite && m_pCurrentSite->m_pPropertyPage)
[240]1683                                _V(m_pCurrentSite->m_pPropertyPage->Move(Position));
[242]1684                        _W(m_ActionDialog.SetWindowPos(NULL, Position, SWP_NOZORDER | SWP_NOACTIVATE));
[240]1685                        _W(m_EmailDialog.SetWindowPos(NULL, Position, SWP_NOZORDER | SWP_NOACTIVATE));
[256]1686                        _W(m_EmailLogDialog.SetWindowPos(NULL, Position, SWP_NOZORDER | SWP_NOACTIVATE));
[231]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
[242]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
[231]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);
[242]1731                                __E(m_ActionDialog.Create(m_hWnd, (LPARAM) this));
[233]1732                                __E(m_EmailDialog.Create(m_hWnd, (LPARAM) this));
[256]1733                                __E(m_EmailLogDialog.Create(m_hWnd, (LPARAM) this));
[231]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                }
[247]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                }
[231]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);
[242]1820                                if(Data.m_Type != CData::TYPE_ACTION)
1821                                        m_ActionDialog.ShowWindow(SW_HIDE);
[233]1822                                if(Data.m_Type != CData::TYPE_EMAIL)
1823                                        m_EmailDialog.ShowWindow(SW_HIDE);
[256]1824                                if(Data.m_Type != CData::TYPE_EMAIL_LOG)
1825                                        m_EmailLogDialog.ShowWindow(SW_HIDE);
[231]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)));
[236]1898                                                                sText += AtlFormatString(_T("%d. ") _T("%s") _T("\r\n"), 1 + nPinIndex, sPinText);
[231]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
[265]1918                                                #pragma region Runtime Property Bag
1919                                                _ATLTRY
1920                                                {
[290]1921                                                        const CString sPropertyBagText = CRunPropertyBagHelper::GetPropertyBagText(Data.m_pBaseFilter, CComQIPtr<ISpy>(m_Owner.m_pFilterGraph));
[266]1922                                                        if(!sPropertyBagText.IsEmpty())
[265]1923                                                        {
[266]1924                                                                sText += AtlFormatString(_T("## ") _T("Runtime Properties") _T("\r\n") _T("\r\n"));
1925                                                                sText += sPropertyBagText;
1926                                                                sText += _T("\r\n");
[265]1927                                                        }
1928                                                }
1929                                                _ATLCATCHALL()
1930                                                {
1931                                                        _Z_EXCEPTION();
1932                                                }
1933                                                #pragma endregion
[231]1934                                                m_TextEdit.SetValue(sText);
1935                                                m_ApplyButton.EnableWindow(FALSE);
1936                                        }
1937                                } else
1938                                {
1939                                        CWaitCursor WaitCursor;
1940                                        HideCurrentSite();
[233]1941                                        switch(Data.m_Type)
1942                                        {
[242]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
[233]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
[256]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
[233]1961                                        default:
1962                                                m_TextEdit.ShowWindow(SW_SHOW);
1963                                                m_TextEdit.SetValue(m_Owner.GetText());
[242]1964                                                m_ActionDialog.ShowWindow(SW_HIDE);
[233]1965                                                m_EmailDialog.ShowWindow(SW_HIDE);
[256]1966                                                m_EmailLogDialog.ShowWindow(SW_HIDE);
[233]1967                                        }
[231]1968                                        m_ApplyButton.EnableWindow(FALSE);
1969                                }
1970                        } else
1971                        {
1972                                HideCurrentSite();
1973                                m_TextEdit.ShowWindow(SW_HIDE);
[242]1974                                m_ActionDialog.ShowWindow(SW_HIDE);
[233]1975                                m_EmailDialog.ShowWindow(SW_HIDE);
[256]1976                                m_EmailLogDialog.ShowWindow(SW_HIDE);
[231]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                }
[258]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                }
[242]2069                LRESULT OnActionCommand(UINT, INT nIdentifier, HWND)
2070                {
2071                        return m_ActionDialog.SendMessage(WM_COMMAND, nIdentifier);
2072                }
[231]2073        };
2074
[199]2075private:
2076        mutable CRoCriticalSection m_DataCriticalSection;
[285]2077        CProcessData m_ProcessData;
[199]2078        CComPtr<IFilterGraph> m_pFilterGraph;
2079
2080public:
2081// CFilterGraphHelper
[231]2082        static HRESULT WINAPI UpdateRegistry(BOOL bRegister)
[199]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        {
[290]2097                _Z4_THIS();
[199]2098        }
2099        ~CFilterGraphHelper()
2100        {
[290]2101                _Z4_THIS();
[199]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        }
[233]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        }
[199]2159        #define I FormatIdentifier
[207]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 },
[231]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);
[207]2200        }
[199]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        }
[285]2215        static CString GetFilterText(IBaseFilter* pBaseFilter, const CProcessData* pProcessData, IReferenceClock* pFilterGraphReferenceClock = NULL)
[231]2216        {
2217                CString sText;
[280]2218                #pragma region COM
[285]2219                CString sPath;
[231]2220                const CStringW sClassIdentifierString = _FilterGraphHelper::GetFilterClassIdentifierString(pBaseFilter);
2221                if(!sClassIdentifierString.IsEmpty())
[265]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                                {
[285]2230                                        sPath = _RegKeyHelper::QueryStringValue(HKEY_CLASSES_ROOT, AtlFormatString(_T("CLSID\\%ls\\InprocServer32"), sClassIdentifierString));
[265]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                }
[285]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                        }
[280]2273                #pragma endregion
[285]2274                #pragma region Pin
[231]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));
[285]2281                #pragma endregion
[231]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
[280]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
[231]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));
[276]2440                                if(!sSubtype.IsEmpty())
2441                                        Array.Add(I(sSubtype));
[231]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)));
[276]2449                                        if(VideoInfoHeader2.AvgTimePerFrame > 0)
2450                                                Array.Add(AtlFormatString(_T("%s frames/sec"), I(_StringHelper::FormatNumber(1E7 / VideoInfoHeader2.AvgTimePerFrame, 3))));
[231]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                                pnExtraData = pMediaType->pbFormat + pMediaType->cbFormat - nExtraDataSize;
2663                        sText += AtlFormatString(_T("  * ") _T("Extra Data: %s") _T("\r\n"), I(AtlFormatData(pnExtraData, nExtraDataSize).TrimRight()));
2664                }
2665                #pragma endregion
2666                return sText;
2667        }
[199]2668        static CString GetText(IFilterGraph* pFilterGraph, const CProcessData* pProcessData = NULL)
2669        {
2670                if(!pFilterGraph)
2671                        return (LPCTSTR) NULL;
[285]2672                const CComQIPtr<ISpy> pSpy = pFilterGraph;
[199]2673                CString sText;
2674                sText += AtlFormatString(_T("# ") _T("Filter Graph") _T("\r\n") _T("\r\n"));
2675                #pragma region Graph Parameters
2676                if(pProcessData)
2677                        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)));
2678                #pragma region IMediaControl
2679                const CComQIPtr<IMediaControl> pMediaControl = pFilterGraph;
2680                if(pMediaControl)
2681                        _ATLTRY
2682                        {
2683                                OAFilterState State;
2684                                const HRESULT nGetStateResult = pMediaControl->GetState(0, &State);
2685                                _Z45_DSHRESULT(nGetStateResult);
2686                                static const LPCTSTR g_ppszStates[] = { _T("Stopped"), _T("Paused"), _T("Running"), };
2687                                if(SUCCEEDED(nGetStateResult) && (SIZE_T) State < DIM(g_ppszStates))
2688                                        sText += AtlFormatString(_T("* ") _T("State: %s") _T("\r\n"), I(g_ppszStates[(SIZE_T) State]));
2689                        }
2690                        _ATLCATCHALL()
2691                        {
2692                                _Z_EXCEPTION();
2693                        }
2694                #pragma endregion
2695                #pragma region IMediaPosition
2696                const CComQIPtr<IMediaPosition> pMediaPosition = pFilterGraph;
2697                if(pMediaPosition)
2698                        _ATLTRY
2699                        {
2700                                DOUBLE fDuration = 0, fPosition = 0;
2701                                const HRESULT nGetDurationResult = pMediaPosition->get_Duration(&fDuration);
2702                                _Z45_DSHRESULT(nGetDurationResult);
2703                                if(fDuration > 0)
2704                                {
2705                                        sText += AtlFormatString(_T("* ") _T("Duration: %s (%s seconds)") _T("\r\n"), I(_FilterGraphHelper::FormatSecondTime(fDuration)), I(_StringHelper::FormatNumber(fDuration, 3)));
2706                                        const HRESULT nCurrentPositionResult = pMediaPosition->get_CurrentPosition(&fPosition);
2707                                        _Z45_DSHRESULT(nCurrentPositionResult);
2708                                        if(SUCCEEDED(nCurrentPositionResult))
2709                                                sText += AtlFormatString(_T("* ") _T("Position: %s (%s seconds)") _T("\r\n"), I(_FilterGraphHelper::FormatSecondTime(fPosition)), I(_StringHelper::FormatNumber(fPosition, 3)));
2710                                }
2711                        }
2712                        _ATLCATCHALL()
2713                        {
2714                                _Z_EXCEPTION();
2715                        }
2716                #pragma endregion
2717                if(pProcessData)
2718                {
2719                        if(!pProcessData->m_sDisplayName.IsEmpty())
2720                                sText += AtlFormatString(_T("* ") _T("Display Name: %s") _T("\r\n"), I(pProcessData->m_sDisplayName));
[285]2721                        if(_tcslen(pProcessData->m_sImagePath))
2722                        {
2723                                const CString sDirectory = (LPCTSTR) GetPathDirectory(pProcessData->m_sImagePath);
2724                                if(!sDirectory.IsEmpty())
2725                                        sText += AtlFormatString(_T("* ") _T("Process Directory: %s") _T("\r\n"), I(sDirectory));
2726                        }
[199]2727                }
[202]2728                const CComQIPtr<IMediaFilter> pMediaFilter = pFilterGraph;
2729                CComPtr<IReferenceClock> pFilterGraphReferenceClock;
2730                const HRESULT nGetSyncSourceResult = pMediaFilter->GetSyncSource(&pFilterGraphReferenceClock);
2731                _Z45_DSHRESULT(nGetSyncSourceResult);
[199]2732                sText += _T("\r\n");
2733                #pragma endregion
2734                #pragma region Filter
2735                _FilterGraphHelper::CFilterArray FilterArray;
2736                _FilterGraphHelper::GetGraphFilters(pFilterGraph, FilterArray);
2737                if(!FilterArray.IsEmpty())
2738                {
2739                        sText += AtlFormatString(_T("## ") _T("Filters") _T("\r\n") _T("\r\n"));
2740                        for(SIZE_T nIndex = 0; nIndex < FilterArray.GetCount(); nIndex++)
2741                                _ATLTRY
2742                                {
2743                                        const CComPtr<IBaseFilter>& pBaseFilter = FilterArray[nIndex];
2744                                        sText += AtlFormatString(_T("%d. ") _T("%ls") _T("\r\n"), nIndex + 1, _FilterGraphHelper::GetFilterName(pBaseFilter));
[285]2745                                        sText += GetFilterText(pBaseFilter, pProcessData, pFilterGraphReferenceClock);
[199]2746                                }
2747                                _ATLCATCHALL()
2748                                {
2749                                        _Z_EXCEPTION();
2750                                }
2751                        sText += _T("\r\n");
2752                        #pragma region Connection
2753                        sText += AtlFormatString(_T("## ") _T("Connections") _T("\r\n") _T("\r\n"));
2754                        INT nConnectionIndex = 0;
2755                        for(SIZE_T nFilterIndex = 0; nFilterIndex < FilterArray.GetCount(); nFilterIndex++)
2756                        {
2757                                const CComPtr<IBaseFilter>& pBaseFilter = FilterArray[nFilterIndex];
2758                                _FilterGraphHelper::CPinArray PinArray;
2759                                _FilterGraphHelper::GetFilterPins(pBaseFilter, PINDIR_OUTPUT, PinArray);
[231]2760                                for(SIZE_T nPinIndex = 0; nPinIndex < PinArray.GetCount(); nPinIndex++)
[199]2761                                {
2762                                        const CComPtr<IPin>& pOutputPin = PinArray[nPinIndex];
2763                                        const CComPtr<IPin> pInputPin = _FilterGraphHelper::GetPeerPin(pOutputPin);
2764                                        if(!pInputPin)
2765                                                continue;
[231]2766                                        sText += AtlFormatString(_T("%d. ") _T("%s") _T("\r\n"), ++nConnectionIndex, GetConnectionText(pOutputPin, pInputPin));
[199]2767                                }
2768                        }
2769                        sText += _T("\r\n");
2770                        #pragma endregion
2771                        #pragma region Media Type
2772                        sText += AtlFormatString(_T("## ") _T("Media Types") _T("\r\n") _T("\r\n"));
2773                        INT nGlobalPinIndex = 0;
2774                        CRoListT<CComPtr<IPin>> PinList;
2775                        for(SIZE_T nFilterIndex = 0; nFilterIndex < FilterArray.GetCount(); nFilterIndex++)
2776                        {
2777                                const CComPtr<IBaseFilter>& pBaseFilter = FilterArray[nFilterIndex];
2778                                _FilterGraphHelper::CPinArray PinArray;
2779                                _FilterGraphHelper::GetFilterPins(pBaseFilter, PinArray);
[231]2780                                for(SIZE_T nPinIndex = 0; nPinIndex < PinArray.GetCount(); nPinIndex++)
[199]2781                                {
2782                                        const CComPtr<IPin>& pPin = PinArray[nPinIndex];
2783                                        if(PinList.FindFirst(pPin))
2784                                                continue;
2785                                        PinList.AddTail(pPin);
2786                                        CString sPinText = AtlFormatString(_T("%s"), I(_FilterGraphHelper::GetPinFullName(pPin)));
2787                                        const CComPtr<IPin> pPeerPin = _FilterGraphHelper::GetPeerPin(pPin);
2788                                        if(pPeerPin)
2789                                        {
2790                                                PinList.AddTail(pPeerPin);
2791                                                sPinText += AtlFormatString(_T(", %s"), I(_FilterGraphHelper::GetPinFullName(pPeerPin)));
2792                                        }
2793                                        sText += AtlFormatString(_T("%d. ") _T("%s") _T("\r\n"), ++nGlobalPinIndex, sPinText);
2794                                        _ATLTRY
2795                                        {
2796                                                CMediaType pMediaType;
2797                                                if(pPeerPin)
2798                                                        pMediaType = _FilterGraphHelper::GetPinMediaType(pPin);
2799                                                else
2800                                                        pMediaType = _FilterGraphHelper::EnumerateFirstPinMediaType(pPin);
2801                                                if(!pMediaType)
2802                                                        continue;
[231]2803                                                sText += GetMediaTypeText(pMediaType);
[199]2804                                        }
2805                                        _ATLCATCHALL()
2806                                        {
2807                                                _Z_EXCEPTION();
2808                                        }
2809                                }
2810                        }
2811                        sText += _T("\r\n");
2812                        #pragma endregion
[280]2813                        #pragma region IMediaSeeking
2814                        BOOL bMediaSeekingHeaderAdded = FALSE;
2815                        for(SIZE_T nFilterIndex = 0; nFilterIndex < FilterArray.GetCount(); nFilterIndex++)
2816                        {
2817                                const CComPtr<IBaseFilter>& pBaseFilter = FilterArray[nFilterIndex];
2818                                _FilterGraphHelper::CPinArray PinArray;
2819                                _FilterGraphHelper::GetFilterPins(pBaseFilter, PINDIR_OUTPUT, PinArray);
2820                                for(SIZE_T nPinIndex = 0; nPinIndex < PinArray.GetCount(); nPinIndex++)
2821                                {
2822                                        const CComPtr<IPin>& pOutputPin = PinArray[nPinIndex];
2823                                        const CComQIPtr<IMediaSeeking> pMediaSeeking = pOutputPin;
2824                                        if(!pMediaSeeking)
2825                                                continue;
2826                                        if(!bMediaSeekingHeaderAdded)
2827                                        {
2828                                                sText += AtlFormatString(_T(" ## ") _T("Media Seeking/Position") _T("\r\n") _T("\r\n"));
2829                                                bMediaSeekingHeaderAdded = TRUE;
2830                                        }
2831                                        sText += AtlFormatString(_T(" * ") _T("Pin: %s") _T("\r\n"), I(_FilterGraphHelper::GetPinFullName(pOutputPin)));
2832                                        _ATLTRY
2833                                        {
2834                                                DWORD nCapabilities = 0;
2835                                                if(SUCCEEDED(pMediaSeeking->GetCapabilities(&nCapabilities)))
2836                                                        sText += AtlFormatString(_T("  * ") _T("Capabilities: %s") _T("\r\n"), I(AtlFormatString(_T("0x%X"), nCapabilities)));
2837                                                LONGLONG nDuration = 0, nPosition = 0, nStopPosition = 0;
2838                                                if(SUCCEEDED(pMediaSeeking->GetDuration(&nDuration)))
2839                                                        sText += AtlFormatString(_T("  * ") _T("Duration: %s (%s seconds)") _T("\r\n"), I(_FilterGraphHelper::FormatSecondTime((DOUBLE) nDuration / 1E7)), I(_StringHelper::FormatNumber((DOUBLE) nDuration / 1E7, 3)));
2840                                                if(SUCCEEDED(pMediaSeeking->GetCurrentPosition(&nPosition)))
2841                                                        sText += AtlFormatString(_T("  * ") _T("Position: %s (%s seconds)") _T("\r\n"), I(_FilterGraphHelper::FormatSecondTime((DOUBLE) nPosition / 1E7)), I(_StringHelper::FormatNumber((DOUBLE) nPosition / 1E7, 3)));
2842                                                if(SUCCEEDED(pMediaSeeking->GetStopPosition(&nStopPosition)))
2843                                                        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)));
2844                                                DOUBLE fRate = 1.0;
2845                                                if(SUCCEEDED(pMediaSeeking->GetRate(&fRate)))
2846                                                        sText += AtlFormatString(_T("  * ") _T("Rate: %s") _T("\r\n"), I(_StringHelper::FormatNumber(fRate, 3)));
2847                                                LONGLONG nPreroll = 0;
2848                                                if(SUCCEEDED(pMediaSeeking->GetPreroll(&nPreroll)) && nPreroll)
2849                                                        sText += AtlFormatString(_T("  * ") _T("Preroll: %s seconds") _T("\r\n"), I(_StringHelper::FormatNumber((DOUBLE) nPreroll / 1E7, 3)));
2850                                        }
2851                                        _ATLCATCHALL()
2852                                        {
2853                                                _Z_EXCEPTION();
2854                                        }
2855                                }
2856                        }
2857                        if(bMediaSeekingHeaderAdded)
2858                                sText += _T("\r\n");
2859                        #pragma endregion
[265]2860                        #pragma region Runtime Property Bag
2861                        BOOL bRunPropertyBagHeaderAdded = FALSE;
2862                        for(SIZE_T nIndex = 0; nIndex < FilterArray.GetCount(); nIndex++)
2863                                _ATLTRY
2864                                {
2865                                        const CComPtr<IBaseFilter>& pBaseFilter = FilterArray[nIndex];
[266]2866                                        //_Z4(atlTraceGeneral, 4, _T("pBaseFilter 0x%p \"%ls\"\n"), pBaseFilter, _FilterGraphHelper::GetFilterName(pBaseFilter));
[290]2867                                        const CString sPropertyBagText = CRunPropertyBagHelper::GetPropertyBagText(pBaseFilter, pSpy);
[265]2868                                        if(sPropertyBagText.IsEmpty())
2869                                                continue;
2870                                        if(!bRunPropertyBagHeaderAdded)
2871                                        {
2872                                                sText += AtlFormatString(_T("## ") _T("Runtime Properties") _T("\r\n") _T("\r\n"));
2873                                                bRunPropertyBagHeaderAdded = TRUE;
2874                                        }
2875                                        sText += AtlFormatString(_T("### ") _T("Filter: %ls") _T("\r\n") _T("\r\n"), _FilterGraphHelper::GetFilterName(pBaseFilter));
2876                                        sText += sPropertyBagText;
2877                                        sText += _T("\r\n");
2878                                }
2879                                _ATLCATCHALL()
2880                                {
2881                                        _Z_EXCEPTION();
2882                                }
2883                        #pragma endregion
[199]2884                }
2885                #pragma endregion
2886                return sText;
2887        }
2888        #undef I
[231]2889        CComPtr<IFilterGraph> GetFilterGraph() const
2890        {
2891                CRoCriticalSectionLock DataLock(m_DataCriticalSection);
2892                return m_pFilterGraph;
2893        }
[285]2894        VOID SetFilterGraph(IFilterGraph* pFilterGraph, CProcessData* pProcessData = NULL) 
[231]2895        {
2896                CRoCriticalSectionLock DataLock(m_DataCriticalSection);
[285]2897                if(!pProcessData)
2898                {
2899                        m_ProcessData = CProcessData();
2900                        const CComQIPtr<ISpyEx> pSpyEx = pFilterGraph;
2901                        if(pSpyEx)
2902                                m_ProcessData.m_nIdentifier = GetCurrentProcessId();
2903                } else
2904                        m_ProcessData = *pProcessData;
[231]2905                m_pFilterGraph = pFilterGraph;
2906        }
[285]2907        BOOL SetFilterGraph(IUnknown* pFilterGraphUnknown, CProcessData* pProcessData = NULL) 
[233]2908        {
2909                CComQIPtr<IFilterGraph> pFilterGraph;
2910                if(pFilterGraphUnknown)
2911                {
2912                        pFilterGraph = pFilterGraphUnknown;
2913                        if(!pFilterGraph)
2914                        {
2915                                const CComQIPtr<IBaseFilter> pBaseFilter = pFilterGraphUnknown;
2916                                if(!pBaseFilter)
2917                                {
2918                                        const CComQIPtr<IPin> pPin = pFilterGraphUnknown;
2919                                        if(pPin)
2920                                                pFilterGraph = _FilterGraphHelper::GetFilterGraph(_FilterGraphHelper::GetPinFilter(pPin));
2921                                } else
2922                                        pFilterGraph = _FilterGraphHelper::GetFilterGraph(pBaseFilter);
2923                        }
2924                }
[285]2925                SetFilterGraph(pFilterGraph, pProcessData);
2926                return pFilterGraph != NULL;
[233]2927        }
[285]2928        CString GetFilterText(IBaseFilter* pBaseFilter) const
2929        {
2930                return GetFilterText(pBaseFilter, m_ProcessData.m_nIdentifier ? &m_ProcessData : NULL);
2931        }
[231]2932        CString GetText() const
2933        {
2934                CRoCriticalSectionLock DataLock(m_DataCriticalSection);
[285]2935                return GetText(m_pFilterGraph, m_ProcessData.m_nIdentifier ? &m_ProcessData : NULL);
[231]2936        }
[242]2937        static LPCTSTR GetPlatformName()
2938        {
2939                #if defined(_WIN64)
2940                        return _T("x64");
2941                #else
2942                        return _T("Win32");
2943                #endif // defined(_WIN64)
2944        }
2945        template <SIZE_T t_nItemCount>
2946        static CString& GetLegacyFilter(const COMDLG_FILTERSPEC (&pItems)[t_nItemCount], CString& sFilter)
2947        {
2948                _A(sFilter.IsEmpty());
2949                for(SIZE_T nIndex = 0; nIndex < t_nItemCount; nIndex++)
2950                {
2951                        const COMDLG_FILTERSPEC& Item = pItems[nIndex];
2952                        sFilter += AtlFormatString(_T("%s (%s)|%s|"), Item.pszName, Item.pszSpec, Item.pszSpec);
2953                }
2954                sFilter.Replace(_T('|'), 0);
2955                return sFilter;
2956        }
2957        static BOOL OpenMonikerWithGsn(LPCWSTR pszMonikerDisplayName, HWND hParentWindow = GetActiveWindow())
2958        {
2959                _A(pszMonikerDisplayName);
2960                static const LPCTSTR g_pszValueName = _T("GraphStudioNext Path");
2961                static const LPCTSTR g_pszFileName = _T("graphstudionext.exe");
2962                const CString sValueName = AtlFormatString(_T("%s (%s)"), g_pszValueName, GetPlatformName());
2963                CString sPath = _RegKeyHelper::QueryStringValue(HKEY_CURRENT_USER, REGISTRY_ROOT, sValueName);
2964                if(!FileExists(sPath))
2965                        sPath.Empty();
2966                #pragma region Current Directory
2967                if(sPath.IsEmpty())
2968                {
2969                        sPath = (LPCTSTR) Combine(GetPathDirectory(GetModulePath()), g_pszFileName);
2970                        if(!FileExists(sPath))
2971                                sPath.Empty();
2972                }
2973                #pragma endregion
2974                #pragma region Application Registry
2975                if(sPath.IsEmpty())
2976                {
2977                        #if defined(_WIN64)
2978                                static const LPCTSTR g_pszValueName = _T("exeLocation64");
2979                        #else
2980                                static const LPCTSTR g_pszValueName = _T("exeLocation");
2981                        #endif // defined(_WIN64)
2982                        sPath = _RegKeyHelper::QueryStringValue(HKEY_CURRENT_USER, _T("Software\\MONOGRAM\\GraphStudioNext"), g_pszValueName);
2983                        if(!FileExists(sPath))
2984                                sPath.Empty();
2985                }
2986                #pragma endregion
2987                if(sPath.IsEmpty())
2988                {
2989                        #pragma region Prompt
2990                        static const COMDLG_FILTERSPEC g_pFilter[] = 
2991                        {
2992                                { _T("Executable Files"), _T("*.exe") },
2993                                { _T("All Files"), _T("*.*") },
2994                        };
2995                        if(GetOsVersion() >= GetWinVistaOsVersion())
2996                        {
2997                                CShellFileOpenDialog Dialog(g_pszFileName, FOS_FORCEFILESYSTEM | FOS_FILEMUSTEXIST, _T("exe"), g_pFilter, DIM(g_pFilter));
2998                                if(Dialog.DoModal(hParentWindow) != IDOK)
2999                                        return FALSE;
3000                                __C(Dialog.GetFilePath(sPath));
3001                        } else
3002                        {
3003                                CString sFilter;
3004                                CFileDialog Dialog(TRUE, _T("exe"), NULL, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_EXPLORER | OFN_ENABLESIZING, GetLegacyFilter(g_pFilter, sFilter));
3005                                if(Dialog.DoModal(hParentWindow) != IDOK)
3006                                        return FALSE;
3007                                sPath = Dialog.m_szFileName;
3008                        }
3009                        #pragma endregion
3010                        _RegKeyHelper::SetStringValue(HKEY_CURRENT_USER, REGISTRY_ROOT, sValueName, sPath);
3011                }
3012                CWaitCursor WaitCursor;
3013                CString sParameters = AtlFormatString(_T("-a \"%ls\""), pszMonikerDisplayName);
3014                SHELLEXECUTEINFO Infomation;
3015                ZeroMemory(&Infomation, sizeof Infomation);
3016                Infomation.cbSize = sizeof Infomation;
3017                Infomation.lpFile = sPath;
3018                Infomation.lpParameters = sParameters;
3019                Infomation.nShow = SW_SHOWNORMAL;
3020                __E(ShellExecuteEx(&Infomation));
3021                return TRUE;
3022        }
3023        static BOOL OpenMonikerWithGe(LPCWSTR pszMonikerDisplayName, HWND hParentWindow = GetActiveWindow())
3024        {
3025                static const LPCTSTR g_pszValueName = _T("GraphEdit Path");
3026                static const LPCTSTR g_pszFileName = _T("graphedt.exe");
3027                const CString sValueName = AtlFormatString(_T("%s (%s)"), g_pszValueName, GetPlatformName());
3028                CString sPath = _RegKeyHelper::QueryStringValue(HKEY_CURRENT_USER, REGISTRY_ROOT, sValueName);
3029                if(!FileExists(sPath))
3030                        sPath.Empty();
3031                #pragma region Current Directory
3032                if(sPath.IsEmpty())
3033                {
3034                        sPath = (LPCTSTR) Combine(GetPathDirectory(GetModulePath()), g_pszFileName);
3035                        if(!FileExists(sPath))
3036                                sPath.Empty();
3037                }
3038                #pragma endregion
3039                // SUGG: Look for Windows SDK
3040                if(sPath.IsEmpty())
3041                {
3042                        #pragma region Prompt
3043                        static const COMDLG_FILTERSPEC g_pFilter[] = 
3044                        {
3045                                { _T("Executable Files"), _T("*.exe") },
3046                                { _T("All Files"), _T("*.*") },
3047                        };
3048                        if(GetOsVersion() >= GetWinVistaOsVersion())
3049                        {
3050                                CShellFileOpenDialog Dialog(g_pszFileName, FOS_FORCEFILESYSTEM | FOS_FILEMUSTEXIST, _T("exe"), g_pFilter, DIM(g_pFilter));
3051                                if(Dialog.DoModal(hParentWindow) != IDOK)
3052                                        return FALSE;
3053                                __C(Dialog.GetFilePath(sPath));
3054                        } else
3055                        {
3056                                CString sFilter;
3057                                CFileDialog Dialog(TRUE, _T("exe"), NULL, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_EXPLORER | OFN_ENABLESIZING, GetLegacyFilter(g_pFilter, sFilter));
3058                                if(Dialog.DoModal(hParentWindow) != IDOK)
3059                                        return FALSE;
3060                                sPath = Dialog.m_szFileName;
3061                        }
3062                        #pragma endregion
3063                        _RegKeyHelper::SetStringValue(HKEY_CURRENT_USER, REGISTRY_ROOT, sValueName, sPath);
3064                }
3065                CStringW sFilterGraphMonikerDisplayName = pszMonikerDisplayName;
3066                const INT nSeparatorPosition = sFilterGraphMonikerDisplayName.Find(L';');
3067                if(nSeparatorPosition >= 0)
3068                        sFilterGraphMonikerDisplayName = sFilterGraphMonikerDisplayName.Left(nSeparatorPosition);
3069                CWaitCursor WaitCursor;
3070                CString sParameters = AtlFormatString(_T("-a %ls"), sFilterGraphMonikerDisplayName);
3071                SHELLEXECUTEINFO Infomation;
3072                ZeroMemory(&Infomation, sizeof Infomation);
3073                Infomation.cbSize = sizeof Infomation;
3074                Infomation.lpFile = sPath;
3075                Infomation.lpParameters = sParameters;
3076                Infomation.nShow = SW_SHOWNORMAL;
3077                __E(ShellExecuteEx(&Infomation));
3078                return TRUE;
3079        }
[199]3080
3081// IFilterGraphHelper
[231]3082        STDMETHOD(get_FilterGraph)(IUnknown** ppFilterGraphUnknown)
[199]3083        {
3084                _Z4(atlTraceCOM, 4, _T("...\n"));
3085                _ATLTRY
3086                {
3087                        __D(ppFilterGraphUnknown, E_POINTER);
[231]3088                        *ppFilterGraphUnknown = GetFilterGraph().Detach();
[199]3089                }
3090                _ATLCATCH(Exception)
3091                {
3092                        _C(Exception);
3093                }
3094                return S_OK;
3095        }
[231]3096        STDMETHOD(put_FilterGraph)(IUnknown* pFilterGraphUnknown)
[199]3097        {
3098                _Z4(atlTraceCOM, 4, _T("pFilterGraphUnknown 0x%p\n"), pFilterGraphUnknown);
3099                _ATLTRY
3100                {
[233]3101                        if(!SetFilterGraph(pFilterGraphUnknown))
3102                                return S_FALSE;
[199]3103                }
3104                _ATLCATCH(Exception)
3105                {
3106                        _C(Exception);
3107                }
3108                return S_OK;
3109        }
[231]3110        STDMETHOD(get_Text)(BSTR* psText)
[199]3111        {
3112                _Z4(atlTraceCOM, 4, _T("...\n"));
3113                _ATLTRY
3114                {
3115                        __D(psText, E_POINTER);
3116                        CRoCriticalSectionLock DataLock(m_DataCriticalSection);
3117                        *psText = CComBSTR(GetText(m_pFilterGraph)).Detach();
3118                }
3119                _ATLCATCH(Exception)
3120                {
3121                        _C(Exception);
3122                }
3123                return S_OK;
3124        }
[231]3125        STDMETHOD(DoPropertyFrameModal)(LONG nParentWindowHandle)
3126        {
[247]3127                _Z4(atlTraceCOM, 4, _T("nParentWindowHandle 0x%08X\n"), nParentWindowHandle);
[231]3128                _ATLTRY
3129                {
3130                        CWindow ParentWindow = (HWND) (LONG_PTR) nParentWindowHandle;
3131                        if(!ParentWindow)
3132                                ParentWindow = GetActiveWindow();
[247]3133                        //__D(!ParentWindow || ParentWindow.IsWindow(), E_INVALIDARG);
[231]3134                        const CComQIPtr<IFilterGraph2> pFilterGraph2 = GetFilterGraph();
3135                        __D(pFilterGraph2, E_NOINTERFACE);
3136                        CPropertyFrameDialog PropertyFrameDialog(this);
3137                        PropertyFrameDialog.DoModal(ParentWindow);
3138                }
3139                _ATLCATCH(Exception)
3140                {
3141                        _C(Exception);
3142                }
3143                return S_OK;
3144        }
[247]3145        STDMETHOD(DoFilterGraphListModal)(LONG nParentWindowHandle)
3146        {
3147                _Z4(atlTraceCOM, 4, _T("nParentWindowHandle 0x%08X\n"), nParentWindowHandle);
3148                _ATLTRY
3149                {
3150                        CWindow ParentWindow = (HWND) (LONG_PTR) nParentWindowHandle;
3151                        if(!ParentWindow)
3152                                ParentWindow = GetActiveWindow();
3153                        //__D(!ParentWindow || ParentWindow.IsWindow(), E_INVALIDARG);
3154                        DoFilterGraphListPropertySheetModal(ParentWindow);
3155                }
3156                _ATLCATCH(Exception)
3157                {
3158                        _C(Exception);
3159                }
3160                return S_OK;
3161        }
3162        STDMETHOD(OpenGraphStudioNext)(LONG nParentWindowHandle, BSTR sMonikerDisplayName, VARIANT_BOOL* pbResult)
3163        {
3164                _Z4(atlTraceCOM, 4, _T("nParentWindowHandle 0x%08X, sMonikerDisplayName \"%s\"\n"), nParentWindowHandle, CString(sMonikerDisplayName));
3165                _ATLTRY
3166                {
3167                        __D(sMonikerDisplayName && *sMonikerDisplayName, E_INVALIDARG);
3168                        CWindow ParentWindow = (HWND) (LONG_PTR) nParentWindowHandle;
3169                        if(!ParentWindow)
3170                                ParentWindow = GetActiveWindow();
3171                        //__D(!ParentWindow || ParentWindow.IsWindow(), E_INVALIDARG);
3172                        const BOOL bResult = OpenMonikerWithGsn(sMonikerDisplayName, ParentWindow);
3173                        if(pbResult)
3174                                *pbResult = bResult ? ATL_VARIANT_TRUE : ATL_VARIANT_FALSE;
3175                }
3176                _ATLCATCH(Exception)
3177                {
3178                        _C(Exception);
3179                }
3180                return S_OK;
3181        }
3182        STDMETHOD(OpenGraphEdit)(LONG nParentWindowHandle, BSTR sMonikerDisplayName, VARIANT_BOOL* pbResult)
3183        {
3184                _Z4(atlTraceCOM, 4, _T("nParentWindowHandle 0x%08X, sMonikerDisplayName \"%s\"\n"), nParentWindowHandle, CString(sMonikerDisplayName));
3185                _ATLTRY
3186                {
3187                        __D(sMonikerDisplayName && *sMonikerDisplayName, E_INVALIDARG);
3188                        CWindow ParentWindow = (HWND) (LONG_PTR) nParentWindowHandle;
3189                        if(!ParentWindow)
3190                                ParentWindow = GetActiveWindow();
3191                        //__D(!ParentWindow || ParentWindow.IsWindow(), E_INVALIDARG);
3192                        const BOOL bResult = OpenMonikerWithGe(sMonikerDisplayName, ParentWindow);
3193                        if(pbResult)
3194                                *pbResult = bResult ? ATL_VARIANT_TRUE : ATL_VARIANT_FALSE;
3195                }
3196                _ATLCATCH(Exception)
3197                {
3198                        _C(Exception);
3199                }
3200                return S_OK;
3201        }
[199]3202};
3203
3204OBJECT_ENTRY_AUTO(__uuidof(FilterGraphHelper), CFilterGraphHelper)
[247]3205
[249]3206inline HRESULT FilterGraphHelper_DoPropertyFrameModal(LONG nParentWindowHandle, IUnknown* pFilterGraphUnknown)
3207{
3208        CLocalObjectPtr<CFilterGraphHelper> pFilterGraphHelper;
3209        pFilterGraphHelper->SetFilterGraph(pFilterGraphUnknown);
3210        return pFilterGraphHelper->DoPropertyFrameModal(nParentWindowHandle);
3211}
3212inline HRESULT FilterGraphHelper_DoFilterGraphListModal(LONG nParentWindowHandle)
3213{
3214        CLocalObjectPtr<CFilterGraphHelper> pFilterGraphHelper;
3215        return pFilterGraphHelper->DoFilterGraphListModal(nParentWindowHandle);
3216}
[247]3217inline HRESULT FilterGraphHelper_OpenGraphStudioNext(LONG nParentWindowHandle, LPCWSTR pszMonikerDisplayName, VARIANT_BOOL* pbResult)
3218{
3219        CLocalObjectPtr<CFilterGraphHelper> pFilterGraphHelper;
3220        return pFilterGraphHelper->OpenGraphStudioNext(nParentWindowHandle, CComBSTR(pszMonikerDisplayName), pbResult);
3221}
3222inline HRESULT FilterGraphHelper_OpenGraphEdit(LONG nParentWindowHandle, LPCWSTR pszMonikerDisplayName, VARIANT_BOOL* pbResult)
3223{
3224        CLocalObjectPtr<CFilterGraphHelper> pFilterGraphHelper;
3225        return pFilterGraphHelper->OpenGraphEdit(nParentWindowHandle, CComBSTR(pszMonikerDisplayName), pbResult);
3226}
Note: See TracBrowser for help on using the repository browser.