PlayerListCtrl.cpp

00001 /* 
00002  *      Copyright (C) 2003-2005 Gabest
00003  *      http://www.gabest.org
00004  *
00005  *  This Program is free software; you can redistribute it and/or modify
00006  *  it under the terms of the GNU General Public License as published by
00007  *  the Free Software Foundation; either version 2, or (at your option)
00008  *  any later version.
00009  *   
00010  *  This Program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00013  *  GNU General Public License for more details.
00014  *   
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with GNU Make; see the file COPYING.  If not, write to
00017  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
00018  *  http://www.gnu.org/copyleft/gpl.html
00019  *
00020  */
00021 
00022 // PlayerListCtrl.cpp : implementation file
00023 //
00024 
00025 #include "stdafx.h"
00026 #include "mplayerc.h"
00027 #include "PlayerListCtrl.h"
00028 #include ".\playerlistctrl.h"
00029 
00030 // CInPlaceEdit
00031 
00032 CInPlaceEdit::CInPlaceEdit(int iItem, int iSubItem, CString sInitText)
00033         : m_sInitText( sInitText )
00034 {
00035         m_iItem = iItem;
00036         m_iSubItem = iSubItem;
00037         m_bESC = FALSE;
00038 }
00039 
00040 CInPlaceEdit::~CInPlaceEdit()
00041 {
00042 }
00043 
00044 BEGIN_MESSAGE_MAP(CInPlaceEdit, CEdit)
00045         //{{AFX_MSG_MAP(CInPlaceEdit)
00046         ON_WM_KILLFOCUS()
00047         ON_WM_NCDESTROY()
00048         ON_WM_CHAR()
00049         ON_WM_CREATE()
00050         //}}AFX_MSG_MAP
00051 END_MESSAGE_MAP()
00052 
00054 // CInPlaceEdit message handlers
00055 
00056 BOOL CInPlaceEdit::PreTranslateMessage(MSG* pMsg)
00057 {
00058         if(pMsg->message == WM_KEYDOWN)
00059         {
00060                 if(pMsg->wParam == VK_RETURN
00061                 || pMsg->wParam == VK_DELETE
00062                 || pMsg->wParam == VK_ESCAPE
00063                 || GetKeyState(VK_CONTROL))
00064                 {
00065                         ::TranslateMessage(pMsg);
00066                         ::DispatchMessage(pMsg);
00067                         return TRUE;                    // DO NOT process further
00068                 }
00069         }
00070 
00071         return CEdit::PreTranslateMessage(pMsg);
00072 }
00073 
00074 void CInPlaceEdit::OnKillFocus(CWnd* pNewWnd)
00075 {
00076         CEdit::OnKillFocus(pNewWnd);
00077 
00078         CString str;
00079         GetWindowText(str);
00080 
00081         LV_DISPINFO dispinfo;
00082         dispinfo.hdr.hwndFrom = GetParent()->m_hWnd;
00083         dispinfo.hdr.idFrom = GetDlgCtrlID();
00084         dispinfo.hdr.code = LVN_ENDLABELEDIT;
00085         dispinfo.item.mask = LVIF_TEXT;
00086         dispinfo.item.iItem = m_iItem;
00087         dispinfo.item.iSubItem = m_iSubItem;
00088         dispinfo.item.pszText = m_bESC ? NULL : LPTSTR((LPCTSTR)str);
00089         dispinfo.item.cchTextMax = str.GetLength();
00090         GetParent()->GetParent()->SendMessage(WM_NOTIFY, GetParent()->GetDlgCtrlID(), (LPARAM)&dispinfo);
00091 
00092         DestroyWindow();
00093 }
00094 
00095 void CInPlaceEdit::OnNcDestroy()
00096 {
00097         CEdit::OnNcDestroy();
00098 
00099         delete this;
00100 }
00101 
00102 
00103 void CInPlaceEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
00104 {
00105         if(nChar == VK_ESCAPE || nChar == VK_RETURN)
00106         {
00107                 if(nChar == VK_ESCAPE) m_bESC = TRUE;
00108                 GetParent()->SetFocus();
00109                 return;
00110         }
00111 
00112         CEdit::OnChar(nChar, nRepCnt, nFlags);
00113 }
00114 
00115 int CInPlaceEdit::OnCreate(LPCREATESTRUCT lpCreateStruct)
00116 {
00117         if(CEdit::OnCreate(lpCreateStruct) == -1)
00118                 return -1;
00119 
00120         // Set the proper font
00121         CFont* font = GetParent()->GetFont();
00122         SetFont(font);
00123 
00124         SetWindowText(m_sInitText);
00125         SetFocus();
00126         SetSel(0, -1);
00127         return 0;
00128 }
00129 
00130 // CInPlaceComboBox
00131 
00132 CInPlaceComboBox::CInPlaceComboBox(int iItem, int iSubItem, CList<CString>& lstItems, int nSel)
00133 {
00134         m_iItem = iItem;
00135         m_iSubItem = iSubItem;
00136 
00137         m_lstItems.AddTail(&lstItems);
00138         m_nSel = nSel;
00139         m_bESC = FALSE;
00140 }
00141 
00142 CInPlaceComboBox::~CInPlaceComboBox()
00143 {
00144 }
00145 
00146 BEGIN_MESSAGE_MAP(CInPlaceComboBox, CComboBox)
00147         //{{AFX_MSG_MAP(CInPlaceComboBox)
00148         ON_WM_CREATE()
00149         ON_WM_KILLFOCUS()
00150         ON_WM_CHAR()
00151         ON_WM_NCDESTROY()
00152         ON_CONTROL_REFLECT(CBN_CLOSEUP, OnCloseup)
00153         //}}AFX_MSG_MAP
00154 END_MESSAGE_MAP()
00155 
00157 // CInPlaceComboBox message handlers
00158 
00159 int CInPlaceComboBox::OnCreate(LPCREATESTRUCT lpCreateStruct) 
00160 {
00161         if (CComboBox::OnCreate(lpCreateStruct) == -1)
00162                 return -1;
00163         
00164         // Set the proper font
00165         CFont* font = GetParent()->GetFont();
00166         SetFont(font);
00167 
00168         for(POSITION pos = m_lstItems.GetHeadPosition(); pos != NULL;)
00169                 AddString((LPCTSTR)(m_lstItems.GetNext(pos)));
00170 
00171         SetFocus();
00172         SetCurSel(m_nSel);
00173         return 0;
00174 }
00175 
00176 BOOL CInPlaceComboBox::PreTranslateMessage(MSG* pMsg) 
00177 {
00178         if(pMsg->message == WM_KEYDOWN)
00179         {
00180                 if(pMsg->wParam == VK_RETURN 
00181                 || pMsg->wParam == VK_ESCAPE)
00182                 {
00183                         ::TranslateMessage(pMsg);
00184                         ::DispatchMessage(pMsg);
00185                         return TRUE;                            // DO NOT process further
00186                 }
00187         }
00188 
00189         return CComboBox::PreTranslateMessage(pMsg);
00190 }
00191 
00192 void CInPlaceComboBox::OnKillFocus(CWnd* pNewWnd) 
00193 {
00194         CComboBox::OnKillFocus(pNewWnd);
00195         
00196         CString str;
00197         GetWindowText(str);
00198 
00199         LV_DISPINFO dispinfo;
00200         dispinfo.hdr.hwndFrom = GetParent()->m_hWnd;
00201         dispinfo.hdr.idFrom = GetDlgCtrlID();
00202         dispinfo.hdr.code = LVN_ENDLABELEDIT;
00203         dispinfo.item.mask = LVIF_TEXT|LVIF_PARAM;
00204         dispinfo.item.iItem = m_iItem;
00205         dispinfo.item.iSubItem = m_iSubItem;
00206         dispinfo.item.pszText = m_bESC ? NULL : LPTSTR((LPCTSTR)str);
00207         dispinfo.item.cchTextMax = str.GetLength();
00208         dispinfo.item.lParam = GetCurSel();
00209         GetParent()->GetParent()->SendMessage(WM_NOTIFY, GetParent()->GetDlgCtrlID(), (LPARAM)&dispinfo);
00210 
00211         PostMessage(WM_CLOSE);
00212 }
00213 
00214 void CInPlaceComboBox::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
00215 {
00216         if(nChar == VK_ESCAPE || nChar == VK_RETURN)
00217         {
00218                 if(nChar == VK_ESCAPE) m_bESC = TRUE;
00219                 GetParent()->SetFocus();
00220                 return;
00221         }
00222 
00223         CComboBox::OnChar(nChar, nRepCnt, nFlags);
00224 }
00225 
00226 void CInPlaceComboBox::OnNcDestroy() 
00227 {
00228         CComboBox::OnNcDestroy();
00229         
00230         delete this;
00231 }
00232 
00233 void CInPlaceComboBox::OnCloseup() 
00234 {
00235         GetParent()->SetFocus();
00236 }
00237 
00238 // CInPlaceListBox
00239 
00240 CInPlaceListBox::CInPlaceListBox(int iItem, int iSubItem, CList<CString>& lstItems, int nSel)
00241 {
00242         m_iItem = iItem;
00243         m_iSubItem = iSubItem;
00244 
00245         m_lstItems.AddTail(&lstItems);
00246         m_nSel = nSel;
00247         m_bESC = FALSE;
00248 }
00249 
00250 CInPlaceListBox::~CInPlaceListBox()
00251 {
00252 }
00253 
00254 BEGIN_MESSAGE_MAP(CInPlaceListBox, CListBox)
00255         //{{AFX_MSG_MAP(CInPlaceListBox)
00256         ON_WM_CREATE()
00257         ON_WM_KILLFOCUS()
00258         ON_WM_CHAR()
00259         ON_WM_NCDESTROY()
00260         //}}AFX_MSG_MAP
00261 END_MESSAGE_MAP()
00262 
00264 // CInPlaceListBox message handlers
00265 
00266 int CInPlaceListBox::OnCreate(LPCREATESTRUCT lpCreateStruct) 
00267 {
00268         if(CListBox::OnCreate(lpCreateStruct) == -1)
00269                 return -1;
00270         
00271         // Set the proper font
00272         CFont* font = GetParent()->GetFont();
00273         SetFont(font);
00274 
00275         for(POSITION pos = m_lstItems.GetHeadPosition(); pos != NULL;)
00276         {
00277                 AddString( (LPCTSTR) (m_lstItems.GetNext( pos )) );
00278         }
00279         SetCurSel( m_nSel );
00280         SetFocus();
00281         return 0;
00282 }
00283 
00284 BOOL CInPlaceListBox::PreTranslateMessage(MSG* pMsg) 
00285 {
00286         if(pMsg->message == WM_KEYDOWN)
00287         {
00288                 if(pMsg->wParam == VK_RETURN 
00289                 || pMsg->wParam == VK_ESCAPE)
00290                 {
00291                         ::TranslateMessage(pMsg);
00292                         ::DispatchMessage(pMsg);
00293                         return TRUE;                            // DO NOT process further
00294                 }
00295         }
00296         
00297         return CListBox::PreTranslateMessage(pMsg);
00298 }
00299 
00300 void CInPlaceListBox::OnKillFocus(CWnd* pNewWnd) 
00301 {
00302         CListBox::OnKillFocus(pNewWnd);
00303         
00304         CString str;
00305         GetWindowText(str);
00306 
00307         LV_DISPINFO dispinfo;
00308         dispinfo.hdr.hwndFrom = GetParent()->m_hWnd;
00309         dispinfo.hdr.idFrom = GetDlgCtrlID();
00310         dispinfo.hdr.code = LVN_ENDLABELEDIT;
00311         dispinfo.item.mask = LVIF_TEXT|LVIF_PARAM;
00312         dispinfo.item.iItem = m_iItem;
00313         dispinfo.item.iSubItem = m_iSubItem;
00314         dispinfo.item.pszText = m_bESC ? NULL : LPTSTR((LPCTSTR)str);
00315         dispinfo.item.cchTextMax = str.GetLength();
00316         dispinfo.item.lParam = GetCurSel();
00317         GetParent()->GetParent()->SendMessage(WM_NOTIFY, GetParent()->GetDlgCtrlID(), (LPARAM)&dispinfo);
00318 
00319         PostMessage(WM_CLOSE);
00320 }
00321 
00322 void CInPlaceListBox::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
00323 {
00324         if(nChar == VK_ESCAPE || nChar == VK_RETURN)
00325         {
00326                 if(nChar == VK_ESCAPE) m_bESC = TRUE;
00327                 GetParent()->SetFocus();
00328                 return;
00329         }
00330 
00331         CListBox::OnChar(nChar, nRepCnt, nFlags);
00332 }
00333 
00334 void CInPlaceListBox::OnNcDestroy() 
00335 {
00336         CListBox::OnNcDestroy();
00337         
00338         delete this;
00339 }
00340 
00341 
00342 
00343 // CPlayerListCtrl
00344 
00345 IMPLEMENT_DYNAMIC(CPlayerListCtrl, CListCtrl)
00346 CPlayerListCtrl::CPlayerListCtrl(int tStartEditingDelay)
00347         : m_tStartEditingDelay(tStartEditingDelay)
00348         , m_nItemClicked(-1)
00349 {
00350 }
00351 
00352 CPlayerListCtrl::~CPlayerListCtrl()
00353 {
00354 }
00355 
00356 void CPlayerListCtrl::PreSubclassWindow()
00357 {
00358         EnableToolTips(TRUE);
00359 
00360         CListCtrl::PreSubclassWindow();
00361 }
00362 
00363 int CPlayerListCtrl::HitTestEx(CPoint& point, int* col) const
00364 {
00365         if(col) *col = 0;
00366 
00367         int row = HitTest(CPoint(0, point.y), NULL);
00368 
00369         if((GetWindowLong(m_hWnd, GWL_STYLE) & LVS_TYPEMASK) != LVS_REPORT)
00370                 return row;
00371 
00372         int nColumnCount = ((CHeaderCtrl*)GetDlgItem(0))->GetItemCount();
00373 
00374         for(int top = GetTopIndex(), bottom = GetBottomIndex(); top <= bottom; top++)
00375         {
00376                 CRect r;
00377                 GetItemRect(top, &r, LVIR_BOUNDS);
00378 
00379                 if(r.top <= point.y && point.y < r.bottom)
00380                 {
00381                         for(int colnum = 0; colnum < nColumnCount; colnum++)
00382                         {
00383                                 int colwidth = GetColumnWidth(colnum);
00384 
00385                                 if(point.x >= r.left && point.x <= (r.left + colwidth))
00386                                 {
00387                                         if(col) *col = colnum;
00388                                         return top;
00389                                 }
00390 
00391                                 r.left += colwidth;
00392                         }
00393                 }
00394         }
00395 
00396         return -1;
00397 }
00398 
00399 int CPlayerListCtrl::GetBottomIndex() const
00400 {
00401         CRect r;
00402         GetClientRect(r);
00403 
00404         int nBottomIndex = GetTopIndex() + GetCountPerPage() - 1;
00405 
00406         if(nBottomIndex >= GetItemCount()) 
00407         {
00408                 nBottomIndex = GetItemCount() - 1;
00409         }
00410         else if(nBottomIndex < GetItemCount())
00411         {
00412                 CRect br;
00413                 GetItemRect(nBottomIndex, br, LVIR_BOUNDS);
00414 
00415                 if(br.bottom < r.bottom)
00416                         nBottomIndex++;
00417         }
00418 
00419         return(nBottomIndex);
00420 }
00421 
00422 CImageList* CPlayerListCtrl::CreateDragImageEx(LPPOINT lpPoint)
00423 {
00424         if(GetSelectedCount() <= 0)
00425                 return NULL;
00426 
00427         CRect cSingleRect, cCompleteRect(0, 0, 0, 0);
00428         GetClientRect(cSingleRect);
00429         int nWidth = cSingleRect.Width();
00430 
00431         // Start and Stop index in view area
00432         int nIndex = GetTopIndex() - 1;
00433         int nBottomIndex = GetBottomIndex();
00434 
00435         // Determine the size of the drag image (limite for 
00436         // rows visibled and Client width)
00437         while((nIndex = GetNextItem(nIndex, LVNI_SELECTED)) != -1 && nIndex <= nBottomIndex)
00438         {
00439                 GetItemRect(nIndex, cSingleRect, LVIR_BOUNDS);
00440 /*
00441                 CRect r;
00442                 GetItemRect(nIndex, r, LVIR_LABEL);
00443                 cSingleRect.left = r.left;
00444 */
00445                 if(cSingleRect.left < 0) cSingleRect.left = 0;
00446                 if(cSingleRect.right > nWidth) cSingleRect.right = nWidth;
00447 
00448                 cCompleteRect |= cSingleRect;
00449         }
00450 
00451         //
00452         // Create bitmap in memory DC
00453         //
00454         CClientDC cDc(this);
00455         CDC cMemDC;
00456         CBitmap cBitmap;
00457 
00458         if(!cMemDC.CreateCompatibleDC(&cDc))
00459                 return NULL;
00460 
00461         if(!cBitmap.CreateCompatibleBitmap(&cDc, cCompleteRect.Width(), cCompleteRect.Height()))
00462                 return NULL;
00463         
00464         CBitmap* pOldMemDCBitmap = cMemDC.SelectObject(&cBitmap);
00465         // Here green is used as mask color
00466         cMemDC.FillSolidRect(0, 0, cCompleteRect.Width(), cCompleteRect.Height(), RGB(0, 255, 0));
00467 
00468         // Paint each DragImage in the DC
00469         nIndex = GetTopIndex() - 1;
00470         while((nIndex = GetNextItem(nIndex, LVNI_SELECTED)) != -1 && nIndex <= nBottomIndex)
00471         {   
00472                 CPoint pt;
00473                 CImageList* pSingleImageList = CreateDragImage(nIndex, &pt);
00474 
00475                 if(pSingleImageList)
00476                 {
00477                         GetItemRect(nIndex, cSingleRect, LVIR_BOUNDS);
00478 
00479                         pSingleImageList->Draw(&cMemDC,
00480                                 0, 
00481                                 CPoint(cSingleRect.left - cCompleteRect.left, cSingleRect.top - cCompleteRect.top), 
00482                                 ILD_MASK);
00483 
00484                         pSingleImageList->DeleteImageList();
00485                         delete pSingleImageList;
00486                 }
00487         }
00488 
00489         cMemDC.SelectObject(pOldMemDCBitmap);
00490 
00491         //
00492         // Create the imagelist with the merged drag images
00493         //
00494         CImageList* pCompleteImageList = new CImageList;
00495         
00496         pCompleteImageList->Create(cCompleteRect.Width(), 
00497                                         cCompleteRect.Height(),
00498                                         ILC_COLOR | ILC_MASK, 0, 1);
00499 
00500         // Here green is used as mask color
00501         pCompleteImageList->Add(&cBitmap, RGB(0, 255, 0)); 
00502 
00503         //
00504         // as an optional service:
00505         // Find the offset of the current mouse cursor to the imagelist
00506         // this we can use in BeginDrag()
00507         //
00508         if(lpPoint)
00509         {
00510                 lpPoint->x = cCompleteRect.left;
00511                 lpPoint->y = cCompleteRect.top;
00512         }
00513 
00514         return(pCompleteImageList);
00515 }
00516 
00517 bool CPlayerListCtrl::PrepareInPlaceControl(int nRow, int nCol, CRect& rect)
00518 {
00519         if(!EnsureVisible(nRow, TRUE)) return(false);
00520 
00521         int nColumnCount = ((CHeaderCtrl*)GetDlgItem(0))->GetItemCount();
00522         if(nCol >= nColumnCount || GetColumnWidth(nCol) < 5) return(false);
00523 
00524         int offset = 0;
00525         for(int i = 0; i < nCol; i++) offset += GetColumnWidth(i);
00526 
00527         GetItemRect(nRow, &rect, LVIR_BOUNDS);
00528 
00529         CRect rcClient;
00530         GetClientRect(&rcClient);
00531         if(offset + rect.left < 0 || offset + rect.left > rcClient.right)
00532         {
00533                 CSize size(offset + rect.left, 0);
00534                 Scroll(size);
00535                 rect.left -= size.cx;
00536         }
00537 
00538         rect.left += offset;
00539         rect.right = rect.left + GetColumnWidth(nCol);
00540         if(rect.right > rcClient.right) rect.right = rcClient.right;
00541 
00542         rect.DeflateRect(1, 0, 0, 1);
00543 
00544         if(nCol == 0)
00545         {
00546                 CRect r;
00547                 GetItemRect(nRow, r, LVIR_LABEL);
00548                 rect.left = r.left-1;
00549         }
00550 
00551         return(true);
00552 }
00553 
00554 CEdit* CPlayerListCtrl::ShowInPlaceEdit(int nItem, int nCol)
00555 {
00556         CRect rect;
00557         if(!PrepareInPlaceControl(nItem, nCol, rect))
00558                 return(NULL);
00559 
00560         DWORD dwStyle = /*WS_BORDER|*/WS_CHILD|WS_VISIBLE|ES_AUTOHSCROLL;
00561 
00562         LV_COLUMN lvcol;
00563         lvcol.mask = LVCF_FMT;
00564         GetColumn(nCol, &lvcol);
00565         dwStyle |= (lvcol.fmt&LVCFMT_JUSTIFYMASK) == LVCFMT_LEFT ? ES_LEFT
00566                 : (lvcol.fmt&LVCFMT_JUSTIFYMASK) == LVCFMT_RIGHT ? ES_RIGHT
00567                 : ES_CENTER;
00568 
00569         CEdit* pEdit = new CInPlaceEdit(nItem, nCol, GetItemText(nItem, nCol));
00570         pEdit->Create(dwStyle, rect, this, IDC_EDIT1);
00571 
00572         m_fInPlaceDirty = false;
00573 
00574         return pEdit;
00575 }
00576 
00577 CComboBox* CPlayerListCtrl::ShowInPlaceComboBox(int nItem, int nCol, CList<CString>& lstItems, int nSel)
00578 {
00579         CRect rect;
00580         if(!PrepareInPlaceControl(nItem, nCol, rect))
00581                 return(NULL);
00582 
00583         DWORD dwStyle = /*WS_BORDER|*/WS_CHILD|WS_VISIBLE|WS_VSCROLL/*|WS_HSCROLL*/
00584                 |CBS_DROPDOWNLIST|CBS_DISABLENOSCROLL/*|CBS_NOINTEGRALHEIGHT*/;
00585         CComboBox* pComboBox = new CInPlaceComboBox(nItem, nCol, lstItems, nSel);
00586         pComboBox->Create(dwStyle, rect, this, IDC_COMBO1);
00587 
00588         CorrectComboListWidth(*pComboBox, GetFont());
00589 
00590         int width = GetColumnWidth(nCol);
00591         if(pComboBox->GetDroppedWidth() < width)
00592                 pComboBox->SetDroppedWidth(width);
00593 
00594         m_fInPlaceDirty = false;
00595 
00596         return pComboBox;
00597 }
00598 
00599 CListBox* CPlayerListCtrl::ShowInPlaceListBox(int nItem, int nCol, CList<CString>& lstItems, int nSel)
00600 {
00601         CRect rect;
00602         if(!PrepareInPlaceControl(nItem, nCol, rect))
00603                 return(NULL);
00604 
00605         DWORD dwStyle = WS_BORDER|WS_CHILD|WS_VISIBLE|WS_VSCROLL/*|WS_HSCROLL*/|LBS_NOTIFY;
00606         CListBox* pListBox = new CInPlaceListBox(nItem, nCol, lstItems, nSel);
00607         pListBox->Create(dwStyle, rect, this, IDC_LIST1);
00608 
00609         CRect ir;
00610         GetItemRect(m_nItemClicked, &ir, LVIR_BOUNDS);
00611 
00612         pListBox->SetItemHeight(-1, ir.Height());
00613 
00614         CDC* pDC = pListBox->GetDC();
00615         CFont* pWndFont = GetFont();
00616         pDC->SelectObject(pWndFont);
00617         int width = GetColumnWidth(nCol);
00618         POSITION pos = lstItems.GetHeadPosition();
00619         while(pos)
00620         {
00621                 int w = pDC->GetTextExtent(lstItems.GetNext(pos)).cx + 16;
00622                 if(width < w) width = w;
00623         }
00624         ReleaseDC(pDC);
00625 
00626         CRect r;
00627         pListBox->GetWindowRect(r);
00628         ScreenToClient(r);
00629         r.top = ir.bottom;
00630         r.bottom = r.top + pListBox->GetItemHeight(0) * (pListBox->GetCount() + 1);
00631         r.right = r.left + width;
00632         pListBox->MoveWindow(r);
00633 
00634         m_fInPlaceDirty = false;
00635 
00636         return pListBox;
00637 }
00638 
00639 BEGIN_MESSAGE_MAP(CPlayerListCtrl, CListCtrl)
00640         ON_WM_VSCROLL()
00641         ON_WM_HSCROLL()
00642         ON_WM_MOUSEWHEEL()
00643         ON_WM_LBUTTONDOWN()
00644         ON_WM_TIMER()
00645         ON_WM_LBUTTONDBLCLK()
00646         ON_NOTIFY_REFLECT(LVN_MARQUEEBEGIN, OnLvnMarqueeBegin)
00647         ON_NOTIFY_REFLECT(LVN_INSERTITEM, OnLvnInsertitem)
00648         ON_NOTIFY_REFLECT(LVN_DELETEITEM, OnLvnDeleteitem)
00649         ON_EN_CHANGE(IDC_EDIT1, OnEnChangeEdit1)
00650         ON_CBN_DROPDOWN(IDC_COMBO1, OnCbnDropdownCombo1)
00651         ON_CBN_SELENDOK(IDC_COMBO1, OnCbnSelendokCombo1)
00652         ON_LBN_SELCHANGE(IDC_LIST1, OnLbnSelChangeList1)
00653         ON_NOTIFY_EX(HDN_ITEMCHANGINGA, 0, OnHdnItemchanging)
00654         ON_NOTIFY_EX(HDN_ITEMCHANGINGW, 0, OnHdnItemchanging)
00655         ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipNotify)
00656         ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipNotify)
00657 END_MESSAGE_MAP()
00658 
00659 // CPlayerListCtrl message handlers
00660 
00661 void CPlayerListCtrl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
00662 {
00663         if(GetFocus() != this) SetFocus();
00664         CListCtrl::OnVScroll(nSBCode, nPos, pScrollBar);
00665 }
00666 
00667 void CPlayerListCtrl::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
00668 {
00669         if(GetFocus() != this) SetFocus();
00670         CListCtrl::OnHScroll(nSBCode, nPos, pScrollBar);
00671 }
00672 
00673 BOOL CPlayerListCtrl::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
00674 {
00675         if(GetFocus() != this) SetFocus();
00676         return CListCtrl::OnMouseWheel(nFlags, zDelta, pt);
00677 }
00678 
00679 void CPlayerListCtrl::OnLButtonDown(UINT nFlags, CPoint point)
00680 {
00681         CListCtrl::OnLButtonDown(nFlags, point);
00682 
00683         if(GetFocus() != this) SetFocus();
00684 
00685         KillTimer(1);
00686 
00687         int m_nItemClickedNow, m_nSubItemClickedNow;
00688 
00689         if((m_nItemClickedNow = HitTestEx(point, &m_nSubItemClickedNow)) < 0)
00690         {
00691                 m_nItemClicked = -1;
00692         }
00693         else if(m_nItemClicked == m_nItemClickedNow /*&& m_nSubItemClicked == m_nSubItemClickedNow*/)
00694         {
00695                 m_nSubItemClicked = m_nSubItemClickedNow;
00696 
00697                 LV_DISPINFO dispinfo;
00698                 dispinfo.hdr.hwndFrom = m_hWnd;
00699                 dispinfo.hdr.idFrom = GetDlgCtrlID();
00700                 dispinfo.hdr.code = LVN_BEGINLABELEDIT;
00701                 dispinfo.item.mask = 0;
00702                 dispinfo.item.iItem = m_nItemClicked;
00703                 dispinfo.item.iSubItem = m_nSubItemClicked;
00704                 if(GetParent()->SendMessage(WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&dispinfo))
00705                 {
00706                         if(m_tStartEditingDelay > 0)
00707                         {
00708                                 SetTimer(1, m_tStartEditingDelay, NULL);
00709                         }
00710                         else
00711                         {
00712                                 dispinfo.hdr.code = LVN_DOLABELEDIT;
00713                                 GetParent()->SendMessage(WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&dispinfo);
00714                         }
00715                 }
00716         }
00717         else
00718         {
00719                 m_nItemClicked = m_nItemClickedNow;
00720                 m_nSubItemClicked = m_nSubItemClickedNow;
00721 
00722                 SetItemState(m_nItemClicked, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED); 
00723         }
00724 }
00725 
00726 void CPlayerListCtrl::OnTimer(UINT nIDEvent)
00727 {
00728         if(nIDEvent == 1)
00729         {
00730                 KillTimer(1);
00731 
00732                 UINT flag = LVIS_FOCUSED;
00733                 if((GetItemState(m_nItemClicked, flag) & flag) == flag && m_nSubItemClicked >= 0)
00734                 {
00735                         LV_DISPINFO dispinfo;
00736                         dispinfo.hdr.hwndFrom = m_hWnd;
00737                         dispinfo.hdr.idFrom = GetDlgCtrlID();
00738                         dispinfo.hdr.code = LVN_DOLABELEDIT;
00739                         dispinfo.item.mask = 0;
00740                         dispinfo.item.iItem = m_nItemClicked;
00741                         dispinfo.item.iSubItem = m_nSubItemClicked;
00742                         GetParent()->SendMessage(WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&dispinfo);
00743                 }
00744         }
00745 
00746         CListCtrl::OnTimer(nIDEvent);
00747 }
00748 
00749 void CPlayerListCtrl::OnLButtonDblClk(UINT nFlags, CPoint point)
00750 {
00751         KillTimer(1);
00752 
00753         CListCtrl::OnLButtonDblClk(nFlags, point);
00754 }
00755 
00756 void CPlayerListCtrl::OnLvnMarqueeBegin(NMHDR* pNMHDR, LRESULT* pResult)
00757 {
00758         LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
00759         *pResult = 1;
00760 }
00761 
00762 void CPlayerListCtrl::OnLvnInsertitem(NMHDR* pNMHDR, LRESULT* pResult)
00763 {
00764         LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
00765         m_nItemClicked = -1;
00766         *pResult = 0;
00767 }
00768 
00769 void CPlayerListCtrl::OnLvnDeleteitem(NMHDR* pNMHDR, LRESULT* pResult)
00770 {
00771         LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
00772         m_nItemClicked = -1;
00773         *pResult = 0;
00774 }
00775 
00776 void CPlayerListCtrl::OnEnChangeEdit1()
00777 {
00778         m_fInPlaceDirty = true;
00779 }
00780 
00781 void CPlayerListCtrl::OnCbnDropdownCombo1()
00782 {
00783         CComboBox* pCombo = (CComboBox*)GetDlgItem(IDC_COMBO1);
00784 
00785         CRect ir;
00786         GetItemRect(m_nItemClicked, &ir, LVIR_BOUNDS);
00787 
00788         CRect r;
00789         pCombo->GetWindowRect(r);
00790         ScreenToClient(r);
00791         r.bottom = r.top + ir.Height() + pCombo->GetItemHeight(0)*10;
00792         pCombo->MoveWindow(r);
00793 }
00794 
00795 void CPlayerListCtrl::OnCbnSelendokCombo1()
00796 {
00797         m_fInPlaceDirty = true;
00798 }
00799 
00800 void CPlayerListCtrl::OnLbnSelChangeList1()
00801 {
00802         m_fInPlaceDirty = true;
00803         SetFocus();
00804 }
00805 
00806 BOOL CPlayerListCtrl::OnHdnItemchanging(UINT id, NMHDR* pNMHDR, LRESULT* pResult)
00807 {
00808         LPNMHEADER phdr = reinterpret_cast<LPNMHEADER>(pNMHDR);
00809 //      SetFocus();
00810         *pResult = 0;
00811         return FALSE;
00812 }
00813 
00814 int CPlayerListCtrl::OnToolHitTest(CPoint point, TOOLINFO* pTI) const
00815 {
00816         int col;
00817         int row = HitTestEx(point, &col);
00818         if(row == -1)
00819                 return -1;
00820 
00821         CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0);
00822         int nColumnCount = pHeader->GetItemCount();
00823 
00824         CRect rect;
00825         GetItemRect(row, &rect, LVIR_BOUNDS);
00826 
00827         for(int colnum = 0; colnum < nColumnCount; colnum++)
00828         {
00829                 int colwidth = GetColumnWidth(colnum);
00830 
00831                 if(colnum == col)
00832                 {
00833                         rect.right = rect.left + colwidth; break;
00834                 }
00835 
00836                 rect.left += colwidth;
00837         }
00838 
00839         pTI->hwnd = m_hWnd;
00840         pTI->uId = (UINT)((row<<10)+(col&0x3ff)+1);
00841         pTI->lpszText = LPSTR_TEXTCALLBACK;
00842         pTI->rect = rect;
00843 
00844         return pTI->uId;
00845 }
00846 
00847 BOOL CPlayerListCtrl::OnToolTipNotify(UINT id, NMHDR* pNMHDR, LRESULT* pResult)
00848 {
00849         TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;
00850         TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;
00851 
00852         UINT nID = pNMHDR->idFrom;
00853 
00854         if(pNMHDR->code == TTN_NEEDTEXTA && (pTTTA->uFlags & TTF_IDISHWND)
00855         || pNMHDR->code == TTN_NEEDTEXTW && (pTTTW->uFlags & TTF_IDISHWND))
00856         {
00857                 // idFrom is actually the HWND of the tool
00858                 nID = ::GetDlgCtrlID((HWND)nID);
00859         }
00860 
00861         if(nID == 0)            // Notification in NT from automatically
00862                 return FALSE;           // created tooltip
00863 
00864         if(pNMHDR->code == TTN_NEEDTEXTA) pTTTA->lParam = (LPARAM)m_hWnd;
00865         else if(pNMHDR->code == TTN_NEEDTEXTW) pTTTW->lParam = (LPARAM)m_hWnd;
00866 
00867         *pResult = 0;
00868 
00869         return GetParent()->SendMessage(WM_NOTIFY, id, (LPARAM)pNMHDR);
00870 }
00871 

Generated on Tue Dec 13 14:46:58 2005 for guliverkli by  doxygen 1.4.5