1 //*******************************************************************************
4 // You may use this source code, compile or redistribute it as part of your application
5 // for free. You cannot redistribute it as a part of a software development
6 // library without the agreement of the author. If the sources are
7 // distributed along with the application, you should leave the original
8 // copyright notes in the source code without any changes.
9 // This code can be used WITHOUT ANY WARRANTIES at your own risk.
11 // For the latest updates to this code, check this site:
12 // http://www.masmex.com
15 // Copyright(C) 2000 Philip Oldaker <email: philip@masmex.com>
16 //*******************************************************************************
20 #include "InPlaceEdit.h"
21 #include "TextProgressCtrl.h"
24 #include "cbformats.h"
27 //////////////////////////////////////////////////////
28 // Temporarily changes the view type
29 //////////////////////////////////////////////////////
30 CChangeViewType::CChangeViewType(CUIODListCtrl *pLC,DWORD dwType)
33 m_dwType = m_pLC->GetViewType();
34 m_pLC->SetViewType(dwType);
37 CChangeViewType::~CChangeViewType()
39 m_pLC->SetViewType(m_dwType);
41 //////////////////////////////////////////////////////////
43 LPCTSTR CUIODListCtrl::szEntryHeadings = _T("Headings");
44 LPCTSTR CUIODListCtrl::szEntryStyle = _T("Style");
45 LPCTSTR CUIODListCtrl::szEntryRowSel = _T("RowSelection");
46 LPCTSTR CUIODListCtrl::szEntryViewType = _T("ViewType");
47 LPCTSTR CUIODListCtrl::szEntryColumnSizing = _T("ColumnSizing");
48 LPCTSTR CUIODListCtrl::szEntrySortColumn = _T("SortColumn");
49 LPCTSTR CUIODListCtrl::szEntrySubItems = _T("Columns");
50 LPCTSTR CUIODListCtrl::szEntryColOrder = _T("ColumnOrder");
51 LPCTSTR CUIODListCtrl::szEntryColWidths = _T("ColumnWidths");
53 IMPLEMENT_SERIAL(CUIODListCtrl, CListCtrl, 0)
55 #define COLUMN_DELIMITER '|'
56 #define COLUMN_DELIMITER_STR "|"
58 const int nMaxDigLen = _MAX_INT_DIG*4;
60 //////////////////////////////
64 //////////////////////////////
65 BEGIN_MESSAGE_MAP(CUIODListCtrl, CListCtrl)
66 //{{AFX_MSG_MAP(CUIODListCtrl)
67 ON_MESSAGE(WM_APP_ON_PROPERTIES_KEY,OnAppPropertiesKey)
68 ON_MESSAGE(WM_APP_ON_DELETE_KEY,OnAppDeleteKey)
69 ON_MESSAGE(WM_APP_ON_CONTEXT_MENU_KEY,OnAppContextMenuKey)
70 ON_MESSAGE(WM_APP_ON_BACKSPACE_KEY,OnAppBackspaceKey)
71 ON_MESSAGE(WM_APP_ON_EDIT_KEY,OnAppEditKey)
72 ON_MESSAGE(WM_APP_ON_REFRESH_KEY,OnAppRefreshKey)
74 ON_NOTIFY_REFLECT_EX(LVN_BEGINDRAG, OnBegindrag)
75 ON_NOTIFY_REFLECT_EX(LVN_BEGINRDRAG, OnBeginRDrag)
78 ON_MESSAGE(LVM_SETCOLUMNWIDTH,OnSetColumnWidth)
79 ON_MESSAGE(LVM_DELETEALLITEMS,OnDeleteAllItems)
80 ON_MESSAGE(LVM_DELETEITEM,OnDeleteItem)
81 ON_MESSAGE(LVM_DELETECOLUMN,OnDeleteColumn)
82 ON_MESSAGE(WM_UPDATEHEADERWIDTH,OnUpdateHeaderWidth)
92 ON_COMMAND(ID_UI_VIEW_LARGE_ICONS,OnViewLargeIcons)
93 ON_COMMAND(ID_UI_VIEW_SMALL_ICONS,OnViewSmallIcons)
94 ON_COMMAND(ID_UI_VIEW_DETAILS,OnViewDetails)
95 ON_COMMAND(ID_UI_VIEW_LIST,OnViewList)
96 ON_COMMAND(ID_UI_VIEW_FULL_ROW_SELECTION,OnViewFullRowSelection)
97 ON_COMMAND(ID_UI_VIEW_COLUMN_ORDERING,OnViewColumnOrdering)
98 ON_COMMAND(ID_UI_VIEW_COLUMN_SIZING,OnViewColumnSizing)
99 ON_COMMAND(ID_UI_VIEW_GRIDLINES,OnViewGridlines)
100 ON_COMMAND(ID_UI_VIEW_CHECKBOXES,OnViewCheckboxes)
101 ON_COMMAND(ID_UI_VIEW_TRACK_SELECT,OnViewTrackSelect)
102 ON_COMMAND(ID_UI_VIEW_EDIT_COLUMN,OnViewEditColumn)
103 ON_COMMAND(ID_HEADER_REMOVE_COL,OnHeaderRemoveColumn)
104 ON_COMMAND(ID_HEADER_EDIT_TEXT,OnHeaderEditText)
105 ON_COMMAND(ID_HEADER_RESET,OnHeaderReset)
106 ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipText)
107 ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipText)
109 ON_MESSAGE(LVM_SETIMAGELIST, OnSetImageList)
110 ON_MESSAGE(LVM_SETTEXTCOLOR, OnSetTextColor)
111 ON_MESSAGE(LVM_SETTEXTBKCOLOR, OnSetTextBkColor)
112 ON_MESSAGE(LVM_SETBKCOLOR, OnSetBkColor)
113 ON_MESSAGE(LVM_GETITEMTEXT, OnGetItemText)
115 ON_MESSAGE(WM_APP_OLE_DD_DROP, OnDragDrop)
116 ON_MESSAGE(WM_APP_OLE_DD_DODRAGDROP, OnDDDoDragDrop)
117 ON_MESSAGE(WM_APP_OLE_DD_OVER, OnDragOver)
118 ON_MESSAGE(WM_APP_OLE_DD_ENTER, OnDragEnter)
119 ON_MESSAGE(WM_APP_OLE_DD_LEAVE, OnDragLeave)
123 CUIODListCtrl::CUIODListCtrl(bool bDragDrop)
127 m_bDragDrop = bDragDrop;
134 m_nImageList = LVSIL_SMALL;
140 m_dwExStyle = LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_INFOTIP;
141 m_dwViewType = LVS_REPORT;
142 m_bDelayPaint = false;
143 m_bColumnSizing=TRUE;
144 m_bRClickChangeIconSize = TRUE;
145 // this is toggled on in InitListCtrl
147 m_bClientWidthSel=TRUE;
148 m_bSortAscending=TRUE;
150 m_bEditSubItems = true;
152 m_cxStateImageOffset=0;
154 m_clrText=::GetSysColor(COLOR_WINDOWTEXT);
155 m_clrTextBk=::GetSysColor(COLOR_WINDOW);
156 m_clrBkgnd=::GetSysColor(COLOR_WINDOW);
157 m_strNoItemsMess.LoadString(IDS_NO_ITEMS_MESS);
160 CUIODListCtrl::~CUIODListCtrl()
165 void CUIODListCtrl::AllItemsDeleted()
170 void CUIODListCtrl::Empty()
172 m_objList.DeleteAll();
173 delete []m_pColWidths;
174 delete []m_pColOrder;
175 delete []m_pColTypes;
181 // should be overridden to do any initialization
182 void CUIODListCtrl::Init()
186 void CUIODListCtrl::UpdateEvent(LPARAM lHint,CObject *pHint)
188 GetParent()->SendMessage(WM_APP_UPDATE_ALL_VIEWS,(WPARAM)lHint,(LPARAM)pHint);
191 BOOL CUIODListCtrl::SetViewType(DWORD dwViewType,UINT nFlags)
193 BOOL bRet = ModifyStyle(LVS_TYPEMASK,dwViewType & LVS_TYPEMASK,nFlags);
199 DWORD CUIODListCtrl::GetViewType() const
201 return(GetStyle() & LVS_TYPEMASK);
204 void CUIODListCtrl::ChangeStyle(UINT &dwStyle)
207 dwStyle |= LVS_SHOWSELALWAYS | m_dwViewType;
210 // offsets for first and other columns
211 #define OFFSET_FIRST 2
212 #define OFFSET_OTHER 6
214 void CUIODListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
216 CDC* pDC=CDC::FromHandle(lpDrawItemStruct->hDC);
217 CRect rcItem(lpDrawItemStruct->rcItem);
218 UINT uiFlags=ILD_TRANSPARENT;
219 CImageList* pImageList;
220 int nItem=lpDrawItemStruct->itemID;
221 BOOL bFocus=(GetFocus()==this);
222 COLORREF clrTextSave, clrBkSave;
223 COLORREF clrImage=m_clrBkgnd;
224 static _TCHAR szBuff[MAX_PATH];
230 GetClientRect(rcClient);
231 m_cxClient = rcClient.Width();
236 lvi.mask=LVIF_TEXT | LVIF_IMAGE | LVIF_STATE | LVIF_PARAM;
240 lvi.cchTextMax=sizeof(szBuff);
241 lvi.stateMask=0xFFFF; // get all state flags
244 BOOL bSelected=(bFocus || (GetStyle() & LVS_SHOWSELALWAYS)) && lvi.state & LVIS_SELECTED;
245 bSelected=bSelected || (lvi.state & LVIS_DROPHILITED);
247 // set colors if item is selected
250 GetItemRect(nItem,rcAllLabels,LVIR_BOUNDS);
252 GetItemRect(nItem,rcLabel,LVIR_LABEL);
253 rcAllLabels.left=rcLabel.left;
254 // if(m_bClientWidthSel && rcAllLabels.right<m_cxClient)
255 // rcAllLabels.right=m_cxClient;
256 int BkMode = pDC->SetBkMode(TRANSPARENT);
257 CUIListCtrlData *pData = (CUIListCtrlData*)lvi.lParam;
258 ASSERT(pData->IsKindOf(RUNTIME_CLASS(CUIListCtrlData)));
259 CFont *pOldFont = NULL;
260 if (pData && pData->IsFontSet())
262 pOldFont = pDC->SelectObject((CFont*)pData->GetFont());
268 clrTextSave=pDC->SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));
269 clrBkSave=pDC->SetBkColor(::GetSysColor(COLOR_HIGHLIGHT));
270 pDC->FillRect(rcAllLabels,&CBrush(::GetSysColor(COLOR_HIGHLIGHT)));
274 clrTextSave=pDC->GetTextColor();
275 clrBkSave=pDC->GetBkColor();
279 pDC->SetTextColor(pData->GetTextColor());
280 clrTextBk = pData->GetBkColor();
284 clrTextBk = m_clrTextBk;
285 pDC->SetTextColor(m_clrText);
287 CRect rc(rcAllLabels);
288 pDC->FillRect(rcAllLabels,&CBrush(clrTextBk));
289 pDC->FrameRect(rc,&CBrush(::GetSysColor(COLOR_HIGHLIGHT)));
294 CUIListCtrlData *pData = (CUIListCtrlData *)lvi.lParam;
297 ASSERT(pData->IsKindOf(RUNTIME_CLASS(CUIListCtrlData)));
298 pDC->SetTextColor(pData->GetTextColor());
299 pDC->SetBkColor(pData->GetBkColor());
300 pDC->FillRect(rcAllLabels,&CBrush(pData->GetBkColor()));
303 pDC->FillRect(rcAllLabels,&CBrush(m_clrTextBk));
305 // set color and mask for the icon
307 if(lvi.state & LVIS_CUT)
310 uiFlags|=ILD_BLEND50;
314 clrImage=::GetSysColor(COLOR_HIGHLIGHT);
315 uiFlags|=ILD_BLEND50;
320 UINT nStateImageMask=lvi.state & LVIS_STATEIMAGEMASK;
323 int nImage=(nStateImageMask>>12)-1;
324 pImageList=GetImageList(LVSIL_STATE);
326 pImageList->Draw(pDC,nImage,CPoint(rcItem.left,rcItem.top),ILD_TRANSPARENT);
329 // draw normal and overlay icon
332 GetItemRect(nItem,rcIcon,LVIR_ICON);
334 pImageList=GetImageList(LVSIL_SMALL);
337 UINT nOvlImageMask=lvi.state & LVIS_OVERLAYMASK;
338 if(rcItem.left<rcItem.right-1)
339 ImageList_DrawEx(pImageList->m_hImageList,lvi.iImage,pDC->m_hDC,rcIcon.left,rcIcon.top,16,16,m_clrBkgnd,clrImage,uiFlags | nOvlImageMask);
344 GetItemRect(nItem,rcItem,LVIR_LABEL);
345 rcItem.right-=m_cxStateImageOffset;
347 pszText=MakeShortString(pDC,szBuff,rcItem.right-rcItem.left,2*OFFSET_FIRST);
350 rcLabel.left+=OFFSET_FIRST;
351 rcLabel.right-=OFFSET_FIRST;
353 pDC->DrawText(pszText,-1,rcLabel,DT_LEFT | DT_SINGLELINE | DT_NOPREFIX | DT_NOCLIP | DT_VCENTER);
354 // draw labels for extra columns
357 lvc.mask=LVCF_FMT | LVCF_WIDTH;
359 for(int nColumn=1; GetColumn(nColumn,&lvc); nColumn++)
361 rcItem.left=rcItem.right;
362 rcItem.right+=lvc.cx;
364 int nRetLen=GetItemText(nItem,nColumn,szBuff,sizeof(szBuff));
365 if(nRetLen==0) continue;
367 pszText=MakeShortString(pDC,szBuff,rcItem.right-rcItem.left,2*OFFSET_OTHER);
369 UINT nJustify=DT_LEFT;
373 switch(lvc.fmt & LVCFMT_JUSTIFYMASK)
387 rcLabel.left+=OFFSET_OTHER;
388 rcLabel.right-=OFFSET_OTHER;
390 pDC->DrawText(pszText,-1,rcLabel,nJustify | DT_SINGLELINE | DT_NOPREFIX | DT_NOCLIP | DT_VCENTER);
392 if (pData->IsKindOf(RUNTIME_CLASS(CUIStrListCtrlData)))
394 CUIStrListCtrlData *pStrData = (CUIStrListCtrlData*)pData;
395 if (!pStrData->GetExtraString().IsEmpty())
398 rcLabel.top += (m_cySmallIcon+1);
399 pDC->DrawText(pStrData->GetExtraString(),-1,rcLabel,DT_LEFT | DT_SINGLELINE | DT_NOPREFIX | DT_NOCLIP | DT_VCENTER);
402 // draw focus rectangle if item has focus
404 if(lvi.state & LVIS_FOCUSED && bFocus)
405 pDC->DrawFocusRect(rcAllLabels);
407 // set original colors if item was selected
411 pDC->SetTextColor(clrTextSave);
412 pDC->SetBkColor(clrBkSave);
415 pDC->SelectObject(pOldFont);
416 pDC->SetBkMode(BkMode);
419 LPCTSTR CUIODListCtrl::MakeShortString(CDC* pDC, LPCTSTR lpszLong, int nColumnLen, int nOffset)
421 static const _TCHAR szThreeDots[]=_T("...");
423 int nStringLen=lstrlen(lpszLong);
425 if(nStringLen==0 || pDC->GetTextExtent(lpszLong,nStringLen).cx+nOffset<=nColumnLen)
428 static _TCHAR szShort[MAX_PATH];
430 lstrcpy(szShort,lpszLong);
431 int nAddLen=pDC->GetTextExtent(szThreeDots,sizeof(szThreeDots)).cx;
433 for(int i=nStringLen-1; i>0; i--)
436 if(pDC->GetTextExtent(szShort,i).cx+nOffset+nAddLen<=nColumnLen)
440 lstrcat(szShort,szThreeDots);
445 void CUIODListCtrl::RepaintSelectedItems()
447 CRect rcItem, rcLabel;
449 // invalidate focused item so it can repaint properly
451 int nItem=GetNextItem(-1,LVNI_FOCUSED);
455 GetItemRect(nItem,rcItem,LVIR_BOUNDS);
456 GetItemRect(nItem,rcLabel,LVIR_LABEL);
457 rcItem.left=rcLabel.left;
459 InvalidateRect(rcItem,FALSE);
462 // if selected items should not be preserved, invalidate them
464 // if(!(GetStyle() & LVS_SHOWSELALWAYS))
466 for(nItem=GetNextItem(-1,LVNI_SELECTED);
467 nItem!=-1; nItem=GetNextItem(nItem,LVNI_SELECTED))
469 GetItemRect(nItem,rcItem,LVIR_BOUNDS);
470 GetItemRect(nItem,rcLabel,LVIR_LABEL);
471 rcItem.left=rcLabel.left;
473 InvalidateRect(rcItem,FALSE);
482 void CUIODListCtrl::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItem)
484 lpMeasureItem->itemHeight = (m_cySmallIcon+1)*3;
488 BOOL CUIODListCtrl::OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
495 ASSERT(pResult == NULL);
496 DrawItem((LPDRAWITEMSTRUCT)lParam);
499 ASSERT(pResult == NULL);
500 MeasureItem((LPMEASUREITEMSTRUCT)lParam);
503 pnmh = (LPNMHDR)lParam;
504 if (pnmh->code == LVN_ITEMCHANGED)
506 NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pnmh;
507 if ((pNMListView->uNewState & LVIS_SELECTED) == LVIS_SELECTED &&
508 (pNMListView->uNewState & LVIS_FOCUSED) == LVIS_FOCUSED)
510 return OnSelChanged(pNMListView->iItem,pResult);
513 else if (pnmh->code == LVN_GETDISPINFO)
515 return GetDispInfo((LV_DISPINFO*)pnmh);
517 else if (pnmh->code == LVN_COLUMNCLICK)
519 return ColumnClick((NM_LISTVIEW*)pnmh);
521 else if (pnmh->code == LVN_ENDLABELEDIT)
523 return OnEndLabelEdit(pnmh,pResult);
525 else if (pnmh->code == NM_DBLCLK)
527 return DoubleClick((NM_LISTVIEW*)pnmh);
529 else if (pnmh->code == NM_RETURN)
531 return OnEnter((NM_LISTVIEW*)pnmh);
533 else if (pnmh->code == NM_CUSTOMDRAW)
535 LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)lParam;
536 if(lplvcd->nmcd.dwDrawStage == CDDS_PREPAINT)
538 //tell the control we want pre-paint notifications for each item
539 *pResult = CDRF_NOTIFYITEMDRAW;
542 if (lplvcd->nmcd.dwDrawStage == (CDDS_ITEMPREPAINT | CDDS_SUBITEM))
544 return SubItemPrePaint(lplvcd,pResult);
546 if (lplvcd->nmcd.dwDrawStage == (CDDS_ITEMPOSTPAINT | CDDS_SUBITEM))
548 return SubItemPostPaint(lplvcd,pResult);
550 if (lplvcd->nmcd.dwDrawStage == CDDS_ITEMPREPAINT)
552 return ItemPrePaint(lplvcd,pResult);
554 if (lplvcd->nmcd.dwDrawStage == CDDS_ITEMPOSTPAINT)
556 return ItemPostPaint(lplvcd,pResult);
560 return CWnd::OnChildNotify(message, wParam, lParam, pResult);
563 LRESULT CUIODListCtrl::OnUpdateHeaderWidth(WPARAM wParam,LPARAM lParam)
565 // lParam = column that has changed its width
567 m_pColWidths[nItem] = GetColumnWidth(nItem);
568 GetParent()->SendMessage(WM_HEADERWIDTHCHANGED,(WPARAM)GetSafeHwnd(),nItem);
572 BOOL CUIODListCtrl::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
574 LPNMHDR pnmh = (LPNMHDR)lParam;
575 if ((pnmh->code == HDN_BEGINTRACKW || pnmh->code == HDN_BEGINTRACKA))
577 if (m_bColumnSizing == FALSE)
582 LPNMHEADER phdr = (LPNMHEADER)lParam;
583 if (phdr->pitem->mask & HDI_WIDTH)
587 if ((pnmh->code == HDN_ITEMCHANGINGW || pnmh->code == HDN_ITEMCHANGINGA))
589 LPNMHEADER phdr = (LPNMHEADER)lParam;
591 if ((pnmh->code == HDN_ENDTRACKW || pnmh->code == HDN_ENDTRACKA))
593 HD_NOTIFY *phdn = (HD_NOTIFY*)pnmh;
594 LPNMHEADER phdr = (LPNMHEADER)lParam;
595 if (m_bColumnSizing == TRUE && (phdr->pitem->mask & HDI_WIDTH))
596 PostMessage(WM_UPDATEHEADERWIDTH,(WPARAM)phdn->hdr.hwndFrom,(LPARAM)phdn->iItem);
598 // wParam is zero for Header ctrl
599 if( wParam == 0 && pnmh->code == NM_RCLICK )
601 // Right button was clicked on header
602 CPoint ptScreen(GetMessagePos());
603 CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0);
605 CPoint ptClient(ptScreen);
606 pHeader->ScreenToClient(&ptClient);
608 // Determine the column index
611 for( int i=0; Header_GetItemRect(pHeader->m_hWnd, i, &rcCol); i++ )
613 if( rcCol.PtInRect( ptClient ) )
619 OnRClickHeader(ptScreen,index);
621 return CWnd::OnNotify(wParam,lParam,pResult);
624 DWORD CUIODListCtrl::GetItemData(int nIndex) const
626 if (nIndex != LB_ERR)
628 const CUIListCtrlData* pListObj = GetListCtrlData(nIndex);
630 return pListObj->GetExtData();
635 BOOL CUIODListCtrl::SetItemDataAutoDelete(int nIndex,CObject *pObj)
637 ASSERT_KINDOF(CObject,pObj);
638 return SetItemData(nIndex,(DWORD)pObj,true);
641 BOOL CUIODListCtrl::SetItemData(int nIndex,DWORD dwData,bool bAutoDelete)
643 if (nIndex != LB_ERR)
645 CUIListCtrlData* pListObj = GetListCtrlData(nIndex);
648 pListObj->SetExtData(dwData);
649 pListObj->SetAutoDelete(bAutoDelete);
656 int CUIODListCtrl::SetIcon(int nRow,int nImage)
659 ZeroMemory(&lvItem,sizeof(LV_ITEM));
660 lvItem.mask = LVIF_IMAGE;
662 lvItem.iImage = nImage;
664 return lvItem.iImage;
667 int CUIODListCtrl::SetIcon(int nRow,UINT nIconID)
669 int nImage = GetImageIndex(nIconID);
670 return SetIcon(nRow,nImage);
673 BOOL CUIODListCtrl::SetColumnFormat(int nCol,int fmt)
676 ZeroMemory(&lvCol,sizeof(lvCol));
677 lvCol.mask = LVCF_FMT;
679 return SetColumn(nCol,&lvCol);
682 void CUIODListCtrl::SetTextColor(int nRow, int nCol, COLORREF TextColor)
684 CUIListCtrlData *pData = GetListCtrlData(nRow);
686 pData->SetTextColor(TextColor,nCol);
689 void CUIODListCtrl::SetDefaultTextColor(int nRow,int nCol)
691 CUIListCtrlData *pData = GetListCtrlData(nRow);
693 pData->SetDefaultTextColor(nCol);
696 void CUIODListCtrl::SetBkColor(int nRow,int nCol,COLORREF BkColor)
698 CUIListCtrlData *pData = GetListCtrlData(nRow);
700 pData->SetBkColor(BkColor,nCol);
703 void CUIODListCtrl::SetDefaultBkColor(int nRow,int nCol)
705 CUIListCtrlData *pData = GetListCtrlData(nRow);
707 pData->SetDefaultBkColor(nCol);
710 CUIListCtrlData *CUIODListCtrl::GetListCtrlData(int nItem) const
712 CUIListCtrlData *pData = (CUIListCtrlData *)CListCtrl::GetItemData(nItem);
715 ASSERT(pData->IsKindOf(RUNTIME_CLASS(CUIListCtrlData)));
719 int CUIODListCtrl::AddColumn(LPCTSTR szText)
722 int nCol = FindColumn(szText);
725 nCol = InsertColumn(m_nSubItems,szText);
728 m_strHeadings += COLUMN_DELIMITER_STR;
729 m_strHeadings += szText;
737 int CUIODListCtrl::FindColumn(LPCTSTR pszText)
739 LPCTSTR pszHeadings = m_strHeadings;
741 while (*pszHeadings != '\0')
743 if (*pszHeadings == COLUMN_DELIMITER)
745 if (_tcsnicmp(pszHeadings,pszText,_tcslen(pszText)) == 0)
749 pszHeadings = _tcsinc(pszHeadings);
751 return *pszHeadings == '\0' ? -1 : nCol;
754 BOOL CUIODListCtrl::InitListCtrl(UINT IconID,LPCTSTR szHeadings,LPCTSTR pszProfile)
756 static UINT Icons[2];
760 return InitListCtrl(&Icons[0],szHeadings,pszProfile);
763 BOOL CUIODListCtrl::InitListCtrl(LPCTSTR szHeadings,LPCTSTR pszProfile)
765 static UINT Icons[1];
768 return InitListCtrl(&Icons[0],szHeadings,pszProfile);
771 int CUIODListCtrl::InitListCtrl(const UINT *pIconIDs,LPCTSTR szHeadings,LPCTSTR pszProfile)
773 BOOL bFailed = FALSE;
774 // TODO: Add extra initialization here
777 SetSection(pszProfile);
782 if (m_strHeadings == szHeadings)
785 int nSubItems=m_nSubItems;
786 for(int i=0;i < nSubItems;i++)
791 if (pszProfile == NULL)
793 if (!m_strSection.IsEmpty())
794 pszProfile = m_strSection;
799 // Use profile headings if found
800 if (!m_strHeadings.IsEmpty())
802 if (m_strHeadings != szHeadings)
804 m_strHeadings = szHeadings;
810 SendMessage(LVM_SETEXTENDEDLISTVIEWSTYLE, 0, m_dwExStyle);
812 // at least one image
813 if (pIconIDs && *pIconIDs)
815 // load the icons and add them to the image lists
817 for(i=0;*pIconIDs;i++,pIconIDs++)
819 if (AddIcon(*pIconIDs) == -1)
824 // Now initialize the columns we will need
825 // Initialize the LV_COLUMN structure
826 // the mask specifies that the .fmt, .ex, width, and .subitem members
827 // of the structure are valid,
829 lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
830 lvC.fmt = LVCFMT_LEFT; // left align the column
834 // parse the string, format it and get column count
835 const int MAX_HEADING_LEN = 512;
836 TCHAR szHeadingsCopy[MAX_HEADING_LEN];
837 if (_tcslen(szHeadings) >= MAX_HEADING_LEN-1)
839 _tcsncpy(szHeadingsCopy,szHeadings,MAX_HEADING_LEN-1);
840 szHeadingsCopy[MAX_HEADING_LEN-1] = '\0';
843 _tcscpy(szHeadingsCopy,szHeadings);
844 LPTSTR p = szHeadingsCopy;
848 if (*p == COLUMN_DELIMITER)
857 LPTSTR pszText = szHeadingsCopy;
859 for (int index = 0;index < nCols; index++)
861 lvC.iSubItem = index;
862 lvC.pszText = pszText;
863 // lvC.cx = LVSCW_AUTOSIZE_USEHEADER;
865 if (InsertColumn(index, &lvC) == -1)
867 TRACE(_T("InsertColumn failed\n"));
872 pszText = _tcsinc(pszText);
873 pszText = _tcsinc(pszText); // Runs past the end of the buffer
876 m_strHeadings = szHeadings;
884 SendMessage(LVM_SETCOLUMNORDERARRAY,(WPARAM)nCols,(LPARAM)m_pColOrder);
888 for(int i=0;i < nCols;i++)
890 if (m_pColWidths[i] != 0)
891 SetColumnWidth(i,m_pColWidths[i]);
896 m_pColWidths = new int[nCols];
897 for(int i=0;i < nCols;i++)
899 m_pColWidths[i] = GetColumnWidth(i);
902 if (m_pColTypes == NULL)
904 // set default column types
905 m_pColTypes = new int[nCols];
906 for(int i=0;i < nCols;i++)
908 m_pColTypes[i] = e_Text;
916 void CUIODListCtrl::GetImageLists(CImageList **pILSmall,CImageList **pILLarge)
918 *pILSmall = GetImageList(LVSIL_SMALL);
919 if (*pILSmall == NULL)
922 *pILSmall = GetImageList(LVSIL_SMALL);
924 *pILLarge = GetImageList(LVSIL_NORMAL);
929 void CUIODListCtrl::CreateImageLists()
931 m_cxSmallIcon = ::GetSystemMetrics(SM_CXSMICON);
932 m_cySmallIcon = ::GetSystemMetrics(SM_CYSMICON);
933 m_cxLargeIcon = ::GetSystemMetrics(SM_CXICON);
934 m_cyLargeIcon = ::GetSystemMetrics(SM_CYICON);
935 if (m_ImageSmall.GetSafeHandle() != NULL)
936 m_ImageSmall.DeleteImageList();
937 if (m_ImageLarge.GetSafeHandle() != NULL)
938 m_ImageLarge.DeleteImageList();
939 // create the small icon image list
940 m_ImageSmall.Create(m_cxSmallIcon,
942 ILC_MASK | ILC_COLOR16,
945 // create the large icon image list
946 m_ImageLarge.Create(m_cxLargeIcon,
948 ILC_MASK | ILC_COLOR16,
951 // Associate the image lists with the list view
952 SetImageList(&m_ImageSmall, LVSIL_SMALL);
953 SetImageList(&m_ImageLarge, LVSIL_NORMAL);
956 void CUIODListCtrl::AddExtraString(int nRow,LPCTSTR pszExtraText)
958 CUIStrListCtrlData *pData = (CUIStrListCtrlData *)GetListCtrlData(nRow);
959 ASSERT_KINDOF(CUIStrListCtrlData,pData);
960 pData->AddExtraString(pszExtraText);
963 void CUIODListCtrl::ConvertToTime(CString &str)
965 int nPoint = str.Find(GetDecimalSep());
972 double dSecs = _tcstod(str,&pszStop);
977 int nMins = nSecs / 60;
979 str.Format(_T("%u:%u"),nMins,nSecs);
982 void CUIODListCtrl::AddThousandSeps(CString &str)
987 int nDouble = str.Find(GetDecimalSep());
990 strTemp = str.Left(nDouble);
991 strExp = str.Right(str.GetLength()-nDouble);
995 if (str.Find(GetNegativeSign()) == 0)
997 strNeg = str.Left(1);
998 strTemp = str.Right(str.GetLength()-1);
1003 int len = strTemp.GetLength();
1004 if (len <= 3 || len > nMaxDigLen)
1006 LPCTSTR pBuf = strTemp;
1008 TCHAR tempbuf[nMaxDigLen+1];
1009 LPTSTR pTempBuf = tempbuf;
1010 LPCTSTR pSep = GetThousandSep();
1011 for(int i=0;i < len;i++)
1013 if (i && ((i % 3) == 0))
1015 if (*pTempBuf != *pSep)
1018 pTempBuf = _tcsinc(pTempBuf);
1022 pTempBuf = _tcsinc(pTempBuf);
1023 pBuf = _tcsdec(strTemp,pBuf);
1032 BOOL CUIODListCtrl::AddString(int nRow,int nCol,int nValue,CUIODListCtrl::eColTypes type)
1035 sValue.Format(_T("%d"),nValue);
1036 return AddString(nRow,nCol,sValue,type);
1039 BOOL CUIODListCtrl::AddString(int nRow,int nCol,double dValue,CUIODListCtrl::eColTypes type)
1041 char szBuf[nMaxDigLen];
1042 _gcvt(dValue,_MAX_INT_DIG,szBuf);
1045 return AddString(nRow,nCol,A2W(szBuf),type);
1047 return AddString(nRow,nCol,szBuf,type);
1051 BOOL CUIODListCtrl::AddString(int nRow,int nCol,COleDateTime &dtValue,CUIODListCtrl::eColTypes type)
1053 return AddString(nRow,nCol,dtValue.Format(),type);
1056 BOOL CUIODListCtrl::AddString(int nRow,int nCol,LPCTSTR szItem,CUIODListCtrl::eColTypes type)
1060 TRACE(_T("No rows defined in ODListCtrl\n"));
1063 if (nCol >= m_nSubItems)
1065 TRACE(_T("Tried to add invalid column number(%d) in ODListCtrl\n"),nCol);
1068 SetColType(nCol,type);
1069 // return SetItemText(nRow,nCol/*+m_nImage*/,szItem);
1070 CUIStrListCtrlData *pData = (CUIStrListCtrlData *)GetListCtrlData(nRow);
1071 ASSERT_KINDOF(CUIStrListCtrlData,pData);
1073 if (type == e_NumericFormatComma || type == e_DoubleFormatComma)
1075 CString sBuf(szItem);
1076 AddThousandSeps(sBuf);
1077 ret = pData->AddString(nCol,sBuf);
1079 else if (type == e_NumericFormatTime || type == e_DoubleFormatTime)
1081 CString sBuf(szItem);
1082 ConvertToTime(sBuf);
1083 ret = pData->AddString(nCol,sBuf);
1086 ret = pData->AddString(nCol,szItem);
1090 void CUIODListCtrl::UpdateString(int nRow)
1093 if (GetItemRect(nRow,&rect,LVIR_BOUNDS))
1095 RedrawItems(nRow,nRow);
1100 int CUIODListCtrl::AddCallBackItem(DWORD dwData,int nImage)
1102 if (m_nSubItems == 0)
1104 TRACE(_T("No columns defined in ODListCtrl\n"));
1107 CUIListCtrlData *pListCtrlData = GetNewListCtrlData(dwData,m_nItems);
1108 BOOL ret = InsertItem(LPSTR_TEXTCALLBACK,(LPARAM)pListCtrlData,nImage);
1110 m_objList.Append(pListCtrlData);
1112 delete pListCtrlData;
1113 return ret ? m_nItems-1 : -1;
1116 int CUIODListCtrl::AddTextItem(int nImage)
1118 CUIStrListCtrlData *pListCtrlData = new CUIStrListCtrlData(m_nSubItems);
1119 if (InsertItem(LPSTR_TEXTCALLBACK,(LPARAM)pListCtrlData,nImage))
1121 m_objList.Append(pListCtrlData);
1124 delete pListCtrlData;
1128 int CUIODListCtrl::GetImageIndex(UINT nIconID)
1133 if (!m_mapImageIndex.Lookup(nIconID,nImage))
1135 nImage = AddIcon(nIconID);
1142 int CUIODListCtrl::AddIcon(HICON hIcon,UINT nIconID)
1144 CImageList *pILSmall = NULL;
1145 CImageList *pILLarge = NULL;
1146 GetImageLists(&pILSmall,&pILLarge);
1147 int nSmallIndex = pILSmall->Add(hIcon);
1148 // save the image ID
1150 m_mapImageIndex[nIconID] = nSmallIndex;
1151 int nLargeIndex = pILLarge->Add(hIcon);
1152 if (nSmallIndex == -1 || nLargeIndex == -1)
1154 TRACE(_T("Failed to add icon to image list in CUIODListCtrl\n"));
1161 int CUIODListCtrl::AddIcon(UINT nIconID)
1163 HICON hIcon = AfxGetApp()->LoadIcon(nIconID);
1166 TRACE(_T("LoadIcon failed in CUIODListCtrl\n"));
1169 return AddIcon(hIcon,nIconID);
1173 int CUIODListCtrl::AddIcon(LPCTSTR pszIcon)
1177 if (m_mapImageFile.Lookup(sImageFile,nIndex))
1181 HICON hIcon = (HICON)LoadImage(AfxGetInstanceHandle(),
1184 ::GetSystemMetrics(SM_CXICON),
1185 ::GetSystemMetrics(SM_CYICON),
1189 TRACE(_T("LoadImage(Large) failed in CUIODListCtrl\n"));
1191 HICON hIconSm = (HICON)LoadImage(AfxGetInstanceHandle(),
1194 ::GetSystemMetrics(SM_CXSMICON),
1195 ::GetSystemMetrics(SM_CYSMICON),
1197 if (hIconSm == NULL)
1199 TRACE(_T("LoadImage(Small) failed in CUIODListCtrl\n"));
1201 if (hIcon == NULL && hIconSm == NULL)
1203 CImageList *pILSmall = NULL;
1204 CImageList *pILLarge = NULL;
1205 GetImageLists(&pILSmall,&pILLarge);
1206 int nSmallIndex = pILSmall->Add(hIconSm);
1207 int nLargeIndex = pILLarge->Add(hIcon);
1208 if (nSmallIndex == -1 || nLargeIndex == -1)
1210 TRACE(_T("Failed to add icon to image list in CUIODListCtrl\n"));
1213 sImageFile = pszIcon;
1214 m_mapImageFile[sImageFile] = nSmallIndex;
1218 BOOL CUIODListCtrl::InsertItem(LPTSTR szItem,LPARAM lParam,int nImage)
1221 lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
1225 lvi.iItem = m_nItems;
1227 lvi.pszText = szItem;
1228 lvi.cchTextMax = MAX_TEXT;
1229 lvi.iImage = nImage;
1230 lvi.lParam = lParam;
1231 if (CListCtrl::InsertItem(&lvi) == -1)
1233 TRACE1("Unable to insert item %u into list control\n",m_nItems);
1242 int CUIODListCtrl::SetCurSel(int nSelect)
1244 if (GetItemCount() && SetItemState(nSelect,LVIS_SELECTED | LVIS_FOCUSED,LVIS_SELECTED | LVIS_FOCUSED))
1250 LRESULT CUIODListCtrl::OnSetColumnWidth(WPARAM wParam,LPARAM lParam)
1256 LRESULT CUIODListCtrl::OnDeleteAllItems(WPARAM wParam,LPARAM lParam)
1262 m_objList.DeleteAll();
1263 TRACE0("All items deleted in CUIODListCtrl\n");
1268 CUIListCtrlData *CUIODListCtrl::GetNewListCtrlData(DWORD dwData,int nItem)
1270 CUIListCtrlData *pListCtrlData = new CUIListCtrlData(m_nSubItems);
1271 pListCtrlData->SetExtData(dwData);
1272 return pListCtrlData;
1275 int CUIODListCtrl::FindItem(DWORD dwExtData)
1277 int count = GetItemCount();
1278 CUIListCtrlData *pData;
1279 for(int i=0;i < count;i++)
1281 pData = GetListCtrlData(i);
1282 if (pData->GetExtData() == dwExtData)
1285 return i == count ? -1 : i;
1288 BOOL CUIODListCtrl::GetFullRowSel() const
1290 return(m_bFullRowSel);
1293 DWORD CUIODListCtrl::GetExStyle()
1295 return SendMessage(LVM_GETEXTENDEDLISTVIEWSTYLE);
1298 BOOL CUIODListCtrl::SetExStyle(UINT nStyle,BOOL bModify)
1300 DWORD dwStyle = GetExStyle();
1305 BOOL bRet = SendMessage(LVM_SETEXTENDEDLISTVIEWSTYLE, 0, dwStyle);
1311 void CUIODListCtrl::SetFullRowSel(bool bSet)
1313 // no painting during change
1314 if ((bSet && m_bFullRowSel==TRUE) || (!bSet && m_bFullRowSel==FALSE))
1317 if(!(GetStyle() & LVS_OWNERDRAWFIXED))
1319 SetExStyle(LVS_EX_FULLROWSELECT,m_bFullRowSel);
1321 RedrawItems(GetCurSel(),GetCurSel());
1325 void CUIODListCtrl::SetIconSize(int nImageList)
1327 m_nImageList = nImageList;
1331 GetParent()->ScreenToClient(rc);
1332 rc.bottom++; // Force a WM_MEASUREITEM message
1333 MoveWindow(rc,FALSE);
1334 rc.bottom--; // We really don't want to resize it
1335 MoveWindow(rc,TRUE);
1338 void CUIODListCtrl::ChangeIconSize()
1342 if (m_nImageList == LVSIL_NORMAL)
1343 SetIconSize(LVSIL_SMALL);
1345 SetIconSize(LVSIL_NORMAL);
1348 BOOL CUIODListCtrl::GetDispInfo(LV_DISPINFO *pDispInfo)
1350 CUIStrListCtrlData *pData = (CUIStrListCtrlData*)pDispInfo->item.lParam;
1351 ASSERT_KINDOF(CUIStrListCtrlData,pData);
1352 if (!pData->IsKindOf(RUNTIME_CLASS(CUIStrListCtrlData)))
1354 pDispInfo->item.pszText = pData->GetString(pDispInfo->item.iSubItem);
1358 BOOL CUIODListCtrl::PopupMenuItem(int nItem,int nCol,CMenu *pPopup,CPoint point)
1360 int nCurSel = GetCurSel();
1361 int nSel = GetNextSel(nCurSel);
1362 UINT nPopupID = (nSel == -1 ? m_PopupID : m_MultiPopupID);
1363 if (nPopupID && (nCol == 0 && nItem != -1))
1366 VERIFY(menu.LoadMenu(nPopupID));
1367 CMenu* pMyPopup = menu.GetSubMenu(0);
1368 ASSERT(pMyPopup != NULL);
1369 if (m_pPopupWnd == NULL)
1371 pMyPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, m_pPopupWnd);
1374 return nSel == -1 ? FALSE : TRUE;
1377 int CUIODListCtrl::HitTestEx(CPoint &point, int *col) const
1380 int row = HitTest( point, NULL );
1384 // Make sure that the ListView is in LVS_REPORT
1385 if( (GetWindowLong(m_hWnd, GWL_STYLE) & LVS_TYPEMASK) != LVS_REPORT)
1388 // Get the top and bottom row visible
1389 row = GetTopIndex();
1390 int bottom = row + GetCountPerPage();
1391 if( bottom > GetItemCount() )
1392 bottom = GetItemCount();
1394 // Get the number of columns
1395 CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0);
1396 int nColumnCount = pHeader->GetItemCount();
1398 pHeader->GetClientRect(&rcHeader);
1399 if (point.y >= 0 && point.y <= rcHeader.Height())
1402 // Loop through the visible rows
1403 for( ;row <=bottom;row++)
1405 // Get bounding rect of item and check whether point falls in it.
1407 GetItemRect( row, &rect, LVIR_BOUNDS );
1408 if( rect.PtInRect(point) )
1410 // Now find the column
1411 for( colnum = 0; colnum < nColumnCount; colnum++ )
1413 int colwidth = GetColumnWidth(colnum);
1414 if( point.x >= rect.left
1415 && point.x <= (rect.left + colwidth ) )
1417 if( col ) *col = colnum;
1420 rect.left += colwidth;
1427 CEdit* CUIODListCtrl::EditSubLabel( int nItem, int nCol )
1429 // The returned pointer should not be saved
1430 if (m_bEditSubItems == false || (GetWindowLong(m_hWnd, GWL_STYLE) & LVS_EDITLABELS) != LVS_EDITLABELS)
1435 // Make sure that the item is visible
1436 if( !EnsureVisible( nItem, TRUE ) )
1439 // Make sure that nCol is valid
1440 CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0);
1441 if (pHeader == NULL)
1443 int nColumnCount = pHeader->GetItemCount();
1444 if( nCol >= nColumnCount || GetColumnWidth(nCol) < 5 )
1447 // Get the column offset
1449 for( int i = 0; i < nCol; i++ )
1450 offset += GetColumnWidth( i );
1453 GetItemRect( nItem, &rect, LVIR_BOUNDS );
1455 // Now scroll if we need to expose the column
1457 GetClientRect( &rcClient );
1458 if( offset + rect.left < 0 || offset + rect.left > rcClient.right )
1461 size.cx = offset + rect.left;
1464 rect.left -= size.cx;
1467 // Get Column alignment
1469 lvcol.mask = LVCF_FMT;
1470 GetColumn( nCol, &lvcol );
1472 if((lvcol.fmt&LVCFMT_JUSTIFYMASK) == LVCFMT_LEFT)
1474 else if((lvcol.fmt&LVCFMT_JUSTIFYMASK) == LVCFMT_RIGHT)
1476 else dwStyle = ES_CENTER;
1478 rect.left += offset+4;
1479 rect.right = rect.left + GetColumnWidth( nCol ) - 3 ;
1480 if( rect.right > rcClient.right) rect.right = rcClient.right;
1482 dwStyle |= WS_BORDER|WS_CHILD|WS_VISIBLE|ES_AUTOHSCROLL;
1483 CEdit *pEdit = new CInPlaceEdit(nItem, nCol, GetItemText( nItem, nCol ));
1484 pEdit->Create( dwStyle, rect, this, -1/*IDC_IPEDIT*/ );
1489 void CUIODListCtrl::DeleteProgressBar(int nRow,int nCol)
1491 CUIListCtrlData *pData = GetListCtrlData(nRow);
1494 pData->DestroyCtrl(nCol);
1495 RedrawItems(nRow,nRow);
1499 void CUIODListCtrl::UpdateProgressBar(int nRow,int nCol,int nPos)
1501 CUIListCtrlData *pData = GetListCtrlData(nRow);
1505 CTextProgressCtrl *pCtrl = (CTextProgressCtrl*)pData->GetCtrl(nCol);
1508 pCtrl->SetPos(nPos);
1509 RedrawItems(nRow,nRow);
1513 CTextProgressCtrl *CUIODListCtrl::AddProgressBar(int nItem,int nCol,int nMin,int nMax)
1515 // The returned pointer should not be saved
1516 if (GetViewType() != LVS_REPORT)
1518 CUIListCtrlData *pData = GetListCtrlData(nItem);
1521 CTextProgressCtrl *pCtrl = new CTextProgressCtrl;
1522 pData->SetCtrl(pCtrl,nCol);
1523 pCtrl->SetRange(nMin,nMax);
1530 void CUIODListCtrl::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
1532 if (GetFocus() != this)
1534 CListCtrl::OnHScroll(nSBCode, nPos, pScrollBar);
1537 void CUIODListCtrl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
1539 if (GetFocus() != this)
1541 CListCtrl::OnVScroll(nSBCode, nPos, pScrollBar);
1544 void CUIODListCtrl::OnLButtonDown(UINT nFlags, CPoint point)
1546 CListCtrl::OnLButtonDown(nFlags, point);
1549 BOOL CUIODListCtrl::OnSelChanged(int nItem, LRESULT* pResult)
1555 BOOL CUIODListCtrl::OnEndLabelEdit(NMHDR* pNMHDR, LRESULT* pResult)
1557 LV_DISPINFO *plvDispInfo = (LV_DISPINFO *)pNMHDR;
1558 LV_ITEM *plvItem = &plvDispInfo->item;
1560 if (plvItem->pszText != NULL)
1562 if (plvItem->iItem == -1)
1564 CHeaderCtrl *pHeader = (CHeaderCtrl*)GetDlgItem(0);
1568 GetHeaderText(pHeader,plvItem->iSubItem,strText);
1570 ZeroMemory(&hdItem,sizeof(hdItem));
1571 hdItem.mask = HDI_TEXT;
1572 hdItem.pszText = plvItem->pszText;
1573 hdItem.cchTextMax = lstrlen(plvItem->pszText);
1574 ReplaceString(m_strHeadings,strText,plvItem->pszText);
1575 if (EndLabelEdit(plvItem->iItem,plvItem->iSubItem,plvItem->pszText))
1576 pHeader->SetItem(plvItem->iSubItem,&hdItem);
1581 if (EndLabelEdit(plvItem->iItem,plvItem->iSubItem,plvItem->pszText))
1582 AddString(plvItem->iItem, plvItem->iSubItem, plvItem->pszText);
1589 LRESULT CUIODListCtrl::OnDeleteItem(WPARAM wParam,LPARAM lParam)
1593 TRACE(_T("Item deleted %d\n"),wParam);
1597 LRESULT CUIODListCtrl::OnDeleteColumn(WPARAM wParam,LPARAM lParam)
1601 TRACE(_T("Column deleted %d\n"),wParam);
1605 LRESULT CUIODListCtrl::OnSetImageList(WPARAM wParam, LPARAM lParam)
1607 if((int)wParam==LVSIL_STATE)
1611 if(::ImageList_GetIconSize((HIMAGELIST)lParam,&cx,&cy))
1612 m_cxStateImageOffset=cx;
1614 m_cxStateImageOffset=0;
1620 LRESULT CUIODListCtrl::OnSetTextColor(WPARAM wParam, LPARAM lParam)
1622 m_clrText=(COLORREF)lParam;
1626 LRESULT CUIODListCtrl::OnSetTextBkColor(WPARAM wParam, LPARAM lParam)
1628 m_clrTextBk=(COLORREF)lParam;
1632 LRESULT CUIODListCtrl::OnSetBkColor(WPARAM wParam, LPARAM lParam)
1634 m_clrBkgnd=(COLORREF)lParam;
1638 void CUIODListCtrl::OnSize(UINT nType, int cx, int cy)
1641 CListCtrl::OnSize(nType, cx, cy);
1644 void CUIODListCtrl::OnPaint()
1649 if (GetItemCount() <= 0)
1651 COLORREF clrText = ::GetSysColor(COLOR_WINDOWTEXT);
1652 COLORREF clrTextBk = ::GetSysColor(COLOR_WINDOW);
1656 int nSavedDC = pDC->SaveDC();
1660 ScreenToClient(&rc);
1663 pHC = GetHeaderCtrl();
1667 pHC->GetItemRect(0, &rcH);
1668 rc.top += rcH.bottom;
1672 pDC->SetTextColor(clrText);
1673 pDC->SetBkColor(clrTextBk);
1674 pDC->FillRect(rc, &CBrush(clrTextBk));
1675 pDC->SelectStockObject(ANSI_VAR_FONT);
1676 pDC->DrawText(m_strNoItemsMess, -1, rc,
1677 DT_CENTER | DT_WORDBREAK | DT_NOPREFIX | DT_NOCLIP);
1680 pDC->RestoreDC(nSavedDC);
1683 // Do not call CListCtrl::OnPaint() for painting messages
1684 // in full row select mode, we need to extend the clipping region
1685 // so we can paint a selection all the way to the right
1686 if(m_bClientWidthSel && (GetStyle() & LVS_TYPEMASK)==LVS_REPORT && GetFullRowSel() && (GetStyle() & LVS_OWNERDRAWFIXED))
1689 GetItemRect(0,rcAllLabels,LVIR_BOUNDS);
1691 if(rcAllLabels.right<m_cxClient)
1693 // need to call BeginPaint (in CPaintDC c-tor)
1694 // to get correct clipping rect
1698 dc.GetClipBox(rcClip);
1700 rcClip.left=min(rcAllLabels.right-1,rcClip.left);
1701 // rcClip.right=m_cxClient;
1703 InvalidateRect(rcClip,FALSE);
1704 // EndPaint will be called in CPaintDC d-tor
1708 // CListCtrl::OnPaint();
1711 void CUIODListCtrl::OnSetFocus(CWnd* pOldWnd)
1713 CListCtrl::OnSetFocus(pOldWnd);
1715 if(pOldWnd!=NULL && ::IsWindow(pOldWnd->m_hWnd))
1717 // check if we are getting focus from label edit box
1718 if(pOldWnd!=NULL && pOldWnd->GetParent()==this)
1723 void CUIODListCtrl::OnKillFocus(CWnd* pNewWnd)
1725 CListCtrl::OnKillFocus(pNewWnd);
1727 // check if we are losing focus to label edit box
1728 if (pNewWnd!=NULL && pNewWnd->GetParent()==this)
1732 void CUIODListCtrl::OnRClickHeader(CPoint point,int nColIndex)
1734 m_nColClicked = nColIndex;
1736 VERIFY(menu.LoadMenu(IDR_POPUPMENU_HEADERCTRL));
1737 CMenu* pPopup = menu.GetSubMenu(0);
1738 ASSERT(pPopup != NULL);
1739 pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y,this);
1742 void CUIODListCtrl::OnHeaderRemoveColumn()
1744 if (m_nColClicked != -1)
1746 int nWidth = GetColumnWidth(m_nColClicked);
1749 m_pColWidths[m_nColClicked] = nWidth;
1750 SetColumnWidth(m_nColClicked,0);
1756 void CUIODListCtrl::OnHeaderEditText()
1758 CHeaderCtrl *pHeader = (CHeaderCtrl*)GetDlgItem(0);
1759 if (pHeader == NULL)
1763 int cxy = GetHeaderText(pHeader,m_nColClicked,strText);
1765 for(int i=0;i < m_nSubItems;i++)
1767 if (i == m_nColClicked)
1769 xPos += m_pColWidths[i];
1773 rect.right = rect.left+cxy;
1775 rect.bottom = GetSystemMetrics(SM_CXHSCROLL);
1776 TRACE2("Creating header edit control at left=%d,right=%d\n",rect.left,rect.right);
1777 DWORD dwStyle = WS_BORDER|WS_CHILD|WS_VISIBLE|ES_AUTOHSCROLL;
1778 CEdit *pEdit = new CInPlaceEdit(-1, m_nColClicked, strText);
1779 pEdit->Create( dwStyle, rect, this, -1/*IDC_IPEDIT*/ );
1783 int CUIODListCtrl::GetHeaderText(CHeaderCtrl *pHeader,int nPos,CString &strText)
1786 ZeroMemory(&hdItem,sizeof(hdItem));
1792 hdItem.mask = HDI_TEXT | HDI_WIDTH;
1793 hdItem.cchTextMax = nLen;
1794 hdItem.pszText = strText.GetBufferSetLength(nLen);
1795 pHeader->GetItem(nPos,&hdItem);
1796 nRes = lstrlen(hdItem.pszText);
1797 } while (nRes == nLen-1);
1798 strText.ReleaseBuffer(-1);
1802 void CUIODListCtrl::OnHeaderReset()
1804 for(int i=0;i < m_nSubItems;i++)
1806 SetColumnWidth(i,m_pColWidths[i]);
1811 void CUIODListCtrl::OnContextMenu(CWnd *pWnd,CPoint point)
1813 CPoint ptClient(point);
1814 ScreenToClient(&ptClient);
1816 int nRow = HitTestEx(ptClient,&nCol);
1819 ShowPopupMenu(nRow,nCol,point);
1822 void CUIODListCtrl::ShowPopupMenu(int nRow,int nCol,CPoint point)
1825 VERIFY(menu.LoadMenu(IDR_POPUPMENU_LISTCTRL));
1826 CMenu* pPopup = menu.GetSubMenu(0);
1827 ASSERT(pPopup != NULL);
1830 if (PopupMenuItem(nRow,nCol,pPopup,point))
1832 m_PopupPoint = point;
1833 pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y,this);
1836 void CUIODListCtrl::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu)
1839 if (m_PopupPoint.x == 0 && m_PopupPoint.y == 0)
1841 if (pPopupMenu->GetMenuItemID(0) == ID_HEADER_REMOVE_COL)
1843 if (m_nColClicked == -1)
1845 pPopupMenu->EnableMenuItem(ID_HEADER_EDIT_TEXT,MF_BYCOMMAND | MF_GRAYED);
1846 pPopupMenu->EnableMenuItem(ID_HEADER_RESET,MF_BYCOMMAND | MF_GRAYED);
1850 // These commands are only available in report mode(detail mode)
1851 UINT nEnabled = (GetViewType() == LVS_REPORT) ? MF_ENABLED : MF_GRAYED;
1852 pPopupMenu->EnableMenuItem(ID_UI_VIEW_FULL_ROW_SELECTION,MF_BYCOMMAND | nEnabled);
1853 pPopupMenu->EnableMenuItem(ID_UI_VIEW_GRIDLINES,MF_BYCOMMAND | nEnabled);
1854 pPopupMenu->EnableMenuItem(ID_UI_VIEW_COLUMN_SIZING,MF_BYCOMMAND | nEnabled);
1855 pPopupMenu->EnableMenuItem(ID_UI_VIEW_COLUMN_ORDERING,MF_BYCOMMAND | nEnabled);
1856 if (nEnabled == MF_ENABLED)
1857 pPopupMenu->EnableMenuItem(ID_UI_VIEW_EDIT_COLUMN,MF_BYCOMMAND | (m_bEditSubItems && (GetStyle() & LVS_EDITLABELS)) ? MF_ENABLED : MF_GRAYED);
1859 pPopupMenu->EnableMenuItem(ID_UI_VIEW_EDIT_COLUMN,MF_BYCOMMAND | MF_GRAYED);
1860 // won't work with owner draw list control
1861 if (GetStyle() & LVS_OWNERDRAWFIXED)
1863 pPopupMenu->EnableMenuItem(ID_UI_VIEW_CHECKBOXES,MF_BYCOMMAND | MF_GRAYED);
1865 UINT nIDItem=ID_VIEW_DETAILS;
1866 switch(GetViewType())
1869 nIDItem = ID_UI_VIEW_LARGE_ICONS;
1872 nIDItem = ID_UI_VIEW_SMALL_ICONS;
1875 nIDItem = ID_UI_VIEW_LIST;
1878 nIDItem = ID_UI_VIEW_DETAILS;
1881 pPopupMenu->CheckMenuRadioItem(ID_UI_VIEW_LARGE_ICONS,ID_VIEW_LIST,nIDItem,MF_BYCOMMAND);
1882 DWORD dwExStyle = GetExStyle();
1884 pPopupMenu->CheckMenuItem(ID_UI_VIEW_FULL_ROW_SELECTION,MF_BYCOMMAND | MF_CHECKED);
1885 if (m_bColumnSizing)
1886 pPopupMenu->CheckMenuItem(ID_UI_VIEW_COLUMN_SIZING,MF_BYCOMMAND | MF_CHECKED);
1887 if ((dwExStyle & LVS_EX_HEADERDRAGDROP))
1888 pPopupMenu->CheckMenuItem(ID_UI_VIEW_COLUMN_ORDERING,MF_BYCOMMAND | MF_CHECKED);
1889 if ((dwExStyle & LVS_EX_GRIDLINES))
1890 pPopupMenu->CheckMenuItem(ID_UI_VIEW_GRIDLINES,MF_BYCOMMAND | MF_CHECKED);
1891 if ((dwExStyle & LVS_EX_CHECKBOXES))
1892 pPopupMenu->CheckMenuItem(ID_UI_VIEW_CHECKBOXES,MF_BYCOMMAND | MF_CHECKED);
1893 if ((dwExStyle & LVS_EX_TRACKSELECT))
1894 pPopupMenu->CheckMenuItem(ID_UI_VIEW_TRACK_SELECT,MF_BYCOMMAND | MF_CHECKED);
1897 void CUIODListCtrl::OnViewLargeIcons()
1899 SetViewType(LVS_ICON);
1902 void CUIODListCtrl::OnViewSmallIcons()
1904 SetViewType(LVS_SMALLICON);
1907 void CUIODListCtrl::OnViewDetails()
1909 SetViewType(LVS_REPORT);
1912 void CUIODListCtrl::OnViewList()
1914 SetViewType(LVS_LIST);
1917 void CUIODListCtrl::OnViewFullRowSelection()
1922 void CUIODListCtrl::OnViewTrackSelect()
1924 ToggleTrackSelect();
1927 void CUIODListCtrl::OnViewGridlines()
1932 void CUIODListCtrl::OnViewCheckboxes()
1937 void CUIODListCtrl::OnViewColumnOrdering()
1939 ToggleHeaderDragDrop();
1942 void CUIODListCtrl::OnViewColumnSizing()
1944 ToggleColumnSizing();
1947 void CUIODListCtrl::OnViewEditColumn()
1951 CPoint point(m_PopupPoint);
1952 ScreenToClient(&point);
1953 if (( index = HitTestEx( point, &colnum )) != -1)
1955 UINT flag = LVIS_FOCUSED;
1956 if( (GetItemState( index, flag ) & flag) == flag && colnum > 0)
1958 // Add check for LVS_EDITLABELS
1959 EditSubLabel( index, colnum );
1964 LRESULT CUIODListCtrl::OnGetItemText(WPARAM wParam, LPARAM lParam)
1966 int iItem = (int)wParam;
1967 LV_ITEM *pitem = (LV_ITEM*)lParam;
1968 int nSubItem = pitem->iSubItem;
1969 int nLen = pitem->cchTextMax;
1970 const CUIStrListCtrlData *pData = (CUIStrListCtrlData *)GetListCtrlData(iItem);
1971 // ASSERT_KINDOF(CUIStrListCtrlData,pData);
1972 if (!pData->IsKindOf(RUNTIME_CLASS(CUIStrListCtrlData)))
1975 di.hdr.hwndFrom = GetSafeHwnd();
1976 di.hdr.code = LVN_GETDISPINFO;
1977 memcpy(&di.item,pitem,sizeof(LVITEM));
1978 di.item.mask = LVIF_TEXT;
1979 #if 1 // bugfix by Rex Lee
1980 di.item.iItem = iItem;
1982 SendMessage(WM_NOTIFY,0,(LPARAM)&di);
1983 _tcsncpy(pitem->pszText,di.item.pszText,nLen);
1987 LPTSTR pStr = ((CUIStrListCtrlData *)pData)->GetString(nSubItem);
1990 _tcsncpy(pitem->pszText,pStr,nLen);
1991 nLen = min(lstrlen(pStr)+1,nLen);
1992 pitem->pszText[nLen-1] = '\0';
1999 int CUIODListCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
2001 if (CListCtrl::OnCreate(lpCreateStruct) == -1)
2004 // TODO: Add your specialized creation code here
2005 RegisterDropTarget();
2010 int CALLBACK CompareFunc(LPARAM lParam1,LPARAM lParam2,LPARAM lParamSort);
2012 PFNLVCOMPARE CUIODListCtrl::GetCompareFunc()
2017 BOOL CUIODListCtrl::ColumnClick(NM_LISTVIEW* pNMListView)
2019 if (pNMListView->iSubItem != m_nSortColumn)
2020 m_bSortAscending = TRUE;
2022 m_bSortAscending = !m_bSortAscending;
2023 m_nSortColumn = pNMListView->iSubItem;
2025 m_HeaderCtrl.SetSortImage(m_nSortColumn,m_bSortAscending);
2026 ASSERT(m_pColTypes);
2027 CUIODListCtrlSortInfo sortinfo(pNMListView->iSubItem,m_pColTypes[pNMListView->iSubItem],m_bSortAscending);
2028 SortItems(GetCompareFunc(),(DWORD)&sortinfo);
2029 int item = GetCurSel();
2030 EnsureVisible(item,0);
2034 ///////////////////////////////////////////////
2035 // static callback for sorting when the header is clicked in report mode
2036 int CALLBACK CompareFunc(LPARAM lParam1,LPARAM lParam2,LPARAM lParamSort)
2038 CUIStrListCtrlData *pData1 = (CUIStrListCtrlData*)lParam1;
2039 CUIStrListCtrlData *pData2 = (CUIStrListCtrlData*)lParam2;
2042 ASSERT_KINDOF(CUIStrListCtrlData,pData1);
2043 ASSERT_KINDOF(CUIStrListCtrlData,pData2);
2044 CUIODListCtrlSortInfo *pSortInfo = (CUIODListCtrlSortInfo *)lParamSort;
2046 switch(pSortInfo->GetColType())
2048 case CUIODListCtrl::e_DateTime:
2051 CString str1(pData1->GetString(pSortInfo->GetColumn()));
2052 if (!str1.IsEmpty())
2053 time1.ParseDateTime(str1);
2055 CString str2(pData2->GetString(pSortInfo->GetColumn()));
2056 if (!str2.IsEmpty())
2057 time2.ParseDateTime(str2);
2060 else if (time1 < time2)
2064 case CUIODListCtrl::e_NumericFormat:
2066 int num1 = _ttoi(CUIODListCtrl::StripNonNumeric((LPCTSTR)pData1->GetString(pSortInfo->GetColumn()),CUIODListCtrl::e_Numeric));
2067 int num2 = _ttoi(CUIODListCtrl::StripNonNumeric((LPCTSTR)pData2->GetString(pSortInfo->GetColumn()),CUIODListCtrl::e_Numeric));
2071 case CUIODListCtrl::e_Numeric:
2073 int num1 = _ttoi((LPCTSTR)pData1->GetString(pSortInfo->GetColumn()));
2074 int num2 = _ttoi((LPCTSTR)pData2->GetString(pSortInfo->GetColumn()));
2078 case CUIODListCtrl::e_DoubleFormat:
2080 double num1 = _tcstod(CUIODListCtrl::StripNonNumeric((LPCTSTR)pData1->GetString(pSortInfo->GetColumn()),CUIODListCtrl::e_Double),NULL);
2081 double num2 = _tcstod(CUIODListCtrl::StripNonNumeric((LPCTSTR)pData2->GetString(pSortInfo->GetColumn()),CUIODListCtrl::e_Double),NULL);
2084 else if (num1 < num2)
2088 case CUIODListCtrl::e_Double:
2090 double num1 = _tcstod((LPCTSTR)pData1->GetString(pSortInfo->GetColumn()),NULL);
2091 double num2 = _tcstod((LPCTSTR)pData2->GetString(pSortInfo->GetColumn()),NULL);
2094 else if (num1 < num2)
2098 case CUIODListCtrl::e_Text:
2100 ret = CompareString(LOCALE_USER_DEFAULT,NORM_IGNORECASE | NORM_IGNOREKANATYPE,
2101 (LPCTSTR)pData1->GetString(pSortInfo->GetColumn()),
2102 pData1->GetStringLen(pSortInfo->GetColumn()),
2103 (LPCTSTR)pData2->GetString(pSortInfo->GetColumn()),
2104 pData2->GetStringLen(pSortInfo->GetColumn())) - 2;
2107 if (!pSortInfo->Ascending())
2112 void CUIODListCtrl::ReplaceString(CString &rStr,LPCTSTR pszOldText,LPCTSTR pszNewText)
2114 int nPos = rStr.Find(pszOldText);
2118 strLeft = rStr.Left(nPos);
2119 CString strRight(rStr.Right(rStr.GetLength()-(nPos+lstrlen(pszOldText))));
2120 strLeft += pszNewText;
2121 strLeft += strRight;
2126 void CUIODListCtrl::Sort()
2128 ASSERT(m_pColTypes);
2129 CUIODListCtrlSortInfo sortinfo(m_nSortColumn,m_pColTypes[m_nSortColumn],m_bSortAscending);
2130 SortItems(GetCompareFunc(),(DWORD)&sortinfo);
2131 m_HeaderCtrl.SetSortImage(m_nSortColumn,m_bSortAscending);
2132 TRACE1("Sorting column %d\n",m_nSortColumn);
2135 void CUIODListCtrl::SetColFont(int nRow,int nCol,CFont *pFont)
2137 CUIListCtrlData* pListObj = GetListCtrlData(nRow);
2142 pListObj->SetFont(pFont,nCol);
2146 void CUIODListCtrl::SetRowFont(int nRow,CFont *pFont)
2148 CUIListCtrlData* pListObj = GetListCtrlData(nRow);
2153 pListObj->SetFont(pFont);
2157 void CUIODListCtrl::SetColBold(int nRow,int nCol,BOOL bBold)
2159 CUIListCtrlData* pListObj = GetListCtrlData(nRow);
2162 if (!pListObj->IsFontSet(nCol))
2164 pListObj->SetFont(GetFont(),nCol);
2166 const CFont *pFont = pListObj->GetFont(nCol);
2168 ((CFont*)pFont)->GetLogFont(&lf);
2169 lf.lfWeight = bBold ? FW_BOLD : FW_NORMAL;
2171 font.CreateFontIndirect(&lf);
2172 pListObj->SetFont(&font,nCol);
2174 RedrawItems(nRow,nRow);
2179 void CUIODListCtrl::SetRowBold(int nRow,BOOL bBold)
2181 CUIListCtrlData* pListObj = GetListCtrlData(nRow);
2184 if (!pListObj->IsFontSet(-1))
2186 pListObj->SetFont(GetFont());
2188 const CFont *pFont = pListObj->GetFont();
2190 ((CFont*)pFont)->GetLogFont(&lf);
2191 lf.lfWeight = bBold ? FW_BOLD : FW_NORMAL;
2193 font.CreateFontIndirect(&lf);
2194 pListObj->SetFont(&font);
2196 RedrawItems(nRow,nRow);
2201 BOOL CUIODListCtrl::SubItemPostPaint(LPNMLVCUSTOMDRAW lplvcd,LRESULT *pResult)
2205 CDC *pDC = CDC::FromHandle(lplvcd->nmcd.hdc);
2206 pDC->SelectObject(CFont::FromHandle(m_hOrigFont));
2212 BOOL CUIODListCtrl::SubItemPrePaint(LPNMLVCUSTOMDRAW lplvcd,LRESULT *pResult)
2214 *pResult = CDRF_DODEFAULT;
2215 int nRow = lplvcd->nmcd.dwItemSpec;
2216 int nCol = lplvcd->iSubItem;
2217 CUIListCtrlData* pListObj = GetListCtrlData(nRow);
2218 if (pListObj == NULL)
2220 *pResult = CDRF_NOTIFYPOSTPAINT;
2221 lplvcd->clrText = pListObj->GetTextColor(nCol);
2222 lplvcd->clrTextBk = pListObj->GetBkColor(nCol);
2223 if (pListObj->IsFontSet(nCol))
2225 CDC *pDC = CDC::FromHandle(lplvcd->nmcd.hdc);
2226 CFont *pOldFont = pDC->SelectObject((CFont*)pListObj->GetFont(nCol));
2227 m_hOrigFont = (HFONT)pOldFont;
2228 *pResult |= CDRF_NEWFONT;
2230 CTextProgressCtrl *pWnd = (CTextProgressCtrl*)pListObj->GetCtrl(nCol);
2234 GetItemRect(nRow,rcItem,LVIR_LABEL);
2235 rcItem.left = lplvcd->nmcd.rc.left;
2236 rcItem.right = lplvcd->nmcd.rc.right;
2237 CDC *pDC = CDC::FromHandle(lplvcd->nmcd.hdc);
2238 pWnd->DoPaint(pDC,rcItem,GetItemState(nRow,LVIS_SELECTED) == LVIS_SELECTED);
2239 *pResult = CDRF_SKIPDEFAULT;
2243 BOOL CUIODListCtrl::ItemPrePaint(LPNMLVCUSTOMDRAW lplvcd,LRESULT *pResult)
2245 *pResult = CDRF_NOTIFYSUBITEMDRAW;
2249 BOOL CUIODListCtrl::ItemPostPaint(LPNMLVCUSTOMDRAW lplvcd,LRESULT *pResult)
2251 *pResult = CDRF_DODEFAULT;
2255 ///////////////////////////////////////////////
2257 ///////////////////////////////////////////////
2258 void CUIODListCtrl::SetSection(LPCTSTR pszSection)
2260 if (pszSection == NULL)
2261 m_strSection.Empty();
2265 m_strSection = _T("UIODListControl\\");
2266 m_strSection += pszSection;
2270 LPCTSTR CUIODListCtrl::GetSection() const
2272 return m_strSection;
2275 void CUIODListCtrl::LoadProfile()
2277 if (m_strSection.IsEmpty())
2279 CWinApp *pApp = AfxGetApp();
2282 LPCTSTR pszSection = GetSection();
2284 m_strHeadings = pApp->GetProfileString(pszSection,szEntryHeadings);
2285 m_dwExStyle = pApp->GetProfileInt(pszSection,szEntryStyle,m_dwExStyle);
2286 m_bFullRowSel = pApp->GetProfileInt(pszSection,szEntryRowSel,m_bFullRowSel);
2287 m_dwViewType = pApp->GetProfileInt(pszSection,szEntryViewType,m_dwViewType);
2288 m_bColumnSizing = pApp->GetProfileInt(pszSection,szEntryColumnSizing,m_bColumnSizing);
2289 m_nSortColumn = pApp->GetProfileInt(pszSection,szEntrySortColumn,m_nSortColumn);
2290 int nSubItems = pApp->GetProfileInt(pszSection,szEntrySubItems,0);
2293 delete []m_pColOrder;
2294 delete []m_pColWidths;
2295 m_pColOrder = new int[nSubItems];
2296 m_pColWidths = new int[nSubItems];
2298 for(int i=0;i < nSubItems;i++)
2300 strEntry.Format(_T("%s%d"),szEntryColOrder,i+1);
2301 m_pColOrder[i] = pApp->GetProfileInt(pszSection,strEntry,0);
2302 strEntry.Format(_T("%s%d"),szEntryColWidths,i+1);
2303 m_pColWidths[i] = pApp->GetProfileInt(pszSection,strEntry,0);
2308 void CUIODListCtrl::SaveProfile()
2310 if (m_strSection.IsEmpty())
2312 CWinApp *pApp = AfxGetApp();
2315 LPCTSTR pszSection = GetSection();
2317 pApp->WriteProfileString(pszSection,szEntryHeadings,m_strHeadings);
2318 pApp->WriteProfileInt(pszSection,szEntryStyle,SendMessage(LVM_GETEXTENDEDLISTVIEWSTYLE));
2319 pApp->WriteProfileInt(pszSection,szEntryRowSel,m_bFullRowSel);
2320 pApp->WriteProfileInt(pszSection,szEntryViewType,GetViewType());
2321 pApp->WriteProfileInt(pszSection,szEntryColumnSizing,m_bColumnSizing);
2322 pApp->WriteProfileInt(pszSection,szEntrySubItems,m_nSubItems);
2323 pApp->WriteProfileInt(pszSection,szEntrySortColumn,m_nSortColumn);
2326 delete []m_pColOrder;
2327 m_pColOrder = new int[m_nSubItems],0;
2328 SendMessage(LVM_GETCOLUMNORDERARRAY,(WPARAM)m_nSubItems,(LPARAM)m_pColOrder);
2330 for(int i=0;i < m_nSubItems;i++)
2332 strEntry.Format(_T("%s%d"),szEntryColOrder,i+1);
2333 pApp->WriteProfileInt(pszSection,strEntry,m_pColOrder[i]);
2336 strEntry.Format(_T("%s%d"),szEntryColWidths,i+1);
2337 pApp->WriteProfileInt(pszSection,strEntry,m_pColWidths[i]);
2343 void CUIODListCtrl::Serialize(CArchive& ar)
2347 ar << m_strHeadings;
2349 m_pColOrder = new int[m_nSubItems];
2350 SendMessage(LVM_GETCOLUMNORDERARRAY,(WPARAM)m_nSubItems,(LPARAM)m_pColOrder);
2351 for(int i=0;i < m_nSubItems;i++)
2353 ar << (int)m_pColOrder[i];
2354 ar << (int)GetColumnWidth(i);
2356 delete []m_pColOrder;
2358 ar << SendMessage(LVM_GETEXTENDEDLISTVIEWSTYLE);
2360 ar << m_bFullRowSel;
2361 ar << m_bColumnSizing;
2365 ar >> m_strHeadings;
2367 delete []m_pColOrder;
2368 delete []m_pColWidths;
2369 m_pColOrder = new int[m_nSubItems];
2370 m_pColWidths = new int[m_nSubItems];
2371 for(int i=0;i < m_nSubItems;i++)
2373 ar >> (int)m_pColOrder[i];
2374 ar >> (int)m_pColWidths[i];
2377 ar >> m_bFullRowSel;
2379 ar >> m_bColumnSizing;
2382 /////////////////////////////////////////////////////////////////
2383 // OLE drag and drop
2384 /////////////////////////////////////////////////////////////////
2386 /////////////////////////////////////////////////////////////////////////////
2388 // CUIODListCtrl message handlers
2389 #include "UIDragImage.h"
2391 BOOL CUIODListCtrl::OnBeginRDrag(NMHDR* pNMHDR, LRESULT* pResult)
2393 NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
2394 // TODO: Add your control notification handler code here
2396 DoOleDrag(pNMListView,true);
2400 BOOL CUIODListCtrl::OnBegindrag(NMHDR* pNMHDR, LRESULT* pResult)
2402 NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
2403 // TODO: Add your control notification handler code here
2405 DoOleDrag(pNMListView,false);
2409 void CUIODListCtrl::DoOleDrag(NM_LISTVIEW* pNMListView,bool bRightMenu)
2411 int nSelected = GetSelectedCount();
2412 if (nSelected == 0 || pNMListView->iItem == -1)
2417 // View type LVS_ICON etc
2418 int nType = GetViewType();
2419 // 2 ints(nSelected,nType) + ImageData + CRect
2420 HANDLE hData = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE,sizeof(int)*2+sizeof(DD_ImageData)*nSelected+sizeof(CRect));
2421 int *pData = (int*)::GlobalLock(hData);
2423 *pData++ = nSelected;
2424 // add the selections
2425 DD_ImageData *pImageData = (DD_ImageData*)pData;
2429 int iItem = pNMListView->iItem;
2430 GetItemRect(iItem,rcItem,LVIR_LABEL);
2431 GetItemRect(iItem,rcIcon,LVIR_ICON);
2432 rcTotalItem.left = rcIcon.left;
2433 rcTotalItem.top = rcIcon.top;
2434 rcTotalItem.right = rcIcon.right+rcItem.right;
2435 rcTotalItem.bottom = 0;
2436 CPoint point(pNMListView->ptAction);
2439 iItem = GetNextSel(-1);
2440 int *pRows = new int[nSelected+1];
2442 for(int i=1;iItem != -1;i++)
2444 GetItemRect(iItem,rcItem,LVIR_LABEL);
2445 GetItemRect(iItem,rcIcon,LVIR_ICON);
2446 ptHitTest.x = rcItem.left;
2447 ptHitTest.y = rcItem.top;
2448 HitTest(ptHitTest,&flag);
2449 if ((flag & LVHT_BELOW) != LVHT_BELOW && (flag & LVHT_ABOVE) != LVHT_ABOVE)
2451 pImageData->m_rcItem = rcItem;
2452 pImageData->m_rcIcon = rcIcon;
2453 pImageData->m_ptDrag = point;
2454 rcTotalItem.bottom += rcIcon.bottom;
2457 CCF_String ccfText(GetItemText(iItem,0));
2458 CWDClipboardData::Instance()->SetData(&m_OleDataSource,&ccfText,CWDClipboardData::e_cfString);
2459 iItem = GetNextSel(iItem);
2462 pData = (int*)pImageData;
2463 *pData++ = rcTotalItem.left;
2464 *pData++ = rcTotalItem.right;
2465 *pData++ = rcTotalItem.top;
2466 *pData = rcTotalItem.bottom;
2467 ::GlobalUnlock (hData);
2468 m_OleDataSource.CacheGlobalData(m_OleDropTarget.GetClipboardFormat(), hData);
2470 rm.SetRightDrag(bRightMenu);
2471 CWDClipboardData::Instance()->SetData(&m_OleDataSource,&rm,CWDClipboardData::e_cfRightMenu);
2472 DWORD dwDragEffect = SendMessage(WM_APP_OLE_DD_DODRAGDROP,(WPARAM)pRows,(LPARAM)&m_OleDataSource);
2473 if (dwDragEffect == 0)
2474 dwDragEffect = GetParent()->SendMessage(WM_APP_OLE_DD_DODRAGDROP,(WPARAM)pRows,(LPARAM)&m_OleDataSource);
2477 // Start the DragDrop
2478 DROPEFFECT effect = m_OleDataSource.DoDragDrop(dwDragEffect,NULL);
2480 m_OleDataSource.Empty();
2485 void CUIODListCtrl::RegisterDropTarget()
2489 VERIFY(m_OleDropTarget.Register(this));
2494 DROPEFFECT CUIODListCtrl::SelectCurrentTarget(CDD_OleDropTargetInfo *pInfo)
2496 // No method to select a list ctrl item during drag and drop
2498 int iItem = HitTest(pInfo->GetPoint(), &flags);
2499 pInfo->SetItem(iItem);
2501 m_iItemDrop = iItem;
2502 LRESULT lResult = SendMessage(WM_APP_OLE_DD_OVER,(WPARAM)pInfo);
2505 lResult = GetParent()->SendMessage(WM_APP_OLE_DD_OVER,(WPARAM)pInfo);
2507 // returns 0 if allowed (so the default is allowed)
2510 // return what was ever set
2511 return pInfo->GetDropEffect();
2513 return DROPEFFECT_NONE;
2516 ///////////////////////////////////////////////
2518 void CUIODListCtrl::PostNcDestroy()
2520 // TODO: Add your specialized code here and/or call the base class
2522 CListCtrl::PostNcDestroy();
2525 void CUIODListCtrl::OnDestroy()
2529 CListCtrl::OnDestroy();
2531 // TODO: Add your message handler code here
2534 void CUIODListCtrl::PreSubclassWindow()
2536 CListCtrl::PreSubclassWindow();
2538 // Add initialization code
2539 EnableToolTips(m_bToolTips);
2543 int CUIODListCtrl::OnToolHitTest(CPoint point, TOOLINFO * pTI) const
2547 row = CellRectFromPoint(point, &cellrect, &col );
2551 if (GetStringWidth(GetItemText(row,col))-10 < cellrect.Width())
2554 CToolTipCtrl* pToolTip = AfxGetThreadState()->m_pToolTip;
2555 pToolTip->SendMessage(TTM_SETDELAYTIME,TTDT_AUTOPOP,10000);
2556 pToolTip->SendMessage(TTM_SETMAXTIPWIDTH,0,30);
2559 pTI->uId = (UINT)((row<<10)+(col&0x3ff)+1);
2560 pTI->lpszText = LPSTR_TEXTCALLBACK;
2562 pTI->rect = cellrect;
2566 // CellRectFromPoint - Determine the row, col and bounding rect of a cell
2567 // Returns - row index on success, -1 otherwise// point - point to be tested.
2568 // cellrect - to hold the bounding rect// col - to hold the column index
2569 int CUIODListCtrl::CellRectFromPoint(CPoint & point, RECT * cellrect, int * col) const
2572 // Make sure that the ListView is in LVS_REPORT
2573 if( (GetWindowLong(m_hWnd, GWL_STYLE) & LVS_TYPEMASK) != LVS_REPORT)
2575 // Get the top and bottom row visible
2576 int row = GetTopIndex();
2577 int bottom = row + GetCountPerPage();
2578 if( bottom > GetItemCount() )
2579 bottom = GetItemCount();
2580 // Get the number of columns
2581 CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0);
2582 int nColumnCount = pHeader->GetItemCount();
2583 // Loop through the visible rows
2584 for( ;row <=bottom;row++)
2586 // Get bounding rect of item and check whether point falls in it.
2588 GetItemRect( row, &rect, LVIR_BOUNDS );
2589 if( rect.PtInRect(point) )
2591 // Now find the column
2592 for( colnum = 0; colnum < nColumnCount; colnum++ )
2594 int colwidth = GetColumnWidth(colnum);
2595 if( point.x >= rect.left && point.x <= (rect.left + colwidth ) )
2598 GetClientRect( &rectClient );
2601 CUIODListCtrl *pThis = const_cast<CUIODListCtrl*>(this);
2602 if (m_pColOrder && pThis->SendMessage(LVM_GETCOLUMNORDERARRAY,(WPARAM)m_nSubItems,(LPARAM)m_pColOrder))
2603 *col = m_pColOrder[colnum];
2607 rect.right = rect.left + colwidth;
2608 // Make sure that the right extent does not exceed
2610 if( rect.right > rectClient.right )
2611 rect.right = rectClient.right;
2615 rect.left += colwidth;
2622 BOOL CUIODListCtrl::OnToolTipText( UINT id, NMHDR * pNMHDR, LRESULT * pResult )
2624 // need to handle both ANSI and UNICODE versions of the message
2625 static WCHAR szToolTipW[256];
2626 static char szToolTipA[256];
2627 TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;
2628 TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;
2629 UINT nID = pNMHDR->idFrom;
2632 // Notification in NT from automatically
2636 int row = ((nID-1) >> 10) & 0x3fffff;
2637 int col = (nID-1) & 0x3ff;
2638 m_sToolTipText = GetItemText( row, col );
2640 // if (pNMHDR->code == TTN_NEEDTEXTA)
2641 // lstrcpyn(pTTTA->szText, strTipText, 80);
2643 // _mbstowcsz(pTTTW->szText, strTipText, 80);
2644 if (pNMHDR->code == TTN_NEEDTEXTA)
2646 pTTTA->lpszText = (LPSTR)(LPCSTR)m_sToolTipText;
2650 _mbstowcsz(szToolTipW, m_sToolTipText, sizeof(szToolTipW)-1);
2651 pTTTW->lpszText = szToolTipW;
2654 if (pNMHDR->code == TTN_NEEDTEXTW)
2656 pTTTW->lpszText = (LPWSTR)(LPCWSTR)m_sToolTipText;
2660 _wcstombsz(szToolTipA, m_sToolTipText, sizeof(szToolTipA)-1);
2661 pTTTA->lpszText = szToolTipA;
2663 // pTTTA->lpszText = (LPTSTR)(LPCTSTR)m_sToolTipText;
2664 // if (pNMHDR->code == TTN_NEEDTEXTA)
2665 // _wcstombsz(pTTTA->szText, strTipText, 80);
2667 // lstrcpyn(pTTTW->szText, strTipText, 80);
2671 // message was handled
2674 CODHeaderCtrl::CODHeaderCtrl()
2679 CODHeaderCtrl::~CODHeaderCtrl()
2683 int CODHeaderCtrl::SetSortImage(int nCol, BOOL bAsc)
2687 int nPrevCol = m_nSortCol;
2691 // Change the item to ownder drawn
2693 hditem.mask = HDI_FORMAT;
2694 GetItem( nCol, &hditem );
2695 hditem.fmt |= HDF_OWNERDRAW;
2696 SetItem( nCol, &hditem ); // Invalidate header control so that it gets redrawn
2701 void CODHeaderCtrl::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )
2705 dc.Attach( lpDrawItemStruct->hDC );
2707 // Get the column rect
2708 CRect rcLabel( lpDrawItemStruct->rcItem );
2711 int nSavedDC = dc.SaveDC();
2713 // Set clipping region to limit drawing within column
2715 rgn.CreateRectRgnIndirect( &rcLabel );
2716 dc.SelectObject( &rgn );
2719 // Draw the background
2720 dc.FillRect(rcLabel, &CBrush(::GetSysColor(COLOR_3DFACE)));
2722 // Labels are offset by a certain amount
2723 // This offset is related to the width of a space character
2724 int offset = dc.GetTextExtent(_T(" "), 1 ).cx*2;
2727 // Get the column text and format
2731 hditem.mask = HDI_TEXT | HDI_FORMAT;
2732 hditem.pszText = buf;
2733 hditem.cchTextMax = 255;
2735 GetItem( lpDrawItemStruct->itemID, &hditem );
2737 // Determine format for drawing column label
2738 UINT uFormat = DT_SINGLELINE | DT_NOPREFIX | DT_NOCLIP
2739 | DT_VCENTER | DT_END_ELLIPSIS ;
2741 if( hditem.fmt & HDF_CENTER)
2742 uFormat |= DT_CENTER;
2743 else if( hditem.fmt & HDF_RIGHT)
2744 uFormat |= DT_RIGHT;
2748 // Adjust the rect if the mouse button is pressed on it
2749 if( lpDrawItemStruct->itemState == ODS_SELECTED )
2756 // Adjust the rect further if Sort arrow is to be displayed
2757 if( lpDrawItemStruct->itemID == (UINT)m_nSortCol )
2759 rcLabel.right -= 3 * offset;
2762 rcLabel.left += offset;
2763 rcLabel.right -= offset;
2765 // Draw column label
2766 if( rcLabel.left < rcLabel.right )
2767 dc.DrawText(buf,-1,rcLabel, uFormat);
2769 // Draw the Sort arrow
2770 if( lpDrawItemStruct->itemID == (UINT)m_nSortCol )
2772 CRect rcIcon( lpDrawItemStruct->rcItem );
2774 // Set up pens to use for drawing the triangle
2775 CPen penLight(PS_SOLID, 1, GetSysColor(COLOR_3DHILIGHT));
2776 CPen penShadow(PS_SOLID, 1, GetSysColor(COLOR_3DSHADOW));
2777 CPen *pOldPen = dc.SelectObject( &penLight );
2781 // Draw triangle pointing upwards
2782 dc.MoveTo( rcIcon.right - 2*offset, offset-1);
2783 dc.LineTo( rcIcon.right - 3*offset/2, rcIcon.bottom - offset );
2784 dc.LineTo( rcIcon.right - 5*offset/2-2, rcIcon.bottom - offset );
2785 dc.MoveTo( rcIcon.right - 5*offset/2-1, rcIcon.bottom - offset-1 );
2787 dc.SelectObject( &penShadow );
2788 dc.LineTo( rcIcon.right - 2*offset, offset-2);
2792 // Draw triangle pointing downwords
2793 dc.MoveTo( rcIcon.right - 3*offset/2, offset-1);
2794 dc.LineTo( rcIcon.right - 2*offset-1, rcIcon.bottom - offset + 1 );
2795 dc.MoveTo( rcIcon.right - 2*offset-1, rcIcon.bottom - offset );
2797 dc.SelectObject( &penShadow );
2798 dc.LineTo( rcIcon.right - 5*offset/2-1, offset -1 );
2799 dc.LineTo( rcIcon.right - 3*offset/2, offset -1);
2803 dc.SelectObject( pOldPen );
2807 dc.RestoreDC( nSavedDC );
2809 // Detach the dc before returning
2813 void CUIODListCtrl::SetSortColumn(int nCol,BOOL bAsc)
2815 m_nSortColumn = nCol;
2816 m_bSortAscending = bAsc;
2817 m_HeaderCtrl.SetSortImage(nCol,bAsc);
2820 void CUIODListCtrl::SetSortHeader()
2822 if (m_HeaderCtrl.GetSafeHwnd() == NULL && m_hWnd != NULL)
2824 m_HeaderCtrl.SubclassWindow( ::GetDlgItem(m_hWnd,0) );
2828 CString CUIODListCtrl::StripNonNumeric(LPCTSTR pszOldNum,CUIODListCtrl::eColTypes type)
2830 TCHAR szNewNum[255];
2831 LPTSTR pszNewNum = szNewNum;
2832 while (*pszOldNum != '\0')
2834 if ((type == CUIODListCtrl::e_Double && *pszOldNum == '.') || *pszOldNum == '-' || *pszOldNum == '+' || _istdigit(*pszOldNum))
2836 *pszNewNum = *pszOldNum;
2837 pszNewNum = _tcsinc(pszNewNum);
2839 pszOldNum = _tcsinc(pszOldNum);
2845 BOOL CUIODListCtrl::PreTranslateMessage(MSG* pMsg)
2847 if (pMsg->message == WM_KEYDOWN || pMsg->message == WM_SYSKEYDOWN)
2849 if (pMsg->wParam == VK_F10 && (GetKeyState(VK_SHIFT) < 0))
2851 PostMessage(WM_APP_ON_CONTEXT_MENU_KEY);
2854 else if (pMsg->wParam == VK_BACK)
2856 PostMessage(WM_APP_ON_BACKSPACE_KEY);
2859 else if (pMsg->wParam == VK_F2)
2861 PostMessage(WM_APP_ON_EDIT_KEY);
2864 else if (pMsg->wParam == VK_F5)
2866 PostMessage(WM_APP_ON_REFRESH_KEY);
2869 else if (pMsg->wParam == VK_DELETE)
2871 PostMessage(WM_APP_ON_DELETE_KEY);
2874 else if (pMsg->message == WM_SYSKEYDOWN && pMsg->wParam == VK_RETURN)
2876 PostMessage(WM_APP_ON_PROPERTIES_KEY);
2880 return CListCtrl::PreTranslateMessage(pMsg);
2883 // User has finished editing a column
2884 bool CUIODListCtrl::EndLabelEdit(int nRow,int nCol,LPCTSTR pszText)
2889 // Left mouse button double clicked
2890 BOOL CUIODListCtrl::DoubleClick(NM_LISTVIEW* pNMListView)
2896 BOOL CUIODListCtrl::OnEnter(NM_LISTVIEW* pNMListView)
2901 // Delete key pressed
2902 bool CUIODListCtrl::DeleteKey(int nRow)
2907 // ALt-Enter pressed
2908 void CUIODListCtrl::ShowProperties(int nRow)
2913 void CUIODListCtrl::Refresh()
2917 // Backspace key pressed
2918 void CUIODListCtrl::GoBack(int nSelRow)
2922 LRESULT CUIODListCtrl::OnDragDrop(WPARAM wParam,LPARAM lParam)
2924 if (IsDragDrop() == false)
2926 // get the info we need
2927 CDD_OleDropTargetInfo *pInfo = (CDD_OleDropTargetInfo*)wParam;
2929 return DragDrop(pInfo) ? 1 : 0;
2932 // user is currently over the list view window
2933 // return 1 if we are interested in the Clipboard format
2934 LRESULT CUIODListCtrl::OnDragOver(WPARAM wParam,LPARAM lParam)
2936 if (IsDragDrop() == false)
2938 CDD_OleDropTargetInfo *pInfo = (CDD_OleDropTargetInfo*)wParam;
2940 return DragOver(pInfo) ? 1 : 0;
2943 LRESULT CUIODListCtrl::OnDragEnter(WPARAM wParam,LPARAM lParam)
2945 if (IsDragDrop() == false)
2947 CDD_OleDropTargetInfo *pInfo = (CDD_OleDropTargetInfo*)wParam;
2949 return DragEnter(pInfo) ? 1 : 0;
2952 LRESULT CUIODListCtrl::OnDragLeave(WPARAM wParam,LPARAM lParam)
2954 if (IsDragDrop() == false)
2956 CDD_OleDropTargetInfo *pInfo = (CDD_OleDropTargetInfo*)wParam;
2958 return DragLeave(pInfo) ? 1 : 0;
2961 // Drag and drop initiated
2962 // Return 1 if processed
2963 LRESULT CUIODListCtrl::OnDDDoDragDrop(WPARAM wParam,LPARAM lParam)
2965 if (IsDragDrop() == false)
2967 COleDataSource *pOleDataSource = (COleDataSource*)lParam;
2968 int *pRows = (int*)wParam;
2969 ASSERT(pOleDataSource);
2970 return DoDragDrop(pRows,pOleDataSource);
2973 bool CUIODListCtrl::DragDrop(CDD_OleDropTargetInfo *pInfo)
2978 bool CUIODListCtrl::DragOver(CDD_OleDropTargetInfo *pInfo)
2983 bool CUIODListCtrl::DragEnter(CDD_OleDropTargetInfo *pInfo)
2988 bool CUIODListCtrl::DragLeave(CDD_OleDropTargetInfo *pInfo)
2993 DROPEFFECT CUIODListCtrl::DoDragDrop(int *pnRows,COleDataSource *pOleDataSource)
2998 void CUIODListCtrl::OnDropFiles(HDROP hDropInfo)
3000 UINT wNumFilesDropped = DragQueryFile(hDropInfo, 0XFFFFFFFF, NULL, 0);
3001 TCHAR szFile[MAX_PATH];
3005 ::DragQueryPoint(hDropInfo,&pt);
3006 int nRow = HitTest(CPoint(pt), &nFlags);
3007 for(UINT i=0; i < wNumFilesDropped;i++)
3009 nLen = DragQueryFile(hDropInfo,i,szFile,sizeof(szFile)/sizeof(TCHAR));
3011 OnDropFile(nRow,szFile,nFlags);
3015 void CUIODListCtrl::OnDropFile(int nRow,LPCTSTR pszFile,UINT nFlags)
3019 LRESULT CUIODListCtrl::OnAppPropertiesKey(WPARAM wParam, LPARAM lParam)
3022 while ((item = GetNextSel(item)) != -1)
3024 ShowProperties(item);
3029 LRESULT CUIODListCtrl::OnAppDeleteKey(WPARAM wParam, LPARAM lParam)
3033 CUIListCtrlData *pData = NULL;
3034 while ((item = GetNextSel(item)) != -1)
3036 pData = GetListCtrlData(item);
3037 if (DeleteKey(item))
3039 pData->SetDeleted(true);
3043 while ((item = GetCurSel()) != -1)
3045 pData = GetListCtrlData(item);
3046 if (pData->IsDeleted())
3048 if (!DeleteItem(item))
3049 SetItemState(item,0,LVIS_SELECTED);
3053 SetItemState(item,0,LVIS_SELECTED);
3055 if (GetItemCount() == 0)
3060 EnsureVisible(nNewItem,0);
3061 SetCurSel(nNewItem);
3066 LRESULT CUIODListCtrl::OnAppRefreshKey(WPARAM wParam, LPARAM lParam)
3072 LRESULT CUIODListCtrl::OnAppEditKey(WPARAM wParam, LPARAM lParam)
3074 EditLabel(GetCurSel());
3078 LRESULT CUIODListCtrl::OnAppContextMenuKey(WPARAM wParam, LPARAM lParam)
3081 if (GetCurSel() != -1)
3082 GetItemPosition(GetCurSel(),&pt);
3083 ClientToScreen(&pt);
3084 ShowPopupMenu(GetCurSel(),0,pt);
3088 LRESULT CUIODListCtrl::OnAppBackspaceKey(WPARAM wParam, LPARAM lParam)
3090 GoBack(GetCurSel());