OSDN Git Service

300534caaadabd8dff4c30ce535c4e5c537b9f7d
[peercast-im/PeerCastIM.git] / PeerCast.root / PeerCast / ui / win32 / simple / Simple.cpp
1 // ------------------------------------------------
2 // File : simple.cpp
3 // Date: 4-apr-2002
4 // Author: giles
5 // Desc: 
6 //              Simple tray icon interface to PeerCast, mostly win32 related stuff.
7 //              
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.
14
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 // ------------------------------------------------
20
21 #include <windows.h>
22 #include <direct.h> 
23 #include "stdafx.h"
24 #include "resource.h"
25 #include "gui.h"
26 #include "channel.h"
27 #include "servent.h"
28 #include "servmgr.h"
29 #include "win32/wsys.h"
30 #include "peercast.h"
31 #include "simple.h"
32 #include "version2.h"
33 #include "gdiplus.h"
34 #include "time.h"
35 #include "stats.h"
36 #include "sys.h"
37 #ifdef _DEBUG
38 #include "chkMemoryLeak.h"
39 #define DEBUG_NEW new(__FILE__, __LINE__)
40 #define new DEBUG_NEW
41 #endif
42
43 #define MAX_LOADSTRING 100
44
45 #define PLAY_CMD 7000
46 #define RELAY_CMD 8000
47 #define INFO_CMD 9000
48 #define URL_CMD 10000
49
50 #define MAX_CHANNELS 999
51
52
53 extern "C"
54 {
55         void loadIcons(HINSTANCE hInstance, HWND hWnd);
56 };
57
58 UINT g_iTaskbarCreated = ~0;    // for PCRaw (tray icon)
59
60 // PeerCast globals
61
62 static int currNotify=0;
63 String iniFileName;
64 HWND guiWnd;
65 HWND mainWnd;
66 static HMENU trayMenu = NULL,ltrayMenu = NULL;  // for PCRaw (tray icon)
67 bool showGUI=true;
68 bool allowMulti=false;
69 bool killMe=false;
70 bool allowTrayMenu=true;
71 static bool winDistinctionNT=false;
72 int             seenNewVersionTime=0;
73 HICON icon1,icon2;
74 ChanInfo chanInfo;
75 bool chanInfoIsRelayed;
76 //GnuID lastPlayID;
77 String exePath;
78 ULONG_PTR gdiplusToken;
79
80 extern Stats stats;
81 ThreadInfo trafficDlgThread;
82 HWND trafficDlg = NULL;
83 FileStream fs;
84
85 // \83v\83\8d\83g\83^\83C\83v\90é\8c¾
86 void createGUI(HWND);
87 LRESULT CALLBACK TrafficDlgProc(HWND, UINT, WPARAM, LPARAM);
88
89 // ---------------------------------
90 Sys * APICALL MyPeercastInst::createSys()
91 {
92         return new WSys(mainWnd);
93 }
94 // ---------------------------------
95 const char * APICALL MyPeercastApp ::getIniFilename()
96 {
97         return iniFileName.cstr();
98 }
99
100 // ---------------------------------
101 const char *APICALL MyPeercastApp ::getClientTypeOS() 
102 {
103         return PCX_OS_WIN32;
104 }
105
106 // ---------------------------------
107 const char * APICALL MyPeercastApp::getPath()
108 {
109         return exePath.cstr();
110 }
111
112 // --------------------------------- JP-EX
113 void    APICALL MyPeercastApp ::openLogFile()
114 {
115         logFile.openWriteReplace("log.txt");
116 }
117 // --------------------------------- JP-EX
118 void    APICALL MyPeercastApp ::getDirectory()
119 {
120         char path_buffer[256],drive[32],dir[128];
121         GetModuleFileName(NULL,path_buffer,255);
122         _splitpath(path_buffer,drive,dir,NULL,NULL);
123         sprintf(servMgr->modulePath,"%s%s",drive,dir);
124 }
125 // --------------------------------- JP-EX
126 bool    APICALL MyPeercastApp ::clearTemp()
127 {
128         if (servMgr->clearPLS)
129                 return true;
130
131         return false;
132 }
133
134
135 class NOTIFYICONDATA2
136 {
137 public:
138         DWORD cbSize; // DWORD
139         HWND hWnd; // HWND
140         UINT uID; // UINT
141         UINT uFlags; // UINT
142         UINT uCallbackMessage; // UINT
143         HICON hIcon; // HICON
144         char szTip[128]; // char[128]
145         DWORD dwState; // DWORD
146         DWORD dwStateMask; // DWORD
147         char szInfo[256]; // char[256]
148         UINT uTimeoutOrVersion; // UINT
149         char szInfoTitle[64]; // char[64]
150         DWORD dwInfoFlags; // DWORD
151         //GUID guidItem; > IE 6
152 };
153
154 NOTIFYICONDATA2 trayIcon;
155
156
157 // Global Variables:
158 HINSTANCE hInst;                                                                // current instance
159 TCHAR szTitle[MAX_LOADSTRING];                                                          // The title bar text
160 TCHAR szWindowClass[MAX_LOADSTRING];                                                            // The title bar text
161 TCHAR szWindowClass2[MAX_LOADSTRING];                                                           // The title bar text
162
163 // Foward declarations of functions included in this code module:
164 ATOM                            MyRegisterClass(HINSTANCE hInstance);
165 ATOM                            MyRegisterClass2(HINSTANCE hInstance);
166 ATOM                            MyRegisterClass3(HINSTANCE hInstance);
167 BOOL                            InitInstance(HINSTANCE, int);
168 LRESULT CALLBACK        WndProc(HWND, UINT, WPARAM, LPARAM);
169 LRESULT CALLBACK        About(HWND, UINT, WPARAM, LPARAM);
170 LRESULT CALLBACK        ChanInfoProc(HWND, UINT, WPARAM, LPARAM);
171
172 void setTrayIcon(int type, const char *,const char *,bool);
173 void flipNotifyPopup(int id, ServMgr::NOTIFY_TYPE nt);
174
175
176 HWND chWnd=NULL;
177
178 // --------------------------------------------------
179 void LOG2(const char *fmt,...)
180 {
181         va_list ap;
182         va_start(ap, fmt);
183         char str[4096];
184         vsprintf(str,fmt,ap);
185         OutputDebugString(str);
186         va_end(ap);     
187 }
188
189
190 // --------------------------------------------------
191 int WinMainDummy(HINSTANCE hInstance,
192                                  HINSTANCE hPrevInstance,
193                                  LPSTR lpCmdLine,
194                                  int nCmdShow)
195 {
196 #ifdef _DEBUG
197         // memory leak check
198         ::_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
199 #endif
200
201         char tmpURL[8192];
202         tmpURL[0]=0;
203         char *chanURL=NULL;
204
205         hInst = hInstance;
206
207         version_ex = 1; // PP\94Å\8ag\92£\8b@\94\\82ð\96³\8cø\82É\81©\91å\89R\81B\83o\81[\83W\83\87\83\93\95\\8bL\82ðEX\82É
208
209         iniFileName.set(".\\peercast.ini");
210
211         WIN32_FIND_DATA fd; //JP-EX
212         HANDLE hFind; //JP-EX
213
214         OSVERSIONINFO osInfo; //JP-EX
215         osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); //JP-EX
216         GetVersionEx(&osInfo);
217         if (osInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
218                 winDistinctionNT = true;
219         else
220                 winDistinctionNT = false;
221
222         // off by default now
223         showGUI = false;
224
225         if (strlen(lpCmdLine) > 0)
226         {
227                 char *p;
228                 if ((p = strstr(lpCmdLine,"-inifile"))!=NULL) 
229                         iniFileName.setFromString(p+8);
230
231                 if (strstr(lpCmdLine,"-zen")) 
232                         showGUI = false;
233
234                 if (strstr(lpCmdLine,"-multi")) 
235                         allowMulti = true;
236
237                 if (strstr(lpCmdLine,"-kill")) 
238                         killMe = true;
239
240                 if ((p = strstr(lpCmdLine,"-url"))!=NULL)
241                 {
242                         p+=4;
243                         while (*p)
244                         {
245                                 if (*p=='"')
246                                 {
247                                         p++;
248                                         break;
249                                 }                               
250                                 if (*p != ' ')
251                                         break;
252                                 p++;
253                         }
254                         if (*p)
255                                 strncpy(tmpURL,p,sizeof(tmpURL)-1);
256                 }
257         }
258
259         // get current path
260         {
261                 exePath = iniFileName;
262                 char *s = exePath.cstr();
263                 char *end = NULL;
264                 while (*s)
265                 {
266                         if (*s++ == '\\')
267                                 end = s;
268                 }
269                 if (end)
270                         *end = 0;
271         }
272
273
274         if (strnicmp(tmpURL,"peercast://",11)==0)
275         {
276                 if (strnicmp(tmpURL+11,"pls/",4)==0)
277                         chanURL = tmpURL+11+4;
278                 else
279                         chanURL = tmpURL+11;
280                 showGUI = false;
281         }
282
283
284         MSG msg;
285         HACCEL hAccelTable;
286
287         // Initialize global strings
288         //LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
289         //LoadString(hInstance, IDC_APP_TITLE, szWindowClass, MAX_LOADSTRING);
290
291         strcpy(szTitle,"PeerCast");
292         strcpy(szWindowClass,"PeerCast");
293         strcpy(szWindowClass2,"Main");
294
295         if (!allowMulti)
296         {
297                 HANDLE mutex = CreateMutex(NULL,TRUE,szWindowClass);
298
299                 if (GetLastError() == ERROR_ALREADY_EXISTS)
300                 {
301                         HWND oldWin = FindWindow(szWindowClass,NULL);
302                         if (oldWin)
303                         {
304                                 //SendMessage(oldWin,WM_SHOWGUI,0,0);
305                                 if (killMe)
306                                 {
307                                         SendMessage(oldWin,WM_DESTROY,0,0);
308                                         return 0;
309                                 }
310
311                                 if (chanURL)
312                                 {
313                                         COPYDATASTRUCT copy;
314                                         copy.dwData = WM_PLAYCHANNEL;
315                                         copy.cbData = strlen(chanURL)+1;                        // plus null term
316                                         copy.lpData = chanURL;
317                                         SendMessage(oldWin,WM_COPYDATA,NULL,(LPARAM)&copy);
318                                 }else{
319                                         if (showGUI)
320                                                 SendMessage(oldWin,WM_SHOWGUI,0,0);
321                                 }
322                         }
323                         return 0;
324                 }
325         }
326
327         if (killMe)
328                 return 0;
329
330         MyRegisterClass(hInstance);
331         MyRegisterClass2(hInstance);
332
333         // Perform application initialization:
334         if (!InitInstance (hInstance, nCmdShow)) 
335                 return FALSE;
336
337         peercastInst = new MyPeercastInst();
338         peercastApp = new MyPeercastApp();
339
340         peercastInst->init();
341
342         LOG_DEBUG("Set OS Type: %s",winDistinctionNT?"WinNT":"Win9x");
343
344         if (peercastApp->clearTemp()) //JP-EX
345         {
346                 DeleteFile("play.pls");
347                 hFind = FindFirstFile("*.asx",&fd);
348                 if (hFind != INVALID_HANDLE_VALUE)
349                 {
350                         do
351                         {
352                                 DeleteFile((char *)&fd.cFileName);
353                         }
354                         while (FindNextFile(hFind,&fd));
355
356                         FindClose(hFind);
357                 }
358         }
359
360         if (chanURL)
361         {
362                 ChanInfo info;
363                 servMgr->procConnectArgs(chanURL,info);
364                 chanMgr->findAndPlayChannel(info,false);
365         }
366
367         hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_SIMPLE);
368
369         // setup menu notifes
370         int mask = peercastInst->getNotifyMask();
371         if (mask & ServMgr::NT_PEERCAST)
372                 CheckMenuItem(trayMenu,ID_POPUP_SHOWMESSAGES_PEERCAST,MF_CHECKED|MF_BYCOMMAND);
373         if (mask & ServMgr::NT_BROADCASTERS)
374                 CheckMenuItem(trayMenu,ID_POPUP_SHOWMESSAGES_BROADCASTERS,MF_CHECKED|MF_BYCOMMAND);
375         if (mask & ServMgr::NT_TRACKINFO)
376                 CheckMenuItem(trayMenu,ID_POPUP_SHOWMESSAGES_TRACKINFO,MF_CHECKED|MF_BYCOMMAND);
377
378         if (servMgr->startWithGui)
379         {
380                 createGUI((HWND)0);
381         }
382
383         // Main message loop:
384         while (GetMessage(&msg, NULL, 0, 0)) 
385         {
386                 if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
387                 {
388                         TranslateMessage(&msg);
389                         DispatchMessage(&msg);
390                 }
391         }
392
393         Shell_NotifyIcon(NIM_DELETE, (NOTIFYICONDATA*)&trayIcon);
394
395         peercastInst->saveSettings();
396         peercastInst->quit();
397
398         Gdiplus::GdiplusShutdown(gdiplusToken);
399
400         return msg.wParam;
401 }
402
403
404 // ---------------------------------------
405 int APIENTRY WinMain(HINSTANCE hInstance,
406                                          HINSTANCE hPrevInstance,
407                                          LPSTR     lpCmdLine,
408                                          int       nCmdShow)
409 {
410         // SEH handling
411         _EXCEPTION_POINTERS *lpExcept;
412         __try
413         {
414                 WinMainDummy(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
415
416         } __except(lpExcept = GetExceptionInformation(), EXCEPTION_EXECUTE_HANDLER)
417         {
418                 DWORD nParams;
419
420                 fs.openWriteReplace(".\\dump.txt");
421                 fs.writeLine("Exception Point: WinMain");
422                 fs.write("Exception: ", 11);
423                 switch (lpExcept->ExceptionRecord->ExceptionCode)
424                 {
425                 case EXCEPTION_ACCESS_VIOLATION:
426                         fs.writeLine("Access violation");
427                         break;
428
429                 case EXCEPTION_FLT_DIVIDE_BY_ZERO:
430                 case EXCEPTION_INT_DIVIDE_BY_ZERO:
431                         fs.writeLine("Divide by zero");
432                         break;
433
434                 case EXCEPTION_STACK_OVERFLOW:
435                         fs.writeLine("Stack overflow");
436                         break;
437
438                 default:
439                         fs.writeLong(lpExcept->ExceptionRecord->ExceptionCode);
440                         fs.writeLine("");
441                 }
442
443                 fs.writeLineF("Address: %p", lpExcept->ExceptionRecord->ExceptionAddress);
444
445                 fs.writeLine("Additional information:");
446                 nParams = lpExcept->ExceptionRecord->NumberParameters;
447                 for (unsigned i=0; i<nParams; ++i)
448                 {
449                         fs.writeLineF("%d: %lu", i, lpExcept->ExceptionRecord->ExceptionInformation[i]);
450                 }
451                 fs.close();
452
453
454                 fs.openWriteReplace(".\\dump.html");
455                 sys->logBuf->dumpHTML(fs);
456                 fs.close();
457
458                 MessageBox(NULL, "\88ê\94Ê\95Û\8cì\88á\94½\82Ì\88×\81A\83v\83\8d\83O\83\89\83\80\82Í\8b­\90§\8fI\97¹\82³\82ê\82Ü\82·\81B\n"
459                         "\96â\91è\89ð\8c\88\82Ì\82½\82ß\82É\83_\83\93\83v\83f\81[\83^(dump.html, dump.txt)\82ð\92ñ\8b\9f\82µ\82Ä\82­\82¾\82³\82¢\81B", "SEH",
460                         MB_OK|MB_ICONWARNING);
461
462                 return GetExceptionCode();
463         }
464
465         // dummy
466         return 0;
467 }
468
469
470
471 //
472 //  FUNCTION: MyRegisterClass()
473 //
474 //  PURPOSE: Registers the window class.
475 //
476 //  COMMENTS:
477 //
478 //    This function and its usage is only necessary if you want this code
479 //    to be compatible with Win32 systems prior to the 'RegisterClassEx'
480 //    function that was added to Windows 95. It is important to call this function
481 //    so that the application will get 'well formed' small icons associated
482 //    with it.
483 //
484 ATOM MyRegisterClass(HINSTANCE hInstance)
485 {
486         WNDCLASSEX wcex;
487
488         wcex.cbSize = sizeof(WNDCLASSEX); 
489
490         wcex.style                      = CS_HREDRAW | CS_VREDRAW;
491         wcex.lpfnWndProc        = (WNDPROC)WndProc;
492         wcex.cbClsExtra         = 0;
493         wcex.cbWndExtra         = 0;
494         wcex.hInstance          = hInstance;
495         wcex.hIcon                      = LoadIcon(hInstance, (LPCTSTR)IDI_SIMPLE);
496         wcex.hCursor            = LoadCursor(NULL, IDC_ARROW);
497         wcex.hbrBackground      = (HBRUSH)(COLOR_WINDOW+1);
498 //      wcex.lpszMenuName       = (LPCSTR)IDC_SIMPLE;
499         wcex.lpszMenuName       = NULL;
500         wcex.lpszClassName      = szWindowClass;
501         wcex.hIconSm            = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
502
503         return RegisterClassEx(&wcex);
504 }
505
506 ATOM MyRegisterClass2(HINSTANCE hInstance)
507 {
508         WNDCLASSEX wcex;
509         
510         wcex.cbSize = sizeof(WNDCLASSEX); 
511
512         wcex.style                      = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS ;
513         wcex.lpfnWndProc        = (WNDPROC)GUIProc;
514         wcex.cbClsExtra         = 0;
515         wcex.cbWndExtra         = 0;
516         wcex.hInstance          = hInstance;
517         wcex.hIcon                      = LoadIcon(hInstance, (LPCTSTR)IDI_SIMPLE);
518         wcex.hCursor            = LoadCursor(NULL, IDC_ARROW);
519         wcex.hbrBackground      = (HBRUSH)(COLOR_WINDOW+1);
520 //      wcex.lpszMenuName       = (LPCSTR)IDC_SIMPLE;
521         wcex.lpszMenuName       = NULL;
522         wcex.lpszClassName      = szWindowClass2;
523         wcex.hIconSm            = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
524
525         return RegisterClassEx(&wcex);
526 }
527
528 //-----------------------------
529 void loadIcons(HINSTANCE hInstance, HWND hWnd)
530 {
531         icon1 = LoadIcon(hInstance, (LPCTSTR)IDI_SMALL);
532         icon2 = LoadIcon(hInstance, (LPCTSTR)IDI_SMALL2);
533
534     trayIcon.cbSize = sizeof(trayIcon);
535     trayIcon.hWnd = hWnd;
536     trayIcon.uID = 100;
537     trayIcon.uFlags = NIF_MESSAGE + NIF_ICON + NIF_TIP;
538     trayIcon.uCallbackMessage = WM_TRAYICON;
539     trayIcon.hIcon = icon1;
540     strcpy(trayIcon.szTip, "PeerCast");
541
542     Shell_NotifyIcon(NIM_ADD, (NOTIFYICONDATA*)&trayIcon);
543
544     //ShowWindow(hWnd, nCmdShow);
545     UpdateWindow(hWnd);
546
547         if(!trayMenu)   // for PCRaw (tray icon)
548                 trayMenu = LoadMenu(hInstance,MAKEINTRESOURCE(IDR_TRAYMENU));
549         if(!ltrayMenu)  // for PCRaw (tray icon)
550                 ltrayMenu = LoadMenu(hInstance,MAKEINTRESOURCE(IDR_LTRAYMENU));
551
552
553 }
554
555 //-----------------------------
556 //
557 //   FUNCTION: InitInstance(HANDLE, int)
558 //
559 //   PURPOSE: Saves instance handle and creates main window
560 //
561 //   COMMENTS:
562 //
563 //        In this function, we save the instance handle in a global variable and
564 //        create and display the main program window.
565 //
566 BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
567 {
568         HWND hWnd;
569
570         hInst = hInstance; // Store instance handle in our global variable
571
572         hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
573           CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
574
575         if (!hWnd)
576         {
577           return FALSE;
578         }
579
580         mainWnd = hWnd;
581
582         g_iTaskbarCreated = RegisterWindowMessage("TaskbarCreated");    // for PCRaw (tray icon)
583
584         loadIcons(hInstance,hWnd);
585
586         using namespace Gdiplus;
587         GdiplusStartupInput gdiplusStartupInput;
588         GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
589
590         return TRUE;
591 }
592 //-----------------------------
593 //static String trackTitle;
594 //static String channelComment;
595
596 //-----------------------------
597 void channelPopup(const char *title, const char *msg, bool isPopup = true)
598 {
599         String both;
600
601         if (*title == '\0') return;
602         both.append(msg);
603         both.append(" (");
604         both.append(title);
605         both.append(")");
606
607         trayIcon.uFlags = NIF_ICON|NIF_TIP;
608         strncpy(trayIcon.szTip, both.cstr(),sizeof(trayIcon.szTip)-1);
609         trayIcon.szTip[sizeof(trayIcon.szTip)-1]=0;
610
611         if (isPopup) trayIcon.uFlags |= 16;
612         trayIcon.uTimeoutOrVersion = 10000;
613         strncpy(trayIcon.szInfo,msg,sizeof(trayIcon.szInfo)-1);
614         strncpy(trayIcon.szInfoTitle,title,sizeof(trayIcon.szInfoTitle)-1);
615                 
616         Shell_NotifyIcon(NIM_MODIFY, (NOTIFYICONDATA*)&trayIcon);
617 }
618 //-----------------------------
619 void clearChannelPopup()
620 {
621         trayIcon.uFlags = NIF_ICON|16;
622         trayIcon.uTimeoutOrVersion = 10000;
623     strncpy(trayIcon.szInfo,"",sizeof(trayIcon.szInfo)-1);
624         strncpy(trayIcon.szInfoTitle,"",sizeof(trayIcon.szInfoTitle)-1);
625         Shell_NotifyIcon(NIM_MODIFY, (NOTIFYICONDATA*)&trayIcon);
626 }
627
628 //-----------------------------
629 // PopupEntry
630 struct PopupEntry {
631         GnuID id;
632         String name;
633         String track;
634         String comment;
635         PopupEntry *next;
636 };
637 static PopupEntry *PEList = NULL;
638 static WLock PELock;
639
640 static void putPopupEntry(PopupEntry *pe)
641 {
642         PELock.on();
643         pe->next = PEList;
644         PEList = pe;
645         PELock.off();
646 }
647
648 static PopupEntry *getPopupEntry(GnuID id)
649 {
650         PELock.on();
651         PopupEntry *pe = PEList;
652         PopupEntry *prev = NULL;
653         while (pe) {
654                 if (id.isSame(pe->id)) {
655                         if (prev) prev->next = pe->next;
656                         else PEList = pe->next;
657                         PELock.off();
658                         pe->next = NULL;
659                         return pe;
660                 }
661                 prev = pe;
662                 pe = pe->next;
663         }
664         PELock.off();
665         return NULL;
666 }
667
668 static PopupEntry *getTopPopupEntry()
669 {
670         PopupEntry *p = NULL;
671         PELock.on();
672         if (PEList) {
673                 p = PEList;
674                 PEList = PEList->next;
675         }
676         PELock.off();
677         return p;
678 }
679
680 //-----------------------------
681 void    APICALL MyPeercastApp::channelStart(ChanInfo *info)
682 {
683
684 //      lastPlayID = info->id;
685 //
686 //      if(!isIndexTxt(info))   // for PCRaw (popup)
687 //              clearChannelPopup();
688
689         PopupEntry *pe = getPopupEntry(info->id);
690         if (!pe) {
691                 pe = new PopupEntry;
692                 pe->id = info->id;
693         }
694         if (!isIndexTxt(info))
695                 putPopupEntry(pe);
696         else
697                 delete pe;
698 }
699 //-----------------------------
700 void    APICALL MyPeercastApp::channelStop(ChanInfo *info)
701 {
702 //      if (info->id.isSame(lastPlayID))
703 //      {
704 //              lastPlayID.clear();
705 //
706 //              if(!isIndexTxt(info))   // for PCRaw (popup)
707 //                      clearChannelPopup();
708 //      }
709
710         PopupEntry *pe = getPopupEntry(info->id);
711         if (pe) delete pe;
712
713         pe = getTopPopupEntry();
714         if (!pe) {
715                 clearChannelPopup();
716         } else {
717                 if (ServMgr::NT_TRACKINFO & peercastInst->getNotifyMask())
718                 {
719                         String name,track; //JP-Patch
720                         name = pe->name; //JP-Patch
721                         track = pe->track; //JP-Patch
722                         name.convertTo(String::T_SJIS); //JP-Patch
723                         track.convertTo(String::T_SJIS); //JP-Patch
724                         clearChannelPopup();
725                 //      channelPopup(info->name.cstr(),trackTitle.cstr());
726                         channelPopup(name.cstr(),track.cstr(), false); //JP-Patch
727                 }
728                 putPopupEntry(pe);
729         }
730 }
731 //-----------------------------
732 void    APICALL MyPeercastApp::channelUpdate(ChanInfo *info)
733 {
734         if (info)
735         {
736                 PopupEntry *pe = getPopupEntry(info->id);
737                 if (!pe) return;
738
739                 String tmp;
740                 tmp.append(info->track.artist);
741                 tmp.append(" ");
742                 tmp.append(info->track.title);
743
744
745                 if (!tmp.isSame(pe->track))
746                 {
747                         pe->name = info->name;
748                         pe->track = tmp;
749                         if (ServMgr::NT_TRACKINFO & peercastInst->getNotifyMask())
750                         {
751                                 //trackTitle=tmp;
752                                 String name,track; //JP-Patch
753                                 name = info->name; //JP-Patch
754                                 track = tmp; //JP-Patch
755                                 name.convertTo(String::T_SJIS); //JP-Patch
756                                 track.convertTo(String::T_SJIS); //JP-Patch
757                                 if(!isIndexTxt(info))   // for PCRaw (popup)
758                                 {
759                                         clearChannelPopup();
760                                 //      channelPopup(info->name.cstr(),trackTitle.cstr());
761                                         channelPopup(name.cstr(),track.cstr()); //JP-Patch
762                                 }
763                         }
764                 } else if (!info->comment.isSame(pe->comment))
765                 {
766                         pe->name = info->name;
767                         pe->comment = info->comment;
768                         if (ServMgr::NT_BROADCASTERS & peercastInst->getNotifyMask())
769                         {
770                                 //channelComment = info->comment;
771                                 String name,comment; //JP-Patch
772                                 name = info->name; //JP-Patch
773                                 comment = info->comment; //JP-Patch
774                                 name.convertTo(String::T_SJIS); //JP-Patch
775                                 comment.convertTo(String::T_SJIS); //JP-Patch
776                                 if(!isIndexTxt(info))   // for PCRaw (popup)
777                                 {
778                                         clearChannelPopup();
779                                 //      channelPopup(info->name.cstr(),channelComment.cstr());
780                                         channelPopup(name.cstr(),comment.cstr());
781                                 }
782                         }
783                 }
784
785                 if (!isIndexTxt(info))
786                         putPopupEntry(pe);
787                 else
788                         delete pe;
789         }
790 }
791 //-----------------------------
792 void    APICALL MyPeercastApp::notifyMessage(ServMgr::NOTIFY_TYPE type, const char *msg)
793 {
794         static bool shownUpgradeAlert=false;
795
796         currNotify = type;
797
798         trayIcon.uFlags = 0;
799
800         if (!shownUpgradeAlert)
801         {
802             trayIcon.uFlags = NIF_ICON;
803
804                 if (type == ServMgr::NT_UPGRADE)
805                 {
806                         shownUpgradeAlert = true;
807                     trayIcon.hIcon = icon2;
808                 }else
809                 {
810                         trayIcon.hIcon = icon1; 
811                 }
812         }else
813         {
814                 if (type == ServMgr::NT_UPGRADE)
815                         return;
816         }
817
818         const char *title="";
819
820         switch(type)
821         {
822                 case ServMgr::NT_UPGRADE:
823                         title = "Upgrade alert";
824                         break;
825                 case ServMgr::NT_PEERCAST:
826                         title = "Message from PeerCast:";
827                         break;
828
829         }
830
831         if (type & peercastInst->getNotifyMask())
832         {
833                 trayIcon.uFlags |= 16;
834         trayIcon.uTimeoutOrVersion = 10000;
835         strncpy(trayIcon.szInfo,msg,sizeof(trayIcon.szInfo)-1);
836                 strncpy(trayIcon.szInfoTitle,title,sizeof(trayIcon.szInfoTitle)-1);
837             Shell_NotifyIcon(NIM_MODIFY, (NOTIFYICONDATA*)&trayIcon);
838         }
839 }
840 //-----------------------------
841
842 // createGUI()
843 //
844 void createGUI(HWND hWnd)
845 {
846         if (!guiWnd){
847                 guiWnd = ::CreateWindow(szWindowClass2,
848                         "Peercast-IM@S",
849                         WS_OVERLAPPEDWINDOW & ~(WS_MAXIMIZEBOX) /*| WS_VSCROLL | WS_HSCROLL*/,
850                         0,
851                         0,
852                         800,
853                         600,
854                         NULL,
855                         NULL,
856                         hInst,
857                         NULL);
858         }
859         ShowWindow(guiWnd,SW_SHOWNORMAL);
860
861         // \8e©\93®\82Å\8dÅ\91O\96Ê
862         if (servMgr->topmostGui)
863         {
864                 ::SetWindowPos(guiWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
865         }
866 }
867
868
869 // 
870 // addRelayedChannelsMenu(HMENU m)
871 // 
872 //
873 void addRelayedChannelsMenu(HMENU cm)
874 {
875         int cnt = GetMenuItemCount(cm);
876         for(int i=0; i<cnt-3; i++)
877                 DeleteMenu(cm,0,MF_BYPOSITION);
878
879         Channel *c = chanMgr->channel;
880         while(c)
881         {
882                 if (c->isActive())
883                 {
884                         char str[128],name[64];
885                         strncpy(name,c->info.name,32);
886                         name[32]=0;
887                         if (strlen(c->info.name) > 32)
888                                 strcat(name,"...");
889
890
891                         sprintf(str,"%s  (%d kb/s %s)",name,c->info.bitrate,ChanInfo::getTypeStr(c->info.contentType));
892                         //InsertMenu(cm,0,MF_BYPOSITION,RELAY_CMD+i,str);
893                 }
894                 c=c->next;
895         }
896 }
897
898 typedef int (*COMPARE_FUNC)(const void *,const void *);
899
900 static int compareHitLists(ChanHitList **c2, ChanHitList **c1)
901 {
902         return stricmp(c1[0]->info.name.cstr(),c2[0]->info.name.cstr());
903 }
904
905 static int compareChannels(Channel **c2, Channel **c1)
906 {
907         return stricmp(c1[0]->info.name.cstr(),c2[0]->info.name.cstr());
908 }
909
910 // 
911 // addAllChannelsMenu(HMENU m)
912 // 
913 //
914 void addAllChannelsMenu(HMENU cm)
915 {
916         int cnt = GetMenuItemCount(cm);
917 /*      for(int i=0; i<cnt-2; i++)
918                 DeleteMenu(cm,0,MF_BYPOSITION);*/
919
920         for(int i=0; i<cnt; i++)
921                 DeleteMenu(cm,0,MF_BYPOSITION);
922
923         HMENU yMenu = CreatePopupMenu();
924         if (!servMgr->rootHost2.isEmpty()){
925                 InsertMenu(yMenu,0,MF_BYPOSITION,ID_POPUP_YELLOWPAGES2,servMgr->rootHost2);
926         }
927         if (!servMgr->rootHost.isEmpty()){
928                 InsertMenu(yMenu,0,MF_BYPOSITION,ID_POPUP_YELLOWPAGES1,servMgr->rootHost);
929         }
930
931         InsertMenu(cm,0,MF_BYPOSITION|MF_POPUP,(UINT)yMenu,"\83C\83G\83\8d\81[\83y\81[\83W");
932         InsertMenu(cm,0,MF_BYPOSITION|MF_SEPARATOR,NULL,NULL);
933         // add channels to menu
934         int numActive=0;
935         Channel *ch = chanMgr->channel;
936         while(ch)
937         {
938                 char str[128],name[64];
939                 String sjis; //JP-Patch
940                 sjis = ch->info.name; //JP-Patch
941                 sjis.convertTo(String::T_SJIS); //JP-Patch
942                 strncpy(name,sjis.cstr(),32);
943                 //strncpy(name,ch->info.name,32);
944                 name[32]=0;
945                 //if (strlen(ch->info.name) > 32)
946                 if (strlen(sjis.cstr()) > 32) //JP-Patch
947                         strcat(name,"...");
948
949                 sprintf(str,"%s  (%d kb/s %s)",name,ch->info.bitrate,ChanInfo::getTypeStr(ch->info.contentType));
950
951                 HMENU opMenu = CreatePopupMenu();
952                 InsertMenu(opMenu,0,MF_BYPOSITION,INFO_CMD+numActive,"Info");
953                 if (ch->info.url.isValidURL())
954                         InsertMenu(opMenu,0,MF_BYPOSITION,URL_CMD+numActive,"URL");
955                 InsertMenu(opMenu,0,MF_BYPOSITION,PLAY_CMD+numActive,"Play");
956
957                 UINT fl = MF_BYPOSITION|MF_POPUP;
958                 if (ch)
959                         fl |= (ch->isPlaying()?MF_CHECKED:0);
960
961                 InsertMenu(cm,0,fl,(UINT)opMenu,str);
962                 
963                 numActive++;
964
965                 ch=ch->next;
966         }
967
968
969         //if (!numActive)
970         //              InsertMenu(cm,0,MF_BYPOSITION,0,"<No channels>");
971
972
973
974
975 }
976
977
978 // 
979 // flipNotifyPopup(id, flag)
980 void flipNotifyPopup(int id, ServMgr::NOTIFY_TYPE nt)
981 {
982         int mask = peercastInst->getNotifyMask();
983
984         mask ^= nt;
985         if (mask & nt)
986                 CheckMenuItem(trayMenu,id,MF_CHECKED|MF_BYCOMMAND);
987         else
988                 CheckMenuItem(trayMenu,id,MF_UNCHECKED|MF_BYCOMMAND);
989
990         peercastInst->setNotifyMask(mask);
991         peercastInst->saveSettings();
992 }
993  
994
995 static void showHTML(const char *file)
996 {
997         char url[256];
998         sprintf(url,"%s/%s",servMgr->htmlPath,file);                                    
999
1000 //      sys->callLocalURL(url,servMgr->serverHost.port);
1001         sys->callLocalURL(url,  // for PCRaw (url)
1002                 (servMgr->allowServer1&Servent::ALLOW_HTML)?(servMgr->serverHost.port):(servMgr->serverHost.port+1));
1003 }
1004
1005 static ChanInfo getChannelInfo(int index)
1006 {
1007         Channel *c = chanMgr->findChannelByIndex(index);
1008         if (c)
1009                 return c->info;
1010
1011         ChanInfo info;
1012         return info;
1013 }
1014
1015 //
1016 //  FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
1017 //
1018 //  PURPOSE:  Processes messages for the main window.
1019 //
1020 //  WM_COMMAND  - process the application menu
1021 //  WM_PAINT    - Paint the main window
1022 //  WM_DESTROY  - post a quit message and return
1023 //
1024 //
1025 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
1026 {
1027         int wmId, wmEvent;
1028         POINT point;
1029         char buf[1024];
1030
1031         if(message == g_iTaskbarCreated)        // for PCRaw (tray icon)
1032                 loadIcons(hInst, hWnd);
1033  
1034         switch (message) 
1035         {
1036                 case WM_SHOWGUI:
1037                         createGUI(hWnd);
1038                         break;
1039
1040
1041                 case WM_TRAYICON:
1042                         switch((UINT)lParam) 
1043                         {
1044                                 case WM_LBUTTONDOWN:
1045                                         if (allowTrayMenu)
1046                                                 SendMessage(hWnd,WM_SHOWMENU,2,0);
1047                                         SetForegroundWindow(hWnd);    
1048                                         break;
1049                                 case WM_RBUTTONDOWN:
1050                                         if (allowTrayMenu)
1051                                                 SendMessage(hWnd,WM_SHOWMENU,1,0);
1052                                         SetForegroundWindow(hWnd);    
1053                                         break;
1054                                 case WM_LBUTTONDBLCLK:
1055                                         createGUI(hWnd);
1056                                         break;
1057                         }
1058                         break;
1059
1060                 case WM_COPYDATA:
1061                         {
1062                                 COPYDATASTRUCT *pc = (COPYDATASTRUCT *)lParam;
1063                                 LOG_DEBUG("URL request: %s",pc->lpData);
1064                                 if (pc->dwData == WM_PLAYCHANNEL)
1065                                 {
1066                                         ChanInfo info;
1067                                         servMgr->procConnectArgs((char *)pc->lpData,info);
1068                                         chanMgr->findAndPlayChannel(info,false);
1069                                 }
1070                                 //sys->callLocalURL((const char *)pc->lpData,servMgr->serverHost.port);
1071                         }
1072                         break;
1073                 case WM_GETPORTNUMBER:
1074                         {
1075                                 int port;
1076                                 port=servMgr->serverHost.port;
1077                                 ReplyMessage(port);
1078                         }
1079                         break;
1080
1081                 case WM_SHOWMENU:
1082                         {
1083                                 if (servMgr->saveGuiPos){
1084                                         CheckMenuItem(trayMenu, ID_POPUP_SAVE_GUI_POS, MF_CHECKED|MF_BYCOMMAND);
1085                                 } else {
1086                                         CheckMenuItem(trayMenu, ID_POPUP_SAVE_GUI_POS, MF_UNCHECKED|MF_BYCOMMAND);
1087                                 }
1088
1089                                 // \8e©\93®GUI/\8dÅ\91O\96Ê\8b@\94\
1090                                 if (servMgr->topmostGui)
1091                                 {
1092                                         CheckMenuItem(trayMenu, ID_POPUP_TOPMOST, MF_CHECKED|MF_BYCOMMAND);
1093                                 } else
1094                                 {
1095                                         CheckMenuItem(trayMenu, ID_POPUP_TOPMOST, MF_UNCHECKED|MF_BYCOMMAND);
1096                                 }
1097
1098                                 if (servMgr->startWithGui)
1099                                 {
1100                                         CheckMenuItem(trayMenu, ID_POPUP_START_WITH_GUI, MF_CHECKED|MF_BYCOMMAND);
1101                                 } else
1102                                 {
1103                                         CheckMenuItem(trayMenu, ID_POPUP_START_WITH_GUI, MF_UNCHECKED|MF_BYCOMMAND);
1104                                 }
1105
1106                                 // \83X\83N\83\8a\81[\83\93\83Z\81[\83o\81[\97}\8e~
1107                                 if (servMgr->preventSS)
1108                                 {
1109                                         CheckMenuItem(trayMenu, ID_POPUP_PREVENT_SS, MF_CHECKED|MF_BYCOMMAND);
1110                                 } else
1111                                 {
1112                                         CheckMenuItem(trayMenu, ID_POPUP_PREVENT_SS, MF_UNCHECKED|MF_BYCOMMAND);
1113                                 }
1114
1115                                 SetForegroundWindow(hWnd);    
1116                                 bool skipMenu=false;
1117
1118                                 allowTrayMenu = false;
1119
1120                                 // check for notifications
1121                                 if (currNotify & ServMgr::NT_UPGRADE)
1122                                 {
1123                                         if (servMgr->downloadURL[0])
1124                                         {
1125                                                 if ((sys->getTime()-seenNewVersionTime) > (60*60))      // notify every hour
1126                                                 {
1127                                                         if (MessageBox(hWnd,"A newer version of PeerCast is available, press OK to upgrade.","PeerCast",MB_OKCANCEL|MB_APPLMODAL|MB_ICONEXCLAMATION) == IDOK)
1128                                                                 sys->getURL(servMgr->downloadURL);
1129
1130                                                         seenNewVersionTime=sys->getTime();
1131                                                         skipMenu=true;
1132                                                 }
1133                                         }
1134                                 }
1135
1136
1137                                 if (!skipMenu)
1138                                 {
1139                                         RECT rcWnd;
1140                                         HMENU menu;
1141                                         UINT flg = 0;
1142
1143                                         SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWnd, 0);
1144                                         GetCursorPos(&point);
1145
1146                                         if (point.x < rcWnd.left){
1147                                                 point.x = rcWnd.left;
1148                                                 flg |= TPM_LEFTALIGN;
1149                                         }
1150                                         if (point.x > rcWnd.right){
1151                                                 point.x = rcWnd.right;
1152                                                 flg |= TPM_RIGHTALIGN;
1153                                         }
1154                                         if (point.y < rcWnd.top){
1155                                                 point.y = rcWnd.top;
1156                                                 flg |= TPM_TOPALIGN;
1157                                         }
1158                                         if (point.y > rcWnd.bottom){
1159                                                 point.y = rcWnd.bottom;
1160                                                 flg |= TPM_BOTTOMALIGN;
1161                                         }
1162                                         if (flg == 0){
1163                                                 flg = TPM_RIGHTALIGN;
1164                                         }
1165
1166                                         switch (wParam)
1167                                         {
1168                                                 case 1:
1169                                                         menu = GetSubMenu(trayMenu,0);
1170                                                         addAllChannelsMenu(GetSubMenu(menu,0));
1171                                                         addRelayedChannelsMenu(GetSubMenu(menu,1));
1172                                                         break;
1173                                                 case 2:
1174                                                         menu = GetSubMenu(ltrayMenu,0);
1175                                                         addAllChannelsMenu(menu);
1176                                                         break;
1177                                         }
1178                                         if (!TrackPopupMenu(menu,flg,point.x,point.y,0,hWnd,NULL))
1179                                         {
1180                                                 LOG_ERROR("Can`t track popup menu: %d",GetLastError());
1181                                         }
1182                                         PostMessage(hWnd,WM_NULL,0,0); 
1183
1184                                 }
1185                                 allowTrayMenu = true;
1186                         }
1187                         break;
1188
1189                 case WM_CREATE:
1190                         if (showGUI)
1191                                 createGUI(hWnd);
1192                         break;
1193
1194                 case WM_COMMAND:
1195                         wmId    = LOWORD(wParam); 
1196                         wmEvent = HIWORD(wParam); 
1197
1198                         if ((wmId >= INFO_CMD) && (wmId < INFO_CMD+MAX_CHANNELS))
1199                         {
1200                                 int c = wmId - INFO_CMD;
1201                                 chanInfo = getChannelInfo(c);
1202                                 chanInfoIsRelayed = false;
1203                                 if (winDistinctionNT)
1204                                         DialogBox(hInst, (LPCTSTR)IDD_CHANINFO, hWnd, (DLGPROC)ChanInfoProc);
1205                                 else
1206                                 {
1207                                         HWND WKDLG; //JP-Patch
1208                                         WKDLG = CreateDialog(hInst, (LPCTSTR)IDD_CHANINFO, hWnd, (DLGPROC)ChanInfoProc); //JP-Patch
1209                                         ShowWindow(WKDLG,SW_SHOWNORMAL); //JP-Patch
1210                                 }
1211                                 return 0;
1212                         }
1213                         if ((wmId >= URL_CMD) && (wmId < URL_CMD+MAX_CHANNELS))
1214                         {
1215                                 int c = wmId - URL_CMD;
1216                                 chanInfo = getChannelInfo(c);
1217                                 if (chanInfo.url.isValidURL())
1218                                         sys->getURL(chanInfo.url);
1219                                 return 0;
1220                         }
1221                         if ((wmId >= PLAY_CMD) && (wmId < PLAY_CMD+MAX_CHANNELS))
1222                         {
1223                                 int c = wmId - PLAY_CMD;
1224                                 chanInfo = getChannelInfo(c);
1225                                 chanMgr->findAndPlayChannel(chanInfo,false);
1226                                 return 0;
1227                         }
1228                         if ((wmId >= RELAY_CMD) && (wmId < RELAY_CMD+MAX_CHANNELS))
1229                         {
1230                                 int c = wmId - RELAY_CMD;
1231                                 chanInfo = getChannelInfo(c);
1232                                 chanMgr->findAndPlayChannel(chanInfo,true);
1233                                 return 0;
1234                         }
1235
1236                         // Parse the menu selections:
1237                         switch (wmId)
1238                         {
1239                                 case ID_POPUP_SHOWMESSAGES_PEERCAST:
1240                                         flipNotifyPopup(ID_POPUP_SHOWMESSAGES_PEERCAST,ServMgr::NT_PEERCAST);
1241                                         break;
1242                                 case ID_POPUP_SHOWMESSAGES_BROADCASTERS:
1243                                         flipNotifyPopup(ID_POPUP_SHOWMESSAGES_BROADCASTERS,ServMgr::NT_BROADCASTERS);
1244                                         break;
1245                                 case ID_POPUP_SHOWMESSAGES_TRACKINFO:
1246                                         flipNotifyPopup(ID_POPUP_SHOWMESSAGES_TRACKINFO,ServMgr::NT_TRACKINFO);
1247                                         break;
1248
1249                                 case ID_POPUP_ABOUT:
1250                                 case IDM_ABOUT:
1251                                         DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
1252                                         break;
1253                                 case ID_POPUP_SHOWGUI:
1254                                 case IDM_SETTINGS_GUI:
1255                                 case ID_POPUP_ADVANCED_SHOWGUI:
1256                                 {
1257                                         createGUI(hWnd);
1258                                         break;
1259                                 }
1260                                 case ID_POPUP_YELLOWPAGES:
1261                                         sys->getURL("http://yp.peercast.org/");
1262                                         break;
1263                                 case ID_POPUP_YELLOWPAGES1:
1264                                         sprintf(buf, "http://%s",servMgr->rootHost.cstr());
1265                                         sys->getURL(buf);
1266                                         break;
1267                                 case ID_POPUP_YELLOWPAGES2:
1268                                         sprintf(buf, "http://%s",servMgr->rootHost2.cstr());
1269                                         sys->getURL(buf);
1270                                         break;
1271
1272                                 case ID_POPUP_ADVANCED_VIEWLOG:
1273                                         showHTML("viewlog.html");
1274                                         break;
1275                                 case ID_POPUP_ADVANCED_SAVESETTINGS:
1276                                         servMgr->saveSettings(iniFileName.cstr());
1277                                         break;
1278                                 case ID_POPUP_ADVANCED_INFORMATION:
1279                                         showHTML("index.html");
1280                                         break;
1281                                 case ID_FIND_CHANNELS:
1282                                 case ID_POPUP_ADVANCED_ALLCHANNELS:
1283                                 case ID_POPUP_UPGRADE:
1284                                         sys->callLocalURL("admin?cmd=upgrade",servMgr->serverHost.port);
1285                                         break;
1286                                 case ID_POPUP_ADVANCED_RELAYEDCHANNELS:
1287                                 case ID_POPUP_FAVORITES_EDIT:
1288                                         showHTML("relays.html");
1289                                         break;
1290                                 case ID_POPUP_ADVANCED_BROADCAST:
1291                                         showHTML("broadcast.html");
1292                                         break;
1293                                 case ID_POPUP_SETTINGS:
1294                                         showHTML("settings.html");
1295                                         break;
1296                                 case ID_POPUP_CONNECTIONS:
1297                                         showHTML("connections.html");
1298                                         break;
1299                                 case ID_POPUP_HELP:
1300                                         sys->getURL("http://www.peercast.org/help.php");
1301                                         break;
1302
1303                                 case ID_POPUP_SAVE_GUI_POS:
1304                                         if (servMgr->saveGuiPos){
1305                                                 servMgr->saveGuiPos = false;
1306                                                 CheckMenuItem(trayMenu, ID_POPUP_SAVE_GUI_POS, MF_UNCHECKED|MF_BYCOMMAND);
1307                                         } else {
1308                                                 servMgr->saveGuiPos = true;
1309                                                 CheckMenuItem(trayMenu, ID_POPUP_SAVE_GUI_POS, MF_CHECKED|MF_BYCOMMAND);
1310                                         }
1311                                         peercastInst->saveSettings();
1312                                         break;
1313
1314                                 case ID_POPUP_KEEP_DOWNSTREAMS:
1315                                         if (servMgr->keepDownstreams){
1316                                                 servMgr->keepDownstreams = false;
1317                                                 CheckMenuItem(trayMenu, ID_POPUP_KEEP_DOWNSTREAMS, MF_UNCHECKED|MF_BYCOMMAND);
1318                                         } else {
1319                                                 servMgr->keepDownstreams = true;
1320                                                 CheckMenuItem(trayMenu, ID_POPUP_KEEP_DOWNSTREAMS, MF_CHECKED|MF_BYCOMMAND);
1321                                         }
1322                                         //peercastInst->saveSettings();
1323                                         break;
1324
1325                                 case ID_POPUP_TOPMOST:
1326                                         // \8dÅ\91O\96Ê\95\\8e¦
1327                                         if (servMgr->topmostGui)
1328                                         {
1329                                                 servMgr->topmostGui = false;
1330                                                 CheckMenuItem(trayMenu, ID_POPUP_TOPMOST, MF_UNCHECKED|MF_BYCOMMAND);
1331                                         } else
1332                                         {
1333                                                 servMgr->topmostGui = true;
1334                                                 CheckMenuItem(trayMenu, ID_POPUP_TOPMOST, MF_CHECKED|MF_BYCOMMAND);
1335                                         }
1336                                         peercastInst->saveSettings();
1337                                         break;
1338
1339                                 case ID_POPUP_START_WITH_GUI:
1340                                         // \8bN\93®\8e\9e\82ÉGUI\95\\8e¦
1341                                         if (servMgr->startWithGui)
1342                                         {
1343                                                 servMgr->startWithGui = false;
1344                                                 CheckMenuItem(trayMenu, ID_POPUP_START_WITH_GUI, MF_UNCHECKED|MF_BYCOMMAND);
1345                                         } else
1346                                         {
1347                                                 servMgr->startWithGui = true;
1348                                                 CheckMenuItem(trayMenu, ID_POPUP_START_WITH_GUI, MF_CHECKED|MF_BYCOMMAND);
1349                                         }
1350                                         peercastInst->saveSettings();
1351                                         break;
1352
1353                                 case ID_POPUP_TRAFFIC:
1354                                         // \83g\83\89\83t\83B\83b\83N\83\82\83j\83^\8bN\93®
1355                                         if (winDistinctionNT)
1356                                                 DialogBox(hInst, (LPCTSTR)IDD_TRAFFIC, hWnd, (DLGPROC)TrafficDlgProc);
1357                                         else
1358                                         {
1359                                                 HWND WKDLG; //JP-Patch
1360                                                 WKDLG = CreateDialog(hInst, (LPCTSTR)IDD_CHANINFO, hWnd, (DLGPROC)TrafficDlgProc); //JP-Patch
1361                                                 ShowWindow(WKDLG,SW_SHOWNORMAL); //JP-Patch
1362                                         }
1363                                         break;
1364
1365                                 case ID_POPUP_PREVENT_SS:
1366                                         // \83X\83N\83\8a\81[\83\93\83Z\81[\83o\81[\97}\8e~
1367                                         if (servMgr->preventSS)
1368                                         {
1369                                                 servMgr->preventSS = false;
1370                                                 CheckMenuItem(trayMenu, ID_POPUP_PREVENT_SS, MF_UNCHECKED|MF_BYCOMMAND);
1371                                         } else
1372                                         {
1373                                                 servMgr->preventSS = true;
1374                                                 CheckMenuItem(trayMenu, ID_POPUP_PREVENT_SS, MF_CHECKED|MF_BYCOMMAND);
1375                                         }
1376                                         peercastInst->saveSettings();
1377                                         break;
1378
1379                                 case ID_POPUP_EXIT_CONFIRM:
1380                                 case IDM_EXIT:
1381                                    DestroyWindow(hWnd);
1382                                    break;
1383                                 default:
1384                                    return DefWindowProc(hWnd, message, wParam, lParam);
1385                         }
1386                         break;
1387                 case WM_DESTROY:
1388                         PostQuitMessage(0);
1389                         break;
1390
1391                 case WM_SYSCOMMAND:
1392                         // \82È\82ñ\82©\83A\83N\83e\83B\83u\82\82á\82È\82¢\82Æ\91\97\82ç\82ê\82Ä\82±\82È\82¢\82ç\82µ\82¢
1393                         if (servMgr->preventSS && (wParam == SC_SCREENSAVE) && chanMgr->isBroadcasting())
1394                                 return 1;
1395                         else
1396                                 return DefWindowProc(hWnd, message, wParam, lParam);
1397                         break;
1398
1399                 default:
1400                         return DefWindowProc(hWnd, message, wParam, lParam);
1401    }
1402    return 0;
1403 }
1404 // Mesage handler for about box.
1405 LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
1406 {
1407         switch (message)
1408         {
1409                 case WM_INITDIALOG:
1410                         //SendDlgItemMessage(hDlg,IDC_ABOUTVER,WM_SETTEXT,0,(LONG)PCX_AGENT);
1411 //                      SendDlgItemMessage(hDlg,IDC_ABOUTVER,WM_SETTEXT,0,(LONG)PCX_AGENTJP);
1412                         if (version_ex)
1413                         {
1414                                 SendDlgItemMessage(hDlg,IDC_ABOUTVER,WM_SETTEXT,0,(LONG)PCX_AGENTEX);
1415                         } else
1416                         {
1417                                 SendDlgItemMessage(hDlg,IDC_ABOUTVER,WM_SETTEXT,0,(LONG)PCX_AGENTVP);
1418                         }
1419
1420                         return TRUE;
1421
1422                 case WM_COMMAND:
1423                         switch (LOWORD(wParam))
1424                         {
1425                                 case IDOK:
1426                                 case IDCANCEL:
1427                                         EndDialog(hDlg, LOWORD(wParam));
1428                                         return TRUE;
1429                                 case IDC_BUTTON1:
1430                                         sys->getURL("http://www.peercast.org");
1431                                         EndDialog(hDlg, LOWORD(wParam));
1432                                         return TRUE;
1433
1434                         }
1435                         break;
1436                 case WM_DESTROY:
1437                         break;
1438         }
1439     return FALSE;
1440 }
1441
1442 // Mesage handler for chaninfo box
1443 LRESULT CALLBACK ChanInfoProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
1444 {
1445         switch (message)
1446         {
1447                 case WM_INITDIALOG:
1448                         {
1449                                 char str[1024];
1450                                 //strcpy(str,chanInfo.track.artist.cstr());
1451                                 strcpy(str,chanInfo.track.artist); //JP-Patch
1452                                 strcat(str," - ");
1453                                 //strcat(str,chanInfo.track.title.cstr());
1454                                 strcat(str,chanInfo.track.title);
1455                                 String name,track,comment,desc,genre; //JP-Patch
1456                                 name = chanInfo.name; //JP-Patch
1457                                 track = str; //JP-Patch
1458                                 comment = chanInfo.comment; //JP-Patch
1459                                 desc = chanInfo.desc; //JP-Patc
1460                                 genre = chanInfo.genre; //JP-Patch
1461                                 name.convertTo(String::T_SJIS); //JP-Patc
1462                                 track.convertTo(String::T_SJIS); //JP-Patch
1463                                 comment.convertTo(String::T_SJIS); //JP-Patch
1464                                 desc.convertTo(String::T_SJIS); //JP-Patch
1465                                 genre.convertTo(String::T_SJIS); //JP-Patch
1466                                 
1467                                 //SendDlgItemMessage(hDlg,IDC_EDIT_NAME,WM_SETTEXT,0,(LONG)chanInfo.name.cstr());
1468                                 SendDlgItemMessage(hDlg,IDC_EDIT_NAME,WM_SETTEXT,0,(LONG)name.cstr()); //JP-Patch
1469                                 //SendDlgItemMessage(hDlg,IDC_EDIT_PLAYING,WM_SETTEXT,0,(LONG)str);
1470                                 SendDlgItemMessage(hDlg,IDC_EDIT_PLAYING,WM_SETTEXT,0,(LONG)track.cstr()); //JP-Patch
1471                                 //SendDlgItemMessage(hDlg,IDC_EDIT_MESSAGE,WM_SETTEXT,0,(LONG)chanInfo.comment.cstr());
1472                                 SendDlgItemMessage(hDlg,IDC_EDIT_MESSAGE,WM_SETTEXT,0,(LONG)comment.cstr()); //JP-Patch
1473                                 //SendDlgItemMessage(hDlg,IDC_EDIT_DESC,WM_SETTEXT,0,(LONG)chanInfo.desc.cstr());
1474                                 SendDlgItemMessage(hDlg,IDC_EDIT_DESC,WM_SETTEXT,0,(LONG)desc.cstr()); //JP-Patch
1475                                 //SendDlgItemMessage(hDlg,IDC_EDIT_GENRE,WM_SETTEXT,0,(LONG)chanInfo.genre.cstr());
1476                                 SendDlgItemMessage(hDlg,IDC_EDIT_GENRE,WM_SETTEXT,0,(LONG)genre.cstr()); //JP-Patch
1477
1478                                 sprintf(str,"%d kb/s %s",chanInfo.bitrate,ChanInfo::getTypeStr(chanInfo.contentType));
1479                                 SendDlgItemMessage(hDlg,IDC_FORMAT,WM_SETTEXT,0,(LONG)str);
1480
1481
1482                                 if (!chanInfo.url.isValidURL())
1483                                         EnableWindow(GetDlgItem(hDlg,IDC_CONTACT),false);
1484
1485                                 Channel *ch = chanMgr->findChannelByID(chanInfo.id);
1486                                 if (ch)
1487                                 {
1488                                         SendDlgItemMessage(hDlg,IDC_EDIT_STATUS,WM_SETTEXT,0,(LONG)ch->getStatusStr());
1489                                         SendDlgItemMessage(hDlg, IDC_KEEP,BM_SETCHECK, ch->stayConnected, 0);
1490
1491                                         // \8c»\8dÝ\82Ì\8cÅ\97L\83\8a\83\8c\81[\8fã\8cÀ\90Ý\92è\82ð\95\\8e¦(0\82Í\96³\8cø)
1492                                         ::SetDlgItemInt(hDlg, IDC_EDIT_MAXRELAYS, ch->maxRelays, false);
1493                                         if (isIndexTxt(ch))
1494                                         {
1495                                                 // index.txt\82È\82Ì\82Å\96³\8cø\82É
1496                                                 ::EnableWindow(::GetDlgItem(hDlg, IDC_EDIT_MAXRELAYS), false);
1497                                                 ::EnableWindow(::GetDlgItem(hDlg, IDC_APPLY_MAXRELAYS), false);
1498                                         }
1499                                 }else
1500                                 {
1501                                         SendDlgItemMessage(hDlg,IDC_EDIT_STATUS,WM_SETTEXT,0,(LONG)"OK");
1502                                         EnableWindow(GetDlgItem(hDlg,IDC_KEEP),false);
1503                                 }
1504
1505
1506
1507                                 POINT point;
1508                                 RECT rect,drect;
1509                                 HWND hDsk = GetDesktopWindow();
1510                                 GetWindowRect(hDsk,&drect);
1511                                 GetWindowRect(hDlg,&rect);
1512                                 GetCursorPos(&point);
1513
1514                                 POINT pos,size;
1515                                 size.x = rect.right-rect.left;
1516                                 size.y = rect.bottom-rect.top;
1517
1518                                 if (point.x-drect.left < size.x)
1519                                         pos.x = point.x;
1520                                 else
1521                                         pos.x = point.x-size.x;
1522
1523                                 if (point.y-drect.top < size.y)
1524                                         pos.y = point.y;
1525                                 else
1526                                         pos.y = point.y-size.y;
1527
1528                                 SetWindowPos(hDlg,HWND_TOPMOST,pos.x,pos.y,size.x,size.y,0);
1529                                 chWnd = hDlg;
1530                         }
1531                         return TRUE;
1532
1533                 case WM_COMMAND:
1534                         {
1535                                 char str[1024],idstr[64];
1536                                 chanInfo.id.toStr(idstr);
1537
1538                                 switch (LOWORD(wParam))
1539                                 {
1540                                 case IDC_CONTACT:
1541                                         {
1542                                                 sys->getURL(chanInfo.url);
1543                                                 return TRUE;
1544                                         }
1545                                 case IDC_DETAILS:
1546                                         {
1547                                                 sprintf(str,"admin?page=chaninfo&id=%s&relay=%d",idstr,chanInfoIsRelayed);
1548                                                 sys->callLocalURL(str,servMgr->serverHost.port);
1549                                                 return TRUE;
1550                                         }
1551                                 case IDC_KEEP:
1552                                         {
1553                                                 Channel *ch = chanMgr->findChannelByID(chanInfo.id);
1554                                                 if (ch)
1555                                                         ch->stayConnected = SendDlgItemMessage(hDlg, IDC_KEEP,BM_GETCHECK, 0, 0) == BST_CHECKED;;
1556                                                 return TRUE;
1557                                         }
1558
1559
1560                                 case IDC_PLAY:
1561                                         {
1562                                                 chanMgr->findAndPlayChannel(chanInfo,false);
1563                                                 return TRUE;
1564                                         }
1565
1566                                 case IDC_APPLY_MAXRELAYS:
1567                                         {
1568                                                 // \83`\83\83\83\93\83l\83\8b\8cÅ\97L\82Ì\8dÅ\91å\83\8a\83\8c\81[\90\94\82ð\90Ý\92è
1569                                                 BOOL bSucc;
1570                                                 unsigned int mr;
1571
1572                                                 // \93ü\97Í\92l\8eæ\93¾
1573                                                 mr = ::GetDlgItemInt(hDlg, IDC_EDIT_MAXRELAYS, &bSucc, false);
1574
1575                                                 if (bSucc)
1576                                                 {
1577                                                         Channel *ch = chanMgr->findChannelByID(chanInfo.id);
1578                                                         if (ch && !isIndexTxt(ch))
1579                                                         {
1580                                                                 ch->maxRelays = mr;
1581                                                         }
1582                                                 } else
1583                                                 {
1584                                                         MessageBox(hDlg, "\93ü\97Í\92l\82ª\95s\90³\82Å\82·\81B", "Error", MB_OK|MB_ICONERROR|MB_APPLMODAL);
1585                                                         Channel *ch = chanMgr->findChannelByID(chanInfo.id);
1586                                                         if (ch)
1587                                                                 ::SetDlgItemInt(hDlg, IDC_EDIT_MAXRELAYS, ch->maxRelays, false);
1588                                                 }
1589                                         }
1590                                 }
1591                         }
1592                         break;
1593
1594                 case WM_CLOSE:
1595                         if (winDistinctionNT)
1596                                 EndDialog(hDlg, 0);
1597                         else
1598                                 DestroyWindow(hDlg); //JP-Patch
1599                         break;
1600
1601                 case WM_ACTIVATE:
1602                         if (LOWORD(wParam) == WA_INACTIVE)
1603                                 if (winDistinctionNT)
1604                                         EndDialog(hDlg, 0);
1605                                 else
1606                                         DestroyWindow(hDlg); //JP-Patch
1607                         break;
1608                 case WM_DESTROY:
1609                         chWnd = NULL;
1610                         break;
1611
1612
1613         }
1614     return FALSE;
1615 }
1616
1617 // control thread (Traffic dialog)
1618 THREAD_PROC trafficDlgUpdate(ThreadInfo *thread)
1619 {
1620         thread->finish = false;
1621
1622         while (trafficDlg && thread->active)
1623         {
1624                 SendMessage(trafficDlg, WM_UPDATETRAFFIC, 0, 0);
1625                 Sleep(1000);
1626         }
1627
1628         thread->finish = true;
1629
1630         return 0;
1631 }
1632
1633 // Dialog procedure (Traffic dialog)
1634 LRESULT CALLBACK TrafficDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
1635 {
1636         switch (message)
1637         {
1638         case WM_INITDIALOG:
1639                 // \8aù\82É\8aJ\82¢\82Ä\82é
1640                 if (trafficDlg || trafficDlgThread.active)
1641                 {
1642                         if (winDistinctionNT)
1643                                 EndDialog(hDlg, 0);
1644                         else
1645                                 DestroyWindow(hDlg);
1646                         return FALSE;
1647                 }
1648
1649                 trafficDlg = hDlg;
1650                 trafficDlgThread.func = trafficDlgUpdate;
1651                 if (!sys->startThread(&trafficDlgThread)){
1652                         MessageBox(NULL,"Unable to start GUI","PeerCast",MB_OK|MB_ICONERROR);
1653                         PostMessage(hDlg,WM_DESTROY,0,0);
1654                 }
1655
1656                 break;
1657
1658         case WM_UPDATETRAFFIC:
1659                 {
1660                         enum unitSymbol { B, KB, MB, GB };
1661                         const unsigned long int unit[] = { 1, 1024, 1024*1024, 1024*1024*1024 };
1662                         char suffix[][3] = { "B", "KB", "MB", "GB" };
1663                         const int bufsize = 60;
1664                         char szUp[bufsize], szDown[bufsize];
1665                         unsigned long long int totalDown = stats.getCurrent(Stats::BYTESIN) - stats.getCurrent(Stats::LOCALBYTESIN);
1666                         unsigned long long int totalUp = stats.getCurrent(Stats::BYTESOUT) - stats.getCurrent(Stats::LOCALBYTESOUT);
1667
1668                         // up
1669                         for (int i=GB; i>0; --i)
1670                         {
1671                                 if (totalUp >= unit[i])
1672                                 {
1673                                         sprintf_s<bufsize>(szUp, "%.2f%s", (double)totalUp/unit[i], suffix[i]);
1674                                         break;
1675                                 }
1676
1677                                 if (i == 1)
1678                                         sprintf_s<bufsize>(szUp, "%d%s", totalUp, suffix[0]);
1679                         }
1680
1681                         // down
1682                         for (int i=GB; i>0; --i)
1683                         {
1684                                 if (totalDown >= unit[i])
1685                                 {
1686                                         sprintf_s<bufsize>(szDown, "%.2f%s", (double)totalDown/unit[i], suffix[i]);
1687                                         break;
1688                                 }
1689
1690                                 if (i == 1)
1691                                         sprintf_s<bufsize>(szDown, "%d%s", totalDown, suffix[0]);
1692                         }
1693
1694                         SetDlgItemText(hDlg, IDC_STATIC_UP, szUp);
1695                         SetDlgItemText(hDlg, IDC_STATIC_DOWN, szDown);
1696                 }
1697                 break;
1698
1699         case WM_CLOSE:
1700                 trafficDlg = NULL;
1701                 trafficDlgThread.active = false;
1702                 if (winDistinctionNT)
1703                         EndDialog(hDlg, 0);
1704                 else
1705                         DestroyWindow(hDlg);
1706
1707                 break;
1708
1709         case WM_DESTROY:
1710                 break;
1711         }
1712
1713         return FALSE;
1714 }