OSDN Git Service

44b79a6285e5a6f6bfe61c7153b8f30ba65524bd
[peercast-im/PeerCastIM.git] / PeerCast.root / PeerCast_1 / ui / win32 / simple / gui.cpp
1 // ------------------------------------------------
2 // File : gui.cpp
3 // Date: 4-apr-2002
4 // Author: giles
5 // Desc: 
6 //              Windows front end GUI, PeerCast core is not dependant on any of this. 
7 //              Its very messy at the moment, but then again Windows UI always is.
8 //              I really don`t like programming win32 UI.. I want my borland back..
9 //
10 // (c) 2002 peercast.org
11 // ------------------------------------------------
12 // This program is free software; you can redistribute it and/or modify
13 // it under the terms of the GNU General Public License as published by
14 // the Free Software Foundation; either version 2 of the License, or
15 // (at your option) any later version.
16
17 // This program is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 // GNU General Public License for more details.
21 // ------------------------------------------------
22
23 #define _WIN32_WINNT 0x0500
24
25 #include <windows.h>
26 #include "stdio.h"
27 #include "string.h"
28 #include "stdarg.h"
29 #include "resource.h"
30 #include "socket.h"
31 #include "win32/wsys.h"
32 #include "servent.h"
33 #include "win32/wsocket.h"
34 #include "inifile.h"
35 #include "gui.h"
36 #include "servmgr.h"
37 #include "peercast.h"
38 #include "simple.h"
39 #include "gdiplus.h"
40 #include "commctrl.h"
41 #include "locale.h"
42 #include "stats.h"
43 #include "socket.h"
44 #include "wininet.h"
45 #ifdef _DEBUG
46 #include "chkMemoryLeak.h"
47 #define DEBUG_NEW new(__FILE__, __LINE__)
48 #define new DEBUG_NEW
49 #endif
50
51 ThreadInfo guiThread;
52 bool shownChannels=false;
53 WINDOWPLACEMENT winPlace;
54 bool guiFlg = false;
55
56 using namespace Gdiplus;
57
58 #include <comdef.h>
59
60 void APICALL MyPeercastApp ::printLog(LogBuffer::TYPE t, const char *str)
61 {
62 /*      ADDLOG(str,logID,true,NULL,t);
63         if (logFile.isOpen())
64         {
65                 logFile.writeLine(str);
66                 logFile.flush();
67         }*/
68 }
69
70 void APICALL MyPeercastApp::updateSettings()
71 {
72 //      setControls(true);
73 }
74
75 Gdiplus::Bitmap bmpBack(800,600,PixelFormat24bppRGB);
76 UINT backWidth;
77 UINT backHeight;
78
79 Gdiplus::Image *backImage;
80 Gdiplus::Bitmap *backBmp;
81 Gdiplus::Graphics *backGra;
82
83 Gdiplus::Image *img_idle;
84 Gdiplus::Image *img_connect;
85 Gdiplus::Image *img_conn_ok;
86 Gdiplus::Image *img_conn_full;
87 Gdiplus::Image *img_conn_over;
88 Gdiplus::Image *img_conn_ok_skip;
89 Gdiplus::Image *img_conn_full_skip;
90 Gdiplus::Image *img_conn_over_skip;
91 Gdiplus::Image *img_error;
92 Gdiplus::Image *img_broad_ok;
93 Gdiplus::Image *img_broad_full;
94
95 UINT winWidth=0;
96 UINT winHeight=0;
97
98 static HWND hTree;
99 extern HINSTANCE hInst;
100 extern HWND guiWnd;
101 extern Stats stats;
102
103 WLock sd_lock;
104 WLock ChannelDataLock;
105 WLock MakeBackLock;
106 ChannelData *channelDataTop = NULL;
107
108 extern bool gbGetFile;
109 extern bool gbStart;
110 extern time_t gtGetFile;
111 extern time_t gtStartTime;
112 ThreadInfo gtiStart;
113 ThreadInfo gtiGetFile;
114 static char *data1URL = "http://www.idolmaster.jp/download/images/wallpaper/imas360p_800.jpg";
115 static char *data2URL = "http://www.xbox.com/NR/rdonlyres/CAB05E2F-3051-409B-A4C8-830167C1C138/0/wpr0701idolmasterw120001.jpg";
116 HWND ghStart;
117
118 bool gbDispTop = false;
119 bool gbAllOpen = false;
120
121 THREAD_PROC FestivalStart(ThreadInfo *thread);
122
123 THREAD_PROC GetHostName(ThreadInfo *thread){
124         IdData *id = (IdData*)(thread->data);
125
126         HOSTENT *he;
127         unsigned int ip;
128         bool flg = TRUE;
129
130         ChannelDataLock.on();
131         ip = htonl(id->getIpAddr());
132
133         for (int i=0; i<5 && flg; i++){
134                 he = gethostbyaddr((char *)&ip,sizeof(ip),AF_INET);
135
136                 ChannelData* cd = channelDataTop;
137                 if (he)
138                 {
139                         while(cd){
140                                 if (cd->setName(id->getServentId(), he->h_name)){
141                                         flg = FALSE;
142                                         break;
143                                 }
144                                 cd = cd->getNextData();
145                         }
146                 }
147 //              ::delete id;
148                 ChannelDataLock.off();
149                 sys->sleep(1000);
150         }
151
152
153         return 0;
154 }
155
156 bool DownloadFile(LPCTSTR URL, LPCTSTR local){
157         char header[] = "Accept: */*\r\n\r\n";
158         char buf[4096];
159
160         FileStream f;
161         HINTERNET hInternet;
162         HINTERNET hConnect;
163
164         try{
165                 f.openWriteReplace(local);
166         }catch(StreamException &e){
167                 return false;
168         }
169
170         hInternet = ::InternetOpen(NULL, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
171         if (hInternet == NULL){
172                 return false;
173         }
174
175         hConnect = ::InternetOpenUrl(hInternet, URL, header, strlen(header), INTERNET_FLAG_DONT_CACHE, 0);
176         if (hConnect == NULL){
177                 ::InternetCloseHandle(hInternet);
178                 return false;
179         }
180
181         while(1){
182                 sys->sleep(0);
183                 DWORD dwReadSize;
184                 BOOL ret = ::InternetReadFile(hConnect, buf, 4096, &dwReadSize);
185                 if (ret){
186                         if (dwReadSize == 0){
187                                 break;
188                         }
189                         try{
190                                 f.write(buf, dwReadSize);
191                                 continue;
192                         } catch(StreamException e){
193                         }
194                         f.close();
195                         ::InternetCloseHandle(hConnect);
196                         ::InternetCloseHandle(hInternet);
197                         return false;
198                 }
199         }
200
201         f.flush();
202         f.close();
203         ::InternetCloseHandle(hConnect);
204         ::InternetCloseHandle(hInternet);
205
206         return true;
207 }
208
209 THREAD_PROC GetInternetFile(ThreadInfo *thread){
210
211         DownloadFile(data1URL, "data1.jpg");
212         DownloadFile(data2URL, "data2.jpg");
213         return 0;
214 }
215
216 extern TCHAR szWindowClass3[];                                                          // The title bar text
217
218
219 int drawSpeed(Graphics *gra, int posX, int posY){
220
221         // \91¬\93x\95\\8e¦\95\94\82Ì\94w\8ci\82ð\94\92\82­\82·\82é
222         SolidBrush b(Color(180,255,255,255));
223         backGra->FillRectangle(&b, posX, posY, 200, 14);
224         // \83t\83H\83\93\83g\90Ý\92è
225         Font font(L"\82l\82\82o\83S\83V\83b\83N",10);
226         // \95\8e\9a\90F
227         SolidBrush strBrush(Color::Black);
228         // \95\8e\9a\97ñ\8dì\90¬
229         char tmp[256];
230         sprintf(tmp, "R:%.1fkbps S:%.1fkbps", 
231                 BYTES_TO_KBPS(stats.getPerSecond(Stats::BYTESIN)-stats.getPerSecond(Stats::LOCALBYTESIN)),
232                 BYTES_TO_KBPS(stats.getPerSecond(Stats::BYTESOUT)-stats.getPerSecond(Stats::LOCALBYTESOUT)));
233         _bstr_t bstr(tmp);
234         // \95\8e\9a\95\\8e¦\94Í\88Í\8ew\92è
235         StringFormat format;
236         format.SetAlignment(StringAlignmentCenter);
237         RectF r((REAL)posX, (REAL)posY, (REAL)200, (REAL)14);
238         // \95\8e\9a\95`\89æ
239         gra->DrawString(bstr, -1, &font, r, &format, &strBrush);
240
241
242
243         return posY + 15;
244 }
245
246 void MakeBack(HWND hwnd, UINT x, UINT y){
247         MakeBackLock.on();
248
249         winWidth = x;
250         winHeight = y;
251
252         if (backGra){
253                 ::delete backBmp;
254                 ::delete backGra;
255         }
256
257         backBmp = ::new Bitmap(x,y);
258         backGra = ::new Graphics(backBmp);
259
260         // \91S\82Ä\94\92\82Å\93h\82è\82Â\82Ô\82µ
261         SolidBrush b(Color(255,255,255,255));
262         backGra->FillRectangle(&b, 0, 0, x, y);
263
264         backWidth = backImage->GetWidth();
265         backHeight = backImage->GetHeight();
266
267         // \94w\8ci\89æ\91\9c\82ð\95`\89æ
268         for (UINT xx = 0; xx < x/backWidth + 1; xx++){
269                 for (UINT yy = 0; yy < y/backHeight + 1; yy++){
270                         UINT width,height;
271                         if (backWidth*(xx+1) > x){
272                                 width = x % backWidth;
273                         } else {
274                                 width = backWidth;
275                         }
276                         if (backHeight*(yy+1) > y){
277                                 height = y % backHeight;
278                         } else {
279                                 height = backHeight;
280                         }
281                         Rect r((INT)backWidth*xx, (INT)backHeight*yy, width, height);
282                         backGra->DrawImage(backImage, r, 0, 0, (INT)width, (INT)height, UnitPixel);
283                 }
284         }
285
286         INT posX = 20;
287         INT posY = 20;
288
289         // \91¬\93x\95`\89æ
290         drawSpeed(backGra, winWidth-205, 5);
291
292         // \83`\83\83\83\93\83l\83\8b\8fî\95ñ\82ð\95`\89æ
293         ChannelDataLock.on();
294         ChannelData *cd = channelDataTop;
295         while(cd){
296                 posY = cd->drawChannel(backGra, 20, posY);
297                 cd = cd->getNextData();
298         }
299         ChannelDataLock.off();
300         MakeBackLock.off();
301 }
302
303 void MakeBack(HWND hwnd){
304         MakeBack(hwnd, winWidth, winHeight);
305         ::InvalidateRect(guiWnd, NULL, FALSE);
306 }
307
308 void ChannelData::setData(Channel *c){
309         String sjis;
310         sjis = c->getName();
311         sjis.convertTo(String::T_SJIS);
312
313         strncpy(name, sjis, 256);
314         name[256] = '\0';
315         channel_id = c->channel_id;
316         bitRate = c->info.bitrate;
317         lastPlayStart = c->info.lastPlayStart;
318         status = c->status;
319         totalListeners = c->totalListeners();
320         totalRelays = c->totalRelays();
321         localListeners = c->localListeners();
322         localRelays = c->localRelays();
323         stayConnected = c->stayConnected;
324         chDisp = c->chDisp;
325         bTracker = c->sourceHost.tracker;
326         lastSkipTime = c->lastSkipTime;
327         skipCount = c->skipCount;
328 }
329
330 int gW = 0;
331 int gWS = 0;
332
333 int ChannelData::drawChannel(Graphics *g, int x, int y){
334         REAL xx = x * 1.0f;
335         REAL yy = y * 1.0f;
336         ServentData* sd;
337
338         // \88Ê\92u\82ð\95Û\91
339         posX = x;
340         posY = y;
341
342         int w,h;
343
344         if (getWidth() == 0){
345                 if (gW){
346                         w = gW;
347                 } else {
348                         w = 400;
349                 }
350         } else {
351                 w = getWidth();
352                 gW = w;
353         }
354
355         // \83`\83\83\83\93\83l\83\8b\95\\8e¦\95\94\82Ì\94w\8ci\82ð\93h\82é
356         if (isSelected()){
357                 // \91I\91ð\92\86
358                 SolidBrush b(Color(160,49,106,197));
359                 g->FillRectangle(&b, x, y, w, 14);
360         } else {
361                 // \94ñ\91I\91ð
362                 SolidBrush b(Color(160,255,255,255));
363                 g->FillRectangle(&b, x, y, w, 14);
364         }
365
366         // \83X\83e\81[\83^\83X\95\\8e¦
367         Gdiplus::Image *img = NULL;
368         unsigned int nowTime = sys->getTime();
369         switch(this->getStatus()){
370                 case Channel::S_IDLE:
371                         img = img_idle;
372                         break;
373                 case Channel::S_SEARCHING:
374                 case Channel::S_CONNECTING:
375                         img = img_connect;
376                         break;
377                 case Channel::S_RECEIVING:
378                         if ((skipCount > 2) && (lastSkipTime + 120 > nowTime)){
379                                 if (chDisp.relay){
380                                         img = img_conn_ok_skip;
381                                 } else {
382                                         if (chDisp.numRelays){
383                                                 img = img_conn_full_skip;
384                                         } else {
385                                                 img = img_conn_over_skip;
386                                         }
387                                 }
388                         } else {
389                                 if (chDisp.relay){
390                                         img = img_conn_ok;
391                                 } else {
392                                         if (chDisp.numRelays){
393                                                 img = img_conn_full;
394                                         } else {
395                                                 img = img_conn_over;
396                                         }
397                                 }
398                         }
399                         break;
400                 case Channel::S_BROADCASTING:
401                         img = img_broad_ok;
402                         break;
403                 case Channel::S_ERROR:
404                         img = img_error;
405                         break;
406                 default:
407                         img = img_idle;
408                         break;
409         }
410         // \95`\89æ\8aî\93_
411         PointF origin(xx, yy);
412         // \83X\83e\81[\83^\83X\95\\8e¦\88Ê\92u
413         Rect img_rect((INT)origin.X, (INT)origin.Y + 1, img ? img->GetWidth() : 12, 12);
414         // \83X\83e\81[\83^\83X\95`\89æ
415         ImageAttributes att;
416 //      att.SetColorKey(Color::White, Color::White, ColorAdjustTypeBitmap);
417         g->DrawImage(img, img_rect, 0, 0, img_rect.Width, 12, UnitPixel, &att);
418         // \8e\9f\82Ì\8aî\93_
419         origin.X += img_rect.Width;
420
421         // \83t\83H\83\93\83g\90Ý\92è
422         Gdiplus::Font font(L"\82l\82\82o\83S\83V\83b\83N",10);
423         // \95\8e\9a\90F
424         SolidBrush *strBrush;
425         if (servMgr->getFirewall() == ServMgr::FW_ON){
426                 strBrush = ::new SolidBrush(Color::Red);
427         } else if (isTracker() && (getStatus() == Channel::S_RECEIVING)){
428                 strBrush = ::new SolidBrush(Color::Green);
429         } else {
430                 if (isSelected()){
431                         // \91I\91ð\92\86
432                         strBrush = ::new SolidBrush(Color::White);
433                 } else {
434                         // \94ñ\91I\91ð
435                         strBrush = ::new SolidBrush(Color::Black);
436                 }
437         }
438         // \83`\83\83\83\93\83l\83\8b\96¼\95\\8e¦
439         g->SetTextRenderingHint(TextRenderingHintAntiAlias);
440         _bstr_t bstr1(getName());
441         // \95\8e\9a\95`\89æ\94Í\88Í\8ew\92è
442         RectF r1(origin.X, origin.Y, 120.0f, 13.0f);
443         StringFormat format;
444         format.SetAlignment(StringAlignmentNear);
445         g->DrawString(bstr1, -1, &font, r1, &format, strBrush);
446         // \8e\9f\82Ì\8aî\93_
447         origin.X += r1.Width;
448
449         // \83\8a\83X\83i\81[\90\94/\83\8a\83\8c\81[\90\94\95\\8e¦
450         char tmp[256];
451         sprintf(tmp, "%d/%d - [%d/%d]", getTotalListeners(), getTotalRelays(), getLocalListeners(), getLocalRelays());
452         _bstr_t bstr2(tmp);
453         // \95\8e\9a\95\\8e¦\94Í\88Í\8ew\92è
454         RectF r2(origin.X, origin.Y, 100.0f, 13.0f);
455         format.SetAlignment(StringAlignmentCenter);
456         g->DrawString(bstr2, -1, &font, r2, &format, strBrush);
457         // \8e\9f\82Ì\8aî\93_
458         origin.X += r2.Width;
459
460         // bps\95\\8e¦
461         Font *f;
462         if (isStayConnected()){
463                 f = ::new Font(L"Arial", 9.0f, FontStyleItalic|FontStyleBold, UnitPoint);
464         } else {
465                 f = ::new Font(L"Arial", 9.0f);
466         }
467         sprintf(tmp, "%dkbps", getBitRate());
468         _bstr_t bstr3(tmp);
469         format.SetAlignment(StringAlignmentFar);
470         // \95\8e\9a\95\\8e¦\94Í\88Í\8ew\92è
471         RectF r3(origin.X, origin.Y, 80.0f, 13.0f);
472         g->DrawString(bstr3, -1, f, r3, &format, strBrush);
473         // \83t\83H\83\93\83g\8aJ\95ú
474         ::delete f;
475
476         // \8e\9f\82Ì\8aî\93_
477         origin.X += r3.Width;
478
479         // \83u\83\89\83V\8dí\8f\9c
480         ::delete strBrush;
481
482         
483         // Servent\95\\8e¦
484         if (!openFlg){
485                 int count = getServentCount();
486                 // Servent\95\\8e¦\95\94\82Ì\94w\8ci\82ð\94\92\82É\82·\82é
487                 SolidBrush b(Color(160,255,255,255));
488                 g->FillRectangle(&b, (INT)origin.X, (INT)origin.Y, 14*count, 14);
489
490                 sd = serventDataTop;
491                 int index = 0;
492                 while(sd){
493                         SolidBrush *serventBrush;
494                         if (sd->getInfoFlg()){
495                                 ChanHit *hit = sd->getChanHit();
496                                 if (hit->firewalled){
497                                         SolidBrush bb(Color(180,255,0,0));
498                                         g->FillRectangle(&bb, (INT)origin.X + 14*index, (INT)origin.Y, 14, 14);
499                                 }
500                                 if (hit->relay){
501                                         // \83\8a\83\8c\81[\82n\82j
502                                         serventBrush = ::new SolidBrush(Color::Green);
503                                 } else {
504                                         // \83\8a\83\8c\81[\95s\89Â
505                                         if (hit->numRelays){
506                                                 // \83\8a\83\8c\81[\88ê\94t
507                                                 serventBrush = ::new SolidBrush(Color::Blue);
508                                         } else {
509                                                 // \83\8a\83\8c\81[\82È\82µ
510                                                 serventBrush = ::new SolidBrush(Color::Purple);
511                                         }
512                                 }
513                         } else {
514                                 // \8fî\95ñ\82È\82µ
515                                 serventBrush = ::new SolidBrush(Color::Black);
516                         }
517                         // \8el\8ap\95`\89æ
518                         backGra->FillRectangle(serventBrush, (INT)origin.X + index*14 + 1, (INT)origin.Y + 1, 12, 12);
519
520                         ::delete serventBrush;
521                         sd = sd->getNextData();
522                         index++;
523                 }
524         }
525
526         // \8e\9f\82Ì\8aî\93_
527         origin.Y += 15;
528
529         // \83T\83C\83Y\82ð\95Û\91
530         setWidth((int)origin.X - posX);
531         setHeight((int)origin.Y - posY);
532
533         // ServentData\95\\8e¦
534         sd = serventDataTop;
535         while(sd){
536                 if (openFlg || sd->getSelected()){
537                         sd->drawServent(g, (INT)x+12, (INT)origin.Y);
538                         // \8e\9f\82Ì\8aî\93_
539                         origin.Y += 15;
540                 }
541                 sd = sd->getNextData();
542         }
543         
544
545         return (int)(origin.Y);
546 }
547
548 bool ChannelData::checkDown(int x,int y){
549         // \94Í\88Í\93à\83`\83F\83b\83N
550         if (    
551                         (x > posX)
552                 &&      (x < posX + getWidth())
553                 &&      (y > posY)
554                 &&      (y < posY + getHeight())
555         ){
556                 return TRUE;
557         }
558         return FALSE;
559 }
560
561 ServentData *ChannelData::findServentData(int servent_id){
562         ServentData *sv = serventDataTop;
563         while(sv){
564                 if (sv->getServentId() == servent_id){
565                         return sv;
566                 }
567                 sv = sv->getNextData();
568         }
569         return NULL;
570 }
571
572 void ChannelData::addServentData(ServentData *sd){
573         sd->setNextData(serventDataTop);
574         serventDataTop = sd;
575 }
576
577 void ChannelData::deleteDisableServents(){
578         ServentData *sd = serventDataTop;
579         ServentData *prev = NULL;
580
581         while(sd){
582                 if (!(sd->getEnableFlg())){
583                         ServentData *next = sd->getNextData();
584                         if (prev){
585                                 prev->setNextData(next);
586                         } else {
587                                 serventDataTop = next;
588                         }
589                         ::delete sd;
590                         sd = next;
591                 } else {
592                         prev = sd;
593                         sd = sd->getNextData();
594                 }
595         }
596 }
597
598 int ChannelData::getServentCount(){
599         int ret = 0;
600
601         ServentData *sd = serventDataTop;
602         while(sd){
603                 ret++;
604                 sd = sd->getNextData();
605         }
606         return ret;
607 }
608
609 bool ChannelData::setName(int servent_id, String name){
610         ServentData *sd = serventDataTop;
611         while(sd){
612                 if (sd->getServentId() == servent_id){
613                         sd->setName(name);
614                         return TRUE;
615                 }
616                 sd = sd->getNextData();
617         }
618         return FALSE;
619 }
620
621 void ServentData::setData(Servent *s, ChanHit *hit, unsigned int listeners, unsigned int relays, bool f){
622         servent_id = s->servent_id;
623         type = s->type;
624         status = s->status;
625         lastSkipTime = s->lastSkipTime;
626         host = s->getHost();
627
628         chanHit.numRelays = hit->numRelays;
629         chanHit.relay = hit->relay;
630         chanHit.firewalled = hit->firewalled;
631         chanHit.version = hit->version;
632         chanHit.version_vp = hit->version_vp;
633         chanHit.version_ex_number = hit->version_ex_number;
634         chanHit.version_ex_prefix[0] = hit->version_ex_prefix[0];
635         chanHit.version_ex_prefix[1] = hit->version_ex_prefix[1];
636
637         totalListeners = listeners;
638         totalRelays = relays;
639
640         infoFlg = f;
641 }
642
643 int ServentData::drawServent(Gdiplus::Graphics *g, int x, int y){
644         REAL xx = x * 1.0f;
645         REAL yy = y * 1.0f;
646         int w,h;
647
648         // \88Ê\92u\82ð\95Û\91
649         posX = x;
650         posY = y;
651
652         if (getWidth() == 0){
653                 if (gWS){
654                         w = gWS;
655                 } else {
656                         w = 400;
657                 }
658         } else {
659                 w = getWidth();
660                 gWS = w;
661         }
662
663         // \95`\89æ\8aî\93_
664         PointF origin(xx, yy);
665
666         // \83t\83H\83\93\83g\90Ý\92è
667         Font font(L"\82l\82\82o\83S\83V\83b\83N",9);
668         // \95\8e\9a\90F
669         SolidBrush *strBrush;
670         if (chanHit.firewalled){
671                 strBrush = ::new SolidBrush(Color::Red);
672         } else {
673                 if (getSelected()){
674                         // \91I\91ð\92\86
675                         strBrush = ::new SolidBrush(Color::White);
676                 } else {
677                         // \94ñ\91I\91ð
678                         strBrush = ::new SolidBrush(Color::Black);
679                 }
680         }
681         // ServantData\95\\8e¦
682         g->SetTextRenderingHint(TextRenderingHintAntiAlias);
683         // \95\8e\9a\97ñ\8dì\90¬
684         char tmp[256];
685         char host1[256];
686         host.toStr(host1);
687
688         if (infoFlg){
689                 if (chanHit.version_ex_number){
690                         // \8ag\92£\83o\81[\83W\83\87\83\93
691                         sprintf(tmp, "%c%c%04d - %d/%d - %s(%s)", 
692                                 chanHit.version_ex_prefix[0],
693                                 chanHit.version_ex_prefix[1],
694                                 chanHit.version_ex_number,
695                                 totalListeners,
696                                 totalRelays,
697                                 host1,
698                                 hostname.cstr()
699                                 );
700                 } else if (chanHit.version_vp){
701                         sprintf(tmp, "VP%04d - %d/%d - %s(%s)", 
702                                 chanHit.version_vp,
703                                 totalListeners,
704                                 totalRelays,
705                                 host1,
706                                 hostname.cstr()
707                                 );
708                 } else {
709                         sprintf(tmp, "(-----) - %d/%d - %s(%s)",
710                                 totalListeners,
711                                 totalRelays,
712                                 host1,
713                                 hostname.cstr()
714                                 );
715                 }
716         } else {
717                         sprintf(tmp, "(-----) - %d/%d - %s(%s)",
718                                 totalListeners,
719                                 totalRelays,
720                                 host1,
721                                 hostname.cstr()
722                                 );
723         }
724         _bstr_t bstr1(tmp);
725
726         // \83X\83e\81[\83^\83X\95\\8e¦
727         Gdiplus::Image *img = NULL;
728         unsigned int nowTime = sys->getTime();
729         switch(getStatus()){
730                 case Servent::S_CONNECTING:
731                         img = img_connect;
732                         break;
733                 case Servent::S_CONNECTED:
734                         if (lastSkipTime + 120 > nowTime){
735                                 if (chanHit.relay){
736                                         img = img_conn_ok_skip;
737                                 } else {
738                                         if (chanHit.numRelays){
739                                                 img = img_conn_full_skip;
740                                         } else {
741                                                 img = img_conn_over_skip;
742                                         }
743                                 }
744                         } else {
745                                 if (chanHit.relay){
746                                         img = img_conn_ok;
747                                 } else {
748                                         if (chanHit.numRelays){
749                                                 img = img_conn_full;
750                                         } else {
751                                                 img = img_conn_over;
752                                         }
753                                 }
754                         }
755                         break;
756                 default:
757                         break;
758         }
759
760         // \95\8e\9a\95`\89æ\94Í\88Í\8ew\92è
761         RectF r1(origin.X + img->GetWidth() + 2, origin.Y, 800.0f, 13.0f);
762         RectF r2;
763         StringFormat format;
764         format.SetAlignment(StringAlignmentNear);
765         g->MeasureString(bstr1, -1, &font, r1, &format, &r2);
766
767         w = (INT)r2.Width + img->GetWidth() + 2;
768         // ServentData\95\\8e¦\95\94\82Ì\94w\8ci\82ð\93h\82é
769         if (getSelected()){
770                 // \91I\91ð\92\86
771                 SolidBrush b(Color(160,49,106,197));
772                 g->FillRectangle(&b, x, y, w, 13);
773         } else {
774                 // \94ñ\91I\91ð
775                 SolidBrush b(Color(160,200,200,200));
776                 g->FillRectangle(&b, x, y, w, 13);
777         }
778
779         // \83X\83e\81[\83^\83X\95\\8e¦\88Ê\92u
780         Rect img_rect((INT)origin.X, (INT)origin.Y+1, img ? img->GetWidth() : 12, 12);
781         // \83X\83e\81[\83^\83X\95`\89æ
782         ImageAttributes att;
783 //      att.SetColorKey(Color::White, Color::White, ColorAdjustTypeBitmap);
784         g->DrawImage(img, img_rect, 0, 0, img_rect.Width, 12, UnitPixel, &att);
785         // \8e\9f\82Ì\8aî\93_
786         origin.X += 12;
787
788         g->DrawString(bstr1, -1, &font, r2, &format, strBrush);
789         // \8e\9f\82Ì\8aî\93_
790         origin.X += r2.Width;
791         origin.Y += 13;
792
793         setWidth((int)origin.X-posX);
794         setHeight((int)origin.Y - posY);
795
796         ::delete strBrush;
797         return 0;
798 }
799
800 bool ServentData::checkDown(int x, int y){
801         if (    
802                         (x > posX)
803                 &&      (x < posX + getWidth())
804                 &&      (y > posY)
805                 &&      (y < posY + getHeight())
806         ){
807                 return TRUE;
808         }
809         return FALSE;
810 }
811
812
813 THREAD_PROC GUIDataUpdate(ThreadInfo *thread){
814         int i;
815
816         // set GUI thread status to running
817         thread->finish = false;
818
819         while(thread->active){
820                 // \83`\83\83\83\93\83l\83\8b\83f\81[\83^\83\8d\83b\83N
821                 ChannelDataLock.on();
822                 // \83`\83\83\83\93\83l\83\8b\83f\81[\83^\82Ì\8dX\90V\83t\83\89\83O\82ð\91S\82ÄFALSE\82É\82·\82é
823                 ChannelData *cd = channelDataTop;
824                 while(cd){
825                         // Servent\82Ì\8dX\90V\83t\83\89\83O\82ðFALSE\82É\82·\82é
826                         ServentData *sv = cd->getServentDataTop();
827                         while(sv){
828                                 sv->setEnableFlg(FALSE);
829                                 sv = sv->getNextData();
830                         }
831                         cd->setEnableFlg(FALSE);
832                         cd = cd->getNextData();
833                 }
834
835                 Channel *c = chanMgr->channel;
836                 // \8c»\8dÝ\91\8dÝ\82·\82é\83`\83\83\83\93\83l\83\8b\95ª\83\8b\81[\83v
837                 while(c){
838                         // \8aù\82É\83`\83\83\83\93\83l\83\8b\83f\81[\83^\82ð\8e\9d\82Á\82Ä\82¢\82é\82©
839                         cd = channelDataTop;
840                         // \94­\8c©\83t\83\89\83OFALSE
841                         bool bFoundFlg = FALSE;
842                         while(cd){
843                                 if (cd->getChannelId() == c->channel_id){
844                                         //\8aù\82É\83`\83\83\83\93\83l\83\8b\83f\81[\83^\82ª\82 \82é\82Ì\82Å\81A\82»\82Ì\82Ü\82Ü\8dX\90V
845                                         cd->setData(c);
846                                         // \8dX\90V\83t\83\89\83OTRUE
847                                         cd->setEnableFlg(TRUE);
848                                         // \94­\8c©\83t\83\89\83OTRUE
849                                         bFoundFlg = TRUE;
850                                         // \83\8b\81[\83v\97£\92E
851                                         break;
852                                 }
853                                 // \8c©\82Â\82©\82ç\82È\82©\82Á\82½\8fê\8d\87\81A\8e\9f\82Ì\83f\81[\83^\82ð\83`\83F\83b\83N
854                                 cd = cd->getNextData();
855                         }
856
857                         // \90V\82µ\82¢\83`\83\83\83\93\83l\83\8b\82Ì\8fê\8d\87\81A\90V\8bK\83f\81[\83^\8dì\90¬
858                         if (!bFoundFlg){
859                                 // \90V\8bK\83f\81[\83^\8dì\90¬
860                                 cd = ::new ChannelData();
861                                 // \83f\81[\83^\8dX\90V
862                                 cd->setData(c);
863                                 // \8dX\90V\83t\83\89\83OTRUE
864                                 cd->setEnableFlg(TRUE);
865
866                                 // \90V\8bK\83f\81[\83^\82ð\83\8a\83X\83g\82Ì\90æ\93ª\82É\93ü\82ê\82é
867                                 cd->setNextData(channelDataTop);
868                                 channelDataTop = cd;
869                         }
870                         // \8e\9f\82Ì\83`\83\83\83\93\83l\83\8b\82ð\8eæ\93¾
871                         c = c->next;
872                 }
873
874                 // \83`\83\83\83\93\83l\83\8b\82ª\82È\82­\82È\82Á\82Ä\82¢\82é\8fê\8d\87\82Ì\8f\88\97\9d
875                 cd = channelDataTop;
876                 ChannelData *prev = NULL; 
877                 while(cd){
878                         // \83f\81[\83^\82ð\8dX\90V\82µ\82È\82©\82Á\82½\82©
879                         if (cd->getEnableFlg() == FALSE){
880                                 // \83`\83\83\83\93\83l\83\8b\82ª\82È\82­\82È\82Á\82Ä\82¢\82é\82Ì\82Å\8dí\8f\9c
881                                 ChannelData *next;
882                                 next = cd->getNextData();
883                                 if (!prev){
884                                         // \90æ\93ª\82Ì\83f\81[\83^\82ð\8dí\8f\9c
885                                         channelDataTop = next;
886                                 } else {
887                                         // \93r\92\86\82Ì\83f\81[\83^\82ð\8dí\8f\9c
888                                         prev->setNextData(next);
889                                 }
890                                 // \8e\9f\82Ì\83f\81[\83^\82Ö
891                                 cd = next;
892                         } else {
893                                 // \83f\81[\83^\8dX\90V\8dÏ\81F\8e\9f\82Ì\83f\81[\83^\82Ö
894                                 prev = cd;
895                                 cd = cd->getNextData();
896                         }
897                 }
898
899                 Servent *s = servMgr->servents;
900                 while(s){
901                         // \8f\89\8aú\89»
902                         ChanHitList *chl;
903                         bool infoFlg = false;
904                         bool relay = true;
905                         bool firewalled = false;
906                         unsigned int numRelays = 0;
907                         int vp_ver = 0;
908                         char ver_ex_prefix[2] = {' ',' '};
909                         int ver_ex_number = 0;
910                         // \92¼\89º\83z\83X\83g\8fî\95ñ\83`\83F\83b\83N
911                         unsigned int totalRelays = 0;
912                         unsigned int totalListeners = 0;
913
914                         ChanHit hitData;
915                         // \8eó\90M\92\86\82©
916                         if ((s->type == Servent::T_RELAY) && (s->status == Servent::S_CONNECTED)){
917                                 // \83z\83X\83g\8fî\95ñ\83\8d\83b\83N
918                                 chanMgr->hitlistlock.on();
919                                 // \92¼\89º\83z\83X\83g\82ª\8eó\90M\82µ\82Ä\82¢\82é\83`\83\83\83\93\83l\83\8b\82Ì\83z\83X\83g\8fî\95ñ\82ð\8eæ\93¾
920                                 chl = chanMgr->findHitListByID(s->chanID);
921                                 // \83`\83\83\83\93\83l\83\8b\82Ì\83z\83X\83g\8fî\95ñ\82ª\82 \82é\82©
922                                 if (chl){
923                                         // \83`\83\83\83\93\83l\83\8b\82Ì\83z\83X\83g\8fî\95ñ\82ª\82 \82é\8fê\8d\87
924                                         ChanHit *hit = chl->hit;
925                                         //\81@\83`\83\83\83\93\83l\83\8b\82Ì\83z\83X\83g\8fî\95ñ\82ð\91S\91\96\8d¸\82µ\82Ä
926                                         while(hit){
927                                                 // ID\82ª\93¯\82\82à\82Ì\82Å\82 \82ê\82Î
928                                                 if (hit->servent_id == s->servent_id){
929                                                         // \83g\81[\83^\83\8b\83\8a\83\8c\81[\82Æ\83g\81[\83^\83\8b\83\8a\83X\83i\81[\82ð\89Á\8eZ
930                                                         totalRelays += hit->numRelays;
931                                                         totalListeners += hit->numListeners;
932                                                         // \92¼\89º\82Å\82 \82ê\82Î
933                                                         if (hit->numHops == 1){
934                                                                 // \8fî\95ñ\82ð\88ê\92U\95Û\91
935                                                                 infoFlg = true;
936                                                                 hitData.relay = hit->relay;
937                                                                 hitData.firewalled = hit->firewalled;
938                                                                 hitData.numRelays = hit->numRelays;
939                                                                 hitData.version_vp = hit->version_vp;
940                                                                 hitData.version_ex_prefix[0] = hit->version_ex_prefix[0];
941                                                                 hitData.version_ex_prefix[1] = hit->version_ex_prefix[1];
942                                                                 hitData.version_ex_number = hit->version_ex_number;
943                                                         }
944                                                 }
945                                                 // \8e\9f\82ð\83`\83F\83b\83N
946                                                 hit = hit->next;
947                                         }
948                                 }
949
950                                 // \83`\83\83\83\93\83l\83\8b\83f\81[\83^\82©\82çServent\82ð\8c\9f\8dõ
951                                 bool bFoundFlg = FALSE;
952                                 cd = channelDataTop;
953                                 while(cd){
954                                         ServentData *sv = cd->findServentData(s->servent_id);
955                                         // ServentData\82ª\82 \82ê\82Î
956                                         if (sv){
957                                                 // \83f\81[\83^\90Ý\92è
958                                                 sv->setData(s, &hitData, totalListeners, totalRelays, infoFlg);
959                                                 sv->setEnableFlg(TRUE);
960                                                 bFoundFlg = TRUE;
961                                                 break;
962                                         }
963                                         cd = cd->getNextData();
964                                 }
965                                 // ServentData\82ª\8c©\82Â\82©\82ç\82È\82©\82Á\82½\8fê\8d\87
966                                 if (!bFoundFlg){
967                                         // \83`\83\83\83\93\83l\83\8b\83f\81[\83^\82ð\92T\82·
968                                         cd = channelDataTop;
969                                         while(cd){
970                                                 // \83`\83\83\83\93\83l\83\8bID\82ª\93¯\82\82©
971                                                 if (cd->getChannelId() == s->channel_id){
972                                                         // \83f\81[\83^\90Ý\92è
973                                                         ServentData *sv = ::new ServentData();
974                                                         sv->setData(s, &hitData, totalListeners, totalRelays, infoFlg);
975                                                         sv->setEnableFlg(TRUE);
976                                                         // \83`\83\83\83\93\83l\83\8b\83f\81[\83^\82ÉServentData\92Ç\89Á
977                                                         cd->addServentData(sv);
978                                                         // \83z\83X\83g\96¼\82ð\8eæ\93¾\82·\82é
979                                                         IdData *id = ::new IdData(cd->getChannelId(), sv->getServentId(), sv->getHost().ip);
980                                                         ThreadInfo t;
981                                                         t.func = GetHostName;
982                                                         t.data = (void*)id;
983                                                         sys->startThread(&t);
984                                                         // \83\8b\81[\83v\8fI\97¹
985                                                         break;
986                                                 }
987                                                 // \8e\9f\82Ì\83f\81[\83^\82Ö
988                                                 cd = cd->getNextData();
989                                         }
990                                 }
991                                 // \83z\83X\83g\8fî\95ñ\83A\83\93\83\8d\83b\83N
992                                 chanMgr->hitlistlock.off();
993                         }
994                         s = s->next;
995                 }
996
997                 // \8dX\90V\82µ\82Ä\82¢\82È\82¢ServentData\82ð\8dí\8f\9c
998                 cd = channelDataTop;
999                 while(cd){
1000                         cd->deleteDisableServents();
1001                         cd = cd->getNextData();
1002                 }
1003
1004                 // \83`\83\83\83\93\83l\83\8b\83f\81[\83^\83A\83\93\83\8d\83b\83N
1005                 ChannelDataLock.off();
1006
1007                 // \95`\89æ\8dX\90V
1008                 if (guiWnd){
1009                         MakeBack(guiWnd);
1010                 }
1011
1012                 // 0.1\95b\81~10\82Å1\95b\91Ò\82¿
1013                 for(i=0; i<10; i++)
1014                 {
1015                         if (!thread->active)
1016                                 break;
1017                         sys->sleep(100);
1018                 }
1019
1020                 if (gbGetFile && (sys->getTime() > gtGetFile)){
1021                         gbGetFile = false;
1022                         gtiGetFile.func = GetInternetFile;
1023                         gtiGetFile.data = NULL;
1024                         sys->startThread(&gtiGetFile);
1025                 }
1026                 else if (gbStart && (sys->getTime() > gtStartTime)){
1027                         gbStart = false;
1028                         SendMessage(guiWnd, WM_START, 0, 0);
1029                         gtiStart.func = FestivalStart;
1030                         gtiStart.data = NULL;
1031                         sys->startThread(&gtiStart);
1032                 }
1033         }
1034
1035         // set GUI thread status to terminated
1036         thread->finish = true;
1037
1038         return 0;
1039 }
1040
1041 ChannelData *findChannelData(int channel_id){
1042         ChannelData *cd = channelDataTop;
1043
1044         while(cd){
1045                 if (cd->getChannelId() == channel_id){
1046                         return cd;
1047                 }
1048                 cd = cd->getNextData();
1049         }
1050
1051         return NULL;
1052 }
1053
1054
1055 void PopupChannelMenu(int channel_id){
1056         POINT pos;
1057         MENUITEMINFO info, separator;
1058         HMENU hMenu;
1059         DWORD dwID;
1060
1061         hMenu = CreatePopupMenu();
1062
1063         memset(&separator, 0, sizeof(MENUITEMINFO));
1064         separator.cbSize = sizeof(MENUITEMINFO);
1065         separator.fMask = MIIM_ID | MIIM_TYPE;
1066         separator.fType = MFT_SEPARATOR;
1067         separator.wID = 8000;
1068
1069         memset(&info, 0, sizeof(MENUITEMINFO));
1070         info.cbSize = sizeof(MENUITEMINFO);
1071         info.fMask = MIIM_ID | MIIM_TYPE;
1072         info.fType = MFT_STRING;
1073
1074         ChannelData *cd = findChannelData(channel_id);
1075
1076         if (cd == NULL){
1077                 return;
1078         }
1079
1080         info.wID = 1001;
1081         info.dwTypeData = "\90Ø\92f";
1082         InsertMenuItem(hMenu, -1, true, &info);
1083
1084         InsertMenuItem(hMenu, -1, true, &separator);
1085
1086         info.wID = 1000;
1087         info.dwTypeData = "\8dÄ\90¶";
1088         InsertMenuItem(hMenu, -1, true, &info);
1089
1090         InsertMenuItem(hMenu, -1, true, &separator);
1091
1092         info.wID = 1002;
1093         info.dwTypeData = "\8dÄ\90Ú\91±";
1094         InsertMenuItem(hMenu, -1, true, &info);
1095
1096         info.wID = 1003;
1097         info.dwTypeData = "\83L\81[\83v";
1098         InsertMenuItem(hMenu, -1, true, &info);
1099
1100         InsertMenuItem(hMenu, -1, true, &separator);
1101
1102         if (!cd->getOpenFlg()){
1103                 info.wID = 1004;
1104                 info.dwTypeData = "\92¼\89º\95\\8e¦";
1105                 InsertMenuItem(hMenu, -1, true, &info);
1106         } else {
1107                 info.wID = 1005;
1108                 info.dwTypeData = "\92¼\89º\89B\95Á";
1109                 InsertMenuItem(hMenu, -1, true, &info);
1110         }
1111
1112         GetCursorPos(&pos);
1113         dwID = TrackPopupMenu(hMenu, TPM_LEFTALIGN|TPM_RETURNCMD, pos.x, pos.y, 0, guiWnd, NULL);
1114
1115         DestroyMenu(hMenu);
1116
1117         cd = findChannelData(channel_id);
1118
1119         if (cd == NULL){
1120                 return;
1121         }
1122
1123         Channel *c = chanMgr->findChannelByChannelID(channel_id);
1124
1125         if (c == NULL){
1126                 return;
1127         }
1128
1129         switch(dwID){
1130                 case 1000:      // \8dÄ\90
1131                         chanMgr->playChannel(c->info);
1132                         break;
1133
1134                 case 1001:      // \90Ø\92f
1135                         c->thread.active = false;
1136                         c->thread.finish = true;
1137                         break;
1138
1139                 case 1002:      // \8dÄ\90Ú\91±
1140                         // \92¼\89º\82©\82Â\8eó\90M\92\86\82Å\82 \82ê\82Î\8am\94F\83\81\83b\83Z\81[\83W\95\\8e¦
1141                         if (cd->isTracker() && cd->getStatus() == Channel::S_RECEIVING)
1142                         {
1143                                 int id;
1144                                 id = MessageBox(guiWnd,
1145                                         "\92¼\89º\82Å\82·\82ª\8dÄ\90Ú\91±\82µ\82Ü\82·\82©\81H",
1146                                         "\92¼\89º\8cx\8d\90",
1147                                         MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2);
1148                                 if (id != IDYES)
1149                                         break;
1150                         }
1151
1152                         c->bump = true;
1153                         break;
1154
1155                 case 1003:      // \83L\81[\83v
1156                         if (!c->stayConnected){
1157                                 c->stayConnected  = true;
1158                         } else {
1159                                 c->stayConnected = false;
1160                         }
1161                         break;
1162
1163                 case 1004:      // \92¼\89º\95\\8e¦
1164                         cd->setOpenFlg(TRUE);
1165                         MakeBack(guiWnd);
1166                         break;
1167
1168                 case 1005:      // \92¼\89º\89B\95Á
1169                         cd->setOpenFlg(FALSE);
1170                         MakeBack(guiWnd);
1171                         break;
1172         }
1173 }
1174
1175 void PopupServentMenu(int servent_id){
1176         POINT pos;
1177         MENUITEMINFO info, separator;
1178         HMENU hMenu;
1179         DWORD dwID;
1180
1181         hMenu = CreatePopupMenu();
1182
1183         memset(&separator, 0, sizeof(MENUITEMINFO));
1184         separator.cbSize = sizeof(MENUITEMINFO);
1185         separator.fMask = MIIM_ID | MIIM_TYPE;
1186         separator.fType = MFT_SEPARATOR;
1187         separator.wID = 8000;
1188
1189         memset(&info, 0, sizeof(MENUITEMINFO));
1190         info.cbSize = sizeof(MENUITEMINFO);
1191         info.fMask = MIIM_ID | MIIM_TYPE;
1192         info.fType = MFT_STRING;
1193
1194         ServentData *sd = NULL;
1195         ChannelData *cd = channelDataTop;
1196         while(cd){
1197                 sd = cd->findServentData(servent_id);
1198                 if (sd){
1199                         break;
1200                 }
1201                 cd = cd->getNextData();
1202         }
1203
1204         if (cd == NULL || sd == NULL){
1205                 return;
1206         }
1207
1208         info.wID = 1001;
1209         info.dwTypeData = "\90Ø\92f";
1210         InsertMenuItem(hMenu, -1, true, &info);
1211
1212 //      InsertMenuItem(hMenu, -1, true, &separator);
1213
1214         GetCursorPos(&pos);
1215         dwID = TrackPopupMenu(hMenu, TPM_LEFTALIGN|TPM_RETURNCMD, pos.x, pos.y, 0, guiWnd, NULL);
1216
1217         DestroyMenu(hMenu);
1218
1219         cd = channelDataTop;
1220         while(cd){
1221                 sd = cd->findServentData(servent_id);
1222                 if (sd){
1223                         break;
1224                 }
1225                 cd = cd->getNextData();
1226         }
1227
1228         if (cd == NULL || sd == NULL){
1229                 return;
1230         }
1231
1232         Servent *s = servMgr->findServentByServentID(servent_id);
1233
1234         if (s == NULL){
1235                 return;
1236         }
1237
1238         switch(dwID){
1239                 case 1001:      // \90Ø\92f
1240                         s->thread.active = false;
1241                         break;
1242
1243         }
1244 }
1245
1246 void PopupOtherMenu(){
1247         POINT pos;
1248         MENUITEMINFO info, separator;
1249         HMENU hMenu;
1250         DWORD dwID;
1251
1252         hMenu = CreatePopupMenu();
1253
1254         memset(&separator, 0, sizeof(MENUITEMINFO));
1255         separator.cbSize = sizeof(MENUITEMINFO);
1256         separator.fMask = MIIM_ID | MIIM_TYPE;
1257         separator.fType = MFT_SEPARATOR;
1258         separator.wID = 8000;
1259
1260         memset(&info, 0, sizeof(MENUITEMINFO));
1261         info.cbSize = sizeof(MENUITEMINFO);
1262         info.fMask = MIIM_ID | MIIM_TYPE;
1263         info.fType = MFT_STRING;
1264
1265         if (!gbDispTop){
1266                 info.wID = 1101;
1267                 info.dwTypeData = "\8dÅ\91O\96Ê\95\\8e¦";
1268                 InsertMenuItem(hMenu, -1, true, &info);
1269         } else {
1270                 info.wID = 1102;
1271                 info.dwTypeData = "\8dÅ\91O\96Ê\89ð\8f\9c";
1272                 InsertMenuItem(hMenu, -1, true, &info);
1273         }
1274
1275         InsertMenuItem(hMenu, -1, true, &separator);
1276
1277         if (!gbAllOpen){
1278                 info.wID = 1103;
1279                 info.dwTypeData = "\91S\92¼\89º\93W\8aJ";
1280                 InsertMenuItem(hMenu, -1, true, &info);
1281         } else {
1282                 info.wID = 1104;
1283                 info.dwTypeData = "\91S\92¼\89º\89B\95Á";
1284                 InsertMenuItem(hMenu, -1, true, &info);
1285         }
1286
1287         InsertMenuItem(hMenu, -1, true, &separator);
1288
1289         if (!servMgr->autoServe){
1290                 info.wID = 1105;
1291                 info.dwTypeData = "\97L\8cø";
1292                 InsertMenuItem(hMenu, -1, true, &info);
1293         } else {
1294                 info.wID = 1106;
1295                 info.dwTypeData = "\96³\8cø";
1296                 InsertMenuItem(hMenu, -1, true, &info);
1297         }
1298
1299         GetCursorPos(&pos);
1300         dwID = TrackPopupMenu(hMenu, TPM_LEFTALIGN|TPM_RETURNCMD, pos.x, pos.y, 0, guiWnd, NULL);
1301
1302         DestroyMenu(hMenu);
1303
1304         ChannelData *cd = channelDataTop;
1305
1306         switch(dwID){
1307                 case 1101:      // \8dÅ\91O\96Ê\95\\8e¦
1308                         gbDispTop = true;
1309                         ::SetWindowPos(guiWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
1310                         break;
1311
1312                 case 1102:      // \8dÅ\91O\96Ê\89ð\8f\9c
1313                         gbDispTop = false;
1314                         ::SetWindowPos(guiWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
1315                         break;
1316
1317                 case 1103:      // \91S\92¼\89º\93W\8aJ
1318                         gbAllOpen = true;
1319                         while(cd){
1320                                 cd->setOpenFlg(true);
1321                                 cd = cd->getNextData();
1322                         }
1323                         break;
1324
1325                 case 1104:      // \91S\92¼\89º\89B\95Á
1326                         gbAllOpen = false;
1327                         while(cd){
1328                                 cd->setOpenFlg(false);
1329                                 cd = cd->getNextData();
1330                         }
1331                         break;
1332
1333                 case 1105:      // \97L\8cø
1334                         servMgr->autoServe = true;
1335                         break;
1336
1337                 case 1106:      // \96³\8cø
1338                         servMgr->autoServe = false;
1339                         break;
1340
1341         }
1342 }
1343
1344 void WmCreateProc(HWND hwnd){
1345         if (backImage){
1346                 ::delete backImage;
1347         }
1348         _bstr_t bstr("back.jpg");
1349         backImage = ::new Image(bstr);
1350
1351         MakeBack(hwnd, 800, 600);
1352
1353         guiThread.func = GUIDataUpdate;
1354         if (!sys->startThread(&guiThread)){
1355                 MessageBox(hwnd,"Unable to start GUI","PeerCast",MB_OK|MB_ICONERROR);
1356                 PostMessage(hwnd,WM_DESTROY,0,0);
1357         }
1358         if (guiFlg){
1359                 SetWindowPlacement(hwnd, &winPlace);
1360         }
1361
1362         if (img_idle){
1363                 ::delete img_idle;
1364                 ::delete img_connect;
1365                 ::delete img_conn_ok;
1366                 ::delete img_conn_full;
1367                 ::delete img_conn_over;
1368                 ::delete img_conn_ok_skip;
1369                 ::delete img_conn_full_skip;
1370                 ::delete img_conn_over_skip;
1371                 ::delete img_error;
1372                 ::delete img_broad_ok;
1373                 ::delete img_broad_full;
1374         }
1375         bstr = L"ST_IDLE.bmp";
1376         img_idle = ::new Image(bstr);
1377         bstr = L"ST_CONNECT.bmp";
1378         img_connect = ::new Image(bstr);
1379         bstr = L"ST_CONN_OK.bmp";
1380         img_conn_ok = ::new Image(bstr);
1381         bstr = L"ST_CONN_FULL.bmp";
1382         img_conn_full = ::new Image(bstr);
1383         bstr = L"ST_CONN_OVER.bmp";
1384         img_conn_over = ::new Image(bstr);
1385         bstr = L"ST_CONN_OK_SKIP.bmp";
1386         img_conn_ok_skip = ::new Image(bstr);
1387         bstr = L"ST_CONN_FULL_SKIP.bmp";
1388         img_conn_full_skip = ::new Image(bstr);
1389         bstr = L"ST_CONN_OVER_SKIP.bmp";
1390         img_conn_over_skip = ::new Image(bstr);
1391         bstr = L"ST_ERROR.bmp";
1392         img_error = ::new Image(bstr);
1393         bstr = L"ST_BROAD_OK.bmp";
1394         img_broad_ok = ::new Image(bstr);
1395         bstr = L"ST_BROAD_FULL.bmp";
1396         img_broad_full = ::new Image(bstr);
1397 }
1398
1399 void WmPaintProc(HWND hwnd){
1400         HDC hdc;
1401         PAINTSTRUCT paint;
1402
1403         if (backGra){
1404                 MakeBackLock.on();
1405                 hdc = BeginPaint(hwnd, &paint);
1406                 RECT *rcRect;   // \95`\89æ\94Í\88Í
1407                 rcRect = &(paint.rcPaint);
1408                 LONG width = rcRect->right - rcRect->left + 1;
1409                 LONG height = rcRect->bottom - rcRect->top + 1;
1410
1411                 Graphics g2(hdc);
1412                 Rect r(rcRect->left, rcRect->top, width, height);
1413                 g2.DrawImage(backBmp,r, rcRect->left, rcRect->top, width, height, UnitPixel);
1414                 EndPaint(hwnd, &paint);
1415                 MakeBackLock.off();
1416         }
1417 }
1418
1419 void WmSizeProc(HWND hwnd, LPARAM lParam){
1420         UINT width = LOWORD(lParam);
1421         UINT height = HIWORD(lParam);
1422
1423         MakeBack(hwnd, width, height);
1424
1425 }
1426
1427 void WmLButtonDownProc(HWND hwnd, LPARAM lParam){
1428         ChannelData *cd;
1429         bool changeFlg = FALSE;
1430
1431         ChannelDataLock.on();
1432         cd = channelDataTop;
1433         while(cd){
1434                 int x = LOWORD(lParam);
1435                 int y = HIWORD(lParam);
1436                 if (cd->checkDown(LOWORD(lParam), HIWORD(lParam))){
1437                         if (!(cd->isSelected())){
1438                                 changeFlg = TRUE;
1439                         }
1440                         cd->setSelected(TRUE);
1441                 } else {
1442                         if (cd->isSelected()){
1443                                 changeFlg = TRUE;
1444                         }
1445                         cd->setSelected(FALSE);
1446                 }
1447                 int sx = cd->getPosX() + cd->getWidth();
1448                 int sy = cd->getPosY();
1449                 int index = 0;
1450                 ServentData *sd = cd->getServentDataTop();
1451                 while(sd){
1452                         if (    (       (!cd->getOpenFlg())
1453                                         &&      (sx + index*14 < x)
1454                                         &&      (x < sx + (index+1)*14)
1455                                         &&      (sy < y)
1456                                         &&      (y < sy + 14)   )
1457                                 ||      sd->checkDown(LOWORD(lParam), HIWORD(lParam))
1458                         ){
1459                                 if (!sd->getSelected()){
1460                                         changeFlg = TRUE;
1461                                 }
1462                                 sd->setSelected(TRUE);
1463                         } else {
1464                                 if (sd->getSelected()){
1465                                         changeFlg = TRUE;
1466                                 }
1467                                 sd->setSelected(FALSE);
1468                         }
1469                         sd = sd->getNextData();
1470                         index++;
1471                 }
1472                 cd = cd->getNextData();
1473         }
1474         ChannelDataLock.off();
1475         if (changeFlg){
1476                 MakeBack(hwnd);
1477         }
1478 }
1479
1480 void WmLButtonDblclkProc(HWND hwnd, LPARAM lParam){
1481         ChannelData *cd;
1482         bool changeFlg = FALSE;
1483
1484         ChannelDataLock.on();
1485         cd = channelDataTop;
1486         while(cd){
1487                 int x = LOWORD(lParam);
1488                 int y = HIWORD(lParam);
1489                 if (cd->checkDown(LOWORD(lParam), HIWORD(lParam))){
1490                         if (!(cd->isSelected())){
1491                                 changeFlg = TRUE;
1492                         }
1493                         if (!(cd->getOpenFlg())){
1494                                 changeFlg = TRUE;
1495                                 cd->setOpenFlg(TRUE);
1496                         } else {
1497                                 changeFlg = TRUE;
1498                                 cd->setOpenFlg(FALSE);
1499                         }
1500                         cd->setSelected(TRUE);
1501                 } else {
1502                         if (cd->isSelected()){
1503                                 changeFlg = TRUE;
1504                         }
1505                         cd->setSelected(FALSE);
1506                 }
1507 /*              int sx = cd->getPosX() + cd->getWidth();
1508                 int sy = cd->getPosY();
1509                 int index = 0;
1510                 ServentData *sd = cd->getServentDataTop();
1511                 while(sd){
1512                         if (    (       (!cd->getOpenFlg())
1513                                         &&      (sx + index*14 < x)
1514                                         &&      (x < sx + (index+1)*14)
1515                                         &&      (sy < y)
1516                                         &&      (y < sy + 14)   )
1517                                 ||      sd->checkDown(LOWORD(lParam), HIWORD(lParam))
1518                         ){
1519                                 if (!sd->getSelected()){
1520                                         changeFlg = TRUE;
1521                                 }
1522                                 sd->setSelected(TRUE);
1523                         } else {
1524                                 if (sd->getSelected()){
1525                                         changeFlg = TRUE;
1526                                 }
1527                                 sd->setSelected(FALSE);
1528                         }
1529                         sd = sd->getNextData();
1530                         index++;
1531                 }*/
1532                 cd = cd->getNextData();
1533         }
1534         ChannelDataLock.off();
1535         if (changeFlg){
1536                 MakeBack(hwnd);
1537         }
1538 }
1539
1540 void WmRButtonDownProc(HWND hwnd, LPARAM lParam){
1541         ChannelData *cd;
1542         bool changeFlg = FALSE;
1543         bool channel_selected = FALSE;
1544         bool servent_selected = FALSE;
1545         int channel_id = 0;
1546         int servent_id = 0;
1547
1548         cd = channelDataTop;
1549         while(cd){
1550                 if (cd->checkDown(LOWORD(lParam), HIWORD(lParam))){
1551                         if (!(cd->isSelected())){
1552                                 changeFlg = TRUE;
1553                         }
1554                         cd->setSelected(TRUE);
1555                         channel_id = cd->getChannelId();
1556                         channel_selected = TRUE;
1557                 } else {
1558                         if (cd->isSelected()){
1559                                 changeFlg = TRUE;
1560                         }
1561                         cd->setSelected(FALSE);
1562                 }
1563                 ServentData *sd = cd->getServentDataTop();
1564                 while(sd){
1565                         if (sd->checkDown(LOWORD(lParam), HIWORD(lParam))){
1566                                 if (!sd->getSelected()){
1567                                         changeFlg = TRUE;
1568                                 }
1569                                 sd->setSelected(TRUE);
1570                                 servent_id = sd->getServentId();
1571                                 servent_selected = TRUE;
1572                         } else {
1573                                 if (sd->getSelected()){
1574                                         changeFlg = TRUE;
1575                                 }
1576                                 sd->setSelected(FALSE);
1577                         }
1578                         sd = sd->getNextData();
1579                 }
1580                 cd = cd->getNextData();
1581         }
1582         if (changeFlg){
1583                 MakeBack(hwnd);
1584         }
1585
1586         if (channel_selected){
1587                 PopupChannelMenu(channel_id);
1588         } else if (servent_selected){
1589                 PopupServentMenu(servent_id);
1590         } else {
1591                 PopupOtherMenu();
1592         }
1593 }
1594
1595 LRESULT CALLBACK GUIProc (HWND hwnd, UINT message,
1596                                  WPARAM wParam, LPARAM lParam)
1597 {
1598         switch(message){
1599                 case WM_CREATE:         // \83E\83B\83\93\83h\83E\8dì\90¬
1600                         WmCreateProc(hwnd);
1601                         break;
1602
1603                 case WM_PAINT:          // \95`\89æ
1604                         WmPaintProc(hwnd);
1605                         break;
1606
1607                 case WM_SIZE:           // \83T\83C\83Y\95Ï\8dX
1608                         WmSizeProc(hwnd,lParam);
1609                         break;
1610
1611                 case WM_LBUTTONDOWN:    // \8d\83{\83^\83\93\89\9f\82·
1612                         WmLButtonDownProc(hwnd,lParam);
1613                         break;
1614
1615                 case WM_RBUTTONDOWN:    // \89E\83{\83^\83\93\89\9f\82·
1616                         WmRButtonDownProc(hwnd,lParam);
1617                         break;
1618
1619                 case WM_LBUTTONDBLCLK:          // \8d\83_\83u\83\8b\83N\83\8a\83b\83N
1620                         WmLButtonDblclkProc(hwnd,lParam);
1621                         break;
1622
1623                 case WM_ERASEBKGND:     // \94w\8ci\8fÁ\8b\8e
1624                         return TRUE;    // \94w\8ci\82Í\8fÁ\82³\82È\82¢
1625
1626                 case WM_CLOSE:
1627                         //if (backImage){
1628                         //      ::delete backImage;
1629                         //      backImage = NULL;
1630                         //}
1631                         GetWindowPlacement(hwnd, &winPlace);
1632                         guiFlg = true;
1633                         DestroyWindow( hwnd );
1634                         break;
1635                 case WM_DESTROY:
1636                         GetWindowPlacement(hwnd, &winPlace);
1637                         guiFlg = true;
1638                         guiThread.active = false;
1639
1640                         // wait until GUI thread terminated,
1641                         // and then dispose background image.
1642                         while (1)
1643                         {
1644                                 if (guiThread.finish)
1645                                         break;
1646                         }
1647                         if (backImage)
1648                         {
1649                                 ::delete backImage;
1650                                 backImage = NULL;
1651                         }
1652
1653                         guiWnd = NULL;
1654                         break;
1655                 case WM_START:
1656                         ghStart = ::CreateWindow(szWindowClass3,
1657                                 "Peercast-IM@S",
1658                                 WS_OVERLAPPEDWINDOW & ~(WS_MAXIMIZEBOX),
1659                                 0,
1660                                 0,
1661                                 400,
1662                                 300,
1663                                 NULL,
1664                                 NULL,
1665                                 hInst,
1666                                 NULL);
1667                         ::ShowWindow(ghStart, SW_SHOWNORMAL);
1668                         break;
1669
1670                 default:
1671                         return (DefWindowProc(hwnd, message, wParam, lParam));
1672         }
1673
1674         return 0;
1675 }
1676
1677 Gdiplus::Image *data1 = NULL;
1678 Gdiplus::Image *data2 = NULL;
1679 Gdiplus::Bitmap *startBmp = NULL;
1680 Gdiplus::Graphics *startGra = NULL;
1681 WLock MakeStartLock;
1682
1683 LRESULT CALLBACK StartProc (HWND hwnd, UINT message,
1684                                  WPARAM wParam, LPARAM lParam)
1685 {
1686         SolidBrush b(Color::Black);
1687         bstr_t bstr;
1688
1689         switch(message){
1690                 case WM_CREATE:
1691                         startBmp = ::new Bitmap(400,300);
1692                         startGra = ::new Graphics(startBmp);
1693                         bstr = L"data1.jpg";
1694                         data1 = ::new Image(bstr);
1695                         bstr = L"data2.jpg";
1696                         data2 = ::new Image(bstr);
1697                         // \8d\95\82Å\93h\82è\82Â\82Ô\82µ
1698                         startGra->FillRectangle(&b, 0, 0, 400, 300);
1699                         break;
1700                 case WM_PAINT:
1701                         if (startGra){
1702                                 HDC hdc;
1703                                 PAINTSTRUCT paint;
1704
1705                                 MakeStartLock.on();
1706                                 hdc = BeginPaint(hwnd, &paint);
1707                                 RECT *rcRect;
1708                                 rcRect = &(paint.rcPaint);
1709                                 LONG width = rcRect->right - rcRect->left + 1;
1710                                 LONG height = rcRect->bottom - rcRect->top + 1;
1711
1712                                 Graphics g2(hdc);
1713                                 Rect r(rcRect->left, rcRect->top, width, height);
1714                                 g2.DrawImage(startBmp, r, rcRect->left, rcRect->top, width, height, UnitPixel);
1715                                 EndPaint(hwnd, &paint);
1716                                 MakeStartLock.off();
1717                         }
1718                         break;
1719                 case WM_ERASEBKGND:
1720                         return TRUE;
1721                 case WM_CLOSE:
1722                         DestroyWindow(ghStart);
1723                         if (startBmp){
1724                                 ::delete startBmp;
1725                         }
1726                         if (startGra){
1727                                 ::delete startGra;
1728                         }
1729                         if (data1){
1730                                 ::delete data1;
1731                         }
1732                         if (data2){
1733                                 ::delete data2;
1734                         }
1735                         break;
1736
1737                 default:
1738                         return (DefWindowProc(hwnd, message, wParam, lParam));
1739         }
1740
1741         return 0;
1742 }
1743
1744 THREAD_PROC FestivalStart(ThreadInfo *thread){
1745
1746         while(startGra==NULL){
1747                 sys->sleep(100);
1748         }
1749
1750         sys->sleep(1000);
1751
1752         MakeStartLock.on();
1753         Font font(L"\82l\82\82o\83S\83V\83b\83N",40);
1754         StringFormat format;
1755         format.SetAlignment(StringAlignmentCenter);
1756         startGra->SetTextRenderingHint(TextRenderingHintAntiAlias);
1757         PointF origin(199.0f,49.0f);
1758         RectF rect(0,0,400,100);
1759         LinearGradientBrush b1(rect, Color::LightSkyBlue, Color::White, LinearGradientModeHorizontal);
1760         startGra->DrawString(L"\91æ\82Q\89ñ", -1, &font, origin, &format, &b1);
1761         origin.Y += 50;
1762         LinearGradientBrush b2(rect, Color::LightGreen, Color::White, LinearGradientModeHorizontal);
1763         startGra->DrawString(L"\83A\83C\83h\83\8b\83}\83X\83^\81[", -1, &font, origin, &format, &b2);
1764         origin.Y += 50;
1765         LinearGradientBrush b3(rect, Color::LightGoldenrodYellow, Color::White, LinearGradientModeHorizontal);
1766         startGra->DrawString(L"\83t\83@\83\93\8a´\8eÓ\8dÕ", -1, &font, origin, &format, &b3);
1767         MakeStartLock.off();
1768         InvalidateRect(ghStart, NULL, FALSE);
1769         sys->sleep(3000);
1770
1771         MakeStartLock.on();
1772         startGra->DrawImage(data1, Rect(0,0,80,400), 200,200,66,330, UnitPixel);
1773         MakeStartLock.off();
1774         InvalidateRect(ghStart, NULL, FALSE);
1775         sys->sleep(500);
1776
1777         MakeStartLock.on();
1778         startGra->DrawImage(data1, Rect(80,0,80,400), 266,200,66,330, UnitPixel);
1779         MakeStartLock.off();
1780         InvalidateRect(ghStart, NULL, FALSE);
1781         sys->sleep(500);
1782
1783         MakeStartLock.on();
1784         startGra->DrawImage(data1, Rect(160,0,80,400), 332,200,66,330, UnitPixel);
1785         MakeStartLock.off();
1786         InvalidateRect(ghStart, NULL, FALSE);
1787         sys->sleep(500);
1788
1789         MakeStartLock.on();
1790         startGra->DrawImage(data1, Rect(240,0,80,400), 398,200,66,330, UnitPixel);
1791         MakeStartLock.off();
1792         InvalidateRect(ghStart, NULL, FALSE);
1793         sys->sleep(500);
1794
1795         MakeStartLock.on();
1796         startGra->DrawImage(data1, Rect(320,0,80,400), 464,200,66,330, UnitPixel);
1797         MakeStartLock.off();
1798         InvalidateRect(ghStart, NULL, FALSE);
1799         sys->sleep(500);
1800
1801         MakeStartLock.on();
1802         startGra->DrawImage(data1, Rect(0,0,80,400), 530,200,54,270, UnitPixel);
1803         MakeStartLock.off();
1804         InvalidateRect(ghStart, NULL, FALSE);
1805         sys->sleep(500);
1806
1807         MakeStartLock.on();
1808         startGra->DrawImage(data1, Rect(80,0,80,400), 584,200,54,270, UnitPixel);
1809         MakeStartLock.off();
1810         InvalidateRect(ghStart, NULL, FALSE);
1811         sys->sleep(500);
1812
1813         MakeStartLock.on();
1814         startGra->DrawImage(data1, Rect(160,0,80,400), 638,200,54,270, UnitPixel);
1815         MakeStartLock.off();
1816         InvalidateRect(ghStart, NULL, FALSE);
1817         sys->sleep(500);
1818
1819         MakeStartLock.on();
1820         startGra->DrawImage(data1, Rect(240,0,80,400), 692,200,54,270, UnitPixel);
1821         MakeStartLock.off();
1822         InvalidateRect(ghStart, NULL, FALSE);
1823         sys->sleep(500);
1824
1825         MakeStartLock.on();
1826         startGra->DrawImage(data1, Rect(320,0,80,400), 746,200,54,270, UnitPixel);
1827         MakeStartLock.off();
1828         InvalidateRect(ghStart, NULL, FALSE);
1829         sys->sleep(500);
1830
1831         for (int i=1; i<=10; i++){
1832                 ColorMatrix mtx = {
1833                         1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
1834                         0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
1835                         0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
1836                         0.0f, 0.0f, 0.0f, 0.1f*i, 0.0f,
1837                         0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
1838                 ImageAttributes att;
1839
1840                 MakeStartLock.on();
1841                 att.SetColorMatrix(&mtx, ColorMatrixFlagsDefault, ColorAdjustTypeBitmap);
1842                 startGra->DrawImage(data2, Rect(0,0,400,300), 360,130,400,300, UnitPixel, &att);
1843                 MakeStartLock.off();
1844                 InvalidateRect(ghStart, NULL, FALSE);
1845                 sys->sleep(100);
1846         }
1847
1848         sys->sleep(2000);
1849
1850         MakeStartLock.on();
1851         INT style = FontStyleBold;
1852         Font font2(L"\82l\82\82o\83S\83V\83b\83N",70,style,UnitPoint);
1853         PointF origin2(199.0f,99.0f);
1854         SolidBrush bs(Color::Black);
1855         startGra->DrawString(L"START!", -1, &font2, origin2, &format, &bs);
1856         Font font3(L"\82l\82\82o\83S\83V\83b\83N",70,style,UnitPoint);
1857         LinearGradientBrush bx(rect, Color::LightPink, Color::DeepPink, LinearGradientModeHorizontal);
1858         startGra->DrawString(L"START!", -1, &font3, origin2, &format, &bx);
1859         MakeStartLock.off();
1860         InvalidateRect(ghStart, NULL, FALSE);
1861         sys->sleep(5000);
1862
1863         SendMessage(ghStart, WM_CLOSE, 0, 0);
1864         return 0;
1865 }