OSDN Git Service

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