OSDN Git Service

d777ed10c2090a8adb9ef74f02f7096b921978fc
[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
84 // \83v\83\8d\83g\83^\83C\83v\90é\8c¾
85 void createGUI(HWND);
86 LRESULT CALLBACK TrafficDlgProc(HWND, UINT, WPARAM, LPARAM);
87
88 // ---------------------------------
89 Sys * APICALL MyPeercastInst::createSys()
90 {
91         return new WSys(mainWnd);
92 }
93 // ---------------------------------
94 const char * APICALL MyPeercastApp ::getIniFilename()
95 {
96         return iniFileName.cstr();
97 }
98
99 // ---------------------------------
100 const char *APICALL MyPeercastApp ::getClientTypeOS() 
101 {
102         return PCX_OS_WIN32;
103 }
104
105 // ---------------------------------
106 const char * APICALL MyPeercastApp::getPath()
107 {
108         return exePath.cstr();
109 }
110
111 // --------------------------------- JP-EX
112 void    APICALL MyPeercastApp ::openLogFile()
113 {
114         logFile.openWriteReplace("log.txt");
115 }
116 // --------------------------------- JP-EX
117 void    APICALL MyPeercastApp ::getDirectory()
118 {
119         char path_buffer[256],drive[32],dir[128];
120         GetModuleFileName(NULL,path_buffer,255);
121         _splitpath(path_buffer,drive,dir,NULL,NULL);
122         sprintf(servMgr->modulePath,"%s%s",drive,dir);
123 }
124 // --------------------------------- JP-EX
125 bool    APICALL MyPeercastApp ::clearTemp()
126 {
127         if (servMgr->clearPLS)
128                 return true;
129
130         return false;
131 }
132
133
134 class NOTIFYICONDATA2
135 {
136 public:
137         DWORD cbSize; // DWORD
138         HWND hWnd; // HWND
139         UINT uID; // UINT
140         UINT uFlags; // UINT
141         UINT uCallbackMessage; // UINT
142         HICON hIcon; // HICON
143         char szTip[128]; // char[128]
144         DWORD dwState; // DWORD
145         DWORD dwStateMask; // DWORD
146         char szInfo[256]; // char[256]
147         UINT uTimeoutOrVersion; // UINT
148         char szInfoTitle[64]; // char[64]
149         DWORD dwInfoFlags; // DWORD
150         //GUID guidItem; > IE 6
151 };
152
153 NOTIFYICONDATA2 trayIcon;
154
155
156 // Global Variables:
157 HINSTANCE hInst;                                                                // current instance
158 TCHAR szTitle[MAX_LOADSTRING];                                                          // The title bar text
159 TCHAR szWindowClass[MAX_LOADSTRING];                                                            // The title bar text
160 TCHAR szWindowClass2[MAX_LOADSTRING];                                                           // The title bar text
161
162 // Foward declarations of functions included in this code module:
163 ATOM                            MyRegisterClass(HINSTANCE hInstance);
164 ATOM                            MyRegisterClass2(HINSTANCE hInstance);
165 ATOM                            MyRegisterClass3(HINSTANCE hInstance);
166 BOOL                            InitInstance(HINSTANCE, int);
167 LRESULT CALLBACK        WndProc(HWND, UINT, WPARAM, LPARAM);
168 LRESULT CALLBACK        About(HWND, UINT, WPARAM, LPARAM);
169 LRESULT CALLBACK        ChanInfoProc(HWND, UINT, WPARAM, LPARAM);
170
171 void setTrayIcon(int type, const char *,const char *,bool);
172 void flipNotifyPopup(int id, ServMgr::NOTIFY_TYPE nt);
173
174
175 HWND chWnd=NULL;
176
177 // --------------------------------------------------
178 void LOG2(const char *fmt,...)
179 {
180         va_list ap;
181         va_start(ap, fmt);
182         char str[4096];
183         vsprintf(str,fmt,ap);
184         OutputDebugString(str);
185         va_end(ap);     
186 }
187
188
189
190 // ---------------------------------------
191 int APIENTRY WinMain(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 //
406 //  FUNCTION: MyRegisterClass()
407 //
408 //  PURPOSE: Registers the window class.
409 //
410 //  COMMENTS:
411 //
412 //    This function and its usage is only necessary if you want this code
413 //    to be compatible with Win32 systems prior to the 'RegisterClassEx'
414 //    function that was added to Windows 95. It is important to call this function
415 //    so that the application will get 'well formed' small icons associated
416 //    with it.
417 //
418 ATOM MyRegisterClass(HINSTANCE hInstance)
419 {
420         WNDCLASSEX wcex;
421
422         wcex.cbSize = sizeof(WNDCLASSEX); 
423
424         wcex.style                      = CS_HREDRAW | CS_VREDRAW;
425         wcex.lpfnWndProc        = (WNDPROC)WndProc;
426         wcex.cbClsExtra         = 0;
427         wcex.cbWndExtra         = 0;
428         wcex.hInstance          = hInstance;
429         wcex.hIcon                      = LoadIcon(hInstance, (LPCTSTR)IDI_SIMPLE);
430         wcex.hCursor            = LoadCursor(NULL, IDC_ARROW);
431         wcex.hbrBackground      = (HBRUSH)(COLOR_WINDOW+1);
432 //      wcex.lpszMenuName       = (LPCSTR)IDC_SIMPLE;
433         wcex.lpszMenuName       = NULL;
434         wcex.lpszClassName      = szWindowClass;
435         wcex.hIconSm            = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
436
437         return RegisterClassEx(&wcex);
438 }
439
440 ATOM MyRegisterClass2(HINSTANCE hInstance)
441 {
442         WNDCLASSEX wcex;
443         
444         wcex.cbSize = sizeof(WNDCLASSEX); 
445
446         wcex.style                      = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS ;
447         wcex.lpfnWndProc        = (WNDPROC)GUIProc;
448         wcex.cbClsExtra         = 0;
449         wcex.cbWndExtra         = 0;
450         wcex.hInstance          = hInstance;
451         wcex.hIcon                      = LoadIcon(hInstance, (LPCTSTR)IDI_SIMPLE);
452         wcex.hCursor            = LoadCursor(NULL, IDC_ARROW);
453         wcex.hbrBackground      = (HBRUSH)(COLOR_WINDOW+1);
454 //      wcex.lpszMenuName       = (LPCSTR)IDC_SIMPLE;
455         wcex.lpszMenuName       = NULL;
456         wcex.lpszClassName      = szWindowClass2;
457         wcex.hIconSm            = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
458
459         return RegisterClassEx(&wcex);
460 }
461
462 //-----------------------------
463 void loadIcons(HINSTANCE hInstance, HWND hWnd)
464 {
465         icon1 = LoadIcon(hInstance, (LPCTSTR)IDI_SMALL);
466         icon2 = LoadIcon(hInstance, (LPCTSTR)IDI_SMALL2);
467
468     trayIcon.cbSize = sizeof(trayIcon);
469     trayIcon.hWnd = hWnd;
470     trayIcon.uID = 100;
471     trayIcon.uFlags = NIF_MESSAGE + NIF_ICON + NIF_TIP;
472     trayIcon.uCallbackMessage = WM_TRAYICON;
473     trayIcon.hIcon = icon1;
474     strcpy(trayIcon.szTip, "PeerCast");
475
476     Shell_NotifyIcon(NIM_ADD, (NOTIFYICONDATA*)&trayIcon);
477
478     //ShowWindow(hWnd, nCmdShow);
479     UpdateWindow(hWnd);
480
481         if(!trayMenu)   // for PCRaw (tray icon)
482                 trayMenu = LoadMenu(hInstance,MAKEINTRESOURCE(IDR_TRAYMENU));
483         if(!ltrayMenu)  // for PCRaw (tray icon)
484                 ltrayMenu = LoadMenu(hInstance,MAKEINTRESOURCE(IDR_LTRAYMENU));
485
486
487 }
488
489 //-----------------------------
490 //
491 //   FUNCTION: InitInstance(HANDLE, int)
492 //
493 //   PURPOSE: Saves instance handle and creates main window
494 //
495 //   COMMENTS:
496 //
497 //        In this function, we save the instance handle in a global variable and
498 //        create and display the main program window.
499 //
500 BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
501 {
502         HWND hWnd;
503
504         hInst = hInstance; // Store instance handle in our global variable
505
506         hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
507           CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
508
509         if (!hWnd)
510         {
511           return FALSE;
512         }
513
514         mainWnd = hWnd;
515
516         g_iTaskbarCreated = RegisterWindowMessage("TaskbarCreated");    // for PCRaw (tray icon)
517
518         loadIcons(hInstance,hWnd);
519
520         using namespace Gdiplus;
521         GdiplusStartupInput gdiplusStartupInput;
522         GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
523
524         return TRUE;
525 }
526 //-----------------------------
527 //static String trackTitle;
528 //static String channelComment;
529
530 //-----------------------------
531 void channelPopup(const char *title, const char *msg, bool isPopup = true)
532 {
533         String both;
534
535         if (*title == '\0') return;
536         both.append(msg);
537         both.append(" (");
538         both.append(title);
539         both.append(")");
540
541         trayIcon.uFlags = NIF_ICON|NIF_TIP;
542         strncpy(trayIcon.szTip, both.cstr(),sizeof(trayIcon.szTip)-1);
543         trayIcon.szTip[sizeof(trayIcon.szTip)-1]=0;
544
545         if (isPopup) trayIcon.uFlags |= 16;
546         trayIcon.uTimeoutOrVersion = 10000;
547         strncpy(trayIcon.szInfo,msg,sizeof(trayIcon.szInfo)-1);
548         strncpy(trayIcon.szInfoTitle,title,sizeof(trayIcon.szInfoTitle)-1);
549                 
550         Shell_NotifyIcon(NIM_MODIFY, (NOTIFYICONDATA*)&trayIcon);
551 }
552 //-----------------------------
553 void clearChannelPopup()
554 {
555         trayIcon.uFlags = NIF_ICON|16;
556         trayIcon.uTimeoutOrVersion = 10000;
557     strncpy(trayIcon.szInfo,"",sizeof(trayIcon.szInfo)-1);
558         strncpy(trayIcon.szInfoTitle,"",sizeof(trayIcon.szInfoTitle)-1);
559         Shell_NotifyIcon(NIM_MODIFY, (NOTIFYICONDATA*)&trayIcon);
560 }
561
562 //-----------------------------
563 // PopupEntry
564 struct PopupEntry {
565         GnuID id;
566         String name;
567         String track;
568         String comment;
569         PopupEntry *next;
570 };
571 static PopupEntry *PEList = NULL;
572 static WLock PELock;
573
574 static void putPopupEntry(PopupEntry *pe)
575 {
576         PELock.on();
577         pe->next = PEList;
578         PEList = pe;
579         PELock.off();
580 }
581
582 static PopupEntry *getPopupEntry(GnuID id)
583 {
584         PELock.on();
585         PopupEntry *pe = PEList;
586         PopupEntry *prev = NULL;
587         while (pe) {
588                 if (id.isSame(pe->id)) {
589                         if (prev) prev->next = pe->next;
590                         else PEList = pe->next;
591                         PELock.off();
592                         pe->next = NULL;
593                         return pe;
594                 }
595                 prev = pe;
596                 pe = pe->next;
597         }
598         PELock.off();
599         return NULL;
600 }
601
602 static PopupEntry *getTopPopupEntry()
603 {
604         PopupEntry *p = NULL;
605         PELock.on();
606         if (PEList) {
607                 p = PEList;
608                 PEList = PEList->next;
609         }
610         PELock.off();
611         return p;
612 }
613
614 //-----------------------------
615 void    APICALL MyPeercastApp::channelStart(ChanInfo *info)
616 {
617
618 //      lastPlayID = info->id;
619 //
620 //      if(!isIndexTxt(info))   // for PCRaw (popup)
621 //              clearChannelPopup();
622
623         PopupEntry *pe = getPopupEntry(info->id);
624         if (!pe) {
625                 pe = new PopupEntry;
626                 pe->id = info->id;
627         }
628         if (!isIndexTxt(info))
629                 putPopupEntry(pe);
630         else
631                 delete pe;
632 }
633 //-----------------------------
634 void    APICALL MyPeercastApp::channelStop(ChanInfo *info)
635 {
636 //      if (info->id.isSame(lastPlayID))
637 //      {
638 //              lastPlayID.clear();
639 //
640 //              if(!isIndexTxt(info))   // for PCRaw (popup)
641 //                      clearChannelPopup();
642 //      }
643
644         PopupEntry *pe = getPopupEntry(info->id);
645         if (pe) delete pe;
646
647         pe = getTopPopupEntry();
648         if (!pe) {
649                 clearChannelPopup();
650         } else {
651                 if (ServMgr::NT_TRACKINFO & peercastInst->getNotifyMask())
652                 {
653                         String name,track; //JP-Patch
654                         name = pe->name; //JP-Patch
655                         track = pe->track; //JP-Patch
656                         name.convertTo(String::T_SJIS); //JP-Patch
657                         track.convertTo(String::T_SJIS); //JP-Patch
658                         clearChannelPopup();
659                 //      channelPopup(info->name.cstr(),trackTitle.cstr());
660                         channelPopup(name.cstr(),track.cstr(), false); //JP-Patch
661                 }
662                 putPopupEntry(pe);
663         }
664 }
665 //-----------------------------
666 void    APICALL MyPeercastApp::channelUpdate(ChanInfo *info)
667 {
668         if (info)
669         {
670                 PopupEntry *pe = getPopupEntry(info->id);
671                 if (!pe) return;
672
673                 String tmp;
674                 tmp.append(info->track.artist);
675                 tmp.append(" ");
676                 tmp.append(info->track.title);
677
678
679                 if (!tmp.isSame(pe->track))
680                 {
681                         pe->name = info->name;
682                         pe->track = tmp;
683                         if (ServMgr::NT_TRACKINFO & peercastInst->getNotifyMask())
684                         {
685                                 //trackTitle=tmp;
686                                 String name,track; //JP-Patch
687                                 name = info->name; //JP-Patch
688                                 track = tmp; //JP-Patch
689                                 name.convertTo(String::T_SJIS); //JP-Patch
690                                 track.convertTo(String::T_SJIS); //JP-Patch
691                                 if(!isIndexTxt(info))   // for PCRaw (popup)
692                                 {
693                                         clearChannelPopup();
694                                 //      channelPopup(info->name.cstr(),trackTitle.cstr());
695                                         channelPopup(name.cstr(),track.cstr()); //JP-Patch
696                                 }
697                         }
698                 } else if (!info->comment.isSame(pe->comment))
699                 {
700                         pe->name = info->name;
701                         pe->comment = info->comment;
702                         if (ServMgr::NT_BROADCASTERS & peercastInst->getNotifyMask())
703                         {
704                                 //channelComment = info->comment;
705                                 String name,comment; //JP-Patch
706                                 name = info->name; //JP-Patch
707                                 comment = info->comment; //JP-Patch
708                                 name.convertTo(String::T_SJIS); //JP-Patch
709                                 comment.convertTo(String::T_SJIS); //JP-Patch
710                                 if(!isIndexTxt(info))   // for PCRaw (popup)
711                                 {
712                                         clearChannelPopup();
713                                 //      channelPopup(info->name.cstr(),channelComment.cstr());
714                                         channelPopup(name.cstr(),comment.cstr());
715                                 }
716                         }
717                 }
718
719                 if (!isIndexTxt(info))
720                         putPopupEntry(pe);
721                 else
722                         delete pe;
723         }
724 }
725 //-----------------------------
726 void    APICALL MyPeercastApp::notifyMessage(ServMgr::NOTIFY_TYPE type, const char *msg)
727 {
728         static bool shownUpgradeAlert=false;
729
730         currNotify = type;
731
732         trayIcon.uFlags = 0;
733
734         if (!shownUpgradeAlert)
735         {
736             trayIcon.uFlags = NIF_ICON;
737
738                 if (type == ServMgr::NT_UPGRADE)
739                 {
740                         shownUpgradeAlert = true;
741                     trayIcon.hIcon = icon2;
742                 }else
743                 {
744                         trayIcon.hIcon = icon1; 
745                 }
746         }else
747         {
748                 if (type == ServMgr::NT_UPGRADE)
749                         return;
750         }
751
752         const char *title="";
753
754         switch(type)
755         {
756                 case ServMgr::NT_UPGRADE:
757                         title = "Upgrade alert";
758                         break;
759                 case ServMgr::NT_PEERCAST:
760                         title = "Message from PeerCast:";
761                         break;
762
763         }
764
765         if (type & peercastInst->getNotifyMask())
766         {
767                 trayIcon.uFlags |= 16;
768         trayIcon.uTimeoutOrVersion = 10000;
769         strncpy(trayIcon.szInfo,msg,sizeof(trayIcon.szInfo)-1);
770                 strncpy(trayIcon.szInfoTitle,title,sizeof(trayIcon.szInfoTitle)-1);
771             Shell_NotifyIcon(NIM_MODIFY, (NOTIFYICONDATA*)&trayIcon);
772         }
773 }
774 //-----------------------------
775
776 // createGUI()
777 //
778 void createGUI(HWND hWnd)
779 {
780         if (!guiWnd){
781                 guiWnd = ::CreateWindow(szWindowClass2,
782                         "Peercast-IM@S",
783                         WS_OVERLAPPEDWINDOW & ~(WS_MAXIMIZEBOX) /*| WS_VSCROLL | WS_HSCROLL*/,
784                         0,
785                         0,
786                         800,
787                         600,
788                         NULL,
789                         NULL,
790                         hInst,
791                         NULL);
792         }
793         ShowWindow(guiWnd,SW_SHOWNORMAL);
794
795         // \8e©\93®\82Å\8dÅ\91O\96Ê
796         if (servMgr->topmostGui)
797         {
798                 ::SetWindowPos(guiWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
799         }
800 }
801
802
803 // 
804 // addRelayedChannelsMenu(HMENU m)
805 // 
806 //
807 void addRelayedChannelsMenu(HMENU cm)
808 {
809         int cnt = GetMenuItemCount(cm);
810         for(int i=0; i<cnt-3; i++)
811                 DeleteMenu(cm,0,MF_BYPOSITION);
812
813         Channel *c = chanMgr->channel;
814         while(c)
815         {
816                 if (c->isActive())
817                 {
818                         char str[128],name[64];
819                         strncpy(name,c->info.name,32);
820                         name[32]=0;
821                         if (strlen(c->info.name) > 32)
822                                 strcat(name,"...");
823
824
825                         sprintf(str,"%s  (%d kb/s %s)",name,c->info.bitrate,ChanInfo::getTypeStr(c->info.contentType));
826                         //InsertMenu(cm,0,MF_BYPOSITION,RELAY_CMD+i,str);
827                 }
828                 c=c->next;
829         }
830 }
831
832 typedef int (*COMPARE_FUNC)(const void *,const void *);
833
834 static int compareHitLists(ChanHitList **c2, ChanHitList **c1)
835 {
836         return stricmp(c1[0]->info.name.cstr(),c2[0]->info.name.cstr());
837 }
838
839 static int compareChannels(Channel **c2, Channel **c1)
840 {
841         return stricmp(c1[0]->info.name.cstr(),c2[0]->info.name.cstr());
842 }
843
844 // 
845 // addAllChannelsMenu(HMENU m)
846 // 
847 //
848 void addAllChannelsMenu(HMENU cm)
849 {
850         int cnt = GetMenuItemCount(cm);
851 /*      for(int i=0; i<cnt-2; i++)
852                 DeleteMenu(cm,0,MF_BYPOSITION);*/
853
854         for(int i=0; i<cnt; i++)
855                 DeleteMenu(cm,0,MF_BYPOSITION);
856
857         HMENU yMenu = CreatePopupMenu();
858         if (!servMgr->rootHost2.isEmpty()){
859                 InsertMenu(yMenu,0,MF_BYPOSITION,ID_POPUP_YELLOWPAGES2,servMgr->rootHost2);
860         }
861         if (!servMgr->rootHost.isEmpty()){
862                 InsertMenu(yMenu,0,MF_BYPOSITION,ID_POPUP_YELLOWPAGES1,servMgr->rootHost);
863         }
864
865         InsertMenu(cm,0,MF_BYPOSITION|MF_POPUP,(UINT)yMenu,"\83C\83G\83\8d\81[\83y\81[\83W");
866         InsertMenu(cm,0,MF_BYPOSITION|MF_SEPARATOR,NULL,NULL);
867         // add channels to menu
868         int numActive=0;
869         Channel *ch = chanMgr->channel;
870         while(ch)
871         {
872                 char str[128],name[64];
873                 String sjis; //JP-Patch
874                 sjis = ch->info.name; //JP-Patch
875                 sjis.convertTo(String::T_SJIS); //JP-Patch
876                 strncpy(name,sjis.cstr(),32);
877                 //strncpy(name,ch->info.name,32);
878                 name[32]=0;
879                 //if (strlen(ch->info.name) > 32)
880                 if (strlen(sjis.cstr()) > 32) //JP-Patch
881                         strcat(name,"...");
882
883                 sprintf(str,"%s  (%d kb/s %s)",name,ch->info.bitrate,ChanInfo::getTypeStr(ch->info.contentType));
884
885                 HMENU opMenu = CreatePopupMenu();
886                 InsertMenu(opMenu,0,MF_BYPOSITION,INFO_CMD+numActive,"Info");
887                 if (ch->info.url.isValidURL())
888                         InsertMenu(opMenu,0,MF_BYPOSITION,URL_CMD+numActive,"URL");
889                 InsertMenu(opMenu,0,MF_BYPOSITION,PLAY_CMD+numActive,"Play");
890
891                 UINT fl = MF_BYPOSITION|MF_POPUP;
892                 if (ch)
893                         fl |= (ch->isPlaying()?MF_CHECKED:0);
894
895                 InsertMenu(cm,0,fl,(UINT)opMenu,str);
896                 
897                 numActive++;
898
899                 ch=ch->next;
900         }
901
902
903         //if (!numActive)
904         //              InsertMenu(cm,0,MF_BYPOSITION,0,"<No channels>");
905
906
907
908
909 }
910
911
912 // 
913 // flipNotifyPopup(id, flag)
914 void flipNotifyPopup(int id, ServMgr::NOTIFY_TYPE nt)
915 {
916         int mask = peercastInst->getNotifyMask();
917
918         mask ^= nt;
919         if (mask & nt)
920                 CheckMenuItem(trayMenu,id,MF_CHECKED|MF_BYCOMMAND);
921         else
922                 CheckMenuItem(trayMenu,id,MF_UNCHECKED|MF_BYCOMMAND);
923
924         peercastInst->setNotifyMask(mask);
925         peercastInst->saveSettings();
926 }
927  
928
929 static void showHTML(const char *file)
930 {
931         char url[256];
932         sprintf(url,"%s/%s",servMgr->htmlPath,file);                                    
933
934 //      sys->callLocalURL(url,servMgr->serverHost.port);
935         sys->callLocalURL(url,  // for PCRaw (url)
936                 (servMgr->allowServer1&Servent::ALLOW_HTML)?(servMgr->serverHost.port):(servMgr->serverHost.port+1));
937 }
938
939 static ChanInfo getChannelInfo(int index)
940 {
941         Channel *c = chanMgr->findChannelByIndex(index);
942         if (c)
943                 return c->info;
944
945         ChanInfo info;
946         return info;
947 }
948
949 //
950 //  FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
951 //
952 //  PURPOSE:  Processes messages for the main window.
953 //
954 //  WM_COMMAND  - process the application menu
955 //  WM_PAINT    - Paint the main window
956 //  WM_DESTROY  - post a quit message and return
957 //
958 //
959 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
960 {
961         int wmId, wmEvent;
962         POINT point;
963         char buf[1024];
964
965         if(message == g_iTaskbarCreated)        // for PCRaw (tray icon)
966                 loadIcons(hInst, hWnd);
967  
968         switch (message) 
969         {
970                 case WM_SHOWGUI:
971                         createGUI(hWnd);
972                         break;
973
974
975                 case WM_TRAYICON:
976                         switch((UINT)lParam) 
977                         {
978                                 case WM_LBUTTONDOWN:
979                                         if (allowTrayMenu)
980                                                 SendMessage(hWnd,WM_SHOWMENU,2,0);
981                                         SetForegroundWindow(hWnd);    
982                                         break;
983                                 case WM_RBUTTONDOWN:
984                                         if (allowTrayMenu)
985                                                 SendMessage(hWnd,WM_SHOWMENU,1,0);
986                                         SetForegroundWindow(hWnd);    
987                                         break;
988                                 case WM_LBUTTONDBLCLK:
989                                         createGUI(hWnd);
990                                         break;
991                         }
992                         break;
993
994                 case WM_COPYDATA:
995                         {
996                                 COPYDATASTRUCT *pc = (COPYDATASTRUCT *)lParam;
997                                 LOG_DEBUG("URL request: %s",pc->lpData);
998                                 if (pc->dwData == WM_PLAYCHANNEL)
999                                 {
1000                                         ChanInfo info;
1001                                         servMgr->procConnectArgs((char *)pc->lpData,info);
1002                                         chanMgr->findAndPlayChannel(info,false);
1003                                 }
1004                                 //sys->callLocalURL((const char *)pc->lpData,servMgr->serverHost.port);
1005                         }
1006                         break;
1007                 case WM_GETPORTNUMBER:
1008                         {
1009                                 int port;
1010                                 port=servMgr->serverHost.port;
1011                                 ReplyMessage(port);
1012                         }
1013                         break;
1014
1015                 case WM_SHOWMENU:
1016                         {
1017                                 if (servMgr->saveGuiPos){
1018                                         CheckMenuItem(trayMenu, ID_POPUP_SAVE_GUI_POS, MF_CHECKED|MF_BYCOMMAND);
1019                                 } else {
1020                                         CheckMenuItem(trayMenu, ID_POPUP_SAVE_GUI_POS, MF_UNCHECKED|MF_BYCOMMAND);
1021                                 }
1022
1023                                 // \8e©\93®GUI/\8dÅ\91O\96Ê\8b@\94\
1024                                 if (servMgr->topmostGui)
1025                                 {
1026                                         CheckMenuItem(trayMenu, ID_POPUP_TOPMOST, MF_CHECKED|MF_BYCOMMAND);
1027                                 } else
1028                                 {
1029                                         CheckMenuItem(trayMenu, ID_POPUP_TOPMOST, MF_UNCHECKED|MF_BYCOMMAND);
1030                                 }
1031
1032                                 if (servMgr->startWithGui)
1033                                 {
1034                                         CheckMenuItem(trayMenu, ID_POPUP_START_WITH_GUI, MF_CHECKED|MF_BYCOMMAND);
1035                                 } else
1036                                 {
1037                                         CheckMenuItem(trayMenu, ID_POPUP_START_WITH_GUI, MF_UNCHECKED|MF_BYCOMMAND);
1038                                 }
1039
1040                                 SetForegroundWindow(hWnd);    
1041                                 bool skipMenu=false;
1042
1043                                 allowTrayMenu = false;
1044
1045                                 // check for notifications
1046                                 if (currNotify & ServMgr::NT_UPGRADE)
1047                                 {
1048                                         if (servMgr->downloadURL[0])
1049                                         {
1050                                                 if ((sys->getTime()-seenNewVersionTime) > (60*60))      // notify every hour
1051                                                 {
1052                                                         if (MessageBox(hWnd,"A newer version of PeerCast is available, press OK to upgrade.","PeerCast",MB_OKCANCEL|MB_APPLMODAL|MB_ICONEXCLAMATION) == IDOK)
1053                                                                 sys->getURL(servMgr->downloadURL);
1054
1055                                                         seenNewVersionTime=sys->getTime();
1056                                                         skipMenu=true;
1057                                                 }
1058                                         }
1059                                 }
1060
1061
1062                                 if (!skipMenu)
1063                                 {
1064                                         RECT rcWnd;
1065                                         HMENU menu;
1066                                         UINT flg = 0;
1067
1068                                         SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWnd, 0);
1069                                         GetCursorPos(&point);
1070
1071                                         if (point.x < rcWnd.left){
1072                                                 point.x = rcWnd.left;
1073                                                 flg |= TPM_LEFTALIGN;
1074                                         }
1075                                         if (point.x > rcWnd.right){
1076                                                 point.x = rcWnd.right;
1077                                                 flg |= TPM_RIGHTALIGN;
1078                                         }
1079                                         if (point.y < rcWnd.top){
1080                                                 point.y = rcWnd.top;
1081                                                 flg |= TPM_TOPALIGN;
1082                                         }
1083                                         if (point.y > rcWnd.bottom){
1084                                                 point.y = rcWnd.bottom;
1085                                                 flg |= TPM_BOTTOMALIGN;
1086                                         }
1087                                         if (flg == 0){
1088                                                 flg = TPM_RIGHTALIGN;
1089                                         }
1090
1091                                         switch (wParam)
1092                                         {
1093                                                 case 1:
1094                                                         menu = GetSubMenu(trayMenu,0);
1095                                                         addAllChannelsMenu(GetSubMenu(menu,0));
1096                                                         addRelayedChannelsMenu(GetSubMenu(menu,1));
1097                                                         break;
1098                                                 case 2:
1099                                                         menu = GetSubMenu(ltrayMenu,0);
1100                                                         addAllChannelsMenu(menu);
1101                                                         break;
1102                                         }
1103                                         if (!TrackPopupMenu(menu,flg,point.x,point.y,0,hWnd,NULL))
1104                                         {
1105                                                 LOG_ERROR("Can`t track popup menu: %d",GetLastError());
1106                                         }
1107                                         PostMessage(hWnd,WM_NULL,0,0); 
1108
1109                                 }
1110                                 allowTrayMenu = true;
1111                         }
1112                         break;
1113
1114                 case WM_CREATE:
1115                         if (showGUI)
1116                                 createGUI(hWnd);
1117                         break;
1118
1119                 case WM_COMMAND:
1120                         wmId    = LOWORD(wParam); 
1121                         wmEvent = HIWORD(wParam); 
1122
1123                         if ((wmId >= INFO_CMD) && (wmId < INFO_CMD+MAX_CHANNELS))
1124                         {
1125                                 int c = wmId - INFO_CMD;
1126                                 chanInfo = getChannelInfo(c);
1127                                 chanInfoIsRelayed = false;
1128                                 if (winDistinctionNT)
1129                                         DialogBox(hInst, (LPCTSTR)IDD_CHANINFO, hWnd, (DLGPROC)ChanInfoProc);
1130                                 else
1131                                 {
1132                                         HWND WKDLG; //JP-Patch
1133                                         WKDLG = CreateDialog(hInst, (LPCTSTR)IDD_CHANINFO, hWnd, (DLGPROC)ChanInfoProc); //JP-Patch
1134                                         ShowWindow(WKDLG,SW_SHOWNORMAL); //JP-Patch
1135                                 }
1136                                 return 0;
1137                         }
1138                         if ((wmId >= URL_CMD) && (wmId < URL_CMD+MAX_CHANNELS))
1139                         {
1140                                 int c = wmId - URL_CMD;
1141                                 chanInfo = getChannelInfo(c);
1142                                 if (chanInfo.url.isValidURL())
1143                                         sys->getURL(chanInfo.url);
1144                                 return 0;
1145                         }
1146                         if ((wmId >= PLAY_CMD) && (wmId < PLAY_CMD+MAX_CHANNELS))
1147                         {
1148                                 int c = wmId - PLAY_CMD;
1149                                 chanInfo = getChannelInfo(c);
1150                                 chanMgr->findAndPlayChannel(chanInfo,false);
1151                                 return 0;
1152                         }
1153                         if ((wmId >= RELAY_CMD) && (wmId < RELAY_CMD+MAX_CHANNELS))
1154                         {
1155                                 int c = wmId - RELAY_CMD;
1156                                 chanInfo = getChannelInfo(c);
1157                                 chanMgr->findAndPlayChannel(chanInfo,true);
1158                                 return 0;
1159                         }
1160
1161                         // Parse the menu selections:
1162                         switch (wmId)
1163                         {
1164                                 case ID_POPUP_SHOWMESSAGES_PEERCAST:
1165                                         flipNotifyPopup(ID_POPUP_SHOWMESSAGES_PEERCAST,ServMgr::NT_PEERCAST);
1166                                         break;
1167                                 case ID_POPUP_SHOWMESSAGES_BROADCASTERS:
1168                                         flipNotifyPopup(ID_POPUP_SHOWMESSAGES_BROADCASTERS,ServMgr::NT_BROADCASTERS);
1169                                         break;
1170                                 case ID_POPUP_SHOWMESSAGES_TRACKINFO:
1171                                         flipNotifyPopup(ID_POPUP_SHOWMESSAGES_TRACKINFO,ServMgr::NT_TRACKINFO);
1172                                         break;
1173
1174                                 case ID_POPUP_ABOUT:
1175                                 case IDM_ABOUT:
1176                                         DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
1177                                         break;
1178                                 case ID_POPUP_SHOWGUI:
1179                                 case IDM_SETTINGS_GUI:
1180                                 case ID_POPUP_ADVANCED_SHOWGUI:
1181                                 {
1182                                         createGUI(hWnd);
1183                                         break;
1184                                 }
1185                                 case ID_POPUP_YELLOWPAGES:
1186                                         sys->getURL("http://yp.peercast.org/");
1187                                         break;
1188                                 case ID_POPUP_YELLOWPAGES1:
1189                                         sprintf(buf, "http://%s",servMgr->rootHost.cstr());
1190                                         sys->getURL(buf);
1191                                         break;
1192                                 case ID_POPUP_YELLOWPAGES2:
1193                                         sprintf(buf, "http://%s",servMgr->rootHost2.cstr());
1194                                         sys->getURL(buf);
1195                                         break;
1196
1197                                 case ID_POPUP_ADVANCED_VIEWLOG:
1198                                         showHTML("viewlog.html");
1199                                         break;
1200                                 case ID_POPUP_ADVANCED_SAVESETTINGS:
1201                                         servMgr->saveSettings(iniFileName.cstr());
1202                                         break;
1203                                 case ID_POPUP_ADVANCED_INFORMATION:
1204                                         showHTML("index.html");
1205                                         break;
1206                                 case ID_FIND_CHANNELS:
1207                                 case ID_POPUP_ADVANCED_ALLCHANNELS:
1208                                 case ID_POPUP_UPGRADE:
1209                                         sys->callLocalURL("admin?cmd=upgrade",servMgr->serverHost.port);
1210                                         break;
1211                                 case ID_POPUP_ADVANCED_RELAYEDCHANNELS:
1212                                 case ID_POPUP_FAVORITES_EDIT:
1213                                         showHTML("relays.html");
1214                                         break;
1215                                 case ID_POPUP_ADVANCED_BROADCAST:
1216                                         showHTML("broadcast.html");
1217                                         break;
1218                                 case ID_POPUP_SETTINGS:
1219                                         showHTML("settings.html");
1220                                         break;
1221                                 case ID_POPUP_CONNECTIONS:
1222                                         showHTML("connections.html");
1223                                         break;
1224                                 case ID_POPUP_HELP:
1225                                         sys->getURL("http://www.peercast.org/help.php");
1226                                         break;
1227
1228                                 case ID_POPUP_SAVE_GUI_POS:
1229                                         if (servMgr->saveGuiPos){
1230                                                 servMgr->saveGuiPos = false;
1231                                                 CheckMenuItem(trayMenu, ID_POPUP_SAVE_GUI_POS, MF_UNCHECKED|MF_BYCOMMAND);
1232                                         } else {
1233                                                 servMgr->saveGuiPos = true;
1234                                                 CheckMenuItem(trayMenu, ID_POPUP_SAVE_GUI_POS, MF_CHECKED|MF_BYCOMMAND);
1235                                         }
1236                                         peercastInst->saveSettings();
1237                                         break;
1238
1239                                 case ID_POPUP_KEEP_DOWNSTREAMS:
1240                                         if (servMgr->keepDownstreams){
1241                                                 servMgr->keepDownstreams = false;
1242                                                 CheckMenuItem(trayMenu, ID_POPUP_KEEP_DOWNSTREAMS, MF_UNCHECKED|MF_BYCOMMAND);
1243                                         } else {
1244                                                 servMgr->keepDownstreams = true;
1245                                                 CheckMenuItem(trayMenu, ID_POPUP_KEEP_DOWNSTREAMS, MF_CHECKED|MF_BYCOMMAND);
1246                                         }
1247                                         //peercastInst->saveSettings();
1248                                         break;
1249
1250                                 case ID_POPUP_TOPMOST:
1251                                         // \8dÅ\91O\96Ê\95\\8e¦
1252                                         if (servMgr->topmostGui)
1253                                         {
1254                                                 servMgr->topmostGui = false;
1255                                                 CheckMenuItem(trayMenu, ID_POPUP_TOPMOST, MF_UNCHECKED|MF_BYCOMMAND);
1256                                         } else
1257                                         {
1258                                                 servMgr->topmostGui = true;
1259                                                 CheckMenuItem(trayMenu, ID_POPUP_TOPMOST, MF_CHECKED|MF_BYCOMMAND);
1260                                         }
1261                                         peercastInst->saveSettings();
1262                                         break;
1263
1264                                 case ID_POPUP_START_WITH_GUI:
1265                                         // \8bN\93®\8e\9e\82ÉGUI\95\\8e¦
1266                                         if (servMgr->startWithGui)
1267                                         {
1268                                                 servMgr->startWithGui = false;
1269                                                 CheckMenuItem(trayMenu, ID_POPUP_START_WITH_GUI, MF_UNCHECKED|MF_BYCOMMAND);
1270                                         } else
1271                                         {
1272                                                 servMgr->startWithGui = true;
1273                                                 CheckMenuItem(trayMenu, ID_POPUP_START_WITH_GUI, MF_CHECKED|MF_BYCOMMAND);
1274                                         }
1275                                         peercastInst->saveSettings();
1276                                         break;
1277
1278                                 case ID_POPUP_TRAFFIC:
1279                                         // \83g\83\89\83t\83B\83b\83N\83\82\83j\83^\8bN\93®
1280                                         if (winDistinctionNT)
1281                                                 DialogBox(hInst, (LPCTSTR)IDD_TRAFFIC, hWnd, (DLGPROC)TrafficDlgProc);
1282                                         else
1283                                         {
1284                                                 HWND WKDLG; //JP-Patch
1285                                                 WKDLG = CreateDialog(hInst, (LPCTSTR)IDD_CHANINFO, hWnd, (DLGPROC)TrafficDlgProc); //JP-Patch
1286                                                 ShowWindow(WKDLG,SW_SHOWNORMAL); //JP-Patch
1287                                         }
1288                                         break;
1289
1290                                 case ID_POPUP_EXIT_CONFIRM:
1291                                 case IDM_EXIT:
1292                                    DestroyWindow(hWnd);
1293                                    break;
1294                                 default:
1295                                    return DefWindowProc(hWnd, message, wParam, lParam);
1296                         }
1297                         break;
1298                 case WM_DESTROY:
1299                         PostQuitMessage(0);
1300                         break;
1301                 default:
1302                         return DefWindowProc(hWnd, message, wParam, lParam);
1303    }
1304    return 0;
1305 }
1306 // Mesage handler for about box.
1307 LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
1308 {
1309         switch (message)
1310         {
1311                 case WM_INITDIALOG:
1312                         //SendDlgItemMessage(hDlg,IDC_ABOUTVER,WM_SETTEXT,0,(LONG)PCX_AGENT);
1313 //                      SendDlgItemMessage(hDlg,IDC_ABOUTVER,WM_SETTEXT,0,(LONG)PCX_AGENTJP);
1314                         if (version_ex)
1315                         {
1316                                 SendDlgItemMessage(hDlg,IDC_ABOUTVER,WM_SETTEXT,0,(LONG)PCX_AGENTEX);
1317                         } else
1318                         {
1319                                 SendDlgItemMessage(hDlg,IDC_ABOUTVER,WM_SETTEXT,0,(LONG)PCX_AGENTVP);
1320                         }
1321
1322                         return TRUE;
1323
1324                 case WM_COMMAND:
1325                         switch (LOWORD(wParam))
1326                         {
1327                                 case IDOK:
1328                                 case IDCANCEL:
1329                                         EndDialog(hDlg, LOWORD(wParam));
1330                                         return TRUE;
1331                                 case IDC_BUTTON1:
1332                                         sys->getURL("http://www.peercast.org");
1333                                         EndDialog(hDlg, LOWORD(wParam));
1334                                         return TRUE;
1335
1336                         }
1337                         break;
1338                 case WM_DESTROY:
1339                         break;
1340         }
1341     return FALSE;
1342 }
1343
1344 // Mesage handler for chaninfo box
1345 LRESULT CALLBACK ChanInfoProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
1346 {
1347         switch (message)
1348         {
1349                 case WM_INITDIALOG:
1350                         {
1351                                 char str[1024];
1352                                 //strcpy(str,chanInfo.track.artist.cstr());
1353                                 strcpy(str,chanInfo.track.artist); //JP-Patch
1354                                 strcat(str," - ");
1355                                 //strcat(str,chanInfo.track.title.cstr());
1356                                 strcat(str,chanInfo.track.title);
1357                                 String name,track,comment,desc,genre; //JP-Patch
1358                                 name = chanInfo.name; //JP-Patch
1359                                 track = str; //JP-Patch
1360                                 comment = chanInfo.comment; //JP-Patch
1361                                 desc = chanInfo.desc; //JP-Patc
1362                                 genre = chanInfo.genre; //JP-Patch
1363                                 name.convertTo(String::T_SJIS); //JP-Patc
1364                                 track.convertTo(String::T_SJIS); //JP-Patch
1365                                 comment.convertTo(String::T_SJIS); //JP-Patch
1366                                 desc.convertTo(String::T_SJIS); //JP-Patch
1367                                 genre.convertTo(String::T_SJIS); //JP-Patch
1368                                 
1369                                 //SendDlgItemMessage(hDlg,IDC_EDIT_NAME,WM_SETTEXT,0,(LONG)chanInfo.name.cstr());
1370                                 SendDlgItemMessage(hDlg,IDC_EDIT_NAME,WM_SETTEXT,0,(LONG)name.cstr()); //JP-Patch
1371                                 //SendDlgItemMessage(hDlg,IDC_EDIT_PLAYING,WM_SETTEXT,0,(LONG)str);
1372                                 SendDlgItemMessage(hDlg,IDC_EDIT_PLAYING,WM_SETTEXT,0,(LONG)track.cstr()); //JP-Patch
1373                                 //SendDlgItemMessage(hDlg,IDC_EDIT_MESSAGE,WM_SETTEXT,0,(LONG)chanInfo.comment.cstr());
1374                                 SendDlgItemMessage(hDlg,IDC_EDIT_MESSAGE,WM_SETTEXT,0,(LONG)comment.cstr()); //JP-Patch
1375                                 //SendDlgItemMessage(hDlg,IDC_EDIT_DESC,WM_SETTEXT,0,(LONG)chanInfo.desc.cstr());
1376                                 SendDlgItemMessage(hDlg,IDC_EDIT_DESC,WM_SETTEXT,0,(LONG)desc.cstr()); //JP-Patch
1377                                 //SendDlgItemMessage(hDlg,IDC_EDIT_GENRE,WM_SETTEXT,0,(LONG)chanInfo.genre.cstr());
1378                                 SendDlgItemMessage(hDlg,IDC_EDIT_GENRE,WM_SETTEXT,0,(LONG)genre.cstr()); //JP-Patch
1379
1380                                 sprintf(str,"%d kb/s %s",chanInfo.bitrate,ChanInfo::getTypeStr(chanInfo.contentType));
1381                                 SendDlgItemMessage(hDlg,IDC_FORMAT,WM_SETTEXT,0,(LONG)str);
1382
1383
1384                                 if (!chanInfo.url.isValidURL())
1385                                         EnableWindow(GetDlgItem(hDlg,IDC_CONTACT),false);
1386
1387                                 Channel *ch = chanMgr->findChannelByID(chanInfo.id);
1388                                 if (ch)
1389                                 {
1390                                         SendDlgItemMessage(hDlg,IDC_EDIT_STATUS,WM_SETTEXT,0,(LONG)ch->getStatusStr());
1391                                         SendDlgItemMessage(hDlg, IDC_KEEP,BM_SETCHECK, ch->stayConnected, 0);
1392
1393                                         // \8c»\8dÝ\82Ì\8cÅ\97L\83\8a\83\8c\81[\8fã\8cÀ\90Ý\92è\82ð\95\\8e¦(0\82Í\96³\8cø)
1394                                         ::SetDlgItemInt(hDlg, IDC_EDIT_MAXRELAYS, ch->maxRelays, false);
1395                                         if (isIndexTxt(ch))
1396                                         {
1397                                                 // index.txt\82È\82Ì\82Å\96³\8cø\82É
1398                                                 ::EnableWindow(::GetDlgItem(hDlg, IDC_EDIT_MAXRELAYS), false);
1399                                                 ::EnableWindow(::GetDlgItem(hDlg, IDC_APPLY_MAXRELAYS), false);
1400                                         }
1401                                 }else
1402                                 {
1403                                         SendDlgItemMessage(hDlg,IDC_EDIT_STATUS,WM_SETTEXT,0,(LONG)"OK");
1404                                         EnableWindow(GetDlgItem(hDlg,IDC_KEEP),false);
1405                                 }
1406
1407
1408
1409                                 POINT point;
1410                                 RECT rect,drect;
1411                                 HWND hDsk = GetDesktopWindow();
1412                                 GetWindowRect(hDsk,&drect);
1413                                 GetWindowRect(hDlg,&rect);
1414                                 GetCursorPos(&point);
1415
1416                                 POINT pos,size;
1417                                 size.x = rect.right-rect.left;
1418                                 size.y = rect.bottom-rect.top;
1419
1420                                 if (point.x-drect.left < size.x)
1421                                         pos.x = point.x;
1422                                 else
1423                                         pos.x = point.x-size.x;
1424
1425                                 if (point.y-drect.top < size.y)
1426                                         pos.y = point.y;
1427                                 else
1428                                         pos.y = point.y-size.y;
1429
1430                                 SetWindowPos(hDlg,HWND_TOPMOST,pos.x,pos.y,size.x,size.y,0);
1431                                 chWnd = hDlg;
1432                         }
1433                         return TRUE;
1434
1435                 case WM_COMMAND:
1436                         {
1437                                 char str[1024],idstr[64];
1438                                 chanInfo.id.toStr(idstr);
1439
1440                                 switch (LOWORD(wParam))
1441                                 {
1442                                 case IDC_CONTACT:
1443                                         {
1444                                                 sys->getURL(chanInfo.url);
1445                                                 return TRUE;
1446                                         }
1447                                 case IDC_DETAILS:
1448                                         {
1449                                                 sprintf(str,"admin?page=chaninfo&id=%s&relay=%d",idstr,chanInfoIsRelayed);
1450                                                 sys->callLocalURL(str,servMgr->serverHost.port);
1451                                                 return TRUE;
1452                                         }
1453                                 case IDC_KEEP:
1454                                         {
1455                                                 Channel *ch = chanMgr->findChannelByID(chanInfo.id);
1456                                                 if (ch)
1457                                                         ch->stayConnected = SendDlgItemMessage(hDlg, IDC_KEEP,BM_GETCHECK, 0, 0) == BST_CHECKED;;
1458                                                 return TRUE;
1459                                         }
1460
1461
1462                                 case IDC_PLAY:
1463                                         {
1464                                                 chanMgr->findAndPlayChannel(chanInfo,false);
1465                                                 return TRUE;
1466                                         }
1467
1468                                 case IDC_APPLY_MAXRELAYS:
1469                                         {
1470                                                 // \83`\83\83\83\93\83l\83\8b\8cÅ\97L\82Ì\8dÅ\91å\83\8a\83\8c\81[\90\94\82ð\90Ý\92è
1471                                                 BOOL bSucc;
1472                                                 unsigned int mr;
1473
1474                                                 // \93ü\97Í\92l\8eæ\93¾
1475                                                 mr = ::GetDlgItemInt(hDlg, IDC_EDIT_MAXRELAYS, &bSucc, false);
1476
1477                                                 if (bSucc)
1478                                                 {
1479                                                         Channel *ch = chanMgr->findChannelByID(chanInfo.id);
1480                                                         if (ch && !isIndexTxt(ch))
1481                                                         {
1482                                                                 ch->maxRelays = mr;
1483                                                         }
1484                                                 } else
1485                                                 {
1486                                                         MessageBox(hDlg, "\93ü\97Í\92l\82ª\95s\90³\82Å\82·\81B", "Error", MB_OK|MB_ICONERROR|MB_APPLMODAL);
1487                                                         Channel *ch = chanMgr->findChannelByID(chanInfo.id);
1488                                                         if (ch)
1489                                                                 ::SetDlgItemInt(hDlg, IDC_EDIT_MAXRELAYS, ch->maxRelays, false);
1490                                                 }
1491                                         }
1492                                 }
1493                         }
1494                         break;
1495
1496                 case WM_CLOSE:
1497                         if (winDistinctionNT)
1498                                 EndDialog(hDlg, 0);
1499                         else
1500                                 DestroyWindow(hDlg); //JP-Patch
1501                         break;
1502
1503                 case WM_ACTIVATE:
1504                         if (LOWORD(wParam) == WA_INACTIVE)
1505                                 if (winDistinctionNT)
1506                                         EndDialog(hDlg, 0);
1507                                 else
1508                                         DestroyWindow(hDlg); //JP-Patch
1509                         break;
1510                 case WM_DESTROY:
1511                         chWnd = NULL;
1512                         break;
1513
1514
1515         }
1516     return FALSE;
1517 }
1518
1519 // control thread (Traffic dialog)
1520 THREAD_PROC trafficDlgUpdate(ThreadInfo *thread)
1521 {
1522         thread->finish = false;
1523
1524         while (trafficDlg && thread->active)
1525         {
1526                 SendMessage(trafficDlg, WM_UPDATETRAFFIC, 0, 0);
1527                 Sleep(1000);
1528         }
1529
1530         thread->finish = true;
1531
1532         return 0;
1533 }
1534
1535 // Dialog procedure (Traffic dialog)
1536 LRESULT CALLBACK TrafficDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
1537 {
1538         switch (message)
1539         {
1540         case WM_INITDIALOG:
1541                 // \8aù\82É\8aJ\82¢\82Ä\82é
1542                 if (trafficDlg || trafficDlgThread.active)
1543                 {
1544                         if (winDistinctionNT)
1545                                 EndDialog(hDlg, 0);
1546                         else
1547                                 DestroyWindow(hDlg);
1548                         return FALSE;
1549                 }
1550
1551                 trafficDlg = hDlg;
1552                 trafficDlgThread.func = trafficDlgUpdate;
1553                 if (!sys->startThread(&trafficDlgThread)){
1554                         MessageBox(NULL,"Unable to start GUI","PeerCast",MB_OK|MB_ICONERROR);
1555                         PostMessage(hDlg,WM_DESTROY,0,0);
1556                 }
1557
1558                 break;
1559
1560         case WM_UPDATETRAFFIC:
1561                 {
1562                         enum unitSymbol { B, KB, MB, GB };
1563                         const unsigned long int unit[] = { 1, 1024, 1024*1024, 1024*1024*1024 };
1564                         char suffix[][3] = { "B", "KB", "MB", "GB" };
1565                         const int bufsize = 60;
1566                         char szUp[bufsize], szDown[bufsize];
1567                         unsigned long long int totalDown = stats.getCurrent(Stats::BYTESIN) - stats.getCurrent(Stats::LOCALBYTESIN);
1568                         unsigned long long int totalUp = stats.getCurrent(Stats::BYTESOUT) - stats.getCurrent(Stats::LOCALBYTESOUT);
1569
1570                         // up
1571                         for (int i=GB; i>0; --i)
1572                         {
1573                                 if (totalUp >= unit[i])
1574                                 {
1575                                         sprintf_s<bufsize>(szUp, "%.2f%s", (double)totalUp/unit[i], suffix[i]);
1576                                         break;
1577                                 }
1578
1579                                 if (i == 1)
1580                                         sprintf_s<bufsize>(szUp, "%d%s", totalUp, suffix[0]);
1581                         }
1582
1583                         // down
1584                         for (int i=GB; i>0; --i)
1585                         {
1586                                 if (totalDown >= unit[i])
1587                                 {
1588                                         sprintf_s<bufsize>(szDown, "%.2f%s", (double)totalDown/unit[i], suffix[i]);
1589                                         break;
1590                                 }
1591
1592                                 if (i == 1)
1593                                         sprintf_s<bufsize>(szDown, "%d%s", totalDown, suffix[0]);
1594                         }
1595
1596                         SetDlgItemText(hDlg, IDC_STATIC_UP, szUp);
1597                         SetDlgItemText(hDlg, IDC_STATIC_DOWN, szDown);
1598                 }
1599                 break;
1600
1601         case WM_CLOSE:
1602                 trafficDlg = NULL;
1603                 trafficDlgThread.active = false;
1604                 if (winDistinctionNT)
1605                         EndDialog(hDlg, 0);
1606                 else
1607                         DestroyWindow(hDlg);
1608
1609                 break;
1610
1611         case WM_DESTROY:
1612                 break;
1613         }
1614
1615         return FALSE;
1616 }