asf2mkvDlg.cpp

00001 /* 
00002  *      Copyright (C) 2003-2005 Gabest
00003  *      http://www.gabest.org
00004  *
00005  *  This Program is free software; you can redistribute it and/or modify
00006  *  it under the terms of the GNU General Public License as published by
00007  *  the Free Software Foundation; either version 2, or (at your option)
00008  *  any later version.
00009  *   
00010  *  This Program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00013  *  GNU General Public License for more details.
00014  *   
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with GNU Make; see the file COPYING.  If not, write to
00017  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
00018  *  http://www.gnu.org/copyleft/gpl.html
00019  *
00020  */
00021 
00022 // asf2mkvDlg.cpp : implementation file
00023 //
00024 
00025 #include "stdafx.h"
00026 #include "asf2mkv.h"
00027 #include "asf2mkvDlg.h"
00028 
00029 #ifdef _DEBUG
00030 #define new DEBUG_NEW
00031 #endif
00032 
00033 #include <initguid.h>
00034 #include ".\asf2mkvdlg.h"
00035 
00036 //  {6B6D0800-9ADA-11d0-A520-00A0D10129C0}
00037 DEFINE_GUID(CLSID_NetShowSource, 
00038 0x6b6d0800, 0x9ada, 0x11d0, 0xa5, 0x20, 0x0, 0xa0, 0xd1, 0x1, 0x29, 0xc0);
00039 
00040 // CAboutDlg dialog used for App About
00041 
00042 class CAboutDlg : public CDialog
00043 {
00044 public:
00045         CAboutDlg();
00046 
00047 // Dialog Data
00048         enum { IDD = IDD_ABOUTBOX };
00049 
00050         protected:
00051         virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
00052 
00053 // Implementation
00054 protected:
00055         DECLARE_MESSAGE_MAP()
00056 };
00057 
00058 CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
00059 {
00060 }
00061 
00062 void CAboutDlg::DoDataExchange(CDataExchange* pDX)
00063 {
00064         CDialog::DoDataExchange(pDX);
00065 }
00066 
00067 BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
00068 END_MESSAGE_MAP()
00069 
00070 // CUrlDropTarget
00071 
00072 BEGIN_MESSAGE_MAP(CUrlDropTarget, COleDropTarget)
00073 END_MESSAGE_MAP()
00074 
00075 DROPEFFECT CUrlDropTarget::OnDragEnter(CWnd* pWnd, COleDataObject* pDataObject, DWORD dwKeyState, CPoint point)
00076 {
00077         return DROPEFFECT_NONE;
00078 }
00079 
00080 DROPEFFECT CUrlDropTarget::OnDragOver(CWnd* pWnd, COleDataObject* pDataObject, DWORD dwKeyState, CPoint point)
00081 {
00082         UINT CF_URL = RegisterClipboardFormat(_T("UniformResourceLocator"));
00083         return pDataObject->IsDataAvailable(CF_URL) ? DROPEFFECT_COPY : DROPEFFECT_NONE;
00084 }
00085 
00086 BOOL CUrlDropTarget::OnDrop(CWnd* pWnd, COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point)
00087 {
00088         UINT CF_URL = RegisterClipboardFormat(_T("UniformResourceLocator"));
00089 
00090         BOOL bResult = FALSE;
00091 
00092         if(pDataObject->IsDataAvailable(CF_URL)) 
00093         {
00094                 FORMATETC fmt = {CF_URL, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
00095                 if(HGLOBAL hGlobal = pDataObject->GetGlobalData(CF_URL, &fmt))
00096                 {
00097                         LPCSTR pText = (LPCSTR)GlobalLock(hGlobal);
00098                         if(AfxIsValidString(pText))
00099                         {
00100                                 AfxGetMainWnd()->SendMessage(WM_OPENURL, 0, (LPARAM)pText);
00101                                 GlobalUnlock(hGlobal);
00102                                 bResult = TRUE;
00103                         }
00104                 }
00105         }
00106 
00107         return bResult;
00108 }
00109 
00110 DROPEFFECT CUrlDropTarget::OnDropEx(CWnd* pWnd, COleDataObject* pDataObject, DROPEFFECT dropDefault, DROPEFFECT dropList, CPoint point)
00111 {
00112         return (DROPEFFECT)-1;
00113 }
00114 
00115 void CUrlDropTarget::OnDragLeave(CWnd* pWnd)
00116 {
00117 }
00118 
00119 DROPEFFECT CUrlDropTarget::OnDragScroll(CWnd* pWnd, DWORD dwKeyState, CPoint point)
00120 {
00121         return DROPEFFECT_NONE;
00122 }
00123 
00124 // Casf2mkvDlg dialog
00125 
00126 #define WM_GRAPHNOTIFY (WM_APP+1)
00127 
00128 Casf2mkvDlg::Casf2mkvDlg(CWnd* pParent /*=NULL*/)
00129         : CResizableDialog(Casf2mkvDlg::IDD, pParent)
00130         , m_fRecording(false)
00131         , m_mru(0, _T("MRU"), _T("file%d"), 20, 10)
00132 {
00133         m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
00134 }
00135 
00136 void Casf2mkvDlg::DoDataExchange(CDataExchange* pDX)
00137 {
00138         __super::DoDataExchange(pDX);
00139         DDX_Control(pDX, IDC_COMBO1, m_combo);
00140         DDX_Control(pDX, IDC_STATIC1, m_video);
00141 }
00142 
00143 
00144 void Casf2mkvDlg::SetupCombo()
00145 {
00146         m_combo.ResetContent();
00147         for(int i = 0; i < m_mru.GetSize(); i++)
00148                 if(!m_mru[i].IsEmpty())
00149                         m_combo.AddString(m_mru[i]);
00150 }
00151 
00152 void Casf2mkvDlg::SetVideoRect()
00153 {
00154         if(pVW)
00155         {
00156                 CRect r;
00157                 m_video.GetWindowRect(r);
00158                 r -= r.TopLeft();
00159                 pVW->SetWindowPosition(r.left, r.top, r.Width(), r.Height());
00160         }       
00161 }
00162 
00163 BEGIN_MESSAGE_MAP(Casf2mkvDlg, CResizableDialog)
00164         ON_WM_SYSCOMMAND()
00165         ON_WM_PAINT()
00166         ON_WM_QUERYDRAGICON()
00167         ON_MESSAGE(WM_GRAPHNOTIFY, OnGraphNotify)
00168         ON_BN_CLICKED(IDC_BUTTON1, OnRecord)
00169         ON_UPDATE_COMMAND_UI(IDC_BUTTON1, OnUpdateRecord)
00170         ON_UPDATE_COMMAND_UI(IDC_COMBO1, OnUpdateFileName)
00171         ON_UPDATE_COMMAND_UI(IDC_BUTTON2, OnUpdateSettings)
00172         ON_UPDATE_COMMAND_UI(IDC_CHECK2, OnUpdateSettings)
00173         ON_WM_SIZE()
00174         ON_WM_TIMER()
00175         ON_BN_CLICKED(IDC_BUTTON2, OnBnClickedButton2)
00176         ON_MESSAGE(WM_APP, OnUrlOpen)
00177 END_MESSAGE_MAP()
00178 
00179 
00180 // Casf2mkvDlg message handlers
00181 
00182 BOOL Casf2mkvDlg::OnInitDialog()
00183 {
00184         __super::OnInitDialog();
00185 
00186         // Add "About..." menu item to system menu.
00187 
00188         // IDM_ABOUTBOX must be in the system command range.
00189         ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
00190         ASSERT(IDM_ABOUTBOX < 0xF000);
00191 
00192         CMenu* pSysMenu = GetSystemMenu(FALSE);
00193         if (pSysMenu != NULL)
00194         {
00195                 CString strAboutMenu;
00196                 strAboutMenu.LoadString(IDS_ABOUTBOX);
00197                 if (!strAboutMenu.IsEmpty())
00198                 {
00199                         pSysMenu->AppendMenu(MF_SEPARATOR);
00200                         pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
00201                 }
00202         }
00203 
00204         // Set the icon for this dialog.  The framework does this automatically
00205         //  when the application's main window is not a dialog
00206         SetIcon(m_hIcon, TRUE);                 // Set big icon
00207         SetIcon(m_hIcon, FALSE);                // Set small icon
00208 
00209         // TODO: Add extra initialization here
00210 
00211         AddAnchor(IDC_STATIC1, TOP_LEFT, BOTTOM_RIGHT);
00212         AddAnchor(IDC_COMBO1, BOTTOM_LEFT, BOTTOM_RIGHT);
00213         AddAnchor(IDC_BUTTON1, BOTTOM_RIGHT);
00214         AddAnchor(IDC_BUTTON2, BOTTOM_RIGHT);
00215 
00216         m_mru.ReadList();
00217         SetupCombo();
00218 
00219         m_video.ModifyStyle(0, WS_CLIPCHILDREN);
00220 
00221         SetWindowText(ResStr(IDS_TITLE));
00222         
00223         m_urlDropTarget.Register(this);
00224 
00225         return TRUE;  // return TRUE  unless you set the focus to a control
00226 }
00227 
00228 BOOL Casf2mkvDlg::DestroyWindow()
00229 {
00230         m_urlDropTarget.Revoke();
00231 
00232         return __super::DestroyWindow();
00233 }
00234 
00235 void Casf2mkvDlg::OnSysCommand(UINT nID, LPARAM lParam)
00236 {
00237         if ((nID & 0xFFF0) == IDM_ABOUTBOX)
00238         {
00239                 CAboutDlg dlgAbout;
00240                 dlgAbout.DoModal();
00241         }
00242         else
00243         {
00244                 __super::OnSysCommand(nID, lParam);
00245         }
00246 }
00247 
00248 // If you add a minimize button to your dialog, you will need the code below
00249 //  to draw the icon.  For MFC applications using the document/view model,
00250 //  this is automatically done for you by the framework.
00251 
00252 void Casf2mkvDlg::OnPaint() 
00253 {
00254         if (IsIconic())
00255         {
00256                 CPaintDC dc(this); // device context for painting
00257 
00258                 SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
00259 
00260                 // Center icon in client rectangle
00261                 int cxIcon = GetSystemMetrics(SM_CXICON);
00262                 int cyIcon = GetSystemMetrics(SM_CYICON);
00263                 CRect rect;
00264                 GetClientRect(&rect);
00265                 int x = (rect.Width() - cxIcon + 1) / 2;
00266                 int y = (rect.Height() - cyIcon + 1) / 2;
00267 
00268                 // Draw the icon
00269                 dc.DrawIcon(x, y, m_hIcon);
00270         }
00271         else
00272         {
00273                 __super::OnPaint();
00274         }
00275 }
00276 
00277 // The system calls this function to obtain the cursor to display while the user drags
00278 //  the minimized window.
00279 HCURSOR Casf2mkvDlg::OnQueryDragIcon()
00280 {
00281         return static_cast<HCURSOR>(m_hIcon);
00282 }
00283 
00284 
00285 LRESULT Casf2mkvDlg::OnGraphNotify(WPARAM wParam, LPARAM lParam)
00286 {
00287     HRESULT hr = S_OK;
00288 
00289         LONG evCode, evParam1, evParam2;
00290     while(pME && SUCCEEDED(pME->GetEvent(&evCode, (LONG_PTR*)&evParam1, (LONG_PTR*)&evParam2, 0)))
00291     {
00292                 hr = pME->FreeEventParams(evCode, evParam1, evParam2);
00293 
00294         if(EC_COMPLETE == evCode)
00295         {
00296                         if(m_fRecording)
00297                         {
00298                                 OnRecord();
00299                                 break;
00300                         }
00301         }
00302         }
00303 
00304     return hr;
00305 }
00306 
00307 void Casf2mkvDlg::OnRecord()
00308 {
00309         UpdateData();
00310 
00311         HRESULT hr;
00312 
00313         if(!m_fRecording)
00314         {
00315                 m_fRecording = true;
00316 
00317                 UpdateDialogControls(this, FALSE);
00318 
00319                 hr = E_FAIL;
00320 
00321                 do
00322                 {
00323                         // i/o
00324 
00325                         CString src;
00326                         m_combo.GetWindowText(src);
00327 
00328                         CFileDialog fd(
00329                                 FALSE, _T("mkv"), m_dst, 
00330                                 OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_EXPLORER|OFN_ENABLESIZING, 
00331                                 _T("Matroska file (*.mkv;*.mka)|*.mkv;*.mka||"), 
00332                                 this);
00333                         if(fd.DoModal() != IDOK) break;
00334                         m_dst = fd.GetPathName();
00335 
00336                         m_mru.Add(src);
00337                         m_mru.WriteList();
00338                         SetupCombo();
00339                         m_combo.SetWindowText(src);
00340 
00341                         if(src.Trim().IsEmpty() || m_dst.Trim().IsEmpty()) 
00342                                 break;
00343 
00344                         // filer graph
00345 
00346                         if(FAILED(hr = pGB.CoCreateInstance(CLSID_FilterGraph))) 
00347                                 break;
00348 
00349                         pMC = pGB; pME = pGB; pMS = pGB; pVW = pGB; pBV = pGB;
00350                         if(!pMC || !pME || !pMS || !pVW || !pBV) 
00351                                 break;
00352 
00353                         if(FAILED(hr = pME->SetNotifyWindow((OAHWND)m_hWnd, WM_GRAPHNOTIFY, 0))) 
00354                                 break;
00355 
00356                         // windows media source filter
00357 
00358                         CComPtr<IBaseFilter> pSrc;
00359                         if(FAILED(hr = pSrc.CoCreateInstance(CLSID_NetShowSource))
00360                         || FAILED(hr = pGB->AddFilter(pSrc, CStringW(src)))
00361                         || FAILED(hr = CComQIPtr<IFileSourceFilter>(pSrc)->Load(CStringW(src), NULL)))
00362                                 break;
00363 
00364                         // matroska muxer
00365 
00366                         CComPtr<IBaseFilter> pMux;
00367                         if(FAILED(hr = pMux.CoCreateInstance(__uuidof(CMatroskaMuxerFilter)))
00368                                 && !(pMux = new CMatroskaMuxerFilter(NULL, NULL))
00369                         || FAILED(hr = pGB->AddFilter(pMux, L"Matroska Muxer")))
00370                                 break;
00371 
00372                         BeginEnumPins(pSrc, pEP, pPin)
00373                                 if(FAILED(hr = pGB->Connect(pPin, GetFirstDisconnectedPin(pMux, PINDIR_INPUT)))) 
00374                                         break;
00375                         EndEnumPins
00376 
00377                         if(FAILED(hr))
00378                                 break;
00379 
00380                         // file writer
00381 
00382                         CComPtr<IBaseFilter> pFW;
00383                         if(FAILED(hr = pFW.CoCreateInstance(CLSID_FileWriter))
00384                         || FAILED(hr = pGB->AddFilter(pFW, CStringW(m_dst)))
00385                         || FAILED(hr = CComQIPtr<IFileSinkFilter2>(pFW)->SetFileName(CStringW(m_dst), NULL))
00386                         || FAILED(hr = CComQIPtr<IFileSinkFilter2>(pFW)->SetMode(AM_FILE_OVERWRITE))
00387                         || FAILED(hr = pGB->Connect(GetFirstDisconnectedPin(pMux, PINDIR_OUTPUT), GetFirstDisconnectedPin(pFW, PINDIR_INPUT))))
00388                                 break;
00389 
00390                         // insert inf. pin tee
00391 
00392                         BeginEnumPins(pMux, pEP, pPin)
00393                         {
00394                                 PIN_DIRECTION dir;
00395                                 CComPtr<IPin> pPinTo;
00396                                 CMediaType mt;
00397                                 if(FAILED(pPin->QueryDirection(&dir)) || dir != PINDIR_INPUT
00398                                 || FAILED(pPin->ConnectedTo(&pPinTo))
00399                                 || FAILED(pPin->ConnectionMediaType(&mt)))
00400                                         continue;
00401 
00402                                 // FIXME: the inf pin tee filter makes the video messed up, like when seeking 
00403                                 // onto a non-keyframe and starting to decode from that point. (audio seems to be ok)
00404 
00405                                 CComPtr<IBaseFilter> pInfPinTee;
00406                                 if(mt.majortype == MEDIATYPE_Video 
00407                                 || mt.majortype == MEDIATYPE_Audio)
00408                                 {
00409                                         if(FAILED(pGB->Disconnect(pPin))
00410                                         || FAILED(pGB->Disconnect(pPinTo))
00411                                         || FAILED(pInfPinTee.CoCreateInstance(CLSID_InfTee))
00412                                         || FAILED(pGB->AddFilter(pInfPinTee, L"Infinite Pin Tee")))
00413                                                 continue;
00414 
00415                                         if(FAILED(pGB->Connect(pPinTo, GetFirstDisconnectedPin(pInfPinTee, PINDIR_INPUT)))
00416                                         || FAILED(pGB->Connect(GetFirstDisconnectedPin(pInfPinTee, PINDIR_OUTPUT), pPin)))
00417                                         {
00418                                                 pGB->RemoveFilter(pInfPinTee);
00419                                                 pGB->ConnectDirect(pPinTo, pPin, NULL);
00420                                                 continue;
00421                                         }
00422                                 }
00423 
00424                                 pPin = GetFirstDisconnectedPin(pInfPinTee, PINDIR_OUTPUT);
00425 
00426                                 CComPtr<IBaseFilter> pRenderer;
00427 
00428                                 if(mt.majortype == MEDIATYPE_Video)
00429                                 {
00430                                         if(SUCCEEDED(pRenderer.CoCreateInstance(CLSID_VideoRendererDefault))
00431                                         || SUCCEEDED(pRenderer.CoCreateInstance(CLSID_VideoRenderer)))
00432                                                 pPinTo = ::GetFirstDisconnectedPin(pRenderer, PINDIR_INPUT);
00433                                 }
00434                                 else if(mt.majortype == MEDIATYPE_Audio)
00435                                 {
00436                                         if(SUCCEEDED(pRenderer.CoCreateInstance(CLSID_DSoundRender)))
00437                                                 pPinTo = ::GetFirstDisconnectedPin(pRenderer, PINDIR_INPUT);
00438                                 }
00439 
00440                                 if(pPin && pPinTo && pRenderer)
00441                                 {
00442                                         if(SUCCEEDED(pGB->AddFilter(pRenderer, L"Renderer"))
00443                                         && FAILED(pGB->Connect(pPin, pPinTo)))
00444                                                 pGB->RemoveFilter(pRenderer);
00445                                 }
00446                         }
00447                         EndEnumPins
00448 
00449                         // setup video window
00450 
00451                         if(SUCCEEDED(pVW->put_Owner((OAHWND)m_video.m_hWnd))
00452                         && SUCCEEDED(pVW->put_WindowStyle(WS_CHILD|WS_CLIPSIBLINGS|WS_CLIPCHILDREN))
00453                         && SUCCEEDED(pVW->put_MessageDrain((OAHWND)m_hWnd)))
00454                         {
00455                                 SetVideoRect();
00456                         }
00457 
00458                         // timer for polling the position
00459 
00460                         SetTimer(1, 500, NULL);
00461 
00462                         // go!
00463 
00464                         if(FAILED(hr = pMC->Run()))
00465                                 break;
00466 
00467                         hr = S_OK;
00468                 }
00469                 while(false);
00470 
00471                 if(FAILED(hr)) OnRecord();
00472         }
00473         else
00474         {
00475                 if(pMC) pMC->Stop();
00476 
00477                 pMC.Release(); pME.Release(); pMS.Release();
00478                 pVW.Release(); pBV.Release();
00479                 pGB.Release();
00480 
00481                 m_fRecording = false;
00482 
00483                 SetWindowText(ResStr(IDS_TITLE));
00484         }
00485 }
00486 
00487 void Casf2mkvDlg::OnUpdateRecord(CCmdUI* pCmdUI)
00488 {
00489         CString url;
00490         m_combo.GetWindowText(url);
00491         url.Trim();
00492         pCmdUI->Enable(!url.IsEmpty());
00493         pCmdUI->SetText(ResStr(!m_fRecording ? IDS_RECORD : IDS_STOP));
00494 }
00495 
00496 void Casf2mkvDlg::OnUpdateFileName(CCmdUI* pCmdUI)
00497 {
00498         pCmdUI->Enable(!m_fRecording);
00499 }
00500 
00501 void Casf2mkvDlg::OnUpdateSettings(CCmdUI* pCmdUI)
00502 {
00503         pCmdUI->Enable(!m_fRecording);
00504 }
00505 
00506 void Casf2mkvDlg::OnSize(UINT nType, int cx, int cy)
00507 {
00508         CResizableDialog::OnSize(nType, cx, cy);
00509 
00510         SetVideoRect();
00511 }
00512 
00513 void Casf2mkvDlg::OnTimer(UINT nIDEvent)
00514 {
00515         if(nIDEvent == 1)
00516         {
00517                 if(pMS)
00518                 {
00519                         REFERENCE_TIME rtPos = 0, rtDur = 0;
00520                         pMS->GetCurrentPosition(&rtPos);
00521                         pMS->GetDuration(&rtDur);
00522 
00523                         CString title;
00524                         if(rtDur > 0) title.Format(_T("%s (progress: %I64d%%)"), ResStr(IDS_TITLE), 100i64 * rtPos / rtDur);
00525                         else title = ResStr(IDS_TITLE) + _T(" (live)");
00526 
00527                         BeginEnumFilters(pGB, pEF, pBF)
00528                         {
00529                                 if(CComQIPtr<IAMNetworkStatus, &IID_IAMNetworkStatus> pAMNS = pBF)
00530                                 {
00531                                         long BufferingProgress = 0;
00532                                         if(SUCCEEDED(pAMNS->get_BufferingProgress(&BufferingProgress)) && BufferingProgress > 0)
00533                                         {
00534                                                 CString str;
00535                                                 str.Format(_T(" (buffer: %d%%)"), BufferingProgress);
00536                                                 title += str;
00537                                         }
00538                                         break;
00539                                 }
00540                         }
00541                         EndEnumFilters
00542 
00543                         SetWindowText(title);
00544                 }
00545         }
00546 
00547         CResizableDialog::OnTimer(nIDEvent);
00548 }
00549 
00550 void Casf2mkvDlg::OnBnClickedButton2()
00551 {
00552         CComPtr<IBaseFilter> pBF;
00553         pBF.CoCreateInstance(CLSID_NetShowSource);
00554         if(pBF) ShowPPage(pBF, m_hWnd);
00555 }
00556 
00557 LRESULT Casf2mkvDlg::OnUrlOpen(WPARAM wParam, LPARAM lParam)
00558 {
00559         m_combo.SetWindowText(CString((char*)lParam));
00560         return 0;
00561 }
00562 
00564 
00565 Casf2mkvDlg::CRecentFileAndURLList::CRecentFileAndURLList(UINT nStart, LPCTSTR lpszSection,
00566                                                                                                                         LPCTSTR lpszEntryFormat, int nSize,     
00567                                                                                                                         int nMaxDispLen) 
00568         : CRecentFileList(nStart, lpszSection, lpszEntryFormat, nSize, nMaxDispLen)     
00569 {
00570 }
00571 
00572 //#include <afximpl.h>
00573 extern BOOL AFXAPI AfxFullPath(LPTSTR lpszPathOut, LPCTSTR lpszFileIn);
00574 extern BOOL AFXAPI AfxComparePath(LPCTSTR lpszPath1, LPCTSTR lpszPath2);
00575 
00576 void Casf2mkvDlg::CRecentFileAndURLList::Add(LPCTSTR lpszPathName)
00577 {
00578         ASSERT(m_arrNames != NULL);
00579         ASSERT(lpszPathName != NULL);
00580         ASSERT(AfxIsValidString(lpszPathName));
00581 
00582         if(CString(lpszPathName).MakeLower().Find(_T("@device:")) >= 0)
00583                 return;
00584 
00585         bool fURL = (CString(lpszPathName).Find(_T("://")) >= 0);
00586 
00587         // fully qualify the path name
00588         TCHAR szTemp[_MAX_PATH];
00589         if(fURL) _tcscpy(szTemp, lpszPathName);
00590         else AfxFullPath(szTemp, lpszPathName);
00591 
00592         // update the MRU list, if an existing MRU string matches file name
00593         int iMRU;
00594         for (iMRU = 0; iMRU < m_nSize-1; iMRU++)
00595         {
00596                 if((fURL && !_tcscmp(m_arrNames[iMRU], szTemp))
00597                 || AfxComparePath(m_arrNames[iMRU], szTemp))
00598                         break;      // iMRU will point to matching entry
00599         }
00600         // move MRU strings before this one down
00601         for (; iMRU > 0; iMRU--)
00602         {
00603                 ASSERT(iMRU > 0);
00604                 ASSERT(iMRU < m_nSize);
00605                 m_arrNames[iMRU] = m_arrNames[iMRU-1];
00606         }
00607         // place this one at the beginning
00608         m_arrNames[0] = szTemp;
00609 }

Generated on Tue Dec 13 14:46:41 2005 for guliverkli by  doxygen 1.4.5