OSDN Git Service

Vss2Git
[peercast-im/PeerCastIM.git] / c: / Git / PeerCast.root / PeerCast / ui / win32 / Simple_vp / 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 #ifdef _DEBUG
34 #include "chkMemoryLeak.h"
35 #define DEBUG_NEW new(__FILE__, __LINE__)
36 #define new DEBUG_NEW
37 #endif
38
39 #define MAX_LOADSTRING 100
40
41 #define PLAY_CMD 7000
42 #define RELAY_CMD 8000
43 #define INFO_CMD 9000
44 #define URL_CMD 10000
45
46 #define MAX_CHANNELS 999
47
48 extern "C"
49 {
50         void loadIcons(HINSTANCE hInstance, HWND hWnd);
51 };
52
53 UINT g_iTaskbarCreated = ~0;    // for PCRaw (tray icon)
54
55 // PeerCast globals
56
57 static int currNotify=0;
58 String iniFileName;
59 HWND guiWnd;
60 HWND mainWnd;
61 static HMENU trayMenu = NULL,ltrayMenu = NULL;  // for PCRaw (tray icon)
62 bool showGUI=true;
63 bool allowMulti=false;
64 bool killMe=false;
65 bool allowTrayMenu=true;
66 static bool winDistinctionNT=false;
67 int             seenNewVersionTime=0;
68 HICON icon1,icon2;
69 ChanInfo chanInfo;
70 bool chanInfoIsRelayed;
71 //GnuID lastPlayID;
72 String exePath;
73 FileStream fs;
74
75 // ---------------------------------
76 Sys * APICALL MyPeercastInst::createSys()
77 {
78         return new WSys(mainWnd);
79 }
80 // ---------------------------------
81 const char * APICALL MyPeercastApp ::getIniFilename()
82 {
83         return iniFileName.cstr();
84 }
85
86 // ---------------------------------
87 const char *APICALL MyPeercastApp ::getClientTypeOS() 
88 {
89         return PCX_OS_WIN32;
90 }
91
92 // ---------------------------------
93 const char * APICALL MyPeercastApp::getPath()
94 {
95         return exePath.cstr();
96 }
97
98 // --------------------------------- JP-EX
99 void    APICALL MyPeercastApp ::openLogFile()
100 {
101         logFile.openWriteReplace("log.txt");
102 }
103 // --------------------------------- JP-EX
104 void    APICALL MyPeercastApp ::getDirectory()
105 {
106         char path_buffer[256],drive[32],dir[128];
107         GetModuleFileName(NULL,path_buffer,255);
108         _splitpath(path_buffer,drive,dir,NULL,NULL);
109         sprintf(servMgr->modulePath,"%s%s",drive,dir);
110 }
111 // --------------------------------- JP-EX
112 bool    APICALL MyPeercastApp ::clearTemp()
113 {
114         if (servMgr->clearPLS)
115                 return true;
116
117         return false;
118 }
119
120
121 class NOTIFYICONDATA2
122 {
123 public:
124         DWORD cbSize; // DWORD
125         HWND hWnd; // HWND
126         UINT uID; // UINT
127         UINT uFlags; // UINT
128         UINT uCallbackMessage; // UINT
129         HICON hIcon; // HICON
130         char szTip[128]; // char[128]
131         DWORD dwState; // DWORD
132         DWORD dwStateMask; // DWORD
133         char szInfo[256]; // char[256]
134         UINT uTimeoutOrVersion; // UINT
135         char szInfoTitle[64]; // char[64]
136         DWORD dwInfoFlags; // DWORD
137         //GUID guidItem; > IE 6
138 };
139
140 NOTIFYICONDATA2 trayIcon;
141
142
143 // Global Variables:
144 HINSTANCE hInst;                                                                // current instance
145 TCHAR szTitle[MAX_LOADSTRING];                                                          // The title bar text
146 TCHAR szWindowClass[MAX_LOADSTRING];                                                            // The title bar text
147
148 // Foward declarations of functions included in this code module:
149 ATOM                            MyRegisterClass(HINSTANCE hInstance);
150 BOOL                            InitInstance(HINSTANCE, int);
151 LRESULT CALLBACK        WndProc(HWND, UINT, WPARAM, LPARAM);
152 LRESULT CALLBACK        About(HWND, UINT, WPARAM, LPARAM);
153 LRESULT CALLBACK        ChanInfoProc(HWND, UINT, WPARAM, LPARAM);
154
155 void setTrayIcon(int type, const char *,const char *,bool);
156 void flipNotifyPopup(int id, ServMgr::NOTIFY_TYPE nt);
157
158
159 HWND chWnd=NULL;
160
161 // --------------------------------------------------
162 void LOG2(const char *fmt,...)
163 {
164         va_list ap;
165         va_start(ap, fmt);
166         char str[4096];
167         vsprintf(str,fmt,ap);
168         OutputDebugString(str);
169         va_end(ap);     
170 }
171
172
173
174 // ---------------------------------------
175
176 int APIENTRY WinMain(HINSTANCE hInstance,
177                      HINSTANCE hPrevInstance,
178                      LPSTR     lpCmdLine,
179                      int       nCmdShow)
180 {
181 #ifdef _DEBUG
182         // memory leak check
183         ::_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
184 #endif
185
186         char tmpURL[8192];
187         tmpURL[0]=0;
188         char *chanURL=NULL;
189
190         //VERSION_EX = 0;
191
192         iniFileName.set(".\\peercast.ini");
193
194         WIN32_FIND_DATA fd; //JP-EX
195         HANDLE hFind; //JP-EX
196
197         OSVERSIONINFO osInfo; //JP-EX
198         osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); //JP-EX
199         GetVersionEx(&osInfo);
200         if (osInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
201                 winDistinctionNT = true;
202         else
203                 winDistinctionNT = false;
204
205         // off by default now
206         showGUI = false;
207
208         if (strlen(lpCmdLine) > 0)
209         {
210                 char *p;
211                 if ((p = strstr(lpCmdLine,"-inifile"))!=NULL) 
212                         iniFileName.setFromString(p+8);
213
214                 if (strstr(lpCmdLine,"-zen")) 
215                         showGUI = false;
216
217                 if (strstr(lpCmdLine,"-multi")) 
218                         allowMulti = true;
219
220                 if (strstr(lpCmdLine,"-kill")) 
221                         killMe = true;
222
223                 if ((p = strstr(lpCmdLine,"-url"))!=NULL)
224                 {
225                         p+=4;
226                         while (*p)
227                         {
228                                 if (*p=='"')
229                                 {
230                                         p++;
231                                         break;
232                                 }                               
233                                 if (*p != ' ')
234                                         break;
235                                 p++;
236                         }
237                         if (*p)
238                                 strncpy(tmpURL,p,sizeof(tmpURL)-1);
239                 }
240         }
241
242         // get current path
243         {
244                 exePath = iniFileName;
245                 char *s = exePath.cstr();
246                 char *end = NULL;
247                 while (*s)
248                 {
249                         if (*s++ == '\\')
250                                 end = s;
251                 }
252                 if (end)
253                         *end = 0;
254         }
255
256         
257         if (strnicmp(tmpURL,"peercast://",11)==0)
258         {
259                 if (strnicmp(tmpURL+11,"pls/",4)==0)
260                         chanURL = tmpURL+11+4;
261                 else
262                         chanURL = tmpURL+11;
263                 showGUI = false;
264         }
265
266
267         MSG msg;
268         HACCEL hAccelTable;
269
270         // Initialize global strings
271         //LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
272         //LoadString(hInstance, IDC_APP_TITLE, szWindowClass, MAX_LOADSTRING);
273
274         strcpy(szTitle,"PeerCast");
275         strcpy(szWindowClass,"PeerCast");
276
277         if (!allowMulti)
278         {
279                 HANDLE mutex = CreateMutex(NULL,TRUE,szWindowClass);
280                 
281                 if (GetLastError() == ERROR_ALREADY_EXISTS)
282                 {
283                         HWND oldWin = FindWindow(szWindowClass,NULL);
284                         if (oldWin)
285                         {
286                                 if (killMe)
287                                 {
288                                         SendMessage(oldWin,WM_DESTROY,0,0);
289                                         return 0;
290                                 }
291
292                                 if (chanURL)
293                                 {
294                                         COPYDATASTRUCT copy;
295                                         copy.dwData = WM_PLAYCHANNEL;
296                                         copy.cbData = strlen(chanURL)+1;                        // plus null term
297                                         copy.lpData = chanURL;
298                                         SendMessage(oldWin,WM_COPYDATA,NULL,(LPARAM)&copy);
299                                 }else{
300                                         if (showGUI)
301                                                 SendMessage(oldWin,WM_SHOWGUI,0,0);
302                                 }
303                         }
304                         return 0;
305                 }
306         }
307
308         if (killMe)
309                 return 0;
310         
311         MyRegisterClass(hInstance);
312
313         // Perform application initialization:
314         if (!InitInstance (hInstance, nCmdShow)) 
315                 return FALSE;
316
317         peercastInst = new MyPeercastInst();
318         peercastApp = new MyPeercastApp();
319
320         peercastInst->init();
321
322         LOG_DEBUG("Set OS Type: %s",winDistinctionNT?"WinNT":"Win9x");
323
324         if (peercastApp->clearTemp()) //JP-EX
325         {
326                 DeleteFile("play.pls");
327                 hFind = FindFirstFile("*.asx",&fd);
328                 if (hFind != INVALID_HANDLE_VALUE)
329                 {
330                         do
331                         {
332                                 DeleteFile((char *)&fd.cFileName);
333                         }
334                         while (FindNextFile(hFind,&fd));
335
336                         FindClose(hFind);
337                 }
338         }
339
340         if (chanURL)
341         {
342                 ChanInfo info;
343                 servMgr->procConnectArgs(chanURL,info);
344                 chanMgr->findAndPlayChannel(info,false);
345         }
346
347
348         hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_SIMPLE);
349
350         // setup menu notifes
351         int mask = peercastInst->getNotifyMask();
352         if (mask & ServMgr::NT_PEERCAST)
353                 CheckMenuItem(trayMenu,ID_POPUP_SHOWMESSAGES_PEERCAST,MF_CHECKED|MF_BYCOMMAND);
354         if (mask & ServMgr::NT_BROADCASTERS)
355                 CheckMenuItem(trayMenu,ID_POPUP_SHOWMESSAGES_BROADCASTERS,MF_CHECKED|MF_BYCOMMAND);
356         if (mask & ServMgr::NT_TRACKINFO)
357                 CheckMenuItem(trayMenu,ID_POPUP_SHOWMESSAGES_TRACKINFO,MF_CHECKED|MF_BYCOMMAND);
358
359         // Main message loop:
360         while (GetMessage(&msg, NULL, 0, 0)) 
361         {
362                 if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
363                 {
364                         TranslateMessage(&msg);
365                         DispatchMessage(&msg);
366                 }
367         }
368
369     Shell_NotifyIcon(NIM_DELETE, (NOTIFYICONDATA*)&trayIcon);
370
371         peercastInst->saveSettings();
372         peercastInst->quit();
373
374         return msg.wParam;
375 }
376
377
378
379 //
380 //  FUNCTION: MyRegisterClass()
381 //
382 //  PURPOSE: Registers the window class.
383 //
384 //  COMMENTS:
385 //
386 //    This function and its usage is only necessary if you want this code
387 //    to be compatible with Win32 systems prior to the 'RegisterClassEx'
388 //    function that was added to Windows 95. It is important to call this function
389 //    so that the application will get 'well formed' small icons associated
390 //    with it.
391 //
392 ATOM MyRegisterClass(HINSTANCE hInstance)
393 {
394         WNDCLASSEX wcex;
395
396         wcex.cbSize = sizeof(WNDCLASSEX); 
397
398         wcex.style                      = CS_HREDRAW | CS_VREDRAW;
399         wcex.lpfnWndProc        = (WNDPROC)WndProc;
400         wcex.cbClsExtra         = 0;
401         wcex.cbWndExtra         = 0;
402         wcex.hInstance          = hInstance;
403         wcex.hIcon                      = LoadIcon(hInstance, (LPCTSTR)IDI_SIMPLE);
404         wcex.hCursor            = LoadCursor(NULL, IDC_ARROW);
405         wcex.hbrBackground      = (HBRUSH)(COLOR_WINDOW+1);
406         wcex.lpszMenuName       = (LPCSTR)IDC_SIMPLE;
407         wcex.lpszClassName      = szWindowClass;
408         wcex.hIconSm            = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
409
410         return RegisterClassEx(&wcex);
411
412 }
413
414 //-----------------------------
415 void loadIcons(HINSTANCE hInstance, HWND hWnd)
416 {
417         icon1 = LoadIcon(hInstance, (LPCTSTR)IDI_SMALL);
418         icon2 = LoadIcon(hInstance, (LPCTSTR)IDI_SMALL2);
419
420     trayIcon.cbSize = sizeof(trayIcon);
421     trayIcon.hWnd = hWnd;
422     trayIcon.uID = 100;
423     trayIcon.uFlags = NIF_MESSAGE + NIF_ICON + NIF_TIP;
424     trayIcon.uCallbackMessage = WM_TRAYICON;
425     trayIcon.hIcon = icon1;
426     strcpy(trayIcon.szTip, "PeerCast");
427
428     Shell_NotifyIcon(NIM_ADD, (NOTIFYICONDATA*)&trayIcon);
429
430     //ShowWindow(hWnd, nCmdShow);
431     UpdateWindow(hWnd);
432
433         if(!trayMenu)   // for PCRaw (tray icon)
434                 trayMenu = LoadMenu(hInstance,MAKEINTRESOURCE(IDR_TRAYMENU));
435         if(!ltrayMenu)  // for PCRaw (tray icon)
436                 ltrayMenu = LoadMenu(hInstance,MAKEINTRESOURCE(IDR_LTRAYMENU));
437
438
439 }
440
441 //-----------------------------
442 //
443 //   FUNCTION: InitInstance(HANDLE, int)
444 //
445 //   PURPOSE: Saves instance handle and creates main window
446 //
447 //   COMMENTS:
448 //
449 //        In this function, we save the instance handle in a global variable and
450 //        create and display the main program window.
451 //
452 BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
453 {
454         HWND hWnd;
455
456         hInst = hInstance; // Store instance handle in our global variable
457
458         hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
459           CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
460
461         if (!hWnd)
462         {
463           return FALSE;
464         }
465
466         mainWnd = hWnd;
467
468         g_iTaskbarCreated = RegisterWindowMessage("TaskbarCreated");    // for PCRaw (tray icon)
469
470         loadIcons(hInstance,hWnd);
471
472         return TRUE;
473 }
474 //-----------------------------
475 //static String trackTitle;
476 //static String channelComment;
477
478 //-----------------------------
479 void channelPopup(const char *title, const char *msg, bool isPopup = true)
480 {
481         String both;
482
483         if (*title == '\0') return;
484         both.append(msg);
485         both.append(" (");
486         both.append(title);
487         both.append(")");
488
489         trayIcon.uFlags = NIF_ICON|NIF_TIP;
490         strncpy(trayIcon.szTip, both.cstr(),sizeof(trayIcon.szTip)-1);
491         trayIcon.szTip[sizeof(trayIcon.szTip)-1]=0;
492
493         if (isPopup) trayIcon.uFlags |= 16;
494         trayIcon.uTimeoutOrVersion = 10000;
495         strncpy(trayIcon.szInfo,msg,sizeof(trayIcon.szInfo)-1);
496         strncpy(trayIcon.szInfoTitle,title,sizeof(trayIcon.szInfoTitle)-1);
497                 
498         Shell_NotifyIcon(NIM_MODIFY, (NOTIFYICONDATA*)&trayIcon);
499 }
500 //-----------------------------
501 void clearChannelPopup()
502 {
503         trayIcon.uFlags = NIF_ICON|16;
504         trayIcon.uTimeoutOrVersion = 10000;
505     strncpy(trayIcon.szInfo,"",sizeof(trayIcon.szInfo)-1);
506         strncpy(trayIcon.szInfoTitle,"",sizeof(trayIcon.szInfoTitle)-1);
507         Shell_NotifyIcon(NIM_MODIFY, (NOTIFYICONDATA*)&trayIcon);
508 }
509
510 //-----------------------------
511 // PopupEntry
512 struct PopupEntry {
513         GnuID id;
514         String name;
515         String track;
516         String comment;
517         PopupEntry *next;
518 };
519 static PopupEntry *PEList = NULL;
520 static WLock PELock;
521
522 static void putPopupEntry(PopupEntry *pe)
523 {
524         PELock.on();
525         pe->next = PEList;
526         PEList = pe;
527         PELock.off();
528 }
529
530 static PopupEntry *getPopupEntry(GnuID id)
531 {
532         PELock.on();
533         PopupEntry *pe = PEList;
534         PopupEntry *prev = NULL;
535         while (pe) {
536                 if (id.isSame(pe->id)) {
537                         if (prev) prev->next = pe->next;
538                         else PEList = pe->next;
539                         PELock.off();
540                         pe->next = NULL;
541                         return pe;
542                 }
543                 prev = pe;
544                 pe = pe->next;
545         }
546         PELock.off();
547         return NULL;
548 }
549
550 static PopupEntry *getTopPopupEntry()
551 {
552         PopupEntry *p = NULL;
553         PELock.on();
554         if (PEList) {
555                 p = PEList;
556                 PEList = PEList->next;
557         }
558         PELock.off();
559         return p;
560 }
561
562 //-----------------------------
563 void    APICALL MyPeercastApp::channelStart(ChanInfo *info)
564 {
565
566 //      lastPlayID = info->id;
567 //
568 //      if(!isIndexTxt(info))   // for PCRaw (popup)
569 //              clearChannelPopup();
570
571         PopupEntry *pe = getPopupEntry(info->id);
572         if (!pe) {
573                 pe = new PopupEntry;
574                 pe->id = info->id;
575         }
576         if (!isIndexTxt(info))
577                 putPopupEntry(pe);
578         else
579                 delete pe;
580 }
581 //-----------------------------
582 void    APICALL MyPeercastApp::channelStop(ChanInfo *info)
583 {
584 //      if (info->id.isSame(lastPlayID))
585 //      {
586 //              lastPlayID.clear();
587 //
588 //              if(!isIndexTxt(info))   // for PCRaw (popup)
589 //                      clearChannelPopup();
590 //      }
591
592         PopupEntry *pe = getPopupEntry(info->id);
593         if (pe) delete pe;
594
595         pe = getTopPopupEntry();
596         if (!pe) {
597                 clearChannelPopup();
598         } else {
599                 if (ServMgr::NT_TRACKINFO & peercastInst->getNotifyMask())
600                 {
601                         String name,track; //JP-Patch
602                         name = pe->name; //JP-Patch
603                         track = pe->track; //JP-Patch
604                         name.convertTo(String::T_SJIS); //JP-Patch
605                         track.convertTo(String::T_SJIS); //JP-Patch
606                         clearChannelPopup();
607                 //      channelPopup(info->name.cstr(),trackTitle.cstr());
608                         channelPopup(name.cstr(),track.cstr(), false); //JP-Patch
609                 }
610                 putPopupEntry(pe);
611         }
612 }
613 //-----------------------------
614 void    APICALL MyPeercastApp::channelUpdate(ChanInfo *info)
615 {
616         if (info)
617         {
618                 PopupEntry *pe = getPopupEntry(info->id);
619                 if (!pe) return;
620
621                 String tmp;
622                 tmp.append(info->track.artist);
623                 tmp.append(" ");
624                 tmp.append(info->track.title);
625
626
627                 if (!tmp.isSame(pe->track))
628                 {
629                         pe->name = info->name;
630                         pe->track = tmp;
631                         if (ServMgr::NT_TRACKINFO & peercastInst->getNotifyMask())
632                         {
633                                 //trackTitle=tmp;
634                                 String name,track; //JP-Patch
635                                 name = info->name; //JP-Patch
636                                 track = tmp; //JP-Patch
637                                 name.convertTo(String::T_SJIS); //JP-Patch
638                                 track.convertTo(String::T_SJIS); //JP-Patch
639                                 if(!isIndexTxt(info))   // for PCRaw (popup)
640                                 {
641                                         clearChannelPopup();
642                                 //      channelPopup(info->name.cstr(),trackTitle.cstr());
643                                         channelPopup(name.cstr(),track.cstr()); //JP-Patch
644                                 }
645                         }
646                 } else if (!info->comment.isSame(pe->comment))
647                 {
648                         pe->name = info->name;
649                         pe->comment = info->comment;
650                         if (ServMgr::NT_BROADCASTERS & peercastInst->getNotifyMask())
651                         {
652                                 //channelComment = info->comment;
653                                 String name,comment; //JP-Patch
654                                 name = info->name; //JP-Patch
655                                 comment = info->comment; //JP-Patch
656                                 name.convertTo(String::T_SJIS); //JP-Patch
657                                 comment.convertTo(String::T_SJIS); //JP-Patch
658                                 if(!isIndexTxt(info))   // for PCRaw (popup)
659                                 {
660                                         clearChannelPopup();
661                                 //      channelPopup(info->name.cstr(),channelComment.cstr());
662                                         channelPopup(name.cstr(),comment.cstr());
663                                 }
664                         }
665                 }
666
667                 if (!isIndexTxt(info))
668                         putPopupEntry(pe);
669                 else
670                         delete pe;
671         }
672 }
673 //-----------------------------
674 void    APICALL MyPeercastApp::notifyMessage(ServMgr::NOTIFY_TYPE type, const char *msg)
675 {
676         static bool shownUpgradeAlert=false;
677
678         currNotify = type;
679
680         trayIcon.uFlags = 0;
681
682         if (!shownUpgradeAlert)
683         {
684             trayIcon.uFlags = NIF_ICON;
685
686                 if (type == ServMgr::NT_UPGRADE)
687                 {
688                         shownUpgradeAlert = true;
689                     trayIcon.hIcon = icon2;
690                 }else
691                 {
692                         trayIcon.hIcon = icon1; 
693                 }
694         }else
695         {
696                 if (type == ServMgr::NT_UPGRADE)
697                         return;
698         }
699
700         const char *title="";
701
702         switch(type)
703         {
704                 case ServMgr::NT_UPGRADE:
705                         title = "Upgrade alert";
706                         break;
707                 case ServMgr::NT_PEERCAST:
708                         title = "Message from PeerCast:";
709                         break;
710
711         }
712
713         if (type & peercastInst->getNotifyMask())
714         {
715                 trayIcon.uFlags |= 16;
716                 trayIcon.uTimeoutOrVersion = 10000;
717                 strncpy(trayIcon.szInfo,msg,sizeof(trayIcon.szInfo)-1);
718                 strncpy(trayIcon.szInfoTitle,title,sizeof(trayIcon.szInfoTitle)-1);
719             Shell_NotifyIcon(NIM_MODIFY, (NOTIFYICONDATA*)&trayIcon);
720         }
721 }
722 //-----------------------------
723
724 // createGUI()
725 //
726 void createGUI(HWND hWnd)
727 {
728         if (!guiWnd)
729                 guiWnd = CreateDialog(hInst, (LPCTSTR)IDD_MAINWINDOW, hWnd, (DLGPROC)GUIProc);
730         ShowWindow(guiWnd,SW_SHOWNORMAL);
731 }
732
733
734 // 
735 // addRelayedChannelsMenu(HMENU m)
736 // 
737 //
738 void addRelayedChannelsMenu(HMENU cm)
739 {
740         int cnt = GetMenuItemCount(cm);
741         for(int i=0; i<cnt-3; i++)
742                 DeleteMenu(cm,0,MF_BYPOSITION);
743
744         Channel *c = chanMgr->channel;
745         while(c)
746         {
747                 if (c->isActive())
748                 {
749                         char str[128],name[64];
750                         strncpy(name,c->info.name,32);
751                         name[32]=0;
752                         if (strlen(c->info.name) > 32)
753                                 strcat(name,"...");
754
755
756                         sprintf(str,"%s  (%d kb/s %s)",name,c->info.bitrate,ChanInfo::getTypeStr(c->info.contentType));
757                         //InsertMenu(cm,0,MF_BYPOSITION,RELAY_CMD+i,str);
758                 }
759                 c=c->next;
760         }
761 }
762
763 typedef int (*COMPARE_FUNC)(const void *,const void *);
764
765 static int compareHitLists(ChanHitList **c2, ChanHitList **c1)
766 {
767         return stricmp(c1[0]->info.name.cstr(),c2[0]->info.name.cstr());
768 }
769
770 static int compareChannels(Channel **c2, Channel **c1)
771 {
772         return stricmp(c1[0]->info.name.cstr(),c2[0]->info.name.cstr());
773 }
774
775 // 
776 // addAllChannelsMenu(HMENU m)
777 // 
778 //
779 void addAllChannelsMenu(HMENU cm)
780 {
781         int cnt = GetMenuItemCount(cm);
782 /*      for(int i=0; i<cnt-2; i++)
783                 DeleteMenu(cm,0,MF_BYPOSITION);*/
784
785         for(int i=0; i<cnt; i++)
786                 DeleteMenu(cm,0,MF_BYPOSITION);
787
788         HMENU yMenu = CreatePopupMenu();
789         if (!servMgr->rootHost2.isEmpty()){
790                 InsertMenu(yMenu,0,MF_BYPOSITION,ID_POPUP_YELLOWPAGES2,servMgr->rootHost2);
791         }
792         if (!servMgr->rootHost.isEmpty()){
793                 InsertMenu(yMenu,0,MF_BYPOSITION,ID_POPUP_YELLOWPAGES1,servMgr->rootHost);
794         }
795
796         InsertMenu(cm,0,MF_BYPOSITION|MF_POPUP,(UINT)yMenu,"\83C\83G\83\8d\81[\83y\81[\83W");
797         InsertMenu(cm,0,MF_BYPOSITION|MF_SEPARATOR,NULL,NULL);
798         // add channels to menu
799         int numActive=0;
800         Channel *ch = chanMgr->channel;
801         while(ch)
802         {
803                 char str[128],name[64];
804                 String sjis; //JP-Patch
805                 sjis = ch->info.name; //JP-Patch
806                 sjis.convertTo(String::T_SJIS); //JP-Patch
807                 strncpy(name,sjis.cstr(),32);
808                 //strncpy(name,ch->info.name,32);
809                 name[32]=0;
810                 //if (strlen(ch->info.name) > 32)
811                 if (strlen(sjis.cstr()) > 32) //JP-Patch
812                         strcat(name,"...");
813
814                 sprintf(str,"%s  (%d kb/s %s)",name,ch->info.bitrate,ChanInfo::getTypeStr(ch->info.contentType));
815
816                 HMENU opMenu = CreatePopupMenu();
817                 InsertMenu(opMenu,0,MF_BYPOSITION,INFO_CMD+numActive,"Info");
818                 if (ch->info.url.isValidURL())
819                         InsertMenu(opMenu,0,MF_BYPOSITION,URL_CMD+numActive,"URL");
820                 InsertMenu(opMenu,0,MF_BYPOSITION,PLAY_CMD+numActive,"Play");
821
822                 UINT fl = MF_BYPOSITION|MF_POPUP;
823                 if (ch)
824                         fl |= (ch->isPlaying()?MF_CHECKED:0);
825
826                 InsertMenu(cm,0,fl,(UINT)opMenu,str);
827                 
828                 numActive++;
829
830                 ch=ch->next;
831         }
832
833
834         //if (!numActive)
835         //              InsertMenu(cm,0,MF_BYPOSITION,0,"<No channels>");
836
837
838
839
840 }
841
842
843 // 
844 // flipNotifyPopup(id, flag)
845 void flipNotifyPopup(int id, ServMgr::NOTIFY_TYPE nt)
846 {
847         int mask = peercastInst->getNotifyMask();
848
849         mask ^= nt;
850         if (mask & nt)
851                 CheckMenuItem(trayMenu,id,MF_CHECKED|MF_BYCOMMAND);
852         else
853                 CheckMenuItem(trayMenu,id,MF_UNCHECKED|MF_BYCOMMAND);
854
855         peercastInst->setNotifyMask(mask);
856         peercastInst->saveSettings();
857 }
858  
859
860 static void showHTML(const char *file)
861 {
862         char url[256];
863         sprintf(url,"%s/%s",servMgr->htmlPath,file);                                    
864
865 //      sys->callLocalURL(url,servMgr->serverHost.port);
866         sys->callLocalURL(url,  // for PCRaw (url)
867                 (servMgr->allowServer1&Servent::ALLOW_HTML)?(servMgr->serverHost.port):(servMgr->serverHost.port+1));
868 }
869
870 static ChanInfo getChannelInfo(int index)
871 {
872         Channel *c = chanMgr->findChannelByIndex(index);
873         if (c)
874                 return c->info;
875
876         ChanInfo info;
877         return info;
878 }
879
880 //
881 //  FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
882 //
883 //  PURPOSE:  Processes messages for the main window.
884 //
885 //  WM_COMMAND  - process the application menu
886 //  WM_PAINT    - Paint the main window
887 //  WM_DESTROY  - post a quit message and return
888 //
889 //
890 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
891 {
892         int wmId, wmEvent;
893         POINT point;
894         char buf[1024];
895
896         if(message == g_iTaskbarCreated)        // for PCRaw (tray icon)
897                 loadIcons(hInst, hWnd);
898  
899         switch (message) 
900         {
901                 case WM_SHOWGUI:
902                         createGUI(hWnd);
903                         break;
904
905
906                 case WM_TRAYICON:
907                         switch((UINT)lParam) 
908                         {
909                                 case WM_LBUTTONDOWN:
910                                         if (allowTrayMenu)
911                                                 SendMessage(hWnd,WM_SHOWMENU,2,0);
912                                         SetForegroundWindow(hWnd);    
913                                         break;
914                                 case WM_RBUTTONDOWN:
915                                         if (allowTrayMenu)
916                                                 SendMessage(hWnd,WM_SHOWMENU,1,0);
917                                         SetForegroundWindow(hWnd);    
918                                         break;
919                                 case WM_LBUTTONDBLCLK:
920                                         createGUI(hWnd);
921                                         break;
922                         }
923                         break;
924
925                 case WM_COPYDATA:
926                         {
927                                 COPYDATASTRUCT *pc = (COPYDATASTRUCT *)lParam;
928                                 LOG_DEBUG("URL request: %s",pc->lpData);
929                                 if (pc->dwData == WM_PLAYCHANNEL)
930                                 {
931                                         ChanInfo info;
932                                         servMgr->procConnectArgs((char *)pc->lpData,info);
933                                         chanMgr->findAndPlayChannel(info,false);
934                                 }
935                                 //sys->callLocalURL((const char *)pc->lpData,servMgr->serverHost.port);
936                         }
937                         break;
938                 case WM_GETPORTNUMBER:
939                         {
940                                 int port;
941                                 port=servMgr->serverHost.port;
942                                 ReplyMessage(port);
943                         }
944                         break;
945
946                 case WM_SHOWMENU:
947                         {
948                                 if (servMgr->saveGuiPos){
949                                         CheckMenuItem(trayMenu, ID_POPUP_SAVE_GUI_POS, MF_CHECKED|MF_BYCOMMAND);
950                                 } else {
951                                         CheckMenuItem(trayMenu, ID_POPUP_SAVE_GUI_POS, MF_UNCHECKED|MF_BYCOMMAND);
952                                 }
953
954                                 SetForegroundWindow(hWnd);    
955                                 bool skipMenu=false;
956
957                                 allowTrayMenu = false;
958
959                                 // check for notifications
960                                 if (currNotify & ServMgr::NT_UPGRADE)
961                                 {
962                                         if (servMgr->downloadURL[0])
963                                         {
964                                                 if ((sys->getTime()-seenNewVersionTime) > (60*60))      // notify every hour
965                                                 {
966                                                         if (MessageBox(hWnd,"A newer version of PeerCast is available, press OK to upgrade.","PeerCast",MB_OKCANCEL|MB_APPLMODAL|MB_ICONEXCLAMATION) == IDOK)
967                                                                 sys->getURL(servMgr->downloadURL);
968
969                                                         seenNewVersionTime=sys->getTime();
970                                                         skipMenu=true;
971                                                 }
972                                         }
973                                 }
974
975
976                                 if (!skipMenu)
977                                 {
978                                         RECT rcWnd;
979                                         HMENU menu;
980                                         UINT flg = 0;
981
982                                         SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWnd, 0);
983                                         GetCursorPos(&point);
984
985                                         if (point.x < rcWnd.left){
986                                                 point.x = rcWnd.left;
987                                                 flg |= TPM_LEFTALIGN;
988                                         }
989                                         if (point.x > rcWnd.right){
990                                                 point.x = rcWnd.right;
991                                                 flg |= TPM_RIGHTALIGN;
992                                         }
993                                         if (point.y < rcWnd.top){
994                                                 point.y = rcWnd.top;
995                                                 flg |= TPM_TOPALIGN;
996                                         }
997                                         if (point.y > rcWnd.bottom){
998                                                 point.y = rcWnd.bottom;
999                                                 flg |= TPM_BOTTOMALIGN;
1000                                         }
1001                                         if (flg == 0){
1002                                                 flg = TPM_RIGHTALIGN;
1003                                         }
1004
1005                                         switch (wParam)
1006                                         {
1007                                                 case 1:
1008                                                         menu = GetSubMenu(trayMenu,0);
1009                                                         addAllChannelsMenu(GetSubMenu(menu,0));
1010                                                         addRelayedChannelsMenu(GetSubMenu(menu,1));
1011                                                         break;
1012                                                 case 2:
1013                                                         menu = GetSubMenu(ltrayMenu,0);
1014                                                         addAllChannelsMenu(menu);
1015                                                         break;
1016                                         }
1017                                         if (!TrackPopupMenu(menu,flg,point.x,point.y,0,hWnd,NULL))
1018                                         {
1019                                                 LOG_ERROR("Can`t track popup menu: %d",GetLastError());
1020                                         }
1021                                         PostMessage(hWnd,WM_NULL,0,0); 
1022
1023                                 }
1024                                 allowTrayMenu = true;
1025                         }
1026                         break;
1027
1028                 case WM_CREATE:
1029                         if (showGUI)
1030                                 createGUI(hWnd);
1031                         break;
1032
1033                 case WM_COMMAND:
1034                         wmId    = LOWORD(wParam); 
1035                         wmEvent = HIWORD(wParam); 
1036
1037                         if ((wmId >= INFO_CMD) && (wmId < INFO_CMD+MAX_CHANNELS))
1038                         {
1039                                 int c = wmId - INFO_CMD;
1040                                 chanInfo = getChannelInfo(c);
1041                                 chanInfoIsRelayed = false;
1042                                 if (winDistinctionNT)
1043                                         DialogBox(hInst, (LPCTSTR)IDD_CHANINFO, hWnd, (DLGPROC)ChanInfoProc);
1044                                 else
1045                                 {
1046                                         HWND WKDLG; //JP-Patch
1047                                         WKDLG = CreateDialog(hInst, (LPCTSTR)IDD_CHANINFO, hWnd, (DLGPROC)ChanInfoProc); //JP-Patch
1048                                         ShowWindow(WKDLG,SW_SHOWNORMAL); //JP-Patch
1049                                 }
1050                                 return 0;
1051                         }
1052                         if ((wmId >= URL_CMD) && (wmId < URL_CMD+MAX_CHANNELS))
1053                         {
1054                                 int c = wmId - URL_CMD;
1055                                 chanInfo = getChannelInfo(c);
1056                                 if (chanInfo.url.isValidURL())
1057                                         sys->getURL(chanInfo.url);
1058                                 return 0;
1059                         }
1060                         if ((wmId >= PLAY_CMD) && (wmId < PLAY_CMD+MAX_CHANNELS))
1061                         {
1062                                 int c = wmId - PLAY_CMD;
1063                                 chanInfo = getChannelInfo(c);
1064                                 chanMgr->findAndPlayChannel(chanInfo,false);
1065                                 return 0;
1066                         }
1067                         if ((wmId >= RELAY_CMD) && (wmId < RELAY_CMD+MAX_CHANNELS))
1068                         {
1069                                 int c = wmId - RELAY_CMD;
1070                                 chanInfo = getChannelInfo(c);
1071                                 chanMgr->findAndPlayChannel(chanInfo,true);
1072                                 return 0;
1073                         }
1074
1075                         // Parse the menu selections:
1076                         switch (wmId)
1077                         {
1078                                 case ID_POPUP_SHOWMESSAGES_PEERCAST:
1079                                         flipNotifyPopup(ID_POPUP_SHOWMESSAGES_PEERCAST,ServMgr::NT_PEERCAST);
1080                                         break;
1081                                 case ID_POPUP_SHOWMESSAGES_BROADCASTERS:
1082                                         flipNotifyPopup(ID_POPUP_SHOWMESSAGES_BROADCASTERS,ServMgr::NT_BROADCASTERS);
1083                                         break;
1084                                 case ID_POPUP_SHOWMESSAGES_TRACKINFO:
1085                                         flipNotifyPopup(ID_POPUP_SHOWMESSAGES_TRACKINFO,ServMgr::NT_TRACKINFO);
1086                                         break;
1087
1088                                 case ID_POPUP_ABOUT:
1089                                 case IDM_ABOUT:
1090                                         DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
1091                                         break;
1092                                 case ID_POPUP_SHOWGUI:
1093                                 case IDM_SETTINGS_GUI:
1094                                 case ID_POPUP_ADVANCED_SHOWGUI:
1095                                 {
1096                                         createGUI(hWnd);
1097                                         break;
1098                                 }
1099                                 case ID_POPUP_YELLOWPAGES:
1100                                         sys->getURL("http://yp.peercast.org/");
1101                                         break;
1102                                 case ID_POPUP_YELLOWPAGES1:
1103                                         sprintf(buf, "http://%s",servMgr->rootHost.cstr());
1104                                         sys->getURL(buf);
1105                                         break;
1106                                 case ID_POPUP_YELLOWPAGES2:
1107                                         sprintf(buf, "http://%s",servMgr->rootHost2.cstr());
1108                                         sys->getURL(buf);
1109                                         break;
1110
1111                                 case ID_POPUP_ADVANCED_VIEWLOG:
1112                                         showHTML("viewlog.html");
1113                                         break;
1114                                 case ID_POPUP_ADVANCED_SAVESETTINGS:
1115                                         servMgr->saveSettings(iniFileName.cstr());
1116                                         break;
1117                                 case ID_POPUP_ADVANCED_INFORMATION:
1118                                         showHTML("index.html");
1119                                         break;
1120                                 case ID_FIND_CHANNELS:
1121                                 case ID_POPUP_ADVANCED_ALLCHANNELS:
1122                                 case ID_POPUP_UPGRADE:
1123                                         sys->callLocalURL("admin?cmd=upgrade",servMgr->serverHost.port);
1124                                         break;
1125                                 case ID_POPUP_ADVANCED_RELAYEDCHANNELS:
1126                                 case ID_POPUP_FAVORITES_EDIT:
1127                                         showHTML("relays.html");
1128                                         break;
1129                                 case ID_POPUP_ADVANCED_BROADCAST:
1130                                         showHTML("broadcast.html");
1131                                         break;
1132                                 case ID_POPUP_SETTINGS:
1133                                         showHTML("settings.html");
1134                                         break;
1135                                 case ID_POPUP_CONNECTIONS:
1136                                         showHTML("connections.html");
1137                                         break;
1138                                 case ID_POPUP_HELP:
1139                                         sys->getURL("http://www.peercast.org/help.php");
1140                                         break;
1141
1142                                 case ID_POPUP_SAVE_GUI_POS:
1143                                         if (servMgr->saveGuiPos){
1144                                                 servMgr->saveGuiPos = false;
1145                                                 CheckMenuItem(trayMenu, ID_POPUP_SAVE_GUI_POS, MF_UNCHECKED|MF_BYCOMMAND);
1146                                         } else {
1147                                                 servMgr->saveGuiPos = true;
1148                                                 CheckMenuItem(trayMenu, ID_POPUP_SAVE_GUI_POS, MF_CHECKED|MF_BYCOMMAND);
1149                                         }
1150                                         peercastInst->saveSettings();
1151                                         break;
1152
1153                                 case ID_POPUP_KEEP_DOWNSTREAMS:
1154                                         if (servMgr->keepDownstreams){
1155                                                 servMgr->keepDownstreams = false;
1156                                                 CheckMenuItem(trayMenu, ID_POPUP_KEEP_DOWNSTREAMS, MF_UNCHECKED|MF_BYCOMMAND);
1157                                         } else {
1158                                                 servMgr->keepDownstreams = true;
1159                                                 CheckMenuItem(trayMenu, ID_POPUP_KEEP_DOWNSTREAMS, MF_CHECKED|MF_BYCOMMAND);
1160                                         }
1161                                         //peercastInst->saveSettings();
1162                                         break;
1163
1164                                 case ID_POPUP_EXIT_CONFIRM:
1165                                 case IDM_EXIT:
1166                                    DestroyWindow(hWnd);
1167                                    break;
1168                                 default:
1169                                    return DefWindowProc(hWnd, message, wParam, lParam);
1170                         }
1171                         break;
1172                 case WM_DESTROY:
1173                         PostQuitMessage(0);
1174                         break;
1175                 default:
1176                         return DefWindowProc(hWnd, message, wParam, lParam);
1177    }
1178    return 0;
1179 }
1180 // Mesage handler for about box.
1181 LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
1182 {
1183         switch (message)
1184         {
1185                 case WM_INITDIALOG:
1186                         //SendDlgItemMessage(hDlg,IDC_ABOUTVER,WM_SETTEXT,0,(LONG)PCX_AGENT);
1187 //                      SendDlgItemMessage(hDlg,IDC_ABOUTVER,WM_SETTEXT,0,(LONG)PCX_AGENTJP);
1188                         //SendDlgItemMessage(hDlg,IDC_ABOUTVER,WM_SETTEXT,0,(LONG)PCX_AGENTVP);
1189
1190                         if (version_ex)
1191                         {
1192                                 SendDlgItemMessage(hDlg,IDC_ABOUTVER,WM_SETTEXT,0,(LPARAM)PCX_AGENTEX); // x64\91ÃŽ\89\9e
1193                         } else
1194                         {
1195                                 SendDlgItemMessage(hDlg,IDC_ABOUTVER,WM_SETTEXT,0,(LONG)PCX_AGENTVP);
1196                         }
1197
1198                         return TRUE;
1199
1200                 case WM_COMMAND:
1201                         switch (LOWORD(wParam))
1202                         {
1203                                 case IDOK:
1204                                 case IDCANCEL:
1205                                         EndDialog(hDlg, LOWORD(wParam));
1206                                         return TRUE;
1207                                 case IDC_BUTTON1:
1208                                         sys->getURL("http://www.peercast.org");
1209                                         EndDialog(hDlg, LOWORD(wParam));
1210                                         return TRUE;
1211
1212                         }
1213                         break;
1214                 case WM_DESTROY:
1215                         break;
1216         }
1217     return FALSE;
1218 }
1219
1220 // Mesage handler for chaninfo box
1221 LRESULT CALLBACK ChanInfoProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
1222 {
1223         switch (message)
1224         {
1225                 case WM_INITDIALOG:
1226                         {
1227                                 char str[1024];
1228                                 //strcpy(str,chanInfo.track.artist.cstr());
1229                                 strcpy(str,chanInfo.track.artist); //JP-Patch
1230                                 strcat(str," - ");
1231                                 //strcat(str,chanInfo.track.title.cstr());
1232                                 strcat(str,chanInfo.track.title);
1233                                 String name,track,comment,desc,genre; //JP-Patch
1234                                 name = chanInfo.name; //JP-Patch
1235                                 track = str; //JP-Patch
1236                                 comment = chanInfo.comment; //JP-Patch
1237                                 desc = chanInfo.desc; //JP-Patc
1238                                 genre = chanInfo.genre; //JP-Patch
1239                                 name.convertTo(String::T_SJIS); //JP-Patc
1240                                 track.convertTo(String::T_SJIS); //JP-Patch
1241                                 comment.convertTo(String::T_SJIS); //JP-Patch
1242                                 desc.convertTo(String::T_SJIS); //JP-Patch
1243                                 genre.convertTo(String::T_SJIS); //JP-Patch
1244                                 
1245                                 //SendDlgItemMessage(hDlg,IDC_EDIT_NAME,WM_SETTEXT,0,(LONG)chanInfo.name.cstr());
1246                                 SendDlgItemMessage(hDlg,IDC_EDIT_NAME,WM_SETTEXT,0,(LONG)name.cstr()); //JP-Patch
1247                                 //SendDlgItemMessage(hDlg,IDC_EDIT_PLAYING,WM_SETTEXT,0,(LONG)str);
1248                                 SendDlgItemMessage(hDlg,IDC_EDIT_PLAYING,WM_SETTEXT,0,(LONG)track.cstr()); //JP-Patch
1249                                 //SendDlgItemMessage(hDlg,IDC_EDIT_MESSAGE,WM_SETTEXT,0,(LONG)chanInfo.comment.cstr());
1250                                 SendDlgItemMessage(hDlg,IDC_EDIT_MESSAGE,WM_SETTEXT,0,(LONG)comment.cstr()); //JP-Patch
1251                                 //SendDlgItemMessage(hDlg,IDC_EDIT_DESC,WM_SETTEXT,0,(LONG)chanInfo.desc.cstr());
1252                                 SendDlgItemMessage(hDlg,IDC_EDIT_DESC,WM_SETTEXT,0,(LONG)desc.cstr()); //JP-Patch
1253                                 //SendDlgItemMessage(hDlg,IDC_EDIT_GENRE,WM_SETTEXT,0,(LONG)chanInfo.genre.cstr());
1254                                 SendDlgItemMessage(hDlg,IDC_EDIT_GENRE,WM_SETTEXT,0,(LONG)genre.cstr()); //JP-Patch
1255
1256                                 sprintf(str,"%d kb/s %s",chanInfo.bitrate,ChanInfo::getTypeStr(chanInfo.contentType));
1257                                 SendDlgItemMessage(hDlg,IDC_FORMAT,WM_SETTEXT,0,(LONG)str);
1258
1259
1260                                 if (!chanInfo.url.isValidURL())
1261                                         EnableWindow(GetDlgItem(hDlg,IDC_CONTACT),false);
1262
1263                                 Channel *ch = chanMgr->findChannelByID(chanInfo.id);
1264                                 if (ch)
1265                                 {
1266                                         SendDlgItemMessage(hDlg,IDC_EDIT_STATUS,WM_SETTEXT,0,(LONG)ch->getStatusStr());
1267                                         SendDlgItemMessage(hDlg, IDC_KEEP,BM_SETCHECK, ch->stayConnected, 0);
1268                                 }else
1269                                 {
1270                                         SendDlgItemMessage(hDlg,IDC_EDIT_STATUS,WM_SETTEXT,0,(LONG)"OK");
1271                                         EnableWindow(GetDlgItem(hDlg,IDC_KEEP),false);
1272                                 }
1273
1274
1275
1276                                 POINT point;
1277                                 RECT rect,drect;
1278                                 HWND hDsk = GetDesktopWindow();
1279                                 GetWindowRect(hDsk,&drect);
1280                                 GetWindowRect(hDlg,&rect);
1281                                 GetCursorPos(&point);
1282
1283                                 POINT pos,size;
1284                                 size.x = rect.right-rect.left;
1285                                 size.y = rect.bottom-rect.top;
1286
1287                                 if (point.x-drect.left < size.x)
1288                                         pos.x = point.x;
1289                                 else
1290                                         pos.x = point.x-size.x;
1291
1292                                 if (point.y-drect.top < size.y)
1293                                         pos.y = point.y;
1294                                 else
1295                                         pos.y = point.y-size.y;
1296
1297                                 SetWindowPos(hDlg,HWND_TOPMOST,pos.x,pos.y,size.x,size.y,0);
1298                                 chWnd = hDlg;
1299                         }
1300                         return TRUE;
1301
1302                 case WM_COMMAND:
1303                         {
1304                                 char str[1024],idstr[64];
1305                                 chanInfo.id.toStr(idstr);
1306
1307                                 switch (LOWORD(wParam))
1308                                 {
1309                                         case IDC_CONTACT:
1310                                         {
1311                                                 sys->getURL(chanInfo.url);
1312                                                 return TRUE;
1313                                         }
1314                                         case IDC_DETAILS:
1315                                         {
1316                                                 sprintf(str,"admin?page=chaninfo&id=%s&relay=%d",idstr,chanInfoIsRelayed);
1317                                                 sys->callLocalURL(str,servMgr->serverHost.port);
1318                                                 return TRUE;
1319                                         }
1320                                         case IDC_KEEP:
1321                                         {
1322                                                 Channel *ch = chanMgr->findChannelByID(chanInfo.id);
1323                                                 if (ch)
1324                                                         ch->stayConnected = SendDlgItemMessage(hDlg, IDC_KEEP,BM_GETCHECK, 0, 0) == BST_CHECKED;;
1325                                                 return TRUE;
1326                                         }
1327
1328
1329                                         case IDC_PLAY:
1330                                         {
1331                                                 chanMgr->findAndPlayChannel(chanInfo,false);
1332                                                 return TRUE;
1333                                         }
1334
1335                                 }
1336                         }
1337                         break;
1338
1339                 case WM_CLOSE:
1340                         if (winDistinctionNT)
1341                                 EndDialog(hDlg, 0);
1342                         else
1343                                 DestroyWindow(hDlg); //JP-Patch
1344                         break;
1345
1346                 case WM_ACTIVATE:
1347                         if (LOWORD(wParam) == WA_INACTIVE)
1348                                 if (winDistinctionNT)
1349                                         EndDialog(hDlg, 0);
1350                                 else
1351                                         DestroyWindow(hDlg); //JP-Patch
1352                         break;
1353                 case WM_DESTROY:
1354                         chWnd = NULL;
1355                         break;
1356
1357
1358         }
1359     return FALSE;
1360 }