HTTPVIEW.CPP
上传用户:btxinjin
上传日期:2007-01-04
资源大小:83k
文件大小:15k
源码类别:

Web服务器

开发平台:

Visual C++

  1. // HttpView.cpp : implementation of the CHttpSvrView class
  2. //
  3. // This is a part of the Microsoft Foundation Classes C++ library.
  4. // Copyright (C) 1997-1998 Microsoft Corporation
  5. // All rights reserved.
  6. //
  7. // This source code is only intended as a supplement to the
  8. // Microsoft Foundation Classes Reference and related
  9. // electronic documentation provided with the library.
  10. // See these sources for detailed information regarding the
  11. // Microsoft Foundation Classes product.
  12. #include "stdafx.h"
  13. #include "HttpSvr.h"
  14. #include "Http.h"
  15. #include "HttpDoc.h"
  16. #include "HttpView.h"
  17. #include "RootDlg.h"
  18. #include "NoRoot.h"
  19. #include "Request.h"
  20. #ifdef _DEBUG
  21. #define new DEBUG_NEW
  22. #undef THIS_FILE
  23. static char THIS_FILE[] = __FILE__;
  24. #endif
  25. /////////////////////////////////////////////////////////////////////////////
  26. // CHttpSvrView
  27. IMPLEMENT_DYNCREATE(CHttpSvrView, CListView)
  28. BEGIN_MESSAGE_MAP(CHttpSvrView, CListView)
  29. //{{AFX_MSG_MAP(CHttpSvrView)
  30. ON_COMMAND(IDM_VIEW_LARGE, OnViewLarge)
  31. ON_UPDATE_COMMAND_UI(IDM_VIEW_LARGE, OnUpdateViewLarge)
  32. ON_COMMAND(IDM_VIEW_LIST, OnViewList)
  33. ON_UPDATE_COMMAND_UI(IDM_VIEW_LIST, OnUpdateViewList)
  34. ON_COMMAND(IDM_VIEW_REPORT, OnViewReport)
  35. ON_UPDATE_COMMAND_UI(IDM_VIEW_REPORT, OnUpdateViewReport)
  36. ON_COMMAND(IDM_VIEW_SMALL, OnViewSmall)
  37. ON_UPDATE_COMMAND_UI(IDM_VIEW_SMALL, OnUpdateViewSmall)
  38. ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, OnColumnclick)
  39. ON_NOTIFY_REFLECT(LVN_GETDISPINFO, OnGetDispInfo)
  40. ON_NOTIFY_REFLECT(LVN_DELETEITEM, OnDeleteItem)
  41. ON_COMMAND(IDM_VIEW_CLEAR, OnViewClear)
  42. //}}AFX_MSG_MAP
  43. ON_NOTIFY_REFLECT(NM_DBLCLK, OnDblclk)
  44. ON_NOTIFY_REFLECT(NM_RCLICK, OnRclick)
  45. ON_COMMAND(IDM_POPUP_CLEAR, OnPopupClear)
  46. ON_COMMAND(IDM_POPUP_EDIT, OnPopupEdit)
  47. ON_COMMAND(IDM_POPUP_OPEN, OnPopupOpen)
  48. END_MESSAGE_MAP()
  49. /////////////////////////////////////////////////////////////////////////////
  50. // CHttpSvrView construction/destruction
  51. CHttpSvrView::CHttpSvrView()
  52. {
  53. m_phdPopup = NULL;
  54. }
  55. CHttpSvrView::~CHttpSvrView()
  56. {
  57. }
  58. BOOL CHttpSvrView::PreCreateWindow(CREATESTRUCT& cs)
  59. {
  60. cs.style = (cs.style & ~LVS_TYPEMASK) | LVS_REPORT;
  61. cs.style |= LVS_AUTOARRANGE;
  62. return CListView::PreCreateWindow(cs);
  63. }
  64. /////////////////////////////////////////////////////////////////////////////
  65. // CHttpSvrView drawing
  66. void CHttpSvrView::OnDraw(CDC* pDC)
  67. {
  68. CHttpSvrDoc* pDoc = GetDocument();
  69. ASSERT_VALID(pDoc);
  70. }
  71. void CHttpSvrView::OnInitialUpdate()
  72. {
  73. CHttpSvrDoc* pDoc = GetDocument();
  74. CListView::OnInitialUpdate();
  75. // get the root directory....
  76. CString strRoot = pDoc->m_strRoot;
  77. // make sure it exists and it's a folder....
  78. BOOL bLoop = TRUE;
  79. while ( bLoop )
  80. {
  81. DWORD dwAttr = GetFileAttributes( strRoot );
  82. if ( dwAttr == -1 )
  83. {
  84. CNoRootDlg dlg;
  85. dlg.m_strRoot = strRoot;
  86. UINT uButton = dlg.DoModal();
  87. if ( uButton == IDOK )
  88. {
  89. strRoot = dlg.m_strRoot;
  90. dwAttr = GetFileAttributes( strRoot );
  91. if ( dwAttr == -1 )
  92. {
  93. if ( !CreateDirectory( strRoot, NULL ) )
  94. {
  95. MessageBox( "Create Directory failed",
  96. strRoot, MB_ICONEXCLAMATION|MB_OK );
  97. }
  98. }
  99. }
  100. else // no....
  101. bLoop = FALSE; // use it anyway
  102. }
  103. else if ( (dwAttr & FILE_ATTRIBUTE_DIRECTORY) == 0 )
  104. {
  105. CBadRootDlg dlg;
  106. dlg.m_strRoot = strRoot;
  107. if ( dlg.DoModal() == IDCANCEL )
  108. bLoop = FALSE; // use it anyway
  109. }
  110. else
  111. {
  112. // root is okay, save it....
  113. if ( strRoot.CompareNoCase(pDoc->m_strRoot) != 0 )
  114. {
  115. pDoc->m_strRoot = strRoot;
  116. pDoc->SetModifiedFlag( TRUE );
  117. }
  118. bLoop = FALSE;  // okay!
  119. }
  120. }
  121. }
  122. /////////////////////////////////////////////////////////////////////////////
  123. // CHttpSvrView diagnostics
  124. #ifdef _DEBUG
  125. void CHttpSvrView::AssertValid() const
  126. {
  127. CListView::AssertValid();
  128. }
  129. void CHttpSvrView::Dump(CDumpContext& dc) const
  130. {
  131. CListView::Dump(dc);
  132. }
  133. CHttpSvrDoc* CHttpSvrView::GetDocument() // non-debug version is inline
  134. {
  135. ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CHttpSvrDoc)));
  136. return (CHttpSvrDoc*)m_pDocument;
  137. }
  138. #endif //_DEBUG
  139. /////////////////////////////////////////////////////////////////////////////
  140. // CHttpSvrView message handlers
  141. BOOL CHttpSvrView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)
  142. {
  143. BOOL bCreated = CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext);
  144. if ( bCreated )
  145. {
  146. CListCtrl& listView = GetListCtrl();
  147. int aWidths[] = { 150, 200, 50, 140, 225, 200 };
  148. CString strHeading;
  149. for ( int iCol = 0; iCol < C_COLUMNS; iCol++) {
  150. strHeading.LoadString( IDS_COLUMN1 + iCol );
  151. listView.InsertColumn( iCol, strHeading, LVCFMT_LEFT,
  152. aWidths[iCol], iCol );
  153. }
  154. // Create the full-sized and small icon image lists.
  155. if ( m_ilLarge.Create( IDB_IMAGES, 32, 1, RGB(0,255,0) ) )
  156. {
  157. listView.SetImageList( &m_ilLarge, LVSIL_NORMAL );
  158. }
  159. if ( m_ilSmall.Create( IDB_SMALLIMAGES, 16, 1, RGB(0,255,0) ) )
  160. {
  161. listView.SetImageList( &m_ilSmall, LVSIL_SMALL);
  162. }
  163. }
  164. return bCreated;
  165. }
  166. void CHttpSvrView::SetListView( DWORD dwView )
  167. {
  168. CListCtrl& list = GetListCtrl();
  169. DWORD dwStyle = GetWindowLong( list.m_hWnd, GWL_STYLE );
  170. if ( (dwStyle & LVS_TYPEMASK) != dwView )
  171. SetWindowLong( list.m_hWnd, GWL_STYLE,
  172. (dwStyle & ~LVS_TYPEMASK) | dwView );
  173. }
  174. void CHttpSvrView::OnViewLarge()
  175. {
  176. SetListView( LVS_ICON );
  177. }
  178. void CHttpSvrView::OnUpdateViewLarge(CCmdUI* pCmdUI)
  179. {
  180. CListCtrl& list = GetListCtrl();
  181. DWORD dwStyle = GetWindowLong( list.m_hWnd, GWL_STYLE ) & LVS_TYPEMASK;
  182. pCmdUI->SetCheck( dwStyle == LVS_ICON );
  183. }
  184. void CHttpSvrView::OnViewList()
  185. {
  186. SetListView( LVS_LIST );
  187. }
  188. void CHttpSvrView::OnUpdateViewList(CCmdUI* pCmdUI)
  189. {
  190. CListCtrl& list = GetListCtrl();
  191. DWORD dwStyle = GetWindowLong( list.m_hWnd, GWL_STYLE ) & LVS_TYPEMASK;
  192. pCmdUI->SetCheck( dwStyle == LVS_LIST );
  193. }
  194. void CHttpSvrView::OnViewReport()
  195. {
  196. SetListView( LVS_REPORT );
  197. }
  198. void CHttpSvrView::OnUpdateViewReport(CCmdUI* pCmdUI)
  199. {
  200. CListCtrl& list = GetListCtrl();
  201. DWORD dwStyle = GetWindowLong( list.m_hWnd, GWL_STYLE ) & LVS_TYPEMASK;
  202. pCmdUI->SetCheck( dwStyle == LVS_REPORT );
  203. }
  204. void CHttpSvrView::OnViewSmall()
  205. {
  206. SetListView( LVS_SMALLICON );
  207. }
  208. void CHttpSvrView::OnUpdateViewSmall(CCmdUI* pCmdUI)
  209. {
  210. CListCtrl& list = GetListCtrl();
  211. DWORD dwStyle = GetWindowLong( list.m_hWnd, GWL_STYLE ) & LVS_TYPEMASK;
  212. pCmdUI->SetCheck( dwStyle == LVS_SMALLICON );
  213. }
  214. int CALLBACK
  215. CompareHitDocs( CHitDoc* doc1, CHitDoc* doc2, LPARAM lCol )
  216. {
  217. int nCmp = 0;
  218. switch( lCol )
  219. {
  220. case COLUMN_PATH:
  221. nCmp = doc1->m_strFolder.CompareNoCase( doc2->m_strFolder );
  222. break;
  223. case COLUMN_HITS:
  224. if ( doc1->m_nHits > doc2->m_nHits )
  225. nCmp = -1;
  226. else if ( doc1->m_nHits < doc2->m_nHits )
  227. nCmp = 1;
  228. break;
  229. case COLUMN_LAST:
  230. if ( doc1->m_timeLastHit > doc2->m_timeLastHit )
  231. nCmp = -1;
  232. else if ( doc1->m_timeLastHit < doc2->m_timeLastHit )
  233. nCmp = 1;
  234. break;
  235. case COLUMN_CMD:
  236. nCmp = doc1->m_strCommand.CompareNoCase( doc2->m_strCommand );
  237. break;
  238. case COLUMN_URL:
  239. nCmp = doc1->m_strURL.CompareNoCase( doc2->m_strURL );
  240. break;
  241. default:
  242. // put folders ahead of everything....
  243. if ( doc1->m_bFolder && !doc2->m_bFolder )
  244. nCmp = -1;
  245. else if ( !doc1->m_bFolder && doc2->m_bFolder )
  246. nCmp = 1;
  247. // sort successfully hit docs....
  248. else if ( doc1->m_nStatus == 200 && doc2->m_nStatus == 200 )
  249. {
  250. nCmp = doc1->m_strFile.CompareNoCase( doc2->m_strFile );
  251. if ( nCmp == 0 )
  252. nCmp = doc1->m_strFolder.CompareNoCase( doc2->m_strFolder );
  253. }
  254. // put hit docs ahead of status items....
  255. else if ( doc1->m_nStatus == 200 )
  256. nCmp = -1;
  257. else if ( doc2->m_nStatus == 200 )
  258. nCmp = 1;
  259. // sort status items by status value....
  260. else if ( doc1->m_nStatus < doc2->m_nStatus )
  261. nCmp = -1;
  262. else if ( doc1->m_nStatus > doc2->m_nStatus )
  263. nCmp = 1;
  264. break;
  265. }
  266. return nCmp;
  267. }
  268. void CHttpSvrView::OnColumnclick(NMHDR* pNMHDR, LRESULT* pResult)
  269. {
  270. NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
  271. CListCtrl& list = GetListCtrl();
  272. list.SortItems( (PFNLVCOMPARE)CompareHitDocs, pNMListView->iSubItem );
  273. *pResult = 0;
  274. }
  275. void CHttpSvrView::OnGetDispInfo(NMHDR* pNMHDR, LRESULT* pResult)
  276. {
  277. LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
  278. if ( pDispInfo->item.mask & LVIF_TEXT )
  279. {
  280. CHitDoc* pHitDoc = (CHitDoc*)(pDispInfo->item.lParam);
  281. switch( pDispInfo->item.iSubItem )
  282. {
  283. case COLUMN_FILE:
  284. lstrcpy( pDispInfo->item.pszText, pHitDoc->m_strFile );
  285. break;
  286. case COLUMN_PATH:
  287. lstrcpy( pDispInfo->item.pszText, pHitDoc->m_strFolder );
  288. break;
  289. case COLUMN_HITS:
  290. wsprintf( pDispInfo->item.pszText, "%d", pHitDoc->m_nHits );
  291. break;
  292. case COLUMN_LAST:
  293. if ( pHitDoc->m_nHits > 0 )
  294. lstrcpy( pDispInfo->item.pszText, (pHitDoc->m_nHits)
  295. ? pHitDoc->m_timeLastHit.Format( IDS_TIMEFORMAT )
  296. : "" );
  297. break;
  298. case COLUMN_URL:
  299. lstrcpy( pDispInfo->item.pszText, pHitDoc->m_strURL );
  300. break;
  301. case COLUMN_CMD:
  302. lstrcpy( pDispInfo->item.pszText, pHitDoc->m_strCommand );
  303. break;
  304. }
  305. }
  306. *pResult = 0;
  307. }
  308. void CHttpSvrView::OnDeleteItem(NMHDR* pNMHDR, LRESULT* pResult)
  309. {
  310. NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
  311. CListCtrl& list = GetListCtrl();
  312. LV_ITEM lvi;
  313. lvi.mask = LVIF_PARAM;
  314. lvi.iItem = pNMListView->iItem;
  315. lvi.iSubItem = 0;
  316. if ( list.GetItem( &lvi ) == TRUE )
  317. {
  318. CHitDoc* pHit = (CHitDoc*)(lvi.lParam);
  319. delete pHit;
  320. }
  321. *pResult = 0;
  322. }
  323. int
  324. CHttpSvrView::GetImage( CHitDoc* pHitDoc )
  325. {
  326. // indexes into image maps for (status/100)....
  327. int aStatImg[] = { 2, 5, 5, 4, 3, 3 };
  328. int iImage;
  329. if ( pHitDoc->m_nStatus != 0 && pHitDoc->m_nStatus != 200 )
  330. iImage = aStatImg[ pHitDoc->m_nStatus/100]; // status image
  331. else if ( pHitDoc->m_dwExecute )
  332. iImage = 2; // CGI executables
  333. else if ( pHitDoc->m_nHits == 0 )
  334. iImage = 0; // no hits yet
  335. else if ( pHitDoc->m_bFolder )
  336. iImage = 1; // folder image
  337. else
  338. iImage = 0; // document
  339. return iImage;
  340. }
  341. void CHttpSvrView::RegisterHit( CListCtrl& list, CRequest* pRequest )
  342. {
  343. CHitDoc* pHitDoc = new CHitDoc( pRequest );
  344. if ( pHitDoc )
  345. InsertHitDoc( pHitDoc );
  346. }
  347. void CHttpSvrView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
  348. {
  349. if ( lHint == HINT_DOCHIT )
  350. {
  351. CRequest* pRequest = (CRequest*)pHint;
  352. CListCtrl& list = GetListCtrl();
  353. RegisterHit( list, pRequest );
  354. }
  355. }
  356. void CHttpSvrView::OnDblclk(NMHDR* pNMHDR, LRESULT* pResult)
  357. {
  358. // Get the control....
  359. CListCtrl& list = GetListCtrl();
  360. int nSelected = list.GetSelectedCount();
  361. // only proceed if one item selected....
  362. if ( nSelected == 1 )
  363. {
  364. // find the selected item....
  365. int ndx = 0;
  366. int nItems = list.GetItemCount();
  367. while ( ndx < nItems )
  368. {
  369. if ( list.GetItemState( ndx, LVIS_SELECTED ) == LVIS_SELECTED )
  370. {
  371. LV_ITEM lvi;
  372. lvi.mask = LVIF_PARAM;
  373. lvi.iItem = ndx;
  374. lvi.iSubItem = 0;
  375. if ( list.GetItem( &lvi ) )
  376. {
  377. // only do something for OK and non-executable hits...
  378. CHitDoc* pHitDoc = (CHitDoc*)(lvi.lParam);
  379. if ( pHitDoc->m_nStatus == IDS_STATUS_OK &&
  380. pHitDoc->m_dwExecute == 0 )
  381. {
  382. ShellExecute( GetSafeHwnd(), "open",
  383. pHitDoc->m_strFile, NULL,
  384. pHitDoc->m_strFolder, SW_SHOW );
  385. }
  386. }
  387. break;
  388. }
  389. ++ndx;
  390. }
  391. }
  392. *pResult = 0;
  393. }
  394. void CHttpSvrView::OnRclick(NMHDR* pNMHDR, LRESULT* pResult)
  395. {
  396. // Get the control....
  397. CListCtrl& list = GetListCtrl();
  398. if ( list.GetSelectedCount() == 1 )
  399. {
  400. CPoint point;
  401. if ( GetCursorPos( &point ) )
  402. DoContextMenu( point );
  403. }
  404. *pResult = 0;
  405. }
  406. void CHttpSvrView::DoContextMenu( const CPoint& point )
  407. {
  408. m_phdPopup = NULL;
  409. // Get the control....
  410. CListCtrl& list = GetListCtrl();
  411. CPoint ptList = point;
  412. list.ScreenToClient( &ptList );
  413. int ndx = list.HitTest( ptList );
  414. if ( ndx != -1 )
  415. {
  416. LV_ITEM lvi;
  417. lvi.mask = LVIF_PARAM;
  418. lvi.iItem = ndx;
  419. lvi.iSubItem = 0;
  420. if ( list.GetItem( &lvi ) )
  421. {
  422. CHitDoc* pHitDoc = (CHitDoc*)(lvi.lParam);
  423. // get the popup menu type index....
  424. int nType = 0;
  425. if ( pHitDoc->m_dwExecute )
  426. nType = 1;
  427. else if ( pHitDoc->m_nStatus != 200 )
  428. nType = 2;
  429. // load the menus....
  430. CMenu menuPopups;
  431. if ( menuPopups.LoadMenu( IDM_POPUPS ) )
  432. {
  433. // get the popup....
  434. CMenu* pMenu = menuPopups.GetSubMenu( nType );
  435. if ( pMenu != NULL )
  436. {
  437. m_phdPopup = pHitDoc;
  438. pMenu->TrackPopupMenu( TPM_LEFTALIGN|TPM_RIGHTBUTTON,
  439. point.x, point.y, this );
  440. }
  441. }
  442. }
  443. }
  444. }
  445. void CHttpSvrView::OnPopupClear()
  446. {
  447. if ( m_phdPopup != NULL )
  448. {
  449. // Get the control....
  450. CListCtrl& list = GetListCtrl();
  451. LV_FINDINFO lvfi;
  452. lvfi.flags = LVFI_PARAM;
  453. lvfi.lParam = (LPARAM)m_phdPopup;
  454. int ndx = list.FindItem( &lvfi );
  455. if ( ndx != -1 )
  456. list.DeleteItem( ndx );
  457. }
  458. }
  459. void CHttpSvrView::OnPopupEdit()
  460. {
  461. if ( m_phdPopup != NULL )
  462. {
  463. ShellExecute( GetSafeHwnd(), "edit",
  464. m_phdPopup->m_strFile, NULL,
  465. m_phdPopup->m_strFolder, SW_SHOW );
  466. }
  467. }
  468. void CHttpSvrView::OnPopupOpen()
  469. {
  470. if ( m_phdPopup != NULL )
  471. {
  472. ShellExecute( GetSafeHwnd(), "open",
  473. m_phdPopup->m_strFile, NULL,
  474. m_phdPopup->m_strFolder, SW_SHOW );
  475. }
  476. }
  477. BOOL CHttpSvrView::InsertHitDoc( CHitDoc* pHitDoc )
  478. {
  479. CListCtrl& list = GetListCtrl();
  480. // look for a match on the file name....
  481. LV_FINDINFO lvfi;
  482. lvfi.flags = LVFI_STRING;
  483. lvfi.psz = pHitDoc->m_strFile;
  484. int ndx = list.FindItem( &lvfi );
  485. while ( ndx != -1 )
  486. {
  487. // match found; see if folder matches....
  488. CString strFolder = list.GetItemText( ndx, COLUMN_PATH );
  489. if ( strFolder.CompareNoCase( pHitDoc->m_strFolder ) == 0 )
  490. {
  491. // matched; get the old HitDoc....
  492. LV_ITEM lvi;
  493. lvi.mask = LVIF_PARAM;
  494. lvi.iItem = ndx;
  495. lvi.iSubItem = 0;
  496. if ( list.GetItem( &lvi ) )
  497. {
  498. // get the old count
  499. CHitDoc* pOldHit = (CHitDoc*)(lvi.lParam);
  500. // add in the previous hits....
  501. pHitDoc->m_nHits += pOldHit->m_nHits;
  502. // delete the old hit....
  503. delete pOldHit;
  504. // update with new HitDoc....
  505. lvi.mask = LVIF_IMAGE|LVIF_PARAM;
  506. lvi.iImage = GetImage( pHitDoc );
  507. lvi.lParam = (LPARAM)pHitDoc;
  508. list.SetItem( &lvi );
  509. // indicate we've made changes....
  510. list.Update( lvi.iItem );
  511. break;
  512. }
  513. }
  514. // get next item....
  515. ndx = list.FindItem( &lvfi, ndx );
  516. }
  517. // if we didn't find anything....
  518. if ( ndx == -1 )
  519. {
  520. // didn't find a match; add it to the list....
  521. LV_ITEM lvi;
  522. lvi.mask = LVIF_TEXT|LVIF_PARAM|LVIF_IMAGE;
  523. lvi.iItem = 0;
  524. lvi.iSubItem = 0;
  525. lvi.pszText = LPSTR_TEXTCALLBACK;
  526. lvi.lParam = (LPARAM)pHitDoc;
  527. lvi.iImage = GetImage( pHitDoc );
  528. if ( (ndx=list.InsertItem( &lvi )) != -1 )
  529. {
  530. // add all the callback sub items....
  531. lvi.mask = LVIF_TEXT;
  532. lvi.pszText = LPSTR_TEXTCALLBACK;
  533. lvi.iItem = ndx;
  534. for( int subNdx=1; subNdx < C_COLUMNS; ++subNdx )
  535. {
  536. lvi.iSubItem = subNdx;
  537. list.SetItem( &lvi );
  538. }
  539. }
  540. else
  541. {
  542. // insert failed; kill it....
  543. delete pHitDoc;
  544. pHitDoc = NULL;
  545. }
  546. }
  547. return (pHitDoc != NULL);
  548. }
  549. void CHttpSvrView::OnViewClear()
  550. {
  551. CListCtrl& list = GetListCtrl();
  552. list.DeleteAllItems();
  553. }