00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "stdafx.h"
00026 #include "mplayerc.h"
00027 #include "mainfrm.h"
00028 #include "PlayerSubresyncBar.h"
00029
00030
00031
00032 IMPLEMENT_DYNAMIC(CPlayerSubresyncBar, CSizingControlBarG)
00033 CPlayerSubresyncBar::CPlayerSubresyncBar()
00034 {
00035 m_rt = 0;
00036 m_fUnlink = false;
00037 m_lastSegment = -1;
00038 }
00039
00040 CPlayerSubresyncBar::~CPlayerSubresyncBar()
00041 {
00042 }
00043
00044 BOOL CPlayerSubresyncBar::Create(CWnd* pParentWnd, CCritSec* pSubLock)
00045 {
00046 if(!CSizingControlBarG::Create(_T("Subresync"), pParentWnd, 50))
00047 return FALSE;
00048
00049 m_pSubLock = pSubLock;
00050
00051 m_list.CreateEx(
00052 WS_EX_DLGMODALFRAME|WS_EX_CLIENTEDGE,
00053 WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_TABSTOP|LVS_REPORT|LVS_AUTOARRANGE|LVS_NOSORTHEADER,
00054 CRect(0,0,100,100), this, IDC_SUBRESYNCLIST);
00055
00056 m_list.SetExtendedStyle(m_list.GetExtendedStyle()|LVS_EX_FULLROWSELECT|LVS_EX_DOUBLEBUFFER);
00057
00058 return TRUE;
00059 }
00060
00061 BOOL CPlayerSubresyncBar::PreCreateWindow(CREATESTRUCT& cs)
00062 {
00063 if(!CSizingControlBarG::PreCreateWindow(cs))
00064 return FALSE;
00065
00066 return TRUE;
00067 }
00068
00069 BOOL CPlayerSubresyncBar::PreTranslateMessage(MSG* pMsg)
00070 {
00071 if(IsWindow(pMsg->hwnd) && IsVisible() && pMsg->message >= WM_KEYFIRST && pMsg->message <= WM_KEYLAST)
00072 {
00073 if(IsDialogMessage(pMsg))
00074 return TRUE;
00075 }
00076
00077 return CSizingControlBarG::PreTranslateMessage(pMsg);
00078 }
00079
00080 void CPlayerSubresyncBar::SetTime(__int64 rt)
00081 {
00082 m_rt = rt;
00083
00084 int curSegment;
00085
00086 if(!m_sts.SearchSubs((int)(rt/10000), 25, &curSegment))
00087 {
00088 curSegment = -1;
00089 }
00090
00091 if(m_lastSegment != curSegment) m_list.Invalidate();
00092 m_lastSegment = curSegment;
00093 }
00094
00095 void CPlayerSubresyncBar::SetSubtitle(ISubStream* pSubStream, double fps)
00096 {
00097 m_pSubStream = pSubStream;
00098
00099 m_mode = NONE;
00100 m_lastSegment = -1;
00101 m_sts.Empty();
00102
00103 ResetSubtitle();
00104
00105 if(!m_pSubStream) return;
00106
00107 CLSID clsid;
00108 m_pSubStream->GetClassID(&clsid);
00109
00110 if(clsid == __uuidof(CVobSubFile))
00111 {
00112 CVobSubFile* pVSF = (CVobSubFile*)(ISubStream*)m_pSubStream;
00113
00114 m_mode = VOBSUB;
00115
00116 CArray<CVobSubFile::SubPos>& sp = pVSF->m_langs[pVSF->m_iLang].subpos;
00117
00118 for(int i = 0, j = sp.GetSize(); i < j; i++)
00119 {
00120 CString str;
00121 str.Format(_T("%d,%d,%d,%d"), sp[i].vobid, sp[i].cellid, sp[i].fForced, i);
00122 m_sts.Add(TToW(str), false, (int)sp[i].start, (int)sp[i].stop);
00123 }
00124
00125 m_sts.CreateDefaultStyle(DEFAULT_CHARSET);
00126
00127 pVSF->m_fOnlyShowForcedSubs = false;
00128
00129 for(int i = 0, j = m_list.GetHeaderCtrl()->GetItemCount(); i < j; i++) m_list.DeleteColumn(0);
00130 m_list.InsertColumn(COL_START, _T("Time"), LVCFMT_LEFT, 80);
00131 m_list.InsertColumn(COL_END, _T("End"), LVCFMT_LEFT, 80);
00132 m_list.InsertColumn(COL_PREVSTART, _T("Preview"), LVCFMT_LEFT, 80);
00133 m_list.InsertColumn(COL_PREVEND, _T("End"), LVCFMT_LEFT, 80);
00134 m_list.InsertColumn(COL_VOBID, _T("Vob ID"), LVCFMT_CENTER, 60);
00135 m_list.InsertColumn(COL_CELLID, _T("Cell ID"), LVCFMT_CENTER, 60);
00136 m_list.InsertColumn(COL_FORCED, _T("Forced"), LVCFMT_CENTER, 60);
00137 }
00138 else if(clsid == __uuidof(CRenderedTextSubtitle))
00139 {
00140 CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)m_pSubStream;
00141
00142 m_mode = TEXTSUB;
00143
00144 m_sts.Copy(*pRTS);
00145 m_sts.ConvertToTimeBased(fps);
00146 m_sts.Sort(true);
00148 #ifndef UNICODE
00149 if(!m_sts.IsEntryUnicode(0))
00150 {
00151 CFont* f = m_list.GetFont();
00152 LOGFONT lf;
00153 f->GetLogFont(&lf);
00154 lf.lfCharSet = m_sts.GetCharSet(0);
00155 m_font.DeleteObject();
00156 m_font.CreateFontIndirect(&lf);
00157 m_list.SetFont(&m_font);
00158 }
00159 #endif
00160 for(int i = 0, j = m_list.GetHeaderCtrl()->GetItemCount(); i < j; i++) m_list.DeleteColumn(0);
00161 m_list.InsertColumn(COL_START, _T("Time"), LVCFMT_LEFT, 90);
00162 m_list.InsertColumn(COL_END, _T("End"), LVCFMT_LEFT, 4);
00163 m_list.InsertColumn(COL_PREVSTART, _T("Preview"), LVCFMT_LEFT, 80);
00164 m_list.InsertColumn(COL_PREVEND, _T("End"), LVCFMT_LEFT, 4);
00165 m_list.InsertColumn(COL_TEXT, _T("Text"), LVCFMT_LEFT, 275);
00166 m_list.InsertColumn(COL_STYLE, _T("Style"), LVCFMT_LEFT, 80);
00167 m_list.InsertColumn(COL_FONT, _T("Font"), LVCFMT_LEFT, 60);
00168 m_list.InsertColumn(COL_CHARSET, _T("CharSet"), LVCFMT_CENTER, 20);
00169 m_list.InsertColumn(COL_UNICODE, _T("Unicode"), LVCFMT_CENTER, 40);
00170 m_list.InsertColumn(COL_LAYER, _T("Layer"), LVCFMT_CENTER, 50);
00171 m_list.InsertColumn(COL_ACTOR, _T("Actor"), LVCFMT_LEFT, 80);
00172 m_list.InsertColumn(COL_EFFECT, _T("Effect"), LVCFMT_LEFT, 80);
00173 }
00174
00175 m_subtimes.SetSize(m_sts.GetSize());
00176
00177 for(int i = 0, j = m_sts.GetSize(); i < j; i++)
00178 {
00179 m_subtimes[i].orgstart = m_sts[i].start;
00180 m_subtimes[i].orgend = m_sts[i].end;
00181 }
00182
00183 ResetSubtitle();
00184 }
00185
00186 void CPlayerSubresyncBar::ResetSubtitle()
00187 {
00188 m_list.DeleteAllItems();
00189
00190 if(m_mode == VOBSUB || m_mode == TEXTSUB)
00191 {
00192 TCHAR buff[32];
00193
00194 int prevstart = INT_MIN;
00195
00196 for(int i = 0, j = m_sts.GetSize(); i < j; i++)
00197 {
00198 m_subtimes[i].newstart = m_subtimes[i].orgstart;
00199 m_subtimes[i].newend = m_subtimes[i].orgend;
00200
00201 FormatTime(i, buff, 0, false);
00202 m_list.InsertItem(i, buff, COL_START);
00203 FormatTime(i, buff, 0, true);
00204 m_list.SetItemText(i, COL_END, buff);
00205
00206 if(prevstart > m_subtimes[i].orgstart) m_list.SetItemData(i, TSEP);
00207 prevstart = m_subtimes[i].orgstart;
00208
00209 SetCheck(i, false, false);
00210 }
00211
00212 UpdatePreview();
00213
00214 m_list.SetColumnWidth(COL_START, LVSCW_AUTOSIZE);
00215 m_list.SetColumnWidth(COL_PREVSTART, LVSCW_AUTOSIZE);
00216 }
00217
00218 UpdateStrings();
00219 }
00220
00221 void CPlayerSubresyncBar::SaveSubtitle()
00222 {
00223 CMainFrame* pFrame = ((CMainFrame*)AfxGetMainWnd());
00224 if(!pFrame) return;
00225
00226 CLSID clsid;
00227 m_pSubStream->GetClassID(&clsid);
00228
00229 if(clsid == __uuidof(CVobSubFile) && m_mode == VOBSUB)
00230 {
00231 CVobSubFile* pVSF = (CVobSubFile*)(ISubStream*)m_pSubStream;
00232
00233 CAutoLock cAutoLock(m_pSubLock);
00234
00235 CArray<CVobSubFile::SubPos>& sp = pVSF->m_langs[pVSF->m_iLang].subpos;
00236
00237 for(int i = 0, j = sp.GetSize(); i < j; i++)
00238 {
00239 sp[i].fValid = false;
00240 }
00241
00242 for(int i = 0, j = m_sts.GetSize(); i < j; i++)
00243 {
00244 int vobid, cellid, forced, spnum, c;
00245 if(_stscanf(m_sts.GetStr(i), _T("%d%c%d%c%d%c%d"), &vobid, &c, &cellid, &c, &forced, &c, &spnum) != 7) continue;
00246 sp[spnum].start = m_sts[i].start;
00247 sp[spnum].stop = m_sts[i].end;
00248 sp[spnum].fValid = true;
00249 }
00250 }
00251 else if(clsid == __uuidof(CRenderedTextSubtitle) && m_mode == TEXTSUB)
00252 {
00253 CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)m_pSubStream;
00254
00255 CAutoLock cAutoLock(m_pSubLock);
00256
00257 pRTS->Copy(m_sts);
00258 }
00259 else
00260 {
00261 return;
00262 }
00263
00264 pFrame->InvalidateSubtitle();
00265 }
00266
00267 void CPlayerSubresyncBar::UpdatePreview()
00268 {
00269 if(m_mode == VOBSUB || m_mode == TEXTSUB)
00270 {
00271 if(0)
00272 {
00273 for(int i = 0, j = m_sts.GetSize(); i < j; i++)
00274 {
00275 bool fStartMod, fEndMod, fStartAdj, fEndAdj;
00276 GetCheck(i, fStartMod, fEndMod, fStartAdj, fEndAdj);
00277 m_sts[i].start = (fStartMod||fStartAdj) ? m_subtimes[i].newstart : m_subtimes[i].orgstart;
00278 m_sts[i].end = (fEndMod||fEndAdj) ? m_subtimes[i].newend : m_subtimes[i].orgend;
00279 }
00280 }
00281 else
00282 {
00283 CArray <int, int> schk;
00284
00285 for(int i = 0, j = m_sts.GetSize(); i < j;)
00286 {
00287 schk.RemoveAll();
00288
00289 int start = i, end;
00290
00291 for(end = i; end < j; end++)
00292 {
00293 int data = (int)m_list.GetItemData(end);
00294 if((data&TSEP) && end > i) break;
00295 if(data&(TSMOD|TSADJ))
00296 schk.Add(end);
00297 }
00298
00299 if(schk.GetSize() == 0)
00300 {
00301 for(; start < end; start++)
00302 {
00303 m_sts[start].start = m_subtimes[start].orgstart;
00304 m_sts[start].end = m_subtimes[start].orgend;
00305 }
00306 }
00307 else if(schk.GetSize() == 1)
00308 {
00309 int k = schk[0];
00310 int dt = m_subtimes[k].newstart - m_subtimes[k].orgstart;
00311 for(; start < end; start++)
00312 {
00313 m_sts[start].start = m_subtimes[start].orgstart + dt;
00314 m_sts[start].end = (m_list.GetItemData(start)&TEMOD)
00315 ? m_subtimes[start].newend
00316 : (m_subtimes[start].orgend + dt);
00317 }
00318 }
00319 else if(schk.GetSize() >= 2)
00320 {
00321 int i0, i1, ti0, ds;
00322 double m = 0;
00323
00324 for(int k = 0, l = schk.GetSize()-1; k < l; k++)
00325 {
00326 i0 = schk[k];
00327 i1 = schk[k+1];
00328
00329 ti0 = m_subtimes[i0].orgstart;
00330 ds = m_subtimes[i1].orgstart - ti0;
00331
00332 if(ds == 0)
00333 {
00334 for(; start < i1; start++)
00335 {
00336 m_sts[start].start = ti0;
00337 m_sts[start].end = (m_list.GetItemData(start)&TEMOD)
00338 ? m_subtimes[start].newend
00339 : (ti0 + m_subtimes[start].orgend - m_subtimes[start].orgstart);
00340 }
00341 }
00342 else
00343 {
00344 m = double(m_subtimes[i1].newstart - m_subtimes[i0].newstart) / ds;
00345
00346 for(; start < i1; start++)
00347 {
00348 m_sts[start].start = int((m_subtimes[start].orgstart - ti0)*m + m_subtimes[i0].newstart);
00349 m_sts[start].end = (m_list.GetItemData(start)&TEMOD)
00350 ? m_subtimes[start].newend
00351 : m_mode == VOBSUB
00352 ? (m_sts[start].start + m_subtimes[start].orgend - m_subtimes[start].orgstart)
00353 : (m_sts[start].start + int((m_subtimes[start].orgend - m_subtimes[start].orgstart)*m));
00354 }
00355 }
00356 }
00357
00358 if(ds == 0)
00359 {
00360 for(; start < end; start++)
00361 {
00362 m_sts[start].start = ti0;
00363 m_sts[start].end = (m_list.GetItemData(start)&TEMOD)
00364 ? m_subtimes[start].newend
00365 : (ti0 + (m_subtimes[start].orgend - m_subtimes[start].orgstart));
00366 }
00367 }
00368 else
00369 {
00370 for(; start < end; start++)
00371 {
00372 m_sts[start].start = int((m_subtimes[start].orgstart - ti0)*m + m_subtimes[i0].newstart);
00373 m_sts[start].end = (m_list.GetItemData(start)&TEMOD)
00374 ? m_subtimes[start].newend
00375 : m_mode == VOBSUB
00376 ? (m_sts[start].start + m_subtimes[start].orgend - m_subtimes[start].orgstart)
00377 : (m_sts[start].start + int((m_subtimes[start].orgend - m_subtimes[start].orgstart)*m));
00378 }
00379 }
00380 }
00381
00382 i = end;
00383 }
00384 }
00385
00386 m_sts.CreateSegments();
00387
00388 for(int i = 0, j = m_sts.GetSize(); i < j; i++)
00389 {
00390 TCHAR buff[32];
00391 FormatTime(i, buff, 2, false);
00392 m_list.SetItemText(i, COL_PREVSTART, buff);
00393 FormatTime(i, buff, 2, true);
00394 m_list.SetItemText(i, COL_PREVEND, buff);
00395 }
00396
00397 if(IsWindowVisible())
00398 {
00399 SaveSubtitle();
00400 }
00401 }
00402 }
00403
00404 void CPlayerSubresyncBar::UpdateStrings()
00405 {
00406 CString str;
00407
00408 if(m_mode == TEXTSUB)
00409 {
00410 for(int i = 0, j = m_sts.GetSize(); i < j; i++)
00411 {
00412 STSStyle stss;
00413 m_sts.GetStyle(i, stss);
00414
00415 m_list.SetItemText(i, COL_TEXT, m_sts.GetStr(i, true));
00416 m_list.SetItemText(i, COL_STYLE, m_sts[i].style);
00417 m_list.SetItemText(i, COL_FONT, stss.fontName);
00418 str.Format(_T("%d"), stss.charSet);
00419 m_list.SetItemText(i, COL_CHARSET, str);
00420 m_list.SetItemText(i, COL_UNICODE, m_sts.IsEntryUnicode(i) ? _T("yes") : _T("no"));
00421 str.Format(_T("%d"), m_sts[i].layer);
00422 m_list.SetItemText(i, COL_LAYER, str);
00423 m_list.SetItemText(i, COL_ACTOR, m_sts[i].actor);
00424 m_list.SetItemText(i, COL_EFFECT, m_sts[i].effect);
00425 }
00426 }
00427 else if(m_mode == VOBSUB)
00428 {
00429 for(int i = 0, j = m_sts.GetSize(); i < j; i++)
00430 {
00431 int vobid, cellid, forced, c;
00432 if(_stscanf(m_sts.GetStr(i), _T("%d%c%d%c%d"), &vobid, &c, &cellid, &c, &forced) != 5) continue;
00433 if(vobid < 0) str = _T("-");
00434 else str.Format(_T("%d"), vobid);
00435 m_list.SetItemText(i, COL_VOBID, str);
00436 if(cellid < 0) str = _T("-");
00437 else str.Format(_T("%d"), cellid);
00438 m_list.SetItemText(i, COL_CELLID, str);
00439 str = forced?_T("Yes"):_T("");
00440 m_list.SetItemText(i, COL_FORCED, str);
00441 }
00442 }
00443 }
00444
00445 void CPlayerSubresyncBar::GetCheck(int iItem, bool& fStartMod, bool& fEndMod, bool& fStartAdj, bool& fEndAdj)
00446 {
00447 if(0 <= iItem && iItem < m_sts.GetSize())
00448 {
00449 int nCheck = (int)m_list.GetItemData(iItem);
00450 fStartMod = !!(nCheck&TSMOD);
00451 fEndMod = !!(nCheck&TEMOD);
00452 fStartAdj = !!(nCheck&TSADJ);
00453 fEndAdj = !!(nCheck&TEADJ);
00454 }
00455 }
00456
00457 void CPlayerSubresyncBar::SetCheck(int iItem, bool fStart, bool fEnd)
00458 {
00459 if(0 <= iItem && iItem < m_sts.GetSize())
00460 {
00461 SubTime& st = m_subtimes[iItem];
00462
00463 int nCheck = (int)m_list.GetItemData(iItem) & TSEP;
00464
00465 if(fStart) nCheck |= TSMOD;
00466 else if(abs(st.orgstart-st.newstart)) nCheck |= TSADJ;
00467 if(fEnd) nCheck |= TEMOD;
00468 else if(abs(st.orgend-st.newend)) nCheck |= TEADJ;
00469
00470 m_list.SetItemData(iItem, (DWORD)nCheck);
00471
00472 TCHAR buff[32];
00473 FormatTime(iItem, buff, fStart, false);
00474 m_list.SetItemText(iItem, COL_START, buff);
00475 FormatTime(iItem, buff, fEnd, true);
00476 m_list.SetItemText(iItem, COL_END, buff);
00477 }
00478 }
00479
00480 bool CPlayerSubresyncBar::ModStart(int iItem, int t, bool fReset)
00481 {
00482 bool fRet = false;
00483
00484 bool fStartMod, fEndMod, fStartAdj, fEndAdj;
00485 GetCheck(iItem, fStartMod, fEndMod, fStartAdj, fEndAdj);
00486
00487 SubTime& st = m_subtimes[iItem];
00488
00489
00490 {
00491 fRet = (st.newstart != t);
00492
00493 st.newstart = t;
00494 if(!fEndMod) st.newend = st.newstart + (st.orgend - st.orgstart);
00495 else if(fReset) st.newstart = st.newend - (st.orgend - st.orgstart);
00496
00497 SetCheck(iItem, !fReset, fEndMod);
00498 }
00499
00500 return(fRet);
00501 }
00502
00503 bool CPlayerSubresyncBar::ModEnd(int iItem, int t, bool fReset)
00504 {
00505 bool fRet = false;
00506
00507 bool fStartMod, fEndMod, fStartAdj, fEndAdj;
00508 GetCheck(iItem, fStartMod, fEndMod, fStartAdj, fEndAdj);
00509
00510 SubTime& st = m_subtimes[iItem];
00511
00512
00513 {
00514 fRet = (st.newend != t);
00515
00516 st.newend = t;
00517 if(!fStartMod) st.newstart = st.newend - (st.orgend - st.orgstart);
00518 else if(fReset) st.newend = st.newstart + (st.orgend - st.orgstart);
00519
00520 SetCheck(iItem, fStartMod, !fReset);
00521 }
00522
00523 return(fRet);
00524 }
00525
00526 void CPlayerSubresyncBar::FormatTime(int iItem, TCHAR* buff, int time, bool fEnd)
00527 {
00528 int t = !fEnd
00529 ?(time == 2 ? m_sts[iItem].start
00530 : time == 1 ? m_subtimes[iItem].newstart
00531 : m_subtimes[iItem].orgstart)
00532 : (time == 2 ? m_sts[iItem].end
00533 : time == 1 ? m_subtimes[iItem].newend
00534 : m_subtimes[iItem].orgend);
00535
00536 _stprintf(buff, t >= 0
00537 ? _T("%02d:%02d:%02d.%03d")
00538 : _T("-%02d:%02d:%02d.%03d"),
00539 abs(t)/60/60/1000,
00540 (abs(t)/60/1000)%60,
00541 (abs(t)/1000)%60,
00542 abs(t)%1000);
00543 }
00544
00545
00546 BEGIN_MESSAGE_MAP(CPlayerSubresyncBar, CSizingControlBarG)
00547 ON_WM_SIZE()
00548 ON_NOTIFY(LVN_BEGINLABELEDIT, IDC_SUBRESYNCLIST, OnBeginlabeleditList)
00549 ON_NOTIFY(LVN_DOLABELEDIT, IDC_SUBRESYNCLIST, OnDolabeleditList)
00550 ON_NOTIFY(LVN_ENDLABELEDIT, IDC_SUBRESYNCLIST, OnEndlabeleditList)
00551 ON_NOTIFY(NM_RCLICK, IDC_SUBRESYNCLIST, OnRclickList)
00552 ON_NOTIFY(NM_DBLCLK, IDC_SUBRESYNCLIST, OnNMDblclkList)
00553 ON_NOTIFY(LVN_KEYDOWN, IDC_SUBRESYNCLIST, OnLvnKeydownList)
00554 ON_NOTIFY(NM_CUSTOMDRAW, IDC_SUBRESYNCLIST, OnCustomdrawList)
00555 END_MESSAGE_MAP()
00556
00557
00558
00559
00560 void CPlayerSubresyncBar::OnSize(UINT nType, int cx, int cy)
00561 {
00562 CSizingControlBarG::OnSize(nType, cx, cy);
00563
00564 if(::IsWindow(m_list.m_hWnd))
00565 {
00566 CRect r;
00567 GetClientRect(r);
00568 r.DeflateRect(2, 2);
00569 m_list.MoveWindow(r);
00570 }
00571 }
00572
00573 static bool ParseTime(CString str, int& ret, bool fWarn = true)
00574 {
00575 int sign = 1, h, m, s, ms;
00576 TCHAR c;
00577
00578 str.Trim();
00579 if(str.GetLength() > 0 && str[0] == '-') sign = -1;
00580
00581 int n = _stscanf(str, _T("%d%c%d%c%d%c%d"), &h, &c, &m, &c, &s, &c, &ms);
00582
00583 h = abs(h);
00584
00585 if(n == 7
00586 && 0 <= h && h < 24
00587 && 0 <= m && m < 60
00588 && 0 <= s && s < 60
00589 && 0 <= ms && ms < 1000)
00590 {
00591 ret = sign*(h*60*60*1000+m*60*1000+s*1000+ms);
00592 return(true);
00593 }
00594
00595 if(fWarn) AfxMessageBox(_T("The correct time format is [-]hh:mm:ss.ms\n(e.g. 01:23:45.678)"));
00596 return(false);
00597 }
00598
00599 void CPlayerSubresyncBar::OnBeginlabeleditList(NMHDR* pNMHDR, LRESULT* pResult)
00600 {
00601 LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
00602 LV_ITEM* pItem = &pDispInfo->item;
00603
00604 *pResult = FALSE;
00605
00606 if(pItem->iItem >= 0)
00607 {
00608 if((pItem->iSubItem == COL_START || pItem->iSubItem == COL_END || pItem->iSubItem == COL_TEXT
00609 || pItem->iSubItem == COL_STYLE || pItem->iSubItem == COL_LAYER
00610 || pItem->iSubItem == COL_ACTOR || pItem->iSubItem == COL_EFFECT)
00611 && m_mode == TEXTSUB)
00612 {
00613 *pResult = TRUE;
00614 }
00615 else if((pItem->iSubItem == COL_START)
00616 && m_mode == VOBSUB)
00617 {
00618 *pResult = TRUE;
00619 }
00620 }
00621 }
00622
00623 void CPlayerSubresyncBar::OnDolabeleditList(NMHDR* pNMHDR, LRESULT* pResult)
00624 {
00625 LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
00626 LV_ITEM* pItem = &pDispInfo->item;
00627
00628 *pResult = FALSE;
00629
00630 if(pItem->iItem >= 0)
00631 {
00632 if((pItem->iSubItem == COL_START || pItem->iSubItem == COL_END || pItem->iSubItem == COL_TEXT
00633 || pItem->iSubItem == COL_STYLE || pItem->iSubItem == COL_LAYER
00634 || pItem->iSubItem == COL_ACTOR || pItem->iSubItem == COL_EFFECT)
00635 && m_mode == TEXTSUB)
00636 {
00637 m_list.ShowInPlaceEdit(pItem->iItem, pItem->iSubItem);
00638 *pResult = TRUE;
00639 }
00640 else if((pItem->iSubItem == COL_START)
00641 && m_mode == VOBSUB)
00642 {
00643 m_list.ShowInPlaceEdit(pItem->iItem, pItem->iSubItem);
00644 *pResult = TRUE;
00645 }
00646 }
00647 }
00648
00649 void CPlayerSubresyncBar::OnEndlabeleditList(NMHDR* pNMHDR, LRESULT* pResult)
00650 {
00651 LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
00652 LV_ITEM* pItem = &pDispInfo->item;
00653
00654 *pResult = FALSE;
00655
00656 if(!m_list.m_fInPlaceDirty)
00657 return;
00658
00659 bool fNeedsUpdate = false;
00660
00661 if(pItem->iItem >= 0 && pItem->pszText && (m_mode == VOBSUB || m_mode == TEXTSUB))
00662 {
00663 if(pItem->iSubItem == COL_START)
00664 {
00665 int t;
00666 if(ParseTime(pItem->pszText, t))
00667 {
00668 fNeedsUpdate = ModStart(pItem->iItem, t);
00669
00670 *pResult = TRUE;
00671 }
00672 }
00673 else if(pItem->iSubItem == COL_END && m_mode == TEXTSUB)
00674 {
00675 int t;
00676 if(ParseTime(pItem->pszText, t))
00677 {
00678 fNeedsUpdate = ModEnd(pItem->iItem, t);
00679
00680 *pResult = TRUE;
00681 }
00682 }
00683 else if(pItem->iSubItem == COL_TEXT && m_mode == TEXTSUB)
00684 {
00685 CString str = m_sts.GetStr(pItem->iItem, true);
00686
00687 if(str != pItem->pszText)
00688 {
00689 fNeedsUpdate = true;
00690 m_sts.SetStr(pItem->iItem, CString(pItem->pszText), true);
00691 m_list.SetItemText(pItem->iItem, pItem->iSubItem, m_sts.GetStr(pItem->iItem, true));
00692 }
00693 }
00694 else if(pItem->iSubItem == COL_STYLE && m_mode == TEXTSUB)
00695 {
00696 CString str(pItem->pszText);
00697 str.Trim();
00698
00699 if(!str.IsEmpty() && m_sts[pItem->iItem].style != str)
00700 {
00701 fNeedsUpdate = true;
00702
00703 void* val;
00704 if(!m_sts.m_styles.Lookup(str, val))
00705 m_sts.AddStyle(str, new STSStyle());
00706
00707 m_sts[pItem->iItem].style = str;
00708
00709 m_list.SetItemText(pItem->iItem, pItem->iSubItem, pItem->pszText);
00710 }
00711 }
00712 else if(pItem->iSubItem == COL_LAYER && m_mode == TEXTSUB)
00713 {
00714 int l;
00715 if(_stscanf(pItem->pszText, _T("%d"), &l) == 1)
00716 {
00717 fNeedsUpdate = true;
00718 m_sts[pItem->iItem].layer = l;
00719 CString str;
00720 str.Format(_T("%d"), l);
00721 m_list.SetItemText(pItem->iItem, pItem->iSubItem, str);
00722 }
00723 }
00724 else if(pItem->iSubItem == COL_ACTOR && m_mode == TEXTSUB)
00725 {
00726 CString str(pItem->pszText);
00727 str.Trim();
00728 if(!str.IsEmpty())
00729 {
00730 fNeedsUpdate = true;
00731 m_sts[pItem->iItem].actor = str;
00732 m_list.SetItemText(pItem->iItem, pItem->iSubItem, str);
00733 }
00734 }
00735 else if(pItem->iSubItem == COL_EFFECT && m_mode == TEXTSUB)
00736 {
00737 CString str(pItem->pszText);
00738 str.Trim();
00739 if(!str.IsEmpty())
00740 {
00741 fNeedsUpdate = true;
00742 m_sts[pItem->iItem].effect = str;
00743 m_list.SetItemText(pItem->iItem, pItem->iSubItem, str);
00744 }
00745 }
00746 }
00747
00748 if(fNeedsUpdate)
00749 {
00750 UpdatePreview();
00751 }
00752 }
00753
00754 static int uintcomp(const void* i1, const void* i2)
00755 {
00756 return(*((UINT*)i2) - *((UINT*)i1));
00757 }
00758
00759 void CPlayerSubresyncBar::OnRclickList(NMHDR* pNMHDR, LRESULT* pResult)
00760 {
00761 LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)pNMHDR;
00762
00763 if(lpnmlv->iItem >= 0 && lpnmlv->iSubItem >= 0)
00764 {
00765 enum
00766 {
00767 TOGSEP=1,
00768 DUPITEM, DELITEM,
00769 RESETS, SETOS, SETCS, RESETE, SETOE, SETCE,
00770 STYLEFIRST, STYLELAST=STYLEFIRST+1000, STYLEEDIT,
00771 UNICODEYES, UNICODENO,
00772 LAYERDEC, LAYERINC,
00773 ACTORFIRST, ACTORLAST=ACTORFIRST+1000,
00774 EFFECTFIRST, EFFECTLAST=EFFECTFIRST+1000
00775 };
00776
00777 CStringArray styles;
00778 CStringArray actors;
00779 CStringArray effects;
00780
00781 CMenu m;
00782 m.CreatePopupMenu();
00783
00784 if(m_mode == VOBSUB || m_mode == TEXTSUB)
00785 {
00786 m.AppendMenu(MF_STRING|MF_ENABLED, TOGSEP, ResStr(IDS_SUBRESYNC_SEPARATOR));
00787 m.AppendMenu(MF_SEPARATOR);
00788 if(m_mode == TEXTSUB) m.AppendMenu(MF_STRING|MF_ENABLED, DUPITEM, ResStr(IDS_SUBRESYNC_DUPLICATE));
00789 m.AppendMenu(MF_STRING|MF_ENABLED, DELITEM, ResStr(IDS_SUBRESYNC_DELETE));
00790 }
00791
00792 if(lpnmlv->iSubItem == COL_START && (m_mode == VOBSUB || m_mode == TEXTSUB))
00793 {
00794 m.AppendMenu(MF_SEPARATOR);
00795 m.AppendMenu(MF_STRING|MF_ENABLED, RESETS, ResStr(IDS_SUBRESYNC_RESET));
00796 m.AppendMenu(MF_STRING|MF_ENABLED, SETOS, ResStr(IDS_SUBRESYNC_ORIGINAL));
00797 m.AppendMenu(MF_STRING|MF_ENABLED, SETCS, ResStr(IDS_SUBRESYNC_CURRENT));
00798 }
00799 else if(lpnmlv->iSubItem == COL_END && m_mode == TEXTSUB)
00800 {
00801 m.AppendMenu(MF_SEPARATOR);
00802 m.AppendMenu(MF_STRING|MF_ENABLED, RESETE, ResStr(IDS_SUBRESYNC_RESET));
00803 m.AppendMenu(MF_STRING|MF_ENABLED, SETOE, ResStr(IDS_SUBRESYNC_ORIGINAL));
00804 m.AppendMenu(MF_STRING|MF_ENABLED, SETCE, ResStr(IDS_SUBRESYNC_CURRENT));
00805 }
00806 else if(lpnmlv->iSubItem == COL_STYLE && m_mode == TEXTSUB)
00807 {
00808 m.AppendMenu(MF_SEPARATOR);
00809
00810 int id = STYLEFIRST;
00811
00812 POSITION pos = m_sts.m_styles.GetStartPosition();
00813 while(pos && id <= STYLELAST)
00814 {
00815 CString key;
00816 void* val;
00817 m_sts.m_styles.GetNextAssoc(pos, key, val);
00818
00819 styles.Add(key);
00820
00821 m.AppendMenu(MF_STRING|MF_ENABLED, id++, key);
00822 }
00823
00824 if(id > STYLEFIRST && m_list.GetSelectedCount() == 1)
00825 {
00826 m.AppendMenu(MF_SEPARATOR);
00827 m.AppendMenu(MF_STRING|MF_ENABLED, STYLEEDIT, ResStr(IDS_SUBRESYNC_EDIT));
00828 }
00829 }
00830 else if(lpnmlv->iSubItem == COL_UNICODE && m_mode == TEXTSUB)
00831 {
00832 m.AppendMenu(MF_SEPARATOR);
00833 m.AppendMenu(MF_STRING|MF_ENABLED, UNICODEYES, ResStr(IDS_SUBRESYNC_YES));
00834 m.AppendMenu(MF_STRING|MF_ENABLED, UNICODENO, ResStr(IDS_SUBRESYNC_NO));
00835 }
00836 else if(lpnmlv->iSubItem == COL_LAYER && m_mode == TEXTSUB)
00837 {
00838 m.AppendMenu(MF_SEPARATOR);
00839 m.AppendMenu(MF_STRING|MF_ENABLED, LAYERDEC, ResStr(IDS_SUBRESYNC_DECREASE));
00840 m.AppendMenu(MF_STRING|MF_ENABLED, LAYERINC, ResStr(IDS_SUBRESYNC_INCREASE));
00841 }
00842 else if(lpnmlv->iSubItem == COL_ACTOR && m_mode == TEXTSUB)
00843 {
00844 CMapStringToPtr actormap;
00845
00846 for(int i = 0, j = m_sts.GetSize(); i < j; i++)
00847 actormap[m_sts[i].actor] = NULL;
00848
00849 actormap.RemoveKey(_T(""));
00850
00851 if(actormap.GetCount() > 0)
00852 {
00853 m.AppendMenu(MF_SEPARATOR);
00854
00855 int id = ACTORFIRST;
00856
00857 POSITION pos = actormap.GetStartPosition();
00858 while(pos && id <= ACTORLAST)
00859 {
00860 CString key;
00861 void* val;
00862 actormap.GetNextAssoc(pos, key, val);
00863
00864 actors.Add(key);
00865
00866 m.AppendMenu(MF_STRING|MF_ENABLED, id++, key);
00867 }
00868 }
00869 }
00870 else if(lpnmlv->iSubItem == COL_EFFECT && m_mode == TEXTSUB)
00871 {
00872 CMapStringToPtr effectmap;
00873
00874 for(int i = 0, j = m_sts.GetSize(); i < j; i++)
00875 effectmap[m_sts[i].effect] = NULL;
00876
00877 effectmap.RemoveKey(_T(""));
00878
00879 if(effectmap.GetCount() > 0)
00880 {
00881 m.AppendMenu(MF_SEPARATOR);
00882
00883 int id = EFFECTFIRST;
00884
00885 POSITION pos = effectmap.GetStartPosition();
00886 while(pos && id <= EFFECTLAST)
00887 {
00888 CString key;
00889 void* val;
00890 effectmap.GetNextAssoc(pos, key, val);
00891
00892 effects.Add(key);
00893
00894 m.AppendMenu(MF_STRING|MF_ENABLED, id++, key);
00895 }
00896 }
00897 }
00898
00899 CPoint p = lpnmlv->ptAction;
00900 ::MapWindowPoints(pNMHDR->hwndFrom, HWND_DESKTOP, &p, 1);
00901
00902 UINT id = m.TrackPopupMenu(TPM_LEFTBUTTON|TPM_RETURNCMD, p.x, p.y, this);
00903
00904 bool fNeedsUpdate = false;
00905
00906 POSITION pos = m_list.GetFirstSelectedItemPosition();
00907 while(pos)
00908 {
00909 int iItem = m_list.GetNextSelectedItem(pos);
00910
00911 SubTime& st = m_subtimes[iItem];
00912
00913 switch(id)
00914 {
00915 case TOGSEP:
00916 m_list.SetItemData(iItem, m_list.GetItemData(iItem)^TSEP);
00917 m_list.Invalidate();
00918 fNeedsUpdate = true;
00919 break;
00920 case DUPITEM:
00921 {
00922 CUIntArray items;
00923 pos = m_list.GetFirstSelectedItemPosition();
00924 while(pos) items.Add(m_list.GetNextSelectedItem(pos));
00925
00926 qsort(items.GetData(), items.GetSize(), sizeof(UINT), uintcomp);
00927
00928 for(int i = 0; i < items.GetSize(); i++)
00929 {
00930 iItem = items[i];
00931
00932 STSEntry stse = m_sts[iItem];
00933 m_sts.InsertAt(iItem+1, stse);
00934
00935 SubTime st = m_subtimes[iItem];
00936 m_subtimes.InsertAt(iItem+1, st);
00937
00938 CHeaderCtrl* pHeader = (CHeaderCtrl*)m_list.GetDlgItem(0);
00939 int nColumnCount = pHeader->GetItemCount();
00940
00941 CStringArray sa;
00942 sa.SetSize(nColumnCount);
00943 for(int col = 0; col < nColumnCount; col++)
00944 sa[col] = m_list.GetItemText(iItem, col);
00945
00946 DWORD data = m_list.GetItemData(iItem);
00947 m_list.InsertItem(iItem+1, sa[0]);
00948 m_list.SetItemData(iItem+1, data);
00949 for(int col = 1; col < nColumnCount; col++)
00950 m_list.SetItemText(iItem+1, col, sa[col]);
00951 }
00952 }
00953
00954 fNeedsUpdate = true;
00955 break;
00956 case DELITEM:
00957 {
00958 CUIntArray items;
00959 pos = m_list.GetFirstSelectedItemPosition();
00960 while(pos) items.Add(m_list.GetNextSelectedItem(pos));
00961
00962 qsort(items.GetData(), items.GetSize(), sizeof(UINT), uintcomp);
00963
00964 for(int i = 0; i < items.GetSize(); i++)
00965 {
00966 iItem = items[i];
00967 m_sts.RemoveAt(iItem);
00968 m_subtimes.RemoveAt(iItem);
00969 m_list.DeleteItem(iItem);
00970 }
00971
00972 iItem = items[items.GetSize()-1];
00973 if(iItem >= m_list.GetItemCount()) iItem = m_list.GetItemCount()-1;
00974
00975 m_list.SetSelectionMark(iItem);
00976 }
00977 fNeedsUpdate = true;
00978 break;
00979 case RESETS: ModStart(iItem, st.orgstart, true); fNeedsUpdate = true; break;
00980 case SETOS: ModStart(iItem, st.orgstart); fNeedsUpdate = true; break;
00981 case SETCS: ModStart(iItem, (int)(m_rt/10000)); fNeedsUpdate = true; break;
00982 case RESETE: ModEnd(iItem, st.orgend, true); fNeedsUpdate = true; break;
00983 case SETOE: ModEnd(iItem, st.orgend); fNeedsUpdate = true; break;
00984 case SETCE: ModEnd(iItem, (int)(m_rt/10000)); fNeedsUpdate = true; break;
00985 default:
00986 if(STYLEFIRST <= id && id <= STYLELAST)
00987 {
00988 CString s = styles[id - STYLEFIRST];
00989 if(m_sts[iItem].style != s) fNeedsUpdate = true;
00990 m_sts[iItem].style = s;
00991 m_list.SetItemText(iItem, lpnmlv->iSubItem, s);
00992 }
00993 else if(id == STYLEEDIT)
00994 {
00995 CAutoPtrArray<CPPageSubStyle> pages;
00996 CArray<STSStyle*> styles;
00997
00998 STSStyle* stss = m_sts.GetStyle(iItem);
00999 int iSelPage = 0;
01000
01001 POSITION pos = m_sts.m_styles.GetStartPosition();
01002 for(int i = 0; pos; i++)
01003 {
01004 CString key;
01005 void* val;
01006 m_sts.m_styles.GetNextAssoc(pos, key, val);
01007
01008 CAutoPtr<CPPageSubStyle> page(new CPPageSubStyle());
01009 page->InitStyle(key, *(STSStyle*)val);
01010 pages.Add(page);
01011 styles.Add((STSStyle*)val);
01012
01013 if(stss == (STSStyle*)val)
01014 iSelPage = i;
01015 }
01016
01017 CPropertySheet dlg(_T("Styles..."), this, iSelPage);
01018 for(int i = 0; i < (int)pages.GetCount(); i++) dlg.AddPage(pages[i]);
01019
01020 if(dlg.DoModal() == IDOK)
01021 {
01022 for(int j = 0; j < (int)pages.GetCount(); j++)
01023 {
01024 stss = styles[j];
01025 pages[j]->GetStyle(*stss);
01026
01027 for(int i = 0; i < m_sts.GetSize(); i++)
01028 {
01029 if(m_sts.GetStyle(i) == stss)
01030 {
01031 CString str;
01032 m_list.SetItemText(i, COL_TEXT, m_sts.GetStr(i, true));
01033 m_list.SetItemText(i, COL_FONT, stss->fontName);
01034 str.Format(_T("%d"), stss->charSet);
01035 m_list.SetItemText(i, COL_CHARSET, str);
01036 str.Format(_T("%d"), m_sts[i].layer);
01037 }
01038 }
01039 }
01040
01041 fNeedsUpdate = true;
01042 }
01043 }
01044 else if(id == UNICODEYES || id == UNICODENO)
01045 {
01046 m_sts.ConvertUnicode(iItem, id == UNICODEYES);
01047 m_list.SetItemText(iItem, COL_TEXT, m_sts.GetStr(iItem, true));
01048 m_list.SetItemText(iItem, COL_UNICODE, m_sts.IsEntryUnicode(iItem) ? _T("yes") : _T("no"));
01049 fNeedsUpdate = true;
01050 }
01051 else if(id == LAYERDEC || id == LAYERINC)
01052 {
01053 int d = (id == LAYERDEC) ? -1 : (id == LAYERINC) ? +1 : 0;
01054 if(d != 0) fNeedsUpdate = true;
01055 m_sts[iItem].layer += d;
01056 CString s;
01057 s.Format(_T("%d"), m_sts[iItem].layer);
01058 m_list.SetItemText(iItem, lpnmlv->iSubItem, s);
01059 }
01060 else if(ACTORFIRST <= id && id <= ACTORLAST)
01061 {
01062 CString s = actors[id - ACTORFIRST];
01063 if(m_sts[iItem].actor != s) fNeedsUpdate = true;
01064 m_sts[iItem].actor = s;
01065 m_list.SetItemText(iItem, lpnmlv->iSubItem, s);
01066 }
01067 else if(EFFECTFIRST <= id && id <= EFFECTLAST)
01068 {
01069 CString s = effects[id - EFFECTFIRST];
01070 if(m_sts[iItem].effect != s) fNeedsUpdate = true;
01071 m_sts[iItem].effect = s;
01072 m_list.SetItemText(iItem, lpnmlv->iSubItem, s);
01073 }
01074 break;
01075 }
01076 }
01077
01078 if(fNeedsUpdate)
01079 {
01080 UpdatePreview();
01081 }
01082 }
01083
01084 *pResult = 0;
01085 }
01086
01087 void CPlayerSubresyncBar::OnNMDblclkList(NMHDR* pNMHDR, LRESULT* pResult)
01088 {
01089 LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)pNMHDR;
01090
01091 if(lpnmlv->iItem >= 0 && lpnmlv->iSubItem >= 0 && (m_mode == VOBSUB || m_mode == TEXTSUB))
01092 {
01093 if(CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd())
01094 {
01095 int t = 0;
01096 if(!ParseTime(m_list.GetItemText(lpnmlv->iItem, lpnmlv->iSubItem), t, false))
01097 t = m_sts[lpnmlv->iItem].start;
01098
01099 REFERENCE_TIME rt =
01100 lpnmlv->iSubItem == COL_START ? ((REFERENCE_TIME)t*10000) :
01101 lpnmlv->iSubItem == COL_END ? ((REFERENCE_TIME)t*10000) :
01102 lpnmlv->iSubItem == COL_PREVSTART ? ((REFERENCE_TIME)t*10000) :
01103 lpnmlv->iSubItem == COL_PREVEND ? ((REFERENCE_TIME)t*10000) :
01104 ((REFERENCE_TIME)t*10000);
01105
01106 pFrame->SeekTo(rt);
01107 }
01108 }
01109
01110 *pResult = 0;
01111 }
01112
01113 void CPlayerSubresyncBar::OnLvnKeydownList(NMHDR* pNMHDR, LRESULT* pResult)
01114 {
01115 LPNMLVKEYDOWN pLVKeyDown = reinterpret_cast<LPNMLVKEYDOWN>(pNMHDR);
01116
01117 *pResult = 0;
01118 }
01119
01120 static CUIntArray m_itemGroups;
01121 static int m_totalGroups;
01122
01123 void CPlayerSubresyncBar::OnCustomdrawList(NMHDR* pNMHDR, LRESULT* pResult)
01124 {
01125 NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>(pNMHDR);
01126
01127 *pResult = CDRF_DODEFAULT;
01128
01129 if(CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage)
01130 {
01131 m_itemGroups.SetSize(m_list.GetItemCount());
01132 m_totalGroups = 0;
01133 for(int i = 0, j = m_list.GetItemCount(); i < j; i++)
01134 {
01135 if(m_list.GetItemData(i)&TSEP) m_totalGroups++;
01136 m_itemGroups[i] = m_totalGroups;
01137 }
01138
01139 *pResult = CDRF_NOTIFYPOSTPAINT|CDRF_NOTIFYITEMDRAW;
01140 }
01141 else if(CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage)
01142 {
01143 pLVCD->nmcd.uItemState &= ~CDIS_FOCUS;
01144
01145 *pResult = CDRF_NOTIFYPOSTPAINT|CDRF_NOTIFYSUBITEMDRAW;
01146 }
01147 else if((CDDS_ITEMPREPAINT|CDDS_SUBITEM) == pLVCD->nmcd.dwDrawStage)
01148 {
01149 COLORREF clrText;
01150 COLORREF clrTextBk;
01151
01152 if((pLVCD->iSubItem == COL_START || pLVCD->iSubItem == COL_END || pLVCD->iSubItem == COL_TEXT || pLVCD->iSubItem == COL_STYLE
01153 || pLVCD->iSubItem == COL_LAYER || pLVCD->iSubItem == COL_ACTOR || pLVCD->iSubItem == COL_EFFECT)
01154 && m_mode == TEXTSUB)
01155 {
01156 clrText = 0;
01157 }
01158 else if((pLVCD->iSubItem == COL_START)
01159 && m_mode == VOBSUB)
01160 {
01161 clrText = 0;
01162 }
01163 else
01164 {
01165 clrText = 0x606060;
01166 }
01167
01168 clrTextBk = 0xffffff;
01169
01170 clrTextBk -= ((m_itemGroups[pLVCD->nmcd.dwItemSpec]&1) ? 0x100010 : 0x200020);
01171
01172 if(m_sts[pLVCD->nmcd.dwItemSpec].start <= m_rt/10000 && m_rt/10000 < m_sts[pLVCD->nmcd.dwItemSpec].end)
01173 {
01174 clrText |= 0xFF;
01175 }
01176
01177 int nCheck = (int)m_list.GetItemData(pLVCD->nmcd.dwItemSpec);
01178
01179 if((nCheck&1) && (pLVCD->iSubItem == COL_START || pLVCD->iSubItem == COL_PREVSTART))
01180 {
01181 clrTextBk = 0xffddbb;
01182 }
01183 else if((nCheck&4) && ( pLVCD->iSubItem == COL_PREVSTART))
01184 {
01185 clrTextBk = 0xffeedd;
01186 }
01187
01188 if((nCheck&2) && (pLVCD->iSubItem == COL_END || pLVCD->iSubItem == COL_PREVEND))
01189 {
01190 clrTextBk = 0xffddbb;
01191 }
01192 else if((nCheck&8) && ( pLVCD->iSubItem == COL_PREVEND))
01193 {
01194 clrTextBk = 0xffeedd;
01195 }
01196
01197 pLVCD->clrText = clrText;
01198 pLVCD->clrTextBk = clrTextBk;
01199
01200 *pResult = CDRF_NOTIFYPOSTPAINT;
01201 }
01202 else if((CDDS_ITEMPOSTPAINT|CDDS_SUBITEM) == pLVCD->nmcd.dwDrawStage)
01203 {
01204
01205 }
01206 else if(CDDS_ITEMPOSTPAINT == pLVCD->nmcd.dwDrawStage)
01207 {
01208 int nItem = static_cast<int>(pLVCD->nmcd.dwItemSpec);
01209
01210 LVITEM rItem;
01211 ZeroMemory(&rItem, sizeof(LVITEM));
01212 rItem.mask = LVIF_IMAGE | LVIF_STATE;
01213 rItem.iItem = nItem;
01214 rItem.stateMask = LVIS_SELECTED;
01215 m_list.GetItem(&rItem);
01216
01217 {
01218 CDC* pDC = CDC::FromHandle(pLVCD->nmcd.hdc);
01219
01220 CRect rcItem;
01221 m_list.GetItemRect(nItem, &rcItem, LVIR_BOUNDS);
01222
01223 {
01224 bool fSeparator = nItem < m_list.GetItemCount()-1 && (m_list.GetItemData(nItem+1)&TSEP);
01225 CPen p(PS_INSIDEFRAME, 1, fSeparator ? 0x404040 : 0xe0e0e0);
01226 CPen* old = pDC->SelectObject(&p);
01227 pDC->MoveTo(CPoint(rcItem.left, rcItem.bottom-1));
01228 pDC->LineTo(CPoint(rcItem.right, rcItem.bottom-1));
01229 pDC->SelectObject(old);
01230 }
01231
01232 {
01233 CPen p(PS_INSIDEFRAME, 1, 0xe0e0e0);
01234 CPen* old = pDC->SelectObject(&p);
01235
01236 CHeaderCtrl* pHeader = (CHeaderCtrl*)m_list.GetDlgItem(0);
01237 int nColumnCount = pHeader->GetItemCount();
01238
01239
01240 int offset = rcItem.left;
01241 for(int i = 0; i < nColumnCount; i++)
01242 {
01243 offset += m_list.GetColumnWidth(i);
01244 pDC->MoveTo(CPoint(offset, rcItem.top));
01245 pDC->LineTo(CPoint(offset, rcItem.bottom));
01246 }
01247
01248 pDC->SelectObject(old);
01249 }
01250
01251 *pResult = CDRF_SKIPDEFAULT;
01252 }
01253 }
01254 else if(CDDS_POSTPAINT == pLVCD->nmcd.dwDrawStage)
01255 {
01256 }
01257 }
01258