ChannelMenu.cpp
资源名称:p2p_vod.rar [点击查看]
上传用户:liguizhu
上传日期:2015-11-01
资源大小:2422k
文件大小:12k
源码类别:
P2P编程
开发平台:
Visual C++
- /*
- * Openmysee
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
- #include "stdafx.h"
- #include ".channelmenu.h"
- #include "httprequest.h"
- #include "xml.h"
- #include "MultiLanguageMgr.h"
- #include "configfile.h"
- #include "..layer1externalmd5.h"
- static CChannelMenu* pChannelMenu = NULL;
- extern TCHAR g_sAppPath[MAX_PATH];
- CChannelMenu::CChannelMenu(void) : h_channelmenu(NULL), h_MenuThread(NULL),
- channeldataOK(0), ParseDataOK(FALSE), useChannel(FALSE), channelthreadStop(FALSE), updatechannel(0),channelrunning(FALSE),
- xmlurl(_T("http://www.Openmysee.com/program.php")),
- pointcookieurl(_T("http://www.Openmysee.com/")),
- pointurl(_T("http://www.Openmysee.com/member/userstat.php"))
- {
- pHttpSession = new HttpRequest;
- pHttpSession->Create();
- pTrayIconMenu = new CTrayIconMenu;
- }
- CChannelMenu::~CChannelMenu(void)
- {
- DestroyMenu(h_channelmenu);
- channelthreadStop = TRUE;
- pHttpSession->SetStopRequest();
- if(h_MenuThread != NULL)
- {
- WaitForSingleObject(h_MenuThread,INFINITE);
- CloseHandle(h_MenuThread);
- }
- delete pHttpSession;
- delete pTrayIconMenu;
- }
- CChannelMenu* CChannelMenu::CreateInstance(BOOL useChannel)
- {
- if(pChannelMenu == NULL)
- {
- pChannelMenu = new CChannelMenu;
- pChannelMenu->useChannel = useChannel;
- if(useChannel)
- {
- mystring filestr(g_sAppPath);
- filestr.append(_T("\config.ini"));
- ConfigFile config(filestr);
- mystring tmp = config.Value(_T("localserver"), _T("channellist"));
- if(!(config.fileNotFound || config.stringNotFound))
- pChannelMenu->xmlurl = tmp;
- tmp = config.Value(_T("localserver"), _T("userdata"));
- if(!(config.fileNotFound || config.stringNotFound))
- pChannelMenu->pointcookieurl = tmp;
- tmp = config.Value(_T("localserver"), _T("postpointurl"));
- if(!(config.fileNotFound || config.stringNotFound))
- pChannelMenu->pointurl = tmp;
- unsigned int threadID;
- pChannelMenu->h_MenuThread = (HANDLE) _beginthreadex(NULL, 0, &_GetMenuThreadProc, pChannelMenu, 0, &threadID);
- }
- }
- return pChannelMenu;
- }
- CChannelMenu* CChannelMenu::GetInstance()
- {
- return pChannelMenu;
- }
- void CChannelMenu::ReleaseInstance()
- {
- delete pChannelMenu;
- }
- extern volatile HWND g_hMainWnd;
- unsigned int CALLBACK CChannelMenu::_GetMenuThreadProc(void* lpParameter)
- {
- CChannelMenu* pClass = (CChannelMenu*) lpParameter;
- //发生随机数
- srand(GetTickCount());
- int idleinterval = 0;
- int nextworkingtime = 0;
- int getxmlerrcount = 0;
- while(!pClass->channelthreadStop)
- {
- if(idleinterval >= nextworkingtime ) //当定时器被触发时,开始获取XML的行动
- {
- InterlockedExchange(&pClass->channeldataOK, 0);
- if(!pClass->GetChannelXML())
- {
- if(getxmlerrcount < 3) //根据已经发生的错误次数制定逐步加长的重试间隔
- {
- nextworkingtime += 1; //隔1s重试一次
- getxmlerrcount++;
- }
- else if(getxmlerrcount < 6)
- {
- nextworkingtime += 10; //隔10s重试一次
- getxmlerrcount++;
- }
- else //放弃重试,等待下一次定时唤醒
- {
- InterlockedExchange(&pClass->channeldataOK, -1);
- nextworkingtime += 1200;
- getxmlerrcount = 0;
- }
- }
- else
- {
- nextworkingtime += 1200; //隔20min重试一次
- getxmlerrcount = 0;
- InterlockedExchange(&pClass->channeldataOK, 1);
- }
- }
- else if(pClass->updatechannel == 1)
- {
- nextworkingtime = idleinterval;
- InterlockedExchange(&pClass->updatechannel, 0);
- }
- if(idleinterval%300 == 0)
- {
- pClass->PostAddPoint();
- }
- Sleep(1000);
- idleinterval++;
- }
- // PostMessage(g_hMainWnd, WM_COMMAND, WM_APP + 1, 0);
- return 0;
- }
- void CChannelMenu::UpdateChannelNow()
- {
- InterlockedExchange(&channeldataOK, 0);
- InterlockedExchange(&updatechannel, 1);
- }
- BOOL CChannelMenu::PostAddPoint()
- {
- if(channelrunning == FALSE)
- return FALSE;
- mystring deststr(pointurl);
- mystring formatstr;
- deststr.append(_T("?u=")); //userstat?
- TCHAR datastr[36];
- DWORD len = 36;
- if(!HttpRequest::GetCookieEx(pointcookieurl.c_str(), "MYSE_UID", datastr, &len))
- return FALSE;
- deststr.append(datastr); //userstat?<userid>
- formatstr.append(datastr);
- formatstr.append(_T("06My&SEe#211")/*约定的密钥*/);
- int _rand = rand();
- _stprintf(datastr, _T("&r=%d&h="), _rand);
- deststr.append(datastr); //userstat?<userid>&<random num>&
- _stprintf(datastr, _T("%d"), _rand);
- formatstr.append(datastr);
- char* srcstr = new char[formatstr.size() + 20];
- wsprintfA(srcstr, "%s", formatstr.c_str());
- MD5 md5((unsigned char*) srcstr, strlen(srcstr));
- char* result = md5.hex_digest();
- delete[] srcstr;
- wsprintf(datastr, "%hs", result);
- delete[] result;
- deststr.append(datastr); //userstat?<userid>&<random num>&<md5>
- return pHttpSession->OpenRequest(deststr.c_str());
- }
- BOOL CChannelMenu::GetChannelXML()
- {
- LANGID langid = pTrayIconMenu->GetCurLanguage();
- mystring appendxmlurl(xmlurl);
- if(appendxmlurl.find(_T(".php")) != mystring::npos) //对于非PHP的URL,应该不应用参数
- {
- switch(langid)
- {
- case MAINLAND_LANG_ID: //简体中文
- appendxmlurl.append(_T("?lang=zh"));
- break;
- case TAIWAN_LANG_ID:
- case HONGKONG_LANG_ID: //繁体中文
- appendxmlurl.append(_T("?lang=big5"));
- break;
- case DEFAULT_LANG_ID: //英文
- default:
- appendxmlurl.append(_T("?lang=en"));
- }
- }
- if(!pHttpSession->OpenRequest(appendxmlurl.c_str()))
- return FALSE;
- // MessageBox(NULL, "get xml!", "", MB_OK);
- BYTE* tempstr = new BYTE[pHttpSession->getBufLen() + 30];
- memset(tempstr, 0, pHttpSession->getBufLen() + 30);
- pHttpSession->TransBuf(tempstr);
- m_critsec_XMLFile.Lock();
- strXMLFile = (LPCSTR) tempstr;
- m_critsec_XMLFile.Unlock();
- delete[] tempstr;
- return TRUE;
- }
- #ifdef _UNICODE
- static const std::wstring groupname[] =
- {
- _T("GROUP"),
- _T("SUBGROUP"),
- _T("Channel"),
- };
- #else
- static const std::string groupname[] =
- {
- _T("GROUP"),
- _T("SUBGROUP"),
- _T("Channel"),
- };
- #endif
- #define ChannelPos 2
- BOOL CChannelMenu::ParseChannelXML(HMENU hmenu)
- {
- CXML* p_xml = new CXML;
- p_xml->InitXml();
- m_critsec_XMLFile.Lock();
- if(!p_xml->OpenXml(strXMLFile))
- {
- m_critsec_XMLFile.Unlock();
- p_xml->unInitXml();
- delete p_xml;
- return FALSE;
- }
- m_critsec_XMLFile.Unlock();
- if(p_xml->SetNodelist(groupname[0].c_str()) != 0)
- MakePopupItem(p_xml, hmenu, 0);
- if(p_xml->SetNodelist(groupname[ChannelPos].c_str()) != 0)
- MakePopupItem(p_xml, hmenu, ChannelPos);
- p_xml->unInitXml();
- delete p_xml;
- return TRUE;
- }
- void CChannelMenu::MakePopupItem(CXML* p_xml, HMENU hmenu, int isubgroup)
- {
- BOOL ischannel = (groupname[isubgroup] == _T("Channel"));
- while(p_xml->ToNextNode())
- {
- if(!ischannel)
- {
- HMENU h_appendmenu = CreatePopupMenu();
- if(p_xml->ToSubNodeList(groupname[isubgroup + 1].c_str()) != 0) //将组名设定成下一级的组名
- {
- MakePopupItem(p_xml, h_appendmenu, isubgroup + 1);
- p_xml->BackParentNodeList();
- }
- if((isubgroup + 1 != ChannelPos) && (p_xml->ToSubNodeList(groupname[ChannelPos].c_str()) != 0)) //在本组下面寻找Channel并加入
- {
- MakePopupItem(p_xml, h_appendmenu, ChannelPos);
- p_xml->BackParentNodeList();
- }
- if(GetMenuItemCount(h_appendmenu) <= 0) //如果最后子菜单中一项都没有, 这个node是错误的, 抛弃它
- {
- assert(0);
- DestroyMenu(h_appendmenu);
- }
- else
- {
- mystring str;
- p_xml->GetCurNodeAttrValue(str, _T("Name"));
- AppendMenu(hmenu, MF_STRING | MF_POPUP, (UINT_PTR) h_appendmenu, str.c_str());
- }
- }
- else//本身已经是Channel,加入菜单中
- {
- ChannelData data;
- p_xml->GetCurNodeAttrValue(data.name, _T("Name"));
- p_xml->GetCurNodeAttrValue(data.url, _T("URL"));
- channellist.push_back(data);
- AppendMenu(hmenu, MF_STRING , TRAYWM_CHANNELSTART + channellist.size() - 1, data.name.c_str());
- }
- }
- }
- LPCTSTR CChannelMenu::GetChannelByCmdID(DWORD m_cmdID)
- {
- if(m_cmdID < TRAYWM_CHANNELSTART || m_cmdID > TRAYWM_CHANNELEND)
- return NULL;
- size_t index = m_cmdID - TRAYWM_CHANNELSTART;
- if(index >= channellist.size())
- return NULL;
- channellist[index].desc.append(channellist[index].url.c_str());
- return channellist[index].url.c_str();
- }
- namespace{
- //一份默认的菜单
- UINT_PTR m_traycmd[] =
- {
- TRAYWM_HOMEPAGE,
- CTrayIconMenu::ID_SEPERATOR,
- //CTrayIconMenu::ID_EXTERNAL, 0,
- //CTrayIconMenu::ID_SEPERATOR,
- CTrayIconMenu::ID_POPUP,
- TRAYWM_UPDATE,
- CTrayIconMenu::ID_LANGUAGE,
- CTrayIconMenu::ID_END,
- CTrayIconMenu::ID_SEPERATOR,
- CTrayIconMenu::ID_POPUP,
- TRAYWM_HELP,
- TRAYWM_NETWORK,
- TRAYWM_EMAIL,
- TRAYWM_ABOUT,
- CTrayIconMenu::ID_END,
- CTrayIconMenu::ID_SEPERATOR,
- TRAYWM_EXIT,
- CTrayIconMenu::ID_END};
- //不同语言的菜单文本,必须和数据严格对应,每一个数据项在文本里都应该有一个*,包括ID_END, ID_SEPERATOR等
- //ID_EXTERNAL除外,其后接一项没有*,而ID_POPUP后应该增加一项*作为标记
- /*const TCHAR m_traystrgb[] =
- _T("首页(&P)*-*频道(&C)*-*设置(&S)*SUBSTART*检查更新(&U)*选择语言(&L)*END*-*帮助(&H)*SUBSTART*使用帮助(&H)*判定网络(&N)*电子邮件(&E)*关于(&A)*END*-*退出(&E)*END*");
- */
- const TCHAR m_traystrgb[] =
- _T("首页(&P)*-*设置(&S)*SUBSTART*检查更新(&U)*选择语言(&L)*END*-*帮助(&H)*SUBSTART*使用帮助(&H)*判定网络(&N)*电子邮件(&E)*关于(&A)*END*-*退出(&E)*END*");
- //这里用"-"表示一个分隔符,"SUBSTART"表示开始一个新子菜单,"END"表示一个菜单结束。也可以换成任何方便的字符,程序并不理会它们
- const UINT m_channellisthandlepos = 3;
- }
- BOOL CChannelMenu::ShowRButtonTIMenu(HWND hparent)
- {
- h_channelmenu = CreatePopupMenu(); //初始化一个提示的菜单
- AppendMenu(h_channelmenu, MF_SEPARATOR, (UINT_PTR) 0, NULL); //加条分隔线意思一下,以防万一……
- m_traycmd[m_channellisthandlepos] = (UINT_PTR) h_channelmenu;;
- pTrayIconMenu->ShowMenu(hparent, m_traycmd, m_traystrgb);
- DestroyMenu(h_channelmenu); //放弃生成的菜单
- h_channelmenu = NULL;
- ParseDataOK = FALSE; //因为生成的菜单已放弃,所以已正确解析的标记变成FALSE
- return TRUE;
- }
- void CChannelMenu::OnPopupMenu(HMENU hmenu, int popuppos)
- {
- if(pTrayIconMenu->OnMenuPopup(hmenu, popuppos))
- return;
- if(hmenu != h_channelmenu) //不是频道窗口不需要处理
- return;
- int count = GetMenuItemCount(hmenu);
- if(count == -1) //菜单错误,放弃解析
- return;
- for(int i = 0; i < count; i++)
- DeleteMenu(hmenu, 0, MF_BYPOSITION); //清除掉整个菜单里的内容
- MultiLanguage langDll;
- if(channeldataOK == 0) //数据未准备好
- {
- AppendMenu(h_channelmenu, MF_STRING | MF_DISABLED , (UINT_PTR) 0, langDll.GetStringByStr(_T("数据读取中...")));
- }
- else if(channeldataOK == -1) //获取数据错误
- {
- AppendMenu(h_channelmenu, MF_STRING | MF_DISABLED , (UINT_PTR) 0, langDll.GetStringByStr(_T("数据读取失败!")));
- AppendMenu(hmenu, MF_SEPARATOR, 0, NULL);
- AppendMenu(hmenu, MF_STRING, TRAYWM_UPDATECHANNEL, langDll.GetStringByStr(_T("更新频道列表")));
- }
- else
- {
- if(ParseChannelXML(hmenu) == TRUE)
- {
- AppendMenu(hmenu, MF_SEPARATOR, 0, NULL);
- AppendMenu(hmenu, MF_STRING, TRAYWM_UPDATECHANNEL, langDll.GetStringByStr(_T("更新频道列表")));
- }
- else
- {
- AppendMenu(hmenu, MF_STRING | MF_DISABLED, 0, langDll.GetStringByStr(_T("频道文件解析失败")));
- }
- }
- }