OSDN Git Service

スクロールバーの表示不正を修正
[nlite/nlite.git] / nlite / nlite_commentview.cpp
1 #include "stdafx.h"
2 #include "nlite_include.h"
3 using namespace std::tr1;
4
5 namespace nlite{
6
7         static const LPCTSTR LIVEURL_PART = TEXT("http://live.nicovideo.jp/watch/");
8         static const LPCTSTR ADDMYLIST_PART = TEXT("http://www.nicovideo.jp/mylist_add/video/");
9
10         static const UINT_PTR SELL_SPACE_LENGTH = 1;
11         //
12         //\83R\83\81\83\93\83g\83r\83\85\81[\93à\82Ì\83R\83\93\83g\83\8d\81[\83\8b\83N\83\89\83X
13         ///////////////////////////////////////////////////////////////////
14
15         CChatReadEdit::CChatReadEdit(CCommentView &m_master):m_master(m_master){
16
17
18         }
19
20         BOOL CChatReadEdit::SetWindowText(const CChatData &chat){
21
22                 BOOL rslt = FALSE;
23                 try{
24                         
25                         tstring viewString(regex_replace(tstring(chat.chatBuf),nliteregex::TAGSTRING,nliteregex::text::NUTHINGSTRING));
26                         rslt = __super::SetWindowText(viewString.c_str());
27
28                         CHARFORMAT2 defaultFormat;
29                         this->GetDefaultCharFormat(defaultFormat);
30                         defaultFormat.dwMask |=  CFM_COLOR;
31                         if(chat.premium == 2 || chat.premium == 3){
32
33                                 defaultFormat.crTextColor = m_master.viewproperty.ownerStringColor;
34                         }
35                         
36                         else {
37
38                                 defaultFormat.crTextColor = m_master.viewproperty.baseStringColor;
39
40                         }
41
42                         BOOL rslt = this->SetDefaultCharFormat(defaultFormat);
43                         
44
45
46                         linkStringBeside(viewString,nliteregex::LILNKREGEX);
47                         
48                         
49
50                 } catch(std::exception &e){
51                         e;
52                         rslt =  FALSE;
53
54                 }
55
56                 return rslt;
57                 
58         }
59
60         VOID CChatReadEdit::linkStringBeside(const tstring &target,const nliteregex::tregex &re){
61
62                 match_results<tstring::const_iterator> regexRslt;
63                 tstring::const_iterator beginStr = target.begin();
64                 tstring::const_iterator endstr = target.end();
65                 CHARFORMAT2 cf;
66                 cf.cbSize = sizeof(cf);
67                 cf.dwMask = CFM_LINK;
68                 cf.dwEffects = CFE_LINK;
69                 INT_PTR basePosition = 0;
70                 while(regex_search(beginStr,endstr,regexRslt,re)){
71                         basePosition += regexRslt.position(0);
72                         this->SetSel(basePosition,basePosition + regexRslt.length());
73                         this->SetCharFormat(cf,SCF_SELECTION);
74                         basePosition += regexRslt.length();
75                                 
76                         beginStr = regexRslt[0].second;
77                 }
78
79         }
80
81         VOID CChatReadEdit::Reset(){
82
83                 __super::SetWindowText(TEXT(""));
84
85                 return;
86         }
87
88         HWND CChatReadEdit::GeneralCreate(HWND hParent,DWORD eventMask,UINT id){
89
90
91                 this->Create(hParent,0,RICHEDIT_CLASS,WS_CHILD | WS_VISIBLE  | WS_CLIPCHILDREN | ES_AUTOVSCROLL | ES_MULTILINE   | ES_READONLY,0,id);
92                 
93                 DWORD dwLangOptons = this->SendMessage(EM_GETLANGOPTIONS,0,0);
94                 dwLangOptons &= ~IMF_DUALFONT;
95                 this->SendMessage(EM_SETLANGOPTIONS,0,(LPARAM)dwLangOptons);
96
97                 
98                 CFont defFont = ::AtlGetDefaultGuiFont();
99                 LOGFONT deflogFont;
100                 defFont.GetLogFont(&deflogFont);
101                 CHARFORMAT2 m_defCharFormat;
102                 this->GetDefaultCharFormat(m_defCharFormat);
103                 CDC cDC = this->GetDC();
104                 int picy = cDC.GetDeviceCaps(LOGPIXELSY);
105                 this->ReleaseDC(cDC.m_hDC);
106                 int point = -MulDiv(deflogFont.lfHeight,72,picy);
107                 int twips = point * 20;
108                 m_defCharFormat.yHeight = twips;
109                 m_defCharFormat.dwEffects ^= CFE_AUTOCOLOR;
110                 _tcscpy(m_defCharFormat.szFaceName,deflogFont.lfFaceName);
111                 this->SetEventMask(eventMask);
112                 
113         this->SetDefaultCharFormat(m_defCharFormat);
114
115
116                 return *this;
117
118         }
119
120         CChatChildCtrls::CChatChildCtrls(CCommentView &hMaster):
121         m_master(hMaster),
122         chatDispCtrl(hMaster)
123         {
124                 
125                 return;
126         }
127
128         
129
130         VOID CChatChildCtrls::Create(){
131
132                 this->chatDispCtrl.GeneralCreate(m_master.m_commentListWindow,ENM_LINK  | ENM_MOUSEEVENTS,CHAT_DISPCTRL_ID);
133
134         }
135
136         VOID CChatChildCtrls::AdjustRect(RECT &rc){
137
138                 rc.left += SELL_SPACE_LENGTH;
139                 rc.top += SELL_SPACE_LENGTH;
140                 rc.right -= SELL_SPACE_LENGTH;
141                 rc.bottom -= SELL_SPACE_LENGTH;
142
143                 return;
144         }
145
146         VOID CChatChildCtrls::Hide(HDWP hdwp){
147
148                 chatDispCtrl.DeferWindowPos(hdwp,chatDispCtrl,0,0,0,0,SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_HIDEWINDOW);
149
150         }
151         
152         VOID CChatChildCtrls::SetCtrl(HDWP hdwp,const RECT  &rc,CCommentList::reference comment,BOOL mulutiLineFlag){
153
154                 
155                 chatDispCtrl.SetWindowText(comment);
156                 RECT chatRect = rc;
157                 
158                 
159                 AdjustRect(chatRect);
160
161                 COLORREF bkColor;
162
163                 if (comment.viewData.selectFlag == TRUE)
164                 {
165                         bkColor = m_master.viewproperty.selectBackColor;
166
167                 }
168                 else  
169                 {
170
171
172                         if(comment.viewData.backColor != CChatData::ViewData::INIT_COLOR){
173                         
174                                 bkColor = comment.viewData.backColor;
175
176                         }else if(comment.listenerData->bgcolor != ListenerData::INIT_COLOR){
177
178                                 bkColor = comment.listenerData->bgcolor;
179
180
181                         } else {
182
183                                 bkColor = m_master.viewproperty.backColor;
184
185
186
187                         }
188                 }
189
190
191                 chatDispCtrl.SetBackgroundColor(bkColor);
192
193                 chatDispCtrl.DeferWindowPos(hdwp,NULL,chatRect.left,chatRect.top,chatRect.right - chatRect.left ,chatRect.bottom - chatRect.top, SWP_NOZORDER | SWP_SHOWWINDOW);
194
195                 return;
196         }
197
198         UINT_PTR CChatChildCtrls::GetCtrlCount(){
199
200                 return 1;
201         }
202
203
204
205         ///
206         ///\83R\83\93\83X\83g\83\89\83N\83^
207         ///
208         CChatChildCtrlsList::CChatChildCtrlsList(CCommentView &hMaster):m_hMaster(hMaster){
209                 
210                 return;
211         }
212
213
214
215         ///
216         ///\83R\83\93\83g\83\8d\81[\83\8b\82ð\95\\8e¦
217         ///
218         VOID CChatChildCtrlsList::ShowCntrls(){
219
220
221                 
222
223                 
224
225                 if(m_hMaster.commentlist.Size() > 0){
226
227
228
229                         RECT headerRect;
230                         RECT tmpRect;
231                         RECT listRect;
232                         m_hMaster.m_commentListWindow.GetClientRect(&listRect);
233                         m_hMaster.m_header.GetItemRect(CCommentView::COMMENT,&headerRect);
234                         headerRect.top = 0;
235                         headerRect.bottom = 0;
236                         
237                         UINT_PTR counter = 0;
238                         INT_PTR heightSum =0;
239
240                         auto ctrlsBegin = m_list.begin();
241                         auto ctrlsEnd = m_list.end();
242                         auto chatDataBegin = m_hMaster.commentlist.GetShortCut();
243                         auto chatDataEnd = m_hMaster.commentlist.end();
244                         auto chatDataTmp = chatDataBegin;
245                         for(;chatDataBegin != chatDataEnd && heightSum < listRect.bottom;++chatDataBegin){
246                                 m_hMaster.m_commentListWindow.CalcItemHeight(*chatDataBegin);
247                                 counter++;
248                                 heightSum += chatDataBegin->viewData.height;
249                         } 
250
251                         
252                 
253                         chatDataBegin = chatDataTmp;
254                         heightSum = 0;
255                         HDWP hdwp = ::BeginDeferWindowPos(CChatChildCtrls::GetCtrlCount() * (counter > m_list.size() ? counter : m_list.size()));
256                         for(;  chatDataBegin != chatDataEnd && counter > 0 ;++ctrlsBegin,++chatDataBegin,--counter){
257                         
258                                 
259                                 tmpRect = headerRect;
260                                 tmpRect.top += heightSum;
261                                 tmpRect.bottom += heightSum + chatDataBegin->viewData.height;
262
263                                 if(ctrlsBegin == ctrlsEnd)ctrlsBegin = Extend();
264
265                                 ctrlsBegin->SetCtrl(hdwp,tmpRect,*chatDataBegin,m_hMaster.viewproperty.commentFoldingFlag);
266
267                                 heightSum = tmpRect.bottom;
268
269                                 
270                         }
271                 
272                         for(;ctrlsBegin != ctrlsEnd;++ctrlsBegin){
273
274                                 ctrlsBegin->Hide(hdwp);
275                         }
276
277                         ::EndDeferWindowPos(hdwp);
278                 }
279                 
280
281
282                 return;
283         }
284
285
286
287         VOID CChatChildCtrlsList::AllHide(){
288
289                 auto begin =m_list.begin();
290                 auto end = m_list.end();
291
292                 HDWP hdwp = ::BeginDeferWindowPos(CChatChildCtrls::GetCtrlCount() * m_list.size());
293                 for(;begin != end;++begin){
294                         begin->Hide(hdwp);
295                 }
296                 ::EndDeferWindowPos(hdwp);
297
298         }
299
300         ///
301         ///\8ag\92£\8f\88\97\9d
302         ///
303         CChatChildCtrlsList::iterator CChatChildCtrlsList::Extend(){
304
305                 
306                 CChatChildCtrls ctrls(m_hMaster);
307                 
308                 m_list.push_back(ctrls);
309                 m_list.back().Create();
310                 auto ite = (--m_list.end());
311         
312                 return ite;
313         }
314
315
316         //
317         //\83R\83\81\83\93\83g\83r\83\85\81[\83N\83\89\83X\83\81\83\\83b\83h
318         ///////////////////////////////////////////////////////
319
320         CCommentView::CCommentView(CNicoLiveStream &stream,CNicoVideoAuth &in_refAuth):
321         m_commentListWindow(*this),
322         stream(stream),
323         refAuth(in_refAuth)
324         ,chatChildCtrlsList(*this)
325
326         {
327
328                 LOGFONT lf = {0};
329                 lf.lfHeight = 10;
330                 lf.lfCharSet = SHIFTJIS_CHARSET;
331
332
333                 hHeaderFontNew = CreateFontIndirect(&lf);
334
335
336                 return;
337
338         }
339
340         CCommentView::~CCommentView(){
341
342
343                 DeleteObject(hHeaderFontNew);
344
345                 return;
346         }
347
348         VOID CCommentView::UpDateUI(){
349
350                 this->chatChildCtrlsList.ShowCntrls();
351                 this->m_commentListWindow.Invalidate();
352                 return;
353         }
354
355
356         VOID CCommentView::OnConnect(){
357                 m_commentListWindow.SetRedraw(FALSE);
358                 m_commentListWindow.ResetViewSellHeight();
359
360                 chatChildCtrlsList.AllHide();
361
362
363                 commentlist.OnConnect();
364
365                 SCROLLINFO vScrollInfo = {0};
366                 vScrollInfo.cbSize = sizeof(vScrollInfo);
367                 vScrollInfo.fMask = SIF_ALL;
368
369                 this->SetScrollInfo(SB_VERT,&vScrollInfo,FALSE);
370
371                 m_commentListWindow.SetRedraw(TRUE);
372                 m_commentListWindow.Invalidate();
373
374
375
376         }
377
378
379         UINT_PTR CCommentView::GetColumnHolSizeSum(){
380
381                 INT_PTR nMin = 0;
382                 INT_PTR nMax = 0;
383                 this->GetScrollRange(SB_HORZ,&nMin,&nMax);
384
385                 return nMax;
386         }
387
388         VOID CCommentView::SetProperty(const CommentViewProperty &setProperty,const GeneralProperty &in_generalProperty){
389
390                 
391                 viewproperty = setProperty;
392                 generalProperty = in_generalProperty;
393                 m_commentListWindow.OnSetProperty();
394                 
395                 return;
396         }
397
398         CommentViewProperty &CCommentView::GetProperty(){
399
400                 return viewproperty;
401
402         }
403
404
405
406
407
408         HWND CCommentView::Create(HWND hWndParent){
409
410
411
412                 HWND rslt = __super::Create(hWndParent,0,commentViewConstant::NLITE_COMMENTVIEW,WS_VISIBLE | WS_CHILD | WS_VSCROLL | WS_HSCROLL | WS_BORDER,0,commentViewConstant::MENU_OR_ID);
413
414                 PAINTSTRUCT ps;
415                 HDC hdc = m_header.BeginPaint(&ps);
416                 SIZE size;
417
418                 HFONT hOld = (HFONT)SelectObject(hdc,hHeaderFontNew);
419
420                 LPTSTR columns[] = {TEXT("\83R\83\81\94Ô"),TEXT("\83\86\81[\83U\81[\96¼"),TEXT("\83R\83\81\83\93\83g"),TEXT("\8e\9e\8aÔ"),TEXT("\8fî\95ñ")};
421                 UINT_PTR holizenSize[] = {0,0,100,0,0};
422
423                 for(UINT_PTR index = 0;index < ARRAY_LENGTH(columns) ;++index){
424
425                         GetTextExtentPoint32(hdc , columns[index] , _tcslen(columns[index]) , &size);
426                         UINT_PTR holsize = holizenSize[index] + size.cx + 15;
427                         holizenSize[index] = viewproperty.headerholSize[index] >= 0 ? viewproperty.headerholSize[index] : holsize;
428                 }
429
430                 SelectObject(hdc,hOld);
431
432                 m_header.EndPaint(&ps);
433
434
435                 HEADERSINFO headersinfo = {columns,holizenSize,ARRAY_LENGTH(columns)};
436
437                 AddHeader(&headersinfo);
438
439                 m_header.SetOrderArray(ARRAY_LENGTH(viewproperty.headerOrderArray),viewproperty.headerOrderArray);
440
441                 
442                 
443
444                 return rslt;
445         }
446
447
448
449
450         LRESULT CCommentView::OnHeaderEndTrack(LPNMHDR lParam){
451
452
453                 if(lParam->hwndFrom == m_header.m_hWnd){
454
455
456                         auto begin = commentlist.begin();
457
458                         auto end = commentlist.end();
459
460                         for(;begin != end;++begin){
461
462                                 begin->viewData.height = 0;
463
464                         }
465
466                         m_commentListWindow.SetRedraw(FALSE);
467                         SCROLLINFO vScrollInfo = {0};
468                         vScrollInfo.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
469
470                         this->GetScrollInfo(SB_VERT,&vScrollInfo);
471                         vScrollInfo.nPage = m_commentListWindow.CalcScrollPage(vScrollInfo.nMax);
472                         vScrollInfo.fMask = SIF_PAGE;
473                         this->SetScrollInfo(SB_VERT,&vScrollInfo);
474
475                         BOOL scrollFlag = vScrollInfo.nPos + (int)vScrollInfo.nPage + 1>= vScrollInfo.nMax;
476                         UINT_PTR commentCount = commentlist.Size();
477                         LPNMHEADER  lpNmHdr = (LPNMHEADER )lParam;
478
479                         m_header.SetItem(lpNmHdr->iItem,lpNmHdr->pitem);
480
481
482
483
484
485
486
487                         if(scrollFlag == TRUE){
488
489                                 this->m_commentListWindow.SendMessageW(WM_VSCROLL,MAKELONG(SB_BOTTOM,0),0);
490                         }
491
492                         INT_PTR itemCount = m_header.GetItemCount();
493                         RECT itemSizeRect;
494
495                         INT_PTR nMax = 0;
496                         for(INT_PTR itemIndex = 0;itemIndex < itemCount;itemIndex++){
497                                 m_header.GetItemRect(itemIndex,&itemSizeRect);
498                                 nMax += itemSizeRect.right - itemSizeRect.left;
499
500                         }
501                         INT_PTR nMin = 0;
502                         this->SetScrollRange(SB_HORZ,nMin,nMax,TRUE);
503                         DecisionHorzSize();
504
505
506                         
507
508                         m_commentListWindow.SetRedraw(TRUE);
509                         
510                         m_commentListWindow.Invalidate();
511                         this->m_commentListWindow.SendMessage(UM_COMMENTVIEW_SETCTRL,NULL,NULL);
512
513                 }
514
515                 return 0;
516         }
517
518         VOID CCommentView::OnChatReceve(NicoLiveChat_P chat,UINT_PTR commnetCountSum){
519
520
521                 commentlist.OnChatReceve(chat,stream.GetDefaultCommunity(),commnetCountSum,this->m_commentListWindow);
522
523                 return;
524         }
525
526
527         VOID CCommentView::OnChatReceveSettle(UINT_PTR chatNo,UINT_PTR commentCountSum){
528
529
530                 SCROLLINFO vScrollInfo = {0};
531
532
533                 vScrollInfo.fMask = SIF_ALL;
534
535                 this->GetScrollInfo(SB_VERT,&vScrollInfo);
536                 BOOL scrollFlag = vScrollInfo.nPos + (int)vScrollInfo.nPage >= vScrollInfo.nMax;
537
538                 vScrollInfo.cbSize = sizeof(vScrollInfo);
539                 vScrollInfo.nMax = commentCountSum;
540                 vScrollInfo.fMask = SIF_RANGE | SIF_PAGE;
541                 vScrollInfo.nPage = m_commentListWindow.CalcScrollPage(vScrollInfo.nMax);
542
543
544                 this->SetScrollInfo(SB_VERT,&vScrollInfo,FALSE);
545
546
547
548
549                 if(scrollFlag == TRUE){
550                         this->PostMessage(WM_VSCROLL,MAKEWORD(SB_BOTTOM,0),0);
551                 }
552
553
554                 if(vScrollInfo.nPos + static_cast<INT_PTR>(vScrollInfo.nPage) >= vScrollInfo.nMax - static_cast<INT_PTR>(vScrollInfo.nPage)){
555                         m_commentListWindow.Invalidate();
556                         this->Invalidate();
557                         
558                         this->m_commentListWindow.PostMessage(UM_COMMENTVIEW_SETCTRL,NULL,NULL);
559                 }
560
561                 return;
562         }
563
564         static UCHAR getrgb(){
565
566                 UCHAR rgb = 192 + rand() % 64;
567                 return rgb;
568         }
569
570
571
572
573
574
575
576
577
578
579
580         LRESULT CCommentView::OnSize(UINT wParam,SIZE lParam){
581                 ChangeSize(lParam);
582
583                 return 0;
584         }
585
586
587         VOID CCommentView::ChangeSize(const SIZE& client){
588
589                 SCROLLINFO hScrollInfo = {0};
590                 hScrollInfo.cbSize = sizeof(hScrollInfo);
591                 hScrollInfo.fMask = SIF_PAGE;
592                 hScrollInfo.nPage = client.cx;
593
594                 this->SetScrollInfo(SB_HORZ,&hScrollInfo);
595                 hScrollInfo.fMask = SIF_ALL;
596                 this->GetScrollInfo(SB_HORZ,&hScrollInfo);
597
598
599                 HDWP hDwp = BeginDeferWindowPos(2);
600
601
602                 INT_PTR movePos =  -1 * hScrollInfo.nPos;
603
604                 m_header.DeferWindowPos(hDwp,m_header.m_hWnd,movePos,0,0,0,SWP_NOSIZE | SWP_NOZORDER);
605                 m_commentListWindow.DeferWindowPos(hDwp,m_commentListWindow.m_hWnd,movePos,commentViewConstant::HEADER_HAIGHT,::GetSystemMetrics(SM_CXFULLSCREEN),client.cy - commentViewConstant::HEADER_HAIGHT,SWP_NOZORDER);         
606
607                 EndDeferWindowPos(hDwp);
608
609
610                 RECT bkRect;
611                 RECT headerRectSize;
612                 m_header.GetWindowRect(&headerRectSize);
613                 bkRect.left = headerRectSize.right - headerRectSize.left - hScrollInfo.nPos;
614                 bkRect.top = 0;
615                 bkRect.right = client.cx ;
616                 bkRect.bottom = client.cy;
617
618
619                 return;
620         }
621
622
623
624         LRESULT CCommentView::OnClickChatNo(UINT uMsg,WPARAM wParam,LPARAM lParam){
625                 
626                 
627                 ::SendMessage(::GetAncestor(*this,GA_ROOT),uMsg,wParam,lParam);
628                 
629                 return 0;
630         }
631                 
632
633         LRESULT CCommentView::OnClickUserName(UINT uMsg,WPARAM wParam,LPARAM lParam){
634                 
635         
636                 ::SendMessage(::GetAncestor(*this,GA_ROOT),uMsg,wParam,lParam);
637                 
638                 return 0;
639         }
640
641         LRESULT CCommentView::OnEraseBkgnd(HDC wParam){
642
643                 return TRUE;
644         }
645
646
647         VOID CCommentView::OnDestroy(){
648                 m_header.GetOrderArray(ARRAY_LENGTH(viewproperty.headerOrderArray),viewproperty.headerOrderArray);
649                 INT_PTR headerItemcount = m_header.GetItemCount();
650                 RECT headerItemRect;
651                 for(INT_PTR itemindex = 0;itemindex < headerItemcount;itemindex++){
652
653                         m_header.GetItemRect(itemindex,&headerItemRect);
654                         viewproperty.headerholSize[itemindex] = headerItemRect.right - headerItemRect.left;
655                 }
656                 commentlist.OnDestroy();
657                 m_header.DestroyWindow();
658                 m_commentListWindow.DestroyWindow();
659                 return;
660
661         }
662
663         LRESULT CCommentView::OnHeaderEndDrag(LPNMHDR lParam){
664
665                 if(lParam->hwndFrom == m_header.m_hWnd){
666                         
667                         LPNMHEADER pNMHeader = (LPNMHEADER) lParam; 
668                         this->m_header.SetItem(pNMHeader->iItem,pNMHeader->pitem);
669                         
670                         m_commentListWindow.Invalidate();
671                         this->m_commentListWindow.SendMessage(UM_COMMENTVIEW_SETCTRL,NULL,NULL);
672                         
673
674                 }
675
676                 return 0;
677         }
678
679         VOID CCommentView::OnHScroll(INT_PTR loWParam,SHORT hiWParam,HWND lParam){
680
681
682                 INT_PTR dy;
683                 SCROLLINFO hScrollInfo = {0};
684                 hScrollInfo.cbSize = sizeof(hScrollInfo);
685                 hScrollInfo.fMask = SIF_ALL;
686                 this->GetScrollInfo(SB_HORZ,&hScrollInfo);
687                 switch(loWParam){
688
689                 case SB_THUMBPOSITION:
690                 case SB_THUMBTRACK:
691                         dy = hiWParam - hScrollInfo.nPos;
692                         break;
693
694                 case SB_LINELEFT:
695                 case SB_PAGELEFT:
696
697                         dy = -1 * hScrollInfo.nPage;
698
699                         break;
700
701                 case SB_LINERIGHT:
702                 case SB_PAGERIGHT:
703
704                         dy = hScrollInfo.nPage + hScrollInfo.nPos > (UINT_PTR)hScrollInfo.nMax ? 0 :(UINT_PTR) (hScrollInfo.nMax - ( hScrollInfo.nPage + hScrollInfo.nPos)) < hScrollInfo.nPage ? (hScrollInfo.nMax - ( hScrollInfo.nPage + hScrollInfo.nPos)) : hScrollInfo.nPage;
705
706                         break;
707
708                 default:
709                         dy = 0;
710                         break;
711
712                 }
713
714                 dy = max(-1 * hScrollInfo.nPos, min(dy, hScrollInfo.nMax - hScrollInfo.nPos));
715
716
717                 if(dy != 0){
718                         hScrollInfo.nPos += dy;
719                         INT_PTR moveRange = -(hScrollInfo.nPos);
720
721                         HDWP hDwp = BeginDeferWindowPos(2);
722
723                         m_header.DeferWindowPos(hDwp,m_header.m_hWnd,moveRange,0,0,0,SWP_NOSIZE | SWP_NOZORDER);
724                         m_commentListWindow.DeferWindowPos(hDwp,m_commentListWindow.m_hWnd,moveRange,commentViewConstant::HEADER_HAIGHT,0,0,SWP_NOSIZE | SWP_NOZORDER);         
725
726                         EndDeferWindowPos(hDwp);
727
728
729                         this->SetScrollInfo(SB_HORZ,&hScrollInfo);
730                 }
731
732                 return;
733         }
734
735
736         VOID CCommentView::OnVScroll(INT_PTR loWParam,SHORT hiWParam,HWND lParam){
737
738                 INT_PTR dy;
739                 SCROLLINFO vScrollInfo = {0};
740                 vScrollInfo.fMask = SIF_ALL;
741
742
743                 this->GetScrollInfo(SB_VERT,&vScrollInfo);
744
745                 switch(loWParam){
746
747
748                 case SB_THUMBPOSITION:
749                 case SB_THUMBTRACK:
750
751                         dy = hiWParam - vScrollInfo.nPos;
752
753                         break;
754
755                 case SB_LINEUP:
756
757                         dy = -1;
758                         break;
759
760                 case SB_LINEDOWN:
761
762                         dy = 1;
763
764                         break;
765
766                 case SB_PAGEUP:
767
768                         dy = -1 * vScrollInfo.nPage;
769
770                         break;
771
772                 case SB_PAGEDOWN:
773
774                         dy = vScrollInfo.nPage;
775
776                         break;
777
778
779                 case SB_TOP:
780
781                         dy = -vScrollInfo.nPos;
782
783                         break;
784
785                 case SB_BOTTOM:
786
787                         dy = vScrollInfo.nMax;
788
789                         break;
790
791                 default:
792
793                         dy = 0;
794
795                         break;
796
797                 }
798
799
800         
801
802                 if(dy != 0){
803
804                         vScrollInfo.nPos += dy;
805                         //              viewStartHeight = vScrollInfo.nPos;
806                         this->SetScrollPos(SB_VERT,vScrollInfo.nPos);
807                         this->commentlist.SetShortCut(this->GetScrollPos(SB_VERT));
808                         //this->SetScrollInfo(SB_VERT,&vScrollInfo);
809                         this->UpdateWindow();
810                         
811                         m_commentListWindow.Invalidate();
812                         this->m_commentListWindow.SendMessage(UM_COMMENTVIEW_SETCTRL,NULL,NULL);        
813                 }
814
815
816
817                 return;
818         }
819
820         LRESULT CCommentView::OnCreate(LPCREATESTRUCT lpcs){
821                 m_header.Create(m_hWnd,0,WC_HEADER,WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN   | HDS_BUTTONS | HDS_HOTTRACK |HDS_DRAGDROP | HDS_FULLDRAG  ,0,commentViewConstant::HEADER_ID);
822                 m_commentListWindow.Create(m_hWnd,0,commentViewConstant::NLITE_COMMENTLISTWINDOW,WS_CHILD | WS_VISIBLE  | WS_CLIPCHILDREN  , 0,commentViewConstant::LISTWINDOW);
823
824
825
826                 return 0;
827         }
828
829         VOID CCommentView::AddHeader(LPHEADERSINFO infos){
830
831
832                 m_header.SetFont(hHeaderFontNew);
833
834                 HDITEM item;
835                 item.mask = HDI_FORMAT | HDI_TEXT | HDI_WIDTH;
836                 item.fmt = HDF_CENTER | HDF_STRING;
837
838
839                 for(UINT_PTR index = 0;index < infos->count ;++index){
840
841                         item.pszText = infos->columns[index];
842
843                         item.cxy =  infos->holizensize[index];
844                         m_header.AddItem(&item);
845                 }
846
847                 RECT itemRect;
848                 INT_PTR nMax = 0;
849                 UINT_PTR itemCount = m_header.GetItemCount();
850                 for(UINT_PTR u_index = 0;u_index < itemCount;++u_index){
851
852                         m_header.GetItemRect(u_index,&itemRect);
853                         nMax += itemRect.right - itemRect.left;
854
855                 }
856
857                 this->SetScrollRange(SB_HORZ,0,nMax,TRUE);
858
859                 DecisionHorzSize();
860                 return;
861         }
862
863         VOID CCommentView::DecisionHorzSize(){
864
865                 HDWP hWindowPosInfo = BeginDeferWindowPos(2);
866                 RECT bkWindowRect;
867                 this->GetClientRect(&bkWindowRect);
868                 m_header.DeferWindowPos(hWindowPosInfo,m_header.m_hWnd,0,0,::GetSystemMetrics(SM_CXFULLSCREEN),commentViewConstant::HEADER_HAIGHT,SWP_NOZORDER | SWP_NOMOVE);
869                 m_commentListWindow.DeferWindowPos(hWindowPosInfo,m_header.m_hWnd,0,0,::GetSystemMetrics(SM_CXFULLSCREEN),bkWindowRect.bottom - commentViewConstant::HEADER_HAIGHT,SWP_NOZORDER | SWP_NOMOVE);
870
871                 EndDeferWindowPos(hWindowPosInfo);
872
873                 return;
874         }
875
876
877
878
879         //
880         //\83R\83\81\83\93\83g\83r\83\85\81[\83N\83\89\83X\93à\95\94\83\8a\83X\83g\83N\83\89\83X
881         ////////////////////////////////////////////////////////////////////
882
883         CCommentListWindow::CCommentListWindow(CCommentView &in_self):
884         self(in_self),
885         viewSellHeight(0)
886         {
887                 CFontHandle font = ::AtlGetDefaultGuiFont();
888                 LOGFONT logfont;
889                 font.GetLogFont(&logfont);
890                 logfont.lfUnderline = TRUE;
891                 
892                 linkFont.CreateFontIndirect(&logfont);
893         }
894
895         CCommentListWindow::~CCommentListWindow(){
896         }
897
898         
899
900         VOID CCommentListWindow::OnSetProperty(){
901
902                 if(IsWindow() == TRUE)this->SetRedraw(FALSE);
903
904                 if(collLinePen.IsNull() == FALSE)collLinePen.DeleteObject();
905                 if(normalSellLinePen.IsNull() == FALSE)normalSellLinePen.DeleteObject();
906                 if(normalBkBrush.IsNull() == FALSE)normalBkBrush.DeleteObject();
907                 if(selectSellLinePen.IsNull() ==FALSE)selectSellLinePen.DeleteObject();
908                 if(selectBkBrush.IsNull() == FALSE)selectBkBrush.DeleteObject();
909
910                 collLinePen.CreatePen(PS_SOLID,1,self.viewproperty.colLineColor);
911                 normalSellLinePen.CreatePen(PS_SOLID,1,self.viewproperty.normalSellLineColor);
912                 normalBkBrush.CreateSolidBrush(self.viewproperty.backColor);
913                 selectSellLinePen.CreatePen(PS_SOLID,1,self.viewproperty.selectSellLineColor);
914                 selectBkBrush.CreateSolidBrush(self.viewproperty.selectBackColor);
915
916
917                 if(IsWindow() == TRUE)this->SetRedraw(TRUE);
918         }
919
920
921         VOID CCommentListWindow::OnPaint(HDC in_hdc){
922
923                 this->self.refAuth.GetUserSession();
924                 RECT windowRect;
925                 RECT listRect = {0};
926                 RECT clientRect;
927
928                 self.GetClientRect(&clientRect);
929                 clientRect.bottom -= commentViewConstant::HEADER_HAIGHT;
930
931                 this->GetWindowRect(&windowRect);
932                 windowRect.right -= windowRect.left;
933                 windowRect.bottom -= windowRect.top;
934                 windowRect.left = 0;
935                 windowRect.top = 0;
936
937
938                 CPaintDC pdc(*this);
939
940                 {
941                         CMemoryDC mdc(pdc,windowRect);
942                         mdc.SelectFont(AtlGetDefaultGuiFont());
943
944
945                         CCommentList &commentList = self.commentlist;
946
947                         BOOL selectFlag = FALSE;
948                         CCommentList::iterator selectData;
949                         RECT selectRect = {0};
950         
951
952
953                         if(commentList.Size() > 0){
954
955                                 listRect = windowRect;
956                                 listRect.right = self.GetColumnHolSizeSum();            
957
958                                 CCommentList::iterator chatData = commentList.GetShortCut();
959
960                         
961                                 
962                                 
963                                 mdc.FillRect(&listRect,this->normalBkBrush);
964                                 
965                                 CCommentList::iterator endData = commentList.end();
966                                 listRect.bottom = 0;
967                                 
968                                 RECT headerRects[COMMENTVIEW_HEADERITEMSIZE];
969                                 RECT colLineRects[COMMENTVIEW_HEADERITEMSIZE];
970                                 RECT selectHeaderRects[COMMENTVIEW_HEADERITEMSIZE];
971                                 
972                                 self.m_header.GetItemRect(CCommentView::NO,&headerRects[CCommentView::NO]);
973                                 self.m_header.GetItemRect(CCommentView::USERNAME,&headerRects[CCommentView::USERNAME]);
974                                 self.m_header.GetItemRect(CCommentView::COMMENT,&headerRects[CCommentView::COMMENT]);
975                                 self.m_header.GetItemRect(CCommentView::TIME,&headerRects[CCommentView::TIME]);
976                                 self.m_header.GetItemRect(CCommentView::INFO,&headerRects[CCommentView::INFO]);
977
978                                 memcpy(colLineRects,headerRects,sizeof(headerRects));
979
980                                 
981                                 
982                                 
983                 
984                                 headerRects[CCommentView::NO].left += SELL_SPACE_LENGTH;
985                                 headerRects[CCommentView::USERNAME].left += SELL_SPACE_LENGTH;
986                                 headerRects[CCommentView::COMMENT].left += SELL_SPACE_LENGTH;
987                                 headerRects[CCommentView::TIME].left += SELL_SPACE_LENGTH;
988                                 headerRects[CCommentView::INFO].left += SELL_SPACE_LENGTH;
989
990                                 headerRects[CCommentView::NO].right -= SELL_SPACE_LENGTH;
991                                 headerRects[CCommentView::USERNAME].right -= SELL_SPACE_LENGTH;
992                                 headerRects[CCommentView::COMMENT].right -= SELL_SPACE_LENGTH;
993                                 headerRects[CCommentView::TIME].right -= SELL_SPACE_LENGTH;
994                                 headerRects[CCommentView::INFO].right -= SELL_SPACE_LENGTH;
995
996                                 headerRects[CCommentView::NO].top = SELL_SPACE_LENGTH;
997                                 headerRects[CCommentView::USERNAME].top = SELL_SPACE_LENGTH;
998                                 headerRects[CCommentView::COMMENT].top = SELL_SPACE_LENGTH;
999                                 headerRects[CCommentView::TIME].top = SELL_SPACE_LENGTH;
1000                                 headerRects[CCommentView::INFO].top = SELL_SPACE_LENGTH;
1001
1002                                 headerRects[CCommentView::NO].bottom = SELL_SPACE_LENGTH;
1003                                 headerRects[CCommentView::USERNAME].bottom = SELL_SPACE_LENGTH;
1004                                 headerRects[CCommentView::COMMENT].bottom = SELL_SPACE_LENGTH;
1005                                 headerRects[CCommentView::TIME].bottom = SELL_SPACE_LENGTH;
1006                                 headerRects[CCommentView::INFO].bottom = SELL_SPACE_LENGTH;
1007
1008                                 INT_PTR listRectTop = listRect.top;
1009                                 for(;chatData != endData && listRect.top < clientRect.bottom;++chatData){
1010                                         CalcItemHeight(*chatData);
1011
1012 //                                      dumpln(TEXT("height:%d"),chatData->viewData.height);
1013                                         listRect.bottom += chatData->viewData.height;
1014
1015                                         headerRects[CCommentView::NO].top = listRect.top + SELL_SPACE_LENGTH;
1016                                         headerRects[CCommentView::USERNAME].top = listRect.top + SELL_SPACE_LENGTH;
1017                                         headerRects[CCommentView::COMMENT].top = listRect.top + SELL_SPACE_LENGTH;
1018                                         headerRects[CCommentView::TIME].top = listRect.top + SELL_SPACE_LENGTH;
1019                                         headerRects[CCommentView::INFO].top = listRect.top + SELL_SPACE_LENGTH;
1020
1021                                         headerRects[CCommentView::NO].bottom = listRect.bottom - SELL_SPACE_LENGTH;
1022                                         headerRects[CCommentView::USERNAME].bottom = listRect.bottom - SELL_SPACE_LENGTH;
1023                                         headerRects[CCommentView::COMMENT].bottom = listRect.bottom - SELL_SPACE_LENGTH;
1024                                         headerRects[CCommentView::TIME].bottom = listRect.bottom - SELL_SPACE_LENGTH;
1025                                         headerRects[CCommentView::INFO].bottom = listRect.bottom - SELL_SPACE_LENGTH;
1026
1027                                         if(chatData->viewData.selectFlag == TRUE){
1028                                                 selectFlag = TRUE;
1029                                                 selectData = chatData;
1030                                                 selectRect = listRect;
1031                                                 memcpy(selectHeaderRects,headerRects,sizeof(headerRects));
1032                                         } else {
1033
1034                                                 
1035
1036
1037                                                 this->DrawItem(mdc,listRect,headerRects,*chatData);
1038                                         }
1039
1040
1041                                         listRect.top = listRect.bottom;
1042                                 }
1043
1044                                 viewSellHeight = listRect.bottom;
1045
1046
1047
1048                                 if(selectFlag == TRUE){
1049                                         this->DrawItem(mdc,selectRect,selectHeaderRects,*selectData);
1050                                 }
1051
1052                                         //\8d\80\96Ú\82Ì\8fc\90ü\82ð\95`\89æ
1053                                 mdc.SelectPen(collLinePen);
1054                                 mdc.MoveTo(colLineRects[CCommentView::NO].right,listRectTop);
1055                                 mdc.LineTo(colLineRects[CCommentView::NO].right,listRect.bottom);
1056                                 mdc.MoveTo(colLineRects[CCommentView::USERNAME].right,listRectTop);
1057                                 mdc.LineTo(colLineRects[CCommentView::USERNAME].right,listRect.bottom);
1058                                 mdc.MoveTo(colLineRects[CCommentView::COMMENT].right,listRectTop);
1059                                 mdc.LineTo(colLineRects[CCommentView::COMMENT].right,listRect.bottom);
1060                                 mdc.MoveTo(colLineRects[CCommentView::TIME].right,listRectTop);
1061                                 mdc.LineTo(colLineRects[CCommentView::TIME].right,listRect.bottom);
1062                                 mdc.MoveTo(colLineRects[CCommentView::INFO].right,listRectTop);
1063                                 mdc.LineTo(colLineRects[CCommentView::INFO].right,listRect.bottom);
1064
1065                         }
1066                         windowRect.left = listRect.right;
1067                         mdc.FillRect(&windowRect,(HBRUSH)::GetStockObject(GRAY_BRUSH));
1068
1069
1070
1071
1072                 }
1073                 
1074
1075                 
1076
1077                 return;
1078         }
1079
1080
1081         LRESULT CCommentListWindow::OnSetCtrol(UINT uMsg,WPARAM wparam,LPARAM lparam){
1082
1083
1084
1085                 self.chatChildCtrlsList.ShowCntrls();
1086
1087
1088
1089                 return 0;
1090         }
1091
1092         VOID CCommentListWindow::OnSize(UINT wParam, _WTYPES_NS::CSize &windowSize){
1093
1094
1095                 SCROLLINFO vScrollInfo = {0};
1096                 vScrollInfo.fMask = SIF_ALL;
1097
1098
1099                 self.GetScrollInfo(SB_VERT,&vScrollInfo);
1100                 BOOL scrollFlag = (UINT)(vScrollInfo.nPage + vScrollInfo.nPos + 1) >= (UINT)vScrollInfo.nMax;
1101                 vScrollInfo.nPage = CalcScrollPage(vScrollInfo.nMax);
1102
1103                 vScrollInfo.fMask = SIF_PAGE;
1104                 self.SetScrollInfo(SB_VERT,&vScrollInfo);
1105
1106
1107
1108                 if(scrollFlag == TRUE){
1109                         self.SendMessageW(WM_VSCROLL,MAKELONG(SB_BOTTOM,0),0);
1110                 }
1111
1112                 this->Invalidate();
1113                 this->SendMessage(UM_COMMENTVIEW_SETCTRL,NULL,NULL);
1114
1115                 return;
1116         }
1117
1118
1119         UINT_PTR CCommentListWindow::CalcScrollPage(UINT_PTR nMax){
1120
1121                 RECT clientRect;
1122                 INT_PTR rslt = 0;
1123                 LONG height = 0;
1124                 this->GetClientRect(&clientRect);
1125
1126                 SCROLLINFO vScrollInfo = {0};
1127                 if(self.commentlist.empty() != TRUE){
1128
1129                         CCommentList::reverse_iterator rbegin = self.commentlist.rbegein();
1130                         CCommentList::reverse_iterator rend = self.commentlist.rend();
1131                         for(;rbegin != rend;++rbegin){
1132                                 CalcItemHeight(*rbegin);
1133                                 height += rbegin->viewData.height;
1134                                 rslt++;
1135                                 if(height > clientRect.bottom)goto overclientrect;
1136
1137                         }
1138                 }
1139                 /*
1140                 vScrollInfo.fMask = SIF_RANGE;
1141                 self.GetScrollInfo(SB_VERT,&vScrollInfo);
1142                 */
1143                 rslt = nMax+ 1;
1144
1145
1146 overclientrect:
1147
1148                 return rslt;
1149         }
1150
1151         VOID CCommentListWindow::DrawItem(CDC &dc,const RECT &rc,const RECT *headerRect,CChatData &chatData){
1152
1153
1154                 RECT noViewRect = headerRect[CCommentView::NO];                                                                         //\83R\83\81\94Ô\95\\8e¦\97Ì\88æ
1155                 RECT userNameViewRect = headerRect[CCommentView::USERNAME];                                                     //\83\86\81[\83U\96¼\95\\8e¦\97Ì\88æ
1156                 RECT chatViewRect = headerRect[CCommentView::COMMENT];                                                          //\83R\83\81\83\93\83g\95\\8e¦\97Ì\88æ
1157                 RECT timeViewRect = headerRect[CCommentView::TIME];                                                                     //\8e\9e\8aÔ\95\\8e¦\97Ì\88æ  
1158                 RECT infoViewRect  = headerRect[CCommentView::INFO];                                                                    //\83R\83\81\83\93\83g\8fî\95ñ\95\\8e¦\97Ì\88æ
1159
1160
1161                 //
1162                 //\83R\83\81\83\93\83g\8e\9e\8aÔ\95\\8e¦\97p\95\8e\9a\97ñ\8dì\90¬
1163                 //
1164                 time_t chatTime = (time_t)difftime(chatData.date,self.stream.GetStartTime());
1165
1166
1167                 BOOL beforeStartFlag = chatTime < 0 ? TRUE : FALSE;
1168                 TCHAR noString[sizeof(chatData.no) * 8]; 
1169                 TCHAR dateString[LENGTH_16];
1170                 if(chatData.no != 0)_stprintf(noString,TEXT("%u"),chatData.no);
1171                 else _tcscpy(noString,TEXT(""));
1172                 CNLiteString timeFormat;
1173
1174
1175                 if(beforeStartFlag == TRUE){
1176
1177                         timeFormat = TEXT("-");
1178                         chatTime = -chatTime;
1179                 }
1180                 tm ct = *gmtime(&chatTime);
1181                 if(ct.tm_hour != 0 ){
1182
1183                         timeFormat += TEXT("%H:%M:%S");
1184
1185                 } else {
1186
1187                         timeFormat += TEXT("%M:%S");
1188                 }
1189
1190                 _tcsftime(dateString,ARRAY_LENGTH(dateString),timeFormat,&ct);
1191
1192
1193                 COLORREF bkColor;                                                                                                       //\94w\8ci\90F
1194                 CPen originSellLinePen;                                                                                                 //\98g\90ü\95`\89æ\97p\83y\83\93
1195                 CBrush originBkBrush;                                                                                                           //\94w\8ci\95`\89æ\97p\83u\83\89\83V
1196                 
1197                 //\91I\91ð\8fó\91Ô\82©\83`\83F\83b\83N
1198                 if (chatData.viewData.selectFlag == TRUE)
1199                 {
1200                         bkColor = self.viewproperty.selectBackColor;
1201                         
1202                         dc.SelectBrush(this->selectBkBrush);
1203                         dc.SelectPen(this->selectSellLinePen);
1204                 }
1205                 else  
1206                 {
1207
1208                         if(chatData.viewData.sellLineColor == CChatData::ViewData::INIT_COLOR){
1209                                 dc.SelectPen(this->normalSellLinePen);
1210
1211                         } else {
1212
1213                                 originSellLinePen.CreatePen(PS_SOLID,1,chatData.viewData.sellLineColor);
1214                                 dc.SelectPen(originSellLinePen);
1215                         }
1216
1217                         
1218
1219                         if(chatData.viewData.backColor != CChatData::ViewData::INIT_COLOR || chatData.listenerData->bgcolor != ListenerData::INIT_COLOR){
1220                         
1221                                 if(chatData.viewData.backColor != CChatData::ViewData::INIT_COLOR){
1222                                         bkColor = chatData.viewData.backColor;
1223                                         originBkBrush.CreateSolidBrush(chatData.viewData.backColor);
1224                                 
1225                                 }else if(chatData.listenerData->bgcolor != ListenerData::INIT_COLOR){
1226
1227                                         bkColor = chatData.listenerData->bgcolor;
1228                                         originBkBrush.CreateSolidBrush(chatData.listenerData->bgcolor);
1229                                         
1230                                 }
1231
1232                                 dc.SelectBrush(originBkBrush);
1233                         } else {
1234
1235                                 bkColor = self.viewproperty.backColor;
1236                                 dc.SelectBrush(this->normalBkBrush);
1237                                 dc.SelectBrush(this->normalBkBrush);
1238
1239
1240                         }
1241                 }
1242                 
1243                 //\94w\8ci\82Æ\98g\90ü\82ð\95`\89æ
1244                 
1245                 
1246                 dc.Rectangle(rc.left,rc.top  - 1,rc.right ,rc.bottom + 1);
1247                 dc.SetBkColor(bkColor);
1248                 
1249
1250                 //\95`\89æ\83T\83C\83Y\82ð\8cv\8eZ
1251
1252
1253                 
1254                 
1255                 CComBSTR &viewUserName = chatData.listenerData->name.Length() == 0 ? chatData.listenerData->user_id : chatData.listenerData->name;
1256                 dc.SelectFont(linkFont);
1257                 dc.SetTextColor(chatData.listenerData->nameColor != ListenerData::INIT_COLOR ? chatData.listenerData->nameColor : self.viewproperty.linkStringColor);
1258                 //\83e\83L\83X\83g\95`\89æ
1259                 dc.DrawTextW(noString,_tcslen(noString),&noViewRect,DT_WORD_ELLIPSIS);
1260
1261                 
1262                 dc.DrawTextW(viewUserName,viewUserName.Length(),&userNameViewRect,DT_WORD_ELLIPSIS);
1263                 dc.SelectFont(::AtlGetDefaultGuiFont());
1264                 dc.SetTextColor(chatData.viewData.stringColor == CChatData::ViewData::INIT_COLOR ? chatData.viewData.stringColor :self.viewproperty.baseStringColor);
1265                 dc.DrawTextW(dateString,_tcslen(dateString),&timeViewRect,DT_WORD_ELLIPSIS);
1266
1267                 return;
1268         }
1269
1270         VOID CCommentListWindow::ResetViewSellHeight(){
1271
1272                 viewSellHeight = 0;
1273
1274                 return;
1275         }
1276
1277
1278         VOID CCommentListWindow::ShowCurSel(){
1279
1280                 auto end = self.commentlist.end();
1281                 INT_PTR cursel = self.commentlist.GetCurSelNo();
1282                 if(cursel == -1)goto end;
1283
1284                 SCROLLINFO vScrollInfo;
1285                 vScrollInfo.cbSize = sizeof(vScrollInfo);
1286                 vScrollInfo.fMask = SIF_ALL;
1287                 self.GetScrollInfo(SB_VERT,&vScrollInfo);
1288                 
1289                 if(!(cursel >= vScrollInfo.nPos + static_cast<INT_PTR>(vScrollInfo.nPage) / 2 && cursel <= vScrollInfo.nPos + static_cast<INT_PTR>(vScrollInfo.nPage) / 2)){
1290                         self.SetScrollPos(SB_VERT,cursel - (vScrollInfo.nPage / 2));
1291                         self.commentlist.SetShortCut(self.GetScrollPos(SB_VERT));
1292                 }
1293
1294                 this->Invalidate();
1295
1296                 this->SendMessage(UM_COMMENTVIEW_SETCTRL,NULL,NULL);
1297 end:
1298
1299                 return;
1300         }
1301
1302
1303
1304         VOID CCommentListWindow::CalcItemHeight(CChatData &chatData){
1305                 
1306                 if(chatData.viewData.height == 0){
1307                         RECT drowSize;
1308                         self.m_header.GetItemRect(CCommentView::COMMENT,&drowSize);
1309                 
1310                         drowSize.bottom = 0;
1311
1312                         CChatReadEdit cedit(self);
1313                 
1314                         cedit.GeneralCreate(*this,ENM_REQUESTRESIZE,CALCEDIT_ID);
1315                         cedit.Reset();
1316                         cedit.SetWindowPos(NULL,0,0,drowSize.right - drowSize.left,drowSize.bottom - drowSize.top,SWP_NOZORDER | SWP_NOMOVE | SWP_NOREDRAW);
1317                         cedit.SetWindowText(chatData);
1318                         cedit.GetClientRect(&drowSize);
1319                         cedit.DestroyWindow();
1320                         drowSize.bottom += 12;
1321                         if(drowSize.bottom - drowSize.top > 120)drowSize.bottom = drowSize.top + 120;
1322                         chatData.viewData.height = drowSize.bottom - drowSize.top;
1323                 }
1324
1325                 return ;
1326         }
1327
1328
1329
1330         LRESULT CCommentListWindow::OnCreate(LPCREATESTRUCT lpCreateStruct){
1331                 
1332                 //CComPtr<IUnknown> iu;
1333                 //::AtlAxCreateControlEx(TEXT("MSHTML:<HTML><BODY></BODY></HTML>"),*this,(IStream*)NULL,(IUnknown**)NULL,&iu,GUID_NULL);
1334
1335                 //iu->QueryInterface(DIID_DWebBrowserEvents2,&addToMyListWindow);
1336                 RECT rc = {0,0,300,200};
1337 //              addToMyListWindow.Create(m_hWnd, &rc,_T("Shell.Explorer.2"),WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN , 0);
1338
1339                 return 0;
1340         }
1341
1342         CCommentList::iterator CCommentListWindow::CalcClickLine(INT_PTR height){
1343
1344                 INT_PTR heightSum = 0;
1345
1346                 CCommentList::iterator chatData = self.commentlist.GetShortCut();
1347                 CCommentList::iterator end  = self.commentlist.end();
1348
1349
1350                 
1351                 for(; chatData != end ;(++chatData)){
1352                         CalcItemHeight(*chatData);
1353                         heightSum += chatData->viewData.height;
1354
1355                         
1356                         if(heightSum >= height)break;
1357                 }
1358                 
1359
1360
1361
1362                 return chatData;
1363         }
1364
1365
1366         BOOL CCommentListWindow::IsOnNoOrUserName(UINT_PTR index,const POINT &point){
1367
1368                 RECT rc = {0};
1369                 
1370                 self.m_header.GetItemRect(index,&rc);
1371                 BOOL rslt = FALSE;
1372
1373                 if((point.x >= rc.left && point.x <= rc.right) && (point.y < static_cast<INT_PTR>(viewSellHeight))){
1374
1375                         INT_PTR heightsum = 0;
1376                         auto clickData = self.commentlist.GetShortCut();
1377                         auto endData = self.commentlist.end();
1378                         for(;clickData != endData;++clickData){
1379
1380                                 heightsum += clickData->viewData.height;
1381
1382                                 if(heightsum > point.y){
1383                                         
1384                                         CDC cdc = this->GetDC();
1385                                         
1386                                         rc.top = heightsum -= clickData->viewData.height;
1387                                         RECT calcRect = {0};
1388                                         cdc.SelectFont(linkFont);
1389
1390
1391                                         if(index == CCommentView::USERNAME){
1392                                                 LPCTSTR viewStr = clickData->listenerData->name.Length() == 0 ? clickData->listenerData->user_id : clickData->listenerData->name;
1393                                                 cdc.DrawTextW(viewStr ,_tcslen(viewStr),&calcRect,DT_CALCRECT);
1394                                         
1395                                         } else if(index == CCommentView::NO){
1396                                                 TCHAR viewStr[sizeof(UINT_PTR) * 8];
1397                                                 _stprintf(viewStr,TEXT("%d"),clickData->no);
1398                                                 cdc.DrawTextW(viewStr,_tcslen(viewStr),&calcRect,DT_CALCRECT);
1399
1400                                         }
1401                                         rc.bottom = rc.top +  calcRect.bottom - calcRect.top;
1402                                         rc.right = rc.right > rc.left + calcRect.right - calcRect.left ? rc.left + calcRect.right - calcRect.left : rc.right;
1403                                         rslt = (point.y >= rc.top && point.y <= rc.bottom && point.x >= rc.left && point.x <= rc.right);
1404                                         
1405                                         break;
1406
1407                                 }
1408                         }
1409                         
1410                 }
1411
1412                 return rslt;
1413
1414         }
1415
1416
1417         VOID CCommentListWindow::OnDestroy(){
1418
1419 //              this->addToMyListWindow.DestroyWindow();
1420
1421         }
1422
1423         VOID CCommentListWindow::OnLButtonDown(UINT wParam, _WTYPES_NS::CPoint &point){
1424
1425
1426
1427                 CCommentList::iterator ite;
1428                 this->SetFocus();
1429                 if(point.x > (INT_PTR)self.GetColumnHolSizeSum()) goto end;
1430
1431                 
1432                 if(self.commentlist.empty() == TRUE)goto end;
1433                 
1434                 ite = CalcClickLine(point.y);
1435                 self.commentlist.SetCurSel(ite);
1436                 
1437                 if(this->IsOnNoOrUserName(CCommentView::NO,point) == TRUE){
1438
1439                         ::SendMessage(self,UM_CLICK_CHATNO,(WPARAM)&(*ite),(LPARAM)self.m_hWnd);
1440
1441                 } else if(this->IsOnNoOrUserName(CCommentView::USERNAME,point) == TRUE){
1442
1443                         ::SendMessage(self,UM_CLICK_USERNAME,(WPARAM)&(*ite),(LPARAM)self.m_hWnd);
1444                 }
1445
1446
1447                 
1448
1449 end:
1450                 this->Invalidate();
1451                 this->SendMessage(UM_COMMENTVIEW_SETCTRL,NULL,NULL);
1452
1453                 return;
1454         }
1455
1456
1457         VOID CCommentListWindow::OnLButtonDblClk(UINT wParam, _WTYPES_NS::CPoint &point){
1458
1459
1460
1461                 if(!(point.x > (INT_PTR)self.GetColumnHolSizeSum() || self.commentlist.empty() == TRUE)){
1462                 
1463                         auto end  = self.commentlist.end();
1464                         auto lineIte = CalcClickLine(point.y);
1465                         if( lineIte == end)goto  endlabel;
1466                 
1467                 
1468                         COLORREF bkColor;
1469                         if(lineIte->listenerData->bgcolor == ListenerData::INIT_COLOR){
1470                                 CListenerColorCollector colorCollector;
1471                                 listenerList.BkColorCollect(colorCollector);
1472                                 UCHAR red;
1473                                 UCHAR green;
1474                                 UCHAR blue;
1475
1476                                 srand((unsigned int)time(NULL));
1477                                 do{
1478
1479                                         red = getrgb();
1480                                         green = getrgb();
1481                                         blue = getrgb();
1482                                         bkColor = PALETTERGB(red,green,blue);
1483
1484                                 }while(colorCollector.Find(bkColor));
1485
1486                                 
1487                                 lineIte->listenerData->SetBkColor(bkColor);
1488                         } else {
1489
1490
1491                                 lineIte->listenerData->bgcolor = ListenerData::INIT_COLOR;
1492                         }
1493                 }
1494
1495
1496
1497
1498
1499 endlabel:
1500
1501
1502                 this->Invalidate(TRUE);
1503
1504                 this->SendMessage(UM_COMMENTVIEW_SETCTRL,NULL,NULL);
1505                 return;
1506         }
1507
1508         LRESULT CCommentListWindow::OnEraseBkGnd(HDC lparam){
1509
1510                 return TRUE;
1511         }
1512
1513         VOID CCommentListWindow::OnKeyDown(TCHAR vKey,UINT loLParam,UINT hiLParam){
1514
1515                 INT_PTR dy = 0;
1516                 switch(vKey){
1517
1518                 case VK_DOWN:
1519                 case VK_RETURN:
1520                         dy = 1;
1521
1522                         break;
1523                 case VK_UP:
1524
1525                         dy = -1;
1526                         break;
1527                 default:
1528                         break;
1529
1530
1531                 }
1532
1533                 
1534                 
1535
1536                 auto cursel = self.commentlist.GetCurSel();
1537                 if((dy < 0 && cursel == self.commentlist.begin())  || dy >= static_cast<INT_PTR>(self.commentlist.Size()))goto end;
1538
1539                 
1540                 std::advance(cursel,dy);
1541                 self.commentlist.SetCurSel(cursel);
1542
1543                 this->ShowCurSel();
1544 end:
1545
1546                                         
1547                 return;
1548         }
1549
1550         LRESULT CCommentListWindow::OnSetCursor(HWND wparam,UINT loLparam,UINT hiLparam){
1551
1552                 
1553                 POINT mousePoint = {0};
1554         
1555                 GetCursorPos(&mousePoint);
1556                 ::ScreenToClient(*this,&mousePoint);
1557                 
1558                 if(( IsOnNoOrUserName(CCommentView::NO,mousePoint) || IsOnNoOrUserName(CCommentView::USERNAME,mousePoint))){
1559                         
1560                         
1561                         ::SetCursor(::LoadCursorW(NULL,IDC_HAND));
1562
1563                 } else {
1564
1565                         DefWindowProc ();
1566
1567                 }
1568                 
1569
1570                 
1571         
1572
1573                 return FALSE;
1574         }
1575
1576         LRESULT CCommentListWindow::OnMouseWheel(UINT loWparam,SHORT hiWparam,CPoint &point){
1577
1578
1579                 self.SendMessageW(WM_VSCROLL,MAKELONG(hiWparam < 0 ? SB_PAGEDOWN : SB_PAGEUP ,0),0);
1580
1581
1582                 return 0;
1583         }
1584
1585         
1586
1587
1588         LRESULT CCommentListWindow::OnChatControlNortify(LPNMHDR lParam){
1589
1590                 LRESULT rslt = 0;
1591
1592                 switch(lParam->code){
1593
1594                 case EN_LINK:
1595                         {
1596                                 ENLINK *lpenlk = (ENLINK *)lParam;
1597                                 if (lpenlk->msg == WM_LBUTTONDOWN) {
1598                                         CRichEditCtrl chatReadEdit = lpenlk->nmhdr.hwndFrom;
1599                                         chatReadEdit.SetSel(lpenlk->chrg);
1600                                         CString selTextBuf;
1601                                         chatReadEdit.GetSelText(selTextBuf);
1602                                         if(regex_match((LPCTSTR)selTextBuf,nliteregex::URL) == TRUE){
1603
1604                                                 
1605                                                 
1606
1607                                         } else if(regex_match((LPCTSTR)selTextBuf,nliteregex::VIDEOID) == TRUE){
1608                                                 
1609                                                 selTextBuf.Insert(0,ADDMYLIST_PART);
1610                                 
1611                                         } else if( regex_match((LPCTSTR)selTextBuf,nliteregex::LIVEID) == TRUE){
1612                                                 
1613                                                 selTextBuf.Insert(0,LIVEURL_PART);
1614                                                 
1615                                         }
1616                                         
1617                                         OpenURL(*this,self.generalProperty,selTextBuf,SW_SHOWNORMAL);
1618                                 }
1619                         }
1620                         break;
1621
1622                 case EN_MSGFILTER:
1623                         {
1624                                 auto pmf = (MSGFILTER *)lParam;
1625                                 if (pmf->msg == WM_LBUTTONDOWN || pmf->msg== WM_LBUTTONDBLCLK || pmf->msg == WM_MOUSEWHEEL){
1626
1627                                         RECT  windowrect;
1628                                         ::GetWindowRect(pmf->nmhdr.hwndFrom,&windowrect);
1629                                         _WTYPES_NS::CPoint point(windowrect.left +  LOWORD(pmf->lParam),windowrect.top + HIWORD(pmf->lParam));
1630                                         ::ScreenToClient(*this,&point);
1631
1632                                         switch(pmf->msg){
1633
1634                                         case WM_LBUTTONDOWN:
1635                                                 OnLButtonDown(pmf->wParam,point);
1636                                                 break;
1637
1638                                         case WM_LBUTTONDBLCLK:
1639                                                 OnLButtonDblClk(pmf->wParam,point);
1640                                                 break;
1641
1642                                         case WM_MOUSEWHEEL:
1643                                                 OnMouseWheel(LOWORD(pmf->wParam),HIWORD(pmf->wParam),point);
1644                                                 break;
1645
1646                                         default:
1647
1648                                                 break;
1649                                         }
1650                                         
1651                                 } 
1652
1653                                         
1654
1655                                 
1656             }
1657                         break;
1658
1659
1660                 default:
1661
1662                         break;
1663
1664                 }
1665
1666
1667                 return rslt;
1668         }
1669
1670         LRESULT CCommentListWindow::OnCalcSellSize(LPNMHDR lParam){
1671
1672                 auto pReqResize = reinterpret_cast <REQRESIZE *>(lParam);
1673                 ::SetWindowPos(pReqResize->nmhdr.hwndFrom,NULL,0,0,pReqResize->rc.right - pReqResize->rc.left,pReqResize->rc.bottom - pReqResize->rc.top,SWP_NOZORDER | SWP_NOMOVE | SWP_HIDEWINDOW);
1674                 return 0;
1675         }
1676
1677 }