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

📄 feedview.cpp.svn-base

📁 wince c++ 下 开发的 rss 阅读器源代码
💻 SVN-BASE
📖 第 1 页 / 共 3 页
字号:

			y += ht - ofsY;
			ofsY = 0;				// for the rest of the items, the ofsY is zero

			//
			memDC.SelectObject(saveBmp);
		}

		// delete the rest of the window
		CRect rcRest(rc.left, y, rc.right, rc.bottom);
		dc.FillSolidRect(rcRest, Appearance.ClrFeedViewBg);
	}
	else {
		CString sText;
		sText.LoadString(IDS_NO_ITEMS_TO_DISPLAY);

		dc.FillSolidRect(rc, Appearance.ClrFeedViewBg);

		rc.DeflateRect(SCALEX(8), SCALEY(8));

		CFont *pFont = dc.SelectObject(&Appearance.BaseFont);
		dc.SetTextColor(Appearance.ClrFeedViewFg);
		dc.DrawText(sText, &rc, DT_CENTER | DT_TOP | DT_NOPREFIX | DT_WORDBREAK);
		dc.SelectObject(pFont);
	}

	dc.RestoreDC(nSavedDC);

	// Do not call CWnd::OnPaint() for painting messages
}

BOOL CFeedView::OnEraseBkgnd(CDC *pDC) {
	return TRUE;
}

static DWORD WINAPI ScrollThread(LPVOID lpParam) {
	CFeedView *view = (CFeedView *) lpParam;

    int top = view->m_nViewTop;
	while (view->m_bScrolling) {
		int oldtop = view->m_nViewTop;
		top += view->m_nScrollDelta;
		view->m_nViewTop = top;
		view->AdjustViewTop();
		if (oldtop != view->m_nViewTop) {
			view->ScrollWindowEx(0, oldtop - view->m_nViewTop, &view->m_rcScroll, &view->m_rcScroll,
				NULL, NULL, SW_INVALIDATE);
			view->m_oVScrollBar.SetScrollPos(view->m_nViewTop, TRUE);
			view->UpdateWindow();
			view->OnMouseMove(view->m_nOldKeys, view->m_ptOldCursorPos);
		}

		Sleep(SCROLL_SLEEP);
	}

	return 0;
}

void CFeedView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar *pScrollBar) {
	int i = m_nViewTop;
	switch (nSBCode) {
		// FIXME
		case SB_LINEDOWN:   m_nViewTop += SCALEY(20); break;
		case SB_LINEUP:     m_nViewTop -= SCALEY(20); break;
		case SB_PAGEDOWN:   m_nViewTop += m_nClientHeight; break;
		case SB_PAGEUP:     m_nViewTop -= m_nClientHeight; break;
		case SB_THUMBTRACK: {
			SCROLLINFO si;
			si.cbSize = sizeof(si);
			si.fMask = SIF_TRACKPOS;
			m_oVScrollBar.GetScrollInfo(&si);
			m_nViewTop = si.nTrackPos;
		}
	}

	AdjustViewTop();

	ScrollWindowEx(0, i - m_nViewTop, &m_rcScroll, &m_rcScroll, NULL, NULL, SW_INVALIDATE);
	m_oVScrollBar.SetScrollPos(m_nViewTop, TRUE);
	UpdateWindow();
}

void CFeedView::UpdateScrollBars() {
	LOG0(3, "CFeedView::UpdateScrollBars()");

	BOOL visible = m_oVScrollBar.IsWindowVisible();

	if (m_nClientHeight >= m_nTotalHeight) {
		m_oVScrollBar.ShowScrollBar(FALSE);
	}
	else {
		m_oVScrollBar.ShowScrollBar(TRUE);

		SCROLLINFO sbi = { 0 };
		sbi.cbSize = sizeof(sbi);
		sbi.fMask = SIF_RANGE | SIF_POS | SIF_PAGE;
		sbi.nMin = 0;
		sbi.nMax = m_nTotalHeight - 1;
		sbi.nPage = m_nClientHeight;
		sbi.nPos = m_nViewTop;
		m_oVScrollBar.SetScrollInfo(&sbi);
	}
}

void CFeedView::OnSize(UINT nType, int cx, int cy) {
	CWnd::OnSize(nType, cx, cy);

	m_nClientHeight = cy;
	m_nClientWidth = cx;

	CRect rcClient;
	GetClientRect(rcClient);

	m_rcScroll = rcClient;

	// place the scroll bar
	CRect rcVert;
	rcVert.top    = -SCALEY(1);
	rcVert.bottom = rcClient.bottom + SCALEY(1);
	rcVert.right  = rcClient.right + SCALEX(1);
	rcVert.left   = rcVert.right - GetSystemMetrics(SM_CXVSCROLL);

	m_oVScrollBar.SetWindowPos(NULL, rcVert.left, rcVert.top, rcVert.Width(), rcVert.Height(), SWP_NOZORDER);

	AdjustViewTop();
	UpdateScrollBars();

	Invalidate();
}

int CFeedView::ItemFromPoint(CPoint pt) {
	if (m_oItemHeight.GetSize() > 0) {
		int y = m_nViewTop + pt.y;
		for (int i = 0; i < m_oItemHeight.GetSize(); i++)
			if (m_oItemHeight[i] >= y)
				return i;
		return m_oItemHeight.GetSize();
	}
	else
		return -1;
}

// Normal

void CFeedView::OnLButtonDownNormal(UINT nFlags, CPoint point) {
	SetFocus();

	int item = ItemFromPoint(point);
	if (item >= 0 && item < m_oItems.GetSize()) {
		CRect rcClient;
		GetClientRect(rcClient);

		if (point.x >= 0 && point.x <= SCALEY(20)) {
			m_nFlagItem = item;
		}

		if (m_nSelectStart <= item && item <= m_nSelectEnd) {
			m_nSelectFirst = item;
		}
		else {
			// deselect
			m_nSelectFirst = m_nSelectStart = m_nSelectEnd = item;
			Invalidate(FALSE);
		}

		m_bSelecting = TRUE;
		m_bClick = TRUE;

		LastCursorPos = point;

		// tap and hold
		SHRGINFO  shrg;
		shrg.cbSize = sizeof(shrg);
		shrg.hwndClient = GetSafeHwnd();
		shrg.ptDown.x = LastCursorPos.x;
		shrg.ptDown.y = LastCursorPos.y;
		shrg.dwFlags = SHRG_NOTIFYPARENT | SHRG_RETURNCMD;

		if (::SHRecognizeGesture(&shrg) == GN_CONTEXTMENU) {
			Invalidate(FALSE);

			CPoint pt = point;
			ClientToScreen(&pt);
			ContextMenu(&pt);

			m_nFlagItem = -1;
			m_bSelecting = FALSE;
		}
		else {
			SetCapture();
			Default();
		}
	}
	else {
		// tap out of items (deselect all)
		m_nSelectStart = m_nSelectEnd = m_nSelectFirst = -1;
		m_bSelecting = FALSE;
		Invalidate(FALSE);
	}
}

void CFeedView::OnMouseMoveNormal(UINT nFlags, CPoint pt) {
	// Scrolling
	if (m_nTotalHeight > m_nClientHeight && GetCapture() == this) {
		int delta = 0;
		if (pt.y < 0) {
			delta = ((pt.y / SCALEY(SCROLL_SPEED)) - SCALEY(1));
			pt.y = 0;
		}
		else if (pt.y >= m_nClientHeight) {
			delta = (((pt.y - m_nClientHeight) / SCALEY(SCROLL_SPEED)) + SCALEY(1));
			pt.y = m_nClientHeight - SCALEY(1);
		}

		if (delta) {
			if (delta > SCALEY(SCROLL_MAXSPEED))
				delta = SCALEY(SCROLL_MAXSPEED);
			else if (delta < -SCALEY(SCROLL_MAXSPEED))
				delta = -SCALEY(SCROLL_MAXSPEED);

			m_nScrollDelta = delta;
			if (!m_bScrolling) {
				m_bScrolling = TRUE;
				CloseHandle(CreateThread(NULL, 0, ScrollThread, (LPVOID) this, 0, NULL));
			}
		}
		else
			m_bScrolling = FALSE;
	}

	if (m_bSelecting) {
		int item = ItemFromPoint(pt);
		if (item < 0) item = 0;
		if (item >= m_oItems.GetSize()) item = m_oItems.GetSize() - 1;

		if (item <= m_nSelectFirst) {
			m_nSelectStart = item;
			m_nSelectEnd = m_nSelectFirst;
		}
		if (item >= m_nSelectFirst) {
			m_nSelectStart = m_nSelectFirst;
			m_nSelectEnd = item;
		}

		Invalidate(FALSE);

		if (abs(pt.x - LastCursorPos.x) > SCALEX(3) || abs(pt.y - LastCursorPos.y) > SCALEX(3))
			m_bClick = FALSE;
	}

	m_nOldKeys = nFlags;
	m_ptOldCursorPos = pt;
}

void CFeedView::OnLButtonUpNormal(UINT nFlags, CPoint point) {
	ReleaseCapture();

	int item = ItemFromPoint(point);
	if (item >= 0 && item < m_oItems.GetSize()) {
		if (item == m_nFlagItem && point.x >= 0 && point.x <= SCALEY(20)) {
			if (GetItem(item)->IsFlagged())
				UnflagItem(item);
			else
				FlagItem(item);

			m_nSelectFirst = item;
			m_nSelectStart = m_nSelectEnd = item;

			Invalidate(FALSE);
		}
		else if (m_bSelecting) {
			if (item == m_nSelectFirst && m_bClick) {
				OpenItem(item);
				Invalidate(FALSE);
			}
		}
	}

	m_bScrolling = FALSE;
	m_bSelecting = FALSE;
}

// TOUCH

void CFeedView::OnLButtonDownTouch(UINT nFlags, CPoint point) {
	int item = ItemFromPoint(point);
	if (item >= 0 && item < m_oItems.GetSize()) {
		CRect rcClient;
		GetClientRect(rcClient);

		if (point.x >= 0 && point.x <= SCALEY(20)) {
			m_nFlagItem = item;
		}

		m_bClick = TRUE;

		LastCursorPos = point;

		// tap and hold
		SHRGINFO  shrg;
		shrg.cbSize = sizeof(shrg);
		shrg.hwndClient = GetSafeHwnd();
		shrg.ptDown.x = LastCursorPos.x;
		shrg.ptDown.y = LastCursorPos.y;
		shrg.dwFlags = SHRG_NOTIFYPARENT | SHRG_RETURNCMD;

		if (::SHRecognizeGesture(&shrg) == GN_CONTEXTMENU) {
			InvalidateItem(m_nSelectFirst, FALSE);
			m_nSelectStart = m_nSelectEnd = m_nSelectFirst = item;
			InvalidateItem(item, FALSE);

			CPoint pt = point;
			ClientToScreen(&pt);
			ContextMenu(&pt);

			m_nFlagItem = -1;
			m_bSelecting = FALSE;
		}
		else {
			SetCapture();
			Default();
		}
	}
	else {
		// tap out of items (deselect all)
		m_nSelectStart = m_nSelectEnd = m_nSelectFirst = -1;
		m_bSelecting = FALSE;
		Invalidate(FALSE);
	}
}

void CFeedView::OnMouseMoveTouch(UINT nFlags, CPoint pt) {
	if (abs(pt.x - LastCursorPos.x) > SCALEX(3) || abs(pt.y - LastCursorPos.y) > SCALEX(3))
		m_bClick = FALSE;

	// Scrolling
	if (m_nTotalHeight > m_nClientHeight && GetCapture() == this) {
		m_bScrolling = TRUE;

		int delta = LastCursorPos.y - pt.y;

		int top = m_nViewTop;
		m_nViewTop += delta;

		AdjustViewTop();

		ScrollWindowEx(0, top - m_nViewTop, &m_rcScroll, &m_rcScroll, NULL, NULL, SW_INVALIDATE);
		m_oVScrollBar.SetScrollPos(m_nViewTop, TRUE);
		UpdateWindow();

		LastCursorPos = pt;
	}
}

void CFeedView::OnLButtonUpTouch(UINT nFlags, CPoint point) {
	ReleaseCapture();

	int item = ItemFromPoint(point);
	if (item >= 0 && item < m_oItems.GetSize()) {
		if (m_bClick) {
			if (m_nFlagItem == item && point.x >= 0 && point.x <= SCALEY(20)) {
				if (GetItem(item)->IsFlagged())
					UnflagItem(item);
				else
					FlagItem(item);

				InvalidateItem(m_nSelectFirst, FALSE);
				m_nSelectFirst = item;
				m_nSelectStart = m_nSelectEnd = item;
				InvalidateItem(item, FALSE);
			}
			else if (m_bClick) {
				InvalidateItem(m_nSelectFirst, FALSE);
				m_nSelectFirst = item;
				m_nSelectStart = m_nSelectEnd = item;
				InvalidateItem(item, FALSE);

				OpenItem(item);
			}
		}
		else {

		}
	}

	m_bClick = FALSE;
	m_bScrolling = FALSE;
	m_bSelecting = FALSE;
}


void CFeedView::OnLButtonDown(UINT nFlags, CPoint point) {
	switch (Config.NavigationType) {
		case NAVIGATION_NORMAL: OnLButtonDownNormal(nFlags, point); break;
		default:
		case NAVIGATION_TOUCH: OnLButtonDownTouch(nFlags, point); break;
	}
}

void CFeedView::OnMouseMove(UINT nFlags, CPoint pt) {
	switch (Config.NavigationType) {
		case NAVIGATION_NORMAL: OnMouseMoveNormal(nFlags, pt); break;
		default:
		case NAVIGATION_TOUCH: OnMouseMoveTouch(nFlags, pt); break;
	}
}

void CFeedView::OnLButtonUp(UINT nFlags, CPoint point) {
	switch (Config.NavigationType) {
		case NAVIGATION_NORMAL: OnLButtonUpNormal(nFlags, point); break;
		default:
		case NAVIGATION_TOUCH: OnLButtonUpTouch(nFlags, point); break;
	}
}


// keys

void CFeedView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) {
	LOG3(5, "CFeedView::OnKeyDown(%d, %d, %d)", nChar, nRepCnt, nFlags);

	switch (nChar) {
		case VK_UP:
			MoveToPrevItem();
			break;

		case VK_DOWN:
			MoveToNextItem();
			break;

		case VK_LEFT:
			if (SiteItem->Type != CSiteItem::VFolder) {
				int oldSiteIdx = Config.ActSiteIdx;
				MoveToPrevChannel();

				CMainFrame *frame = (CMainFrame *) AfxGetMainWnd();
				frame->AddSiteToSave(oldSiteIdx);
				frame->PreloadSite(Config.ActSiteIdx);
			}
			break;

		case VK_RIGHT:
			if (SiteItem->Type != CSiteItem::VFolder) {
				int oldSiteIdx = Config.ActSiteIdx;
				MoveToNextChannel();

				CMainFrame *frame = (CMainFrame *) AfxGetMainWnd();
				frame->AddSiteToSave(oldSiteIdx);
				frame->PreloadSite(Config.ActSiteIdx);
			}
			break;

		case VK_RETURN:
			if (!(nFlags & 0x4000)) {
				m_bOpenCtxMenu = FALSE;
				SetTimer(CtxMenuTimer, TIMER_KEY_CTX_MENU, NULL);
			}
			break;

		default:
			break;
	}

	CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
}

void CFeedView::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) {
	LOG3(5, "CFeedView::OnKeyUp(%d, %d, %d)", nChar, nRepCnt, nFlags);

	switch (nChar) {
		case VK_RETURN:
			KillTimer(CtxMenuTimer);
			if (m_bOpenCtxMenu) {
				m_bOpenCtxMenu = FALSE;
				if (m_oItems.GetSize() > 0 && m_nSelectFirst >= 0) {
					int y;
					if (m_nSelectFirst > 0) y = (m_oItemHeight[m_nSelectFirst] + m_oItemHeight[m_nSelectFirst - 1]) / 2;
					else y = m_oItemHeight[m_nSelectFirst] / 2;
					y -= m_nViewTop;

					CPoint pt(m_nClientWidth / 2, y);
					ClientToScreen(&pt);
					ContextMenu(&pt);
				}
				else
					CWnd::OnKeyUp(nChar, nRepCnt, nFlags);
			}
			else {
				if (m_oItems.GetSize() > 0 && m_nSelectFirst >= 0)
					OpenItem(m_nSelectFirst);
				CWnd::OnKeyUp(nChar, nRepCnt, nFlags);
			}
			break;

		case VK_APPS: {
			CPoint pt;
			int y;

			if (m_nSelectFirst > 0) y = (m_oItemHeight[m_nSelectFirst] + m_oItemHeight[m_nSelectFirst - 1]) / 2;
			else y = m_oItemHeight[m_nSelectFirst] / 2;
			y -= m_nViewTop;

			pt.x = m_nClientWidth / 2;
			pt.y = y;

			ClientToScreen(&pt);

			ContextMenu(&pt);
			} break;

		default:
			CWnd::OnKeyUp(nChar, nRepCnt, nFlags);
			break;
	}
}

void CFeedView::ContextMenu(CPoint *pt) {
	LOG0(5, "CFeedView::ContextMenu()");

	if (m_nSelectFirst != -1) {
		CMenu popup;
		popup.CreatePopupMenu();

		AppendMenuFromResource(&popup, IDR_OPEN);
		popup.AppendMenu(MF_SEPARATOR);
		AppendMenuFromResource(&popup, IDR_FEEDITEM);
		AppendMenuFromResource(&popup, IDR_CACHE);
		AppendMenuFromResource(&popup, IDR_ENCLOSURES);
		AppendMenuFromResource(&popup, IDR_COPY_URL);
		AppendMenuFromResource(&popup, IDR_SEND_BY_EMAIL);
		popup.AppendMenu(MF_SEPARATOR);
		AppendMenuFromResource(&popup, IDR_ITEM_OPER);

		// track popup menu
		popup.TrackPopupMenu(TPM_TOPALIGN | TPM_LEFTALIGN, pt->x, pt->y, AfxGetMainWnd());
	}
}

void CFeedView::OnTimer(UINT nIDEvent) {
	LOG0(5, "CFeedView::OnTimer()");

	if (nIDEvent == CtxMenuTimer) {
		m_bOpenCtxMenu = TRUE;
		KillTimer(CtxMenuTimer);
	}

	CWnd::OnTimer(nIDEvent);
}

⌨️ 快捷键说明

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