OSDN Git Service

感謝祭機能を削除
[peercast-im/PeerCastIM.git] / PeerCast.root / PeerCast / 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 bool gbDispTop = false;
109 bool gbAllOpen = false;
110
111 THREAD_PROC GetHostName(ThreadInfo *thread){
112         IdData *id = (IdData*)(thread->data);
113
114         HOSTENT *he;
115         unsigned int ip;
116         bool flg = TRUE;
117
118         ip = htonl(id->getIpAddr());
119
120         for (int i=0; i<5 && flg; i++){
121                 he = gethostbyaddr((char *)&ip,sizeof(ip),AF_INET);
122
123                 ChannelDataLock.on();
124                 ChannelData* cd = channelDataTop;
125                 if (he)
126                 {
127                         while(cd){
128                                 if (cd->setName(id->getServentId(), he->h_name)){
129                                         flg = FALSE;
130                                         break;
131                                 }
132                                 cd = cd->getNextData();
133                         }
134                 }
135 //              ::delete id;
136                 ChannelDataLock.off();
137                 sys->sleep(1000);
138         }
139
140
141         return 0;
142 }
143
144 int drawSpeed(Graphics *gra, int posX, int posY){
145
146         // \91¬\93x\95\\8e¦\95\94\82Ì\94w\8ci\82ð\94\92\82­\82·\82é
147         SolidBrush b(Color(180,255,255,255));
148         backGra->FillRectangle(&b, posX, posY, 200, 14);
149         // \83t\83H\83\93\83g\90Ý\92è
150         Font font(L"\82l\82\82o\83S\83V\83b\83N",10);
151         // \95\8e\9a\90F
152         SolidBrush strBrush(Color::Black);
153         // \95\8e\9a\97ñ\8dì\90¬
154         char tmp[256];
155         sprintf(tmp, "R:%.1fkbps S:%.1fkbps", 
156                 BYTES_TO_KBPS(stats.getPerSecond(Stats::BYTESIN)-stats.getPerSecond(Stats::LOCALBYTESIN)),
157                 BYTES_TO_KBPS(stats.getPerSecond(Stats::BYTESOUT)-stats.getPerSecond(Stats::LOCALBYTESOUT)));
158         _bstr_t bstr(tmp);
159         // \95\8e\9a\95\\8e¦\94Í\88Í\8ew\92è
160         StringFormat format;
161         format.SetAlignment(StringAlignmentCenter);
162         RectF r((REAL)posX, (REAL)posY, (REAL)200, (REAL)14);
163         // \95\8e\9a\95`\89æ
164         gra->DrawString(bstr, -1, &font, r, &format, &strBrush);
165
166
167
168         return posY + 15;
169 }
170
171 void MakeBack(HWND hwnd, UINT x, UINT y){
172         MakeBackLock.on();
173
174         winWidth = x;
175         winHeight = y;
176
177         if (backGra){
178                 ::delete backBmp;
179                 ::delete backGra;
180         }
181
182         backBmp = ::new Bitmap(x,y);
183         backGra = ::new Graphics(backBmp);
184
185         // \91S\82Ä\94\92\82Å\93h\82è\82Â\82Ô\82µ
186         SolidBrush b(Color(255,255,255,255));
187         backGra->FillRectangle(&b, 0, 0, x, y);
188
189         backWidth = backImage->GetWidth();
190         backHeight = backImage->GetHeight();
191
192         // \94w\8ci\89æ\91\9c\82ð\95`\89æ
193         for (UINT xx = 0; xx < x/backWidth + 1; xx++){
194                 for (UINT yy = 0; yy < y/backHeight + 1; yy++){
195                         UINT width,height;
196                         if (backWidth*(xx+1) > x){
197                                 width = x % backWidth;
198                         } else {
199                                 width = backWidth;
200                         }
201                         if (backHeight*(yy+1) > y){
202                                 height = y % backHeight;
203                         } else {
204                                 height = backHeight;
205                         }
206                         Rect r((INT)backWidth*xx, (INT)backHeight*yy, width, height);
207                         backGra->DrawImage(backImage, r, 0, 0, (INT)width, (INT)height, UnitPixel);
208                 }
209         }
210
211         INT posX = 20;
212         INT posY = 20;
213
214         // \91¬\93x\95`\89æ
215         drawSpeed(backGra, winWidth-205, 5);
216
217         // \83`\83\83\83\93\83l\83\8b\8fî\95ñ\82ð\95`\89æ
218         ChannelDataLock.on();
219         ChannelData *cd = channelDataTop;
220         while(cd){
221                 posY = cd->drawChannel(backGra, 20, posY);
222                 cd = cd->getNextData();
223         }
224         ChannelDataLock.off();
225         MakeBackLock.off();
226 }
227
228 void MakeBack(HWND hwnd){
229         MakeBack(hwnd, winWidth, winHeight);
230         ::InvalidateRect(guiWnd, NULL, FALSE);
231 }
232
233 void ChannelData::setData(Channel *c){
234         String sjis;
235         sjis = c->getName();
236         sjis.convertTo(String::T_SJIS);
237
238         strncpy(name, sjis, 256);
239         name[256] = '\0';
240         channel_id = c->channel_id;
241         bitRate = c->info.bitrate;
242         lastPlayStart = c->info.lastPlayStart;
243         status = c->status;
244         totalListeners = c->totalListeners();
245         totalRelays = c->totalRelays();
246         localListeners = c->localListeners();
247         localRelays = c->localRelays();
248         stayConnected = c->stayConnected;
249         chDisp = c->chDisp;
250         bTracker = c->sourceHost.tracker;
251         lastSkipTime = c->lastSkipTime;
252         skipCount = c->skipCount;
253 }
254
255 int gW = 0;
256 int gWS = 0;
257
258 int ChannelData::drawChannel(Graphics *g, int x, int y){
259         REAL xx = x * 1.0f;
260         REAL yy = y * 1.0f;
261         ServentData* sd;
262
263         // \88Ê\92u\82ð\95Û\91
264         posX = x;
265         posY = y;
266
267         int w/*,h*/;
268
269         if (getWidth() == 0){
270                 if (gW){
271                         w = gW;
272                 } else {
273                         w = 400;
274                 }
275         } else {
276                 w = getWidth();
277                 gW = w;
278         }
279
280         // \83`\83\83\83\93\83l\83\8b\95\\8e¦\95\94\82Ì\94w\8ci\82ð\93h\82é
281         if (isSelected()){
282                 // \91I\91ð\92\86
283                 SolidBrush b(Color(160,49,106,197));
284                 g->FillRectangle(&b, x, y, w, 14);
285         } else {
286                 // \94ñ\91I\91ð
287                 SolidBrush b(Color(160,255,255,255));
288                 g->FillRectangle(&b, x, y, w, 14);
289         }
290
291         // \83X\83e\81[\83^\83X\95\\8e¦
292         Gdiplus::Image *img = NULL;
293         unsigned int nowTime = sys->getTime();
294         Channel *ch = chanMgr->findChannelByChannelID(this->channel_id);
295         switch(this->getStatus()){
296                 case Channel::S_IDLE:
297                         img = img_idle;
298                         break;
299                 case Channel::S_SEARCHING:
300                 case Channel::S_CONNECTING:
301                         img = img_connect;
302                         break;
303                 case Channel::S_RECEIVING:
304                         if ((skipCount > 2) && (lastSkipTime + 120 > nowTime)){
305                                 if (chDisp.relay){
306                                         img = img_conn_ok_skip;
307                                 } else {
308                                         if (chDisp.numRelays){
309                                                 img = img_conn_full_skip;
310                                         } else {
311                                                 img = img_conn_over_skip;
312                                         }
313                                 }
314                         } else {
315                                 if (chDisp.relay){
316                                         img = img_conn_ok;
317                                 } else {
318                                         if (chDisp.numRelays){
319                                                 img = img_conn_full;
320                                         } else {
321                                                 img = img_conn_over;
322                                         }
323                                 }
324                         }
325                         break;
326                 case Channel::S_BROADCASTING:
327                         img = img_broad_ok;
328                         break;
329                 case Channel::S_ERROR:
330                         // bump\8e\9e\82É\83G\83\89\81[\82ª\95\\8e¦\82³\82ê\82é\82Ì\82ð\96h\8e~
331                         if (ch && ch->bumped)
332                         {
333                                 img = img_connect;
334                         } else
335                         {
336                                 img = img_error;
337                         }
338                         break;
339                 default:
340                         img = img_idle;
341                         break;
342         }
343         // \95`\89æ\8aî\93_
344         PointF origin(xx, yy);
345         // \83X\83e\81[\83^\83X\95\\8e¦\88Ê\92u
346         Rect img_rect((INT)origin.X, (INT)origin.Y + 1, img ? img->GetWidth() : 12, 12);
347         // \83X\83e\81[\83^\83X\95`\89æ
348         ImageAttributes att;
349 //      att.SetColorKey(Color::White, Color::White, ColorAdjustTypeBitmap);
350         g->DrawImage(img, img_rect, 0, 0, img_rect.Width, 12, UnitPixel, &att);
351         // \8e\9f\82Ì\8aî\93_
352         origin.X += img_rect.Width;
353
354         // \83t\83H\83\93\83g\90Ý\92è
355         Gdiplus::Font font(L"\82l\82\82o\83S\83V\83b\83N",10);
356         // \95\8e\9a\90F
357         SolidBrush *strBrush;
358         if (servMgr->getFirewall() == ServMgr::FW_ON){
359                 strBrush = ::new SolidBrush(Color::Red);
360         } else if (isTracker() && (getStatus() == Channel::S_RECEIVING)){
361                 strBrush = ::new SolidBrush(Color::Green);
362         } else {
363                 if (isSelected()){
364                         // \91I\91ð\92\86
365                         strBrush = ::new SolidBrush(Color::White);
366                 } else {
367                         // \94ñ\91I\91ð
368                         strBrush = ::new SolidBrush(Color::Black);
369                 }
370         }
371         // \83`\83\83\83\93\83l\83\8b\96¼\95\\8e¦
372         g->SetTextRenderingHint(TextRenderingHintAntiAlias);
373         _bstr_t bstr1(getName());
374         // \95\8e\9a\95`\89æ\94Í\88Í\8ew\92è
375         RectF r1(origin.X, origin.Y, 120.0f, 13.0f);
376         StringFormat format;
377         format.SetAlignment(StringAlignmentNear);
378         g->DrawString(bstr1, -1, &font, r1, &format, strBrush);
379         // \8e\9f\82Ì\8aî\93_
380         origin.X += r1.Width;
381
382         //// \8fã\97¬IP/\83\8a\83X\83i\81[\90\94/\83\8a\83\8c\81[\90\94\95\\8e¦
383         //// NOTE:
384         ////    \82Ò\82 \82©\82·\82Ì\93®\8dì\95×\8b­\97p\81B\83\8a\83\8a\81[\83X\83r\83\8b\83h\82Å\82Í\8c³\82Ì\83R\81[\83h\82ð\8eg\97p\82Ì\8e\96\81B
385         ////    \95\8e\9a\95\\8e¦\94Í\88Í\82Í\95\9d220\82®\82ç\82¢\82Å\82¨\82\8b
386         //char tmp[512]; // \95\\8e¦\97p\83o\83b\83t\83@
387         //char hostip[256]; // IP\83A\83h\83\8c\83X\83o\83b\83t\83@
388         //chDisp.uphost.toStr(hostip); // \8fã\97¬IP
389         //sprintf(tmp, "%d/%d - [%d/%d] - %s",
390         //      getTotalListeners(),
391         //      getTotalRelays(),
392         //      getLocalListeners(),
393         //      getLocalRelays(),
394         //      hostip
395         //      );
396
397         // \83\8a\83X\83i\81[\90\94/\83\8a\83\8c\81[\90\94\95\\8e¦
398         char tmp[256];
399         sprintf(tmp, "%d/%d - [%d/%d]", getTotalListeners(), getTotalRelays(), getLocalListeners(), getLocalRelays());
400         _bstr_t bstr2(tmp);
401         // \95\8e\9a\95\\8e¦\94Í\88Í\8ew\92è
402         RectF r2(origin.X, origin.Y, 100.0f, 13.0f);
403         format.SetAlignment(StringAlignmentCenter);
404         g->DrawString(bstr2, -1, &font, r2, &format, strBrush);
405         // \8e\9f\82Ì\8aî\93_
406         origin.X += r2.Width;
407
408         // bps\95\\8e¦
409         Font *f;
410         if (isStayConnected()){
411                 f = ::new Font(L"Arial", 9.0f, FontStyleItalic|FontStyleBold, UnitPoint);
412         } else {
413                 f = ::new Font(L"Arial", 9.0f);
414         }
415         sprintf(tmp, "%dkbps", getBitRate());
416         _bstr_t bstr3(tmp);
417         format.SetAlignment(StringAlignmentFar);
418         // \95\8e\9a\95\\8e¦\94Í\88Í\8ew\92è
419         RectF r3(origin.X, origin.Y, 80.0f, 13.0f);
420         g->DrawString(bstr3, -1, f, r3, &format, strBrush);
421         // \83t\83H\83\93\83g\8aJ\95ú
422         ::delete f;
423
424         // \8e\9f\82Ì\8aî\93_
425         origin.X += r3.Width;
426
427         // \83u\83\89\83V\8dí\8f\9c
428         ::delete strBrush;
429
430         
431         // Servent\95\\8e¦
432         if (!openFlg){
433                 int count = getServentCount();
434                 // Servent\95\\8e¦\95\94\82Ì\94w\8ci\82ð\94\92\82É\82·\82é
435                 SolidBrush b(Color(160,255,255,255));
436                 g->FillRectangle(&b, (INT)origin.X, (INT)origin.Y, 14*count, 14);
437
438                 sd = serventDataTop;
439                 int index = 0;
440                 while(sd){
441                         SolidBrush *serventBrush;
442                         if (sd->getInfoFlg()){
443                                 ChanHit *hit = sd->getChanHit();
444                                 if (hit->firewalled){
445                                         SolidBrush bb(Color(180,255,0,0));
446                                         g->FillRectangle(&bb, (INT)origin.X + 14*index, (INT)origin.Y, 14, 14);
447                                 }
448                                 if (hit->relay){
449                                         // \83\8a\83\8c\81[\82n\82j
450                                         serventBrush = ::new SolidBrush(Color::Green);
451                                 } else {
452                                         // \83\8a\83\8c\81[\95s\89Â
453                                         if (hit->numRelays){
454                                                 // \83\8a\83\8c\81[\88ê\94t
455                                                 serventBrush = ::new SolidBrush(Color::Blue);
456                                         } else {
457                                                 // \83\8a\83\8c\81[\82È\82µ
458                                                 serventBrush = ::new SolidBrush(Color::Purple);
459                                         }
460                                 }
461                         } else {
462                                 // \8fî\95ñ\82È\82µ
463                                 serventBrush = ::new SolidBrush(Color::Black);
464                         }
465                         // \8el\8ap\95`\89æ
466                         backGra->FillRectangle(serventBrush, (INT)origin.X + index*14 + 1, (INT)origin.Y + 1, 12, 12);
467
468                         ::delete serventBrush;
469                         sd = sd->getNextData();
470                         index++;
471                 }
472         }
473
474         // \8e\9f\82Ì\8aî\93_
475         origin.Y += 15;
476
477         // \83T\83C\83Y\82ð\95Û\91
478         setWidth((int)origin.X - posX);
479         setHeight((int)origin.Y - posY);
480
481         // ServentData\95\\8e¦
482         sd = serventDataTop;
483         while(sd){
484                 if (openFlg || sd->getSelected()){
485                         sd->drawServent(g, (INT)x+12, (INT)origin.Y);
486                         // \8e\9f\82Ì\8aî\93_
487                         origin.Y += 15;
488                 }
489                 sd = sd->getNextData();
490         }
491         
492
493         return (int)(origin.Y);
494 }
495
496 bool ChannelData::checkDown(int x,int y){
497         // \94Í\88Í\93à\83`\83F\83b\83N
498         if (    
499                         (x > posX)
500                 &&      (x < posX + getWidth())
501                 &&      (y > posY)
502                 &&      (y < posY + getHeight())
503         ){
504                 return TRUE;
505         }
506         return FALSE;
507 }
508
509 ServentData *ChannelData::findServentData(int servent_id){
510         ServentData *sv = serventDataTop;
511         while(sv){
512                 if (sv->getServentId() == servent_id){
513                         return sv;
514                 }
515                 sv = sv->getNextData();
516         }
517         return NULL;
518 }
519
520 void ChannelData::addServentData(ServentData *sd){
521         sd->setNextData(serventDataTop);
522         serventDataTop = sd;
523 }
524
525 void ChannelData::deleteDisableServents(){
526         ServentData *sd = serventDataTop;
527         ServentData *prev = NULL;
528
529         while(sd){
530                 if (!(sd->getEnableFlg())){
531                         ServentData *next = sd->getNextData();
532                         if (prev){
533                                 prev->setNextData(next);
534                         } else {
535                                 serventDataTop = next;
536                         }
537                         ::delete sd;
538                         sd = next;
539                 } else {
540                         prev = sd;
541                         sd = sd->getNextData();
542                 }
543         }
544 }
545
546 int ChannelData::getServentCount(){
547         int ret = 0;
548
549         ServentData *sd = serventDataTop;
550         while(sd){
551                 ret++;
552                 sd = sd->getNextData();
553         }
554         return ret;
555 }
556
557 bool ChannelData::setName(int servent_id, String name){
558         ServentData *sd = serventDataTop;
559         while(sd){
560                 if (sd->getServentId() == servent_id){
561                         sd->setName(name);
562                         return TRUE;
563                 }
564                 sd = sd->getNextData();
565         }
566         return FALSE;
567 }
568
569 void ServentData::setData(Servent *s, ChanHit *hit, unsigned int listeners, unsigned int relays, bool f){
570         servent_id = s->servent_id;
571         type = s->type;
572         status = s->status;
573         lastSkipTime = s->lastSkipTime;
574         host = s->getHost();
575
576         chanHit.numRelays = hit->numRelays;
577         chanHit.relay = hit->relay;
578         chanHit.firewalled = hit->firewalled;
579         chanHit.version = hit->version;
580         chanHit.version_vp = hit->version_vp;
581         chanHit.version_ex_number = hit->version_ex_number;
582         chanHit.version_ex_prefix[0] = hit->version_ex_prefix[0];
583         chanHit.version_ex_prefix[1] = hit->version_ex_prefix[1];
584
585         totalListeners = listeners;
586         totalRelays = relays;
587
588         infoFlg = f;
589 }
590
591 int ServentData::drawServent(Gdiplus::Graphics *g, int x, int y){
592         REAL xx = x * 1.0f;
593         REAL yy = y * 1.0f;
594         int w/*,h*/;
595
596         // \88Ê\92u\82ð\95Û\91
597         posX = x;
598         posY = y;
599
600         if (getWidth() == 0){
601                 if (gWS){
602                         w = gWS;
603                 } else {
604                         w = 400;
605                 }
606         } else {
607                 w = getWidth();
608                 gWS = w;
609         }
610
611         // \95`\89æ\8aî\93_
612         PointF origin(xx, yy);
613
614         // \83t\83H\83\93\83g\90Ý\92è
615         Font font(L"\82l\82\82o\83S\83V\83b\83N",9);
616         // \95\8e\9a\90F
617         SolidBrush *strBrush;
618         if (chanHit.firewalled){
619                 strBrush = ::new SolidBrush(Color::Red);
620         } else {
621                 if (getSelected()){
622                         // \91I\91ð\92\86
623                         strBrush = ::new SolidBrush(Color::White);
624                 } else {
625                         // \94ñ\91I\91ð
626                         strBrush = ::new SolidBrush(Color::Black);
627                 }
628         }
629         // ServantData\95\\8e¦
630         g->SetTextRenderingHint(TextRenderingHintAntiAlias);
631         // \95\8e\9a\97ñ\8dì\90¬
632         char tmp[256];
633         char host1[256];
634         host.toStr(host1);
635
636         if (infoFlg){
637                 if (chanHit.version_ex_number){
638                         // \8ag\92£\83o\81[\83W\83\87\83\93
639                         sprintf(tmp, "%c%c%04d - %d/%d - %s(%s)", 
640                                 chanHit.version_ex_prefix[0],
641                                 chanHit.version_ex_prefix[1],
642                                 chanHit.version_ex_number,
643                                 totalListeners,
644                                 totalRelays,
645                                 host1,
646                                 hostname.cstr()
647                                 );
648                 } else if (chanHit.version_vp){
649                         sprintf(tmp, "VP%04d - %d/%d - %s(%s)", 
650                                 chanHit.version_vp,
651                                 totalListeners,
652                                 totalRelays,
653                                 host1,
654                                 hostname.cstr()
655                                 );
656                 } else {
657                         sprintf(tmp, "(-----) - %d/%d - %s(%s)",
658                                 totalListeners,
659                                 totalRelays,
660                                 host1,
661                                 hostname.cstr()
662                                 );
663                 }
664         } else {
665                         sprintf(tmp, "(-----) - %d/%d - %s(%s)",
666                                 totalListeners,
667                                 totalRelays,
668                                 host1,
669                                 hostname.cstr()
670                                 );
671         }
672         _bstr_t bstr1(tmp);
673
674         // \83X\83e\81[\83^\83X\95\\8e¦
675         Gdiplus::Image *img = NULL;
676         unsigned int nowTime = sys->getTime();
677         switch(getStatus()){
678                 case Servent::S_CONNECTING:
679                         img = img_connect;
680                         break;
681                 case Servent::S_CONNECTED:
682                         if (lastSkipTime + 120 > nowTime){
683                                 if (chanHit.relay){
684                                         img = img_conn_ok_skip;
685                                 } else {
686                                         if (chanHit.numRelays){
687                                                 img = img_conn_full_skip;
688                                         } else {
689                                                 img = img_conn_over_skip;
690                                         }
691                                 }
692                         } else {
693                                 if (chanHit.relay){
694                                         img = img_conn_ok;
695                                 } else {
696                                         if (chanHit.numRelays){
697                                                 img = img_conn_full;
698                                         } else {
699                                                 img = img_conn_over;
700                                         }
701                                 }
702                         }
703                         break;
704                 default:
705                         break;
706         }
707
708         // \95\8e\9a\95`\89æ\94Í\88Í\8ew\92è
709         RectF r1(origin.X + img->GetWidth() + 2, origin.Y, 800.0f, 13.0f);
710         RectF r2;
711         StringFormat format;
712         format.SetAlignment(StringAlignmentNear);
713         g->MeasureString(bstr1, -1, &font, r1, &format, &r2);
714
715         w = (INT)r2.Width + img->GetWidth() + 2;
716         // ServentData\95\\8e¦\95\94\82Ì\94w\8ci\82ð\93h\82é
717         if (getSelected()){
718                 // \91I\91ð\92\86
719                 SolidBrush b(Color(160,49,106,197));
720                 g->FillRectangle(&b, x, y, w, 13);
721         } else {
722                 // \94ñ\91I\91ð
723                 SolidBrush b(Color(160,200,200,200));
724                 g->FillRectangle(&b, x, y, w, 13);
725         }
726
727         // \83X\83e\81[\83^\83X\95\\8e¦\88Ê\92u
728         Rect img_rect((INT)origin.X, (INT)origin.Y+1, img ? img->GetWidth() : 12, 12);
729         // \83X\83e\81[\83^\83X\95`\89æ
730         ImageAttributes att;
731 //      att.SetColorKey(Color::White, Color::White, ColorAdjustTypeBitmap);
732         g->DrawImage(img, img_rect, 0, 0, img_rect.Width, 12, UnitPixel, &att);
733         // \8e\9f\82Ì\8aî\93_
734         origin.X += 12;
735
736         g->DrawString(bstr1, -1, &font, r2, &format, strBrush);
737         // \8e\9f\82Ì\8aî\93_
738         origin.X += r2.Width;
739         origin.Y += 13;
740
741         setWidth((int)origin.X-posX);
742         setHeight((int)origin.Y - posY);
743
744         ::delete strBrush;
745         return 0;
746 }
747
748 bool ServentData::checkDown(int x, int y){
749         if (    
750                         (x > posX)
751                 &&      (x < posX + getWidth())
752                 &&      (y > posY)
753                 &&      (y < posY + getHeight())
754         ){
755                 return TRUE;
756         }
757         return FALSE;
758 }
759
760
761 THREAD_PROC GUIDataUpdate(ThreadInfo *thread){
762         int i;
763
764         // set GUI thread status to running
765         thread->finish = false;
766
767         while(thread->active){
768                 // \83`\83\83\83\93\83l\83\8b\83f\81[\83^\83\8d\83b\83N
769                 ChannelDataLock.on();
770                 // \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é
771                 ChannelData *cd = channelDataTop;
772                 while(cd){
773                         // Servent\82Ì\8dX\90V\83t\83\89\83O\82ðFALSE\82É\82·\82é
774                         ServentData *sv = cd->getServentDataTop();
775                         while(sv){
776                                 sv->setEnableFlg(FALSE);
777                                 sv = sv->getNextData();
778                         }
779                         cd->setEnableFlg(FALSE);
780                         cd = cd->getNextData();
781                 }
782
783                 Channel *c = chanMgr->channel;
784                 // \8c»\8dÝ\91\8dÝ\82·\82é\83`\83\83\83\93\83l\83\8b\95ª\83\8b\81[\83v
785                 while(c){
786                         // \8aù\82É\83`\83\83\83\93\83l\83\8b\83f\81[\83^\82ð\8e\9d\82Á\82Ä\82¢\82é\82©
787                         cd = channelDataTop;
788                         // \94­\8c©\83t\83\89\83OFALSE
789                         bool bFoundFlg = FALSE;
790                         while(cd){
791                                 if (cd->getChannelId() == c->channel_id){
792                                         //\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
793                                         cd->setData(c);
794                                         // \8dX\90V\83t\83\89\83OTRUE
795                                         cd->setEnableFlg(TRUE);
796                                         // \94­\8c©\83t\83\89\83OTRUE
797                                         bFoundFlg = TRUE;
798                                         // \83\8b\81[\83v\97£\92E
799                                         break;
800                                 }
801                                 // \8c©\82Â\82©\82ç\82È\82©\82Á\82½\8fê\8d\87\81A\8e\9f\82Ì\83f\81[\83^\82ð\83`\83F\83b\83N
802                                 cd = cd->getNextData();
803                         }
804
805                         // \90V\82µ\82¢\83`\83\83\83\93\83l\83\8b\82Ì\8fê\8d\87\81A\90V\8bK\83f\81[\83^\8dì\90¬
806                         if (!bFoundFlg){
807                                 // \90V\8bK\83f\81[\83^\8dì\90¬
808                                 cd = ::new ChannelData();
809                                 // \83f\81[\83^\8dX\90V
810                                 cd->setData(c);
811                                 // \8dX\90V\83t\83\89\83OTRUE
812                                 cd->setEnableFlg(TRUE);
813
814                                 // \90V\8bK\83f\81[\83^\82ð\83\8a\83X\83g\82Ì\90æ\93ª\82É\93ü\82ê\82é
815                                 cd->setNextData(channelDataTop);
816                                 channelDataTop = cd;
817                         }
818                         // \8e\9f\82Ì\83`\83\83\83\93\83l\83\8b\82ð\8eæ\93¾
819                         c = c->next;
820                 }
821
822                 // \83`\83\83\83\93\83l\83\8b\82ª\82È\82­\82È\82Á\82Ä\82¢\82é\8fê\8d\87\82Ì\8f\88\97\9d
823                 cd = channelDataTop;
824                 ChannelData *prev = NULL; 
825                 while(cd){
826                         // \83f\81[\83^\82ð\8dX\90V\82µ\82È\82©\82Á\82½\82©
827                         if (cd->getEnableFlg() == FALSE){
828                                 // \83`\83\83\83\93\83l\83\8b\82ª\82È\82­\82È\82Á\82Ä\82¢\82é\82Ì\82Å\8dí\8f\9c
829                                 ChannelData *next;
830                                 next = cd->getNextData();
831                                 if (!prev){
832                                         // \90æ\93ª\82Ì\83f\81[\83^\82ð\8dí\8f\9c
833                                         channelDataTop = next;
834                                 } else {
835                                         // \93r\92\86\82Ì\83f\81[\83^\82ð\8dí\8f\9c
836                                         prev->setNextData(next);
837                                 }
838                                 // \8e\9f\82Ì\83f\81[\83^\82Ö
839                                 cd = next;
840                         } else {
841                                 // \83f\81[\83^\8dX\90V\8dÏ\81F\8e\9f\82Ì\83f\81[\83^\82Ö
842                                 prev = cd;
843                                 cd = cd->getNextData();
844                         }
845                 }
846
847                 Servent *s = servMgr->servents;
848                 while(s){
849                         // \8f\89\8aú\89»
850                         ChanHitList *chl;
851                         bool infoFlg = false;
852                         bool relay = true;
853                         bool firewalled = false;
854                         unsigned int numRelays = 0;
855                         int vp_ver = 0;
856                         char ver_ex_prefix[2] = {' ', ' '};
857                         int ver_ex_number = 0;
858                         // \92¼\89º\83z\83X\83g\8fî\95ñ\83`\83F\83b\83N
859                         unsigned int totalRelays = 0;
860                         unsigned int totalListeners = 0;
861
862                         ChanHit hitData;
863                         // \8eó\90M\92\86\82©
864                         if ((s->type == Servent::T_RELAY) && (s->status == Servent::S_CONNECTED)){
865                                 // \83z\83X\83g\8fî\95ñ\83\8d\83b\83N
866                                 chanMgr->hitlistlock.on();
867                                 // \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¾
868                                 chl = chanMgr->findHitListByID(s->chanID);
869                                 // \83`\83\83\83\93\83l\83\8b\82Ì\83z\83X\83g\8fî\95ñ\82ª\82 \82é\82©
870                                 if (chl){
871                                         // \83`\83\83\83\93\83l\83\8b\82Ì\83z\83X\83g\8fî\95ñ\82ª\82 \82é\8fê\8d\87
872                                         ChanHit *hit = chl->hit;
873                                         //\81@\83`\83\83\83\93\83l\83\8b\82Ì\83z\83X\83g\8fî\95ñ\82ð\91S\91\96\8d¸\82µ\82Ä
874                                         while(hit){
875                                                 // ID\82ª\93¯\82\82à\82Ì\82Å\82 \82ê\82Î
876                                                 if (hit->servent_id == s->servent_id){
877                                                         // \83g\81[\83^\83\8b\83\8a\83\8c\81[\82Æ\83g\81[\83^\83\8b\83\8a\83X\83i\81[\82ð\89Á\8eZ
878                                                         totalRelays += hit->numRelays;
879                                                         totalListeners += hit->numListeners;
880                                                         // \92¼\89º\82Å\82 \82ê\82Î
881                                                         if (hit->numHops == 1){
882                                                                 // \8fî\95ñ\82ð\88ê\92U\95Û\91
883                                                                 infoFlg = true;
884                                                                 hitData.relay = hit->relay;
885                                                                 hitData.firewalled = hit->firewalled;
886                                                                 hitData.numRelays = hit->numRelays;
887                                                                 hitData.version_vp = hit->version_vp;
888                                                                 hitData.version_ex_prefix[0] = hit->version_ex_prefix[0];
889                                                                 hitData.version_ex_prefix[1] = hit->version_ex_prefix[1];
890                                                                 hitData.version_ex_number = hit->version_ex_number;
891                                                         }
892                                                 }
893                                                 // \8e\9f\82ð\83`\83F\83b\83N
894                                                 hit = hit->next;
895                                         }
896                                 }
897
898                                 // \83`\83\83\83\93\83l\83\8b\83f\81[\83^\82©\82çServent\82ð\8c\9f\8dõ
899                                 bool bFoundFlg = FALSE;
900                                 cd = channelDataTop;
901                                 while(cd){
902                                         ServentData *sv = cd->findServentData(s->servent_id);
903                                         // ServentData\82ª\82 \82ê\82Î
904                                         if (sv && cd->getChannelId() == s->channel_id){
905                                                 // \83f\81[\83^\90Ý\92è
906                                                 sv->setData(s, &hitData, totalListeners, totalRelays, infoFlg);
907                                                 sv->setEnableFlg(TRUE);
908                                                 bFoundFlg = TRUE;
909                                                 break;
910                                         }
911                                         cd = cd->getNextData();
912                                 }
913                                 // ServentData\82ª\8c©\82Â\82©\82ç\82È\82©\82Á\82½\8fê\8d\87
914                                 if (!bFoundFlg){
915                                         // \83`\83\83\83\93\83l\83\8b\83f\81[\83^\82ð\92T\82·
916                                         cd = channelDataTop;
917                                         while(cd){
918                                                 // \83`\83\83\83\93\83l\83\8bID\82ª\93¯\82\82©
919                                                 if (cd->getChannelId() == s->channel_id){
920                                                         // \83f\81[\83^\90Ý\92è
921                                                         ServentData *sv = ::new ServentData();
922                                                         sv->setData(s, &hitData, totalListeners, totalRelays, infoFlg);
923                                                         sv->setEnableFlg(TRUE);
924                                                         // \83`\83\83\83\93\83l\83\8b\83f\81[\83^\82ÉServentData\92Ç\89Á
925                                                         cd->addServentData(sv);
926                                                         // \83z\83X\83g\96¼\82ð\8eæ\93¾\82·\82é
927                                                         IdData *id = ::new IdData(cd->getChannelId(), sv->getServentId(), sv->getHost().ip);
928                                                         ThreadInfo t;
929                                                         t.func = GetHostName;
930                                                         t.data = (void*)id;
931                                                         sys->startThread(&t);
932                                                         // \83\8b\81[\83v\8fI\97¹
933                                                         break;
934                                                 }
935                                                 // \8e\9f\82Ì\83f\81[\83^\82Ö
936                                                 cd = cd->getNextData();
937                                         }
938                                 }
939                                 // \83z\83X\83g\8fî\95ñ\83A\83\93\83\8d\83b\83N
940                                 chanMgr->hitlistlock.off();
941                         }
942                         s = s->next;
943                 }
944
945                 // \8dX\90V\82µ\82Ä\82¢\82È\82¢ServentData\82ð\8dí\8f\9c
946                 cd = channelDataTop;
947                 while(cd){
948                         cd->deleteDisableServents();
949                         cd = cd->getNextData();
950                 }
951
952                 // \83`\83\83\83\93\83l\83\8b\83f\81[\83^\83A\83\93\83\8d\83b\83N
953                 ChannelDataLock.off();
954
955                 // \95`\89æ\8dX\90V
956                 if (guiWnd){
957                         MakeBack(guiWnd);
958                 }
959
960                 // 0.1\95b\81~10\82Å1\95b\91Ò\82¿
961                 for(i=0; i<10; i++)
962                 {
963                         if (!thread->active)
964                                 break;
965                         sys->sleep(100);
966                 }
967         }
968
969         // set GUI thread status to terminated
970         thread->finish = true;
971
972         return 0;
973 }
974
975 ChannelData *findChannelData(int channel_id){
976         ChannelData *cd = channelDataTop;
977
978         while(cd){
979                 if (cd->getChannelId() == channel_id){
980                         return cd;
981                 }
982                 cd = cd->getNextData();
983         }
984
985         return NULL;
986 }
987
988
989 void PopupChannelMenu(int channel_id){
990         POINT pos;
991         MENUITEMINFO info, separator;
992         HMENU hMenu;
993         DWORD dwID;
994
995         hMenu = CreatePopupMenu();
996
997         memset(&separator, 0, sizeof(MENUITEMINFO));
998         separator.cbSize = sizeof(MENUITEMINFO);
999         separator.fMask = MIIM_ID | MIIM_TYPE;
1000         separator.fType = MFT_SEPARATOR;
1001         separator.wID = 8000;
1002
1003         memset(&info, 0, sizeof(MENUITEMINFO));
1004         info.cbSize = sizeof(MENUITEMINFO);
1005         info.fMask = MIIM_ID | MIIM_TYPE;
1006         info.fType = MFT_STRING;
1007
1008         ChannelData *cd = findChannelData(channel_id);
1009
1010         if (cd == NULL){
1011                 return;
1012         }
1013
1014         info.wID = 1001;
1015         info.dwTypeData = "\90Ø\92f";
1016         InsertMenuItem(hMenu, -1, true, &info);
1017
1018         InsertMenuItem(hMenu, -1, true, &separator);
1019
1020         info.wID = 1000;
1021         info.dwTypeData = "\8dÄ\90¶";
1022         InsertMenuItem(hMenu, -1, true, &info);
1023
1024         InsertMenuItem(hMenu, -1, true, &separator);
1025
1026         info.wID = 1002;
1027         info.dwTypeData = "\8dÄ\90Ú\91±";
1028         InsertMenuItem(hMenu, -1, true, &info);
1029
1030         info.wID = 1003;
1031         info.dwTypeData = "\83L\81[\83v";
1032         InsertMenuItem(hMenu, -1, true, &info);
1033
1034         InsertMenuItem(hMenu, -1, true, &separator);
1035
1036         if (!cd->getOpenFlg()){
1037                 info.wID = 1004;
1038                 info.dwTypeData = "\92¼\89º\95\\8e¦";
1039                 InsertMenuItem(hMenu, -1, true, &info);
1040         } else {
1041                 info.wID = 1005;
1042                 info.dwTypeData = "\92¼\89º\89B\95Á";
1043                 InsertMenuItem(hMenu, -1, true, &info);
1044         }
1045
1046         GetCursorPos(&pos);
1047         dwID = TrackPopupMenu(hMenu, TPM_LEFTALIGN|TPM_RETURNCMD, pos.x, pos.y, 0, guiWnd, NULL);
1048
1049         DestroyMenu(hMenu);
1050
1051         cd = findChannelData(channel_id);
1052
1053         if (cd == NULL){
1054                 return;
1055         }
1056
1057         Channel *c = chanMgr->findChannelByChannelID(channel_id);
1058
1059         if (c == NULL){
1060                 return;
1061         }
1062
1063         switch(dwID){
1064                 case 1000:      // \8dÄ\90
1065                         chanMgr->playChannel(c->info);
1066                         break;
1067
1068                 case 1001:      // \90Ø\92f
1069                         c->thread.active = false;
1070                         c->thread.finish = true;
1071                         break;
1072
1073                 case 1002:      // \8dÄ\90Ú\91±
1074                         // \92¼\89º\82©\82Â\8eó\90M\92\86\82Å\82 \82ê\82Î\8am\94F\83\81\83b\83Z\81[\83W\95\\8e¦
1075                         if (cd->isTracker() && cd->getStatus() == Channel::S_RECEIVING)
1076                         {
1077                                 int id;
1078                                 id = MessageBox(guiWnd,
1079                                         "\92¼\89º\82Å\82·\82ª\8dÄ\90Ú\91±\82µ\82Ü\82·\82©\81H",
1080                                         "\92¼\89º\8cx\8d\90",
1081                                         MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2);
1082                                 if (id != IDYES)
1083                                         break;
1084                         }
1085
1086                         c->bump = true;
1087                         break;
1088
1089                 case 1003:      // \83L\81[\83v
1090                         if (!c->stayConnected){
1091                                 c->stayConnected  = true;
1092                         } else {
1093                                 c->stayConnected = false;
1094                         }
1095                         break;
1096
1097                 case 1004:      // \92¼\89º\95\\8e¦
1098                         cd->setOpenFlg(TRUE);
1099                         MakeBack(guiWnd);
1100                         break;
1101
1102                 case 1005:      // \92¼\89º\89B\95Á
1103                         cd->setOpenFlg(FALSE);
1104                         MakeBack(guiWnd);
1105                         break;
1106         }
1107 }
1108
1109 void PopupServentMenu(int servent_id){
1110         POINT pos;
1111         MENUITEMINFO info, separator;
1112         HMENU hMenu;
1113         DWORD dwID;
1114
1115         hMenu = CreatePopupMenu();
1116
1117         memset(&separator, 0, sizeof(MENUITEMINFO));
1118         separator.cbSize = sizeof(MENUITEMINFO);
1119         separator.fMask = MIIM_ID | MIIM_TYPE;
1120         separator.fType = MFT_SEPARATOR;
1121         separator.wID = 8000;
1122
1123         memset(&info, 0, sizeof(MENUITEMINFO));
1124         info.cbSize = sizeof(MENUITEMINFO);
1125         info.fMask = MIIM_ID | MIIM_TYPE;
1126         info.fType = MFT_STRING;
1127
1128         ServentData *sd = NULL;
1129         ChannelData *cd = channelDataTop;
1130         while(cd){
1131                 sd = cd->findServentData(servent_id);
1132                 if (sd){
1133                         break;
1134                 }
1135                 cd = cd->getNextData();
1136         }
1137
1138         if (cd == NULL || sd == NULL){
1139                 return;
1140         }
1141
1142         info.wID = 1001;
1143         info.dwTypeData = "\90Ø\92f";
1144         InsertMenuItem(hMenu, -1, true, &info);
1145
1146 //      InsertMenuItem(hMenu, -1, true, &separator);
1147
1148         GetCursorPos(&pos);
1149         dwID = TrackPopupMenu(hMenu, TPM_LEFTALIGN|TPM_RETURNCMD, pos.x, pos.y, 0, guiWnd, NULL);
1150
1151         DestroyMenu(hMenu);
1152
1153         cd = channelDataTop;
1154         while(cd){
1155                 sd = cd->findServentData(servent_id);
1156                 if (sd){
1157                         break;
1158                 }
1159                 cd = cd->getNextData();
1160         }
1161
1162         if (cd == NULL || sd == NULL){
1163                 return;
1164         }
1165
1166         Servent *s = servMgr->findServentByServentID(servent_id);
1167
1168         if (s == NULL){
1169                 return;
1170         }
1171
1172         switch(dwID){
1173                 case 1001:      // \90Ø\92f
1174                         s->thread.active = false;
1175                         break;
1176
1177         }
1178 }
1179
1180 void PopupOtherMenu(){
1181         POINT pos;
1182         MENUITEMINFO info, separator;
1183         HMENU hMenu;
1184         DWORD dwID;
1185
1186         hMenu = CreatePopupMenu();
1187
1188         memset(&separator, 0, sizeof(MENUITEMINFO));
1189         separator.cbSize = sizeof(MENUITEMINFO);
1190         separator.fMask = MIIM_ID | MIIM_TYPE;
1191         separator.fType = MFT_SEPARATOR;
1192         separator.wID = 8000;
1193
1194         memset(&info, 0, sizeof(MENUITEMINFO));
1195         info.cbSize = sizeof(MENUITEMINFO);
1196         info.fMask = MIIM_ID | MIIM_TYPE;
1197         info.fType = MFT_STRING;
1198
1199         if (!gbDispTop){
1200                 info.wID = 1101;
1201                 info.dwTypeData = "\8dÅ\91O\96Ê\95\\8e¦";
1202                 InsertMenuItem(hMenu, -1, true, &info);
1203         } else {
1204                 info.wID = 1102;
1205                 info.dwTypeData = "\8dÅ\91O\96Ê\89ð\8f\9c";
1206                 InsertMenuItem(hMenu, -1, true, &info);
1207         }
1208
1209         InsertMenuItem(hMenu, -1, true, &separator);
1210
1211         if (!gbAllOpen){
1212                 info.wID = 1103;
1213                 info.dwTypeData = "\91S\92¼\89º\93W\8aJ";
1214                 InsertMenuItem(hMenu, -1, true, &info);
1215         } else {
1216                 info.wID = 1104;
1217                 info.dwTypeData = "\91S\92¼\89º\89B\95Á";
1218                 InsertMenuItem(hMenu, -1, true, &info);
1219         }
1220
1221         InsertMenuItem(hMenu, -1, true, &separator);
1222
1223         if (!servMgr->autoServe){
1224                 info.wID = 1105;
1225                 info.dwTypeData = "\97L\8cø";
1226                 InsertMenuItem(hMenu, -1, true, &info);
1227         } else {
1228                 info.wID = 1106;
1229                 info.dwTypeData = "\96³\8cø";
1230                 InsertMenuItem(hMenu, -1, true, &info);
1231         }
1232
1233         GetCursorPos(&pos);
1234         dwID = TrackPopupMenu(hMenu, TPM_LEFTALIGN|TPM_RETURNCMD, pos.x, pos.y, 0, guiWnd, NULL);
1235
1236         DestroyMenu(hMenu);
1237
1238         ChannelData *cd = channelDataTop;
1239
1240         switch(dwID){
1241                 case 1101:      // \8dÅ\91O\96Ê\95\\8e¦
1242                         gbDispTop = true;
1243                         ::SetWindowPos(guiWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
1244                         break;
1245
1246                 case 1102:      // \8dÅ\91O\96Ê\89ð\8f\9c
1247                         gbDispTop = false;
1248                         ::SetWindowPos(guiWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
1249                         break;
1250
1251                 case 1103:      // \91S\92¼\89º\93W\8aJ
1252                         gbAllOpen = true;
1253                         while(cd){
1254                                 cd->setOpenFlg(true);
1255                                 cd = cd->getNextData();
1256                         }
1257                         break;
1258
1259                 case 1104:      // \91S\92¼\89º\89B\95Á
1260                         gbAllOpen = false;
1261                         while(cd){
1262                                 cd->setOpenFlg(false);
1263                                 cd = cd->getNextData();
1264                         }
1265                         break;
1266
1267                 case 1105:      // \97L\8cø
1268                         servMgr->autoServe = true;
1269                         break;
1270
1271                 case 1106:      // \96³\8cø
1272                         servMgr->autoServe = false;
1273                         break;
1274
1275         }
1276 }
1277
1278 void WmCreateProc(HWND hwnd){
1279         // \8e©\93®\8dÅ\91O\96Ê\8b@\94\
1280         if (servMgr->topmostGui)
1281         {
1282                 ::gbDispTop = true;
1283         }
1284
1285         if (backImage){
1286                 ::delete backImage;
1287         }
1288         _bstr_t bstr("back.jpg");
1289         backImage = ::new Image(bstr);
1290
1291         MakeBack(hwnd, 800, 600);
1292
1293         guiThread.func = GUIDataUpdate;
1294         if (!sys->startThread(&guiThread)){
1295                 MessageBox(hwnd,"Unable to start GUI","PeerCast",MB_OK|MB_ICONERROR);
1296                 PostMessage(hwnd,WM_DESTROY,0,0);
1297         }
1298         if (guiFlg){
1299                 SetWindowPlacement(hwnd, &winPlace);
1300         }
1301
1302         if (img_idle){
1303                 ::delete img_idle;
1304                 ::delete img_connect;
1305                 ::delete img_conn_ok;
1306                 ::delete img_conn_full;
1307                 ::delete img_conn_over;
1308                 ::delete img_conn_ok_skip;
1309                 ::delete img_conn_full_skip;
1310                 ::delete img_conn_over_skip;
1311                 ::delete img_error;
1312                 ::delete img_broad_ok;
1313                 ::delete img_broad_full;
1314         }
1315         bstr = L"ST_IDLE.bmp";
1316         img_idle = ::new Image(bstr);
1317         bstr = L"ST_CONNECT.bmp";
1318         img_connect = ::new Image(bstr);
1319         bstr = L"ST_CONN_OK.bmp";
1320         img_conn_ok = ::new Image(bstr);
1321         bstr = L"ST_CONN_FULL.bmp";
1322         img_conn_full = ::new Image(bstr);
1323         bstr = L"ST_CONN_OVER.bmp";
1324         img_conn_over = ::new Image(bstr);
1325         bstr = L"ST_CONN_OK_SKIP.bmp";
1326         img_conn_ok_skip = ::new Image(bstr);
1327         bstr = L"ST_CONN_FULL_SKIP.bmp";
1328         img_conn_full_skip = ::new Image(bstr);
1329         bstr = L"ST_CONN_OVER_SKIP.bmp";
1330         img_conn_over_skip = ::new Image(bstr);
1331         bstr = L"ST_ERROR.bmp";
1332         img_error = ::new Image(bstr);
1333         bstr = L"ST_BROAD_OK.bmp";
1334         img_broad_ok = ::new Image(bstr);
1335         bstr = L"ST_BROAD_FULL.bmp";
1336         img_broad_full = ::new Image(bstr);
1337 }
1338
1339 void WmPaintProc(HWND hwnd){
1340         HDC hdc;
1341         PAINTSTRUCT paint;
1342
1343         if (backGra){
1344                 MakeBackLock.on();
1345                 hdc = BeginPaint(hwnd, &paint);
1346                 RECT *rcRect;   // \95`\89æ\94Í\88Í
1347                 rcRect = &(paint.rcPaint);
1348                 LONG width = rcRect->right - rcRect->left + 1;
1349                 LONG height = rcRect->bottom - rcRect->top + 1;
1350
1351                 Graphics g2(hdc);
1352                 Rect r(rcRect->left, rcRect->top, width, height);
1353                 g2.DrawImage(backBmp,r, rcRect->left, rcRect->top, width, height, UnitPixel);
1354                 EndPaint(hwnd, &paint);
1355                 MakeBackLock.off();
1356         }
1357 }
1358
1359 void WmSizeProc(HWND hwnd, LPARAM lParam){
1360         UINT width = LOWORD(lParam);
1361         UINT height = HIWORD(lParam);
1362
1363         MakeBack(hwnd, width, height);
1364
1365 }
1366
1367 void WmLButtonDownProc(HWND hwnd, LPARAM lParam){
1368         ChannelData *cd;
1369         bool changeFlg = FALSE;
1370
1371         ChannelDataLock.on();
1372         cd = channelDataTop;
1373         while(cd){
1374                 int x = LOWORD(lParam);
1375                 int y = HIWORD(lParam);
1376                 if (cd->checkDown(LOWORD(lParam), HIWORD(lParam))){
1377                         if (!(cd->isSelected())){
1378                                 changeFlg = TRUE;
1379                         }
1380                         cd->setSelected(TRUE);
1381                 } else {
1382                         if (cd->isSelected()){
1383                                 changeFlg = TRUE;
1384                         }
1385                         cd->setSelected(FALSE);
1386                 }
1387                 int sx = cd->getPosX() + cd->getWidth();
1388                 int sy = cd->getPosY();
1389                 int index = 0;
1390                 ServentData *sd = cd->getServentDataTop();
1391                 while(sd){
1392                         if (    (       (!cd->getOpenFlg())
1393                                         &&      (sx + index*14 < x)
1394                                         &&      (x < sx + (index+1)*14)
1395                                         &&      (sy < y)
1396                                         &&      (y < sy + 14)   )
1397                                 ||      sd->checkDown(LOWORD(lParam), HIWORD(lParam))
1398                         ){
1399                                 if (!sd->getSelected()){
1400                                         changeFlg = TRUE;
1401                                 }
1402                                 sd->setSelected(TRUE);
1403                         } else {
1404                                 if (sd->getSelected()){
1405                                         changeFlg = TRUE;
1406                                 }
1407                                 sd->setSelected(FALSE);
1408                         }
1409                         sd = sd->getNextData();
1410                         index++;
1411                 }
1412                 cd = cd->getNextData();
1413         }
1414         ChannelDataLock.off();
1415         if (changeFlg){
1416                 MakeBack(hwnd);
1417         }
1418 }
1419
1420 void WmLButtonDblclkProc(HWND hwnd, LPARAM lParam){
1421         ChannelData *cd;
1422         bool changeFlg = FALSE;
1423
1424         ChannelDataLock.on();
1425         cd = channelDataTop;
1426         while(cd){
1427                 int x = LOWORD(lParam);
1428                 int y = HIWORD(lParam);
1429                 if (cd->checkDown(LOWORD(lParam), HIWORD(lParam))){
1430                         if (!(cd->isSelected())){
1431                                 changeFlg = TRUE;
1432                         }
1433                         if (!(cd->getOpenFlg())){
1434                                 changeFlg = TRUE;
1435                                 cd->setOpenFlg(TRUE);
1436                         } else {
1437                                 changeFlg = TRUE;
1438                                 cd->setOpenFlg(FALSE);
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 WmRButtonDownProc(HWND hwnd, LPARAM lParam){
1481         ChannelData *cd;
1482         bool changeFlg = FALSE;
1483         bool channel_selected = FALSE;
1484         bool servent_selected = FALSE;
1485         int channel_id = 0;
1486         int servent_id = 0;
1487
1488         cd = channelDataTop;
1489         while(cd){
1490                 if (cd->checkDown(LOWORD(lParam), HIWORD(lParam))){
1491                         if (!(cd->isSelected())){
1492                                 changeFlg = TRUE;
1493                         }
1494                         cd->setSelected(TRUE);
1495                         channel_id = cd->getChannelId();
1496                         channel_selected = TRUE;
1497                 } else {
1498                         if (cd->isSelected()){
1499                                 changeFlg = TRUE;
1500                         }
1501                         cd->setSelected(FALSE);
1502                 }
1503                 ServentData *sd = cd->getServentDataTop();
1504                 while(sd){
1505                         if (sd->checkDown(LOWORD(lParam), HIWORD(lParam))){
1506                                 if (!sd->getSelected()){
1507                                         changeFlg = TRUE;
1508                                 }
1509                                 sd->setSelected(TRUE);
1510                                 servent_id = sd->getServentId();
1511                                 servent_selected = TRUE;
1512                         } else {
1513                                 if (sd->getSelected()){
1514                                         changeFlg = TRUE;
1515                                 }
1516                                 sd->setSelected(FALSE);
1517                         }
1518                         sd = sd->getNextData();
1519                 }
1520                 cd = cd->getNextData();
1521         }
1522         if (changeFlg){
1523                 MakeBack(hwnd);
1524         }
1525
1526         if (channel_selected){
1527                 PopupChannelMenu(channel_id);
1528         } else if (servent_selected){
1529                 PopupServentMenu(servent_id);
1530         } else {
1531                 PopupOtherMenu();
1532         }
1533 }
1534
1535 LRESULT CALLBACK GUIProc (HWND hwnd, UINT message,
1536                                  WPARAM wParam, LPARAM lParam)
1537 {
1538         switch(message){
1539                 case WM_CREATE:         // \83E\83B\83\93\83h\83E\8dì\90¬
1540                         WmCreateProc(hwnd);
1541                         break;
1542
1543                 case WM_PAINT:          // \95`\89æ
1544                         WmPaintProc(hwnd);
1545                         break;
1546
1547                 case WM_SIZE:           // \83T\83C\83Y\95Ï\8dX
1548                         WmSizeProc(hwnd,lParam);
1549                         break;
1550
1551                 case WM_LBUTTONDOWN:    // \8d\83{\83^\83\93\89\9f\82·
1552                         WmLButtonDownProc(hwnd,lParam);
1553                         break;
1554
1555                 case WM_RBUTTONDOWN:    // \89E\83{\83^\83\93\89\9f\82·
1556                         WmRButtonDownProc(hwnd,lParam);
1557                         break;
1558
1559                 case WM_LBUTTONDBLCLK:          // \8d\83_\83u\83\8b\83N\83\8a\83b\83N
1560                         WmLButtonDblclkProc(hwnd,lParam);
1561                         break;
1562
1563                 case WM_ERASEBKGND:     // \94w\8ci\8fÁ\8b\8e
1564                         return TRUE;    // \94w\8ci\82Í\8fÁ\82³\82È\82¢
1565
1566                 case WM_CLOSE:
1567                         //if (backImage){
1568                         //      ::delete backImage;
1569                         //      backImage = NULL;
1570                         //}
1571                         GetWindowPlacement(hwnd, &winPlace);
1572                         guiFlg = true;
1573                         DestroyWindow( hwnd );
1574                         break;
1575                 case WM_DESTROY:
1576                         GetWindowPlacement(hwnd, &winPlace);
1577                         guiFlg = true;
1578                         guiThread.active = false;
1579
1580                         // wait until GUI thread terminated,
1581                         // and then dispose background image.
1582                         while (1)
1583                         {
1584                                 if (guiThread.finish)
1585                                         break;
1586                         }
1587                         if (backImage)
1588                         {
1589                                 ::delete backImage;
1590                                 backImage = NULL;
1591                         }
1592
1593                         guiWnd = NULL;
1594                         break;
1595
1596                 default:
1597                         return (DefWindowProc(hwnd, message, wParam, lParam));
1598         }
1599
1600         return 0;
1601 }