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 //
\83v
\83\8d\83g
\83^
\83C
\83v
\90é
\8c¾
81 // ---------------------------------
82 Sys * APICALL MyPeercastInst::createSys()
84 return new WSys(mainWnd);
86 // ---------------------------------
87 const char * APICALL MyPeercastApp ::getIniFilename()
89 return iniFileName.cstr();
92 // ---------------------------------
93 const char *APICALL MyPeercastApp ::getClientTypeOS()
98 // ---------------------------------
99 const char * APICALL MyPeercastApp::getPath()
101 return exePath.cstr();
104 // --------------------------------- JP-EX
105 void APICALL MyPeercastApp ::openLogFile()
107 logFile.openWriteReplace("log.txt");
109 // --------------------------------- JP-EX
110 void APICALL MyPeercastApp ::getDirectory()
112 char path_buffer[256],drive[32],dir[128];
113 GetModuleFileName(NULL,path_buffer,255);
114 _splitpath(path_buffer,drive,dir,NULL,NULL);
115 sprintf(servMgr->modulePath,"%s%s",drive,dir);
117 // --------------------------------- JP-EX
118 bool APICALL MyPeercastApp ::clearTemp()
120 if (servMgr->clearPLS)
127 class NOTIFYICONDATA2
130 DWORD cbSize; // DWORD
134 UINT uCallbackMessage; // UINT
135 HICON hIcon; // HICON
136 char szTip[128]; // char[128]
137 DWORD dwState; // DWORD
138 DWORD dwStateMask; // DWORD
139 char szInfo[256]; // char[256]
140 UINT uTimeoutOrVersion; // UINT
141 char szInfoTitle[64]; // char[64]
142 DWORD dwInfoFlags; // DWORD
143 //GUID guidItem; > IE 6
146 NOTIFYICONDATA2 trayIcon;
150 HINSTANCE hInst; // current instance
151 TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
152 TCHAR szWindowClass[MAX_LOADSTRING]; // The title bar text
153 TCHAR szWindowClass2[MAX_LOADSTRING]; // The title bar text
155 // Foward declarations of functions included in this code module:
156 ATOM MyRegisterClass(HINSTANCE hInstance);
157 ATOM MyRegisterClass2(HINSTANCE hInstance);
158 ATOM MyRegisterClass3(HINSTANCE hInstance);
159 BOOL InitInstance(HINSTANCE, int);
160 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
161 LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
162 LRESULT CALLBACK ChanInfoProc(HWND, UINT, WPARAM, LPARAM);
164 void setTrayIcon(int type, const char *,const char *,bool);
165 void flipNotifyPopup(int id, ServMgr::NOTIFY_TYPE nt);
170 // --------------------------------------------------
171 void LOG2(const char *fmt,...)
176 vsprintf(str,fmt,ap);
177 OutputDebugString(str);
183 // ---------------------------------------
184 int APIENTRY WinMain(HINSTANCE hInstance,
185 HINSTANCE hPrevInstance,
191 ::_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
200 version_ex = 0; // PP
\94Å
\8ag
\92£
\8b@
\94\
\82ð
\96³
\8cø
\82É
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");
290 HANDLE mutex = CreateMutex(NULL,TRUE,szWindowClass);
292 if (GetLastError() == ERROR_ALREADY_EXISTS)
294 HWND oldWin = FindWindow(szWindowClass,NULL);
297 SendMessage(oldWin,WM_SHOWGUI,0,0);
300 SendMessage(oldWin,WM_DESTROY,0,0);
307 copy.dwData = WM_PLAYCHANNEL;
308 copy.cbData = strlen(chanURL)+1; // plus null term
309 copy.lpData = chanURL;
310 SendMessage(oldWin,WM_COPYDATA,NULL,(LPARAM)©);
313 SendMessage(oldWin,WM_SHOWGUI,0,0);
323 MyRegisterClass(hInstance);
324 MyRegisterClass2(hInstance);
326 // Perform application initialization:
327 if (!InitInstance (hInstance, nCmdShow))
330 peercastInst = new MyPeercastInst();
331 peercastApp = new MyPeercastApp();
333 peercastInst->init();
335 LOG_DEBUG("Set OS Type: %s",winDistinctionNT?"WinNT":"Win9x");
337 if (peercastApp->clearTemp()) //JP-EX
339 DeleteFile("play.pls");
340 hFind = FindFirstFile("*.asx",&fd);
341 if (hFind != INVALID_HANDLE_VALUE)
345 DeleteFile((char *)&fd.cFileName);
347 while (FindNextFile(hFind,&fd));
356 servMgr->procConnectArgs(chanURL,info);
357 chanMgr->findAndPlayChannel(info,false);
360 hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_SIMPLE);
362 // setup menu notifes
363 int mask = peercastInst->getNotifyMask();
364 if (mask & ServMgr::NT_PEERCAST)
365 CheckMenuItem(trayMenu,ID_POPUP_SHOWMESSAGES_PEERCAST,MF_CHECKED|MF_BYCOMMAND);
366 if (mask & ServMgr::NT_BROADCASTERS)
367 CheckMenuItem(trayMenu,ID_POPUP_SHOWMESSAGES_BROADCASTERS,MF_CHECKED|MF_BYCOMMAND);
368 if (mask & ServMgr::NT_TRACKINFO)
369 CheckMenuItem(trayMenu,ID_POPUP_SHOWMESSAGES_TRACKINFO,MF_CHECKED|MF_BYCOMMAND);
371 if (servMgr->startWithGui)
376 // Main message loop:
377 while (GetMessage(&msg, NULL, 0, 0))
379 if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
381 TranslateMessage(&msg);
382 DispatchMessage(&msg);
386 Shell_NotifyIcon(NIM_DELETE, (NOTIFYICONDATA*)&trayIcon);
388 peercastInst->saveSettings();
389 peercastInst->quit();
391 Gdiplus::GdiplusShutdown(gdiplusToken);
399 // FUNCTION: MyRegisterClass()
401 // PURPOSE: Registers the window class.
405 // This function and its usage is only necessary if you want this code
406 // to be compatible with Win32 systems prior to the 'RegisterClassEx'
407 // function that was added to Windows 95. It is important to call this function
408 // so that the application will get 'well formed' small icons associated
411 ATOM MyRegisterClass(HINSTANCE hInstance)
415 wcex.cbSize = sizeof(WNDCLASSEX);
417 wcex.style = CS_HREDRAW | CS_VREDRAW;
418 wcex.lpfnWndProc = (WNDPROC)WndProc;
421 wcex.hInstance = hInstance;
422 wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_SIMPLE);
423 wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
424 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
425 // wcex.lpszMenuName = (LPCSTR)IDC_SIMPLE;
426 wcex.lpszMenuName = NULL;
427 wcex.lpszClassName = szWindowClass;
428 wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
430 return RegisterClassEx(&wcex);
433 ATOM MyRegisterClass2(HINSTANCE hInstance)
437 wcex.cbSize = sizeof(WNDCLASSEX);
439 wcex.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS ;
440 wcex.lpfnWndProc = (WNDPROC)GUIProc;
443 wcex.hInstance = hInstance;
444 wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_SIMPLE);
445 wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
446 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
447 // wcex.lpszMenuName = (LPCSTR)IDC_SIMPLE;
448 wcex.lpszMenuName = NULL;
449 wcex.lpszClassName = szWindowClass2;
450 wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
452 return RegisterClassEx(&wcex);
455 //-----------------------------
456 void loadIcons(HINSTANCE hInstance, HWND hWnd)
458 icon1 = LoadIcon(hInstance, (LPCTSTR)IDI_SMALL);
459 icon2 = LoadIcon(hInstance, (LPCTSTR)IDI_SMALL2);
461 trayIcon.cbSize = sizeof(trayIcon);
462 trayIcon.hWnd = hWnd;
464 trayIcon.uFlags = NIF_MESSAGE + NIF_ICON + NIF_TIP;
465 trayIcon.uCallbackMessage = WM_TRAYICON;
466 trayIcon.hIcon = icon1;
467 strcpy(trayIcon.szTip, "PeerCast");
469 Shell_NotifyIcon(NIM_ADD, (NOTIFYICONDATA*)&trayIcon);
471 //ShowWindow(hWnd, nCmdShow);
474 if(!trayMenu) // for PCRaw (tray icon)
475 trayMenu = LoadMenu(hInstance,MAKEINTRESOURCE(IDR_TRAYMENU));
476 if(!ltrayMenu) // for PCRaw (tray icon)
477 ltrayMenu = LoadMenu(hInstance,MAKEINTRESOURCE(IDR_LTRAYMENU));
482 //-----------------------------
484 // FUNCTION: InitInstance(HANDLE, int)
486 // PURPOSE: Saves instance handle and creates main window
490 // In this function, we save the instance handle in a global variable and
491 // create and display the main program window.
493 BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
497 hInst = hInstance; // Store instance handle in our global variable
499 hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
500 CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
509 g_iTaskbarCreated = RegisterWindowMessage("TaskbarCreated"); // for PCRaw (tray icon)
511 loadIcons(hInstance,hWnd);
513 using namespace Gdiplus;
514 GdiplusStartupInput gdiplusStartupInput;
515 GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
519 //-----------------------------
520 //static String trackTitle;
521 //static String channelComment;
523 //-----------------------------
524 void channelPopup(const char *title, const char *msg, bool isPopup = true)
528 if (*title == '\0') return;
534 trayIcon.uFlags = NIF_ICON|NIF_TIP;
535 strncpy(trayIcon.szTip, both.cstr(),sizeof(trayIcon.szTip)-1);
536 trayIcon.szTip[sizeof(trayIcon.szTip)-1]=0;
538 if (isPopup) trayIcon.uFlags |= 16;
539 trayIcon.uTimeoutOrVersion = 10000;
540 strncpy(trayIcon.szInfo,msg,sizeof(trayIcon.szInfo)-1);
541 strncpy(trayIcon.szInfoTitle,title,sizeof(trayIcon.szInfoTitle)-1);
543 Shell_NotifyIcon(NIM_MODIFY, (NOTIFYICONDATA*)&trayIcon);
545 //-----------------------------
546 void clearChannelPopup()
548 trayIcon.uFlags = NIF_ICON|16;
549 trayIcon.uTimeoutOrVersion = 10000;
550 strncpy(trayIcon.szInfo,"",sizeof(trayIcon.szInfo)-1);
551 strncpy(trayIcon.szInfoTitle,"",sizeof(trayIcon.szInfoTitle)-1);
552 Shell_NotifyIcon(NIM_MODIFY, (NOTIFYICONDATA*)&trayIcon);
555 //-----------------------------
564 static PopupEntry *PEList = NULL;
567 static void putPopupEntry(PopupEntry *pe)
575 static PopupEntry *getPopupEntry(GnuID id)
578 PopupEntry *pe = PEList;
579 PopupEntry *prev = NULL;
581 if (id.isSame(pe->id)) {
582 if (prev) prev->next = pe->next;
583 else PEList = pe->next;
595 static PopupEntry *getTopPopupEntry()
597 PopupEntry *p = NULL;
601 PEList = PEList->next;
607 //-----------------------------
608 void APICALL MyPeercastApp::channelStart(ChanInfo *info)
611 // lastPlayID = info->id;
613 // if(!isIndexTxt(info)) // for PCRaw (popup)
614 // clearChannelPopup();
616 PopupEntry *pe = getPopupEntry(info->id);
621 if (!isIndexTxt(info))
626 //-----------------------------
627 void APICALL MyPeercastApp::channelStop(ChanInfo *info)
629 // if (info->id.isSame(lastPlayID))
631 // lastPlayID.clear();
633 // if(!isIndexTxt(info)) // for PCRaw (popup)
634 // clearChannelPopup();
637 PopupEntry *pe = getPopupEntry(info->id);
640 pe = getTopPopupEntry();
644 if (ServMgr::NT_TRACKINFO & peercastInst->getNotifyMask())
646 String name,track; //JP-Patch
647 name = pe->name; //JP-Patch
648 track = pe->track; //JP-Patch
649 name.convertTo(String::T_SJIS); //JP-Patch
650 track.convertTo(String::T_SJIS); //JP-Patch
652 // channelPopup(info->name.cstr(),trackTitle.cstr());
653 channelPopup(name.cstr(),track.cstr(), false); //JP-Patch
658 //-----------------------------
659 void APICALL MyPeercastApp::channelUpdate(ChanInfo *info)
663 PopupEntry *pe = getPopupEntry(info->id);
667 tmp.append(info->track.artist);
669 tmp.append(info->track.title);
672 if (!tmp.isSame(pe->track))
674 pe->name = info->name;
676 if (ServMgr::NT_TRACKINFO & peercastInst->getNotifyMask())
679 String name,track; //JP-Patch
680 name = info->name; //JP-Patch
681 track = tmp; //JP-Patch
682 name.convertTo(String::T_SJIS); //JP-Patch
683 track.convertTo(String::T_SJIS); //JP-Patch
684 if(!isIndexTxt(info)) // for PCRaw (popup)
687 // channelPopup(info->name.cstr(),trackTitle.cstr());
688 channelPopup(name.cstr(),track.cstr()); //JP-Patch
691 } else if (!info->comment.isSame(pe->comment))
693 pe->name = info->name;
694 pe->comment = info->comment;
695 if (ServMgr::NT_BROADCASTERS & peercastInst->getNotifyMask())
697 //channelComment = info->comment;
698 String name,comment; //JP-Patch
699 name = info->name; //JP-Patch
700 comment = info->comment; //JP-Patch
701 name.convertTo(String::T_SJIS); //JP-Patch
702 comment.convertTo(String::T_SJIS); //JP-Patch
703 if(!isIndexTxt(info)) // for PCRaw (popup)
706 // channelPopup(info->name.cstr(),channelComment.cstr());
707 channelPopup(name.cstr(),comment.cstr());
712 if (!isIndexTxt(info))
718 //-----------------------------
719 void APICALL MyPeercastApp::notifyMessage(ServMgr::NOTIFY_TYPE type, const char *msg)
721 static bool shownUpgradeAlert=false;
727 if (!shownUpgradeAlert)
729 trayIcon.uFlags = NIF_ICON;
731 if (type == ServMgr::NT_UPGRADE)
733 shownUpgradeAlert = true;
734 trayIcon.hIcon = icon2;
737 trayIcon.hIcon = icon1;
741 if (type == ServMgr::NT_UPGRADE)
745 const char *title="";
749 case ServMgr::NT_UPGRADE:
750 title = "Upgrade alert";
752 case ServMgr::NT_PEERCAST:
753 title = "Message from PeerCast:";
758 if (type & peercastInst->getNotifyMask())
760 trayIcon.uFlags |= 16;
761 trayIcon.uTimeoutOrVersion = 10000;
762 strncpy(trayIcon.szInfo,msg,sizeof(trayIcon.szInfo)-1);
763 strncpy(trayIcon.szInfoTitle,title,sizeof(trayIcon.szInfoTitle)-1);
764 Shell_NotifyIcon(NIM_MODIFY, (NOTIFYICONDATA*)&trayIcon);
767 //-----------------------------
771 void createGUI(HWND hWnd)
774 guiWnd = ::CreateWindow(szWindowClass2,
776 WS_OVERLAPPEDWINDOW & ~(WS_MAXIMIZEBOX) /*| WS_VSCROLL | WS_HSCROLL*/,
786 ShowWindow(guiWnd,SW_SHOWNORMAL);
788 //
\8e©
\93®
\82Å
\8dÅ
\91O
\96Ê
789 if (servMgr->topmostGui)
791 ::SetWindowPos(guiWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
797 // addRelayedChannelsMenu(HMENU m)
800 void addRelayedChannelsMenu(HMENU cm)
802 int cnt = GetMenuItemCount(cm);
803 for(int i=0; i<cnt-3; i++)
804 DeleteMenu(cm,0,MF_BYPOSITION);
806 Channel *c = chanMgr->channel;
811 char str[128],name[64];
812 strncpy(name,c->info.name,32);
814 if (strlen(c->info.name) > 32)
818 sprintf(str,"%s (%d kb/s %s)",name,c->info.bitrate,ChanInfo::getTypeStr(c->info.contentType));
819 //InsertMenu(cm,0,MF_BYPOSITION,RELAY_CMD+i,str);
825 typedef int (*COMPARE_FUNC)(const void *,const void *);
827 static int compareHitLists(ChanHitList **c2, ChanHitList **c1)
829 return stricmp(c1[0]->info.name.cstr(),c2[0]->info.name.cstr());
832 static int compareChannels(Channel **c2, Channel **c1)
834 return stricmp(c1[0]->info.name.cstr(),c2[0]->info.name.cstr());
838 // addAllChannelsMenu(HMENU m)
841 void addAllChannelsMenu(HMENU cm)
843 int cnt = GetMenuItemCount(cm);
844 /* for(int i=0; i<cnt-2; i++)
845 DeleteMenu(cm,0,MF_BYPOSITION);*/
847 for(int i=0; i<cnt; i++)
848 DeleteMenu(cm,0,MF_BYPOSITION);
850 HMENU yMenu = CreatePopupMenu();
851 if (!servMgr->rootHost2.isEmpty()){
852 InsertMenu(yMenu,0,MF_BYPOSITION,ID_POPUP_YELLOWPAGES2,servMgr->rootHost2);
854 if (!servMgr->rootHost.isEmpty()){
855 InsertMenu(yMenu,0,MF_BYPOSITION,ID_POPUP_YELLOWPAGES1,servMgr->rootHost);
858 InsertMenu(cm,0,MF_BYPOSITION|MF_POPUP,(UINT)yMenu,"
\83C
\83G
\83\8d\81[
\83y
\81[
\83W");
859 InsertMenu(cm,0,MF_BYPOSITION|MF_SEPARATOR,NULL,NULL);
860 // add channels to menu
862 Channel *ch = chanMgr->channel;
865 char str[128],name[64];
866 String sjis; //JP-Patch
867 sjis = ch->info.name; //JP-Patch
868 sjis.convertTo(String::T_SJIS); //JP-Patch
869 strncpy(name,sjis.cstr(),32);
870 //strncpy(name,ch->info.name,32);
872 //if (strlen(ch->info.name) > 32)
873 if (strlen(sjis.cstr()) > 32) //JP-Patch
876 sprintf(str,"%s (%d kb/s %s)",name,ch->info.bitrate,ChanInfo::getTypeStr(ch->info.contentType));
878 HMENU opMenu = CreatePopupMenu();
879 InsertMenu(opMenu,0,MF_BYPOSITION,INFO_CMD+numActive,"Info");
880 if (ch->info.url.isValidURL())
881 InsertMenu(opMenu,0,MF_BYPOSITION,URL_CMD+numActive,"URL");
882 InsertMenu(opMenu,0,MF_BYPOSITION,PLAY_CMD+numActive,"Play");
884 UINT fl = MF_BYPOSITION|MF_POPUP;
886 fl |= (ch->isPlaying()?MF_CHECKED:0);
888 InsertMenu(cm,0,fl,(UINT)opMenu,str);
897 // InsertMenu(cm,0,MF_BYPOSITION,0,"<No channels>");
906 // flipNotifyPopup(id, flag)
907 void flipNotifyPopup(int id, ServMgr::NOTIFY_TYPE nt)
909 int mask = peercastInst->getNotifyMask();
913 CheckMenuItem(trayMenu,id,MF_CHECKED|MF_BYCOMMAND);
915 CheckMenuItem(trayMenu,id,MF_UNCHECKED|MF_BYCOMMAND);
917 peercastInst->setNotifyMask(mask);
918 peercastInst->saveSettings();
922 static void showHTML(const char *file)
925 sprintf(url,"%s/%s",servMgr->htmlPath,file);
927 // sys->callLocalURL(url,servMgr->serverHost.port);
928 sys->callLocalURL(url, // for PCRaw (url)
929 (servMgr->allowServer1&Servent::ALLOW_HTML)?(servMgr->serverHost.port):(servMgr->serverHost.port+1));
932 static ChanInfo getChannelInfo(int index)
934 Channel *c = chanMgr->findChannelByIndex(index);
943 // FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
945 // PURPOSE: Processes messages for the main window.
947 // WM_COMMAND - process the application menu
948 // WM_PAINT - Paint the main window
949 // WM_DESTROY - post a quit message and return
952 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
958 if(message == g_iTaskbarCreated) // for PCRaw (tray icon)
959 loadIcons(hInst, hWnd);
973 SendMessage(hWnd,WM_SHOWMENU,2,0);
974 SetForegroundWindow(hWnd);
978 SendMessage(hWnd,WM_SHOWMENU,1,0);
979 SetForegroundWindow(hWnd);
981 case WM_LBUTTONDBLCLK:
989 COPYDATASTRUCT *pc = (COPYDATASTRUCT *)lParam;
990 LOG_DEBUG("URL request: %s",pc->lpData);
991 if (pc->dwData == WM_PLAYCHANNEL)
994 servMgr->procConnectArgs((char *)pc->lpData,info);
995 chanMgr->findAndPlayChannel(info,false);
997 //sys->callLocalURL((const char *)pc->lpData,servMgr->serverHost.port);
1000 case WM_GETPORTNUMBER:
1003 port=servMgr->serverHost.port;
1010 if (servMgr->saveGuiPos){
1011 CheckMenuItem(trayMenu, ID_POPUP_SAVE_GUI_POS, MF_CHECKED|MF_BYCOMMAND);
1013 CheckMenuItem(trayMenu, ID_POPUP_SAVE_GUI_POS, MF_UNCHECKED|MF_BYCOMMAND);
1016 //
\8e©
\93®GUI/
\8dÅ
\91O
\96Ê
\8b@
\94\
1017 if (servMgr->topmostGui)
1019 CheckMenuItem(trayMenu, ID_POPUP_TOPMOST, MF_CHECKED|MF_BYCOMMAND);
1022 CheckMenuItem(trayMenu, ID_POPUP_TOPMOST, MF_UNCHECKED|MF_BYCOMMAND);
1025 if (servMgr->startWithGui)
1027 CheckMenuItem(trayMenu, ID_POPUP_START_WITH_GUI, MF_CHECKED|MF_BYCOMMAND);
1030 CheckMenuItem(trayMenu, ID_POPUP_START_WITH_GUI, MF_UNCHECKED|MF_BYCOMMAND);
1033 SetForegroundWindow(hWnd);
1034 bool skipMenu=false;
1036 allowTrayMenu = false;
1038 // check for notifications
1039 if (currNotify & ServMgr::NT_UPGRADE)
1041 if (servMgr->downloadURL[0])
1043 if ((sys->getTime()-seenNewVersionTime) > (60*60)) // notify every hour
1045 if (MessageBox(hWnd,"A newer version of PeerCast is available, press OK to upgrade.","PeerCast",MB_OKCANCEL|MB_APPLMODAL|MB_ICONEXCLAMATION) == IDOK)
1046 sys->getURL(servMgr->downloadURL);
1048 seenNewVersionTime=sys->getTime();
1061 SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWnd, 0);
1062 GetCursorPos(&point);
1064 if (point.x < rcWnd.left){
1065 point.x = rcWnd.left;
1066 flg |= TPM_LEFTALIGN;
1068 if (point.x > rcWnd.right){
1069 point.x = rcWnd.right;
1070 flg |= TPM_RIGHTALIGN;
1072 if (point.y < rcWnd.top){
1073 point.y = rcWnd.top;
1074 flg |= TPM_TOPALIGN;
1076 if (point.y > rcWnd.bottom){
1077 point.y = rcWnd.bottom;
1078 flg |= TPM_BOTTOMALIGN;
1081 flg = TPM_RIGHTALIGN;
1087 menu = GetSubMenu(trayMenu,0);
1088 addAllChannelsMenu(GetSubMenu(menu,0));
1089 addRelayedChannelsMenu(GetSubMenu(menu,1));
1092 menu = GetSubMenu(ltrayMenu,0);
1093 addAllChannelsMenu(menu);
1096 if (!TrackPopupMenu(menu,flg,point.x,point.y,0,hWnd,NULL))
1098 LOG_ERROR("Can`t track popup menu: %d",GetLastError());
1100 PostMessage(hWnd,WM_NULL,0,0);
1103 allowTrayMenu = true;
1113 wmId = LOWORD(wParam);
1114 wmEvent = HIWORD(wParam);
1116 if ((wmId >= INFO_CMD) && (wmId < INFO_CMD+MAX_CHANNELS))
1118 int c = wmId - INFO_CMD;
1119 chanInfo = getChannelInfo(c);
1120 chanInfoIsRelayed = false;
1121 if (winDistinctionNT)
1122 DialogBox(hInst, (LPCTSTR)IDD_CHANINFO, hWnd, (DLGPROC)ChanInfoProc);
1125 HWND WKDLG; //JP-Patch
1126 WKDLG = CreateDialog(hInst, (LPCTSTR)IDD_CHANINFO, hWnd, (DLGPROC)ChanInfoProc); //JP-Patch
1127 ShowWindow(WKDLG,SW_SHOWNORMAL); //JP-Patch
1131 if ((wmId >= URL_CMD) && (wmId < URL_CMD+MAX_CHANNELS))
1133 int c = wmId - URL_CMD;
1134 chanInfo = getChannelInfo(c);
1135 if (chanInfo.url.isValidURL())
1136 sys->getURL(chanInfo.url);
1139 if ((wmId >= PLAY_CMD) && (wmId < PLAY_CMD+MAX_CHANNELS))
1141 int c = wmId - PLAY_CMD;
1142 chanInfo = getChannelInfo(c);
1143 chanMgr->findAndPlayChannel(chanInfo,false);
1146 if ((wmId >= RELAY_CMD) && (wmId < RELAY_CMD+MAX_CHANNELS))
1148 int c = wmId - RELAY_CMD;
1149 chanInfo = getChannelInfo(c);
1150 chanMgr->findAndPlayChannel(chanInfo,true);
1154 // Parse the menu selections:
1157 case ID_POPUP_SHOWMESSAGES_PEERCAST:
1158 flipNotifyPopup(ID_POPUP_SHOWMESSAGES_PEERCAST,ServMgr::NT_PEERCAST);
1160 case ID_POPUP_SHOWMESSAGES_BROADCASTERS:
1161 flipNotifyPopup(ID_POPUP_SHOWMESSAGES_BROADCASTERS,ServMgr::NT_BROADCASTERS);
1163 case ID_POPUP_SHOWMESSAGES_TRACKINFO:
1164 flipNotifyPopup(ID_POPUP_SHOWMESSAGES_TRACKINFO,ServMgr::NT_TRACKINFO);
1167 case ID_POPUP_ABOUT:
1169 DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
1171 case ID_POPUP_SHOWGUI:
1172 case IDM_SETTINGS_GUI:
1173 case ID_POPUP_ADVANCED_SHOWGUI:
1178 case ID_POPUP_YELLOWPAGES:
1179 sys->getURL("http://yp.peercast.org/");
1181 case ID_POPUP_YELLOWPAGES1:
1182 sprintf(buf, "http://%s",servMgr->rootHost.cstr());
1185 case ID_POPUP_YELLOWPAGES2:
1186 sprintf(buf, "http://%s",servMgr->rootHost2.cstr());
1190 case ID_POPUP_ADVANCED_VIEWLOG:
1191 showHTML("viewlog.html");
1193 case ID_POPUP_ADVANCED_SAVESETTINGS:
1194 servMgr->saveSettings(iniFileName.cstr());
1196 case ID_POPUP_ADVANCED_INFORMATION:
1197 showHTML("index.html");
1199 case ID_FIND_CHANNELS:
1200 case ID_POPUP_ADVANCED_ALLCHANNELS:
1201 case ID_POPUP_UPGRADE:
1202 sys->callLocalURL("admin?cmd=upgrade",servMgr->serverHost.port);
1204 case ID_POPUP_ADVANCED_RELAYEDCHANNELS:
1205 case ID_POPUP_FAVORITES_EDIT:
1206 showHTML("relays.html");
1208 case ID_POPUP_ADVANCED_BROADCAST:
1209 showHTML("broadcast.html");
1211 case ID_POPUP_SETTINGS:
1212 showHTML("settings.html");
1214 case ID_POPUP_CONNECTIONS:
1215 showHTML("connections.html");
1218 sys->getURL("http://www.peercast.org/help.php");
1221 case ID_POPUP_SAVE_GUI_POS:
1222 if (servMgr->saveGuiPos){
1223 servMgr->saveGuiPos = false;
1224 CheckMenuItem(trayMenu, ID_POPUP_SAVE_GUI_POS, MF_UNCHECKED|MF_BYCOMMAND);
1226 servMgr->saveGuiPos = true;
1227 CheckMenuItem(trayMenu, ID_POPUP_SAVE_GUI_POS, MF_CHECKED|MF_BYCOMMAND);
1229 peercastInst->saveSettings();
1232 case ID_POPUP_KEEP_DOWNSTREAMS:
1233 if (servMgr->keepDownstreams){
1234 servMgr->keepDownstreams = false;
1235 CheckMenuItem(trayMenu, ID_POPUP_KEEP_DOWNSTREAMS, MF_UNCHECKED|MF_BYCOMMAND);
1237 servMgr->keepDownstreams = true;
1238 CheckMenuItem(trayMenu, ID_POPUP_KEEP_DOWNSTREAMS, MF_CHECKED|MF_BYCOMMAND);
1240 //peercastInst->saveSettings();
1243 case ID_POPUP_TOPMOST:
1244 //
\8dÅ
\91O
\96Ê
\95\
\8e¦
1245 if (servMgr->topmostGui)
1247 servMgr->topmostGui = false;
1248 CheckMenuItem(trayMenu, ID_POPUP_TOPMOST, MF_UNCHECKED|MF_BYCOMMAND);
1251 servMgr->topmostGui = true;
1252 CheckMenuItem(trayMenu, ID_POPUP_TOPMOST, MF_CHECKED|MF_BYCOMMAND);
1254 peercastInst->saveSettings();
1257 case ID_POPUP_START_WITH_GUI:
1258 //
\8bN
\93®
\8e\9e\82ÉGUI
\95\
\8e¦
1259 if (servMgr->startWithGui)
1261 servMgr->startWithGui = false;
1262 CheckMenuItem(trayMenu, ID_POPUP_START_WITH_GUI, MF_UNCHECKED|MF_BYCOMMAND);
1265 servMgr->startWithGui = true;
1266 CheckMenuItem(trayMenu, ID_POPUP_START_WITH_GUI, MF_CHECKED|MF_BYCOMMAND);
1268 peercastInst->saveSettings();
1271 case ID_POPUP_EXIT_CONFIRM:
1273 DestroyWindow(hWnd);
1276 return DefWindowProc(hWnd, message, wParam, lParam);
1283 return DefWindowProc(hWnd, message, wParam, lParam);
1287 // Mesage handler for about box.
1288 LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
1293 //SendDlgItemMessage(hDlg,IDC_ABOUTVER,WM_SETTEXT,0,(LONG)PCX_AGENT);
1294 // SendDlgItemMessage(hDlg,IDC_ABOUTVER,WM_SETTEXT,0,(LONG)PCX_AGENTJP);
1297 SendDlgItemMessage(hDlg,IDC_ABOUTVER,WM_SETTEXT,0,(LONG)PCX_AGENTEX);
1300 SendDlgItemMessage(hDlg,IDC_ABOUTVER,WM_SETTEXT,0,(LONG)PCX_AGENTVP);
1306 switch (LOWORD(wParam))
1310 EndDialog(hDlg, LOWORD(wParam));
1313 sys->getURL("http://www.peercast.org");
1314 EndDialog(hDlg, LOWORD(wParam));
1325 // Mesage handler for chaninfo box
1326 LRESULT CALLBACK ChanInfoProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
1333 //strcpy(str,chanInfo.track.artist.cstr());
1334 strcpy(str,chanInfo.track.artist); //JP-Patch
1336 //strcat(str,chanInfo.track.title.cstr());
1337 strcat(str,chanInfo.track.title);
1338 String name,track,comment,desc,genre; //JP-Patch
1339 name = chanInfo.name; //JP-Patch
1340 track = str; //JP-Patch
1341 comment = chanInfo.comment; //JP-Patch
1342 desc = chanInfo.desc; //JP-Patc
1343 genre = chanInfo.genre; //JP-Patch
1344 name.convertTo(String::T_SJIS); //JP-Patc
1345 track.convertTo(String::T_SJIS); //JP-Patch
1346 comment.convertTo(String::T_SJIS); //JP-Patch
1347 desc.convertTo(String::T_SJIS); //JP-Patch
1348 genre.convertTo(String::T_SJIS); //JP-Patch
1350 //SendDlgItemMessage(hDlg,IDC_EDIT_NAME,WM_SETTEXT,0,(LONG)chanInfo.name.cstr());
1351 SendDlgItemMessage(hDlg,IDC_EDIT_NAME,WM_SETTEXT,0,(LONG)name.cstr()); //JP-Patch
1352 //SendDlgItemMessage(hDlg,IDC_EDIT_PLAYING,WM_SETTEXT,0,(LONG)str);
1353 SendDlgItemMessage(hDlg,IDC_EDIT_PLAYING,WM_SETTEXT,0,(LONG)track.cstr()); //JP-Patch
1354 //SendDlgItemMessage(hDlg,IDC_EDIT_MESSAGE,WM_SETTEXT,0,(LONG)chanInfo.comment.cstr());
1355 SendDlgItemMessage(hDlg,IDC_EDIT_MESSAGE,WM_SETTEXT,0,(LONG)comment.cstr()); //JP-Patch
1356 //SendDlgItemMessage(hDlg,IDC_EDIT_DESC,WM_SETTEXT,0,(LONG)chanInfo.desc.cstr());
1357 SendDlgItemMessage(hDlg,IDC_EDIT_DESC,WM_SETTEXT,0,(LONG)desc.cstr()); //JP-Patch
1358 //SendDlgItemMessage(hDlg,IDC_EDIT_GENRE,WM_SETTEXT,0,(LONG)chanInfo.genre.cstr());
1359 SendDlgItemMessage(hDlg,IDC_EDIT_GENRE,WM_SETTEXT,0,(LONG)genre.cstr()); //JP-Patch
1361 sprintf(str,"%d kb/s %s",chanInfo.bitrate,ChanInfo::getTypeStr(chanInfo.contentType));
1362 SendDlgItemMessage(hDlg,IDC_FORMAT,WM_SETTEXT,0,(LONG)str);
1365 if (!chanInfo.url.isValidURL())
1366 EnableWindow(GetDlgItem(hDlg,IDC_CONTACT),false);
1368 Channel *ch = chanMgr->findChannelByID(chanInfo.id);
1371 SendDlgItemMessage(hDlg,IDC_EDIT_STATUS,WM_SETTEXT,0,(LONG)ch->getStatusStr());
1372 SendDlgItemMessage(hDlg, IDC_KEEP,BM_SETCHECK, ch->stayConnected, 0);
1374 //
\8c»
\8dÝ
\82Ì
\8cÅ
\97L
\83\8a\83\8c\81[
\8fã
\8cÀ
\90Ý
\92è
\82ð
\95\
\8e¦(0
\82Í
\96³
\8cø)
1375 ::SetDlgItemInt(hDlg, IDC_EDIT_MAXRELAYS, ch->maxRelays, false);
1378 // index.txt
\82È
\82Ì
\82Å
\96³
\8cø
\82É
1379 ::EnableWindow(::GetDlgItem(hDlg, IDC_EDIT_MAXRELAYS), false);
1380 ::EnableWindow(::GetDlgItem(hDlg, IDC_APPLY_MAXRELAYS), false);
1384 SendDlgItemMessage(hDlg,IDC_EDIT_STATUS,WM_SETTEXT,0,(LONG)"OK");
1385 EnableWindow(GetDlgItem(hDlg,IDC_KEEP),false);
1392 HWND hDsk = GetDesktopWindow();
1393 GetWindowRect(hDsk,&drect);
1394 GetWindowRect(hDlg,&rect);
1395 GetCursorPos(&point);
1398 size.x = rect.right-rect.left;
1399 size.y = rect.bottom-rect.top;
1401 if (point.x-drect.left < size.x)
1404 pos.x = point.x-size.x;
1406 if (point.y-drect.top < size.y)
1409 pos.y = point.y-size.y;
1411 SetWindowPos(hDlg,HWND_TOPMOST,pos.x,pos.y,size.x,size.y,0);
1418 char str[1024],idstr[64];
1419 chanInfo.id.toStr(idstr);
1421 switch (LOWORD(wParam))
1425 sys->getURL(chanInfo.url);
1430 sprintf(str,"admin?page=chaninfo&id=%s&relay=%d",idstr,chanInfoIsRelayed);
1431 sys->callLocalURL(str,servMgr->serverHost.port);
1436 Channel *ch = chanMgr->findChannelByID(chanInfo.id);
1438 ch->stayConnected = SendDlgItemMessage(hDlg, IDC_KEEP,BM_GETCHECK, 0, 0) == BST_CHECKED;;
1445 chanMgr->findAndPlayChannel(chanInfo,false);
1449 case IDC_APPLY_MAXRELAYS:
1451 //
\83`
\83\83\83\93\83l
\83\8b\8cÅ
\97L
\82Ì
\8dÅ
\91å
\83\8a\83\8c\81[
\90\94\82ð
\90Ý
\92è
1455 //
\93ü
\97Í
\92l
\8eæ
\93¾
1456 mr = ::GetDlgItemInt(hDlg, IDC_EDIT_MAXRELAYS, &bSucc, false);
1460 Channel *ch = chanMgr->findChannelByID(chanInfo.id);
1461 if (ch && !isIndexTxt(ch))
1467 MessageBox(hDlg, "
\93ü
\97Í
\92l
\82ª
\95s
\90³
\82Å
\82·
\81B", "Error", MB_OK|MB_ICONERROR|MB_APPLMODAL);
1468 Channel *ch = chanMgr->findChannelByID(chanInfo.id);
1470 ::SetDlgItemInt(hDlg, IDC_EDIT_MAXRELAYS, ch->maxRelays, false);
1478 if (winDistinctionNT)
1481 DestroyWindow(hDlg); //JP-Patch
1485 if (LOWORD(wParam) == WA_INACTIVE)
1486 if (winDistinctionNT)
1489 DestroyWindow(hDlg); //JP-Patch