Uictrl.cpp
上传用户:yatsl7111
上传日期:2007-01-08
资源大小:1433k
文件大小:79k
源码类别:

图形图象

开发平台:

Visual C++

  1. //*******************************************************************************
  2. // COPYRIGHT NOTES
  3. // ---------------
  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.
  10. // 
  11. // For the latest updates to this code, check this site:
  12. // http://www.masmex.com 
  13. // after Sept 2000
  14. // 
  15. // Copyright(C) 2000 Philip Oldaker <email: philip@masmex.com>
  16. //*******************************************************************************
  17. #include "stdafx.h"
  18. #include "UICtrl.h"
  19. #include "InPlaceEdit.h"
  20. #include "TextProgressCtrl.h"
  21. #include "UIres.h"
  22. #include "ctype.h"
  23. #include "cbformats.h"
  24. #include <yvals.h>
  25. //////////////////////////////////////////////////////
  26. // Temporarily changes the view type
  27. //////////////////////////////////////////////////////
  28. CChangeViewType::CChangeViewType(CUIODListCtrl *pLC,DWORD dwType)
  29. {
  30. m_pLC = pLC;
  31. m_dwType = m_pLC->GetViewType();
  32. m_pLC->SetViewType(dwType);
  33. }
  34. CChangeViewType::~CChangeViewType()
  35. {
  36. m_pLC->SetViewType(m_dwType);
  37. }
  38. //////////////////////////////////////////////////////////
  39. LPCTSTR CUIODListCtrl::szEntryHeadings = _T("Headings");
  40. LPCTSTR CUIODListCtrl::szEntryStyle = _T("Style");
  41. LPCTSTR CUIODListCtrl::szEntryRowSel = _T("RowSelection");
  42. LPCTSTR CUIODListCtrl::szEntryViewType = _T("ViewType");
  43. LPCTSTR CUIODListCtrl::szEntryColumnSizing = _T("ColumnSizing");
  44. LPCTSTR CUIODListCtrl::szEntrySortColumn = _T("SortColumn");
  45. LPCTSTR CUIODListCtrl::szEntrySubItems = _T("Columns");
  46. LPCTSTR CUIODListCtrl::szEntryColOrder = _T("ColumnOrder");
  47. LPCTSTR CUIODListCtrl::szEntryColWidths = _T("ColumnWidths");
  48. IMPLEMENT_SERIAL(CUIODListCtrl, CListCtrl, 0)
  49. #define COLUMN_DELIMITER '|'
  50. #define COLUMN_DELIMITER_STR "|"
  51. const int nMaxDigLen = _MAX_INT_DIG*4;
  52. //////////////////////////////
  53. //
  54. // CUIODListCtrl
  55. //
  56. //////////////////////////////
  57. BEGIN_MESSAGE_MAP(CUIODListCtrl, CListCtrl)
  58. //{{AFX_MSG_MAP(CUIODListCtrl)
  59. ON_MESSAGE(WM_APP_ON_PROPERTIES_KEY,OnAppPropertiesKey)
  60. ON_MESSAGE(WM_APP_ON_DELETE_KEY,OnAppDeleteKey)
  61. ON_MESSAGE(WM_APP_ON_CONTEXT_MENU_KEY,OnAppContextMenuKey)
  62. ON_MESSAGE(WM_APP_ON_BACKSPACE_KEY,OnAppBackspaceKey)
  63. ON_MESSAGE(WM_APP_ON_EDIT_KEY,OnAppEditKey)
  64. ON_MESSAGE(WM_APP_ON_REFRESH_KEY,OnAppRefreshKey)
  65. ON_NOTIFY_REFLECT_EX(LVN_BEGINDRAG, OnBegindrag)
  66. ON_NOTIFY_REFLECT_EX(LVN_BEGINRDRAG, OnBeginRDrag)
  67. ON_WM_CREATE()
  68. ON_WM_DESTROY()
  69. ON_MESSAGE(LVM_SETCOLUMNWIDTH,OnSetColumnWidth)
  70. ON_MESSAGE(LVM_DELETEALLITEMS,OnDeleteAllItems)
  71. ON_MESSAGE(LVM_DELETEITEM,OnDeleteItem)
  72. ON_MESSAGE(LVM_DELETECOLUMN,OnDeleteColumn)
  73. ON_MESSAGE(WM_UPDATEHEADERWIDTH,OnUpdateHeaderWidth)
  74. ON_WM_SIZE()
  75. ON_WM_PAINT()
  76. ON_WM_SETFOCUS()
  77. ON_WM_KILLFOCUS()
  78. ON_WM_CONTEXTMENU()
  79. ON_WM_INITMENUPOPUP()
  80. ON_WM_LBUTTONDOWN()
  81. ON_WM_HSCROLL()
  82. ON_WM_VSCROLL()
  83. ON_COMMAND(ID_UI_VIEW_LARGE_ICONS,OnViewLargeIcons)
  84. ON_COMMAND(ID_UI_VIEW_SMALL_ICONS,OnViewSmallIcons)
  85. ON_COMMAND(ID_UI_VIEW_DETAILS,OnViewDetails)
  86. ON_COMMAND(ID_UI_VIEW_LIST,OnViewList)
  87. ON_COMMAND(ID_UI_VIEW_FULL_ROW_SELECTION,OnViewFullRowSelection)
  88. ON_COMMAND(ID_UI_VIEW_COLUMN_ORDERING,OnViewColumnOrdering)
  89. ON_COMMAND(ID_UI_VIEW_COLUMN_SIZING,OnViewColumnSizing)
  90. ON_COMMAND(ID_UI_VIEW_GRIDLINES,OnViewGridlines)
  91. ON_COMMAND(ID_UI_VIEW_CHECKBOXES,OnViewCheckboxes)
  92. ON_COMMAND(ID_UI_VIEW_TRACK_SELECT,OnViewTrackSelect)
  93. ON_COMMAND(ID_UI_VIEW_EDIT_COLUMN,OnViewEditColumn)
  94. ON_COMMAND(ID_HEADER_REMOVE_COL,OnHeaderRemoveColumn)
  95. ON_COMMAND(ID_HEADER_EDIT_TEXT,OnHeaderEditText)
  96. ON_COMMAND(ID_HEADER_RESET,OnHeaderReset)
  97. ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipText)
  98. ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipText)
  99. ON_WM_DROPFILES()
  100. ON_MESSAGE(LVM_SETIMAGELIST, OnSetImageList)
  101. ON_MESSAGE(LVM_SETTEXTCOLOR, OnSetTextColor)
  102. ON_MESSAGE(LVM_SETTEXTBKCOLOR, OnSetTextBkColor)
  103. ON_MESSAGE(LVM_SETBKCOLOR, OnSetBkColor)
  104. ON_MESSAGE(LVM_GETITEMTEXT, OnGetItemText)
  105. //}}AFX_MSG_MAP
  106. ON_MESSAGE(WM_APP_OLE_DD_DROP, OnDragDrop)
  107. ON_MESSAGE(WM_APP_OLE_DD_DODRAGDROP, OnDDDoDragDrop)
  108. ON_MESSAGE(WM_APP_OLE_DD_OVER, OnDragOver)
  109. ON_MESSAGE(WM_APP_OLE_DD_ENTER, OnDragEnter)
  110. ON_MESSAGE(WM_APP_OLE_DD_LEAVE, OnDragLeave)
  111. END_MESSAGE_MAP()
  112. CUIODListCtrl::CUIODListCtrl(bool bDragDrop) 
  113. {
  114. m_PopupID = 0;
  115. m_MultiPopupID = 0;
  116. m_bDragDrop = bDragDrop;
  117. m_bDropFiles = true;
  118. m_pColWidths = NULL;
  119. m_pColOrder = NULL;
  120. m_pColTypes = NULL;
  121. m_hOrigFont = NULL;
  122. m_pPopupWnd = NULL;
  123. m_nImageList = LVSIL_SMALL;
  124. m_nColClicked = -1;
  125. m_nSortColumn = 0;
  126. m_nSubItems = 0;
  127. m_nItems = 0;
  128. m_nImage = 0;
  129. m_dwExStyle = LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_INFOTIP;
  130. m_dwViewType = LVS_REPORT;
  131. m_bDelayPaint = false;
  132. m_bColumnSizing=TRUE;
  133. m_bRClickChangeIconSize = TRUE;
  134. // this is toggled on in InitListCtrl
  135. m_bFullRowSel=FALSE;
  136. m_bClientWidthSel=TRUE;
  137. m_bSortAscending=TRUE;
  138. m_bToolTips=FALSE;
  139. m_bEditSubItems = true;
  140. m_cxClient=0;
  141. m_cxStateImageOffset=0;
  142. m_clrText=::GetSysColor(COLOR_WINDOWTEXT);
  143. m_clrTextBk=::GetSysColor(COLOR_WINDOW);
  144. m_clrBkgnd=::GetSysColor(COLOR_WINDOW);
  145. m_strNoItemsMess.LoadString(IDS_NO_ITEMS_MESS);
  146. }
  147. CUIODListCtrl::~CUIODListCtrl()
  148. {
  149. Empty();
  150. }
  151. void CUIODListCtrl::AllItemsDeleted()
  152. {
  153. }
  154. void CUIODListCtrl::Empty()
  155. {
  156. m_objList.DeleteAll();
  157. delete []m_pColWidths;
  158. delete []m_pColOrder;
  159. delete []m_pColTypes;
  160. m_pColWidths = NULL;
  161. m_pColOrder = NULL;
  162. m_pColTypes = NULL;
  163. }
  164. // should be overridden to do any initialization
  165. void CUIODListCtrl::Init()
  166. {
  167. }
  168. void CUIODListCtrl::UpdateEvent(LPARAM lHint,CObject *pHint)
  169. {
  170. GetParent()->SendMessage(WM_APP_UPDATE_ALL_VIEWS,(WPARAM)lHint,(LPARAM)pHint);
  171. }
  172. BOOL CUIODListCtrl::SetViewType(DWORD dwViewType,UINT nFlags)
  173. {
  174. BOOL bRet = ModifyStyle(LVS_TYPEMASK,dwViewType & LVS_TYPEMASK,nFlags);
  175. if (bRet)
  176. SaveProfile();
  177. return bRet;
  178. }
  179. DWORD CUIODListCtrl::GetViewType() const
  180. {
  181. return(GetStyle() & LVS_TYPEMASK);
  182. }
  183. void CUIODListCtrl::ChangeStyle(UINT &dwStyle)
  184. {
  185. LoadProfile();
  186. dwStyle |= LVS_SHOWSELALWAYS | m_dwViewType;
  187. }
  188. // offsets for first and other columns
  189. #define OFFSET_FIRST 2
  190. #define OFFSET_OTHER 6
  191. void CUIODListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
  192. {
  193. CDC* pDC=CDC::FromHandle(lpDrawItemStruct->hDC);
  194. CRect rcItem(lpDrawItemStruct->rcItem);
  195. UINT uiFlags=ILD_TRANSPARENT;
  196. CImageList* pImageList;
  197. int nItem=lpDrawItemStruct->itemID;
  198. BOOL bFocus=(GetFocus()==this);
  199. COLORREF clrTextSave, clrBkSave;
  200. COLORREF clrImage=m_clrBkgnd;
  201. static _TCHAR szBuff[MAX_PATH];
  202. LPCTSTR pszText;
  203. if (m_cxClient == 0)
  204. {
  205. CRect rcClient;
  206. GetClientRect(rcClient);
  207. m_cxClient = rcClient.Width();
  208. }
  209. // get item data
  210. LV_ITEM lvi;
  211. lvi.mask=LVIF_TEXT | LVIF_IMAGE | LVIF_STATE | LVIF_PARAM;
  212. lvi.iItem=nItem;
  213. lvi.iSubItem=0;
  214. lvi.pszText=szBuff;
  215. lvi.cchTextMax=sizeof(szBuff);
  216. lvi.stateMask=0xFFFF; // get all state flags
  217. GetItem(&lvi);
  218. BOOL bSelected=(bFocus || (GetStyle() & LVS_SHOWSELALWAYS)) && lvi.state & LVIS_SELECTED;
  219. bSelected=bSelected || (lvi.state & LVIS_DROPHILITED);
  220. // set colors if item is selected
  221. CRect rcAllLabels;
  222. GetItemRect(nItem,rcAllLabels,LVIR_BOUNDS);
  223. CRect rcLabel;
  224. GetItemRect(nItem,rcLabel,LVIR_LABEL);
  225. rcAllLabels.left=rcLabel.left;
  226. // if(m_bClientWidthSel && rcAllLabels.right<m_cxClient)
  227. // rcAllLabels.right=m_cxClient;
  228. int BkMode = pDC->SetBkMode(TRANSPARENT);
  229. CUIListCtrlData *pData = (CUIListCtrlData*)lvi.lParam;
  230. ASSERT(pData->IsKindOf(RUNTIME_CLASS(CUIListCtrlData)));
  231. CFont *pOldFont = NULL;
  232. if (pData && pData->IsFontSet())
  233. {
  234. pOldFont = pDC->SelectObject((CFont*)pData->GetFont());
  235. }
  236. if(bSelected)
  237. {
  238. if (bFocus) 
  239. {
  240. clrTextSave=pDC->SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));
  241. clrBkSave=pDC->SetBkColor(::GetSysColor(COLOR_HIGHLIGHT));
  242. pDC->FillRect(rcAllLabels,&CBrush(::GetSysColor(COLOR_HIGHLIGHT)));
  243. }
  244. else 
  245. {
  246. clrTextSave=pDC->GetTextColor();
  247. clrBkSave=pDC->GetBkColor();
  248. DWORD clrTextBk;
  249. if (pData)
  250. {
  251. pDC->SetTextColor(pData->GetTextColor());
  252. clrTextBk = pData->GetBkColor();
  253. }
  254. else 
  255. {
  256. clrTextBk = m_clrTextBk;
  257. pDC->SetTextColor(m_clrText);
  258. }
  259. CRect rc(rcAllLabels);
  260. pDC->FillRect(rcAllLabels,&CBrush(clrTextBk));
  261. pDC->FrameRect(rc,&CBrush(::GetSysColor(COLOR_HIGHLIGHT)));
  262. }
  263. }
  264. else 
  265. {
  266. CUIListCtrlData *pData = (CUIListCtrlData *)lvi.lParam;
  267. if (pData) 
  268. {
  269. ASSERT(pData->IsKindOf(RUNTIME_CLASS(CUIListCtrlData)));
  270. pDC->SetTextColor(pData->GetTextColor());
  271. pDC->SetBkColor(pData->GetBkColor());
  272. pDC->FillRect(rcAllLabels,&CBrush(pData->GetBkColor()));
  273. }
  274. else
  275. pDC->FillRect(rcAllLabels,&CBrush(m_clrTextBk));
  276. }
  277. // set color and mask for the icon
  278. if(lvi.state & LVIS_CUT)
  279. {
  280. clrImage=m_clrBkgnd;
  281. uiFlags|=ILD_BLEND50;
  282. }
  283. else if(bSelected)
  284. {
  285. clrImage=::GetSysColor(COLOR_HIGHLIGHT);
  286. uiFlags|=ILD_BLEND50;
  287. }
  288. // draw state icon
  289. UINT nStateImageMask=lvi.state & LVIS_STATEIMAGEMASK;
  290. if(nStateImageMask)
  291. {
  292. int nImage=(nStateImageMask>>12)-1;
  293. pImageList=GetImageList(LVSIL_STATE);
  294. if(pImageList)
  295. pImageList->Draw(pDC,nImage,CPoint(rcItem.left,rcItem.top),ILD_TRANSPARENT);
  296. }
  297. // draw normal and overlay icon
  298. CRect rcIcon;
  299. GetItemRect(nItem,rcIcon,LVIR_ICON);
  300. pImageList=GetImageList(LVSIL_SMALL);
  301. if(pImageList)
  302. {
  303. UINT nOvlImageMask=lvi.state & LVIS_OVERLAYMASK;
  304. if(rcItem.left<rcItem.right-1)
  305. ImageList_DrawEx(pImageList->m_hImageList,lvi.iImage,pDC->m_hDC,rcIcon.left,rcIcon.top,16,16,m_clrBkgnd,clrImage,uiFlags | nOvlImageMask);
  306. }
  307. // draw item label
  308. GetItemRect(nItem,rcItem,LVIR_LABEL);
  309. rcItem.right-=m_cxStateImageOffset;
  310. pszText=MakeShortString(pDC,szBuff,rcItem.right-rcItem.left,2*OFFSET_FIRST);
  311. rcLabel=rcItem;
  312. rcLabel.left+=OFFSET_FIRST;
  313. rcLabel.right-=OFFSET_FIRST;
  314. pDC->DrawText(pszText,-1,rcLabel,DT_LEFT | DT_SINGLELINE | DT_NOPREFIX | DT_NOCLIP | DT_VCENTER);
  315. // draw labels for extra columns
  316. LV_COLUMN lvc;
  317. lvc.mask=LVCF_FMT | LVCF_WIDTH;
  318. for(int nColumn=1; GetColumn(nColumn,&lvc); nColumn++)
  319. {
  320. rcItem.left=rcItem.right;
  321. rcItem.right+=lvc.cx;
  322. int nRetLen=GetItemText(nItem,nColumn,szBuff,sizeof(szBuff));
  323. if(nRetLen==0) continue;
  324. pszText=MakeShortString(pDC,szBuff,rcItem.right-rcItem.left,2*OFFSET_OTHER);
  325. UINT nJustify=DT_LEFT;
  326. if(pszText==szBuff)
  327. {
  328. switch(lvc.fmt & LVCFMT_JUSTIFYMASK)
  329. {
  330. case LVCFMT_RIGHT:
  331. nJustify=DT_RIGHT;
  332. break;
  333. case LVCFMT_CENTER:
  334. nJustify=DT_CENTER;
  335. break;
  336. default:
  337. break;
  338. }
  339. }
  340. rcLabel=rcItem;
  341. rcLabel.left+=OFFSET_OTHER;
  342. rcLabel.right-=OFFSET_OTHER;
  343. pDC->DrawText(pszText,-1,rcLabel,nJustify | DT_SINGLELINE | DT_NOPREFIX | DT_NOCLIP | DT_VCENTER);
  344. }
  345. if (pData->IsKindOf(RUNTIME_CLASS(CUIStrListCtrlData)))
  346. {
  347. CUIStrListCtrlData *pStrData = (CUIStrListCtrlData*)pData;
  348. if (!pStrData->GetExtraString().IsEmpty())
  349. {
  350. rcLabel=rcAllLabels;
  351. rcLabel.top += (m_cySmallIcon+1);
  352. pDC->DrawText(pStrData->GetExtraString(),-1,rcLabel,DT_LEFT | DT_SINGLELINE | DT_NOPREFIX | DT_NOCLIP | DT_VCENTER);
  353. }
  354. }
  355. // draw focus rectangle if item has focus
  356. if(lvi.state & LVIS_FOCUSED && bFocus)
  357. pDC->DrawFocusRect(rcAllLabels);
  358. // set original colors if item was selected
  359. if(bSelected)
  360. {
  361.     pDC->SetTextColor(clrTextSave);
  362. pDC->SetBkColor(clrBkSave);
  363. }
  364. if (pOldFont)
  365. pDC->SelectObject(pOldFont);
  366. pDC->SetBkMode(BkMode);
  367. }
  368. LPCTSTR CUIODListCtrl::MakeShortString(CDC* pDC, LPCTSTR lpszLong, int nColumnLen, int nOffset)
  369. {
  370. static const _TCHAR szThreeDots[]=_T("...");
  371. int nStringLen=lstrlen(lpszLong);
  372. if(nStringLen==0 || pDC->GetTextExtent(lpszLong,nStringLen).cx+nOffset<=nColumnLen)
  373. return(lpszLong);
  374. static _TCHAR szShort[MAX_PATH];
  375. lstrcpy(szShort,lpszLong);
  376. int nAddLen=pDC->GetTextExtent(szThreeDots,sizeof(szThreeDots)).cx;
  377. for(int i=nStringLen-1; i>0; i--)
  378. {
  379. szShort[i]=0;
  380. if(pDC->GetTextExtent(szShort,i).cx+nOffset+nAddLen<=nColumnLen)
  381. break;
  382. }
  383. lstrcat(szShort,szThreeDots);
  384. return(szShort);
  385. }
  386. void CUIODListCtrl::RepaintSelectedItems()
  387. {
  388. CRect rcItem, rcLabel;
  389. // invalidate focused item so it can repaint properly
  390. int nItem=GetNextItem(-1,LVNI_FOCUSED);
  391. if(nItem!=-1)
  392. {
  393. GetItemRect(nItem,rcItem,LVIR_BOUNDS);
  394. GetItemRect(nItem,rcLabel,LVIR_LABEL);
  395. rcItem.left=rcLabel.left;
  396. InvalidateRect(rcItem,FALSE);
  397. }
  398. // if selected items should not be preserved, invalidate them
  399. // if(!(GetStyle() & LVS_SHOWSELALWAYS))
  400. // {
  401. for(nItem=GetNextItem(-1,LVNI_SELECTED);
  402. nItem!=-1; nItem=GetNextItem(nItem,LVNI_SELECTED))
  403. {
  404. GetItemRect(nItem,rcItem,LVIR_BOUNDS);
  405. GetItemRect(nItem,rcLabel,LVIR_LABEL);
  406. rcItem.left=rcLabel.left;
  407. InvalidateRect(rcItem,FALSE);
  408. }
  409. // }
  410. // update changes 
  411. UpdateWindow();
  412. }
  413. void CUIODListCtrl::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItem)
  414. {
  415.     lpMeasureItem->itemHeight = (m_cySmallIcon+1)*3;
  416. }
  417. BOOL CUIODListCtrl::OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
  418. {
  419. LPNMHDR pnmh;
  420. switch (message)
  421. {
  422. case WM_DRAWITEM:
  423. ASSERT(pResult == NULL);       
  424. DrawItem((LPDRAWITEMSTRUCT)lParam);
  425. break;
  426. case WM_MEASUREITEM:
  427. ASSERT(pResult == NULL);       
  428. MeasureItem((LPMEASUREITEMSTRUCT)lParam);
  429. break;
  430. case WM_NOTIFY:
  431. pnmh = (LPNMHDR)lParam;
  432. if (pnmh->code == LVN_ITEMCHANGED)
  433. {
  434. NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pnmh;
  435. if ((pNMListView->uNewState & LVIS_SELECTED) == LVIS_SELECTED && 
  436. (pNMListView->uNewState & LVIS_FOCUSED) == LVIS_FOCUSED) 
  437. {
  438. return OnSelChanged(pNMListView->iItem,pResult);
  439. }
  440. }
  441. else if (pnmh->code == LVN_GETDISPINFO) 
  442. {
  443. return GetDispInfo((LV_DISPINFO*)pnmh);
  444. }
  445. else if (pnmh->code == LVN_COLUMNCLICK) 
  446. {
  447. return ColumnClick((NM_LISTVIEW*)pnmh);
  448. }
  449. else if (pnmh->code == LVN_ENDLABELEDIT) 
  450. {
  451. return OnEndLabelEdit(pnmh,pResult);
  452. }
  453. else if (pnmh->code == NM_DBLCLK) 
  454. {
  455. return DoubleClick((NM_LISTVIEW*)pnmh);
  456. }
  457. else if (pnmh->code == NM_RETURN) 
  458. {
  459. return OnEnter((NM_LISTVIEW*)pnmh);
  460. }
  461. else if (pnmh->code == NM_CUSTOMDRAW)
  462. {
  463.      LPNMLVCUSTOMDRAW  lplvcd = (LPNMLVCUSTOMDRAW)lParam;
  464.  if(lplvcd->nmcd.dwDrawStage == CDDS_PREPAINT)
  465.  {
  466. //tell the control we want pre-paint notifications for each item
  467. *pResult = CDRF_NOTIFYITEMDRAW;
  468. return TRUE;
  469.  }
  470.  if (lplvcd->nmcd.dwDrawStage == (CDDS_ITEMPREPAINT | CDDS_SUBITEM))
  471.  {
  472.  return SubItemPrePaint(lplvcd,pResult);
  473.  }
  474.  if (lplvcd->nmcd.dwDrawStage == (CDDS_ITEMPOSTPAINT | CDDS_SUBITEM))
  475.  {
  476.  return SubItemPostPaint(lplvcd,pResult);
  477.  }
  478.  if (lplvcd->nmcd.dwDrawStage == CDDS_ITEMPREPAINT)
  479.  {
  480.  return ItemPrePaint(lplvcd,pResult);
  481.  }
  482.  if (lplvcd->nmcd.dwDrawStage == CDDS_ITEMPOSTPAINT)
  483.  {
  484.  return ItemPostPaint(lplvcd,pResult);
  485.  }
  486.         }
  487. }
  488. return CWnd::OnChildNotify(message, wParam, lParam, pResult);
  489. }
  490. LRESULT CUIODListCtrl::OnUpdateHeaderWidth(WPARAM wParam,LPARAM lParam)
  491. {
  492. // lParam = column that has changed its width
  493. int nItem = lParam;
  494. m_pColWidths[nItem] = GetColumnWidth(nItem);
  495.     GetParent()->SendMessage(WM_HEADERWIDTHCHANGED,(WPARAM)GetSafeHwnd(),nItem);
  496. return TRUE;
  497. }
  498. BOOL CUIODListCtrl::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
  499. {
  500. LPNMHDR pnmh = (LPNMHDR)lParam;
  501. if ((pnmh->code == HDN_BEGINTRACKW || pnmh->code == HDN_BEGINTRACKA)) 
  502. {
  503. if (m_bColumnSizing == FALSE) 
  504. {
  505. *pResult = TRUE;
  506. return TRUE;
  507. }
  508. LPNMHEADER phdr = (LPNMHEADER)lParam;
  509. if (phdr->pitem->mask & HDI_WIDTH)
  510. {
  511. }
  512. }
  513. if ((pnmh->code == HDN_ITEMCHANGINGW || pnmh->code == HDN_ITEMCHANGINGA)) 
  514. {
  515. LPNMHEADER phdr = (LPNMHEADER)lParam;
  516. }
  517. if ((pnmh->code == HDN_ENDTRACKW || pnmh->code == HDN_ENDTRACKA)) 
  518. {
  519.     HD_NOTIFY *phdn = (HD_NOTIFY*)pnmh;
  520. LPNMHEADER phdr = (LPNMHEADER)lParam;
  521. if (m_bColumnSizing == TRUE && (phdr->pitem->mask & HDI_WIDTH))
  522. PostMessage(WM_UPDATEHEADERWIDTH,(WPARAM)phdn->hdr.hwndFrom,(LPARAM)phdn->iItem);
  523. // wParam is zero for Header ctrl
  524. if( wParam == 0 && pnmh->code == NM_RCLICK )
  525. {
  526. // Right button was clicked on header
  527. CPoint ptScreen(GetMessagePos());
  528. CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0);
  529. ASSERT(pHeader);
  530. CPoint ptClient(ptScreen);
  531. pHeader->ScreenToClient(&ptClient);
  532. // Determine the column index
  533. int index=-1;
  534. CRect rcCol;
  535. for( int i=0; Header_GetItemRect(pHeader->m_hWnd, i, &rcCol); i++ )
  536. {
  537. if( rcCol.PtInRect( ptClient ) )
  538. {
  539. index = i;
  540. break;
  541. }
  542. }
  543. OnRClickHeader(ptScreen,index);
  544. }
  545. return CWnd::OnNotify(wParam,lParam,pResult);
  546. }
  547. DWORD CUIODListCtrl::GetItemData(int nIndex) const
  548. {
  549. if (nIndex != LB_ERR)
  550. {
  551. const CUIListCtrlData* pListObj = GetListCtrlData(nIndex);
  552. if (pListObj)
  553. return pListObj->GetExtData();
  554. }
  555. return 0;
  556. }
  557. BOOL CUIODListCtrl::SetItemDataAutoDelete(int nIndex,CObject *pObj)
  558. {
  559. ASSERT_KINDOF(CObject,pObj);
  560. return SetItemData(nIndex,(DWORD)pObj,true);
  561. }
  562. BOOL CUIODListCtrl::SetItemData(int nIndex,DWORD dwData,bool bAutoDelete)
  563. {
  564. if (nIndex != LB_ERR) 
  565. {
  566. CUIListCtrlData* pListObj = GetListCtrlData(nIndex);
  567. if (pListObj) 
  568. {
  569. pListObj->SetExtData(dwData);
  570. pListObj->SetAutoDelete(bAutoDelete);
  571. return TRUE;
  572. }
  573. }
  574. return FALSE;
  575. }
  576. int CUIODListCtrl::SetIcon(int nRow,int nImage)
  577. {
  578. LV_ITEM lvItem;
  579. ZeroMemory(&lvItem,sizeof(LV_ITEM));
  580. lvItem.mask = LVIF_IMAGE;
  581. lvItem.iItem = nRow;
  582. lvItem.iImage = nImage;
  583. SetItem(&lvItem);
  584. return lvItem.iImage;
  585. }
  586. int CUIODListCtrl::SetIcon(int nRow,UINT nIconID)
  587. {
  588. int nImage = GetImageIndex(nIconID);
  589. return SetIcon(nRow,nImage);
  590. }
  591. BOOL CUIODListCtrl::SetColumnFormat(int nCol,int fmt)
  592. {
  593. LVCOLUMN lvCol;
  594. ZeroMemory(&lvCol,sizeof(lvCol));
  595. lvCol.mask = LVCF_FMT;
  596. lvCol.fmt = fmt;
  597. return SetColumn(nCol,&lvCol);
  598. }
  599. void CUIODListCtrl::SetTextColor(int nRow, int nCol, COLORREF TextColor)
  600. {
  601. CUIListCtrlData *pData = GetListCtrlData(nRow);
  602. if (pData)
  603. pData->SetTextColor(TextColor,nCol);
  604. }
  605. void CUIODListCtrl::SetDefaultTextColor(int nRow,int nCol)
  606. {
  607. CUIListCtrlData *pData = GetListCtrlData(nRow);
  608. if (pData)
  609. pData->SetDefaultTextColor(nCol);
  610. }
  611. void CUIODListCtrl::SetBkColor(int nRow,int nCol,COLORREF BkColor)
  612. {
  613. CUIListCtrlData *pData = GetListCtrlData(nRow);
  614. if (pData)
  615. pData->SetBkColor(BkColor,nCol);
  616. }
  617. void CUIODListCtrl::SetDefaultBkColor(int nRow,int nCol)
  618. {
  619. CUIListCtrlData *pData = GetListCtrlData(nRow);
  620. if (pData)
  621. pData->SetDefaultBkColor(nCol);
  622. }
  623. CUIListCtrlData *CUIODListCtrl::GetListCtrlData(int nItem) const
  624. {
  625. CUIListCtrlData *pData = (CUIListCtrlData *)CListCtrl::GetItemData(nItem);
  626. if (pData == NULL)
  627. return NULL;
  628. ASSERT(pData->IsKindOf(RUNTIME_CLASS(CUIListCtrlData)));
  629. return pData;
  630. }
  631. int CUIODListCtrl::AddColumn(LPCTSTR szText)
  632. {
  633. // don't add again
  634. int nCol = FindColumn(szText);
  635. if (nCol >= 0)
  636. return nCol;
  637. nCol = InsertColumn(m_nSubItems,szText);
  638. if (nCol != -1)
  639. {
  640. m_strHeadings += COLUMN_DELIMITER_STR;
  641. m_strHeadings += szText;
  642. m_nSubItems++;
  643. SaveProfile();
  644. LoadProfile();
  645. }
  646. return nCol;
  647. }
  648. int CUIODListCtrl::FindColumn(LPCTSTR pszText)
  649. {
  650. LPCTSTR pszHeadings = m_strHeadings;
  651. int nCol=0;
  652. while (*pszHeadings != '')
  653. {
  654. if (*pszHeadings == COLUMN_DELIMITER)
  655. nCol++;
  656. if (_tcsnicmp(pszHeadings,pszText,_tcslen(pszText)) == 0)
  657. {
  658. break;
  659. }
  660. pszHeadings = _tcsinc(pszHeadings);
  661. }
  662. return *pszHeadings == '' ? -1 : nCol;
  663. }
  664. BOOL CUIODListCtrl::InitListCtrl(UINT IconID,LPCTSTR szHeadings,LPCTSTR pszProfile)
  665. {
  666. static UINT Icons[2];
  667. Icons[0] = IconID;
  668. Icons[1] = 0;
  669. return InitListCtrl(&Icons[0],szHeadings,pszProfile);
  670. }
  671. BOOL CUIODListCtrl::InitListCtrl(LPCTSTR szHeadings,LPCTSTR pszProfile)
  672. {
  673. static UINT Icons[1];
  674. Icons[0] = 0;
  675. return InitListCtrl(&Icons[0],szHeadings,pszProfile);
  676. }
  677. int CUIODListCtrl::InitListCtrl(const UINT *pIconIDs,LPCTSTR szHeadings,LPCTSTR pszProfile)
  678. {
  679. BOOL bFailed = FALSE;
  680. // TODO: Add extra initialization here
  681. if (pszProfile)
  682. {
  683. SetSection(pszProfile);
  684. }
  685. //clean up
  686. if (m_nSubItems) 
  687. {
  688. if (m_strHeadings == szHeadings)
  689. return m_nSubItems;
  690. DeleteAllItems();
  691. int nSubItems=m_nSubItems;
  692. for(int i=0;i < nSubItems;i++)
  693. DeleteColumn(0);
  694. m_nSubItems = 0;
  695. Empty();
  696. }
  697. if (pszProfile == NULL)
  698. {
  699. if (!m_strSection.IsEmpty())
  700. pszProfile = m_strSection;
  701. }
  702. if (pszProfile)
  703. {
  704. LoadProfile();
  705. // Use profile headings if found
  706. if (!m_strHeadings.IsEmpty())
  707. {
  708. if (m_strHeadings != szHeadings)
  709. {
  710. m_strHeadings = szHeadings;
  711. SaveProfile();
  712. }
  713. }
  714. }
  715. if (m_dwExStyle)
  716. SendMessage(LVM_SETEXTENDEDLISTVIEWSTYLE, 0, m_dwExStyle);
  717. // at least one image
  718. if (pIconIDs && *pIconIDs) 
  719. {
  720. // load the icons and add them to the image lists
  721. int i;
  722. for(i=0;*pIconIDs;i++,pIconIDs++) 
  723. {
  724. if (AddIcon(*pIconIDs) == -1)
  725. bFailed = TRUE;
  726. }
  727. // Now initialize the columns we will need
  728. // Initialize the LV_COLUMN structure
  729. // the mask specifies that the .fmt, .ex, width, and .subitem members 
  730. // of the structure are valid,
  731. LV_COLUMN lvC;
  732. lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  733. lvC.fmt = LVCFMT_LEFT;  // left align the column
  734. if (szHeadings)
  735. {
  736. // parse the string, format it and get column count
  737. const int MAX_HEADING_LEN = 512;
  738. TCHAR szHeadingsCopy[MAX_HEADING_LEN]; 
  739. if (_tcslen(szHeadings) >= MAX_HEADING_LEN-1)
  740. {
  741. _tcsncpy(szHeadingsCopy,szHeadings,MAX_HEADING_LEN-1);
  742. szHeadingsCopy[MAX_HEADING_LEN-1] = '';
  743. }
  744. else
  745. _tcscpy(szHeadingsCopy,szHeadings);
  746. LPTSTR p = szHeadingsCopy;
  747. int nCols = 0;
  748. while (*p != '')
  749. {
  750. if (*p == COLUMN_DELIMITER) 
  751. {
  752.  nCols++;
  753.  *p = '';
  754. }
  755. p = _tcsinc(p);
  756. }
  757. if (*szHeadingsCopy)
  758. nCols++;
  759. LPTSTR pszText = szHeadingsCopy;
  760. m_nSubItems = nCols; 
  761. for (int index = 0;index < nCols; index++)
  762. {
  763. lvC.iSubItem = index;
  764. lvC.pszText = pszText;
  765. // lvC.cx = LVSCW_AUTOSIZE_USEHEADER;  
  766. lvC.cx = 100;  
  767. if (InsertColumn(index, &lvC) == -1) 
  768. {
  769. TRACE(_T("InsertColumn failedn"));
  770. m_nSubItems--;
  771. bFailed = TRUE;
  772. }
  773. while (*pszText)
  774.    pszText = _tcsinc(pszText);
  775. pszText = _tcsinc(pszText); // Runs past the end of the buffer
  776. }
  777. // Add the columns.
  778. m_strHeadings = szHeadings;
  779. if (pszProfile)
  780. {
  781. SaveProfile();
  782. LoadProfile();
  783. }
  784. if (m_pColOrder)
  785. {
  786. SendMessage(LVM_SETCOLUMNORDERARRAY,(WPARAM)nCols,(LPARAM)m_pColOrder);
  787. }
  788. if (m_pColWidths)
  789. {
  790. for(int i=0;i < nCols;i++)
  791. {
  792. if (m_pColWidths[i] != 0)
  793. SetColumnWidth(i,m_pColWidths[i]);
  794. }
  795. }
  796. else
  797. {
  798. m_pColWidths = new int[nCols];
  799. for(int i=0;i < nCols;i++)
  800. {
  801. m_pColWidths[i] = GetColumnWidth(i);
  802. }
  803. }
  804. if (m_pColTypes == NULL)
  805. {
  806. // set default column types
  807. m_pColTypes = new int[nCols];
  808. for(int i=0;i < nCols;i++)
  809. {
  810. m_pColTypes[i] = e_Text;
  811. }
  812. }
  813. }
  814. SetSortHeader();
  815. return m_nSubItems;
  816. }
  817. void CUIODListCtrl::GetImageLists(CImageList **pILSmall,CImageList **pILLarge)
  818. {
  819. *pILSmall = GetImageList(LVSIL_SMALL);
  820. if (*pILSmall == NULL)
  821. {
  822. CreateImageLists();
  823. *pILSmall = GetImageList(LVSIL_SMALL);
  824. }
  825. *pILLarge = GetImageList(LVSIL_NORMAL);
  826. ASSERT(*pILSmall);
  827. ASSERT(*pILLarge);
  828. }
  829. void CUIODListCtrl::CreateImageLists()
  830. {
  831. m_cxSmallIcon = ::GetSystemMetrics(SM_CXSMICON);
  832. m_cySmallIcon = ::GetSystemMetrics(SM_CYSMICON);
  833. m_cxLargeIcon = ::GetSystemMetrics(SM_CXICON);
  834. m_cyLargeIcon = ::GetSystemMetrics(SM_CYICON);
  835. if (m_ImageSmall.GetSafeHandle() != NULL)
  836. m_ImageSmall.DeleteImageList();
  837. if (m_ImageLarge.GetSafeHandle() != NULL)
  838. m_ImageLarge.DeleteImageList();
  839. // create the small icon image list
  840. m_ImageSmall.Create(m_cxSmallIcon,
  841. m_cySmallIcon,
  842. ILC_MASK | ILC_COLOR16,
  843. 1,
  844. 1);
  845. // create the large icon image list
  846. m_ImageLarge.Create(m_cxLargeIcon,
  847. m_cyLargeIcon,
  848. ILC_MASK | ILC_COLOR16,
  849. 1,
  850. 1);
  851. // Associate the image lists with the list view
  852. SetImageList(&m_ImageSmall, LVSIL_SMALL);
  853. SetImageList(&m_ImageLarge, LVSIL_NORMAL);
  854. }
  855. void CUIODListCtrl::AddExtraString(int nRow,LPCTSTR pszExtraText)
  856. {
  857. CUIStrListCtrlData *pData = (CUIStrListCtrlData *)GetListCtrlData(nRow);
  858. ASSERT_KINDOF(CUIStrListCtrlData,pData);
  859. pData->AddExtraString(pszExtraText);
  860. }
  861. void CUIODListCtrl::ConvertToTime(CString &str)
  862. {
  863. int nPoint = str.Find(GetDecimalSep());
  864. int nSecs=0;
  865. if (nPoint == -1)
  866. nSecs = _ttoi(str);
  867. else
  868. {
  869. LPTSTR pszStop;
  870. double dSecs = _tcstod(str,&pszStop);
  871. nSecs = dSecs;
  872. }
  873. if (nSecs == 0)
  874. return;
  875. int nMins = nSecs / 60;
  876. nSecs = nSecs % 60;
  877. str.Format(_T("%u:%u"),nMins,nSecs);
  878. }
  879. void CUIODListCtrl::AddThousandSeps(CString &str)
  880. {
  881. CString strTemp;
  882. CString strExp;
  883. CString strNeg;
  884. int nDouble = str.Find(GetDecimalSep());
  885. if (nDouble >= 0)
  886. {
  887. strTemp = str.Left(nDouble);
  888. strExp = str.Right(str.GetLength()-nDouble);
  889. }
  890. else
  891. {
  892. if (str.Find(GetNegativeSign()) == 0)
  893. {
  894. strNeg = str.Left(1);
  895. strTemp = str.Right(str.GetLength()-1);
  896. }
  897. else
  898. strTemp = str;
  899. }
  900. int len = strTemp.GetLength();
  901. if (len <= 3 || len > nMaxDigLen)
  902. return;
  903. LPCTSTR pBuf = strTemp;
  904. pBuf += (len-1);
  905. TCHAR tempbuf[nMaxDigLen+1];
  906. LPTSTR pTempBuf = tempbuf;
  907. LPCTSTR pSep = GetThousandSep();
  908. for(int i=0;i < len;i++)
  909. {
  910. if (i && ((i % 3) == 0)) 
  911. {
  912. if (*pTempBuf != *pSep)
  913. {
  914. *pTempBuf =  *pSep;
  915. pTempBuf = _tcsinc(pTempBuf);
  916. }
  917. }
  918. *pTempBuf = *pBuf;
  919. pTempBuf = _tcsinc(pTempBuf);
  920. pBuf = _tcsdec(strTemp,pBuf);
  921. }
  922. *pTempBuf = '';
  923. _tcsrev(tempbuf);
  924. str = strNeg;
  925. str += tempbuf;
  926. str += strExp;
  927. }
  928. BOOL CUIODListCtrl::AddString(int nRow,int nCol,int nValue,CUIODListCtrl::eColTypes type)
  929. {
  930. CString sValue;
  931. sValue.Format(_T("%d"),nValue);
  932. return AddString(nRow,nCol,sValue,type);
  933. }
  934. BOOL CUIODListCtrl::AddString(int nRow,int nCol,double dValue,CUIODListCtrl::eColTypes type)
  935. {
  936. char szBuf[nMaxDigLen];
  937. _gcvt(dValue,_MAX_INT_DIG,szBuf);
  938. #ifdef _UNICODE
  939. USES_CONVERSION;
  940. return AddString(nRow,nCol,A2W(szBuf),type);
  941. #else
  942. return AddString(nRow,nCol,szBuf,type);
  943. #endif
  944. }
  945. BOOL CUIODListCtrl::AddString(int nRow,int nCol,COleDateTime &dtValue,CUIODListCtrl::eColTypes type)
  946. {
  947. return AddString(nRow,nCol,dtValue.Format(),type);
  948. }
  949. BOOL CUIODListCtrl::AddString(int nRow,int nCol,LPCTSTR szItem,CUIODListCtrl::eColTypes type)
  950. {
  951. if (m_nItems == 0) 
  952. {
  953. TRACE(_T("No rows defined in ODListCtrln")); 
  954. return FALSE;
  955. }
  956. if (nCol >= m_nSubItems) 
  957. {
  958. TRACE(_T("Tried to add invalid column number(%d) in ODListCtrln"),nCol); 
  959. return FALSE;
  960. }
  961. SetColType(nCol,type);
  962. // return SetItemText(nRow,nCol/*+m_nImage*/,szItem);
  963. CUIStrListCtrlData *pData = (CUIStrListCtrlData *)GetListCtrlData(nRow);
  964. ASSERT_KINDOF(CUIStrListCtrlData,pData);
  965. BOOL ret=FALSE;
  966. if (type == e_NumericFormatComma || type == e_DoubleFormatComma)
  967. {
  968. CString sBuf(szItem);
  969. AddThousandSeps(sBuf);
  970. ret = pData->AddString(nCol,sBuf);
  971. }
  972. else if (type == e_NumericFormatTime || type == e_DoubleFormatTime)
  973. {
  974. CString sBuf(szItem);
  975. ConvertToTime(sBuf);
  976. ret = pData->AddString(nCol,sBuf);
  977. }
  978. else
  979. ret = pData->AddString(nCol,szItem);
  980. return ret;
  981. }   
  982. void CUIODListCtrl::UpdateString(int nRow)
  983. CRect rect;
  984. if (GetItemRect(nRow,&rect,LVIR_BOUNDS))
  985. {
  986. RedrawItems(nRow,nRow);
  987. UpdateWindow();
  988. }
  989. }
  990. int CUIODListCtrl::AddCallBackItem(DWORD dwData,int nImage)
  991. {
  992. if (m_nSubItems == 0) 
  993. {
  994. TRACE(_T("No columns defined in ODListCtrln")); 
  995. return FALSE;
  996. }
  997. CUIListCtrlData *pListCtrlData = GetNewListCtrlData(dwData,m_nItems);
  998. BOOL ret = InsertItem(LPSTR_TEXTCALLBACK,(LPARAM)pListCtrlData,nImage);
  999. if (ret)
  1000. m_objList.Append(pListCtrlData);
  1001. else
  1002. delete pListCtrlData;
  1003. return ret ? m_nItems-1 : -1;
  1004. }
  1005. int CUIODListCtrl::AddTextItem(int nImage)
  1006. {
  1007. CUIStrListCtrlData *pListCtrlData = new CUIStrListCtrlData(m_nSubItems);
  1008. if (InsertItem(LPSTR_TEXTCALLBACK,(LPARAM)pListCtrlData,nImage))
  1009. {
  1010. m_objList.Append(pListCtrlData);
  1011. return m_nItems-1;
  1012. }
  1013. delete pListCtrlData;
  1014. return -1;
  1015. }
  1016. int CUIODListCtrl::GetImageIndex(UINT nIconID)
  1017. {
  1018. int nImage = 0;
  1019. if (nIconID)
  1020. {
  1021. if (!m_mapImageIndex.Lookup(nIconID,nImage))
  1022. {
  1023. nImage = AddIcon(nIconID);
  1024. }
  1025. }
  1026. return nImage;
  1027. }
  1028. // from handle
  1029. int CUIODListCtrl::AddIcon(HICON hIcon,UINT nIconID)
  1030. {
  1031. CImageList *pILSmall = NULL;
  1032. CImageList *pILLarge = NULL;
  1033. GetImageLists(&pILSmall,&pILLarge);
  1034. int nSmallIndex = pILSmall->Add(hIcon);
  1035. // save the image ID
  1036. if (nIconID)
  1037. m_mapImageIndex[nIconID] = nSmallIndex;
  1038. int nLargeIndex = pILLarge->Add(hIcon); 
  1039. if (nSmallIndex == -1 || nLargeIndex == -1)
  1040. {
  1041. TRACE(_T("Failed to add icon to image list in CUIODListCtrln"));
  1042. return -1;
  1043. }
  1044. return nSmallIndex;
  1045. }
  1046. // from resource id
  1047. int CUIODListCtrl::AddIcon(UINT nIconID)
  1048. {
  1049. HICON hIcon = AfxGetApp()->LoadIcon(nIconID);
  1050. if (hIcon == NULL)
  1051. {
  1052. TRACE(_T("LoadIcon failed in CUIODListCtrln"));
  1053. return -1;
  1054. }
  1055. return AddIcon(hIcon,nIconID);
  1056. }
  1057. // from file
  1058. int CUIODListCtrl::AddIcon(LPCTSTR pszIcon)
  1059. {
  1060. CString sImageFile;
  1061. int nIndex;
  1062. if (m_mapImageFile.Lookup(sImageFile,nIndex))
  1063. {
  1064. return nIndex;
  1065. }
  1066.     HICON hIcon = (HICON)LoadImage(AfxGetInstanceHandle(), 
  1067.             pszIcon,
  1068.             IMAGE_ICON,
  1069.             ::GetSystemMetrics(SM_CXICON),
  1070.             ::GetSystemMetrics(SM_CYICON),
  1071.             LR_LOADFROMFILE);
  1072. if (hIcon == NULL)
  1073. {
  1074. TRACE(_T("LoadImage(Large) failed in CUIODListCtrln"));
  1075. }
  1076.     HICON hIconSm = (HICON)LoadImage(AfxGetInstanceHandle(), 
  1077.             pszIcon,
  1078.             IMAGE_ICON,
  1079.             ::GetSystemMetrics(SM_CXSMICON),
  1080.             ::GetSystemMetrics(SM_CYSMICON),
  1081.             LR_LOADFROMFILE);
  1082. if (hIconSm == NULL)
  1083. {
  1084. TRACE(_T("LoadImage(Small) failed in CUIODListCtrln"));
  1085. }
  1086. if (hIcon == NULL && hIconSm == NULL)
  1087. return -1;
  1088. CImageList *pILSmall = NULL;
  1089. CImageList *pILLarge = NULL;
  1090. GetImageLists(&pILSmall,&pILLarge);
  1091. int nSmallIndex = pILSmall->Add(hIconSm);
  1092. int nLargeIndex = pILLarge->Add(hIcon); 
  1093. if (nSmallIndex == -1 || nLargeIndex == -1)
  1094. {
  1095. TRACE(_T("Failed to add icon to image list in CUIODListCtrln"));
  1096. return -1;
  1097. }
  1098. sImageFile = pszIcon;
  1099. m_mapImageFile[sImageFile] = nSmallIndex;
  1100. return nSmallIndex;
  1101. }
  1102. BOOL CUIODListCtrl::InsertItem(LPTSTR szItem,LPARAM lParam,int nImage)
  1103. {
  1104. LV_ITEM lvi;
  1105. lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
  1106. lvi.state = 0;      
  1107. lvi.stateMask = 0;  
  1108. lvi.iItem = m_nItems;
  1109. lvi.iSubItem = 0;
  1110. lvi.pszText = szItem; 
  1111. lvi.cchTextMax = MAX_TEXT;
  1112. lvi.iImage = nImage;
  1113. lvi.lParam = lParam;
  1114. if (CListCtrl::InsertItem(&lvi) == -1) 
  1115. {
  1116. TRACE1("Unable to insert item %u into list controln",m_nItems);
  1117. return FALSE;
  1118. }
  1119. if (nImage) 
  1120. m_nImage = 1;
  1121. m_nItems++;
  1122. return TRUE;
  1123. }
  1124. int CUIODListCtrl::SetCurSel(int nSelect)
  1125. {
  1126. if (GetItemCount() && SetItemState(nSelect,LVIS_SELECTED | LVIS_FOCUSED,LVIS_SELECTED | LVIS_FOCUSED))
  1127. return TRUE;
  1128. return -1;
  1129. }
  1130. // messages
  1131. LRESULT CUIODListCtrl::OnSetColumnWidth(WPARAM wParam,LPARAM lParam)
  1132. {
  1133. Default();
  1134. return TRUE;
  1135. }
  1136. LRESULT CUIODListCtrl::OnDeleteAllItems(WPARAM wParam,LPARAM lParam)
  1137. {
  1138. m_nItems=0;
  1139. m_nImage=0;
  1140. m_hOrigFont=NULL;
  1141. AllItemsDeleted();
  1142. m_objList.DeleteAll();
  1143. TRACE0("All items deleted in CUIODListCtrln");
  1144. Default();
  1145. return TRUE;
  1146. }
  1147. CUIListCtrlData *CUIODListCtrl::GetNewListCtrlData(DWORD dwData,int nItem)
  1148. {
  1149. CUIListCtrlData *pListCtrlData = new CUIListCtrlData(m_nSubItems);
  1150. pListCtrlData->SetExtData(dwData); 
  1151. return pListCtrlData;
  1152. }
  1153. int CUIODListCtrl::FindItem(DWORD dwExtData)
  1154. {
  1155. int count = GetItemCount();
  1156. CUIListCtrlData *pData;
  1157. for(int i=0;i < count;i++) 
  1158. {
  1159. pData = GetListCtrlData(i);
  1160. if (pData->GetExtData() == dwExtData)
  1161. break;
  1162. }
  1163. return i == count ? -1 : i;
  1164. }
  1165. BOOL CUIODListCtrl::GetFullRowSel() const
  1166. {
  1167. return(m_bFullRowSel);
  1168. }
  1169. DWORD CUIODListCtrl::GetExStyle() 
  1170. {
  1171. return SendMessage(LVM_GETEXTENDEDLISTVIEWSTYLE);
  1172. }
  1173. BOOL CUIODListCtrl::SetExStyle(UINT nStyle,BOOL bModify)
  1174. {
  1175. DWORD dwStyle = GetExStyle();
  1176. if (bModify)
  1177. dwStyle |= nStyle;
  1178. else
  1179. dwStyle &= ~nStyle;
  1180. BOOL bRet = SendMessage(LVM_SETEXTENDEDLISTVIEWSTYLE, 0, dwStyle);
  1181. if (bRet)
  1182. SaveProfile();
  1183. return bRet;
  1184. }
  1185. void CUIODListCtrl::SetFullRowSel(bool bSet)
  1186. {
  1187. // no painting during change
  1188. if ((bSet && m_bFullRowSel==TRUE) || (!bSet && m_bFullRowSel==FALSE))
  1189. return;
  1190. m_bFullRowSel=bSet;
  1191. if(!(GetStyle() & LVS_OWNERDRAWFIXED)) 
  1192. {
  1193. SetExStyle(LVS_EX_FULLROWSELECT,m_bFullRowSel);
  1194. }
  1195. RedrawItems(GetCurSel(),GetCurSel());
  1196. SaveProfile();
  1197. }
  1198. void CUIODListCtrl::SetIconSize(int nImageList)
  1199. {
  1200. m_nImageList = nImageList;
  1201. CRect rc;
  1202. GetWindowRect(rc);
  1203. GetParent()->ScreenToClient(rc);
  1204. rc.bottom++; // Force a WM_MEASUREITEM message
  1205. MoveWindow(rc,FALSE);
  1206. rc.bottom--; // We really don't want to resize it
  1207. MoveWindow(rc,TRUE);
  1208. }
  1209. void CUIODListCtrl::ChangeIconSize()
  1210. {
  1211. SetCurSel(0);
  1212. EnsureVisible(0,0);
  1213. if (m_nImageList == LVSIL_NORMAL)
  1214. SetIconSize(LVSIL_SMALL);
  1215. else
  1216. SetIconSize(LVSIL_NORMAL);
  1217. }
  1218. BOOL CUIODListCtrl::GetDispInfo(LV_DISPINFO *pDispInfo)
  1219. {
  1220. CUIStrListCtrlData *pData = (CUIStrListCtrlData*)pDispInfo->item.lParam;
  1221. ASSERT_KINDOF(CUIStrListCtrlData,pData);
  1222. if (!pData->IsKindOf(RUNTIME_CLASS(CUIStrListCtrlData)))
  1223. return FALSE;
  1224. pDispInfo->item.pszText = pData->GetString(pDispInfo->item.iSubItem);
  1225. return TRUE;
  1226. }
  1227. BOOL CUIODListCtrl::PopupMenuItem(int nItem,int nCol,CMenu *pPopup,CPoint point)
  1228. {
  1229. int nCurSel = GetCurSel();
  1230. int nSel = GetNextSel(nCurSel);
  1231. UINT nPopupID = (nSel == -1 ? m_PopupID : m_MultiPopupID);
  1232. if (nPopupID && (nCol == 0 && nItem != -1))
  1233. {
  1234. CMenu menu;
  1235. VERIFY(menu.LoadMenu(nPopupID));
  1236. CMenu* pMyPopup = menu.GetSubMenu(0);
  1237. ASSERT(pMyPopup != NULL);
  1238. if (m_pPopupWnd == NULL)
  1239. m_pPopupWnd = this;
  1240. pMyPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, m_pPopupWnd);
  1241. return TRUE;
  1242. }
  1243. return nSel == -1 ? FALSE : TRUE;
  1244. }
  1245. int CUIODListCtrl::HitTestEx(CPoint &point, int *col) const
  1246. {
  1247. int colnum = 0;
  1248. int row = HitTest( point, NULL );
  1249. if( col ) *col = 0;
  1250. // Make sure that the ListView is in LVS_REPORT
  1251. if( (GetWindowLong(m_hWnd, GWL_STYLE) & LVS_TYPEMASK) != LVS_REPORT)
  1252. return row;
  1253. // Get the top and bottom row visible
  1254. row = GetTopIndex();
  1255. int bottom = row + GetCountPerPage();
  1256. if( bottom > GetItemCount() )
  1257. bottom = GetItemCount();
  1258. // Get the number of columns
  1259. CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0);
  1260. int nColumnCount = pHeader->GetItemCount();
  1261. CRect rcHeader;
  1262. pHeader->GetClientRect(&rcHeader);
  1263. if (point.y >= 0 && point.y <= rcHeader.Height())
  1264. return -2;
  1265. // Loop through the visible rows
  1266. for( ;row <=bottom;row++)
  1267. {
  1268. // Get bounding rect of item and check whether point falls in it.
  1269. CRect rect;
  1270. GetItemRect( row, &rect, LVIR_BOUNDS );
  1271. if( rect.PtInRect(point) )
  1272. {
  1273. // Now find the column
  1274. for( colnum = 0; colnum < nColumnCount; colnum++ )
  1275. {
  1276. int colwidth = GetColumnWidth(colnum);
  1277. if( point.x >= rect.left 
  1278. && point.x <= (rect.left + colwidth ) )
  1279. {
  1280. if( col ) *col = colnum;
  1281. return row;
  1282. }
  1283. rect.left += colwidth;
  1284. }
  1285. }
  1286. }
  1287. return -1;
  1288. }
  1289. CEdit* CUIODListCtrl::EditSubLabel( int nItem, int nCol )
  1290. {
  1291. // The returned pointer should not be saved
  1292. if (m_bEditSubItems == false || (GetWindowLong(m_hWnd, GWL_STYLE) & LVS_EDITLABELS) != LVS_EDITLABELS)
  1293. {
  1294. return NULL;
  1295. }
  1296. // Make sure that the item is visible
  1297. if( !EnsureVisible( nItem, TRUE ) ) 
  1298. return NULL;
  1299. // Make sure that nCol is valid
  1300. CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0);
  1301. if (pHeader == NULL)
  1302. return NULL;
  1303. int nColumnCount = pHeader->GetItemCount();
  1304. if( nCol >= nColumnCount || GetColumnWidth(nCol) < 5 )
  1305. return NULL;
  1306. // Get the column offset
  1307. int offset = 0;
  1308. for( int i = 0; i < nCol; i++ )
  1309. offset += GetColumnWidth( i );
  1310. CRect rect;
  1311. GetItemRect( nItem, &rect, LVIR_BOUNDS );
  1312. // Now scroll if we need to expose the column
  1313. CRect rcClient;
  1314. GetClientRect( &rcClient );
  1315. if( offset + rect.left < 0 || offset + rect.left > rcClient.right )
  1316. {
  1317. CSize size;
  1318. size.cx = offset + rect.left;
  1319. size.cy = 0;
  1320. Scroll( size );
  1321. rect.left -= size.cx;
  1322. }
  1323. // Get Column alignment
  1324. LV_COLUMN lvcol;
  1325. lvcol.mask = LVCF_FMT;
  1326. GetColumn( nCol, &lvcol );
  1327. DWORD dwStyle ;
  1328. if((lvcol.fmt&LVCFMT_JUSTIFYMASK) == LVCFMT_LEFT)
  1329. dwStyle = ES_LEFT;
  1330. else if((lvcol.fmt&LVCFMT_JUSTIFYMASK) == LVCFMT_RIGHT)
  1331. dwStyle = ES_RIGHT;
  1332. else dwStyle = ES_CENTER;
  1333. rect.left += offset+4;
  1334. rect.right = rect.left + GetColumnWidth( nCol ) - 3 ;
  1335. if( rect.right > rcClient.right) rect.right = rcClient.right;
  1336. dwStyle |= WS_BORDER|WS_CHILD|WS_VISIBLE|ES_AUTOHSCROLL;
  1337. CEdit *pEdit = new CInPlaceEdit(nItem, nCol, GetItemText( nItem, nCol ));
  1338. pEdit->Create( dwStyle, rect, this, -1/*IDC_IPEDIT*/ );
  1339. return pEdit;
  1340. }
  1341. void CUIODListCtrl::DeleteProgressBar(int nRow,int nCol)
  1342. {
  1343. CUIListCtrlData *pData = GetListCtrlData(nRow);
  1344. if (pData)
  1345. {
  1346. pData->DestroyCtrl(nCol);
  1347. RedrawItems(nRow,nRow);
  1348. }
  1349. }
  1350. void CUIODListCtrl::UpdateProgressBar(int nRow,int nCol,int nPos)
  1351. {
  1352. CUIListCtrlData *pData = GetListCtrlData(nRow);
  1353. ASSERT(pData);
  1354. if (pData == NULL)
  1355. return;
  1356. CTextProgressCtrl *pCtrl = (CTextProgressCtrl*)pData->GetCtrl(nCol);
  1357. if (pCtrl)
  1358. {
  1359. pCtrl->SetPos(nPos);
  1360. RedrawItems(nRow,nRow);
  1361. }
  1362. }
  1363. CTextProgressCtrl *CUIODListCtrl::AddProgressBar(int nItem,int nCol,int nMin,int nMax)
  1364. {
  1365. // The returned pointer should not be saved
  1366. if (GetViewType() != LVS_REPORT)
  1367. return NULL;
  1368. CUIListCtrlData *pData = GetListCtrlData(nItem);
  1369. if (pData == NULL)
  1370. return NULL;
  1371. CTextProgressCtrl *pCtrl = new CTextProgressCtrl;
  1372. pData->SetCtrl(pCtrl,nCol);
  1373. pCtrl->SetRange(nMin,nMax);
  1374. return pCtrl;
  1375. }
  1376. //
  1377. // Message handlers
  1378. //
  1379. void CUIODListCtrl::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
  1380. {
  1381. if (GetFocus() != this) 
  1382. SetFocus();
  1383. CListCtrl::OnHScroll(nSBCode, nPos, pScrollBar);
  1384. }
  1385. void CUIODListCtrl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
  1386. {
  1387. if (GetFocus() != this) 
  1388. SetFocus();
  1389. CListCtrl::OnVScroll(nSBCode, nPos, pScrollBar);
  1390. }
  1391. void CUIODListCtrl::OnLButtonDown(UINT nFlags, CPoint point)
  1392. {
  1393. CListCtrl::OnLButtonDown(nFlags, point);
  1394. }
  1395. BOOL CUIODListCtrl::OnSelChanged(int nItem, LRESULT* pResult)
  1396. {
  1397. SelChanged( nItem , pResult );
  1398. return TRUE;
  1399. }
  1400. BOOL CUIODListCtrl::OnEndLabelEdit(NMHDR* pNMHDR, LRESULT* pResult)
  1401. {
  1402. LV_DISPINFO *plvDispInfo = (LV_DISPINFO *)pNMHDR;
  1403. LV_ITEM *plvItem = &plvDispInfo->item;
  1404. if (plvItem->pszText != NULL)
  1405. {
  1406. if (plvItem->iItem == -1)
  1407. {
  1408. CHeaderCtrl *pHeader = (CHeaderCtrl*)GetDlgItem(0);
  1409. if (pHeader)
  1410. {
  1411. CString strText;
  1412. GetHeaderText(pHeader,plvItem->iSubItem,strText);
  1413. HD_ITEM hdItem;
  1414. ZeroMemory(&hdItem,sizeof(hdItem));
  1415. hdItem.mask = HDI_TEXT;
  1416. hdItem.pszText = plvItem->pszText;
  1417. hdItem.cchTextMax = lstrlen(plvItem->pszText);
  1418. ReplaceString(m_strHeadings,strText,plvItem->pszText);
  1419. if (EndLabelEdit(plvItem->iItem,plvItem->iSubItem,plvItem->pszText))
  1420. pHeader->SetItem(plvItem->iSubItem,&hdItem);
  1421. }
  1422. }
  1423. else
  1424. {
  1425. if (EndLabelEdit(plvItem->iItem,plvItem->iSubItem,plvItem->pszText))
  1426. AddString(plvItem->iItem, plvItem->iSubItem, plvItem->pszText);
  1427. }
  1428. }
  1429. *pResult = FALSE;
  1430. return TRUE;
  1431. }
  1432. LRESULT CUIODListCtrl::OnDeleteItem(WPARAM wParam,LPARAM lParam)
  1433. {
  1434. if (m_nItems)
  1435. m_nItems--;
  1436. TRACE(_T("Item deleted %dn"),wParam);
  1437. return Default();
  1438. }
  1439. LRESULT CUIODListCtrl::OnDeleteColumn(WPARAM wParam,LPARAM lParam)
  1440. {
  1441. if (m_nSubItems)
  1442. m_nSubItems--;
  1443. TRACE(_T("Column deleted %dn"),wParam);
  1444. return Default();
  1445. }
  1446. LRESULT CUIODListCtrl::OnSetImageList(WPARAM wParam, LPARAM lParam)
  1447. {
  1448. if((int)wParam==LVSIL_STATE)
  1449. {
  1450. int cx, cy;
  1451. if(::ImageList_GetIconSize((HIMAGELIST)lParam,&cx,&cy))
  1452. m_cxStateImageOffset=cx;
  1453. else
  1454. m_cxStateImageOffset=0;
  1455. }
  1456. return Default();
  1457. }
  1458. LRESULT CUIODListCtrl::OnSetTextColor(WPARAM wParam, LPARAM lParam)
  1459. {
  1460. m_clrText=(COLORREF)lParam;
  1461. return(Default());
  1462. }
  1463. LRESULT CUIODListCtrl::OnSetTextBkColor(WPARAM wParam, LPARAM lParam)
  1464. {
  1465. m_clrTextBk=(COLORREF)lParam;
  1466. return(Default());
  1467. }
  1468. LRESULT CUIODListCtrl::OnSetBkColor(WPARAM wParam, LPARAM lParam)
  1469. {
  1470. m_clrBkgnd=(COLORREF)lParam;
  1471. return(Default());
  1472. }
  1473. void CUIODListCtrl::OnSize(UINT nType, int cx, int cy) 
  1474. {
  1475. m_cxClient=cx;
  1476. CListCtrl::OnSize(nType, cx, cy);
  1477. }
  1478. void CUIODListCtrl::OnPaint() 
  1479. {
  1480. if (m_bDelayPaint)
  1481. return;
  1482. Default();
  1483.     if (GetItemCount() <= 0)
  1484.     {
  1485.         COLORREF clrText = ::GetSysColor(COLOR_WINDOWTEXT);
  1486.         COLORREF clrTextBk = ::GetSysColor(COLOR_WINDOW);
  1487.         CDC* pDC = GetDC();
  1488.         // Save dc state
  1489.         int nSavedDC = pDC->SaveDC();
  1490.         CRect rc;
  1491.         GetWindowRect(&rc);
  1492.         ScreenToClient(&rc);
  1493.         CHeaderCtrl* pHC;
  1494.         pHC = GetHeaderCtrl();
  1495.         if (pHC != NULL)
  1496.         {
  1497.             CRect rcH;
  1498.             pHC->GetItemRect(0, &rcH);
  1499.             rc.top += rcH.bottom;
  1500.         }
  1501.         rc.top += 10;
  1502.         pDC->SetTextColor(clrText);
  1503.         pDC->SetBkColor(clrTextBk);
  1504.         pDC->FillRect(rc, &CBrush(clrTextBk));
  1505.         pDC->SelectStockObject(ANSI_VAR_FONT);
  1506.         pDC->DrawText(m_strNoItemsMess, -1, rc, 
  1507.                       DT_CENTER | DT_WORDBREAK | DT_NOPREFIX | DT_NOCLIP);
  1508.         // Restore dc
  1509.         pDC->RestoreDC(nSavedDC);
  1510.         ReleaseDC(pDC);
  1511.     }
  1512.     // Do not call CListCtrl::OnPaint() for painting messages
  1513. // in full row select mode, we need to extend the clipping region
  1514. // so we can paint a selection all the way to the right
  1515. if(m_bClientWidthSel && (GetStyle() & LVS_TYPEMASK)==LVS_REPORT && GetFullRowSel() && (GetStyle() & LVS_OWNERDRAWFIXED))
  1516. {
  1517. CRect rcAllLabels;
  1518. GetItemRect(0,rcAllLabels,LVIR_BOUNDS);
  1519. if(rcAllLabels.right<m_cxClient)
  1520. {
  1521. // need to call BeginPaint (in CPaintDC c-tor)
  1522. // to get correct clipping rect
  1523. CPaintDC dc(this);
  1524. CRect rcClip;
  1525. dc.GetClipBox(rcClip);
  1526. rcClip.left=min(rcAllLabels.right-1,rcClip.left);
  1527. // rcClip.right=m_cxClient;
  1528. InvalidateRect(rcClip,FALSE);
  1529. // EndPaint will be called in CPaintDC d-tor
  1530. }
  1531. }
  1532. // CListCtrl::OnPaint();
  1533. }
  1534. void CUIODListCtrl::OnSetFocus(CWnd* pOldWnd) 
  1535. {
  1536. CListCtrl::OnSetFocus(pOldWnd);
  1537. if(pOldWnd!=NULL && ::IsWindow(pOldWnd->m_hWnd))
  1538. {
  1539. // check if we are getting focus from label edit box
  1540. if(pOldWnd!=NULL && pOldWnd->GetParent()==this)
  1541. return;
  1542. }
  1543. }
  1544. void CUIODListCtrl::OnKillFocus(CWnd* pNewWnd) 
  1545. {
  1546. CListCtrl::OnKillFocus(pNewWnd);
  1547. // check if we are losing focus to label edit box
  1548. if (pNewWnd!=NULL && pNewWnd->GetParent()==this)
  1549. return;
  1550. }
  1551. void CUIODListCtrl::OnRClickHeader(CPoint point,int nColIndex)
  1552. {
  1553. m_nColClicked = nColIndex;
  1554. CMenu menu;
  1555. VERIFY(menu.LoadMenu(IDR_POPUPMENU_HEADERCTRL));
  1556. CMenu* pPopup = menu.GetSubMenu(0);
  1557. ASSERT(pPopup != NULL);
  1558. pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y,this);
  1559. }
  1560. void CUIODListCtrl::OnHeaderRemoveColumn()
  1561. {
  1562. if (m_nColClicked != -1)
  1563. {
  1564. int nWidth = GetColumnWidth(m_nColClicked);
  1565. if (nWidth)
  1566. {
  1567. m_pColWidths[m_nColClicked] = nWidth;
  1568. SetColumnWidth(m_nColClicked,0);
  1569. }
  1570. m_nColClicked = -1;
  1571. }
  1572. }
  1573. void CUIODListCtrl::OnHeaderEditText()
  1574. {
  1575. CHeaderCtrl *pHeader = (CHeaderCtrl*)GetDlgItem(0);
  1576. if (pHeader == NULL)
  1577. return;
  1578. CString strText;
  1579. int cxy = GetHeaderText(pHeader,m_nColClicked,strText);
  1580. int xPos = 0;
  1581. for(int i=0;i < m_nSubItems;i++)
  1582. {
  1583. if (i == m_nColClicked)
  1584. break;
  1585. xPos += m_pColWidths[i];
  1586. }
  1587. CRect rect;
  1588. rect.left = xPos;
  1589. rect.right = rect.left+cxy;
  1590. rect.top = 0;
  1591. rect.bottom = GetSystemMetrics(SM_CXHSCROLL);
  1592. TRACE2("Creating header edit control at left=%d,right=%dn",rect.left,rect.right);
  1593. DWORD dwStyle = WS_BORDER|WS_CHILD|WS_VISIBLE|ES_AUTOHSCROLL;
  1594. CEdit *pEdit = new CInPlaceEdit(-1, m_nColClicked, strText);
  1595. pEdit->Create( dwStyle, rect, this, -1/*IDC_IPEDIT*/ );
  1596. m_nColClicked = -1;
  1597. }
  1598. int CUIODListCtrl::GetHeaderText(CHeaderCtrl *pHeader,int nPos,CString &strText)
  1599. {
  1600. HD_ITEM hdItem;
  1601. ZeroMemory(&hdItem,sizeof(hdItem));
  1602. int nLen = 128;
  1603. int nRes;
  1604. do
  1605. {
  1606. nLen *= 2;
  1607. hdItem.mask = HDI_TEXT | HDI_WIDTH;
  1608. hdItem.cchTextMax = nLen;
  1609. hdItem.pszText = strText.GetBufferSetLength(nLen);
  1610. pHeader->GetItem(nPos,&hdItem);
  1611. nRes = lstrlen(hdItem.pszText);
  1612. } while (nRes == nLen-1);
  1613. strText.ReleaseBuffer(-1);
  1614. return hdItem.cxy;
  1615. }
  1616. void CUIODListCtrl::OnHeaderReset()
  1617. {
  1618. for(int i=0;i < m_nSubItems;i++)
  1619. {
  1620. SetColumnWidth(i,m_pColWidths[i]);
  1621. }
  1622. m_nColClicked = -1;
  1623. }
  1624. void CUIODListCtrl::OnContextMenu(CWnd *pWnd,CPoint point)
  1625. {
  1626. CPoint ptClient(point);
  1627. ScreenToClient(&ptClient);
  1628. // int nCol;
  1629. int nRow = HitTestEx(ptClient, NULL );
  1630. if (nRow == -2 || nRow == -1 )
  1631. return;
  1632. ShowPopupMenu( nRow , 0 , point );
  1633. }
  1634. void CUIODListCtrl::ShowPopupMenu(int nRow,int nCol,CPoint point)
  1635. {
  1636. CMenu menu;
  1637. VERIFY(menu.LoadMenu(IDR_POPUPMENU_LISTCTRL));
  1638. CMenu* pPopup = menu.GetSubMenu(0);
  1639. ASSERT(pPopup != NULL);
  1640. m_PopupPoint.x = 0;
  1641. m_PopupPoint.y = 0;
  1642. if (PopupMenuItem(nRow,nCol,pPopup,point))
  1643. return;
  1644. m_PopupPoint = point;
  1645. pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y,this);
  1646. }
  1647. void CUIODListCtrl::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu)
  1648. {
  1649. // is it for us?
  1650. if (m_PopupPoint.x == 0 && m_PopupPoint.y == 0)
  1651. return;
  1652. if (pPopupMenu->GetMenuItemID(0) == ID_HEADER_REMOVE_COL)
  1653. {
  1654. if (m_nColClicked == -1)
  1655. {
  1656. pPopupMenu->EnableMenuItem(ID_HEADER_EDIT_TEXT,MF_BYCOMMAND | MF_GRAYED);
  1657. pPopupMenu->EnableMenuItem(ID_HEADER_RESET,MF_BYCOMMAND | MF_GRAYED);
  1658. }
  1659. return;
  1660. }
  1661. // These commands are only available in report mode(detail mode)
  1662. UINT nEnabled = (GetViewType() == LVS_REPORT) ? MF_ENABLED : MF_GRAYED; 
  1663. pPopupMenu->EnableMenuItem(ID_UI_VIEW_FULL_ROW_SELECTION,MF_BYCOMMAND | nEnabled);
  1664. pPopupMenu->EnableMenuItem(ID_UI_VIEW_GRIDLINES,MF_BYCOMMAND | nEnabled);
  1665. pPopupMenu->EnableMenuItem(ID_UI_VIEW_COLUMN_SIZING,MF_BYCOMMAND | nEnabled);
  1666. pPopupMenu->EnableMenuItem(ID_UI_VIEW_COLUMN_ORDERING,MF_BYCOMMAND | nEnabled);
  1667. if (nEnabled == MF_ENABLED)
  1668. pPopupMenu->EnableMenuItem(ID_UI_VIEW_EDIT_COLUMN,MF_BYCOMMAND | (m_bEditSubItems && (GetStyle() & LVS_EDITLABELS)) ? MF_ENABLED : MF_GRAYED);
  1669. else
  1670. pPopupMenu->EnableMenuItem(ID_UI_VIEW_EDIT_COLUMN,MF_BYCOMMAND | MF_GRAYED);
  1671. // won't work with owner draw list control
  1672. if (GetStyle() & LVS_OWNERDRAWFIXED)
  1673. {
  1674. pPopupMenu->EnableMenuItem(ID_UI_VIEW_CHECKBOXES,MF_BYCOMMAND | MF_GRAYED);
  1675. }
  1676. UINT nIDItem=ID_VIEW_DETAILS;
  1677. switch(GetViewType())
  1678. {
  1679. case LVS_ICON:
  1680. nIDItem = ID_UI_VIEW_LARGE_ICONS;
  1681. break;
  1682. case LVS_SMALLICON:
  1683. nIDItem = ID_UI_VIEW_SMALL_ICONS;
  1684. break;
  1685. case LVS_LIST:
  1686. nIDItem = ID_UI_VIEW_LIST;
  1687. break;
  1688. case LVS_REPORT:
  1689. nIDItem = ID_UI_VIEW_DETAILS;
  1690. break;
  1691. }
  1692. pPopupMenu->CheckMenuRadioItem(ID_UI_VIEW_LARGE_ICONS,ID_VIEW_LIST,nIDItem,MF_BYCOMMAND);
  1693. DWORD dwExStyle = GetExStyle();
  1694. if (m_bFullRowSel)
  1695. pPopupMenu->CheckMenuItem(ID_UI_VIEW_FULL_ROW_SELECTION,MF_BYCOMMAND | MF_CHECKED);
  1696. if (m_bColumnSizing)
  1697. pPopupMenu->CheckMenuItem(ID_UI_VIEW_COLUMN_SIZING,MF_BYCOMMAND | MF_CHECKED);
  1698. if ((dwExStyle & LVS_EX_HEADERDRAGDROP))
  1699. pPopupMenu->CheckMenuItem(ID_UI_VIEW_COLUMN_ORDERING,MF_BYCOMMAND | MF_CHECKED);
  1700. if ((dwExStyle & LVS_EX_GRIDLINES))
  1701. pPopupMenu->CheckMenuItem(ID_UI_VIEW_GRIDLINES,MF_BYCOMMAND | MF_CHECKED);
  1702. if ((dwExStyle & LVS_EX_CHECKBOXES))
  1703. pPopupMenu->CheckMenuItem(ID_UI_VIEW_CHECKBOXES,MF_BYCOMMAND | MF_CHECKED);
  1704. if ((dwExStyle & LVS_EX_TRACKSELECT))
  1705. pPopupMenu->CheckMenuItem(ID_UI_VIEW_TRACK_SELECT,MF_BYCOMMAND | MF_CHECKED);
  1706. }
  1707. void CUIODListCtrl::OnViewLargeIcons()
  1708. {
  1709. SetViewType(LVS_ICON);
  1710. }
  1711. void CUIODListCtrl::OnViewSmallIcons()
  1712. {
  1713. SetViewType(LVS_SMALLICON);
  1714. }
  1715. void CUIODListCtrl::OnViewDetails()
  1716. {
  1717. SetViewType(LVS_REPORT);
  1718. }
  1719. void CUIODListCtrl::OnViewList()
  1720. {
  1721. SetViewType(LVS_LIST);
  1722. }
  1723. void CUIODListCtrl::OnViewFullRowSelection()
  1724. {
  1725. ToggleFullRowSel();
  1726. }
  1727. void CUIODListCtrl::OnViewTrackSelect()
  1728. {
  1729. ToggleTrackSelect();
  1730. }
  1731. void CUIODListCtrl::OnViewGridlines()
  1732. {
  1733. ToggleGridLines();
  1734. }
  1735. void CUIODListCtrl::OnViewCheckboxes()
  1736. {
  1737. ToggleCheckBoxes();
  1738. }
  1739. void CUIODListCtrl::OnViewColumnOrdering()
  1740. {
  1741. ToggleHeaderDragDrop();
  1742. }
  1743. void CUIODListCtrl::OnViewColumnSizing()
  1744. {
  1745. ToggleColumnSizing();
  1746. }
  1747. void CUIODListCtrl::OnViewEditColumn()
  1748. {
  1749. int index;
  1750. int colnum;
  1751. CPoint point(m_PopupPoint);
  1752. ScreenToClient(&point);
  1753. if (( index = HitTestEx( point, &colnum )) != -1)
  1754. {
  1755. UINT flag = LVIS_FOCUSED;
  1756. if( (GetItemState( index, flag ) & flag) == flag && colnum > 0)
  1757. {
  1758. // Add check for LVS_EDITLABELS
  1759. EditSubLabel( index, colnum );
  1760. }
  1761. }
  1762. }
  1763. LRESULT CUIODListCtrl::OnGetItemText(WPARAM wParam, LPARAM lParam)
  1764. {
  1765. int iItem = (int)wParam; 
  1766. LV_ITEM *pitem = (LV_ITEM*)lParam;
  1767. int nSubItem = pitem->iSubItem;
  1768. int nLen = pitem->cchTextMax;
  1769. const CUIStrListCtrlData *pData = (CUIStrListCtrlData *)GetListCtrlData(iItem);
  1770. // ASSERT_KINDOF(CUIStrListCtrlData,pData);
  1771. if (!pData->IsKindOf(RUNTIME_CLASS(CUIStrListCtrlData)))
  1772. {
  1773. NMLVDISPINFO di;
  1774. di.hdr.hwndFrom = GetSafeHwnd();
  1775. di.hdr.code = LVN_GETDISPINFO;
  1776. memcpy(&di.item,pitem,sizeof(LVITEM));
  1777. di.item.mask = LVIF_TEXT;
  1778. SendMessage(WM_NOTIFY,0,(LPARAM)&di);
  1779. _tcsncpy(pitem->pszText,di.item.pszText,nLen);
  1780. }
  1781. else
  1782. {
  1783. LPTSTR pStr = ((CUIStrListCtrlData *)pData)->GetString(nSubItem);
  1784. if (pStr)
  1785. {
  1786. _tcsncpy(pitem->pszText,pStr,nLen);
  1787. nLen = min(lstrlen(pStr)+1,nLen);
  1788. pitem->pszText[nLen-1] = '';
  1789. return nLen;
  1790. }
  1791. }
  1792. return 0L;
  1793. }
  1794. int CUIODListCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) 
  1795. {
  1796. if (CListCtrl::OnCreate(lpCreateStruct) == -1)
  1797. return -1;
  1798. // TODO: Add your specialized creation code here
  1799. RegisterDropTarget();
  1800. return 0;
  1801. }
  1802. int CALLBACK CompareFunc(LPARAM lParam1,LPARAM lParam2,LPARAM lParamSort);
  1803. PFNLVCOMPARE CUIODListCtrl::GetCompareFunc()
  1804. {
  1805. return CompareFunc;
  1806. }
  1807. BOOL CUIODListCtrl::ColumnClick(NM_LISTVIEW* pNMListView)
  1808. {
  1809. if (pNMListView->iSubItem != m_nSortColumn)
  1810. m_bSortAscending = TRUE;
  1811. else
  1812. m_bSortAscending = !m_bSortAscending;
  1813. m_nSortColumn = pNMListView->iSubItem;
  1814. m_HeaderCtrl.SetSortImage(m_nSortColumn,m_bSortAscending);
  1815. ASSERT(m_pColTypes);
  1816. CUIODListCtrlSortInfo sortinfo(pNMListView->iSubItem,m_pColTypes[pNMListView->iSubItem],m_bSortAscending);
  1817. SortItems(GetCompareFunc(),(DWORD)&sortinfo);
  1818. int item = GetCurSel();
  1819. EnsureVisible(item,0);
  1820. return TRUE;
  1821. }
  1822. ///////////////////////////////////////////////
  1823. // static callback for sorting when the header is clicked in report mode
  1824. int CALLBACK CompareFunc(LPARAM lParam1,LPARAM lParam2,LPARAM lParamSort)
  1825. {
  1826. CUIStrListCtrlData *pData1 = (CUIStrListCtrlData*)lParam1;
  1827. CUIStrListCtrlData *pData2 = (CUIStrListCtrlData*)lParam2;
  1828. ASSERT(pData1);
  1829. ASSERT(pData2);
  1830. ASSERT_KINDOF(CUIStrListCtrlData,pData1);
  1831. ASSERT_KINDOF(CUIStrListCtrlData,pData2);
  1832. CUIODListCtrlSortInfo *pSortInfo = (CUIODListCtrlSortInfo *)lParamSort;
  1833. int ret=0;
  1834. switch(pSortInfo->GetColType())
  1835. {
  1836. case CUIODListCtrl::e_DateTime:
  1837. {
  1838. COleDateTime time1;
  1839. CString str1(pData1->GetString(pSortInfo->GetColumn()));
  1840. if (!str1.IsEmpty())
  1841. time1.ParseDateTime(str1);
  1842. COleDateTime time2;
  1843. CString str2(pData2->GetString(pSortInfo->GetColumn()));
  1844. if (!str2.IsEmpty())
  1845. time2.ParseDateTime(str2);
  1846. if (time1 > time2)
  1847. ret = 1;
  1848. else if (time1 < time2)
  1849. ret = -1;
  1850. break;
  1851. }
  1852. case CUIODListCtrl::e_NumericFormat:
  1853. {
  1854. int num1 = _ttoi(CUIODListCtrl::StripNonNumeric((LPCTSTR)pData1->GetString(pSortInfo->GetColumn()),CUIODListCtrl::e_Numeric));
  1855. int num2 = _ttoi(CUIODListCtrl::StripNonNumeric((LPCTSTR)pData2->GetString(pSortInfo->GetColumn()),CUIODListCtrl::e_Numeric));
  1856. ret = num1-num2;
  1857. break;
  1858. }
  1859. case CUIODListCtrl::e_Numeric:
  1860. {
  1861. int num1 = _ttoi((LPCTSTR)pData1->GetString(pSortInfo->GetColumn()));
  1862. int num2 = _ttoi((LPCTSTR)pData2->GetString(pSortInfo->GetColumn()));
  1863. ret = num1-num2;
  1864. break;
  1865. }
  1866. case CUIODListCtrl::e_DoubleFormat:
  1867. {
  1868. double num1 = _tcstod(CUIODListCtrl::StripNonNumeric((LPCTSTR)pData1->GetString(pSortInfo->GetColumn()),CUIODListCtrl::e_Double),NULL);
  1869. double num2 = _tcstod(CUIODListCtrl::StripNonNumeric((LPCTSTR)pData2->GetString(pSortInfo->GetColumn()),CUIODListCtrl::e_Double),NULL);
  1870. if (num1 > num2)
  1871. ret = 1;
  1872. else if (num1 < num2)
  1873. ret = -1;
  1874. break;
  1875. }
  1876. case CUIODListCtrl::e_Double:
  1877. {
  1878. double num1 = _tcstod((LPCTSTR)pData1->GetString(pSortInfo->GetColumn()),NULL);
  1879. double num2 = _tcstod((LPCTSTR)pData2->GetString(pSortInfo->GetColumn()),NULL);
  1880. if (num1 > num2)
  1881. ret = 1;
  1882. else if (num1 < num2)
  1883. ret = -1;
  1884. break;
  1885. }
  1886. case CUIODListCtrl::e_Text:
  1887. default:
  1888. ret = CompareString(LOCALE_USER_DEFAULT,NORM_IGNORECASE | NORM_IGNOREKANATYPE,
  1889. (LPCTSTR)pData1->GetString(pSortInfo->GetColumn()),
  1890. pData1->GetStringLen(pSortInfo->GetColumn()),
  1891. (LPCTSTR)pData2->GetString(pSortInfo->GetColumn()),
  1892. pData2->GetStringLen(pSortInfo->GetColumn())) - 2;
  1893. break;
  1894. }
  1895. if (!pSortInfo->Ascending())
  1896. ret = -ret;
  1897. return ret;
  1898. }
  1899. void CUIODListCtrl::ReplaceString(CString &rStr,LPCTSTR pszOldText,LPCTSTR pszNewText)
  1900. {
  1901. int nPos = rStr.Find(pszOldText);
  1902. CString strLeft;
  1903. if (nPos != -1)
  1904. {
  1905. strLeft = rStr.Left(nPos);
  1906. CString strRight(rStr.Right(rStr.GetLength()-(nPos+lstrlen(pszOldText))));
  1907. strLeft += pszNewText;
  1908. strLeft += strRight;
  1909. }
  1910. rStr = strLeft;
  1911. }
  1912. void CUIODListCtrl::Sort()
  1913. {
  1914. ASSERT(m_pColTypes);
  1915. CUIODListCtrlSortInfo sortinfo(m_nSortColumn,m_pColTypes[m_nSortColumn],m_bSortAscending);
  1916. SortItems(GetCompareFunc(),(DWORD)&sortinfo);
  1917. m_HeaderCtrl.SetSortImage(m_nSortColumn,m_bSortAscending);
  1918. TRACE1("Sorting column %dn",m_nSortColumn);
  1919. }
  1920. void CUIODListCtrl::SetColFont(int nRow,int nCol,CFont *pFont)
  1921. {
  1922. CUIListCtrlData* pListObj = GetListCtrlData(nRow);
  1923. if (pListObj)
  1924. {
  1925. ASSERT(pFont);
  1926. if (pFont)
  1927. pListObj->SetFont(pFont,nCol);
  1928. }
  1929. }
  1930. void CUIODListCtrl::SetRowFont(int nRow,CFont *pFont)
  1931. {
  1932. CUIListCtrlData* pListObj = GetListCtrlData(nRow);
  1933. if (pListObj)
  1934. {
  1935. ASSERT(pFont);
  1936. if (pFont)
  1937. pListObj->SetFont(pFont);
  1938. }
  1939. }
  1940. void CUIODListCtrl::SetColBold(int nRow,int nCol,BOOL bBold)
  1941. {
  1942. CUIListCtrlData* pListObj = GetListCtrlData(nRow);
  1943. if (pListObj)
  1944. {
  1945. if (!pListObj->IsFontSet(nCol))
  1946. {
  1947. pListObj->SetFont(GetFont(),nCol);
  1948. }
  1949. const CFont *pFont = pListObj->GetFont(nCol);
  1950. LOGFONT lf;
  1951. ((CFont*)pFont)->GetLogFont(&lf);
  1952. lf.lfWeight = bBold ? FW_BOLD : FW_NORMAL; 
  1953. CFont font;
  1954. font.CreateFontIndirect(&lf);
  1955. pListObj->SetFont(&font,nCol);
  1956. CRect rect;
  1957. RedrawItems(nRow,nRow);
  1958. UpdateWindow();
  1959. }
  1960. }
  1961. void CUIODListCtrl::SetRowBold(int nRow,BOOL bBold)
  1962. {
  1963. CUIListCtrlData* pListObj = GetListCtrlData(nRow);
  1964. if (pListObj)
  1965. {
  1966. if (!pListObj->IsFontSet(-1))
  1967. {
  1968. pListObj->SetFont(GetFont());
  1969. }
  1970. const CFont *pFont = pListObj->GetFont();
  1971. LOGFONT lf;
  1972. ((CFont*)pFont)->GetLogFont(&lf);
  1973. lf.lfWeight = bBold ? FW_BOLD : FW_NORMAL; 
  1974. CFont font;
  1975. font.CreateFontIndirect(&lf);
  1976. pListObj->SetFont(&font);
  1977. CRect rect;
  1978. RedrawItems(nRow,nRow);
  1979. UpdateWindow();
  1980. }
  1981. }
  1982. BOOL CUIODListCtrl::SubItemPostPaint(LPNMLVCUSTOMDRAW lplvcd,LRESULT *pResult)
  1983. {
  1984. if (m_hOrigFont)
  1985. {
  1986. CDC *pDC = CDC::FromHandle(lplvcd->nmcd.hdc);
  1987. pDC->SelectObject(CFont::FromHandle(m_hOrigFont));
  1988. m_hOrigFont = NULL;
  1989. }
  1990. return TRUE;
  1991. }
  1992. BOOL CUIODListCtrl::SubItemPrePaint(LPNMLVCUSTOMDRAW lplvcd,LRESULT *pResult)
  1993. {
  1994. *pResult = CDRF_DODEFAULT;
  1995. int nRow = lplvcd->nmcd.dwItemSpec;
  1996. int nCol = lplvcd->iSubItem;
  1997. CUIListCtrlData* pListObj = GetListCtrlData(nRow);
  1998. if (pListObj == NULL)
  1999. return FALSE;
  2000. *pResult = CDRF_NOTIFYPOSTPAINT;
  2001. lplvcd->clrText = pListObj->GetTextColor(nCol);
  2002. lplvcd->clrTextBk = pListObj->GetBkColor(nCol);
  2003. if (pListObj->IsFontSet(nCol))
  2004. {
  2005. CDC *pDC = CDC::FromHandle(lplvcd->nmcd.hdc);
  2006. CFont *pOldFont = pDC->SelectObject((CFont*)pListObj->GetFont(nCol));
  2007. m_hOrigFont = (HFONT)pOldFont;
  2008. *pResult |= CDRF_NEWFONT;
  2009. }
  2010. CTextProgressCtrl *pWnd = (CTextProgressCtrl*)pListObj->GetCtrl(nCol);
  2011. if (pWnd == NULL)
  2012. return TRUE;
  2013. CRect rcItem;
  2014. GetItemRect(nRow,rcItem,LVIR_LABEL);
  2015. rcItem.left = lplvcd->nmcd.rc.left;
  2016. rcItem.right = lplvcd->nmcd.rc.right;
  2017. CDC *pDC = CDC::FromHandle(lplvcd->nmcd.hdc);
  2018. pWnd->DoPaint(pDC,rcItem,GetItemState(nRow,LVIS_SELECTED) == LVIS_SELECTED);
  2019. *pResult = CDRF_SKIPDEFAULT;
  2020. return TRUE;
  2021. }
  2022. BOOL CUIODListCtrl::ItemPrePaint(LPNMLVCUSTOMDRAW lplvcd,LRESULT *pResult)
  2023. {
  2024.     *pResult = CDRF_NOTIFYSUBITEMDRAW;
  2025. return TRUE;
  2026. }
  2027. BOOL CUIODListCtrl::ItemPostPaint(LPNMLVCUSTOMDRAW lplvcd,LRESULT *pResult)
  2028. {
  2029. *pResult = CDRF_DODEFAULT;
  2030. return TRUE;
  2031. }
  2032. ///////////////////////////////////////////////
  2033. // Persistence
  2034. ///////////////////////////////////////////////
  2035. void CUIODListCtrl::SetSection(LPCTSTR pszSection) 
  2036. {
  2037. if (pszSection == NULL)
  2038. m_strSection.Empty();
  2039. else
  2040. {
  2041. SaveProfile();
  2042. m_strSection = _T("UIODListControl\");
  2043. m_strSection += pszSection;
  2044. }
  2045. }
  2046. LPCTSTR CUIODListCtrl::GetSection() const
  2047. {
  2048. return m_strSection;
  2049. }
  2050. void CUIODListCtrl::LoadProfile() 
  2051. {
  2052. if (m_strSection.IsEmpty())
  2053. return;
  2054. CWinApp *pApp = AfxGetApp();
  2055. if (pApp == NULL)
  2056. return;
  2057. LPCTSTR pszSection = GetSection();
  2058. m_strHeadings = pApp->GetProfileString(pszSection,szEntryHeadings);
  2059. m_dwExStyle = pApp->GetProfileInt(pszSection,szEntryStyle,m_dwExStyle);
  2060. m_bFullRowSel = pApp->GetProfileInt(pszSection,szEntryRowSel,m_bFullRowSel);
  2061. m_dwViewType = pApp->GetProfileInt(pszSection,szEntryViewType,m_dwViewType);
  2062. m_bColumnSizing = pApp->GetProfileInt(pszSection,szEntryColumnSizing,m_bColumnSizing);
  2063. m_nSortColumn = pApp->GetProfileInt(pszSection,szEntrySortColumn,m_nSortColumn);
  2064. int nSubItems = pApp->GetProfileInt(pszSection,szEntrySubItems,0);
  2065. if (nSubItems)
  2066. {
  2067. delete []m_pColOrder;
  2068. delete []m_pColWidths;
  2069. m_pColOrder = new int[nSubItems];
  2070. m_pColWidths = new int[nSubItems];
  2071. CString strEntry;
  2072. for(int i=0;i < nSubItems;i++)
  2073. {
  2074. strEntry.Format(_T("%s%d"),szEntryColOrder,i+1);
  2075. m_pColOrder[i] = pApp->GetProfileInt(pszSection,strEntry,0);
  2076. strEntry.Format(_T("%s%d"),szEntryColWidths,i+1);
  2077. m_pColWidths[i] = pApp->GetProfileInt(pszSection,strEntry,0);
  2078. }
  2079. }
  2080. }
  2081. void CUIODListCtrl::SaveProfile()
  2082. {
  2083. if (m_strSection.IsEmpty())
  2084. return;
  2085. CWinApp *pApp = AfxGetApp();
  2086. if (pApp == NULL)
  2087. return;
  2088. LPCTSTR pszSection = GetSection();
  2089. pApp->WriteProfileString(pszSection,szEntryHeadings,m_strHeadings);
  2090. pApp->WriteProfileInt(pszSection,szEntryStyle,SendMessage(LVM_GETEXTENDEDLISTVIEWSTYLE));
  2091. pApp->WriteProfileInt(pszSection,szEntryRowSel,m_bFullRowSel);
  2092. pApp->WriteProfileInt(pszSection,szEntryViewType,GetViewType());
  2093. pApp->WriteProfileInt(pszSection,szEntryColumnSizing,m_bColumnSizing);
  2094. pApp->WriteProfileInt(pszSection,szEntrySubItems,m_nSubItems);
  2095. pApp->WriteProfileInt(pszSection,szEntrySortColumn,m_nSortColumn);
  2096. if (m_nSubItems)
  2097. {
  2098. delete []m_pColOrder;
  2099. m_pColOrder = new int[m_nSubItems],0;
  2100. SendMessage(LVM_GETCOLUMNORDERARRAY,(WPARAM)m_nSubItems,(LPARAM)m_pColOrder);
  2101. CString strEntry;
  2102. for(int i=0;i < m_nSubItems;i++)
  2103. {
  2104. strEntry.Format(_T("%s%d"),szEntryColOrder,i+1);
  2105. pApp->WriteProfileInt(pszSection,strEntry,m_pColOrder[i]);
  2106. if (m_pColWidths)
  2107. {
  2108. strEntry.Format(_T("%s%d"),szEntryColWidths,i+1);
  2109. pApp->WriteProfileInt(pszSection,strEntry,m_pColWidths[i]);
  2110. }
  2111. }
  2112. }
  2113. }
  2114. void CUIODListCtrl::Serialize(CArchive& ar)
  2115. {
  2116. if (ar.IsStoring())
  2117. {
  2118. ar << m_strHeadings;
  2119. ar << m_nSubItems;
  2120. m_pColOrder = new int[m_nSubItems];
  2121. SendMessage(LVM_GETCOLUMNORDERARRAY,(WPARAM)m_nSubItems,(LPARAM)m_pColOrder);
  2122. for(int i=0;i < m_nSubItems;i++)
  2123. {
  2124. ar << (int)m_pColOrder[i];
  2125. ar << (int)GetColumnWidth(i);
  2126. }
  2127. delete []m_pColOrder;
  2128. m_pColOrder = NULL;
  2129. ar << SendMessage(LVM_GETEXTENDEDLISTVIEWSTYLE);
  2130. ar << m_dwViewType;
  2131. ar << m_bFullRowSel;
  2132. ar << m_bColumnSizing;
  2133. }
  2134. else
  2135. {
  2136. ar >> m_strHeadings;
  2137. ar >> m_nSubItems;
  2138. delete []m_pColOrder;
  2139. delete []m_pColWidths;
  2140. m_pColOrder = new int[m_nSubItems];
  2141. m_pColWidths = new int[m_nSubItems];
  2142. for(int i=0;i < m_nSubItems;i++)
  2143. {
  2144. ar >> (int)m_pColOrder[i];
  2145. ar >> (int)m_pColWidths[i];
  2146. }
  2147. ar >> m_dwExStyle;
  2148. ar >> m_bFullRowSel;
  2149. ar >> m_dwViewType;
  2150. ar >> m_bColumnSizing;
  2151. }
  2152. }
  2153. /////////////////////////////////////////////////////////////////
  2154. // OLE drag and drop
  2155. /////////////////////////////////////////////////////////////////
  2156. /////////////////////////////////////////////////////////////////////////////
  2157. // CUIODListCtrl message handlers
  2158. #include "UIDragImage.h"
  2159. BOOL CUIODListCtrl::OnBeginRDrag(NMHDR* pNMHDR, LRESULT* pResult) 
  2160. {
  2161. NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
  2162. // TODO: Add your control notification handler code here
  2163. *pResult = 0;
  2164. // DoOleDrag(pNMListView,true);  COMMINT TO DISABLE DRAGDROP
  2165. return TRUE;
  2166. }
  2167. BOOL CUIODListCtrl::OnBegindrag(NMHDR* pNMHDR, LRESULT* pResult) 
  2168. {
  2169. NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
  2170. // TODO: Add your control notification handler code here
  2171. *pResult = 0;
  2172. // DoOleDrag(pNMListView,false); COMMINT TO DISABLE DRAGDROP
  2173. return TRUE;
  2174. }
  2175. void CUIODListCtrl::DoOleDrag(NM_LISTVIEW* pNMListView,bool bRightMenu)
  2176. {
  2177. int nSelected = GetSelectedCount();
  2178. if (nSelected == 0 || pNMListView->iItem == -1)
  2179. return;
  2180. BOOL bRet=TRUE;
  2181. if (bRet == FALSE)
  2182. return;
  2183. // View type LVS_ICON etc
  2184. int nType = GetViewType();
  2185. // 2 ints(nSelected,nType) + ImageData + CRect 
  2186.     HANDLE hData = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE,sizeof(int)*2+sizeof(DD_ImageData)*nSelected+sizeof(CRect));
  2187.     int *pData = (int*)::GlobalLock(hData);
  2188. *pData++ = nType;
  2189. *pData++ = nSelected;
  2190. // add the selections
  2191.     DD_ImageData *pImageData = (DD_ImageData*)pData;
  2192. CRect rcItem;
  2193. CRect rcIcon;
  2194. CRect rcTotalItem;
  2195. int iItem = pNMListView->iItem;
  2196. GetItemRect(iItem,rcItem,LVIR_LABEL); 
  2197. GetItemRect(iItem,rcIcon,LVIR_ICON);
  2198. rcTotalItem.left = rcIcon.left;
  2199. rcTotalItem.top = rcIcon.top;
  2200. rcTotalItem.right = rcIcon.right+rcItem.right;
  2201. rcTotalItem.bottom = 0;
  2202. CPoint point(pNMListView->ptAction);
  2203. CPoint ptHitTest;
  2204. UINT flag=0;
  2205. iItem = GetNextSel(-1);
  2206. int *pRows = new int[nSelected+1];
  2207. pRows[0] = iItem;
  2208. for(int i=1;iItem != -1;i++)
  2209. {
  2210. GetItemRect(iItem,rcItem,LVIR_LABEL); 
  2211. GetItemRect(iItem,rcIcon,LVIR_ICON); 
  2212. ptHitTest.x = rcItem.left;
  2213. ptHitTest.y = rcItem.top;
  2214. HitTest(ptHitTest,&flag);
  2215. if ((flag & LVHT_BELOW) != LVHT_BELOW && (flag & LVHT_ABOVE) != LVHT_ABOVE)
  2216. {
  2217. pImageData->m_rcItem = rcItem;
  2218. pImageData->m_rcIcon = rcIcon;
  2219. pImageData->m_ptDrag = point;
  2220. rcTotalItem.bottom += rcIcon.bottom;
  2221. pImageData++;
  2222. }
  2223. CCF_String ccfText(GetItemText(iItem,0));
  2224. CWDClipboardData::Instance()->SetData(&m_OleDataSource,&ccfText,CWDClipboardData::e_cfString);
  2225. iItem = GetNextSel(iItem);
  2226. pRows[i] = iItem;
  2227. }
  2228. pData = (int*)pImageData;
  2229. *pData++ = rcTotalItem.left;
  2230. *pData++ = rcTotalItem.right;
  2231. *pData++ = rcTotalItem.top;
  2232. *pData = rcTotalItem.bottom;
  2233.     ::GlobalUnlock (hData);
  2234.     m_OleDataSource.CacheGlobalData(m_OleDropTarget.GetClipboardFormat(), hData);
  2235. CCF_RightMenu rm;
  2236. rm.SetRightDrag(bRightMenu);
  2237. CWDClipboardData::Instance()->SetData(&m_OleDataSource,&rm,CWDClipboardData::e_cfRightMenu);
  2238. DWORD dwDragEffect = SendMessage(WM_APP_OLE_DD_DODRAGDROP,(WPARAM)pRows,(LPARAM)&m_OleDataSource);
  2239. if (dwDragEffect == 0)
  2240. dwDragEffect = GetParent()->SendMessage(WM_APP_OLE_DD_DODRAGDROP,(WPARAM)pRows,(LPARAM)&m_OleDataSource);
  2241. if (dwDragEffect)
  2242. {
  2243. // Start the DragDrop
  2244. DROPEFFECT effect = m_OleDataSource.DoDragDrop(dwDragEffect,NULL);
  2245. // Clear the cache
  2246. m_OleDataSource.Empty();        
  2247. }
  2248. delete []pRows;
  2249. }
  2250. void CUIODListCtrl::RegisterDropTarget()
  2251. {
  2252. if (!IsDragDrop())
  2253. return;
  2254. VERIFY(m_OleDropTarget.Register(this));
  2255. if (IsDropFiles())
  2256. DragAcceptFiles();
  2257. }
  2258. DROPEFFECT CUIODListCtrl::SelectCurrentTarget(CDD_OleDropTargetInfo *pInfo)
  2259. {
  2260. // No method to select a list ctrl item during drag and drop
  2261. UINT flags;
  2262. int iItem = HitTest(pInfo->GetPoint(), &flags);
  2263. pInfo->SetItem(iItem);
  2264. // save it
  2265. m_iItemDrop = iItem;
  2266. LRESULT lResult = SendMessage(WM_APP_OLE_DD_OVER,(WPARAM)pInfo);
  2267. if (lResult == 0)
  2268. {
  2269. lResult = GetParent()->SendMessage(WM_APP_OLE_DD_OVER,(WPARAM)pInfo);
  2270. }
  2271. // returns 0 if allowed (so the default is allowed)
  2272. if (lResult)
  2273. {
  2274. // return what was ever set
  2275. return pInfo->GetDropEffect();
  2276. }
  2277. return DROPEFFECT_NONE;
  2278. }
  2279. ///////////////////////////////////////////////
  2280. void CUIODListCtrl::PostNcDestroy() 
  2281. {
  2282. // TODO: Add your specialized code here and/or call the base class
  2283. CListCtrl::PostNcDestroy();
  2284. }
  2285. void CUIODListCtrl::OnDestroy() 
  2286. {
  2287. SaveProfile();
  2288. CListCtrl::OnDestroy();
  2289. // TODO: Add your message handler code here
  2290. }
  2291. void CUIODListCtrl::PreSubclassWindow() 
  2292. {
  2293. CListCtrl::PreSubclassWindow();
  2294. // Add initialization code
  2295. EnableToolTips(m_bToolTips);
  2296. SetSortHeader();
  2297. }
  2298. int CUIODListCtrl::OnToolHitTest(CPoint point, TOOLINFO * pTI) const
  2299. {
  2300. int row, col;
  2301. CRect cellrect;
  2302. row = CellRectFromPoint(point, &cellrect, &col );
  2303. if ( row == -1 ) 
  2304. return -1;
  2305. if (GetStringWidth(GetItemText(row,col))-10 < cellrect.Width())
  2306. return -1;
  2307. CToolTipCtrl* pToolTip = AfxGetThreadState()->m_pToolTip;
  2308. pToolTip->SendMessage(TTM_SETDELAYTIME,TTDT_AUTOPOP,10000);
  2309. pToolTip->SendMessage(TTM_SETMAXTIPWIDTH,0,30);
  2310. pTI->hwnd = m_hWnd;
  2311. pTI->uId = (UINT)((row<<10)+(col&0x3ff)+1);
  2312. pTI->lpszText = LPSTR_TEXTCALLBACK;
  2313. pTI->rect = cellrect;
  2314. return pTI->uId;
  2315. }
  2316. // CellRectFromPoint - Determine the row, col and bounding rect of a cell
  2317. // Returns - row index on success, -1 otherwise// point - point to be tested.
  2318. // cellrect - to hold the bounding rect// col - to hold the column index
  2319. int CUIODListCtrl::CellRectFromPoint(CPoint & point, RECT * cellrect, int * col) const
  2320. {
  2321. int colnum;
  2322. // Make sure that the ListView is in LVS_REPORT
  2323. if( (GetWindowLong(m_hWnd, GWL_STYLE) & LVS_TYPEMASK) != LVS_REPORT)
  2324. return -1;
  2325. // Get the top and bottom row visible
  2326. int row = GetTopIndex();
  2327. int bottom = row + GetCountPerPage();
  2328. if( bottom > GetItemCount() )
  2329. bottom = GetItemCount();
  2330. // Get the number of columns
  2331. CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0);
  2332. int nColumnCount = pHeader->GetItemCount();
  2333. // Loop through the visible rows
  2334. for( ;row <=bottom;row++)
  2335. {
  2336. // Get bounding rect of item and check whether point falls in it.
  2337. CRect rect;
  2338. GetItemRect( row, &rect, LVIR_BOUNDS );
  2339. if( rect.PtInRect(point) )
  2340. {
  2341. // Now find the column
  2342. for( colnum = 0; colnum < nColumnCount; colnum++ )
  2343. {
  2344. int colwidth = GetColumnWidth(colnum);
  2345. if( point.x >= rect.left && point.x <= (rect.left + colwidth ) )
  2346. {
  2347. RECT rectClient;
  2348. GetClientRect( &rectClient );
  2349. if( col ) 
  2350. {
  2351. CUIODListCtrl *pThis = const_cast<CUIODListCtrl*>(this);
  2352. if (m_pColOrder && pThis->SendMessage(LVM_GETCOLUMNORDERARRAY,(WPARAM)m_nSubItems,(LPARAM)m_pColOrder))
  2353. *col = m_pColOrder[colnum];
  2354. else
  2355. *col = colnum;
  2356. }
  2357. rect.right = rect.left + colwidth;
  2358. // Make sure that the right extent does not exceed
  2359. // the client area
  2360. if( rect.right > rectClient.right ) 
  2361. rect.right = rectClient.right;
  2362. *cellrect = rect;
  2363. return row;
  2364. }
  2365. rect.left += colwidth;
  2366. }
  2367. }
  2368. }
  2369. return -1;
  2370. }
  2371. BOOL CUIODListCtrl::OnToolTipText( UINT id, NMHDR * pNMHDR, LRESULT * pResult )
  2372. {
  2373. // need to handle both ANSI and UNICODE versions of the message
  2374. static WCHAR szToolTipW[256];
  2375. static char szToolTipA[256];
  2376. TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;
  2377. TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;
  2378. UINT nID = pNMHDR->idFrom;
  2379. if( nID == 0 )
  2380. {
  2381. // Notification in NT from automatically
  2382. return FALSE;   
  2383. }
  2384. // created tooltip
  2385. int row = ((nID-1) >> 10) & 0x3fffff;
  2386. int col = (nID-1) & 0x3ff;
  2387. m_sToolTipText = GetItemText( row, col );
  2388. #ifndef _UNICODE
  2389. // if (pNMHDR->code == TTN_NEEDTEXTA)
  2390. // lstrcpyn(pTTTA->szText, strTipText, 80);
  2391. // else
  2392. // _mbstowcsz(pTTTW->szText, strTipText, 80);
  2393. if (pNMHDR->code == TTN_NEEDTEXTA)
  2394. {
  2395. pTTTA->lpszText = (LPSTR)(LPCSTR)m_sToolTipText;
  2396. }
  2397. else
  2398. {
  2399. _mbstowcsz(szToolTipW, m_sToolTipText, sizeof(szToolTipW)-1);
  2400. pTTTW->lpszText = szToolTipW;
  2401. }
  2402. #else
  2403. if (pNMHDR->code == TTN_NEEDTEXTW)
  2404. {
  2405. pTTTW->lpszText = (LPWSTR)(LPCWSTR)m_sToolTipText;
  2406. }
  2407. else
  2408. {
  2409. _wcstombsz(szToolTipA, m_sToolTipText, sizeof(szToolTipA)-1);
  2410. pTTTA->lpszText = szToolTipA;
  2411. }
  2412. // pTTTA->lpszText = (LPTSTR)(LPCTSTR)m_sToolTipText;
  2413. // if (pNMHDR->code == TTN_NEEDTEXTA)
  2414. // _wcstombsz(pTTTA->szText, strTipText, 80);
  2415. // else
  2416. // lstrcpyn(pTTTW->szText, strTipText, 80);
  2417. #endif
  2418. *pResult = 0;
  2419. return TRUE;    
  2420. // message was handled
  2421. }
  2422. CODHeaderCtrl::CODHeaderCtrl()
  2423. {
  2424. m_nSortCol = -1;
  2425. }
  2426. CODHeaderCtrl::~CODHeaderCtrl()
  2427. {
  2428. }
  2429. int CODHeaderCtrl::SetSortImage(int nCol, BOOL bAsc)
  2430. {
  2431. if (m_hWnd == NULL)
  2432. return -1;
  2433. int nPrevCol = m_nSortCol;
  2434. m_nSortCol = nCol;
  2435. m_bSortAsc = bAsc;
  2436. // Change the item to ownder drawn
  2437. HD_ITEM hditem;
  2438. hditem.mask = HDI_FORMAT;
  2439. GetItem( nCol, &hditem );
  2440. hditem.fmt |= HDF_OWNERDRAW;
  2441. SetItem( nCol, &hditem ); // Invalidate header control so that it gets redrawn
  2442. Invalidate();
  2443. return nPrevCol;
  2444. }
  2445. void CODHeaderCtrl::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )
  2446. {
  2447. CDC dc;
  2448. dc.Attach( lpDrawItemStruct->hDC );
  2449. // Get the column rect
  2450. CRect rcLabel( lpDrawItemStruct->rcItem );
  2451. // Save DC
  2452. int nSavedDC = dc.SaveDC();
  2453. // Set clipping region to limit drawing within column
  2454. CRgn rgn;
  2455. rgn.CreateRectRgnIndirect( &rcLabel );
  2456. dc.SelectObject( &rgn );
  2457. rgn.DeleteObject();
  2458.         // Draw the background
  2459.         dc.FillRect(rcLabel, &CBrush(::GetSysColor(COLOR_3DFACE)));
  2460. // Labels are offset by a certain amount  
  2461. // This offset is related to the width of a space character
  2462. int offset = dc.GetTextExtent(_T(" "), 1 ).cx*2;
  2463. // Get the column text and format
  2464. TCHAR buf[256];
  2465. HD_ITEM hditem;
  2466. hditem.mask = HDI_TEXT | HDI_FORMAT;
  2467. hditem.pszText = buf;
  2468. hditem.cchTextMax = 255;
  2469. GetItem( lpDrawItemStruct->itemID, &hditem );
  2470. // Determine format for drawing column label
  2471. UINT uFormat = DT_SINGLELINE | DT_NOPREFIX | DT_NOCLIP 
  2472. | DT_VCENTER | DT_END_ELLIPSIS ;
  2473. if( hditem.fmt & HDF_CENTER)
  2474. uFormat |= DT_CENTER;
  2475. else if( hditem.fmt & HDF_RIGHT)
  2476. uFormat |= DT_RIGHT;
  2477. else
  2478. uFormat |= DT_LEFT;
  2479. // Adjust the rect if the mouse button is pressed on it
  2480. if( lpDrawItemStruct->itemState == ODS_SELECTED )
  2481. {
  2482. rcLabel.left++;
  2483. rcLabel.top += 2;
  2484. rcLabel.right++;
  2485. }
  2486. // Adjust the rect further if Sort arrow is to be displayed
  2487. if( lpDrawItemStruct->itemID == (UINT)m_nSortCol )
  2488. {
  2489. rcLabel.right -= 3 * offset;
  2490. }
  2491. rcLabel.left += offset;
  2492. rcLabel.right -= offset;
  2493. // Draw column label
  2494. if( rcLabel.left < rcLabel.right )
  2495. dc.DrawText(buf,-1,rcLabel, uFormat);
  2496. // Draw the Sort arrow
  2497. if( lpDrawItemStruct->itemID == (UINT)m_nSortCol )
  2498. {
  2499. CRect rcIcon( lpDrawItemStruct->rcItem );
  2500. // Set up pens to use for drawing the triangle
  2501. CPen penLight(PS_SOLID, 1, GetSysColor(COLOR_3DHILIGHT));
  2502. CPen penShadow(PS_SOLID, 1, GetSysColor(COLOR_3DSHADOW));
  2503. CPen *pOldPen = dc.SelectObject( &penLight );
  2504. if( m_bSortAsc )
  2505. {
  2506. // Draw triangle pointing upwards
  2507. dc.MoveTo( rcIcon.right - 2*offset, offset-1);
  2508. dc.LineTo( rcIcon.right - 3*offset/2, rcIcon.bottom - offset );
  2509. dc.LineTo( rcIcon.right - 5*offset/2-2, rcIcon.bottom - offset );
  2510. dc.MoveTo( rcIcon.right - 5*offset/2-1, rcIcon.bottom - offset-1 );
  2511. dc.SelectObject( &penShadow );
  2512. dc.LineTo( rcIcon.right - 2*offset, offset-2);
  2513. }
  2514. else
  2515. {
  2516. // Draw triangle pointing downwords
  2517. dc.MoveTo( rcIcon.right - 3*offset/2, offset-1);
  2518. dc.LineTo( rcIcon.right - 2*offset-1, rcIcon.bottom - offset + 1 );
  2519. dc.MoveTo( rcIcon.right - 2*offset-1, rcIcon.bottom - offset );
  2520. dc.SelectObject( &penShadow );
  2521. dc.LineTo( rcIcon.right - 5*offset/2-1, offset -1 );
  2522. dc.LineTo( rcIcon.right - 3*offset/2, offset -1);
  2523. }
  2524. // Restore the pen
  2525. dc.SelectObject( pOldPen );
  2526. }
  2527. // Restore dc
  2528. dc.RestoreDC( nSavedDC );
  2529. // Detach the dc before returning
  2530. dc.Detach();
  2531. }
  2532. void CUIODListCtrl::SetSortColumn(int nCol,BOOL bAsc)
  2533. {
  2534. m_nSortColumn = nCol;
  2535. m_bSortAscending = bAsc;
  2536. m_HeaderCtrl.SetSortImage(nCol,bAsc);
  2537. }
  2538. void CUIODListCtrl::SetSortHeader()
  2539. {
  2540. if (m_HeaderCtrl.GetSafeHwnd() == NULL && m_hWnd != NULL)
  2541. {
  2542. m_HeaderCtrl.SubclassWindow( ::GetDlgItem(m_hWnd,0) );
  2543. }
  2544. }
  2545. CString CUIODListCtrl::StripNonNumeric(LPCTSTR pszOldNum,CUIODListCtrl::eColTypes type)
  2546. {
  2547. TCHAR szNewNum[255];
  2548. LPTSTR pszNewNum = szNewNum;
  2549. while (*pszOldNum != '')
  2550. {
  2551. if ((type == CUIODListCtrl::e_Double && *pszOldNum == '.') || *pszOldNum == '-' || *pszOldNum == '+' || _istdigit(*pszOldNum))
  2552. {
  2553. *pszNewNum = *pszOldNum;
  2554. pszNewNum = _tcsinc(pszNewNum);
  2555. }
  2556. pszOldNum = _tcsinc(pszOldNum);
  2557. }
  2558. *pszNewNum = '';
  2559. return szNewNum;
  2560. }
  2561. BOOL CUIODListCtrl::PreTranslateMessage(MSG* pMsg)
  2562. {
  2563. if (pMsg->message == WM_KEYDOWN || pMsg->message == WM_SYSKEYDOWN)
  2564. {
  2565. if (pMsg->wParam == VK_F10 && (GetKeyState(VK_SHIFT) < 0))
  2566. {
  2567. PostMessage(WM_APP_ON_CONTEXT_MENU_KEY);
  2568. return TRUE;
  2569. }
  2570. else if (pMsg->wParam == VK_BACK)
  2571. {
  2572. PostMessage(WM_APP_ON_BACKSPACE_KEY);
  2573. return TRUE;
  2574. }
  2575. else if (pMsg->wParam == VK_F2)
  2576. {
  2577. PostMessage(WM_APP_ON_EDIT_KEY);
  2578. return TRUE;
  2579. }
  2580. else if (pMsg->wParam == VK_F5)
  2581. {
  2582. PostMessage(WM_APP_ON_REFRESH_KEY);
  2583. return TRUE;
  2584. }
  2585. else if (pMsg->wParam == VK_DELETE)
  2586. {
  2587. PostMessage(WM_APP_ON_DELETE_KEY);
  2588. return TRUE;
  2589. }
  2590. else if (pMsg->message == WM_SYSKEYDOWN && pMsg->wParam == VK_RETURN)
  2591. {
  2592. PostMessage(WM_APP_ON_PROPERTIES_KEY);
  2593. return TRUE;
  2594. }
  2595. }
  2596. return CListCtrl::PreTranslateMessage(pMsg);
  2597. }
  2598. // User has finished editing a column
  2599. bool CUIODListCtrl::EndLabelEdit(int nRow,int nCol,LPCTSTR pszText)
  2600. {
  2601. return false;
  2602. }
  2603. // Left mouse button double clicked
  2604. BOOL CUIODListCtrl::DoubleClick(NM_LISTVIEW* pNMListView)
  2605. {
  2606. return FALSE;
  2607. }
  2608. // Enter Pressed
  2609. BOOL CUIODListCtrl::OnEnter(NM_LISTVIEW* pNMListView)
  2610. {
  2611. return FALSE;
  2612. }
  2613. // Delete key pressed
  2614. bool CUIODListCtrl::DeleteKey(int nRow)
  2615. {
  2616. return false;
  2617. }
  2618. // ALt-Enter pressed
  2619. void CUIODListCtrl::ShowProperties(int nRow)
  2620. {
  2621. }
  2622. // F5 key pressed
  2623. void CUIODListCtrl::Refresh()
  2624. {
  2625. }
  2626. // Backspace key pressed
  2627. void CUIODListCtrl::GoBack(int nSelRow)
  2628. {
  2629. }
  2630. LRESULT CUIODListCtrl::OnDragDrop(WPARAM wParam,LPARAM lParam)
  2631. {
  2632. if (IsDragDrop() == false)
  2633. return 1L;
  2634. // get the info we need
  2635. CDD_OleDropTargetInfo *pInfo = (CDD_OleDropTargetInfo*)wParam;
  2636. ASSERT(pInfo);
  2637. return DragDrop(pInfo) ? 1 : 0;
  2638. }
  2639. // user is currently over the list view window
  2640. // return 1 if we are interested in the Clipboard format
  2641. LRESULT CUIODListCtrl::OnDragOver(WPARAM wParam,LPARAM lParam)
  2642. {
  2643. if (IsDragDrop() == false)
  2644. return 1L;
  2645. CDD_OleDropTargetInfo *pInfo = (CDD_OleDropTargetInfo*)wParam;
  2646. ASSERT(pInfo);
  2647. return DragOver(pInfo) ? 1 : 0;
  2648. }
  2649. LRESULT CUIODListCtrl::OnDragEnter(WPARAM wParam,LPARAM lParam)
  2650. {
  2651. if (IsDragDrop() == false)
  2652. return 1L;
  2653. CDD_OleDropTargetInfo *pInfo = (CDD_OleDropTargetInfo*)wParam;
  2654. ASSERT(pInfo);
  2655. return DragEnter(pInfo) ? 1 : 0;
  2656. }
  2657. LRESULT CUIODListCtrl::OnDragLeave(WPARAM wParam,LPARAM lParam)
  2658. {
  2659. if (IsDragDrop() == false)
  2660. return 1L;
  2661. CDD_OleDropTargetInfo *pInfo = (CDD_OleDropTargetInfo*)wParam;
  2662. ASSERT(pInfo);
  2663. return DragLeave(pInfo) ? 1 : 0;
  2664. }
  2665. // Drag and drop initiated
  2666. // Return 1 if processed
  2667. LRESULT CUIODListCtrl::OnDDDoDragDrop(WPARAM wParam,LPARAM lParam)
  2668. {
  2669. if (IsDragDrop() == false)
  2670. return 1L;
  2671. COleDataSource *pOleDataSource = (COleDataSource*)lParam;
  2672. int *pRows = (int*)wParam;
  2673. ASSERT(pOleDataSource);
  2674. return DoDragDrop(pRows,pOleDataSource);
  2675. }
  2676. bool CUIODListCtrl::DragDrop(CDD_OleDropTargetInfo *pInfo)
  2677. {
  2678. return false;
  2679. }
  2680. bool CUIODListCtrl::DragOver(CDD_OleDropTargetInfo *pInfo)
  2681. {
  2682. return false;
  2683. }
  2684. bool CUIODListCtrl::DragEnter(CDD_OleDropTargetInfo *pInfo)
  2685. {
  2686. return false;
  2687. }
  2688. bool CUIODListCtrl::DragLeave(CDD_OleDropTargetInfo *pInfo)
  2689. {
  2690. return false;
  2691. }
  2692. DROPEFFECT CUIODListCtrl::DoDragDrop(int *pnRows,COleDataSource *pOleDataSource)
  2693. {
  2694. return true;
  2695. }
  2696. void CUIODListCtrl::OnDropFiles(HDROP hDropInfo)
  2697. {
  2698. UINT wNumFilesDropped = DragQueryFile(hDropInfo, 0XFFFFFFFF, NULL, 0);
  2699. TCHAR szFile[MAX_PATH];
  2700. UINT nLen;
  2701. UINT nFlags;
  2702. POINT pt;
  2703. ::DragQueryPoint(hDropInfo,&pt);
  2704. int nRow = HitTest(CPoint(pt), &nFlags);
  2705. for(UINT i=0; i < wNumFilesDropped;i++)
  2706. {
  2707. nLen = DragQueryFile(hDropInfo,i,szFile,sizeof(szFile)/sizeof(TCHAR));
  2708. if (nLen)
  2709. OnDropFile(nRow,szFile,nFlags);
  2710. }
  2711. }
  2712. void CUIODListCtrl::OnDropFile(int nRow,LPCTSTR pszFile,UINT nFlags)
  2713. {
  2714. }
  2715. LRESULT CUIODListCtrl::OnAppPropertiesKey(WPARAM wParam, LPARAM lParam)
  2716. {
  2717. int item=-1;
  2718. while ((item = GetNextSel(item)) != -1)
  2719. {
  2720. ShowProperties(item);
  2721. }
  2722. return 1L;
  2723. }
  2724. LRESULT CUIODListCtrl::OnAppDeleteKey(WPARAM wParam, LPARAM lParam)
  2725. {
  2726. int nNewItem = -1;
  2727. int item=-1;
  2728. CUIListCtrlData *pData = NULL;
  2729. while ((item = GetNextSel(item)) != -1)
  2730. {
  2731. pData = GetListCtrlData(item);
  2732. if (DeleteKey(item))
  2733. {
  2734. pData->SetDeleted(true);
  2735. }
  2736. nNewItem = item;
  2737. }
  2738. while ((item = GetCurSel()) != -1)
  2739. {
  2740. pData = GetListCtrlData(item);
  2741. if (pData->IsDeleted())
  2742. {
  2743. if (!DeleteItem(item))
  2744. SetItemState(item,0,LVIS_SELECTED);
  2745. }
  2746. else
  2747. {
  2748. SetItemState(item,0,LVIS_SELECTED);
  2749. }
  2750. if (GetItemCount() == 0)
  2751. break;
  2752. }
  2753. if (nNewItem != -1)
  2754. {
  2755. EnsureVisible(nNewItem,0);
  2756. SetCurSel(nNewItem);
  2757. }
  2758. return 1L;
  2759. }
  2760. LRESULT CUIODListCtrl::OnAppRefreshKey(WPARAM wParam, LPARAM lParam)
  2761. {
  2762. Refresh();
  2763. return 1L;
  2764. }
  2765. LRESULT CUIODListCtrl::OnAppEditKey(WPARAM wParam, LPARAM lParam)
  2766. {
  2767. EditLabel(GetCurSel());
  2768. return 1L;
  2769. }
  2770. LRESULT CUIODListCtrl::OnAppContextMenuKey(WPARAM wParam, LPARAM lParam)
  2771. {
  2772. CPoint pt;
  2773. if (GetCurSel() != -1)
  2774. GetItemPosition(GetCurSel(),&pt);
  2775. ClientToScreen(&pt);
  2776. ShowPopupMenu(GetCurSel(),0,pt);
  2777. return 1L;
  2778. }
  2779. LRESULT CUIODListCtrl::OnAppBackspaceKey(WPARAM wParam, LPARAM lParam)
  2780. {
  2781. GoBack(GetCurSel());
  2782. return 1L;
  2783. }
  2784. void CUIODListCtrl::SelChanged(int nItem, LRESULT *pResult)
  2785. {
  2786. *pResult = 0;
  2787. }