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

📄 todaypluginwnd.cpp.svn-base

📁 wince c++ 下 开发的 rss 阅读器源代码
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
		if (Config.DisplayIcon && (point.x >= 0 && point.x <= SCALEX(21) && point.y >= 0 && point.y <= SCALEY(21))) {
			OpenConfig();
		}
		else
			OnAction();
	}

	Invalidate();
}


LRESULT CTodayPluginWnd::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) {
	if (message == WM_SH_UIMETRIC_CHANGE) {
		OnUIMetricChange(wParam, lParam);
		return 0;
	}
	else if (message == ReadConfigMessage) {
		OnReadConfig();
		return 0;
	}
	else if (message == ReloadSubscriptionsMessage) {
		if (wParam == -1)
			SetEvent(HReloadSubscriptions);
		else {
			// reload particular site
			int idx = (int) wParam;
			if (0 <= idx && idx < SiteList.GetCount()) {
				EnterCriticalSection(&CSSiteList);

				CSiteItem *si = SiteList.GetAt(idx);
				LoadSiteItem(si, idx + 1);
				LoadSiteItemUnreadCount(si, idx + 1);

				if (si->Info->TodayShow)
					ReloadFeed(si);
				else
					UnloadFeed(si);

				UpdateUnreadNewCounts();

				LeaveCriticalSection(&CSSiteList);
			}
		}
		return 0;
	}
	else if (message == CheckFeedsMessage) {
		SetEvent(HCheckFeeds);
		return 0;
	}
	else if (message == UpdateFeedFlagsMessage) {
		int idx = wParam;
		EnterCriticalSection(&CSSiteList);
		if (0 <= idx && idx < SiteList.GetCount())
			SiteList.GetAt(idx)->SetModified();
		LeaveCriticalSection(&CSSiteList);

		SetEvent(HUpdateFeedFlags);
		return 0;
	}
	else {
		switch (message) {
			case WM_TODAYCUSTOM_QUERYREFRESHCACHE:
				return OnQueryRefreshCache((TODAYLISTITEM *) wParam);

			case WM_TODAYCUSTOM_CLEARCACHE:
				OnClearCache((TODAYLISTITEM *) wParam);
				return 0;

			case WM_TODAYCUSTOM_RECEIVEDSELECTION:
				if (!NewsAvailable() && Config.HidePlugin)
					// if zero height, pass the selection along to the next item
					return FALSE;
				else {
					Selected = TRUE;
					InvalidateRect(NULL, FALSE);
					return TRUE;
				}

			case WM_TODAYCUSTOM_LOSTSELECTION:
				Selected = FALSE;
				InvalidateRect(NULL, FALSE);
				break;

			case WM_TODAYCUSTOM_USERNAVIGATION:
				return FALSE;

			case WM_TODAYCUSTOM_ACTION:
				OnAction();
				break;
		}

		return CWnd::WindowProc(message, wParam, lParam);
	}
}

extern CPrssrtodayApp theApp;

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

	// Note: Loading from resource did not work for me :(
	CString s;
	CMenu popup;
	popup.CreatePopupMenu();
	s.LoadString(IDS_UPDATE_ALL); popup.AppendMenu(MF_ENABLED | MF_STRING, ID_TODAY_UPDATEALL, s);
	popup.AppendMenu(MF_SEPARATOR);
	s.LoadString(IDS_MODE_BRIEF); popup.AppendMenu(MF_ENABLED | MF_STRING, ID_TODAY_BRIEF, s);
	s.LoadString(IDS_MODE_CYCLING); popup.AppendMenu(MF_ENABLED | MF_STRING, ID_TODAY_CYCLING, s);
	popup.AppendMenu(MF_SEPARATOR);
	s.LoadString(IDS_SETTINGS); popup.AppendMenu(MF_ENABLED | MF_STRING, ID_TODAY_SETTINGS, s);

	UINT idCheck;
	switch (Config.Mode) {
		case MODE_BRIEF: idCheck = ID_TODAY_BRIEF; break;
		case MODE_CYCLING: idCheck = ID_TODAY_CYCLING; break;
	}
	popup.CheckMenuRadioItem(ID_TODAY_BRIEF, ID_TODAY_TREE, idCheck, MF_BYCOMMAND);

	ClientToScreen(&pt);
	popup.TrackPopupMenu(TPM_LEFTALIGN, pt.x, pt.y, this);
}

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

	if (nIDEvent == (UINT) CycleTimer) {
		if (Config.Mode == MODE_CYCLING)
			Cycle();
	}
	else if (nIDEvent == TapAndHoldTimer) {
		ReleaseCapture();

		KillTimer(TapAndHoldTimer);
		Selected = FALSE;

		// 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) {
			ContextMenu(LastCursorPos);
		}
	}

	CWnd::OnTimer(nIDEvent);
}

void CTodayPluginWnd::OnTodayBrief() {
	LOG0(5, "CTodayPluginWnd::OnTodayBrief()");

	Config.Mode = MODE_BRIEF;
	Config.Save();

	Invalidate();
}

void CTodayPluginWnd::OnTodayCycling() {
	LOG0(5, "CTodayPluginWnd::OnTodayCycling()");

	Config.Mode = MODE_CYCLING;
	Config.Save();

	Invalidate();
}

void CTodayPluginWnd::OnTodayUpdateall() {
	LOG0(5, "CTodayPluginWnd::OnTodayUpdateall()");

	UpdateAll();
}

void CTodayPluginWnd::OnTodaySettings() {
	LOG0(5, "CTodayPluginWnd::OnTodaySettings()");

	OpenConfig();
}


void CTodayPluginWnd::OnSize(UINT nType, int cx, int cy) {
	LOG0(5, "CTodayPluginWnd::OnSize()");

	CWnd::OnSize(nType, cx, cy);
}

/////////////////////////////////////////////////////////////////////////////

void CTodayPluginWnd::UpdateAll() {
	LOG0(1, "CTodayPluginWnd::UpdateAll()");

	HWND hPRSSRWnd = FindPRSSRMainWindow();
	if (hPRSSRWnd != NULL) {
		// pRSSreader is running -> send a message
		::SendMessage(hPRSSRWnd, UWM_UPDATE_ALL, 0, 0);
	}
	else {
		// pRSSreader is NOT running -> start it
		PROCESS_INFORMATION pi;
		CString fileName;
		fileName.Format(_T("%s\\%s"), Config.InstallDir, PRSSREADER_BIN);
		::CreateProcess(fileName, _T("/updateall"), NULL, NULL, FALSE, 0, NULL, NULL, NULL, &pi);
	}
}

void CTodayPluginWnd::Cycle() {
	LOG0(3, "CTodayPluginWnd::Cycle()");

	if (NewsAvailable() && SiteIdx != -1) {
		int oldSiteIdx = SiteIdx;
		int oldItemIdx = ItemIdx;
		BOOL bMoved = FALSE;

		do {
			if (SiteList.GetCount() <= 0) {
				SiteIdx = -1;
				break;
			}

			if (Config.CyclingSubMode == CYCLING_SUBMODE_FEED_ITEMS) {
				CSiteItem *si = SiteList.GetAt(SiteIdx);

				if (si->Status == CSiteItem::Ok && si->Info->TodayShow) {
					if (si->Feed != NULL) {
						ItemIdx++;
						if (ItemIdx >= si->Feed->GetItemCount()) {
							SiteIdx = (SiteIdx + 1) % SiteList.GetCount();
							ItemIdx = -1;
						}
						else if (ItemIdx < 0) {
							ItemIdx = -1;
						}
						else {
							if (Config.ShowOnlyNew) {
								CFeedItem *fi = si->Feed->GetItem(ItemIdx);
								if (!fi->IsDeleted() && (fi->IsNew() || fi->IsUnread())) {
									bMoved = TRUE;
								}
							}
							else {
								// show all items
								bMoved = TRUE;
							}
						}
					}
					else {
						SiteIdx = (SiteIdx + 1) % SiteList.GetCount();
					}
				}
				else {
					SiteIdx = (SiteIdx + 1) % SiteList.GetCount();
				}

				if (SiteIdx == oldSiteIdx && ItemIdx == oldItemIdx)
					break;
			}
			else {
				SiteIdx = (SiteIdx + 1) % SiteList.GetCount();
				ItemIdx = 0;

				CSiteItem *si = SiteList.GetAt(SiteIdx);
				if (si->Status == CSiteItem::Ok && si->Info->TodayShow) {
					if (Config.ShowOnlyNew) {
						if (si->GetUnreadCount() > 0)
							bMoved = TRUE;
					}
					else
						bMoved = TRUE;
				}

				if (SiteIdx == oldSiteIdx)
					break;
			}
		} while (!bMoved);

		// has the site changed?
		if (oldSiteIdx != SiteIdx) {
			InvalidateSiteTitle();
			InvalidateFeedItem();
		}
		// has the feed item changed?
		if (oldItemIdx != ItemIdx)
			InvalidateFeedItem();

		// to reflect changes in config
		KillTimer(CycleTimer);
		SetTimer(CycleTimer, Config.CyclingSpeed * 1000, NULL);
	}
}

void CTodayPluginWnd::OpenConfig() {
	LOG0(3, "CTodayPluginWnd::OpenConfig()");

	COptChannelsPg pgChannels;
	COptAppearancePg pgAppearance;
	COptModePg pgMode;

	CCePropertySheet sheet(IDS_OPTION_TITLE);
	sheet.AddPage(&pgChannels);
	sheet.AddPage(&pgMode);
	sheet.AddPage(&pgAppearance);
	sheet.SetMenu(IDR_DONE);

	if (sheet.DoModal()) {
		Config.Save();

		LoadFonts();
		SetEvent(HCheckFeeds);
	}
}

void CTodayPluginWnd::UpdateUnreadNewCounts() {
	LOG0(3, "CTodayPluginWnd::UpdateUnreadNewCounts()");

	int newItems = NewItems;
	int unreadItems = UnreadItems;

	NewItems = 0;
	UnreadItems = 0;

	// load flags for registry
	for (int i = 0; i < SiteList.GetCount(); i++) {
		CSiteItem *si = SiteList.GetAt(i);

		if (si->Info->TodayShow && si->Feed != NULL) {
			NewItems += si->Feed->GetNewCount();
			UnreadItems += si->Feed->GetUnreadCount();
		}
	}

	if (unreadItems != UnreadItems || newItems != NewItems)
		Invalidate();
}

void CTodayPluginWnd::InvalidateSiteTitle() {
	LOG0(5, "CTodayPluginWnd::InvalidateSiteTitle()");

	CRect rcClient;
	GetClientRect(&rcClient);

	rcClient.top += SCALEY(Config.VOffset);
	rcClient.left += SCALEX(4);
	if (Config.DisplayIcon)
		rcClient.left += SCALEX(24);
	InvalidateRect(rcClient);
	UpdateWindow();
}

void CTodayPluginWnd::InvalidateFeedItem() {
	LOG0(5, "CTodayPluginWnd::InvalidateFeedItem()");

	CRect rcClient;
	GetClientRect(&rcClient);

	rcClient.top += SCALEY(Config.VOffset);
	if (Config.ShowSiteName)
		rcClient.top += RowHeight + SCALEY(2) + SCALEY(2);
	rcClient.left += SCALEX(4);
	if (Config.DisplayIcon)
		rcClient.left += SCALEX(24);
	InvalidateRect(rcClient);
	UpdateWindow();
}


//
// returns TRUE if news are here
//
BOOL CTodayPluginWnd::NewsAvailable() {
	LOG0(5, "CTodayPluginWnd::NewsAvailable()");

	EnterCriticalSection(&CSSiteList);
	int itemCount = 0;
	if (Config.ShowOnlyNew) {
		for (int i = 0; i < SiteList.GetCount(); i++) {
			CSiteItem *si = SiteList.GetAt(i);
			if (si->Status == CSiteItem::Ok && si->Info->TodayShow && si->Feed != NULL)
				itemCount += si->Feed->GetNewCount() + si->Feed->GetUnreadCount();

			if (itemCount > 0)
				break;
		}
	}
	else {
		for (int i = 0; i < SiteList.GetCount(); i++) {
			CSiteItem *si = SiteList.GetAt(i);
			if (si->Status == CSiteItem::Ok && si->Info->TodayShow && si->Feed != NULL)
				itemCount += si->Feed->GetItemCount();

			if (itemCount > 0)
				break;
		}
	}
	LeaveCriticalSection(&CSSiteList);

	return itemCount > 0;
}

CString CTodayPluginWnd::GetPrssFilePath() {
	LOG0(5, "CTodayPluginWnd::GetPrssFilePath()");
	CString fileName;
	fileName.Format(_T("%s\\%s"), Config.InstallDir, PRSSREADER_BIN);
//	LOG1(1, "file = '%S'", fileName);

	return fileName;
}

void CTodayPluginWnd::OpenReader() {
	LOG0(1, "CTodayPluginWnd::OpenReader()");

	PROCESS_INFORMATION pi;
	::CreateProcess(GetPrssFilePath(), _T(""), NULL, NULL, FALSE, 0, NULL, NULL, NULL, &pi);
}

void CTodayPluginWnd::OpenReaderSite(int siteIdx) {
	LOG1(1, "CTodayPluginWnd::OpenReaderSite(%d)", siteIdx);

	PROCESS_INFORMATION pi;
	CString pars;

	HWND hPRSSRMain = FindPRSSRMainWindow();
	if (hPRSSRMain != NULL) {
		::PostMessage(hPRSSRMain, UWM_OPEN_SITE, siteIdx, 0);
	}
	else {
		pars.Format(_T("/opensite %d"), siteIdx);
	}
	::CreateProcess(GetPrssFilePath(), pars, NULL, NULL, FALSE, 0, NULL, NULL, NULL, &pi);
}

void CTodayPluginWnd::OpenReaderFeedItem(int siteIdx, int feedIdx) {
	LOG2(1, "CTodayPluginWnd::OpenReaderFeedItem(%d, %d)", siteIdx, feedIdx);

	PROCESS_INFORMATION pi;
	CString pars;

	HWND hPRSSRMain = FindPRSSRMainWindow();
	if (hPRSSRMain != NULL) {
		::PostMessage(hPRSSRMain, UWM_OPEN_FEEDITEM, siteIdx, (LPARAM) feedIdx);
	}
	else {
		pars.Format(_T("/openitem %d %d"), siteIdx, feedIdx);
	}
	::CreateProcess(GetPrssFilePath(), pars, NULL, NULL, FALSE, 0, NULL, NULL, NULL, &pi);
}

void CTodayPluginWnd::UnloadFeed(CSiteItem *si) {
	LOG0(3, "CTodayPluginWnd::UnloadFeed()");

	delete si->Feed;
	si->Feed = NULL;
	si->Status = CSiteItem::Empty;
	memset(&(si->LastUpdate), 0, sizeof(FILETIME));
	si->UpdateCachedCounts();
}

void CTodayPluginWnd::ReloadFeed(CSiteItem *si) {
	LOG0(3, "CTodayPluginWnd::UnloadFeed()");
	// reload
	si->Status = CSiteItem::Empty;
	si->EnsureSiteLoaded();
}

void CTodayPluginWnd::CheckFeedFile(CSiteItem *si) {
	LOG0(3, "CTodayPluginWnd::CheckFeedFile()");

	if (si != NULL && si->Info != NULL) {
		if (si->Info->TodayShow) {
			CString sXmlFileName;

			sXmlFileName.Format(_T("%s\\feeds\\%s"), Config.CacheLocation, si->Info->FileName);
			if (IsFileChanged(sXmlFileName, &(si->LastUpdate))) {
				LOG1(3, "Reloaded: '%S'", si->Name);
				// feed file was changed -> reload it
				ReloadFeed(si);

				if (!GetFileTime(sXmlFileName, &(si->LastUpdate)))
					memset(&(si->LastUpdate), 0, sizeof(FILETIME));
			}
		}
		else {
			// unload the feed
			if (si->Status == CSiteItem::Ok) {
				LOG1(3, "Unloading: '%S'", si->Name);
				UnloadFeed(si);
			}
		}
	}
}

void CTodayPluginWnd::UpdateFeedFlags(CSiteItem *si) {
	LOG0(3, "CTodayPluginWnd::UpdateFeedFlags()");

	if (si != NULL && si->Info != NULL) {
		if (si->Info->TodayShow && si->IsModified()) {
			LOG1(3, "Updating flags: '%S'", si->Name);
			// reload feed file
			ReloadFeed(si);
		}
	}
}

DWORD CTodayPluginWnd::Thread() {
	LOG0(1, "CTodayPluginWnd::Thread() - start");

	// wait until cache location is accessible
	// (if cache is located on sd-card, is it not available right after the reboot)
	while (!DirectoryExists(Config.CacheLocation))
		Sleep(1000);

	// load all feeds
	Loading = TRUE;
	SetEvent(HCheckFeeds);

	// periodically check each feed file and if it was changed, reload it
	HANDLE handles[] = { HTerminate, HCheckFeeds, HReloadSubscriptions, HUpdateFeedFlags };
	while (TRUE) {
		DWORD dwResult = WaitForMultipleObjects(countof(handles), handles, FALSE, INFINITE);
		if (dwResult == WAIT_OBJECT_0) {
			// terminate
			break;
		}
		else if (dwResult == WAIT_OBJECT_0 + 1) {
			// check if the feed was changed
			EnterCriticalSection(&CSSiteList);
			for (int i = 0; i < SiteList.GetCount(); i++) {
				CSiteItem *si = SiteList.GetAt(i);
				CheckFeedFile(si);

				// break loading if terminated is signaled
				if (WaitForSingleObject(HTerminate, 0) == WAIT_OBJECT_0)
					break;
			}
			UpdateUnreadNewCounts();
			LeaveCriticalSection(&CSSiteList);
			Loading = FALSE;
		}
		else if (dwResult == WAIT_OBJECT_0 + 2) {
			// reload subscriptions
			CSiteList tmpSiteList;
			LoadSiteList(tmpSiteList);

			CSiteItem *root = tmpSiteList.GetRoot();
			EnterCriticalSection(&CSSiteList);
			SiteList.Destroy();
			SiteList.CreateFrom(root);
			SiteList.SetRoot(root);

			if (SiteList.GetCount() > 0)
				SiteIdx = 0;
			else
				SiteIdx = -1;
			LeaveCriticalSection(&CSSiteList);

			SetEvent(HCheckFeeds);
		}
		else if (dwResult == WAIT_OBJECT_0 + 3) {
			// update feed flags
			EnterCriticalSection(&CSSiteList);
			for (int i = 0; i < SiteList.GetCount(); i++) {
				CSiteItem *si = SiteList.GetAt(i);
				UpdateFeedFlags(si);

				// break loading if terminated is signaled
				if (WaitForSingleObject(HTerminate, 0) == WAIT_OBJECT_0)
					break;
			}
			UpdateUnreadNewCounts();
			LeaveCriticalSection(&CSSiteList);
		}
	}

	CloseHandle(HThread);
	HThread = NULL;

	LOG0(1, "CTodayPluginWnd::Thread() - end");

	return 0;
}

⌨️ 快捷键说明

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