home *** CD-ROM | disk | FTP | other *** search
/ Mastering MFC Development / MMD.ISO / labs / c11 / lab02 / ex01 / ic_2view.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-02-20  |  10.7 KB  |  442 lines

  1. // IC_2View.cpp : implementation of the CIC_2View class
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include "IC_2.h"
  6.  
  7. #include "IC_2Doc.h"
  8. #include "IC_2View.h"
  9.  
  10. #include "UrlDialog.h"
  11.  
  12. #ifdef _DEBUG
  13. #define new DEBUG_NEW
  14. #undef THIS_FILE
  15. static char THIS_FILE[] = __FILE__;
  16. #endif
  17.  
  18. /////////////////////////////////////////////////////////////////////////////
  19. // CIC_2View
  20.  
  21. IMPLEMENT_DYNCREATE(CIC_2View, CScrollView)
  22.  
  23. BEGIN_MESSAGE_MAP(CIC_2View, CScrollView)
  24.     //{{AFX_MSG_MAP(CIC_2View)
  25.     ON_COMMAND(ID_INTERNET_CREATESESSION, OnInternetCreateSession)
  26.     ON_UPDATE_COMMAND_UI(ID_INTERNET_CREATESESSION, OnUpdateInternetCreateSession)
  27.     ON_COMMAND(ID_INTERNET_GETCONNECTION, OnInternetGetConnection)
  28.     ON_UPDATE_COMMAND_UI(ID_INTERNET_GETCONNECTION, OnUpdateInternetGetConnection)
  29.     ON_COMMAND(ID_INTERNET_CLOSESESSION, OnInternetCloseSession)
  30.     ON_UPDATE_COMMAND_UI(ID_INTERNET_CLOSESESSION, OnUpdateInternetCloseSession)
  31.     ON_COMMAND(ID_INTERNET_SENDREQUEST, OnInternetSendRequest)
  32.     ON_COMMAND(ID_INTERNET_OPENREQUEST, OnInternetOpenRequest)
  33.     ON_COMMAND(ID_INTERNET_READINFORMATION, OnInternetReadInformation)
  34.     ON_UPDATE_COMMAND_UI(ID_INTERNET_OPENREQUEST, OnUpdateInternetOpenRequest)
  35.     ON_UPDATE_COMMAND_UI(ID_INTERNET_SENDREQUEST, OnUpdateInternetSendRequest)
  36.     ON_UPDATE_COMMAND_UI(ID_INTERNET_READINFORMATION, OnUpdateInternetReadInformation)
  37.     ON_COMMAND(ID_INTERNET_OBTAINURL, OnInternetObtainUrl)
  38.     ON_COMMAND(ID_INTERNET_ALLTHEABOVE, OnInternetAllTheAbove)
  39.     ON_UPDATE_COMMAND_UI(ID_INTERNET_ALLTHEABOVE, OnUpdateInternetAllTheAbove)
  40.     //}}AFX_MSG_MAP
  41.     // Standard printing commands
  42.     ON_COMMAND(ID_FILE_PRINT, CScrollView::OnFilePrint)
  43.     ON_COMMAND(ID_FILE_PRINT_DIRECT, CScrollView::OnFilePrint)
  44.     ON_COMMAND(ID_FILE_PRINT_PREVIEW, CScrollView::OnFilePrintPreview)
  45. END_MESSAGE_MAP()
  46.  
  47. /////////////////////////////////////////////////////////////////////////////
  48. // CIC_2View construction/destruction
  49.  
  50. CIC_2View::CIC_2View()
  51. {
  52. }
  53.  
  54. CIC_2View::~CIC_2View()
  55. {
  56.     CloseSession();
  57. }
  58.  
  59. BOOL CIC_2View::PreCreateWindow(CREATESTRUCT& cs)
  60. {
  61.     return CScrollView::PreCreateWindow(cs);
  62. }
  63.  
  64. /////////////////////////////////////////////////////////////////////////////
  65. // CIC_2View drawing
  66.  
  67. void CIC_2View::OnDraw(CDC* pDC)
  68. {
  69.     CIC_2Doc* pDoc = GetDocument();
  70.     ASSERT_VALID(pDoc);
  71.  
  72.     // Do nothing if there's nothing to display.
  73.     if (pDoc->m_WebPage.IsEmpty() == TRUE)
  74.         return;
  75.  
  76.     int BeginningRow, EndingRow, i, x, y;
  77.     TEXTMETRIC tm;
  78.     CPoint pt;
  79.     CRect rect;
  80.  
  81.     pDC->GetTextMetrics(&tm);
  82.     pt = GetScrollPosition();
  83.   
  84.     // In the interest of efficiency, only display as many rows of the
  85.     // retrieved document as the view's height will allow. This requires
  86.     // knowing 2 things: the current vertical scroll position...
  87.     BeginningRow = pt.y / tm.tmHeight;
  88.  
  89.     // and the current height of the view window, which determines
  90.     // how many 'rows' can be displayed.
  91.     GetClientRect(&rect);
  92.     EndingRow = BeginningRow + rect.Height() / tm.tmHeight;
  93.     
  94.     // However, don't attempt to display more lines than exist
  95.     // in the document.
  96.     int linecount = pDoc->m_WebPage.GetCount();
  97.     if (EndingRow > linecount)
  98.         EndingRow = linecount;
  99.         
  100.     x = 0;
  101.     y = BeginningRow * tm.tmHeight;
  102.     POSITION pos = pDoc->m_WebPage.FindIndex(BeginningRow);
  103.     for (i = BeginningRow; i <= EndingRow; i++, y += tm.tmHeight)
  104.     {
  105.         if (!pos) break;
  106.         CString & s = pDoc->m_WebPage.GetNext(pos);
  107.         pDC->TabbedTextOut( x, y, s, 0, NULL, 0);
  108.     }
  109.     
  110. }
  111.  
  112. // CIC_2View diagnostics
  113.  
  114. #ifdef _DEBUG
  115. void CIC_2View::AssertValid() const
  116. {
  117.     CScrollView::AssertValid();
  118. }
  119.  
  120. void CIC_2View::Dump(CDumpContext& dc) const
  121. {
  122.     CScrollView::Dump(dc);
  123. }
  124.  
  125. CIC_2Doc* CIC_2View::GetDocument() // non-debug version is inline
  126. {
  127.     ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CIC_2Doc)));
  128.     return (CIC_2Doc*)m_pDocument;
  129. }
  130. #endif //_DEBUG
  131.  
  132. /////////////////////////////////////////////////////////////////////////////
  133. // CIC_2View message handlers
  134. void CIC_2View::OnInternetObtainUrl() 
  135. {
  136.     CIC_2Doc* pDoc = GetDocument();
  137.  
  138.     CUrlDialog dlg;
  139.     
  140.     if (IDOK == dlg.DoModal())
  141.     {
  142.         pDoc->m_Object = dlg.m_Object;
  143.         pDoc->m_Server = dlg.m_Server;
  144.         pDoc->m_Port = dlg.m_Port;
  145.         pDoc->m_ServerType = dlg.m_ServerType;
  146.         m_processState = 0;
  147.     }
  148. }
  149.  
  150. void CIC_2View::OnInternetCreateSession() 
  151. {
  152.     // Member function to close any previous session.
  153.     CloseSession();
  154.  
  155.     // Create a new session.
  156.     m_pInternetSession = new CInternetSession;
  157.     ASSERT(m_pInternetSession != NULL);
  158.  
  159.     // Update the state.
  160.     m_processState++;
  161. }
  162.  
  163. void CIC_2View::OnInternetGetConnection() 
  164. {
  165.     CIC_2Doc* pDoc = GetDocument();
  166.  
  167.     // Attempt to get an HTTP connection.
  168.     try {
  169.         m_pHttpConnection = m_pInternetSession->GetHttpConnection(pDoc->m_Server, pDoc->m_Port);
  170.     }
  171.     catch (CInternetException *e)
  172.     {
  173.         char buff[256];
  174.         e->GetErrorMessage(buff,256);
  175.         MessageBox(buff);
  176.         e->Delete();
  177.         return;
  178.     }
  179.     ASSERT(m_pHttpConnection != NULL);
  180.     
  181.     // Update the state.
  182.     m_processState++;
  183. }
  184.  
  185. void CIC_2View::OnInternetOpenRequest() 
  186. {
  187.     // Set some request flags.
  188.     DWORD dwHttpRequestFlags = INTERNET_FLAG_EXISTING_CONNECT | INTERNET_FLAG_NO_AUTO_REDIRECT;
  189.  
  190.     CIC_2Doc* pDoc = GetDocument();
  191.  
  192.     // Open a GET request and get an Internet File handle to communicate through.
  193.     m_pHttpFile = m_pHttpConnection->OpenRequest(CHttpConnection::HTTP_VERB_GET,
  194.                                 pDoc->m_Object, 
  195.                                 NULL, 1, NULL, NULL, dwHttpRequestFlags);
  196.  
  197.     if (NULL == m_pHttpFile)
  198.     {
  199.         CString s;
  200.         s.Format ("An error occurred opening the request");
  201.         MessageBox(s);
  202.         return;
  203.     }
  204.  
  205.     // Update the state.
  206.     m_processState++;
  207. }
  208.  
  209. void CIC_2View::OnInternetSendRequest() 
  210. {
  211.     // Initialize our request header.
  212.     const TCHAR szHeaders[] =
  213.         _T("Accept: text/*\r\nUser-Agent: IC_2\r\n");
  214.     
  215.     BOOL rc;
  216.  
  217.     // Send the request.
  218.     try {
  219.         rc = m_pHttpFile->AddRequestHeaders(szHeaders);
  220.         rc = m_pHttpFile->SendRequest();
  221.     }
  222.  
  223.     catch (CInternetException * e)
  224.     {
  225.         char buff[256];
  226.         e->GetErrorMessage(buff,256);
  227.         MessageBox(buff);
  228.         e->Delete();
  229.         return;
  230.     }
  231.  
  232.     // Update the state.
  233.     m_processState++;
  234. }
  235.  
  236. void CIC_2View::OnInternetReadInformation() 
  237. {
  238.     char s[1024];
  239.     CIC_2Doc* pDoc = GetDocument();
  240.  
  241.     //
  242.     // Get the received header and prepend to view output.
  243.     //
  244.     DWORD bufsiz= 1024;
  245.     if (m_pHttpFile->QueryInfo(HTTP_QUERY_RAW_HEADERS_CRLF, s, &bufsiz))
  246.     {
  247.         char * p = strtok(s, "\n\r");
  248.         // Extract line at a time.
  249.         while (p)
  250.         {
  251.             pDoc->m_WebPage.AddTail(p);
  252.             p = strtok(NULL, "\n\r");
  253.         }
  254.         // Delimiter between header and body.
  255.         pDoc->m_WebPage.AddTail("+=+=+=+=+=+=+=+=+=+ End of Header +=+=+=+=+=+=+=+=+=+=+=+=+=+");
  256.     }
  257.  
  258.     //
  259.     // Read body.
  260.     //
  261.     m_pHttpFile->SetReadBufferSize(4096);
  262.         
  263.     while(m_pHttpFile->ReadString(s, 1023))
  264.     {
  265.         // Extract a line at a time.
  266.         char * p = strtok(s, "\n\r");
  267.         while (p)
  268.         {
  269.             pDoc->m_WebPage.AddTail(p);
  270.             p = strtok(NULL, "\n\r");
  271.         }
  272.     }
  273.     
  274.     // Have view repaint itself.
  275.     pDoc->UpdateAllViews(NULL);
  276.  
  277.     // Update state.
  278.     m_processState++;
  279. }
  280.  
  281. // This is a shortcut way of calling all the 5 menu items.
  282. void CIC_2View::OnInternetAllTheAbove() 
  283. {
  284.     this->SendMessage(WM_COMMAND, ID_INTERNET_CREATESESSION);
  285.     this->SendMessage(WM_COMMAND, ID_INTERNET_GETCONNECTION);
  286.     this->SendMessage(WM_COMMAND, ID_INTERNET_OPENREQUEST);
  287.     this->SendMessage(WM_COMMAND, ID_INTERNET_SENDREQUEST);
  288.     this->SendMessage(WM_COMMAND, ID_INTERNET_READINFORMATION);
  289. }
  290.  
  291. void CIC_2View::OnInternetCloseSession() 
  292. {
  293.     // Clean up view and any objects that are lying around.
  294.     CloseSession();
  295.  
  296.     // Clear the view.
  297.     CIC_2Doc* pDoc = GetDocument();
  298.     pDoc->UpdateAllViews(NULL);
  299.  
  300.     // Initialize the state.
  301.     m_processState = -1;
  302. }
  303.  
  304. void CIC_2View::OnUpdateInternetCreateSession(CCmdUI* pCmdUI) 
  305. {
  306.     pCmdUI->Enable(m_processState == 0);
  307. }
  308.  
  309. void CIC_2View::OnUpdateInternetGetConnection(CCmdUI* pCmdUI) 
  310. {
  311.     pCmdUI->Enable(m_processState == 1);
  312. }
  313.  
  314. void CIC_2View::OnUpdateInternetOpenRequest(CCmdUI* pCmdUI) 
  315. {
  316.     pCmdUI->Enable(m_processState == 2);
  317. }
  318.  
  319. void CIC_2View::OnUpdateInternetSendRequest(CCmdUI* pCmdUI) 
  320. {
  321.     pCmdUI->Enable(m_processState == 3);
  322. }
  323.  
  324. void CIC_2View::OnUpdateInternetReadInformation(CCmdUI* pCmdUI) 
  325. {
  326.     pCmdUI->Enable(m_processState == 4);
  327. }
  328.  
  329. void CIC_2View::OnUpdateInternetAllTheAbove(CCmdUI* pCmdUI) 
  330. {
  331.     pCmdUI->Enable(m_processState == 0);
  332. }
  333.  
  334. void CIC_2View::OnUpdateInternetCloseSession(CCmdUI* pCmdUI) 
  335. {
  336.     pCmdUI->Enable(m_processState > 0);
  337. }
  338.  
  339. void CIC_2View::OnInitialUpdate() 
  340. {
  341.     CScrollView::OnInitialUpdate();
  342.  
  343.     m_pInternetSession = NULL;
  344.     m_pHttpConnection = NULL;
  345.     m_pHttpFile = NULL;
  346.     m_processState = -1;
  347. }
  348.  
  349. BOOL CIC_2View::OnScroll(UINT nScrollCode, UINT nPos, BOOL bDoScroll) 
  350. {
  351.     // If we're scrolling in the vertical direction by use of the
  352.     // thumbtack, we only want to scroll in units equal to a character's
  353.     // height. nPos is adjusted so it's always equal to some multiple
  354.     // of a character's height.
  355.     if (SB_THUMBTRACK == HIBYTE(nScrollCode))
  356.     {
  357.         TEXTMETRIC tm;
  358.         CClientDC dc(this);
  359.         dc.GetTextMetrics(&tm);
  360.         while ((nPos % tm.tmHeight) != 0)
  361.             nPos--;
  362.     }
  363.  
  364.     return CScrollView::OnScroll(nScrollCode, nPos, bDoScroll);
  365. }
  366.  
  367. void CIC_2View::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) 
  368. {
  369.     CView::OnUpdate(pSender, lHint, pHint);
  370.     SetScrollingAttributes();
  371. }
  372.  
  373. void CIC_2View::SetScrollingAttributes()
  374. {
  375.     CIC_2Doc* pDoc = GetDocument();
  376.  
  377.     CSize sizeTotal, sizePage, sizeLine;
  378.  
  379.     CClientDC dc(this);
  380.     TEXTMETRIC tm;
  381.     dc.GetTextMetrics(&tm);
  382.  
  383.     // Calculate the total size of this view
  384.     sizeTotal.cx = 80 * tm.tmMaxCharWidth;
  385.     
  386.     // Just for grins, if there are no lines to be displayed,
  387.     // I'll use the classic 25x80 display size.
  388.     if (pDoc->m_WebPage.GetCount() == 0)
  389.         sizeTotal.cy = 25 * tm.tmHeight;     
  390.     else
  391.         sizeTotal.cy = pDoc->m_WebPage.GetCount() * tm.tmHeight;     
  392.     // Note: this value cannot exceed 32767
  393.  
  394.     // Scroll one letter in either direction when
  395.     // clicking on a scroll bar's arrows.
  396.     // Current page length when clicking in the vertical shaft.
  397.     // 5 characters when clicking in the horizontal shaft.
  398.     sizeLine.cx = tm.tmAveCharWidth;
  399.     sizeLine.cy = tm.tmHeight;
  400.     sizePage.cx = 5 * tm.tmAveCharWidth;
  401.     sizePage.cy = 25 * tm.tmHeight;
  402.  
  403.     SetScrollSizes(MM_TEXT, sizeTotal, sizePage, sizeLine);
  404.  
  405.     GetParentFrame()->RecalcLayout();
  406.     ResizeParentToFit();
  407. }
  408. void CIC_2View::CloseSession()
  409. {
  410.     if (m_pInternetSession != NULL)
  411.     {
  412.         m_pInternetSession->Close();
  413.         delete m_pInternetSession;
  414.         m_pInternetSession = NULL;
  415.     }
  416.     
  417.     if (m_pHttpConnection != NULL)
  418.     {
  419.         m_pHttpConnection->Close();
  420.         delete m_pHttpConnection;
  421.         m_pHttpConnection = NULL;
  422.     }
  423.  
  424.     if (m_pHttpFile != NULL)
  425.     {
  426.         m_pHttpFile->Close();
  427.         delete m_pHttpFile;
  428.         m_pHttpFile = NULL;
  429.     }
  430.     
  431.     CIC_2Doc* pDoc = GetDocument();
  432.     while (!pDoc->m_WebPage.IsEmpty()) 
  433.     {
  434.         CString String= pDoc->m_WebPage.RemoveHead();
  435.     }
  436.  
  437. //    pDoc->m_WebPage.RemoveAll();
  438.  
  439. }
  440.  
  441.  
  442.