📄 todaypluginwnd.cpp.svn-base
字号:
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 + -