1 // ------------------------------------------------
6 // Simple tray icon interface to PeerCast, mostly win32 related stuff.
8 // (c) 2002 peercast.org
9 // ------------------------------------------------
10 // This program is free software; you can redistribute it and/or modify
11 // it under the terms of the GNU General Public License as published by
12 // the Free Software Foundation; either version 2 of the License, or
13 // (at your option) any later version.
15 // This program is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 // ------------------------------------------------
29 #include "win32/wsys.h"
36 #include "chkMemoryLeak.h"
37 #define DEBUG_NEW new(__FILE__, __LINE__)
41 #define MAX_LOADSTRING 100
44 #define RELAY_CMD 8000
48 #define MAX_CHANNELS 999
53 void loadIcons(HINSTANCE hInstance, HWND hWnd);
56 UINT g_iTaskbarCreated = ~0; // for PCRaw (tray icon)
60 static int currNotify=0;
64 static HMENU trayMenu = NULL,ltrayMenu = NULL; // for PCRaw (tray icon)
66 bool allowMulti=false;
68 bool allowTrayMenu=true;
69 static bool winDistinctionNT=false;
70 int seenNewVersionTime=0;
73 bool chanInfoIsRelayed;
76 ULONG_PTR gdiplusToken;
78 // ---------------------------------
79 Sys * APICALL MyPeercastInst::createSys()
81 return new WSys(mainWnd);
83 // ---------------------------------
84 const char * APICALL MyPeercastApp ::getIniFilename()
86 return iniFileName.cstr();
89 // ---------------------------------
90 const char *APICALL MyPeercastApp ::getClientTypeOS()
95 // ---------------------------------
96 const char * APICALL MyPeercastApp::getPath()
98 return exePath.cstr();
101 // --------------------------------- JP-EX
102 void APICALL MyPeercastApp ::openLogFile()
104 logFile.openWriteReplace("log.txt");
106 // --------------------------------- JP-EX
107 void APICALL MyPeercastApp ::getDirectory()
109 char path_buffer[256],drive[32],dir[128];
110 GetModuleFileName(NULL,path_buffer,255);
111 _splitpath(path_buffer,drive,dir,NULL,NULL);
112 sprintf(servMgr->modulePath,"%s%s",drive,dir);
114 // --------------------------------- JP-EX
115 bool APICALL MyPeercastApp ::clearTemp()
117 if (servMgr->clearPLS)
124 class NOTIFYICONDATA2
127 DWORD cbSize; // DWORD
131 UINT uCallbackMessage; // UINT
132 HICON hIcon; // HICON
133 char szTip[128]; // char[128]
134 DWORD dwState; // DWORD
135 DWORD dwStateMask; // DWORD
136 char szInfo[256]; // char[256]
137 UINT uTimeoutOrVersion; // UINT
138 char szInfoTitle[64]; // char[64]
139 DWORD dwInfoFlags; // DWORD
140 //GUID guidItem; > IE 6
143 NOTIFYICONDATA2 trayIcon;
147 HINSTANCE hInst; // current instance
148 TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
149 TCHAR szWindowClass[MAX_LOADSTRING]; // The title bar text
150 TCHAR szWindowClass2[MAX_LOADSTRING]; // The title bar text
151 TCHAR szWindowClass3[MAX_LOADSTRING]; // The title bar text
153 // Foward declarations of functions included in this code module:
154 ATOM MyRegisterClass(HINSTANCE hInstance);
155 ATOM MyRegisterClass2(HINSTANCE hInstance);
156 ATOM MyRegisterClass3(HINSTANCE hInstance);
157 BOOL InitInstance(HINSTANCE, int);
158 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
159 LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
160 LRESULT CALLBACK ChanInfoProc(HWND, UINT, WPARAM, LPARAM);
162 void setTrayIcon(int type, const char *,const char *,bool);
163 void flipNotifyPopup(int id, ServMgr::NOTIFY_TYPE nt);
168 bool gbGetFile = FALSE;
169 bool gbStart = FALSE;
172 // --------------------------------------------------
173 void LOG2(const char *fmt,...)
178 vsprintf(str,fmt,ap);
179 OutputDebugString(str);
185 // ---------------------------------------
186 int APIENTRY WinMain(HINSTANCE hInstance,
187 HINSTANCE hPrevInstance,
193 ::_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
202 iniFileName.set(".\\peercast.ini");
204 WIN32_FIND_DATA fd; //JP-EX
205 HANDLE hFind; //JP-EX
207 OSVERSIONINFO osInfo; //JP-EX
208 osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); //JP-EX
209 GetVersionEx(&osInfo);
210 if (osInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
211 winDistinctionNT = true;
213 winDistinctionNT = false;
215 // off by default now
218 if (strlen(lpCmdLine) > 0)
221 if ((p = strstr(lpCmdLine,"-inifile"))!=NULL)
222 iniFileName.setFromString(p+8);
224 if (strstr(lpCmdLine,"-zen"))
227 if (strstr(lpCmdLine,"-multi"))
230 if (strstr(lpCmdLine,"-kill"))
233 if ((p = strstr(lpCmdLine,"-url"))!=NULL)
248 strncpy(tmpURL,p,sizeof(tmpURL)-1);
254 exePath = iniFileName;
255 char *s = exePath.cstr();
267 if (strnicmp(tmpURL,"peercast://",11)==0)
269 if (strnicmp(tmpURL+11,"pls/",4)==0)
270 chanURL = tmpURL+11+4;
280 // Initialize global strings
281 //LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
282 //LoadString(hInstance, IDC_APP_TITLE, szWindowClass, MAX_LOADSTRING);
284 strcpy(szTitle,"PeerCast");
285 strcpy(szWindowClass,"PeerCast");
286 strcpy(szWindowClass2,"Main");
287 strcpy(szWindowClass3,"Start");
293 HANDLE mutex = CreateMutex(NULL,TRUE,szWindowClass);
295 if (GetLastError() == ERROR_ALREADY_EXISTS)
297 HWND oldWin = FindWindow(szWindowClass,NULL);
300 SendMessage(oldWin,WM_SHOWGUI,0,0);
303 SendMessage(oldWin,WM_DESTROY,0,0);
310 copy.dwData = WM_PLAYCHANNEL;
311 copy.cbData = strlen(chanURL)+1; // plus null term
312 copy.lpData = chanURL;
313 SendMessage(oldWin,WM_COPYDATA,NULL,(LPARAM)©);
316 SendMessage(oldWin,WM_SHOWGUI,0,0);
326 MyRegisterClass(hInstance);
327 MyRegisterClass2(hInstance);
328 MyRegisterClass3(hInstance);
330 // Perform application initialization:
331 if (!InitInstance (hInstance, nCmdShow))
334 peercastInst = new MyPeercastInst();
335 peercastApp = new MyPeercastApp();
337 peercastInst->init();
339 LOG_DEBUG("Set OS Type: %s",winDistinctionNT?"WinNT":"Win9x");
341 if (peercastApp->clearTemp()) //JP-EX
343 DeleteFile("play.pls");
344 hFind = FindFirstFile("*.asx",&fd);
345 if (hFind != INVALID_HANDLE_VALUE)
349 DeleteFile((char *)&fd.cFileName);
351 while (FindNextFile(hFind,&fd));
360 servMgr->procConnectArgs(chanURL,info);
361 chanMgr->findAndPlayChannel(info,false);
365 memset(&t,0,sizeof(t));
366 t.tm_year = 2007 - 1900;
372 gtStartTime = ::mktime(&t);
375 gtGetFile = ::mktime(&t);
377 if (gtStartTime > sys->getTime()){
382 hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_SIMPLE);
384 // setup menu notifes
385 int mask = peercastInst->getNotifyMask();
386 if (mask & ServMgr::NT_PEERCAST)
387 CheckMenuItem(trayMenu,ID_POPUP_SHOWMESSAGES_PEERCAST,MF_CHECKED|MF_BYCOMMAND);
388 if (mask & ServMgr::NT_BROADCASTERS)
389 CheckMenuItem(trayMenu,ID_POPUP_SHOWMESSAGES_BROADCASTERS,MF_CHECKED|MF_BYCOMMAND);
390 if (mask & ServMgr::NT_TRACKINFO)
391 CheckMenuItem(trayMenu,ID_POPUP_SHOWMESSAGES_TRACKINFO,MF_CHECKED|MF_BYCOMMAND);
393 // Main message loop:
394 while (GetMessage(&msg, NULL, 0, 0))
396 if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
398 TranslateMessage(&msg);
399 DispatchMessage(&msg);
403 Shell_NotifyIcon(NIM_DELETE, (NOTIFYICONDATA*)&trayIcon);
405 peercastInst->saveSettings();
406 peercastInst->quit();
408 Gdiplus::GdiplusShutdown(gdiplusToken);
416 // FUNCTION: MyRegisterClass()
418 // PURPOSE: Registers the window class.
422 // This function and its usage is only necessary if you want this code
423 // to be compatible with Win32 systems prior to the 'RegisterClassEx'
424 // function that was added to Windows 95. It is important to call this function
425 // so that the application will get 'well formed' small icons associated
428 ATOM MyRegisterClass(HINSTANCE hInstance)
432 wcex.cbSize = sizeof(WNDCLASSEX);
434 wcex.style = CS_HREDRAW | CS_VREDRAW;
435 wcex.lpfnWndProc = (WNDPROC)WndProc;
438 wcex.hInstance = hInstance;
439 wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_SIMPLE);
440 wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
441 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
442 // wcex.lpszMenuName = (LPCSTR)IDC_SIMPLE;
443 wcex.lpszMenuName = NULL;
444 wcex.lpszClassName = szWindowClass;
445 wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
447 return RegisterClassEx(&wcex);
450 ATOM MyRegisterClass2(HINSTANCE hInstance)
454 wcex.cbSize = sizeof(WNDCLASSEX);
456 wcex.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS ;
457 wcex.lpfnWndProc = (WNDPROC)GUIProc;
460 wcex.hInstance = hInstance;
461 wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_SIMPLE);
462 wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
463 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
464 // wcex.lpszMenuName = (LPCSTR)IDC_SIMPLE;
465 wcex.lpszMenuName = NULL;
466 wcex.lpszClassName = szWindowClass2;
467 wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
469 return RegisterClassEx(&wcex);
472 ATOM MyRegisterClass3(HINSTANCE hInstance)
476 wcex.cbSize = sizeof(WNDCLASSEX);
478 wcex.style = CS_HREDRAW | CS_VREDRAW;
479 wcex.lpfnWndProc = (WNDPROC)StartProc;
482 wcex.hInstance = hInstance;
483 wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_SIMPLE);
484 wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
485 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
486 // wcex.lpszMenuName = (LPCSTR)IDC_SIMPLE;
487 wcex.lpszMenuName = NULL;
488 wcex.lpszClassName = szWindowClass3;
489 wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
491 return RegisterClassEx(&wcex);
494 //-----------------------------
495 void loadIcons(HINSTANCE hInstance, HWND hWnd)
497 icon1 = LoadIcon(hInstance, (LPCTSTR)IDI_SMALL);
498 icon2 = LoadIcon(hInstance, (LPCTSTR)IDI_SMALL2);
500 trayIcon.cbSize = sizeof(trayIcon);
501 trayIcon.hWnd = hWnd;
503 trayIcon.uFlags = NIF_MESSAGE + NIF_ICON + NIF_TIP;
504 trayIcon.uCallbackMessage = WM_TRAYICON;
505 trayIcon.hIcon = icon1;
506 strcpy(trayIcon.szTip, "PeerCast");
508 Shell_NotifyIcon(NIM_ADD, (NOTIFYICONDATA*)&trayIcon);
510 //ShowWindow(hWnd, nCmdShow);
513 if(!trayMenu) // for PCRaw (tray icon)
514 trayMenu = LoadMenu(hInstance,MAKEINTRESOURCE(IDR_TRAYMENU));
515 if(!ltrayMenu) // for PCRaw (tray icon)
516 ltrayMenu = LoadMenu(hInstance,MAKEINTRESOURCE(IDR_LTRAYMENU));
521 //-----------------------------
523 // FUNCTION: InitInstance(HANDLE, int)
525 // PURPOSE: Saves instance handle and creates main window
529 // In this function, we save the instance handle in a global variable and
530 // create and display the main program window.
532 BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
536 hInst = hInstance; // Store instance handle in our global variable
538 hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
539 CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
548 g_iTaskbarCreated = RegisterWindowMessage("TaskbarCreated"); // for PCRaw (tray icon)
550 loadIcons(hInstance,hWnd);
552 using namespace Gdiplus;
553 GdiplusStartupInput gdiplusStartupInput;
554 GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
558 //-----------------------------
559 //static String trackTitle;
560 //static String channelComment;
562 //-----------------------------
563 void channelPopup(const char *title, const char *msg, bool isPopup = true)
567 if (*title == '\0') return;
573 trayIcon.uFlags = NIF_ICON|NIF_TIP;
574 strncpy(trayIcon.szTip, both.cstr(),sizeof(trayIcon.szTip)-1);
575 trayIcon.szTip[sizeof(trayIcon.szTip)-1]=0;
577 if (isPopup) trayIcon.uFlags |= 16;
578 trayIcon.uTimeoutOrVersion = 10000;
579 strncpy(trayIcon.szInfo,msg,sizeof(trayIcon.szInfo)-1);
580 strncpy(trayIcon.szInfoTitle,title,sizeof(trayIcon.szInfoTitle)-1);
582 Shell_NotifyIcon(NIM_MODIFY, (NOTIFYICONDATA*)&trayIcon);
584 //-----------------------------
585 void clearChannelPopup()
587 trayIcon.uFlags = NIF_ICON|16;
588 trayIcon.uTimeoutOrVersion = 10000;
589 strncpy(trayIcon.szInfo,"",sizeof(trayIcon.szInfo)-1);
590 strncpy(trayIcon.szInfoTitle,"",sizeof(trayIcon.szInfoTitle)-1);
591 Shell_NotifyIcon(NIM_MODIFY, (NOTIFYICONDATA*)&trayIcon);
594 //-----------------------------
603 static PopupEntry *PEList = NULL;
606 static void putPopupEntry(PopupEntry *pe)
614 static PopupEntry *getPopupEntry(GnuID id)
617 PopupEntry *pe = PEList;
618 PopupEntry *prev = NULL;
620 if (id.isSame(pe->id)) {
621 if (prev) prev->next = pe->next;
622 else PEList = pe->next;
634 static PopupEntry *getTopPopupEntry()
636 PopupEntry *p = NULL;
640 PEList = PEList->next;
646 //-----------------------------
647 void APICALL MyPeercastApp::channelStart(ChanInfo *info)
650 // lastPlayID = info->id;
652 // if(!isIndexTxt(info)) // for PCRaw (popup)
653 // clearChannelPopup();
655 PopupEntry *pe = getPopupEntry(info->id);
660 if (!isIndexTxt(info))
665 //-----------------------------
666 void APICALL MyPeercastApp::channelStop(ChanInfo *info)
668 // if (info->id.isSame(lastPlayID))
670 // lastPlayID.clear();
672 // if(!isIndexTxt(info)) // for PCRaw (popup)
673 // clearChannelPopup();
676 PopupEntry *pe = getPopupEntry(info->id);
679 pe = getTopPopupEntry();
683 if (ServMgr::NT_TRACKINFO & peercastInst->getNotifyMask())
685 String name,track; //JP-Patch
686 name = pe->name; //JP-Patch
687 track = pe->track; //JP-Patch
688 name.convertTo(String::T_SJIS); //JP-Patch
689 track.convertTo(String::T_SJIS); //JP-Patch
691 // channelPopup(info->name.cstr(),trackTitle.cstr());
692 channelPopup(name.cstr(),track.cstr(), false); //JP-Patch
697 //-----------------------------
698 void APICALL MyPeercastApp::channelUpdate(ChanInfo *info)
702 PopupEntry *pe = getPopupEntry(info->id);
706 tmp.append(info->track.artist);
708 tmp.append(info->track.title);
711 if (!tmp.isSame(pe->track))
713 pe->name = info->name;
715 if (ServMgr::NT_TRACKINFO & peercastInst->getNotifyMask())
718 String name,track; //JP-Patch
719 name = info->name; //JP-Patch
720 track = tmp; //JP-Patch
721 name.convertTo(String::T_SJIS); //JP-Patch
722 track.convertTo(String::T_SJIS); //JP-Patch
723 if(!isIndexTxt(info)) // for PCRaw (popup)
726 // channelPopup(info->name.cstr(),trackTitle.cstr());
727 channelPopup(name.cstr(),track.cstr()); //JP-Patch
730 } else if (!info->comment.isSame(pe->comment))
732 pe->name = info->name;
733 pe->comment = info->comment;
734 if (ServMgr::NT_BROADCASTERS & peercastInst->getNotifyMask())
736 //channelComment = info->comment;
737 String name,comment; //JP-Patch
738 name = info->name; //JP-Patch
739 comment = info->comment; //JP-Patch
740 name.convertTo(String::T_SJIS); //JP-Patch
741 comment.convertTo(String::T_SJIS); //JP-Patch
742 if(!isIndexTxt(info)) // for PCRaw (popup)
745 // channelPopup(info->name.cstr(),channelComment.cstr());
746 channelPopup(name.cstr(),comment.cstr());
751 if (!isIndexTxt(info))
757 //-----------------------------
758 void APICALL MyPeercastApp::notifyMessage(ServMgr::NOTIFY_TYPE type, const char *msg)
762 if (type == ServMgr::NT_UPGRADE)
764 trayIcon.uFlags = NIF_ICON;
765 trayIcon.hIcon = icon2;
767 trayIcon.uFlags = NIF_ICON;
768 trayIcon.hIcon = icon1;
771 const char *title="";
775 case ServMgr::NT_UPGRADE:
776 title = "Upgrade alert";
778 case ServMgr::NT_PEERCAST:
779 title = "Message from PeerCast:";
784 if (type & peercastInst->getNotifyMask())
786 trayIcon.uFlags |= 16;
787 trayIcon.uTimeoutOrVersion = 10000;
788 strncpy(trayIcon.szInfo,msg,sizeof(trayIcon.szInfo)-1);
789 strncpy(trayIcon.szInfoTitle,title,sizeof(trayIcon.szInfoTitle)-1);
790 Shell_NotifyIcon(NIM_MODIFY, (NOTIFYICONDATA*)&trayIcon);
793 //-----------------------------
797 void createGUI(HWND hWnd)
800 guiWnd = ::CreateWindow(szWindowClass2,
802 WS_OVERLAPPEDWINDOW & ~(WS_MAXIMIZEBOX) /*| WS_VSCROLL | WS_HSCROLL*/,
812 ShowWindow(guiWnd,SW_SHOWNORMAL);
817 // addRelayedChannelsMenu(HMENU m)
820 void addRelayedChannelsMenu(HMENU cm)
822 int cnt = GetMenuItemCount(cm);
823 for(int i=0; i<cnt-3; i++)
824 DeleteMenu(cm,0,MF_BYPOSITION);
826 Channel *c = chanMgr->channel;
831 char str[128],name[64];
832 strncpy(name,c->info.name,32);
834 if (strlen(c->info.name) > 32)
838 sprintf(str,"%s (%d kb/s %s)",name,c->info.bitrate,ChanInfo::getTypeStr(c->info.contentType));
839 //InsertMenu(cm,0,MF_BYPOSITION,RELAY_CMD+i,str);
845 typedef int (*COMPARE_FUNC)(const void *,const void *);
847 static int compareHitLists(ChanHitList **c2, ChanHitList **c1)
849 return stricmp(c1[0]->info.name.cstr(),c2[0]->info.name.cstr());
852 static int compareChannels(Channel **c2, Channel **c1)
854 return stricmp(c1[0]->info.name.cstr(),c2[0]->info.name.cstr());
858 // addAllChannelsMenu(HMENU m)
861 void addAllChannelsMenu(HMENU cm)
863 int cnt = GetMenuItemCount(cm);
864 /* for(int i=0; i<cnt-2; i++)
865 DeleteMenu(cm,0,MF_BYPOSITION);*/
867 for(int i=0; i<cnt; i++)
868 DeleteMenu(cm,0,MF_BYPOSITION);
870 HMENU yMenu = CreatePopupMenu();
871 if (!servMgr->rootHost2.isEmpty()){
872 InsertMenu(yMenu,0,MF_BYPOSITION,ID_POPUP_YELLOWPAGES2,servMgr->rootHost2);
874 if (!servMgr->rootHost.isEmpty()){
875 InsertMenu(yMenu,0,MF_BYPOSITION,ID_POPUP_YELLOWPAGES1,servMgr->rootHost);
878 InsertMenu(cm,0,MF_BYPOSITION|MF_POPUP,(UINT)yMenu,"
\83C
\83G
\83\8d\81[
\83y
\81[
\83W");
879 InsertMenu(cm,0,MF_BYPOSITION|MF_SEPARATOR,NULL,NULL);
880 // add channels to menu
882 Channel *ch = chanMgr->channel;
885 char str[128],name[64];
886 String sjis; //JP-Patch
887 sjis = ch->info.name; //JP-Patch
888 sjis.convertTo(String::T_SJIS); //JP-Patch
889 strncpy(name,sjis.cstr(),32);
890 //strncpy(name,ch->info.name,32);
892 //if (strlen(ch->info.name) > 32)
893 if (strlen(sjis.cstr()) > 32) //JP-Patch
896 sprintf(str,"%s (%d kb/s %s)",name,ch->info.bitrate,ChanInfo::getTypeStr(ch->info.contentType));
898 HMENU opMenu = CreatePopupMenu();
899 InsertMenu(opMenu,0,MF_BYPOSITION,INFO_CMD+numActive,"Info");
900 if (ch->info.url.isValidURL())
901 InsertMenu(opMenu,0,MF_BYPOSITION,URL_CMD+numActive,"URL");
902 InsertMenu(opMenu,0,MF_BYPOSITION,PLAY_CMD+numActive,"Play");
904 UINT fl = MF_BYPOSITION|MF_POPUP;
906 fl |= (ch->isPlaying()?MF_CHECKED:0);
908 InsertMenu(cm,0,fl,(UINT)opMenu,str);
917 // InsertMenu(cm,0,MF_BYPOSITION,0,"<No channels>");
926 // flipNotifyPopup(id, flag)
927 void flipNotifyPopup(int id, ServMgr::NOTIFY_TYPE nt)
929 int mask = peercastInst->getNotifyMask();
933 CheckMenuItem(trayMenu,id,MF_CHECKED|MF_BYCOMMAND);
935 CheckMenuItem(trayMenu,id,MF_UNCHECKED|MF_BYCOMMAND);
937 peercastInst->setNotifyMask(mask);
938 peercastInst->saveSettings();
942 static void showHTML(const char *file)
945 sprintf(url,"%s/%s",servMgr->htmlPath,file);
947 // sys->callLocalURL(url,servMgr->serverHost.port);
948 sys->callLocalURL(url, // for PCRaw (url)
949 (servMgr->allowServer1&Servent::ALLOW_HTML)?(servMgr->serverHost.port):(servMgr->serverHost.port+1));
952 static ChanInfo getChannelInfo(int index)
954 Channel *c = chanMgr->findChannelByIndex(index);
963 // FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
965 // PURPOSE: Processes messages for the main window.
967 // WM_COMMAND - process the application menu
968 // WM_PAINT - Paint the main window
969 // WM_DESTROY - post a quit message and return
972 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
978 if(message == g_iTaskbarCreated) // for PCRaw (tray icon)
979 loadIcons(hInst, hWnd);
993 SendMessage(hWnd,WM_SHOWMENU,2,0);
994 SetForegroundWindow(hWnd);
998 SendMessage(hWnd,WM_SHOWMENU,1,0);
999 SetForegroundWindow(hWnd);
1001 case WM_LBUTTONDBLCLK:
1009 COPYDATASTRUCT *pc = (COPYDATASTRUCT *)lParam;
1010 LOG_DEBUG("URL request: %s",pc->lpData);
1011 if (pc->dwData == WM_PLAYCHANNEL)
1014 servMgr->procConnectArgs((char *)pc->lpData,info);
1015 chanMgr->findAndPlayChannel(info,false);
1017 //sys->callLocalURL((const char *)pc->lpData,servMgr->serverHost.port);
1020 case WM_GETPORTNUMBER:
1023 port=servMgr->serverHost.port;
1030 if (servMgr->saveGuiPos){
1031 CheckMenuItem(trayMenu, ID_POPUP_SAVE_GUI_POS, MF_CHECKED|MF_BYCOMMAND);
1033 CheckMenuItem(trayMenu, ID_POPUP_SAVE_GUI_POS, MF_UNCHECKED|MF_BYCOMMAND);
1036 SetForegroundWindow(hWnd);
1037 bool skipMenu=false;
1039 allowTrayMenu = false;
1041 // check for notifications
1042 if (currNotify & ServMgr::NT_UPGRADE)
1044 if (servMgr->downloadURL[0])
1046 if ((sys->getTime()-seenNewVersionTime) > (60*60)) // notify every hour
1048 if (MessageBox(hWnd,"A newer version of PeerCast is available, press OK to upgrade.","PeerCast",MB_OKCANCEL|MB_APPLMODAL|MB_ICONEXCLAMATION) == IDOK)
1049 sys->getURL(servMgr->downloadURL);
1051 seenNewVersionTime=sys->getTime();
1064 SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWnd, 0);
1065 GetCursorPos(&point);
1067 if (point.x < rcWnd.left){
1068 point.x = rcWnd.left;
1069 flg |= TPM_LEFTALIGN;
1071 if (point.x > rcWnd.right){
1072 point.x = rcWnd.right;
1073 flg |= TPM_RIGHTALIGN;
1075 if (point.y < rcWnd.top){
1076 point.y = rcWnd.top;
1077 flg |= TPM_TOPALIGN;
1079 if (point.y > rcWnd.bottom){
1080 point.y = rcWnd.bottom;
1081 flg |= TPM_BOTTOMALIGN;
1084 flg = TPM_RIGHTALIGN;
1090 menu = GetSubMenu(trayMenu,0);
1091 addAllChannelsMenu(GetSubMenu(menu,0));
1092 addRelayedChannelsMenu(GetSubMenu(menu,1));
1095 menu = GetSubMenu(ltrayMenu,0);
1096 addAllChannelsMenu(menu);
1099 if (!TrackPopupMenu(menu,flg,point.x,point.y,0,hWnd,NULL))
1101 LOG_ERROR("Can`t track popup menu: %d",GetLastError());
1103 PostMessage(hWnd,WM_NULL,0,0);
1106 allowTrayMenu = true;
1116 wmId = LOWORD(wParam);
1117 wmEvent = HIWORD(wParam);
1119 if ((wmId >= INFO_CMD) && (wmId < INFO_CMD+MAX_CHANNELS))
1121 int c = wmId - INFO_CMD;
1122 chanInfo = getChannelInfo(c);
1123 chanInfoIsRelayed = false;
1124 if (winDistinctionNT)
1125 DialogBox(hInst, (LPCTSTR)IDD_CHANINFO, hWnd, (DLGPROC)ChanInfoProc);
1128 HWND WKDLG; //JP-Patch
1129 WKDLG = CreateDialog(hInst, (LPCTSTR)IDD_CHANINFO, hWnd, (DLGPROC)ChanInfoProc); //JP-Patch
1130 ShowWindow(WKDLG,SW_SHOWNORMAL); //JP-Patch
1134 if ((wmId >= URL_CMD) && (wmId < URL_CMD+MAX_CHANNELS))
1136 int c = wmId - URL_CMD;
1137 chanInfo = getChannelInfo(c);
1138 if (chanInfo.url.isValidURL())
1139 sys->getURL(chanInfo.url);
1142 if ((wmId >= PLAY_CMD) && (wmId < PLAY_CMD+MAX_CHANNELS))
1144 int c = wmId - PLAY_CMD;
1145 chanInfo = getChannelInfo(c);
1146 chanMgr->findAndPlayChannel(chanInfo,false);
1149 if ((wmId >= RELAY_CMD) && (wmId < RELAY_CMD+MAX_CHANNELS))
1151 int c = wmId - RELAY_CMD;
1152 chanInfo = getChannelInfo(c);
1153 chanMgr->findAndPlayChannel(chanInfo,true);
1157 // Parse the menu selections:
1160 case ID_POPUP_SHOWMESSAGES_PEERCAST:
1161 flipNotifyPopup(ID_POPUP_SHOWMESSAGES_PEERCAST,ServMgr::NT_PEERCAST);
1163 case ID_POPUP_SHOWMESSAGES_BROADCASTERS:
1164 flipNotifyPopup(ID_POPUP_SHOWMESSAGES_BROADCASTERS,ServMgr::NT_BROADCASTERS);
1166 case ID_POPUP_SHOWMESSAGES_TRACKINFO:
1167 flipNotifyPopup(ID_POPUP_SHOWMESSAGES_TRACKINFO,ServMgr::NT_TRACKINFO);
1170 case ID_POPUP_ABOUT:
1172 DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
1174 case ID_POPUP_SHOWGUI:
1175 case IDM_SETTINGS_GUI:
1176 case ID_POPUP_ADVANCED_SHOWGUI:
1181 case ID_POPUP_YELLOWPAGES:
1182 sys->getURL("http://yp.peercast.org/");
1184 case ID_POPUP_YELLOWPAGES1:
1185 sprintf(buf, "http://%s",servMgr->rootHost.cstr());
1188 case ID_POPUP_YELLOWPAGES2:
1189 sprintf(buf, "http://%s",servMgr->rootHost2.cstr());
1193 case ID_POPUP_ADVANCED_VIEWLOG:
1194 showHTML("viewlog.html");
1196 case ID_POPUP_ADVANCED_SAVESETTINGS:
1197 servMgr->saveSettings(iniFileName.cstr());
1199 case ID_POPUP_ADVANCED_INFORMATION:
1200 showHTML("index.html");
1202 case ID_FIND_CHANNELS:
1203 case ID_POPUP_ADVANCED_ALLCHANNELS:
1204 case ID_POPUP_UPGRADE:
1205 sys->callLocalURL("admin?cmd=upgrade",servMgr->serverHost.port);
1207 case ID_POPUP_ADVANCED_RELAYEDCHANNELS:
1208 case ID_POPUP_FAVORITES_EDIT:
1209 showHTML("relays.html");
1211 case ID_POPUP_ADVANCED_BROADCAST:
1212 showHTML("broadcast.html");
1214 case ID_POPUP_SETTINGS:
1215 showHTML("settings.html");
1217 case ID_POPUP_CONNECTIONS:
1218 showHTML("connections.html");
1221 sys->getURL("http://www.peercast.org/help.php");
1224 case ID_POPUP_SAVE_GUI_POS:
1225 if (servMgr->saveGuiPos){
1226 servMgr->saveGuiPos = false;
1227 CheckMenuItem(trayMenu, ID_POPUP_SAVE_GUI_POS, MF_UNCHECKED|MF_BYCOMMAND);
1229 servMgr->saveGuiPos = true;
1230 CheckMenuItem(trayMenu, ID_POPUP_SAVE_GUI_POS, MF_CHECKED|MF_BYCOMMAND);
1232 peercastInst->saveSettings();
1235 case ID_POPUP_KEEP_DOWNSTREAMS:
1236 if (servMgr->keepDownstreams){
1237 servMgr->keepDownstreams = false;
1238 CheckMenuItem(trayMenu, ID_POPUP_KEEP_DOWNSTREAMS, MF_UNCHECKED|MF_BYCOMMAND);
1240 servMgr->keepDownstreams = true;
1241 CheckMenuItem(trayMenu, ID_POPUP_KEEP_DOWNSTREAMS, MF_CHECKED|MF_BYCOMMAND);
1243 //peercastInst->saveSettings();
1246 case ID_POPUP_EXIT_CONFIRM:
1248 DestroyWindow(hWnd);
1251 return DefWindowProc(hWnd, message, wParam, lParam);
1258 return DefWindowProc(hWnd, message, wParam, lParam);
1262 // Mesage handler for about box.
1263 LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
1268 //SendDlgItemMessage(hDlg,IDC_ABOUTVER,WM_SETTEXT,0,(LONG)PCX_AGENT);
1269 // SendDlgItemMessage(hDlg,IDC_ABOUTVER,WM_SETTEXT,0,(LONG)PCX_AGENTJP);
1271 SendDlgItemMessage(hDlg,IDC_ABOUTVER,WM_SETTEXT,0,(LONG)PCX_AGENTEX);
1273 SendDlgItemMessage(hDlg,IDC_ABOUTVER,WM_SETTEXT,0,(LONG)PCX_AGENTVP);
1278 switch (LOWORD(wParam))
1282 EndDialog(hDlg, LOWORD(wParam));
1285 sys->getURL("http://www.peercast.org");
1286 EndDialog(hDlg, LOWORD(wParam));
1297 // Mesage handler for chaninfo box
1298 LRESULT CALLBACK ChanInfoProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
1305 //strcpy(str,chanInfo.track.artist.cstr());
1306 strcpy(str,chanInfo.track.artist); //JP-Patch
1308 //strcat(str,chanInfo.track.title.cstr());
1309 strcat(str,chanInfo.track.title);
1310 String name,track,comment,desc,genre; //JP-Patch
1311 name = chanInfo.name; //JP-Patch
1312 track = str; //JP-Patch
1313 comment = chanInfo.comment; //JP-Patch
1314 desc = chanInfo.desc; //JP-Patc
1315 genre = chanInfo.genre; //JP-Patch
1316 name.convertTo(String::T_SJIS); //JP-Patc
1317 track.convertTo(String::T_SJIS); //JP-Patch
1318 comment.convertTo(String::T_SJIS); //JP-Patch
1319 desc.convertTo(String::T_SJIS); //JP-Patch
1320 genre.convertTo(String::T_SJIS); //JP-Patch
1322 //SendDlgItemMessage(hDlg,IDC_EDIT_NAME,WM_SETTEXT,0,(LONG)chanInfo.name.cstr());
1323 SendDlgItemMessage(hDlg,IDC_EDIT_NAME,WM_SETTEXT,0,(LONG)name.cstr()); //JP-Patch
1324 //SendDlgItemMessage(hDlg,IDC_EDIT_PLAYING,WM_SETTEXT,0,(LONG)str);
1325 SendDlgItemMessage(hDlg,IDC_EDIT_PLAYING,WM_SETTEXT,0,(LONG)track.cstr()); //JP-Patch
1326 //SendDlgItemMessage(hDlg,IDC_EDIT_MESSAGE,WM_SETTEXT,0,(LONG)chanInfo.comment.cstr());
1327 SendDlgItemMessage(hDlg,IDC_EDIT_MESSAGE,WM_SETTEXT,0,(LONG)comment.cstr()); //JP-Patch
1328 //SendDlgItemMessage(hDlg,IDC_EDIT_DESC,WM_SETTEXT,0,(LONG)chanInfo.desc.cstr());
1329 SendDlgItemMessage(hDlg,IDC_EDIT_DESC,WM_SETTEXT,0,(LONG)desc.cstr()); //JP-Patch
1330 //SendDlgItemMessage(hDlg,IDC_EDIT_GENRE,WM_SETTEXT,0,(LONG)chanInfo.genre.cstr());
1331 SendDlgItemMessage(hDlg,IDC_EDIT_GENRE,WM_SETTEXT,0,(LONG)genre.cstr()); //JP-Patch
1333 sprintf(str,"%d kb/s %s",chanInfo.bitrate,ChanInfo::getTypeStr(chanInfo.contentType));
1334 SendDlgItemMessage(hDlg,IDC_FORMAT,WM_SETTEXT,0,(LONG)str);
1337 if (!chanInfo.url.isValidURL())
1338 EnableWindow(GetDlgItem(hDlg,IDC_CONTACT),false);
1340 Channel *ch = chanMgr->findChannelByID(chanInfo.id);
1343 SendDlgItemMessage(hDlg,IDC_EDIT_STATUS,WM_SETTEXT,0,(LONG)ch->getStatusStr());
1344 SendDlgItemMessage(hDlg, IDC_KEEP,BM_SETCHECK, ch->stayConnected, 0);
1347 SendDlgItemMessage(hDlg,IDC_EDIT_STATUS,WM_SETTEXT,0,(LONG)"OK");
1348 EnableWindow(GetDlgItem(hDlg,IDC_KEEP),false);
1355 HWND hDsk = GetDesktopWindow();
1356 GetWindowRect(hDsk,&drect);
1357 GetWindowRect(hDlg,&rect);
1358 GetCursorPos(&point);
1361 size.x = rect.right-rect.left;
1362 size.y = rect.bottom-rect.top;
1364 if (point.x-drect.left < size.x)
1367 pos.x = point.x-size.x;
1369 if (point.y-drect.top < size.y)
1372 pos.y = point.y-size.y;
1374 SetWindowPos(hDlg,HWND_TOPMOST,pos.x,pos.y,size.x,size.y,0);
1381 char str[1024],idstr[64];
1382 chanInfo.id.toStr(idstr);
1384 switch (LOWORD(wParam))
1388 sys->getURL(chanInfo.url);
1393 sprintf(str,"admin?page=chaninfo&id=%s&relay=%d",idstr,chanInfoIsRelayed);
1394 sys->callLocalURL(str,servMgr->serverHost.port);
1399 Channel *ch = chanMgr->findChannelByID(chanInfo.id);
1401 ch->stayConnected = SendDlgItemMessage(hDlg, IDC_KEEP,BM_GETCHECK, 0, 0) == BST_CHECKED;;
1408 chanMgr->findAndPlayChannel(chanInfo,false);
1417 if (winDistinctionNT)
1420 DestroyWindow(hDlg); //JP-Patch
1424 if (LOWORD(wParam) == WA_INACTIVE)
1425 if (winDistinctionNT)
1428 DestroyWindow(hDlg); //JP-Patch