OSDN Git Service

5aa8a838a41174513ebe0a98bfa55e98557f9574
[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         __try
412         {
413 #if 0
414 #ifdef _DEBUG
415                 // memory leak check
416                 ::_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
417 #endif
418
419                 char tmpURL[8192];
420                 tmpURL[0]=0;
421                 char *chanURL=NULL;
422
423                 hInst = hInstance;
424
425                 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É
426
427                 iniFileName.set(".\\peercast.ini");
428
429                 WIN32_FIND_DATA fd; //JP-EX
430                 HANDLE hFind; //JP-EX
431
432                 OSVERSIONINFO osInfo; //JP-EX
433                 osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); //JP-EX
434                 GetVersionEx(&osInfo);
435                 if (osInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
436                         winDistinctionNT = true;
437                 else
438                         winDistinctionNT = false;
439
440                 // off by default now
441                 showGUI = false;
442
443                 if (strlen(lpCmdLine) > 0)
444                 {
445                         char *p;
446                         if ((p = strstr(lpCmdLine,"-inifile"))!=NULL) 
447                                 iniFileName.setFromString(p+8);
448
449                         if (strstr(lpCmdLine,"-zen")) 
450                                 showGUI = false;
451
452                         if (strstr(lpCmdLine,"-multi")) 
453                                 allowMulti = true;
454
455                         if (strstr(lpCmdLine,"-kill")) 
456                                 killMe = true;
457
458                         if ((p = strstr(lpCmdLine,"-url"))!=NULL)
459                         {
460                                 p+=4;
461                                 while (*p)
462                                 {
463                                         if (*p=='"')
464                                         {
465                                                 p++;
466                                                 break;
467                                         }                               
468                                         if (*p != ' ')
469                                                 break;
470                                         p++;
471                                 }
472                                 if (*p)
473                                         strncpy(tmpURL,p,sizeof(tmpURL)-1);
474                         }
475                 }
476
477                 // get current path
478                 {
479                         exePath = iniFileName;
480                         char *s = exePath.cstr();
481                         char *end = NULL;
482                         while (*s)
483                         {
484                                 if (*s++ == '\\')
485                                         end = s;
486                         }
487                         if (end)
488                                 *end = 0;
489                 }
490
491
492                 if (strnicmp(tmpURL,"peercast://",11)==0)
493                 {
494                         if (strnicmp(tmpURL+11,"pls/",4)==0)
495                                 chanURL = tmpURL+11+4;
496                         else
497                                 chanURL = tmpURL+11;
498                         showGUI = false;
499                 }
500
501
502                 MSG msg;
503                 HACCEL hAccelTable;
504
505                 // Initialize global strings
506                 //LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
507                 //LoadString(hInstance, IDC_APP_TITLE, szWindowClass, MAX_LOADSTRING);
508
509                 strcpy(szTitle,"PeerCast");
510                 strcpy(szWindowClass,"PeerCast");
511                 strcpy(szWindowClass2,"Main");
512
513                 if (!allowMulti)
514                 {
515                         HANDLE mutex = CreateMutex(NULL,TRUE,szWindowClass);
516
517                         if (GetLastError() == ERROR_ALREADY_EXISTS)
518                         {
519                                 HWND oldWin = FindWindow(szWindowClass,NULL);
520                                 if (oldWin)
521                                 {
522                                         //SendMessage(oldWin,WM_SHOWGUI,0,0);
523                                         if (killMe)
524                                         {
525                                                 SendMessage(oldWin,WM_DESTROY,0,0);
526                                                 return 0;
527                                         }
528
529                                         if (chanURL)
530                                         {
531                                                 COPYDATASTRUCT copy;
532                                                 copy.dwData = WM_PLAYCHANNEL;
533                                                 copy.cbData = strlen(chanURL)+1;                        // plus null term
534                                                 copy.lpData = chanURL;
535                                                 SendMessage(oldWin,WM_COPYDATA,NULL,(LPARAM)&copy);
536                                         }else{
537                                                 if (showGUI)
538                                                         SendMessage(oldWin,WM_SHOWGUI,0,0);
539                                         }
540                                 }
541                                 return 0;
542                         }
543                 }
544
545                 if (killMe)
546                         return 0;
547
548                 MyRegisterClass(hInstance);
549                 MyRegisterClass2(hInstance);
550
551                 // Perform application initialization:
552                 if (!InitInstance (hInstance, nCmdShow)) 
553                         return FALSE;
554
555                 peercastInst = new MyPeercastInst();
556                 peercastApp = new MyPeercastApp();
557
558                 peercastInst->init();
559
560                 LOG_DEBUG("Set OS Type: %s",winDistinctionNT?"WinNT":"Win9x");
561
562                 if (peercastApp->clearTemp()) //JP-EX
563                 {
564                         DeleteFile("play.pls");
565                         hFind = FindFirstFile("*.asx",&fd);
566                         if (hFind != INVALID_HANDLE_VALUE)
567                         {
568                                 do
569                                 {
570                                         DeleteFile((char *)&fd.cFileName);
571                                 }
572                                 while (FindNextFile(hFind,&fd));
573
574                                 FindClose(hFind);
575                         }
576                 }
577
578                 if (chanURL)
579                 {
580                         ChanInfo info;
581                         servMgr->procConnectArgs(chanURL,info);
582                         chanMgr->findAndPlayChannel(info,false);
583                 }
584
585                 hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_SIMPLE);
586
587                 // setup menu notifes
588                 int mask = peercastInst->getNotifyMask();
589                 if (mask & ServMgr::NT_PEERCAST)
590                         CheckMenuItem(trayMenu,ID_POPUP_SHOWMESSAGES_PEERCAST,MF_CHECKED|MF_BYCOMMAND);
591                 if (mask & ServMgr::NT_BROADCASTERS)
592                         CheckMenuItem(trayMenu,ID_POPUP_SHOWMESSAGES_BROADCASTERS,MF_CHECKED|MF_BYCOMMAND);
593                 if (mask & ServMgr::NT_TRACKINFO)
594                         CheckMenuItem(trayMenu,ID_POPUP_SHOWMESSAGES_TRACKINFO,MF_CHECKED|MF_BYCOMMAND);
595
596                 if (servMgr->startWithGui)
597                 {
598                         createGUI((HWND)0);
599                 }
600
601                 // Main message loop:
602                 while (GetMessage(&msg, NULL, 0, 0)) 
603                 {
604                         if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
605                         {
606                                 TranslateMessage(&msg);
607                                 DispatchMessage(&msg);
608                         }
609                 }
610
611                 Shell_NotifyIcon(NIM_DELETE, (NOTIFYICONDATA*)&trayIcon);
612
613                 peercastInst->saveSettings();
614                 peercastInst->quit();
615
616                 Gdiplus::GdiplusShutdown(gdiplusToken);
617
618                 return msg.wParam;
619 #endif
620                 WinMainDummy(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
621
622         } __except(EXCEPTION_EXECUTE_HANDLER)
623         {
624                 fs.openWriteReplace(".\\dump.html");
625                 sys->logBuf->dumpHTML(fs);
626                 fs.close();
627
628                 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"
629                         "\96â\91è\89ð\8c\88\82Ì\82½\82ß\82É\83_\83\93\83v\83f\81[\83^(dump.html)\82ð\92ñ\8b\9f\82µ\82Ä\82­\82¾\82³\82¢\81B", "SEH",
630                         MB_OK|MB_ICONWARNING);
631
632                 return GetExceptionCode();
633         }
634
635         // dummy
636         return 0;
637 }
638
639
640
641 //
642 //  FUNCTION: MyRegisterClass()
643 //
644 //  PURPOSE: Registers the window class.
645 //
646 //  COMMENTS:
647 //
648 //    This function and its usage is only necessary if you want this code
649 //    to be compatible with Win32 systems prior to the 'RegisterClassEx'
650 //    function that was added to Windows 95. It is important to call this function
651 //    so that the application will get 'well formed' small icons associated
652 //    with it.
653 //
654 ATOM MyRegisterClass(HINSTANCE hInstance)
655 {
656         WNDCLASSEX wcex;
657
658         wcex.cbSize = sizeof(WNDCLASSEX); 
659
660         wcex.style                      = CS_HREDRAW | CS_VREDRAW;
661         wcex.lpfnWndProc        = (WNDPROC)WndProc;
662         wcex.cbClsExtra         = 0;
663         wcex.cbWndExtra         = 0;
664         wcex.hInstance          = hInstance;
665         wcex.hIcon                      = LoadIcon(hInstance, (LPCTSTR)IDI_SIMPLE);
666         wcex.hCursor            = LoadCursor(NULL, IDC_ARROW);
667         wcex.hbrBackground      = (HBRUSH)(COLOR_WINDOW+1);
668 //      wcex.lpszMenuName       = (LPCSTR)IDC_SIMPLE;
669         wcex.lpszMenuName       = NULL;
670         wcex.lpszClassName      = szWindowClass;
671         wcex.hIconSm            = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
672
673         return RegisterClassEx(&wcex);
674 }
675
676 ATOM MyRegisterClass2(HINSTANCE hInstance)
677 {
678         WNDCLASSEX wcex;
679         
680         wcex.cbSize = sizeof(WNDCLASSEX); 
681
682         wcex.style                      = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS ;
683         wcex.lpfnWndProc        = (WNDPROC)GUIProc;
684         wcex.cbClsExtra         = 0;
685         wcex.cbWndExtra         = 0;
686         wcex.hInstance          = hInstance;
687         wcex.hIcon                      = LoadIcon(hInstance, (LPCTSTR)IDI_SIMPLE);
688         wcex.hCursor            = LoadCursor(NULL, IDC_ARROW);
689         wcex.hbrBackground      = (HBRUSH)(COLOR_WINDOW+1);
690 //      wcex.lpszMenuName       = (LPCSTR)IDC_SIMPLE;
691         wcex.lpszMenuName       = NULL;
692         wcex.lpszClassName      = szWindowClass2;
693         wcex.hIconSm            = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
694
695         return RegisterClassEx(&wcex);
696 }
697
698 //-----------------------------
699 void loadIcons(HINSTANCE hInstance, HWND hWnd)
700 {
701         icon1 = LoadIcon(hInstance, (LPCTSTR)IDI_SMALL);
702         icon2 = LoadIcon(hInstance, (LPCTSTR)IDI_SMALL2);
703
704     trayIcon.cbSize = sizeof(trayIcon);
705     trayIcon.hWnd = hWnd;
706     trayIcon.uID = 100;
707     trayIcon.uFlags = NIF_MESSAGE + NIF_ICON + NIF_TIP;
708     trayIcon.uCallbackMessage = WM_TRAYICON;
709     trayIcon.hIcon = icon1;
710     strcpy(trayIcon.szTip, "PeerCast");
711
712     Shell_NotifyIcon(NIM_ADD, (NOTIFYICONDATA*)&trayIcon);
713
714     //ShowWindow(hWnd, nCmdShow);
715     UpdateWindow(hWnd);
716
717         if(!trayMenu)   // for PCRaw (tray icon)
718                 trayMenu = LoadMenu(hInstance,MAKEINTRESOURCE(IDR_TRAYMENU));
719         if(!ltrayMenu)  // for PCRaw (tray icon)
720                 ltrayMenu = LoadMenu(hInstance,MAKEINTRESOURCE(IDR_LTRAYMENU));
721
722
723 }
724
725 //-----------------------------
726 //
727 //   FUNCTION: InitInstance(HANDLE, int)
728 //
729 //   PURPOSE: Saves instance handle and creates main window
730 //
731 //   COMMENTS:
732 //
733 //        In this function, we save the instance handle in a global variable and
734 //        create and display the main program window.
735 //
736 BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
737 {
738         HWND hWnd;
739
740         hInst = hInstance; // Store instance handle in our global variable
741
742         hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
743           CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
744
745         if (!hWnd)
746         {
747           return FALSE;
748         }
749
750         mainWnd = hWnd;
751
752         g_iTaskbarCreated = RegisterWindowMessage("TaskbarCreated");    // for PCRaw (tray icon)
753
754         loadIcons(hInstance,hWnd);
755
756         using namespace Gdiplus;
757         GdiplusStartupInput gdiplusStartupInput;
758         GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
759
760         return TRUE;
761 }
762 //-----------------------------
763 //static String trackTitle;
764 //static String channelComment;
765
766 //-----------------------------
767 void channelPopup(const char *title, const char *msg, bool isPopup = true)
768 {
769         String both;
770
771         if (*title == '\0') return;
772         both.append(msg);
773         both.append(" (");
774         both.append(title);
775         both.append(")");
776
777         trayIcon.uFlags = NIF_ICON|NIF_TIP;
778         strncpy(trayIcon.szTip, both.cstr(),sizeof(trayIcon.szTip)-1);
779         trayIcon.szTip[sizeof(trayIcon.szTip)-1]=0;
780
781         if (isPopup) trayIcon.uFlags |= 16;
782         trayIcon.uTimeoutOrVersion = 10000;
783         strncpy(trayIcon.szInfo,msg,sizeof(trayIcon.szInfo)-1);
784         strncpy(trayIcon.szInfoTitle,title,sizeof(trayIcon.szInfoTitle)-1);
785                 
786         Shell_NotifyIcon(NIM_MODIFY, (NOTIFYICONDATA*)&trayIcon);
787 }
788 //-----------------------------
789 void clearChannelPopup()
790 {
791         trayIcon.uFlags = NIF_ICON|16;
792         trayIcon.uTimeoutOrVersion = 10000;
793     strncpy(trayIcon.szInfo,"",sizeof(trayIcon.szInfo)-1);
794         strncpy(trayIcon.szInfoTitle,"",sizeof(trayIcon.szInfoTitle)-1);
795         Shell_NotifyIcon(NIM_MODIFY, (NOTIFYICONDATA*)&trayIcon);
796 }
797
798 //-----------------------------
799 // PopupEntry
800 struct PopupEntry {
801         GnuID id;
802         String name;
803         String track;
804         String comment;
805         PopupEntry *next;
806 };
807 static PopupEntry *PEList = NULL;
808 static WLock PELock;
809
810 static void putPopupEntry(PopupEntry *pe)
811 {
812         PELock.on();
813         pe->next = PEList;
814         PEList = pe;
815         PELock.off();
816 }
817
818 static PopupEntry *getPopupEntry(GnuID id)
819 {
820         PELock.on();
821         PopupEntry *pe = PEList;
822         PopupEntry *prev = NULL;
823         while (pe) {
824                 if (id.isSame(pe->id)) {
825                         if (prev) prev->next = pe->next;
826                         else PEList = pe->next;
827                         PELock.off();
828                         pe->next = NULL;
829                         return pe;
830                 }
831                 prev = pe;
832                 pe = pe->next;
833         }
834         PELock.off();
835         return NULL;
836 }
837
838 static PopupEntry *getTopPopupEntry()
839 {
840         PopupEntry *p = NULL;
841         PELock.on();
842         if (PEList) {
843                 p = PEList;
844                 PEList = PEList->next;
845         }
846         PELock.off();
847         return p;
848 }
849
850 //-----------------------------
851 void    APICALL MyPeercastApp::channelStart(ChanInfo *info)
852 {
853
854 //      lastPlayID = info->id;
855 //
856 //      if(!isIndexTxt(info))   // for PCRaw (popup)
857 //              clearChannelPopup();
858
859         PopupEntry *pe = getPopupEntry(info->id);
860         if (!pe) {
861                 pe = new PopupEntry;
862                 pe->id = info->id;
863         }
864         if (!isIndexTxt(info))
865                 putPopupEntry(pe);
866         else
867                 delete pe;
868 }
869 //-----------------------------
870 void    APICALL MyPeercastApp::channelStop(ChanInfo *info)
871 {
872 //      if (info->id.isSame(lastPlayID))
873 //      {
874 //              lastPlayID.clear();
875 //
876 //              if(!isIndexTxt(info))   // for PCRaw (popup)
877 //                      clearChannelPopup();
878 //      }
879
880         PopupEntry *pe = getPopupEntry(info->id);
881         if (pe) delete pe;
882
883         pe = getTopPopupEntry();
884         if (!pe) {
885                 clearChannelPopup();
886         } else {
887                 if (ServMgr::NT_TRACKINFO & peercastInst->getNotifyMask())
888                 {
889                         String name,track; //JP-Patch
890                         name = pe->name; //JP-Patch
891                         track = pe->track; //JP-Patch
892                         name.convertTo(String::T_SJIS); //JP-Patch
893                         track.convertTo(String::T_SJIS); //JP-Patch
894                         clearChannelPopup();
895                 //      channelPopup(info->name.cstr(),trackTitle.cstr());
896                         channelPopup(name.cstr(),track.cstr(), false); //JP-Patch
897                 }
898                 putPopupEntry(pe);
899         }
900 }
901 //-----------------------------
902 void    APICALL MyPeercastApp::channelUpdate(ChanInfo *info)
903 {
904         if (info)
905         {
906                 PopupEntry *pe = getPopupEntry(info->id);
907                 if (!pe) return;
908
909                 String tmp;
910                 tmp.append(info->track.artist);
911                 tmp.append(" ");
912                 tmp.append(info->track.title);
913
914
915                 if (!tmp.isSame(pe->track))
916                 {
917                         pe->name = info->name;
918                         pe->track = tmp;
919                         if (ServMgr::NT_TRACKINFO & peercastInst->getNotifyMask())
920                         {
921                                 //trackTitle=tmp;
922                                 String name,track; //JP-Patch
923                                 name = info->name; //JP-Patch
924                                 track = tmp; //JP-Patch
925                                 name.convertTo(String::T_SJIS); //JP-Patch
926                                 track.convertTo(String::T_SJIS); //JP-Patch
927                                 if(!isIndexTxt(info))   // for PCRaw (popup)
928                                 {
929                                         clearChannelPopup();
930                                 //      channelPopup(info->name.cstr(),trackTitle.cstr());
931                                         channelPopup(name.cstr(),track.cstr()); //JP-Patch
932                                 }
933                         }
934                 } else if (!info->comment.isSame(pe->comment))
935                 {
936                         pe->name = info->name;
937                         pe->comment = info->comment;
938                         if (ServMgr::NT_BROADCASTERS & peercastInst->getNotifyMask())
939                         {
940                                 //channelComment = info->comment;
941                                 String name,comment; //JP-Patch
942                                 name = info->name; //JP-Patch
943                                 comment = info->comment; //JP-Patch
944                                 name.convertTo(String::T_SJIS); //JP-Patch
945                                 comment.convertTo(String::T_SJIS); //JP-Patch
946                                 if(!isIndexTxt(info))   // for PCRaw (popup)
947                                 {
948                                         clearChannelPopup();
949                                 //      channelPopup(info->name.cstr(),channelComment.cstr());
950                                         channelPopup(name.cstr(),comment.cstr());
951                                 }
952                         }
953                 }
954
955                 if (!isIndexTxt(info))
956                         putPopupEntry(pe);
957                 else
958                         delete pe;
959         }
960 }
961 //-----------------------------
962 void    APICALL MyPeercastApp::notifyMessage(ServMgr::NOTIFY_TYPE type, const char *msg)
963 {
964         static bool shownUpgradeAlert=false;
965
966         currNotify = type;
967
968         trayIcon.uFlags = 0;
969
970         if (!shownUpgradeAlert)
971         {
972             trayIcon.uFlags = NIF_ICON;
973
974                 if (type == ServMgr::NT_UPGRADE)
975                 {
976                         shownUpgradeAlert = true;
977                     trayIcon.hIcon = icon2;
978                 }else
979                 {
980                         trayIcon.hIcon = icon1; 
981                 }
982         }else
983         {
984                 if (type == ServMgr::NT_UPGRADE)
985                         return;
986         }
987
988         const char *title="";
989
990         switch(type)
991         {
992                 case ServMgr::NT_UPGRADE:
993                         title = "Upgrade alert";
994                         break;
995                 case ServMgr::NT_PEERCAST:
996                         title = "Message from PeerCast:";
997                         break;
998
999         }
1000
1001         if (type & peercastInst->getNotifyMask())
1002         {
1003                 trayIcon.uFlags |= 16;
1004         trayIcon.uTimeoutOrVersion = 10000;
1005         strncpy(trayIcon.szInfo,msg,sizeof(trayIcon.szInfo)-1);
1006                 strncpy(trayIcon.szInfoTitle,title,sizeof(trayIcon.szInfoTitle)-1);
1007             Shell_NotifyIcon(NIM_MODIFY, (NOTIFYICONDATA*)&trayIcon);
1008         }
1009 }
1010 //-----------------------------
1011
1012 // createGUI()
1013 //
1014 void createGUI(HWND hWnd)
1015 {
1016         if (!guiWnd){
1017                 guiWnd = ::CreateWindow(szWindowClass2,
1018                         "Peercast-IM@S",
1019                         WS_OVERLAPPEDWINDOW & ~(WS_MAXIMIZEBOX) /*| WS_VSCROLL | WS_HSCROLL*/,
1020                         0,
1021                         0,
1022                         800,
1023                         600,
1024                         NULL,
1025                         NULL,
1026                         hInst,
1027                         NULL);
1028         }
1029         ShowWindow(guiWnd,SW_SHOWNORMAL);
1030
1031         // \8e©\93®\82Å\8dÅ\91O\96Ê
1032         if (servMgr->topmostGui)
1033         {
1034                 ::SetWindowPos(guiWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
1035         }
1036 }
1037
1038
1039 // 
1040 // addRelayedChannelsMenu(HMENU m)
1041 // 
1042 //
1043 void addRelayedChannelsMenu(HMENU cm)
1044 {
1045         int cnt = GetMenuItemCount(cm);
1046         for(int i=0; i<cnt-3; i++)
1047                 DeleteMenu(cm,0,MF_BYPOSITION);
1048
1049         Channel *c = chanMgr->channel;
1050         while(c)
1051         {
1052                 if (c->isActive())
1053                 {
1054                         char str[128],name[64];
1055                         strncpy(name,c->info.name,32);
1056                         name[32]=0;
1057                         if (strlen(c->info.name) > 32)
1058                                 strcat(name,"...");
1059
1060
1061                         sprintf(str,"%s  (%d kb/s %s)",name,c->info.bitrate,ChanInfo::getTypeStr(c->info.contentType));
1062                         //InsertMenu(cm,0,MF_BYPOSITION,RELAY_CMD+i,str);
1063                 }
1064                 c=c->next;
1065         }
1066 }
1067
1068 typedef int (*COMPARE_FUNC)(const void *,const void *);
1069
1070 static int compareHitLists(ChanHitList **c2, ChanHitList **c1)
1071 {
1072         return stricmp(c1[0]->info.name.cstr(),c2[0]->info.name.cstr());
1073 }
1074
1075 static int compareChannels(Channel **c2, Channel **c1)
1076 {
1077         return stricmp(c1[0]->info.name.cstr(),c2[0]->info.name.cstr());
1078 }
1079
1080 // 
1081 // addAllChannelsMenu(HMENU m)
1082 // 
1083 //
1084 void addAllChannelsMenu(HMENU cm)
1085 {
1086         int cnt = GetMenuItemCount(cm);
1087 /*      for(int i=0; i<cnt-2; i++)
1088                 DeleteMenu(cm,0,MF_BYPOSITION);*/
1089
1090         for(int i=0; i<cnt; i++)
1091                 DeleteMenu(cm,0,MF_BYPOSITION);
1092
1093         HMENU yMenu = CreatePopupMenu();
1094         if (!servMgr->rootHost2.isEmpty()){
1095                 InsertMenu(yMenu,0,MF_BYPOSITION,ID_POPUP_YELLOWPAGES2,servMgr->rootHost2);
1096         }
1097         if (!servMgr->rootHost.isEmpty()){
1098                 InsertMenu(yMenu,0,MF_BYPOSITION,ID_POPUP_YELLOWPAGES1,servMgr->rootHost);
1099         }
1100
1101         InsertMenu(cm,0,MF_BYPOSITION|MF_POPUP,(UINT)yMenu,"\83C\83G\83\8d\81[\83y\81[\83W");
1102         InsertMenu(cm,0,MF_BYPOSITION|MF_SEPARATOR,NULL,NULL);
1103         // add channels to menu
1104         int numActive=0;
1105         Channel *ch = chanMgr->channel;
1106         while(ch)
1107         {
1108                 char str[128],name[64];
1109                 String sjis; //JP-Patch
1110                 sjis = ch->info.name; //JP-Patch
1111                 sjis.convertTo(String::T_SJIS); //JP-Patch
1112                 strncpy(name,sjis.cstr(),32);
1113                 //strncpy(name,ch->info.name,32);
1114                 name[32]=0;
1115                 //if (strlen(ch->info.name) > 32)
1116                 if (strlen(sjis.cstr()) > 32) //JP-Patch
1117                         strcat(name,"...");
1118
1119                 sprintf(str,"%s  (%d kb/s %s)",name,ch->info.bitrate,ChanInfo::getTypeStr(ch->info.contentType));
1120
1121                 HMENU opMenu = CreatePopupMenu();
1122                 InsertMenu(opMenu,0,MF_BYPOSITION,INFO_CMD+numActive,"Info");
1123                 if (ch->info.url.isValidURL())
1124                         InsertMenu(opMenu,0,MF_BYPOSITION,URL_CMD+numActive,"URL");
1125                 InsertMenu(opMenu,0,MF_BYPOSITION,PLAY_CMD+numActive,"Play");
1126
1127                 UINT fl = MF_BYPOSITION|MF_POPUP;
1128                 if (ch)
1129                         fl |= (ch->isPlaying()?MF_CHECKED:0);
1130
1131                 InsertMenu(cm,0,fl,(UINT)opMenu,str);
1132                 
1133                 numActive++;
1134
1135                 ch=ch->next;
1136         }
1137
1138
1139         //if (!numActive)
1140         //              InsertMenu(cm,0,MF_BYPOSITION,0,"<No channels>");
1141
1142
1143
1144
1145 }
1146
1147
1148 // 
1149 // flipNotifyPopup(id, flag)
1150 void flipNotifyPopup(int id, ServMgr::NOTIFY_TYPE nt)
1151 {
1152         int mask = peercastInst->getNotifyMask();
1153
1154         mask ^= nt;
1155         if (mask & nt)
1156                 CheckMenuItem(trayMenu,id,MF_CHECKED|MF_BYCOMMAND);
1157         else
1158                 CheckMenuItem(trayMenu,id,MF_UNCHECKED|MF_BYCOMMAND);
1159
1160         peercastInst->setNotifyMask(mask);
1161         peercastInst->saveSettings();
1162 }
1163  
1164
1165 static void showHTML(const char *file)
1166 {
1167         char url[256];
1168         sprintf(url,"%s/%s",servMgr->htmlPath,file);                                    
1169
1170 //      sys->callLocalURL(url,servMgr->serverHost.port);
1171         sys->callLocalURL(url,  // for PCRaw (url)
1172                 (servMgr->allowServer1&Servent::ALLOW_HTML)?(servMgr->serverHost.port):(servMgr->serverHost.port+1));
1173 }
1174
1175 static ChanInfo getChannelInfo(int index)
1176 {
1177         Channel *c = chanMgr->findChannelByIndex(index);
1178         if (c)
1179                 return c->info;
1180
1181         ChanInfo info;
1182         return info;
1183 }
1184
1185 //
1186 //  FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
1187 //
1188 //  PURPOSE:  Processes messages for the main window.
1189 //
1190 //  WM_COMMAND  - process the application menu
1191 //  WM_PAINT    - Paint the main window
1192 //  WM_DESTROY  - post a quit message and return
1193 //
1194 //
1195 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
1196 {
1197         int wmId, wmEvent;
1198         POINT point;
1199         char buf[1024];
1200
1201         if(message == g_iTaskbarCreated)        // for PCRaw (tray icon)
1202                 loadIcons(hInst, hWnd);
1203  
1204         switch (message) 
1205         {
1206                 case WM_SHOWGUI:
1207                         createGUI(hWnd);
1208                         break;
1209
1210
1211                 case WM_TRAYICON:
1212                         switch((UINT)lParam) 
1213                         {
1214                                 case WM_LBUTTONDOWN:
1215                                         if (allowTrayMenu)
1216                                                 SendMessage(hWnd,WM_SHOWMENU,2,0);
1217                                         SetForegroundWindow(hWnd);    
1218                                         break;
1219                                 case WM_RBUTTONDOWN:
1220                                         if (allowTrayMenu)
1221                                                 SendMessage(hWnd,WM_SHOWMENU,1,0);
1222                                         SetForegroundWindow(hWnd);    
1223                                         break;
1224                                 case WM_LBUTTONDBLCLK:
1225                                         createGUI(hWnd);
1226                                         break;
1227                         }
1228                         break;
1229
1230                 case WM_COPYDATA:
1231                         {
1232                                 COPYDATASTRUCT *pc = (COPYDATASTRUCT *)lParam;
1233                                 LOG_DEBUG("URL request: %s",pc->lpData);
1234                                 if (pc->dwData == WM_PLAYCHANNEL)
1235                                 {
1236                                         ChanInfo info;
1237                                         servMgr->procConnectArgs((char *)pc->lpData,info);
1238                                         chanMgr->findAndPlayChannel(info,false);
1239                                 }
1240                                 //sys->callLocalURL((const char *)pc->lpData,servMgr->serverHost.port);
1241                         }
1242                         break;
1243                 case WM_GETPORTNUMBER:
1244                         {
1245                                 int port;
1246                                 port=servMgr->serverHost.port;
1247                                 ReplyMessage(port);
1248                         }
1249                         break;
1250
1251                 case WM_SHOWMENU:
1252                         {
1253                                 if (servMgr->saveGuiPos){
1254                                         CheckMenuItem(trayMenu, ID_POPUP_SAVE_GUI_POS, MF_CHECKED|MF_BYCOMMAND);
1255                                 } else {
1256                                         CheckMenuItem(trayMenu, ID_POPUP_SAVE_GUI_POS, MF_UNCHECKED|MF_BYCOMMAND);
1257                                 }
1258
1259                                 // \8e©\93®GUI/\8dÅ\91O\96Ê\8b@\94\
1260                                 if (servMgr->topmostGui)
1261                                 {
1262                                         CheckMenuItem(trayMenu, ID_POPUP_TOPMOST, MF_CHECKED|MF_BYCOMMAND);
1263                                 } else
1264                                 {
1265                                         CheckMenuItem(trayMenu, ID_POPUP_TOPMOST, MF_UNCHECKED|MF_BYCOMMAND);
1266                                 }
1267
1268                                 if (servMgr->startWithGui)
1269                                 {
1270                                         CheckMenuItem(trayMenu, ID_POPUP_START_WITH_GUI, MF_CHECKED|MF_BYCOMMAND);
1271                                 } else
1272                                 {
1273                                         CheckMenuItem(trayMenu, ID_POPUP_START_WITH_GUI, MF_UNCHECKED|MF_BYCOMMAND);
1274                                 }
1275
1276                                 // \83X\83N\83\8a\81[\83\93\83Z\81[\83o\81[\97}\8e~
1277                                 if (servMgr->preventSS)
1278                                 {
1279                                         CheckMenuItem(trayMenu, ID_POPUP_PREVENT_SS, MF_CHECKED|MF_BYCOMMAND);
1280                                 } else
1281                                 {
1282                                         CheckMenuItem(trayMenu, ID_POPUP_PREVENT_SS, MF_UNCHECKED|MF_BYCOMMAND);
1283                                 }
1284
1285                                 SetForegroundWindow(hWnd);    
1286                                 bool skipMenu=false;
1287
1288                                 allowTrayMenu = false;
1289
1290                                 // check for notifications
1291                                 if (currNotify & ServMgr::NT_UPGRADE)
1292                                 {
1293                                         if (servMgr->downloadURL[0])
1294                                         {
1295                                                 if ((sys->getTime()-seenNewVersionTime) > (60*60))      // notify every hour
1296                                                 {
1297                                                         if (MessageBox(hWnd,"A newer version of PeerCast is available, press OK to upgrade.","PeerCast",MB_OKCANCEL|MB_APPLMODAL|MB_ICONEXCLAMATION) == IDOK)
1298                                                                 sys->getURL(servMgr->downloadURL);
1299
1300                                                         seenNewVersionTime=sys->getTime();
1301                                                         skipMenu=true;
1302                                                 }
1303                                         }
1304                                 }
1305
1306
1307                                 if (!skipMenu)
1308                                 {
1309                                         RECT rcWnd;
1310                                         HMENU menu;
1311                                         UINT flg = 0;
1312
1313                                         SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWnd, 0);
1314                                         GetCursorPos(&point);
1315
1316                                         if (point.x < rcWnd.left){
1317                                                 point.x = rcWnd.left;
1318                                                 flg |= TPM_LEFTALIGN;
1319                                         }
1320                                         if (point.x > rcWnd.right){
1321                                                 point.x = rcWnd.right;
1322                                                 flg |= TPM_RIGHTALIGN;
1323                                         }
1324                                         if (point.y < rcWnd.top){
1325                                                 point.y = rcWnd.top;
1326                                                 flg |= TPM_TOPALIGN;
1327                                         }
1328                                         if (point.y > rcWnd.bottom){
1329                                                 point.y = rcWnd.bottom;
1330                                                 flg |= TPM_BOTTOMALIGN;
1331                                         }
1332                                         if (flg == 0){
1333                                                 flg = TPM_RIGHTALIGN;
1334                                         }
1335
1336                                         switch (wParam)
1337                                         {
1338                                                 case 1:
1339                                                         menu = GetSubMenu(trayMenu,0);
1340                                                         addAllChannelsMenu(GetSubMenu(menu,0));
1341                                                         addRelayedChannelsMenu(GetSubMenu(menu,1));
1342                                                         break;
1343                                                 case 2:
1344                                                         menu = GetSubMenu(ltrayMenu,0);
1345                                                         addAllChannelsMenu(menu);
1346                                                         break;
1347                                         }
1348                                         if (!TrackPopupMenu(menu,flg,point.x,point.y,0,hWnd,NULL))
1349                                         {
1350                                                 LOG_ERROR("Can`t track popup menu: %d",GetLastError());
1351                                         }
1352                                         PostMessage(hWnd,WM_NULL,0,0); 
1353
1354                                 }
1355                                 allowTrayMenu = true;
1356                         }
1357                         break;
1358
1359                 case WM_CREATE:
1360                         if (showGUI)
1361                                 createGUI(hWnd);
1362                         break;
1363
1364                 case WM_COMMAND:
1365                         wmId    = LOWORD(wParam); 
1366                         wmEvent = HIWORD(wParam); 
1367
1368                         if ((wmId >= INFO_CMD) && (wmId < INFO_CMD+MAX_CHANNELS))
1369                         {
1370                                 int c = wmId - INFO_CMD;
1371                                 chanInfo = getChannelInfo(c);
1372                                 chanInfoIsRelayed = false;
1373                                 if (winDistinctionNT)
1374                                         DialogBox(hInst, (LPCTSTR)IDD_CHANINFO, hWnd, (DLGPROC)ChanInfoProc);
1375                                 else
1376                                 {
1377                                         HWND WKDLG; //JP-Patch
1378                                         WKDLG = CreateDialog(hInst, (LPCTSTR)IDD_CHANINFO, hWnd, (DLGPROC)ChanInfoProc); //JP-Patch
1379                                         ShowWindow(WKDLG,SW_SHOWNORMAL); //JP-Patch
1380                                 }
1381                                 return 0;
1382                         }
1383                         if ((wmId >= URL_CMD) && (wmId < URL_CMD+MAX_CHANNELS))
1384                         {
1385                                 int c = wmId - URL_CMD;
1386                                 chanInfo = getChannelInfo(c);
1387                                 if (chanInfo.url.isValidURL())
1388                                         sys->getURL(chanInfo.url);
1389                                 return 0;
1390                         }
1391                         if ((wmId >= PLAY_CMD) && (wmId < PLAY_CMD+MAX_CHANNELS))
1392                         {
1393                                 int c = wmId - PLAY_CMD;
1394                                 chanInfo = getChannelInfo(c);
1395                                 chanMgr->findAndPlayChannel(chanInfo,false);
1396                                 return 0;
1397                         }
1398                         if ((wmId >= RELAY_CMD) && (wmId < RELAY_CMD+MAX_CHANNELS))
1399                         {
1400                                 int c = wmId - RELAY_CMD;
1401                                 chanInfo = getChannelInfo(c);
1402                                 chanMgr->findAndPlayChannel(chanInfo,true);
1403                                 return 0;
1404                         }
1405
1406                         // Parse the menu selections:
1407                         switch (wmId)
1408                         {
1409                                 case ID_POPUP_SHOWMESSAGES_PEERCAST:
1410                                         flipNotifyPopup(ID_POPUP_SHOWMESSAGES_PEERCAST,ServMgr::NT_PEERCAST);
1411                                         break;
1412                                 case ID_POPUP_SHOWMESSAGES_BROADCASTERS:
1413                                         flipNotifyPopup(ID_POPUP_SHOWMESSAGES_BROADCASTERS,ServMgr::NT_BROADCASTERS);
1414                                         break;
1415                                 case ID_POPUP_SHOWMESSAGES_TRACKINFO:
1416                                         flipNotifyPopup(ID_POPUP_SHOWMESSAGES_TRACKINFO,ServMgr::NT_TRACKINFO);
1417                                         break;
1418
1419                                 case ID_POPUP_ABOUT:
1420                                 case IDM_ABOUT:
1421                                         DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
1422                                         break;
1423                                 case ID_POPUP_SHOWGUI:
1424                                 case IDM_SETTINGS_GUI:
1425                                 case ID_POPUP_ADVANCED_SHOWGUI:
1426                                 {
1427                                         createGUI(hWnd);
1428                                         break;
1429                                 }
1430                                 case ID_POPUP_YELLOWPAGES:
1431                                         sys->getURL("http://yp.peercast.org/");
1432                                         break;
1433                                 case ID_POPUP_YELLOWPAGES1:
1434                                         sprintf(buf, "http://%s",servMgr->rootHost.cstr());
1435                                         sys->getURL(buf);
1436                                         break;
1437                                 case ID_POPUP_YELLOWPAGES2:
1438                                         sprintf(buf, "http://%s",servMgr->rootHost2.cstr());
1439                                         sys->getURL(buf);
1440                                         break;
1441
1442                                 case ID_POPUP_ADVANCED_VIEWLOG:
1443                                         showHTML("viewlog.html");
1444                                         break;
1445                                 case ID_POPUP_ADVANCED_SAVESETTINGS:
1446                                         servMgr->saveSettings(iniFileName.cstr());
1447                                         break;
1448                                 case ID_POPUP_ADVANCED_INFORMATION:
1449                                         showHTML("index.html");
1450                                         break;
1451                                 case ID_FIND_CHANNELS:
1452                                 case ID_POPUP_ADVANCED_ALLCHANNELS:
1453                                 case ID_POPUP_UPGRADE:
1454                                         sys->callLocalURL("admin?cmd=upgrade",servMgr->serverHost.port);
1455                                         break;
1456                                 case ID_POPUP_ADVANCED_RELAYEDCHANNELS:
1457                                 case ID_POPUP_FAVORITES_EDIT:
1458                                         showHTML("relays.html");
1459                                         break;
1460                                 case ID_POPUP_ADVANCED_BROADCAST:
1461                                         showHTML("broadcast.html");
1462                                         break;
1463                                 case ID_POPUP_SETTINGS:
1464                                         showHTML("settings.html");
1465                                         break;
1466                                 case ID_POPUP_CONNECTIONS:
1467                                         showHTML("connections.html");
1468                                         break;
1469                                 case ID_POPUP_HELP:
1470                                         sys->getURL("http://www.peercast.org/help.php");
1471                                         break;
1472
1473                                 case ID_POPUP_SAVE_GUI_POS:
1474                                         if (servMgr->saveGuiPos){
1475                                                 servMgr->saveGuiPos = false;
1476                                                 CheckMenuItem(trayMenu, ID_POPUP_SAVE_GUI_POS, MF_UNCHECKED|MF_BYCOMMAND);
1477                                         } else {
1478                                                 servMgr->saveGuiPos = true;
1479                                                 CheckMenuItem(trayMenu, ID_POPUP_SAVE_GUI_POS, MF_CHECKED|MF_BYCOMMAND);
1480                                         }
1481                                         peercastInst->saveSettings();
1482                                         break;
1483
1484                                 case ID_POPUP_KEEP_DOWNSTREAMS:
1485                                         if (servMgr->keepDownstreams){
1486                                                 servMgr->keepDownstreams = false;
1487                                                 CheckMenuItem(trayMenu, ID_POPUP_KEEP_DOWNSTREAMS, MF_UNCHECKED|MF_BYCOMMAND);
1488                                         } else {
1489                                                 servMgr->keepDownstreams = true;
1490                                                 CheckMenuItem(trayMenu, ID_POPUP_KEEP_DOWNSTREAMS, MF_CHECKED|MF_BYCOMMAND);
1491                                         }
1492                                         //peercastInst->saveSettings();
1493                                         break;
1494
1495                                 case ID_POPUP_TOPMOST:
1496                                         // \8dÅ\91O\96Ê\95\\8e¦
1497                                         if (servMgr->topmostGui)
1498                                         {
1499                                                 servMgr->topmostGui = false;
1500                                                 CheckMenuItem(trayMenu, ID_POPUP_TOPMOST, MF_UNCHECKED|MF_BYCOMMAND);
1501                                         } else
1502                                         {
1503                                                 servMgr->topmostGui = true;
1504                                                 CheckMenuItem(trayMenu, ID_POPUP_TOPMOST, MF_CHECKED|MF_BYCOMMAND);
1505                                         }
1506                                         peercastInst->saveSettings();
1507                                         break;
1508
1509                                 case ID_POPUP_START_WITH_GUI:
1510                                         // \8bN\93®\8e\9e\82ÉGUI\95\\8e¦
1511                                         if (servMgr->startWithGui)
1512                                         {
1513                                                 servMgr->startWithGui = false;
1514                                                 CheckMenuItem(trayMenu, ID_POPUP_START_WITH_GUI, MF_UNCHECKED|MF_BYCOMMAND);
1515                                         } else
1516                                         {
1517                                                 servMgr->startWithGui = true;
1518                                                 CheckMenuItem(trayMenu, ID_POPUP_START_WITH_GUI, MF_CHECKED|MF_BYCOMMAND);
1519                                         }
1520                                         peercastInst->saveSettings();
1521                                         break;
1522
1523                                 case ID_POPUP_TRAFFIC:
1524                                         // \83g\83\89\83t\83B\83b\83N\83\82\83j\83^\8bN\93®
1525                                         if (winDistinctionNT)
1526                                                 DialogBox(hInst, (LPCTSTR)IDD_TRAFFIC, hWnd, (DLGPROC)TrafficDlgProc);
1527                                         else
1528                                         {
1529                                                 HWND WKDLG; //JP-Patch
1530                                                 WKDLG = CreateDialog(hInst, (LPCTSTR)IDD_CHANINFO, hWnd, (DLGPROC)TrafficDlgProc); //JP-Patch
1531                                                 ShowWindow(WKDLG,SW_SHOWNORMAL); //JP-Patch
1532                                         }
1533                                         break;
1534
1535                                 case ID_POPUP_PREVENT_SS:
1536                                         // \83X\83N\83\8a\81[\83\93\83Z\81[\83o\81[\97}\8e~
1537                                         if (servMgr->preventSS)
1538                                         {
1539                                                 servMgr->preventSS = false;
1540                                                 CheckMenuItem(trayMenu, ID_POPUP_PREVENT_SS, MF_UNCHECKED|MF_BYCOMMAND);
1541                                         } else
1542                                         {
1543                                                 servMgr->preventSS = true;
1544                                                 CheckMenuItem(trayMenu, ID_POPUP_PREVENT_SS, MF_CHECKED|MF_BYCOMMAND);
1545                                         }
1546                                         peercastInst->saveSettings();
1547                                         break;
1548
1549                                 case ID_POPUP_EXIT_CONFIRM:
1550                                 case IDM_EXIT:
1551                                    DestroyWindow(hWnd);
1552                                    break;
1553                                 default:
1554                                    return DefWindowProc(hWnd, message, wParam, lParam);
1555                         }
1556                         break;
1557                 case WM_DESTROY:
1558                         PostQuitMessage(0);
1559                         break;
1560
1561                 case WM_SYSCOMMAND:
1562                         // \82È\82ñ\82©\83A\83N\83e\83B\83u\82\82á\82È\82¢\82Æ\91\97\82ç\82ê\82Ä\82±\82È\82¢\82ç\82µ\82¢
1563                         if (servMgr->preventSS && (wParam == SC_SCREENSAVE) && chanMgr->isBroadcasting())
1564                                 return 1;
1565                         else
1566                                 return DefWindowProc(hWnd, message, wParam, lParam);
1567                         break;
1568
1569                 default:
1570                         return DefWindowProc(hWnd, message, wParam, lParam);
1571    }
1572    return 0;
1573 }
1574 // Mesage handler for about box.
1575 LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
1576 {
1577         switch (message)
1578         {
1579                 case WM_INITDIALOG:
1580                         //SendDlgItemMessage(hDlg,IDC_ABOUTVER,WM_SETTEXT,0,(LONG)PCX_AGENT);
1581 //                      SendDlgItemMessage(hDlg,IDC_ABOUTVER,WM_SETTEXT,0,(LONG)PCX_AGENTJP);
1582                         if (version_ex)
1583                         {
1584                                 SendDlgItemMessage(hDlg,IDC_ABOUTVER,WM_SETTEXT,0,(LONG)PCX_AGENTEX);
1585                         } else
1586                         {
1587                                 SendDlgItemMessage(hDlg,IDC_ABOUTVER,WM_SETTEXT,0,(LONG)PCX_AGENTVP);
1588                         }
1589
1590                         return TRUE;
1591
1592                 case WM_COMMAND:
1593                         switch (LOWORD(wParam))
1594                         {
1595                                 case IDOK:
1596                                 case IDCANCEL:
1597                                         EndDialog(hDlg, LOWORD(wParam));
1598                                         return TRUE;
1599                                 case IDC_BUTTON1:
1600                                         sys->getURL("http://www.peercast.org");
1601                                         EndDialog(hDlg, LOWORD(wParam));
1602                                         return TRUE;
1603
1604                         }
1605                         break;
1606                 case WM_DESTROY:
1607                         break;
1608         }
1609     return FALSE;
1610 }
1611
1612 // Mesage handler for chaninfo box
1613 LRESULT CALLBACK ChanInfoProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
1614 {
1615         switch (message)
1616         {
1617                 case WM_INITDIALOG:
1618                         {
1619                                 char str[1024];
1620                                 //strcpy(str,chanInfo.track.artist.cstr());
1621                                 strcpy(str,chanInfo.track.artist); //JP-Patch
1622                                 strcat(str," - ");
1623                                 //strcat(str,chanInfo.track.title.cstr());
1624                                 strcat(str,chanInfo.track.title);
1625                                 String name,track,comment,desc,genre; //JP-Patch
1626                                 name = chanInfo.name; //JP-Patch
1627                                 track = str; //JP-Patch
1628                                 comment = chanInfo.comment; //JP-Patch
1629                                 desc = chanInfo.desc; //JP-Patc
1630                                 genre = chanInfo.genre; //JP-Patch
1631                                 name.convertTo(String::T_SJIS); //JP-Patc
1632                                 track.convertTo(String::T_SJIS); //JP-Patch
1633                                 comment.convertTo(String::T_SJIS); //JP-Patch
1634                                 desc.convertTo(String::T_SJIS); //JP-Patch
1635                                 genre.convertTo(String::T_SJIS); //JP-Patch
1636                                 
1637                                 //SendDlgItemMessage(hDlg,IDC_EDIT_NAME,WM_SETTEXT,0,(LONG)chanInfo.name.cstr());
1638                                 SendDlgItemMessage(hDlg,IDC_EDIT_NAME,WM_SETTEXT,0,(LONG)name.cstr()); //JP-Patch
1639                                 //SendDlgItemMessage(hDlg,IDC_EDIT_PLAYING,WM_SETTEXT,0,(LONG)str);
1640                                 SendDlgItemMessage(hDlg,IDC_EDIT_PLAYING,WM_SETTEXT,0,(LONG)track.cstr()); //JP-Patch
1641                                 //SendDlgItemMessage(hDlg,IDC_EDIT_MESSAGE,WM_SETTEXT,0,(LONG)chanInfo.comment.cstr());
1642                                 SendDlgItemMessage(hDlg,IDC_EDIT_MESSAGE,WM_SETTEXT,0,(LONG)comment.cstr()); //JP-Patch
1643                                 //SendDlgItemMessage(hDlg,IDC_EDIT_DESC,WM_SETTEXT,0,(LONG)chanInfo.desc.cstr());
1644                                 SendDlgItemMessage(hDlg,IDC_EDIT_DESC,WM_SETTEXT,0,(LONG)desc.cstr()); //JP-Patch
1645                                 //SendDlgItemMessage(hDlg,IDC_EDIT_GENRE,WM_SETTEXT,0,(LONG)chanInfo.genre.cstr());
1646                                 SendDlgItemMessage(hDlg,IDC_EDIT_GENRE,WM_SETTEXT,0,(LONG)genre.cstr()); //JP-Patch
1647
1648                                 sprintf(str,"%d kb/s %s",chanInfo.bitrate,ChanInfo::getTypeStr(chanInfo.contentType));
1649                                 SendDlgItemMessage(hDlg,IDC_FORMAT,WM_SETTEXT,0,(LONG)str);
1650
1651
1652                                 if (!chanInfo.url.isValidURL())
1653                                         EnableWindow(GetDlgItem(hDlg,IDC_CONTACT),false);
1654
1655                                 Channel *ch = chanMgr->findChannelByID(chanInfo.id);
1656                                 if (ch)
1657                                 {
1658                                         SendDlgItemMessage(hDlg,IDC_EDIT_STATUS,WM_SETTEXT,0,(LONG)ch->getStatusStr());
1659                                         SendDlgItemMessage(hDlg, IDC_KEEP,BM_SETCHECK, ch->stayConnected, 0);
1660
1661                                         // \8c»\8dÝ\82Ì\8cÅ\97L\83\8a\83\8c\81[\8fã\8cÀ\90Ý\92è\82ð\95\\8e¦(0\82Í\96³\8cø)
1662                                         ::SetDlgItemInt(hDlg, IDC_EDIT_MAXRELAYS, ch->maxRelays, false);
1663                                         if (isIndexTxt(ch))
1664                                         {
1665                                                 // index.txt\82È\82Ì\82Å\96³\8cø\82É
1666                                                 ::EnableWindow(::GetDlgItem(hDlg, IDC_EDIT_MAXRELAYS), false);
1667                                                 ::EnableWindow(::GetDlgItem(hDlg, IDC_APPLY_MAXRELAYS), false);
1668                                         }
1669                                 }else
1670                                 {
1671                                         SendDlgItemMessage(hDlg,IDC_EDIT_STATUS,WM_SETTEXT,0,(LONG)"OK");
1672                                         EnableWindow(GetDlgItem(hDlg,IDC_KEEP),false);
1673                                 }
1674
1675
1676
1677                                 POINT point;
1678                                 RECT rect,drect;
1679                                 HWND hDsk = GetDesktopWindow();
1680                                 GetWindowRect(hDsk,&drect);
1681                                 GetWindowRect(hDlg,&rect);
1682                                 GetCursorPos(&point);
1683
1684                                 POINT pos,size;
1685                                 size.x = rect.right-rect.left;
1686                                 size.y = rect.bottom-rect.top;
1687
1688                                 if (point.x-drect.left < size.x)
1689                                         pos.x = point.x;
1690                                 else
1691                                         pos.x = point.x-size.x;
1692
1693                                 if (point.y-drect.top < size.y)
1694                                         pos.y = point.y;
1695                                 else
1696                                         pos.y = point.y-size.y;
1697
1698                                 SetWindowPos(hDlg,HWND_TOPMOST,pos.x,pos.y,size.x,size.y,0);
1699                                 chWnd = hDlg;
1700                         }
1701                         return TRUE;
1702
1703                 case WM_COMMAND:
1704                         {
1705                                 char str[1024],idstr[64];
1706                                 chanInfo.id.toStr(idstr);
1707
1708                                 switch (LOWORD(wParam))
1709                                 {
1710                                 case IDC_CONTACT:
1711                                         {
1712                                                 sys->getURL(chanInfo.url);
1713                                                 return TRUE;
1714                                         }
1715                                 case IDC_DETAILS:
1716                                         {
1717                                                 sprintf(str,"admin?page=chaninfo&id=%s&relay=%d",idstr,chanInfoIsRelayed);
1718                                                 sys->callLocalURL(str,servMgr->serverHost.port);
1719                                                 return TRUE;
1720                                         }
1721                                 case IDC_KEEP:
1722                                         {
1723                                                 Channel *ch = chanMgr->findChannelByID(chanInfo.id);
1724                                                 if (ch)
1725                                                         ch->stayConnected = SendDlgItemMessage(hDlg, IDC_KEEP,BM_GETCHECK, 0, 0) == BST_CHECKED;;
1726                                                 return TRUE;
1727                                         }
1728
1729
1730                                 case IDC_PLAY:
1731                                         {
1732                                                 chanMgr->findAndPlayChannel(chanInfo,false);
1733                                                 return TRUE;
1734                                         }
1735
1736                                 case IDC_APPLY_MAXRELAYS:
1737                                         {
1738                                                 // \83`\83\83\83\93\83l\83\8b\8cÅ\97L\82Ì\8dÅ\91å\83\8a\83\8c\81[\90\94\82ð\90Ý\92è
1739                                                 BOOL bSucc;
1740                                                 unsigned int mr;
1741
1742                                                 // \93ü\97Í\92l\8eæ\93¾
1743                                                 mr = ::GetDlgItemInt(hDlg, IDC_EDIT_MAXRELAYS, &bSucc, false);
1744
1745                                                 if (bSucc)
1746                                                 {
1747                                                         Channel *ch = chanMgr->findChannelByID(chanInfo.id);
1748                                                         if (ch && !isIndexTxt(ch))
1749                                                         {
1750                                                                 ch->maxRelays = mr;
1751                                                         }
1752                                                 } else
1753                                                 {
1754                                                         MessageBox(hDlg, "\93ü\97Í\92l\82ª\95s\90³\82Å\82·\81B", "Error", MB_OK|MB_ICONERROR|MB_APPLMODAL);
1755                                                         Channel *ch = chanMgr->findChannelByID(chanInfo.id);
1756                                                         if (ch)
1757                                                                 ::SetDlgItemInt(hDlg, IDC_EDIT_MAXRELAYS, ch->maxRelays, false);
1758                                                 }
1759                                         }
1760                                 }
1761                         }
1762                         break;
1763
1764                 case WM_CLOSE:
1765                         if (winDistinctionNT)
1766                                 EndDialog(hDlg, 0);
1767                         else
1768                                 DestroyWindow(hDlg); //JP-Patch
1769                         break;
1770
1771                 case WM_ACTIVATE:
1772                         if (LOWORD(wParam) == WA_INACTIVE)
1773                                 if (winDistinctionNT)
1774                                         EndDialog(hDlg, 0);
1775                                 else
1776                                         DestroyWindow(hDlg); //JP-Patch
1777                         break;
1778                 case WM_DESTROY:
1779                         chWnd = NULL;
1780                         break;
1781
1782
1783         }
1784     return FALSE;
1785 }
1786
1787 // control thread (Traffic dialog)
1788 THREAD_PROC trafficDlgUpdate(ThreadInfo *thread)
1789 {
1790         thread->finish = false;
1791
1792         while (trafficDlg && thread->active)
1793         {
1794                 SendMessage(trafficDlg, WM_UPDATETRAFFIC, 0, 0);
1795                 Sleep(1000);
1796         }
1797
1798         thread->finish = true;
1799
1800         return 0;
1801 }
1802
1803 // Dialog procedure (Traffic dialog)
1804 LRESULT CALLBACK TrafficDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
1805 {
1806         switch (message)
1807         {
1808         case WM_INITDIALOG:
1809                 // \8aù\82É\8aJ\82¢\82Ä\82é
1810                 if (trafficDlg || trafficDlgThread.active)
1811                 {
1812                         if (winDistinctionNT)
1813                                 EndDialog(hDlg, 0);
1814                         else
1815                                 DestroyWindow(hDlg);
1816                         return FALSE;
1817                 }
1818
1819                 trafficDlg = hDlg;
1820                 trafficDlgThread.func = trafficDlgUpdate;
1821                 if (!sys->startThread(&trafficDlgThread)){
1822                         MessageBox(NULL,"Unable to start GUI","PeerCast",MB_OK|MB_ICONERROR);
1823                         PostMessage(hDlg,WM_DESTROY,0,0);
1824                 }
1825
1826                 break;
1827
1828         case WM_UPDATETRAFFIC:
1829                 {
1830                         enum unitSymbol { B, KB, MB, GB };
1831                         const unsigned long int unit[] = { 1, 1024, 1024*1024, 1024*1024*1024 };
1832                         char suffix[][3] = { "B", "KB", "MB", "GB" };
1833                         const int bufsize = 60;
1834                         char szUp[bufsize], szDown[bufsize];
1835                         unsigned long long int totalDown = stats.getCurrent(Stats::BYTESIN) - stats.getCurrent(Stats::LOCALBYTESIN);
1836                         unsigned long long int totalUp = stats.getCurrent(Stats::BYTESOUT) - stats.getCurrent(Stats::LOCALBYTESOUT);
1837
1838                         // up
1839                         for (int i=GB; i>0; --i)
1840                         {
1841                                 if (totalUp >= unit[i])
1842                                 {
1843                                         sprintf_s<bufsize>(szUp, "%.2f%s", (double)totalUp/unit[i], suffix[i]);
1844                                         break;
1845                                 }
1846
1847                                 if (i == 1)
1848                                         sprintf_s<bufsize>(szUp, "%d%s", totalUp, suffix[0]);
1849                         }
1850
1851                         // down
1852                         for (int i=GB; i>0; --i)
1853                         {
1854                                 if (totalDown >= unit[i])
1855                                 {
1856                                         sprintf_s<bufsize>(szDown, "%.2f%s", (double)totalDown/unit[i], suffix[i]);
1857                                         break;
1858                                 }
1859
1860                                 if (i == 1)
1861                                         sprintf_s<bufsize>(szDown, "%d%s", totalDown, suffix[0]);
1862                         }
1863
1864                         SetDlgItemText(hDlg, IDC_STATIC_UP, szUp);
1865                         SetDlgItemText(hDlg, IDC_STATIC_DOWN, szDown);
1866                 }
1867                 break;
1868
1869         case WM_CLOSE:
1870                 trafficDlg = NULL;
1871                 trafficDlgThread.active = false;
1872                 if (winDistinctionNT)
1873                         EndDialog(hDlg, 0);
1874                 else
1875                         DestroyWindow(hDlg);
1876
1877                 break;
1878
1879         case WM_DESTROY:
1880                 break;
1881         }
1882
1883         return FALSE;
1884 }