⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 linkckview.cpp

📁 讲mfc的书
💻 CPP
字号:
// linkckView.cpp : implementation of the CLinkckView class
//

#include "stdafx.h"
#include "linkck.h"
#include <afxinet.h>
#include "urlinput.h"

#include "linkckDoc.h"
#include "linkckView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

///////////////////////
// CLinkckView

IMPLEMENT_DYNCREATE(CLinkckView, CFormView)

BEGIN_MESSAGE_MAP(CLinkckView, CFormView)
  //{{AFX_MSG_MAP(CLinkckView)
 ON_BN_CLICKED(IDC_SCAN, OnScan)
 ON_COMMAND(ID_FILE_PRINT_PREVIEW, OnFilePrintPreview)
 ON_COMMAND(ID_FILE_SCAN, OnScan)
 ON_LBN_DBLCLK(IDC_LB, OnScan)
 ON_UPDATE_COMMAND_UI(ID_FILE_PRINT, OnUpdateFilePrint)
 ON_UPDATE_COMMAND_UI(ID_FILE_PRINT_PREVIEW, OnUpdateFilePrint)
 //}}AFX_MSG_MAP
 // Standard printing commands
 ON_COMMAND(ID_FILE_PRINT, CFormView::OnFilePrint)
 ON_COMMAND(ID_FILE_PRINT_DIRECT, CFormView::OnFilePrint)
END_MESSAGE_MAP()

///////////////////////
// CLinkckView construction/destruction

void CLinkckView::OnFilePrintPreview()
{
        AfxGetMainWnd()->ShowWindow(SW_MAXIMIZE);
        CFormView::OnFilePrintPreview();
}

CLinkckView::CLinkckView()
        : CFormView(CLinkckView::IDD)
{
        //{{AFX_DATA_INIT(CLinkckView)
// NOTE: the ClassWizard will add member initialization here
        //}}AFX_DATA_INIT
        PrintEnable=FALSE;

}

CLinkckView::~CLinkckView()
{
}

void CLinkckView::DoDataExchange(CDataExchange* pDX)
{
        CFormView::DoDataExchange(pDX);
        //{{AFX_DATA_MAP(CLinkckView)
        DDX_Control(pDX, IDC_LB, m_lb);
        //}}AFX_DATA_MAP
}

BOOL CLinkckView::PreCreateWindow(CREATESTRUCT& cs)
{
        return CFormView::PreCreateWindow(cs);
}

///////////////////////
// CLinkckView printing

BOOL CLinkckView::OnPreparePrinting(CPrintInfo* pInfo)
{
        // default preparation
        return DoPreparePrinting(pInfo);
}

void CLinkckView::OnBeginPrinting(CDC* /*pDC*/,
         CPrintInfo* /*pInfo*/)
{
        // TODO: add extra initialization before printing
}

void CLinkckView::OnEndPrinting(CDC* /*pDC*/,
         CPrintInfo* /*pInfo*/)
{
        // TODO: add cleanup after printing
}

// Simple code to dump the results out to a printed page
void CLinkckView::OnPrint(CDC* pDC, CPrintInfo*)
{
        int i;
        int y=0,texthi;
        TEXTMETRIC tm;
        pDC->GetTextMetrics(&tm);
        texthi=tm.tmHeight+tm.tmExternalLeading;
        for (i=1;i<m_lb.GetCount();i++)
        {
          CString item;
          m_lb.GetText(i,item);
          pDC->TabbedTextOut(5,y,item,0,NULL,0);
          y+=texthi;
        }
}

///////////////////////
// CLinkckView diagnostics

#ifdef _DEBUG
void CLinkckView::AssertValid() const
{
        CFormView::AssertValid();
}

void CLinkckView::Dump(CDumpContext& dc) const
{
        CFormView::Dump(dc);
}

CLinkckDoc* CLinkckView::GetDocument()
{
   ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CLinkckDoc)));
   return (CLinkckDoc*)m_pDocument;
}
#endif //_DEBUG

///////////////////////
// CLinkckView message handlers

// Do a scan from user interface
void CLinkckView::OnScan()
{
  CString URL;
  CString err;
  int sel=m_lb.GetCurSel();
  if (sel==LB_ERR||sel==0||m_lb.GetItemData(sel)==-1)
  {
  // prompt if no good selection in the list box
          CUrlInput indlg;
          if (indlg.DoModal()==IDCANCEL) return;
          URL=indlg.m_url;
  }
  else
  {
          m_lb.GetText(sel,URL);
  }
// clear list box
  m_lb.ResetContent();
  m_lb.AddString("<<New URL>>");
// do real work
  DoScan(URL);
  // enable menu items
  PrintEnable=TRUE;
}

// This routine really does the work
void CLinkckView::DoScan(CString & URL, BOOL recurse)
{
        CString line;
        int item;
        CInternetSession session("Commando Link Check V1.0");
        CStdioFile *f;
        try
          {
          f=session.OpenURL(URL);
          }
        catch (...)
          {
          f=NULL;
          }
// apparently the MFC Dlls don't export
// CHttpFile's runtime class? (see text)
    if (f && f->IsKindOf(RUNTIME_CLASS(CHttpFile)))
//      if (f && !strnicmp(URL,"http",4))
        {
                DWORD stat; // http status
                CHttpFile *hf=(CHttpFile *)f;
                hf->QueryInfoStatusCode(stat);
// only codes 200-299 are good
                if (stat<200||stat>299)
                {
                        f->Close();
                        f=NULL;
                }
        }
        if (!f)  // some problem
        {
          CString err;
          err=URL;
          err+="\tError!";
          item=m_lb.AddString(err);
          m_lb.SetItemData(item,-1);
          return;
        }
// go!
        item=m_lb.AddString(URL);
        m_lb.SetItemData(item,0);
// if recurse is true, then parse file
        while (recurse && f->ReadString(line))
        {
                int n=0;
                 char *p, *e;
                p=(char *)(LPCSTR)line;
                do {
                  p=strchr(p,'=');    // search for =
                  if (p)    // backward search for HREF/SRC
                  {
                          if (toupper(p[-1])!='F' ||
                                  toupper(p[-2])!='E' ||
                                  toupper(p[-3])!='R' ||
                                  toupper(p[-4])!='H')
                                  if (toupper(p[-1])!='C' ||
                                          toupper(p[-2])!='R' ||
                                          toupper(p[-3])!='S')
                                  {
                                          p++;
                                          continue;
                                  }
                          if (p[1]=='"') // skip quotes
                                p++;
                                 e=p+1+strcspn(p+1," \t\n>\"#");
                                 *e='\0';
// don't recurse empty URLs (e.g., HREF=#anchor)
                                 if (e!=p+1)
                                  {
                                    CString newURL;
                                    ExpandURL(newURL,p+1,URL);
                                    DoScan(newURL,FALSE);
                                  }
                                *e=' ';
                                p=e+1;
                  }
                } while (p && *p);
        } // end while
    f->Close();
}

void CLinkckView::OnInitialUpdate()
{
        CFormView::OnInitialUpdate();
        GetParentFrame()->RecalcLayout();
        ResizeParentToFit(FALSE);
}


void CLinkckView::ExpandURL(CString &result,
   CString source,CString current)
{
   CString proto,host,path,file,chost,cpath,cproto;
// break up both URLs
   ParseURL(source,&proto,&host,&path,&file);
   ParseURL(current,&cproto,&chost,&cpath,NULL);
// copy empty parts from current URL
   if (proto.IsEmpty()) proto=cproto;
   if (host.IsEmpty()) host=chost;
   if (path.IsEmpty())
     path=cpath;
   else if (path[0]!='/'&&path[0]!='\\'&&!cpath.IsEmpty())
     path=cpath+"/"+path;
   result=proto + host ;
// if path is relative, prepend current path
   if (!path.IsEmpty())
        {
        if (path[0]!='/' && path[0]!='\\')
          result+="/";
        result+= path;
        }
   if (!file.IsEmpty()) result+="/" + file;
}


// Homebrew URL parser AfxParseURL is too lazy to
// decide what is a file and what is a directory, so we
// do it ourselves (sigh)
void CLinkckView::ParseURL(CString url,CString *proto,
                           CString *host, CString *path,
                           CString *fileplus)
{

        CString _proto, _host, _path, _fileplus;
        int n;
        n=url.Find("://");
        if (n==-1) n=url.Find(":\\\\");
// get protocol
        if (n!=-1)
        {
                _proto=url.Left(n+3);
                url=url.Right(url.GetLength()-(n+3));
                n=url.FindOneOf("/\\");
                if (n==-1)
                {  // get host
                        _host=url;
                        url="";
                }
                else
                {
                        _host=url.Left(n);
                        url=url.Right(url.GetLength()-n);
                }
        }
// find path or file name
        n=url.ReverseFind('/');
        if (n==-1) n=url.ReverseFind('\\');
        if (n!=-1)
        {
                _fileplus=url.Right(url.GetLength()-n-1);
                _path=n==-1?url:url.Left(n);
                if (!_path.IsEmpty()&&(_path[0]=='/'||
                     _path[0]=='\\'))
                        _path=_path.Right(_path.GetLength()-1);
        }
        else
        {
                _fileplus=url;
        }
        // Special case heruistic
        // if host name and file provide, but no path then file
        // is probably a path if it doesn't contain a period
        if (!_host.IsEmpty() && _path.IsEmpty() &&
                !_fileplus.IsEmpty() && _fileplus.Find('.')==-1)
        {
                _path="/" + _fileplus;
                _fileplus="";
        }
        if (proto) *proto=_proto;
        if (host) *host=_host;
        if (path) *path=_path;
        if (fileplus) *fileplus=_fileplus;
}


void CLinkckView::OnEndPrintPreview(CDC* pDC, CPrintInfo* pInfo,
              POINT point, CPreviewView* pView)
{
        AfxGetMainWnd()->ShowWindow(SW_NORMAL);
        CFormView::OnEndPrintPreview(pDC, pInfo, point, pView);
}

void CLinkckView::OnUpdateFilePrint(CCmdUI* pCmdUI)
{
        pCmdUI->Enable(PrintEnable);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -