2 #include "nlite_include.h"
3 using namespace std::tr1;
7 static const LPCTSTR LIVEURL_PART = TEXT("http://live.nicovideo.jp/watch/");
9 static const UINT_PTR SELL_SPACE_LENGTH = 1;
11 //
\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
12 ///////////////////////////////////////////////////////////////////
14 CChatReadEdit::CChatReadEdit(CCommentView &m_master):m_master(m_master){
19 BOOL CChatReadEdit::SetWindowText(const CChatData &chat){
24 tstring viewString(regex_replace(tstring(chat.chatBuf),nliteregex::TAGSTRING,nliteregex::NUTHINGSTRING));
25 rslt = __super::SetWindowText(viewString.c_str());
27 CHARFORMAT2 defaultFormat;
28 this->GetDefaultCharFormat(defaultFormat);
29 defaultFormat.dwMask |= CFM_COLOR;
30 if(chat.premium == 2 || chat.premium == 3){
32 defaultFormat.crTextColor = m_master.viewproperty.ownerStringColor;
37 defaultFormat.crTextColor = m_master.viewproperty.baseStringColor;
41 BOOL rslt = this->SetDefaultCharFormat(defaultFormat);
45 linkStringBeside(viewString,nliteregex::LILNKREGEX);
49 } catch(std::exception &e){
59 VOID CChatReadEdit::linkStringBeside(const tstring &target,const nliteregex::tregex &re){
61 match_results<tstring::const_iterator> regexRslt;
62 tstring::const_iterator beginStr = target.begin();
63 tstring::const_iterator endstr = target.end();
65 cf.cbSize = sizeof(cf);
67 cf.dwEffects = CFE_LINK;
68 INT_PTR basePosition = 0;
69 while(regex_search(beginStr,endstr,regexRslt,re)){
70 basePosition += regexRslt.position(0);
71 this->SetSel(basePosition,basePosition + regexRslt.length());
72 this->SetCharFormat(cf,SCF_SELECTION);
73 basePosition += regexRslt.length();
75 beginStr = regexRslt[0].second;
80 VOID CChatReadEdit::Reset(){
82 __super::SetWindowText(TEXT(""));
87 HWND CChatReadEdit::GeneralCreate(HWND hParent,DWORD eventMask,UINT id){
90 this->Create(hParent,0,RICHEDIT_CLASS,WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | ES_AUTOVSCROLL | ES_MULTILINE | ES_READONLY,0,id);
92 DWORD dwLangOptons = this->SendMessage(EM_GETLANGOPTIONS,0,0);
93 dwLangOptons &= ~IMF_DUALFONT;
94 this->SendMessage(EM_SETLANGOPTIONS,0,(LPARAM)dwLangOptons);
97 CFont defFont = ::AtlGetDefaultGuiFont();
99 defFont.GetLogFont(&deflogFont);
100 CHARFORMAT2 m_defCharFormat;
101 this->GetDefaultCharFormat(m_defCharFormat);
102 CDC cDC = this->GetDC();
103 int picy = cDC.GetDeviceCaps(LOGPIXELSY);
104 this->ReleaseDC(cDC.m_hDC);
105 int point = -MulDiv(deflogFont.lfHeight,72,picy);
106 int twips = point * 20;
107 m_defCharFormat.yHeight = twips;
108 m_defCharFormat.dwEffects ^= CFE_AUTOCOLOR;
109 _tcscpy(m_defCharFormat.szFaceName,deflogFont.lfFaceName);
110 this->SetEventMask(eventMask);
112 this->SetDefaultCharFormat(m_defCharFormat);
119 CChatChildCtrls::CChatChildCtrls(CCommentView &hMaster):
121 chatDispCtrl(hMaster)
129 VOID CChatChildCtrls::Create(){
131 this->chatDispCtrl.GeneralCreate(m_master.m_commentListWindow,ENM_LINK | ENM_MOUSEEVENTS,CHAT_DISPCTRL_ID);
135 VOID CChatChildCtrls::AdjustRect(RECT &rc){
137 rc.left += SELL_SPACE_LENGTH;
138 rc.top += SELL_SPACE_LENGTH;
139 rc.right -= SELL_SPACE_LENGTH;
140 rc.bottom -= SELL_SPACE_LENGTH;
145 VOID CChatChildCtrls::Hide(HDWP hdwp){
147 chatDispCtrl.DeferWindowPos(hdwp,chatDispCtrl,0,0,0,0,SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_HIDEWINDOW);
151 VOID CChatChildCtrls::SetCtrl(HDWP hdwp,const RECT &rc,CCommentList::reference comment,BOOL mulutiLineFlag){
154 chatDispCtrl.SetWindowText(comment);
158 AdjustRect(chatRect);
162 if (comment.viewData.selectFlag == TRUE)
164 bkColor = m_master.viewproperty.selectBackColor;
171 if(comment.viewData.backColor != CChatData::ViewData::INIT_COLOR){
173 bkColor = comment.viewData.backColor;
175 }else if(comment.listenerData->originBkFlag == TRUE){
177 bkColor = comment.listenerData->bkColor;
182 bkColor = m_master.viewproperty.backColor;
190 chatDispCtrl.SetBackgroundColor(bkColor);
192 chatDispCtrl.DeferWindowPos(hdwp,NULL,chatRect.left,chatRect.top,chatRect.right - chatRect.left ,chatRect.bottom - chatRect.top, SWP_NOZORDER | SWP_SHOWWINDOW);
197 UINT_PTR CChatChildCtrls::GetCtrlCount(){
205 ///
\83R
\83\93\83X
\83g
\83\89\83N
\83^
207 CChatChildCtrlsList::CChatChildCtrlsList(CCommentView &hMaster):m_hMaster(hMaster){
215 ///
\83R
\83\93\83g
\83\8d\81[
\83\8b\82ð
\95\
\8e¦
217 VOID CChatChildCtrlsList::ShowCntrls(){
224 if(m_hMaster.commentlist.Size() > 0){
231 m_hMaster.m_commentListWindow.GetClientRect(&listRect);
232 m_hMaster.m_header.GetItemRect(CCommentView::COMMENT,&headerRect);
234 headerRect.bottom = 0;
236 UINT_PTR counter = 0;
237 INT_PTR heightSum =0;
239 auto ctrlsBegin = m_list.begin();
240 auto ctrlsEnd = m_list.end();
241 auto chatDataBegin = m_hMaster.commentlist.GetShortCut();
242 auto chatDataEnd = m_hMaster.commentlist.end();
243 auto chatDataTmp = chatDataBegin;
244 for(;chatDataBegin != chatDataEnd && heightSum < listRect.bottom;++chatDataBegin){
245 m_hMaster.m_commentListWindow.CalcItemHeight(*chatDataBegin);
247 heightSum += chatDataBegin->viewData.height;
252 chatDataBegin = chatDataTmp;
254 HDWP hdwp = ::BeginDeferWindowPos(CChatChildCtrls::GetCtrlCount() * (counter > m_list.size() ? counter : m_list.size()));
255 for(; chatDataBegin != chatDataEnd && counter > 0 ;++ctrlsBegin,++chatDataBegin,--counter){
258 tmpRect = headerRect;
259 tmpRect.top += heightSum;
260 tmpRect.bottom += heightSum + chatDataBegin->viewData.height;
262 if(ctrlsBegin == ctrlsEnd)ctrlsBegin = Extend();
264 ctrlsBegin->SetCtrl(hdwp,tmpRect,*chatDataBegin,m_hMaster.viewproperty.commentFoldingFlag);
266 heightSum = tmpRect.bottom;
271 for(;ctrlsBegin != ctrlsEnd;++ctrlsBegin){
273 ctrlsBegin->Hide(hdwp);
276 ::EndDeferWindowPos(hdwp);
286 VOID CChatChildCtrlsList::AllHide(){
288 auto begin =m_list.begin();
289 auto end = m_list.end();
291 HDWP hdwp = ::BeginDeferWindowPos(CChatChildCtrls::GetCtrlCount() * m_list.size());
292 for(;begin != end;++begin){
295 ::EndDeferWindowPos(hdwp);
300 ///
\8ag
\92£
\8f\88\97\9d
302 CChatChildCtrlsList::iterator CChatChildCtrlsList::Extend(){
305 CChatChildCtrls ctrls(m_hMaster);
307 m_list.push_back(ctrls);
308 m_list.back().Create();
309 auto ite = (--m_list.end());
316 //
\83R
\83\81\83\93\83g
\83r
\83\85\81[
\83N
\83\89\83X
\83\81\83\
\83b
\83h
317 ///////////////////////////////////////////////////////
319 CCommentView::CCommentView(CNicoLiveStream &stream,CNicoVideoAuth &in_refAuth):
320 m_commentListWindow(*this),
323 ,chatChildCtrlsList(*this)
329 lf.lfCharSet = SHIFTJIS_CHARSET;
332 hHeaderFontNew = CreateFontIndirect(&lf);
339 CCommentView::~CCommentView(){
342 DeleteObject(hHeaderFontNew);
350 VOID CCommentView::OnConnect(){
351 m_commentListWindow.SetRedraw(FALSE);
352 m_commentListWindow.ResetViewSellHeight();
354 chatChildCtrlsList.AllHide();
357 commentlist.OnConnect();
359 SCROLLINFO vScrollInfo = {0};
360 vScrollInfo.cbSize = sizeof(vScrollInfo);
361 vScrollInfo.fMask = SIF_ALL;
363 this->SetScrollInfo(SB_VERT,&vScrollInfo,FALSE);
365 m_commentListWindow.SetRedraw(TRUE);
366 m_commentListWindow.Invalidate();
373 UINT_PTR CCommentView::GetColumnHolSizeSum(){
377 this->GetScrollRange(SB_HORZ,&nMin,&nMax);
382 VOID CCommentView::SetProperty(const CommentViewProperty &setProperty,const GeneralProperty &in_generalProperty){
385 viewproperty = setProperty;
386 generalProperty = in_generalProperty;
387 m_commentListWindow.OnSetProperty();
392 CommentViewProperty &CCommentView::GetProperty(){
402 HWND CCommentView::Create(HWND hWndParent){
406 HWND rslt = __super::Create(hWndParent,0,commentViewConstant::NLITE_COMMENTVIEW,WS_VISIBLE | WS_CHILD | WS_VSCROLL | WS_HSCROLL | WS_BORDER,0,commentViewConstant::MENU_OR_ID);
409 HDC hdc = m_header.BeginPaint(&ps);
412 HFONT hOld = (HFONT)SelectObject(hdc,hHeaderFontNew);
414 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ñ")};
415 UINT_PTR holizenSize[] = {0,0,100,0,0};
417 for(UINT_PTR index = 0;index < ARRAY_LENGTH(columns) ;++index){
419 GetTextExtentPoint32(hdc , columns[index] , _tcslen(columns[index]) , &size);
420 UINT_PTR holsize = holizenSize[index] + size.cx + 15;
421 holizenSize[index] = viewproperty.headerholSize[index] >= 0 ? viewproperty.headerholSize[index] : holsize;
424 SelectObject(hdc,hOld);
426 m_header.EndPaint(&ps);
429 HEADERSINFO headersinfo = {columns,holizenSize,ARRAY_LENGTH(columns)};
431 AddHeader(&headersinfo);
433 m_header.SetOrderArray(ARRAY_LENGTH(viewproperty.headerOrderArray),viewproperty.headerOrderArray);
444 LRESULT CCommentView::OnHeaderEndTrack(LPNMHDR lParam){
447 if(lParam->hwndFrom == m_header.m_hWnd){
450 auto begin = commentlist.begin();
452 auto end = commentlist.end();
454 for(;begin != end;++begin){
456 begin->viewData.height = 0;
460 m_commentListWindow.SetRedraw(FALSE);
461 SCROLLINFO vScrollInfo = {0};
462 vScrollInfo.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
464 this->GetScrollInfo(SB_VERT,&vScrollInfo);
465 vScrollInfo.nPage = m_commentListWindow.CalcScrollPage(vScrollInfo.nMax);
466 vScrollInfo.fMask = SIF_PAGE;
467 this->SetScrollInfo(SB_VERT,&vScrollInfo);
469 BOOL scrollFlag = vScrollInfo.nPos + (int)vScrollInfo.nPage + 1>= vScrollInfo.nMax;
470 UINT_PTR commentCount = commentlist.Size();
471 LPNMHEADER lpNmHdr = (LPNMHEADER )lParam;
473 m_header.SetItem(lpNmHdr->iItem,lpNmHdr->pitem);
481 if(scrollFlag == TRUE){
483 this->m_commentListWindow.SendMessageW(WM_VSCROLL,MAKELONG(SB_BOTTOM,0),0);
486 INT_PTR itemCount = m_header.GetItemCount();
490 for(INT_PTR itemIndex = 0;itemIndex < itemCount;itemIndex++){
491 m_header.GetItemRect(itemIndex,&itemSizeRect);
492 nMax += itemSizeRect.right - itemSizeRect.left;
496 this->SetScrollRange(SB_HORZ,nMin,nMax,TRUE);
502 m_commentListWindow.SetRedraw(TRUE);
504 m_commentListWindow.Invalidate();
505 this->m_commentListWindow.SendMessage(UM_COMMENTVIEW_SETCTRL,NULL,NULL);
512 VOID CCommentView::OnChatReceve(NicoLiveChat_P chat,UINT_PTR commnetCountSum){
515 commentlist.OnChatReceve(chat,commnetCountSum,this->m_commentListWindow);
521 VOID CCommentView::OnChatReceveSettle(UINT_PTR chatNo,UINT_PTR commentCountSum){
524 SCROLLINFO vScrollInfo = {0};
527 vScrollInfo.fMask = SIF_ALL;
529 this->GetScrollInfo(SB_VERT,&vScrollInfo);
530 BOOL scrollFlag = vScrollInfo.nPos + (int)vScrollInfo.nPage >= vScrollInfo.nMax;
532 vScrollInfo.cbSize = sizeof(vScrollInfo);
533 vScrollInfo.nMax = commentCountSum;
534 vScrollInfo.fMask = SIF_RANGE | SIF_PAGE;
535 vScrollInfo.nPage = m_commentListWindow.CalcScrollPage(vScrollInfo.nMax);
538 this->SetScrollInfo(SB_VERT,&vScrollInfo,FALSE);
543 if(scrollFlag == TRUE){
544 this->PostMessage(WM_VSCROLL,MAKEWORD(SB_BOTTOM,0),0);
548 if(vScrollInfo.nPos + static_cast<INT_PTR>(vScrollInfo.nPage) >= vScrollInfo.nMax - static_cast<INT_PTR>(vScrollInfo.nPage)){
549 m_commentListWindow.Invalidate();
551 this->PostMessage(UM_COMMENTVIEW_SETCTRL,NULL,NULL);
557 static UCHAR getrgb(){
559 UCHAR rgb = 192 + rand() % 64;
573 LRESULT CCommentView::OnSize(UINT wParam,SIZE lParam){
580 VOID CCommentView::ChangeSize(const SIZE& client){
582 SCROLLINFO hScrollInfo = {0};
583 hScrollInfo.cbSize = sizeof(hScrollInfo);
584 hScrollInfo.fMask = SIF_PAGE;
585 hScrollInfo.nPage = client.cx;
587 this->SetScrollInfo(SB_HORZ,&hScrollInfo);
588 hScrollInfo.fMask = SIF_ALL;
589 this->GetScrollInfo(SB_HORZ,&hScrollInfo);
592 HDWP hDwp = BeginDeferWindowPos(2);
595 INT_PTR movePos = -1 * hScrollInfo.nPos;
597 m_header.DeferWindowPos(hDwp,m_header.m_hWnd,movePos,0,0,0,SWP_NOSIZE | SWP_NOZORDER);
598 m_commentListWindow.DeferWindowPos(hDwp,m_commentListWindow.m_hWnd,movePos,commentViewConstant::HEADER_HAIGHT,::GetSystemMetrics(SM_CXFULLSCREEN),client.cy - commentViewConstant::HEADER_HAIGHT,SWP_NOZORDER);
600 EndDeferWindowPos(hDwp);
605 m_header.GetWindowRect(&headerRectSize);
606 bkRect.left = headerRectSize.right - headerRectSize.left - hScrollInfo.nPos;
608 bkRect.right = client.cx ;
609 bkRect.bottom = client.cy;
616 LRESULT CCommentView::OnEraseBkgnd(HDC wParam){
622 VOID CCommentView::OnDestroy(){
623 m_header.GetOrderArray(ARRAY_LENGTH(viewproperty.headerOrderArray),viewproperty.headerOrderArray);
624 INT_PTR headerItemcount = m_header.GetItemCount();
626 for(INT_PTR itemindex = 0;itemindex < headerItemcount;itemindex++){
628 m_header.GetItemRect(itemindex,&headerItemRect);
629 viewproperty.headerholSize[itemindex] = headerItemRect.right - headerItemRect.left;
631 commentlist.OnDestroy();
632 m_header.DestroyWindow();
633 m_commentListWindow.DestroyWindow();
638 LRESULT CCommentView::OnHeaderEndDrag(LPNMHDR lParam){
640 if(lParam->hwndFrom == m_header.m_hWnd){
642 LPNMHEADER pNMHeader = (LPNMHEADER) lParam;
643 this->m_header.SetItem(pNMHeader->iItem,pNMHeader->pitem);
645 m_commentListWindow.Invalidate();
646 this->m_commentListWindow.SendMessage(UM_COMMENTVIEW_SETCTRL,NULL,NULL);
654 VOID CCommentView::OnHScroll(INT_PTR loWParam,SHORT hiWParam,HWND lParam){
658 SCROLLINFO hScrollInfo = {0};
659 hScrollInfo.cbSize = sizeof(hScrollInfo);
660 hScrollInfo.fMask = SIF_ALL;
661 this->GetScrollInfo(SB_HORZ,&hScrollInfo);
664 case SB_THUMBPOSITION:
666 dy = hiWParam - hScrollInfo.nPos;
672 dy = -1 * hScrollInfo.nPage;
679 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;
689 dy = max(-1 * hScrollInfo.nPos, min(dy, hScrollInfo.nMax - hScrollInfo.nPos));
693 hScrollInfo.nPos += dy;
694 INT_PTR moveRange = -(hScrollInfo.nPos);
696 HDWP hDwp = BeginDeferWindowPos(2);
698 m_header.DeferWindowPos(hDwp,m_header.m_hWnd,moveRange,0,0,0,SWP_NOSIZE | SWP_NOZORDER);
699 m_commentListWindow.DeferWindowPos(hDwp,m_commentListWindow.m_hWnd,moveRange,commentViewConstant::HEADER_HAIGHT,0,0,SWP_NOSIZE | SWP_NOZORDER);
701 EndDeferWindowPos(hDwp);
704 this->SetScrollInfo(SB_HORZ,&hScrollInfo);
711 VOID CCommentView::OnVScroll(INT_PTR loWParam,SHORT hiWParam,HWND lParam){
714 SCROLLINFO vScrollInfo = {0};
715 vScrollInfo.fMask = SIF_ALL;
718 this->GetScrollInfo(SB_VERT,&vScrollInfo);
723 case SB_THUMBPOSITION:
726 dy = hiWParam - vScrollInfo.nPos;
743 dy = -1 * vScrollInfo.nPage;
749 dy = vScrollInfo.nPage;
756 dy = -vScrollInfo.nPos;
762 dy = vScrollInfo.nMax;
779 vScrollInfo.nPos += dy;
780 // viewStartHeight = vScrollInfo.nPos;
781 this->SetScrollPos(SB_VERT,vScrollInfo.nPos);
782 this->commentlist.SetShortCut(this->GetScrollPos(SB_VERT));
783 //this->SetScrollInfo(SB_VERT,&vScrollInfo);
784 this->UpdateWindow();
786 m_commentListWindow.Invalidate();
787 this->m_commentListWindow.SendMessage(UM_COMMENTVIEW_SETCTRL,NULL,NULL);
795 LRESULT CCommentView::OnCreate(LPCREATESTRUCT lpcs){
796 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);
797 m_commentListWindow.Create(m_hWnd,0,commentViewConstant::NLITE_COMMENTLISTWINDOW,WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN , 0,commentViewConstant::LISTWINDOW);
804 VOID CCommentView::AddHeader(LPHEADERSINFO infos){
807 m_header.SetFont(hHeaderFontNew);
810 item.mask = HDI_FORMAT | HDI_TEXT | HDI_WIDTH;
811 item.fmt = HDF_CENTER | HDF_STRING;
814 for(UINT_PTR index = 0;index < infos->count ;++index){
816 item.pszText = infos->columns[index];
818 item.cxy = infos->holizensize[index];
819 m_header.AddItem(&item);
824 UINT_PTR itemCount = m_header.GetItemCount();
825 for(UINT_PTR u_index = 0;u_index < itemCount;++u_index){
827 m_header.GetItemRect(u_index,&itemRect);
828 nMax += itemRect.right - itemRect.left;
832 this->SetScrollRange(SB_HORZ,0,nMax,TRUE);
838 VOID CCommentView::DecisionHorzSize(){
840 HDWP hWindowPosInfo = BeginDeferWindowPos(2);
842 this->GetClientRect(&bkWindowRect);
843 m_header.DeferWindowPos(hWindowPosInfo,m_header.m_hWnd,0,0,::GetSystemMetrics(SM_CXFULLSCREEN),commentViewConstant::HEADER_HAIGHT,SWP_NOZORDER | SWP_NOMOVE);
844 m_commentListWindow.DeferWindowPos(hWindowPosInfo,m_header.m_hWnd,0,0,::GetSystemMetrics(SM_CXFULLSCREEN),bkWindowRect.bottom - commentViewConstant::HEADER_HAIGHT,SWP_NOZORDER | SWP_NOMOVE);
846 EndDeferWindowPos(hWindowPosInfo);
855 //
\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
856 ////////////////////////////////////////////////////////////////////
858 CCommentListWindow::CCommentListWindow(CCommentView &in_self):
862 CFontHandle font = ::AtlGetDefaultGuiFont();
864 font.GetLogFont(&logfont);
865 logfont.lfUnderline = TRUE;
867 linkFont.CreateFontIndirect(&logfont);
870 CCommentListWindow::~CCommentListWindow(){
873 VOID CCommentListWindow::OnSetProperty(){
875 if(IsWindow() == TRUE)this->SetRedraw(FALSE);
877 if(collLinePen.IsNull() == FALSE)collLinePen.DeleteObject();
878 if(normalSellLinePen.IsNull() == FALSE)normalSellLinePen.DeleteObject();
879 if(normalBkBrush.IsNull() == FALSE)normalBkBrush.DeleteObject();
880 if(selectSellLinePen.IsNull() ==FALSE)selectSellLinePen.DeleteObject();
881 if(selectBkBrush.IsNull() == FALSE)selectBkBrush.DeleteObject();
883 collLinePen.CreatePen(PS_SOLID,1,self.viewproperty.colLineColor);
884 normalSellLinePen.CreatePen(PS_SOLID,1,self.viewproperty.normalSellLineColor);
885 normalBkBrush.CreateSolidBrush(self.viewproperty.backColor);
886 selectSellLinePen.CreatePen(PS_SOLID,1,self.viewproperty.selectSellLineColor);
887 selectBkBrush.CreateSolidBrush(self.viewproperty.selectBackColor);
890 if(IsWindow() == TRUE)this->SetRedraw(TRUE);
894 VOID CCommentListWindow::OnPaint(HDC in_hdc){
896 this->self.refAuth.GetUserSession();
901 self.GetClientRect(&clientRect);
902 clientRect.bottom -= commentViewConstant::HEADER_HAIGHT;
904 this->GetWindowRect(&windowRect);
905 windowRect.right -= windowRect.left;
906 windowRect.bottom -= windowRect.top;
914 CMemoryDC mdc(pdc,windowRect);
915 mdc.SelectFont(AtlGetDefaultGuiFont());
918 CCommentList &commentList = self.commentlist;
920 BOOL selectFlag = FALSE;
921 CCommentList::iterator selectData;
922 RECT selectRect = {0};
926 if(commentList.Size() > 0){
928 listRect = windowRect;
929 listRect.right = self.GetColumnHolSizeSum();
931 CCommentList::iterator chatData = commentList.GetShortCut();
936 mdc.FillRect(&listRect,this->normalBkBrush);
938 CCommentList::iterator endData = commentList.end();
941 RECT headerRects[COMMENTVIEW_HEADERITEMSIZE];
942 RECT colLineRects[COMMENTVIEW_HEADERITEMSIZE];
943 RECT selectHeaderRects[COMMENTVIEW_HEADERITEMSIZE];
945 self.m_header.GetItemRect(CCommentView::NO,&headerRects[CCommentView::NO]);
946 self.m_header.GetItemRect(CCommentView::USERNAME,&headerRects[CCommentView::USERNAME]);
947 self.m_header.GetItemRect(CCommentView::COMMENT,&headerRects[CCommentView::COMMENT]);
948 self.m_header.GetItemRect(CCommentView::TIME,&headerRects[CCommentView::TIME]);
949 self.m_header.GetItemRect(CCommentView::INFO,&headerRects[CCommentView::INFO]);
951 memcpy(colLineRects,headerRects,sizeof(headerRects));
957 headerRects[CCommentView::NO].left += SELL_SPACE_LENGTH;
958 headerRects[CCommentView::USERNAME].left += SELL_SPACE_LENGTH;
959 headerRects[CCommentView::COMMENT].left += SELL_SPACE_LENGTH;
960 headerRects[CCommentView::TIME].left += SELL_SPACE_LENGTH;
961 headerRects[CCommentView::INFO].left += SELL_SPACE_LENGTH;
963 headerRects[CCommentView::NO].right -= SELL_SPACE_LENGTH;
964 headerRects[CCommentView::USERNAME].right -= SELL_SPACE_LENGTH;
965 headerRects[CCommentView::COMMENT].right -= SELL_SPACE_LENGTH;
966 headerRects[CCommentView::TIME].right -= SELL_SPACE_LENGTH;
967 headerRects[CCommentView::INFO].right -= SELL_SPACE_LENGTH;
969 headerRects[CCommentView::NO].top = SELL_SPACE_LENGTH;
970 headerRects[CCommentView::USERNAME].top = SELL_SPACE_LENGTH;
971 headerRects[CCommentView::COMMENT].top = SELL_SPACE_LENGTH;
972 headerRects[CCommentView::TIME].top = SELL_SPACE_LENGTH;
973 headerRects[CCommentView::INFO].top = SELL_SPACE_LENGTH;
975 headerRects[CCommentView::NO].bottom = SELL_SPACE_LENGTH;
976 headerRects[CCommentView::USERNAME].bottom = SELL_SPACE_LENGTH;
977 headerRects[CCommentView::COMMENT].bottom = SELL_SPACE_LENGTH;
978 headerRects[CCommentView::TIME].bottom = SELL_SPACE_LENGTH;
979 headerRects[CCommentView::INFO].bottom = SELL_SPACE_LENGTH;
981 INT_PTR listRectTop = listRect.top;
982 for(;chatData != endData && listRect.top < clientRect.bottom;++chatData){
983 CalcItemHeight(*chatData);
985 // dumpln(TEXT("height:%d"),chatData->viewData.height);
986 listRect.bottom += chatData->viewData.height;
988 headerRects[CCommentView::NO].top = listRect.top + SELL_SPACE_LENGTH;
989 headerRects[CCommentView::USERNAME].top = listRect.top + SELL_SPACE_LENGTH;
990 headerRects[CCommentView::COMMENT].top = listRect.top + SELL_SPACE_LENGTH;
991 headerRects[CCommentView::TIME].top = listRect.top + SELL_SPACE_LENGTH;
992 headerRects[CCommentView::INFO].top = listRect.top + SELL_SPACE_LENGTH;
994 headerRects[CCommentView::NO].bottom = listRect.bottom - SELL_SPACE_LENGTH;
995 headerRects[CCommentView::USERNAME].bottom = listRect.bottom - SELL_SPACE_LENGTH;
996 headerRects[CCommentView::COMMENT].bottom = listRect.bottom - SELL_SPACE_LENGTH;
997 headerRects[CCommentView::TIME].bottom = listRect.bottom - SELL_SPACE_LENGTH;
998 headerRects[CCommentView::INFO].bottom = listRect.bottom - SELL_SPACE_LENGTH;
1000 if(chatData->viewData.selectFlag == TRUE){
1002 selectData = chatData;
1003 selectRect = listRect;
1004 memcpy(selectHeaderRects,headerRects,sizeof(headerRects));
1010 this->DrawItem(mdc,listRect,headerRects,*chatData);
1014 listRect.top = listRect.bottom;
1017 viewSellHeight = listRect.bottom;
1021 if(selectFlag == TRUE){
1022 this->DrawItem(mdc,selectRect,selectHeaderRects,*selectData);
1025 //
\8d\80\96Ú
\82Ì
\8fc
\90ü
\82ð
\95`
\89æ
1026 mdc.SelectPen(collLinePen);
1027 mdc.MoveTo(colLineRects[CCommentView::NO].right,listRectTop);
1028 mdc.LineTo(colLineRects[CCommentView::NO].right,listRect.bottom);
1029 mdc.MoveTo(colLineRects[CCommentView::USERNAME].right,listRectTop);
1030 mdc.LineTo(colLineRects[CCommentView::USERNAME].right,listRect.bottom);
1031 mdc.MoveTo(colLineRects[CCommentView::COMMENT].right,listRectTop);
1032 mdc.LineTo(colLineRects[CCommentView::COMMENT].right,listRect.bottom);
1033 mdc.MoveTo(colLineRects[CCommentView::TIME].right,listRectTop);
1034 mdc.LineTo(colLineRects[CCommentView::TIME].right,listRect.bottom);
1035 mdc.MoveTo(colLineRects[CCommentView::INFO].right,listRectTop);
1036 mdc.LineTo(colLineRects[CCommentView::INFO].right,listRect.bottom);
1039 windowRect.left = listRect.right;
1040 mdc.FillRect(&windowRect,(HBRUSH)::GetStockObject(GRAY_BRUSH));
1054 LRESULT CCommentListWindow::OnSetCtrol(UINT uMsg,WPARAM wparam,LPARAM lparam){
1058 self.chatChildCtrlsList.ShowCntrls();
1065 VOID CCommentListWindow::OnSize(UINT wParam, _WTYPES_NS::CSize &windowSize){
1068 SCROLLINFO vScrollInfo = {0};
1069 vScrollInfo.fMask = SIF_ALL;
1072 self.GetScrollInfo(SB_VERT,&vScrollInfo);
1073 BOOL scrollFlag = (UINT)(vScrollInfo.nPage + vScrollInfo.nPos + 1) >= (UINT)vScrollInfo.nMax;
1074 vScrollInfo.nPage = CalcScrollPage(vScrollInfo.nMax);
1076 vScrollInfo.fMask = SIF_PAGE;
1077 self.SetScrollInfo(SB_VERT,&vScrollInfo);
1081 if(scrollFlag == TRUE){
1082 self.SendMessageW(WM_VSCROLL,MAKELONG(SB_BOTTOM,0),0);
1086 this->SendMessage(UM_COMMENTVIEW_SETCTRL,NULL,NULL);
1092 UINT_PTR CCommentListWindow::CalcScrollPage(UINT_PTR nMax){
1097 this->GetClientRect(&clientRect);
1099 SCROLLINFO vScrollInfo = {0};
1100 if(self.commentlist.empty() != TRUE){
1102 CCommentList::reverse_iterator rbegin = self.commentlist.rbegein();
1103 CCommentList::reverse_iterator rend = self.commentlist.rend();
1104 for(;rbegin != rend;++rbegin){
1105 CalcItemHeight(*rbegin);
1106 height += rbegin->viewData.height;
1108 if(height > clientRect.bottom)goto overclientrect;
1113 vScrollInfo.fMask = SIF_RANGE;
1114 self.GetScrollInfo(SB_VERT,&vScrollInfo);
1124 VOID CCommentListWindow::DrawItem(CDC &dc,const RECT &rc,const RECT *headerRect,CChatData &chatData){
1127 RECT noViewRect = headerRect[CCommentView::NO]; //
\83R
\83\81\94Ô
\95\
\8e¦
\97Ì
\88æ
1128 RECT userNameViewRect = headerRect[CCommentView::USERNAME]; //
\83\86\81[
\83U
\96¼
\95\
\8e¦
\97Ì
\88æ
1129 RECT chatViewRect = headerRect[CCommentView::COMMENT]; //
\83R
\83\81\83\93\83g
\95\
\8e¦
\97Ì
\88æ
1130 RECT timeViewRect = headerRect[CCommentView::TIME]; //
\8e\9e\8aÔ
\95\
\8e¦
\97Ì
\88æ
1131 RECT infoViewRect = headerRect[CCommentView::INFO]; //
\83R
\83\81\83\93\83g
\8fî
\95ñ
\95\
\8e¦
\97Ì
\88æ
1135 //
\83R
\83\81\83\93\83g
\8e\9e\8aÔ
\95\
\8e¦
\97p
\95¶
\8e\9a\97ñ
\8dì
\90¬
1137 time_t chatTime = (time_t)difftime(chatData.date,self.stream.GetStartTime());
1140 BOOL beforeStartFlag = chatTime < 0 ? TRUE : FALSE;
1141 TCHAR noString[sizeof(chatData.no) * 8];
1142 TCHAR dateString[LENGTH_16];
1143 if(chatData.no != 0)_stprintf(noString,TEXT("%u"),chatData.no);
1144 else _tcscpy(noString,TEXT(""));
1145 CNLiteString timeFormat;
1148 if(beforeStartFlag == TRUE){
1150 timeFormat = TEXT("-");
1151 chatTime = -chatTime;
1153 tm ct = *gmtime(&chatTime);
1154 if(ct.tm_hour != 0 ){
1156 timeFormat += TEXT("%H:%M:%S");
1160 timeFormat += TEXT("%M:%S");
1163 _tcsftime(dateString,ARRAY_LENGTH(dateString),timeFormat,&ct);
1166 COLORREF bkColor; //
\94w
\8ci
\90F
1167 CPen originSellLinePen; //
\98g
\90ü
\95`
\89æ
\97p
\83y
\83\93
1168 CBrush originBkBrush; //
\94w
\8ci
\95`
\89æ
\97p
\83u
\83\89\83V
1170 //
\91I
\91ð
\8fó
\91Ô
\82©
\83`
\83F
\83b
\83N
1171 if (chatData.viewData.selectFlag == TRUE)
1173 bkColor = self.viewproperty.selectBackColor;
1175 dc.SelectBrush(this->selectBkBrush);
1176 dc.SelectPen(this->selectSellLinePen);
1181 if(chatData.viewData.sellLineColor == CChatData::ViewData::INIT_COLOR){
1182 dc.SelectPen(this->normalSellLinePen);
1186 originSellLinePen.CreatePen(PS_SOLID,1,chatData.viewData.sellLineColor);
1187 dc.SelectPen(originSellLinePen);
1192 if(chatData.viewData.backColor != CChatData::ViewData::INIT_COLOR || chatData.listenerData->originBkFlag == TRUE){
1194 if(chatData.viewData.backColor != CChatData::ViewData::INIT_COLOR){
1195 bkColor = chatData.viewData.backColor;
1196 originBkBrush.CreateSolidBrush(chatData.viewData.backColor);
1198 }else if(chatData.listenerData->originBkFlag == TRUE){
1200 bkColor = chatData.listenerData->bkColor;
1201 originBkBrush.CreateSolidBrush(chatData.listenerData->bkColor);
1205 dc.SelectBrush(originBkBrush);
1208 bkColor = self.viewproperty.backColor;
1209 dc.SelectBrush(this->normalBkBrush);
1210 dc.SelectBrush(this->normalBkBrush);
1216 //
\94w
\8ci
\82Æ
\98g
\90ü
\82ð
\95`
\89æ
1219 dc.Rectangle(rc.left,rc.top - 1,rc.right ,rc.bottom + 1);
1220 dc.SetBkColor(bkColor);
1223 //
\95`
\89æ
\83T
\83C
\83Y
\82ð
\8cv
\8eZ
1229 dc.SelectFont(linkFont);
1230 dc.SetTextColor(self.viewproperty.linkStringColor);
1231 //
\83e
\83L
\83X
\83g
\95`
\89æ
1232 dc.DrawTextW(noString,_tcslen(noString),&noViewRect,DT_WORD_ELLIPSIS);
1233 dc.DrawTextW(chatData.listenerData->user_id,chatData.listenerData->user_id.Length(),&userNameViewRect,DT_WORD_ELLIPSIS);
1235 dc.SelectFont(::AtlGetDefaultGuiFont());
1236 dc.SetTextColor(chatData.viewData.stringColor == CChatData::ViewData::INIT_COLOR ? chatData.viewData.stringColor :self.viewproperty.baseStringColor);
1237 dc.DrawTextW(dateString,_tcslen(dateString),&timeViewRect,DT_WORD_ELLIPSIS);
1242 VOID CCommentListWindow::ResetViewSellHeight(){
1250 VOID CCommentListWindow::ShowCurSel(){
1252 auto end = self.commentlist.end();
1253 INT_PTR cursel = self.commentlist.GetCurSelNo();
1254 if(cursel == -1)goto end;
1256 SCROLLINFO vScrollInfo;
1257 vScrollInfo.cbSize = sizeof(vScrollInfo);
1258 vScrollInfo.fMask = SIF_ALL;
1259 self.GetScrollInfo(SB_VERT,&vScrollInfo);
1261 if(!(cursel >= vScrollInfo.nPos + static_cast<INT_PTR>(vScrollInfo.nPage) / 2 && cursel <= vScrollInfo.nPos + static_cast<INT_PTR>(vScrollInfo.nPage) / 2)){
1262 self.SetScrollPos(SB_VERT,cursel - (vScrollInfo.nPage / 2));
1263 self.commentlist.SetShortCut(self.GetScrollPos(SB_VERT));
1268 this->SendMessage(UM_COMMENTVIEW_SETCTRL,NULL,NULL);
1276 VOID CCommentListWindow::CalcItemHeight(CChatData &chatData){
1278 if(chatData.viewData.height == 0){
1280 self.m_header.GetItemRect(CCommentView::COMMENT,&drowSize);
1282 drowSize.bottom = 0;
1284 CChatReadEdit cedit(self);
1286 cedit.GeneralCreate(*this,ENM_REQUESTRESIZE,CALCEDIT_ID);
1288 cedit.SetWindowPos(NULL,0,0,drowSize.right - drowSize.left,drowSize.bottom - drowSize.top,SWP_NOZORDER | SWP_NOMOVE | SWP_NOREDRAW);
1289 cedit.SetWindowText(chatData);
1290 cedit.GetClientRect(&drowSize);
1291 cedit.DestroyWindow();
1292 drowSize.bottom += 12;
1293 if(drowSize.bottom - drowSize.top > 120)drowSize.bottom = drowSize.top + 120;
1294 chatData.viewData.height = drowSize.bottom - drowSize.top;
1302 LRESULT CCommentListWindow::OnCreate(LPCREATESTRUCT lpCreateStruct){
1304 addToMyListWindow.Create(m_hWnd, 0,_T("Shell.Explorer.2"),WS_CHILD | WS_VISIBLE, 0, IDC_NLITE_ADDMYLIST);
1309 CCommentList::iterator CCommentListWindow::CalcClickLine(INT_PTR height){
1311 INT_PTR heightSum = 0;
1313 CCommentList::iterator chatData = self.commentlist.GetShortCut();
1314 CCommentList::iterator end = self.commentlist.end();
1318 for(; chatData != end ;(++chatData)){
1319 CalcItemHeight(*chatData);
1320 heightSum += chatData->viewData.height;
1323 if(heightSum >= height)break;
1333 BOOL CCommentListWindow::IsOnNoOrUserName(UINT_PTR index,const POINT &point){
1337 self.m_header.GetItemRect(index,&rc);
1340 if((point.x >= rc.left && point.x <= rc.right) && (point.y < static_cast<INT_PTR>(viewSellHeight))){
1342 INT_PTR heightsum = 0;
1343 auto clickData = self.commentlist.GetShortCut();
1344 auto endData = self.commentlist.end();
1345 for(;clickData != endData;++clickData){
1347 heightsum += clickData->viewData.height;
1349 if(heightsum > point.y){
1351 CDC cdc = this->GetDC();
1353 rc.top = heightsum -= clickData->viewData.height;
1354 RECT calcRect = {0};
1355 cdc.SelectFont(linkFont);
1358 if(index == CCommentView::USERNAME){
1359 LPCTSTR viewStr = clickData->listenerData->userName.Length() == 0 ? clickData->listenerData->user_id : clickData->listenerData->userName;
1360 cdc.DrawTextW(viewStr ,_tcslen(viewStr),&calcRect,DT_CALCRECT);
1362 } else if(index == CCommentView::NO){
1363 TCHAR viewStr[sizeof(UINT_PTR) * 8];
1364 _stprintf(viewStr,TEXT("%d"),clickData->no);
1365 cdc.DrawTextW(viewStr,_tcslen(viewStr),&calcRect,DT_CALCRECT);
1368 rc.bottom = rc.top + calcRect.bottom - calcRect.top;
1369 rc.right = rc.right > rc.left + calcRect.right - calcRect.left ? rc.left + calcRect.right - calcRect.left : rc.right;
1370 rslt = (point.y >= rc.top && point.y <= rc.bottom && point.x >= rc.left && point.x <= rc.right);
1384 VOID CCommentListWindow::OnDestroy(){
1386 this->addToMyListWindow.DestroyWindow();
1390 VOID CCommentListWindow::OnLButtonDown(UINT wParam, _WTYPES_NS::CPoint &point){
1396 if(point.x > (INT_PTR)self.GetColumnHolSizeSum()) goto end;
1399 if(self.commentlist.empty() == TRUE)goto end;
1401 self.commentlist.SetCurSel(CalcClickLine(point.y));
1409 this->SendMessage(UM_COMMENTVIEW_SETCTRL,NULL,NULL);
1415 VOID CCommentListWindow::OnLButtonDblClk(UINT wParam, _WTYPES_NS::CPoint &point){
1419 if(!(point.x > (INT_PTR)self.GetColumnHolSizeSum() || self.commentlist.empty() == TRUE)){
1421 auto end = self.commentlist.end();
1422 auto lineIte = CalcClickLine(point.y);
1423 if( lineIte == end)goto endlabel;
1427 if(lineIte->listenerData->originBkFlag == FALSE){
1428 CListenerColorCollector colorCollector;
1429 listenerList.BkColorCollect(colorCollector);
1434 srand((unsigned int)time(NULL));
1440 bkColor = PALETTERGB(red,green,blue);
1442 }while(colorCollector.Find(bkColor));
1444 lineIte->listenerData->originBkFlag = TRUE;
1445 lineIte->listenerData->SetBkColor(bkColor);
1449 lineIte->listenerData->originBkFlag = FALSE;
1460 this->Invalidate(TRUE);
1462 this->SendMessage(UM_COMMENTVIEW_SETCTRL,NULL,NULL);
1466 LRESULT CCommentListWindow::OnEraseBkGnd(HDC lparam){
1471 VOID CCommentListWindow::OnKeyDown(TCHAR vKey,UINT loLParam,UINT hiLParam){
1494 auto cursel = self.commentlist.GetCurSel();
1495 if((dy < 0 && cursel == self.commentlist.begin()) || dy >= static_cast<INT_PTR>(self.commentlist.Size()))goto end;
1498 std::advance(cursel,dy);
1499 self.commentlist.SetCurSel(cursel);
1508 LRESULT CCommentListWindow::OnSetCursor(HWND wparam,UINT loLparam,UINT hiLparam){
1511 POINT mousePoint = {0};
1513 GetCursorPos(&mousePoint);
1514 ::ScreenToClient(*this,&mousePoint);
1516 if(/*static_cast<INT>(loLparam) == 1 &&*/( IsOnNoOrUserName(CCommentView::NO,mousePoint) || IsOnNoOrUserName(CCommentView::USERNAME,mousePoint))){
1519 ::SetCursor(::LoadCursorW(NULL,IDC_HAND));
1534 LRESULT CCommentListWindow::OnMouseWheel(UINT loWparam,SHORT hiWparam,CPoint &point){
1537 self.SendMessageW(WM_VSCROLL,MAKELONG(hiWparam < 0 ? SB_PAGEDOWN : SB_PAGEUP ,0),0);
1544 LRESULT CCommentListWindow::OnChatControlNortify(LPNMHDR lParam){
1548 switch(lParam->code){
1552 ENLINK *lpenlk = (ENLINK *)lParam;
1553 if (lpenlk->msg == WM_LBUTTONDOWN) {
1554 CRichEditCtrl chatReadEdit = lpenlk->nmhdr.hwndFrom;
1555 chatReadEdit.SetSel(lpenlk->chrg);
1557 chatReadEdit.GetSelText(selTextBuf);
1558 if(regex_match((LPCTSTR)selTextBuf,nliteregex::URL) == TRUE){
1560 OpenURL(*this,self.generalProperty,selTextBuf,SW_SHOWNORMAL);
1563 } else if(regex_match((LPCTSTR)selTextBuf,nliteregex::VIDEOID) == TRUE){
1567 addToMyListWindow.ShowAddWindow(self.refAuth,selTextBuf);
1569 ::SetFocus(lParam->hwndFrom);
1572 } else if( regex_match((LPCTSTR)selTextBuf,nliteregex::LIVEID) == TRUE){
1574 selTextBuf.Insert(0,LIVEURL_PART);
1575 OpenURL(*this,self.generalProperty,selTextBuf,SW_SHOWNORMAL);
1585 auto pmf = (MSGFILTER *)lParam;
1586 if (pmf->msg == WM_LBUTTONDOWN || pmf->msg== WM_LBUTTONDBLCLK || pmf->msg == WM_MOUSEWHEEL){
1589 ::GetWindowRect(pmf->nmhdr.hwndFrom,&windowrect);
1590 _WTYPES_NS::CPoint point(windowrect.left + LOWORD(pmf->lParam),windowrect.top + HIWORD(pmf->lParam));
1591 ::ScreenToClient(*this,&point);
1595 case WM_LBUTTONDOWN:
1596 OnLButtonDown(pmf->wParam,point);
1599 case WM_LBUTTONDBLCLK:
1600 OnLButtonDblClk(pmf->wParam,point);
1604 OnMouseWheel(LOWORD(pmf->wParam),HIWORD(pmf->wParam),point);
1631 LRESULT CCommentListWindow::OnCalcSellSize(LPNMHDR lParam){
1633 auto pReqResize = reinterpret_cast <REQRESIZE *>(lParam);
1634 ::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);