PropertyList.cpp
上传用户:liming
上传日期:2022-02-22
资源大小:23k
文件大小:11k
源码类别:

ListView/ListBox

开发平台:

Visual C++

  1. // PropertyList.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. //#include "PropListBox.h"
  5. #include "PropertyList.h"
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #undef THIS_FILE
  9. static char THIS_FILE[] = __FILE__;
  10. #endif
  11. /////////////////////////////////////////////////////////////////////////////
  12. // CPropertyList
  13. CPropertyList::CPropertyList()
  14. {
  15. }
  16. CPropertyList::~CPropertyList()
  17. {
  18. }
  19. BEGIN_MESSAGE_MAP(CPropertyList, CListBox)
  20. //{{AFX_MSG_MAP(CPropertyList)
  21. ON_WM_CREATE()
  22. ON_CONTROL_REFLECT(LBN_SELCHANGE, OnSelchange)
  23. ON_WM_LBUTTONUP()
  24. ON_WM_KILLFOCUS()
  25. ON_WM_LBUTTONDOWN()
  26. ON_WM_MOUSEMOVE()
  27. //}}AFX_MSG_MAP
  28. ON_CBN_KILLFOCUS(IDC_PROPCMBBOX, OnKillfocusCmbBox)
  29. ON_CBN_SELCHANGE(IDC_PROPCMBBOX, OnSelchangeCmbBox)
  30. ON_EN_KILLFOCUS(IDC_PROPEDITBOX, OnKillfocusEditBox)
  31. ON_EN_CHANGE(IDC_PROPEDITBOX, OnChangeEditBox)
  32. ON_BN_CLICKED(IDC_PROPBTNCTRL, OnButton)
  33. END_MESSAGE_MAP()
  34. /////////////////////////////////////////////////////////////////////////////
  35. // CPropertyList message handlers
  36. BOOL CPropertyList::PreCreateWindow(CREATESTRUCT& cs) 
  37. {
  38. if (!CListBox::PreCreateWindow(cs))
  39. return FALSE;
  40. cs.style &= ~(LBS_OWNERDRAWVARIABLE | LBS_SORT);
  41. cs.style |= LBS_OWNERDRAWFIXED;
  42. m_bTracking = FALSE;
  43. m_nDivider = 0;
  44. m_bDivIsSet = FALSE;
  45. return TRUE;
  46. }
  47. void CPropertyList::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct) 
  48. {
  49. lpMeasureItemStruct->itemHeight = 20; //pixels
  50. }
  51. void CPropertyList::DrawItem(LPDRAWITEMSTRUCT lpDIS) 
  52. {
  53. CDC dc;
  54. dc.Attach(lpDIS->hDC);
  55. CRect rectFull = lpDIS->rcItem;
  56. CRect rect = rectFull;
  57. if (m_nDivider==0)
  58. m_nDivider = rect.Width() / 2;
  59. rect.left = m_nDivider;
  60. CRect rect2 = rectFull;
  61. rect2.right = rect.left - 1;
  62. UINT nIndex = lpDIS->itemID;
  63. if (nIndex != (UINT) -1)
  64. {
  65. //draw two rectangles, one for each row column
  66. dc.FillSolidRect(rect2,RGB(192,192,192));
  67. dc.DrawEdge(rect2,EDGE_SUNKEN,BF_BOTTOMRIGHT);
  68. dc.DrawEdge(rect,EDGE_SUNKEN,BF_BOTTOM);
  69. //get the CPropertyItem for the current row
  70. CPropertyItem* pItem = (CPropertyItem*) GetItemDataPtr(nIndex);
  71. //write the property name in the first rectangle
  72. dc.SetBkMode(TRANSPARENT);
  73. dc.DrawText(pItem->m_propName,CRect(rect2.left+3,rect2.top+3,
  74. rect2.right-3,rect2.bottom+3),
  75. DT_LEFT | DT_SINGLELINE);
  76. //write the initial property value in the second rectangle
  77. dc.DrawText(pItem->m_curValue,CRect(rect.left+3,rect.top+3,
  78. rect.right+3,rect.bottom+3),
  79. DT_LEFT | DT_SINGLELINE);
  80. }
  81. dc.Detach();
  82. }
  83. int CPropertyList::AddItem(CString txt)
  84. {
  85. int nIndex = AddString(txt);
  86. return nIndex;
  87. }
  88. int CPropertyList::AddPropItem(CPropertyItem* pItem)
  89. {
  90. int nIndex = AddString(_T(""));
  91. SetItemDataPtr(nIndex,pItem);
  92. return nIndex;
  93. }
  94. int CPropertyList::OnCreate(LPCREATESTRUCT lpCreateStruct) 
  95. {
  96. if (CListBox::OnCreate(lpCreateStruct) == -1)
  97. return -1;
  98. m_bDivIsSet = FALSE;
  99. m_nDivider = 0;
  100. m_bTracking = FALSE;
  101. m_hCursorSize = AfxGetApp()->LoadStandardCursor(IDC_SIZEWE);
  102. m_hCursorArrow = AfxGetApp()->LoadStandardCursor(IDC_ARROW);
  103. m_SSerif8Font.CreatePointFont(80,_T("MS Sans Serif"));
  104. return 0;
  105. }
  106. void CPropertyList::OnSelchange() 
  107. {
  108. CRect rect;
  109. CString lBoxSelText;
  110. //m_curSel = GetCurSel();
  111. GetItemRect(m_curSel,rect);
  112. rect.left = m_nDivider;
  113. CPropertyItem* pItem = (CPropertyItem*) GetItemDataPtr(m_curSel);
  114. if (m_btnCtrl)
  115. m_btnCtrl.ShowWindow(SW_HIDE);
  116. if (pItem->m_nItemType==PIT_COMBO)
  117. {
  118. //display the combo box.  If the combo box has already been
  119. //created then simply move it to the new location, else create it
  120. m_nLastBox = 0;
  121. if (m_cmbBox)
  122. m_cmbBox.MoveWindow(rect);
  123. else
  124. {
  125. rect.bottom += 100;
  126. m_cmbBox.Create(CBS_DROPDOWNLIST | CBS_NOINTEGRALHEIGHT | WS_VISIBLE | WS_CHILD | WS_BORDER,
  127. rect,this,IDC_PROPCMBBOX);
  128. m_cmbBox.SetFont(&m_SSerif8Font);
  129. }
  130. //add the choices for this particular property
  131. CString cmbItems = pItem->m_cmbItems;
  132. lBoxSelText = pItem->m_curValue;
  133. m_cmbBox.ResetContent();
  134. m_cmbBox.AddString("");
  135. int i,i2;
  136. i=0;
  137. while ((i2=cmbItems.Find('|',i)) != -1)
  138. {
  139. m_cmbBox.AddString(cmbItems.Mid(i,i2-i));
  140. i=i2+1;
  141. }
  142. m_cmbBox.ShowWindow(SW_SHOW);
  143. m_cmbBox.SetFocus();
  144. //jump to the property's current value in the combo box
  145. int j = m_cmbBox.FindStringExact(0,lBoxSelText);
  146. if (j != CB_ERR)
  147. m_cmbBox.SetCurSel(j);
  148. else
  149. m_cmbBox.SetCurSel(0);
  150. }
  151. else if (pItem->m_nItemType==PIT_EDIT)
  152. {
  153. //display edit box
  154. m_nLastBox = 1;
  155. m_prevSel = m_curSel;
  156. rect.bottom -= 3;
  157. if (m_editBox)
  158. m_editBox.MoveWindow(rect);
  159. else
  160. {
  161. m_editBox.Create(ES_LEFT | ES_AUTOHSCROLL | WS_VISIBLE | WS_CHILD | WS_BORDER,
  162. rect,this,IDC_PROPEDITBOX);
  163. m_editBox.SetFont(&m_SSerif8Font);
  164. }
  165. lBoxSelText = pItem->m_curValue;
  166. m_editBox.ShowWindow(SW_SHOW);
  167. m_editBox.SetFocus();
  168. //set the text in the edit box to the property's current value
  169. m_editBox.SetWindowText(lBoxSelText);
  170. }
  171. else
  172. DisplayButton(rect);
  173. }
  174. void CPropertyList::DisplayButton(CRect region)
  175. {
  176. //displays a button if the property is a file/color/font chooser
  177. m_nLastBox = 2;
  178. m_prevSel = m_curSel;
  179. if (region.Width() > 25)
  180. region.left = region.right - 25;
  181. region.bottom -= 3;
  182. if (m_btnCtrl)
  183. m_btnCtrl.MoveWindow(region);
  184. else
  185. {
  186. m_btnCtrl.Create("...",BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD,
  187. region,this,IDC_PROPBTNCTRL);
  188. m_btnCtrl.SetFont(&m_SSerif8Font);
  189. }
  190. m_btnCtrl.ShowWindow(SW_SHOW);
  191. m_btnCtrl.SetFocus();
  192. }
  193. void CPropertyList::OnKillFocus(CWnd* pNewWnd) 
  194. {
  195. //m_btnCtrl.ShowWindow(SW_HIDE);
  196. CListBox::OnKillFocus(pNewWnd);
  197. }
  198. void CPropertyList::OnKillfocusCmbBox() 
  199. {
  200. m_cmbBox.ShowWindow(SW_HIDE);
  201. Invalidate();
  202. }
  203. void CPropertyList::OnKillfocusEditBox()
  204. {
  205. CString newStr;
  206. m_editBox.ShowWindow(SW_HIDE);
  207. Invalidate();
  208. }
  209. void CPropertyList::OnSelchangeCmbBox()
  210. {
  211. CString selStr;
  212. if (m_cmbBox)
  213. {
  214. m_cmbBox.GetLBText(m_cmbBox.GetCurSel(),selStr);
  215. CPropertyItem* pItem = (CPropertyItem*) GetItemDataPtr(m_curSel);
  216. pItem->m_curValue = selStr;
  217. }
  218. }
  219. void CPropertyList::OnChangeEditBox()
  220. {
  221. CString newStr;
  222. m_editBox.GetWindowText(newStr);
  223. CPropertyItem* pItem = (CPropertyItem*) GetItemDataPtr(m_curSel);
  224. pItem->m_curValue = newStr;
  225. }
  226. void CPropertyList::OnButton()
  227. {
  228. CPropertyItem* pItem = (CPropertyItem*) GetItemDataPtr(m_curSel);
  229. //display the appropriate common dialog depending on what type
  230. //of chooser is associated with the property
  231. if (pItem->m_nItemType == PIT_COLOR)
  232. {
  233. COLORREF initClr;
  234. CString currClr = pItem->m_curValue;
  235. //parse the property's current color value
  236. if (currClr.Find("RGB") > -1)
  237. {
  238. int j = currClr.Find(',',3);
  239. CString bufr = currClr.Mid(4,j-4);
  240. int RVal = atoi(bufr);
  241. int j2 = currClr.Find(',',j+1);
  242. bufr = currClr.Mid(j+1,j2-(j+1));
  243. int GVal = atoi(bufr);
  244. int j3 = currClr.Find(')',j2+1);
  245. bufr = currClr.Mid(j2+1,j3-(j2+1));
  246. int BVal = atoi(bufr);
  247. initClr = RGB(RVal,GVal,BVal);
  248. }
  249. else
  250. initClr = 0;
  251. CColorDialog ClrDlg(initClr);
  252. if (IDOK == ClrDlg.DoModal())
  253. {
  254. COLORREF selClr = ClrDlg.GetColor();
  255. CString clrStr;
  256. clrStr.Format("RGB(%d,%d,%d)",GetRValue(selClr),
  257. GetGValue(selClr),GetBValue(selClr));
  258. m_btnCtrl.ShowWindow(SW_HIDE);
  259. pItem->m_curValue = clrStr;
  260. Invalidate();
  261. }
  262. }
  263. else if (pItem->m_nItemType == PIT_FILE)
  264. {
  265. CString SelectedFile; 
  266. CString Filter("Gif Files (*.gif)|*.gif||");
  267. CFileDialog FileDlg(TRUE, NULL, NULL, NULL,
  268. Filter);
  269. CString currPath = pItem->m_curValue;
  270. FileDlg.m_ofn.lpstrTitle = "Select file";
  271. if (currPath.GetLength() > 0)
  272. FileDlg.m_ofn.lpstrInitialDir = currPath.Left(
  273. currPath.GetLength() - currPath.ReverseFind('\'));
  274. if(IDOK == FileDlg.DoModal())
  275. {
  276. SelectedFile = FileDlg.GetPathName();
  277. m_btnCtrl.ShowWindow(SW_HIDE);
  278. pItem->m_curValue = SelectedFile;
  279. Invalidate();
  280. }
  281. }
  282. else if (pItem->m_nItemType == PIT_FONT)
  283. {
  284. CFontDialog FontDlg(NULL,CF_EFFECTS | CF_SCREENFONTS,NULL,this);
  285. if(IDOK == FontDlg.DoModal())
  286. {
  287. CString faceName = FontDlg.GetFaceName();
  288. m_btnCtrl.ShowWindow(SW_HIDE);
  289. pItem->m_curValue = faceName;
  290. Invalidate();
  291. }
  292. }
  293. }
  294. void CPropertyList::OnLButtonUp(UINT nFlags, CPoint point) 
  295. {
  296. if (m_bTracking)
  297. {
  298. //if columns were being resized then this indicates
  299. //that mouse is up so resizing is done.  Need to redraw
  300. //columns to reflect their new widths.
  301. m_bTracking = FALSE;
  302. //if mouse was captured then release it
  303. if (GetCapture()==this)
  304. ::ReleaseCapture();
  305. ::ClipCursor(NULL);
  306. CClientDC dc(this);
  307. InvertLine(&dc,CPoint(point.x,m_nDivTop),CPoint(point.x,m_nDivBtm));
  308. //set the divider position to the new value
  309. m_nDivider = point.x;
  310. //redraw
  311. Invalidate();
  312. }
  313. else
  314. {
  315. BOOL loc;
  316. int i = ItemFromPoint(point,loc);
  317. m_curSel = i;
  318. CListBox::OnLButtonUp(nFlags, point);
  319. }
  320. }
  321. void CPropertyList::OnLButtonDown(UINT nFlags, CPoint point) 
  322. {
  323. if ((point.x>=m_nDivider-5) && (point.x<=m_nDivider+5))
  324. {
  325. //if mouse clicked on divider line, then start resizing
  326. ::SetCursor(m_hCursorSize);
  327. CRect windowRect;
  328. GetWindowRect(windowRect);
  329. windowRect.left += 10; windowRect.right -= 10;
  330. //do not let mouse leave the list box boundary
  331. ::ClipCursor(windowRect);
  332. if (m_cmbBox)
  333. m_cmbBox.ShowWindow(SW_HIDE);
  334. if (m_editBox)
  335. m_editBox.ShowWindow(SW_HIDE);
  336. CRect clientRect;
  337. GetClientRect(clientRect);
  338. m_bTracking = TRUE;
  339. m_nDivTop = clientRect.top;
  340. m_nDivBtm = clientRect.bottom;
  341. m_nOldDivX = point.x;
  342. CClientDC dc(this);
  343. InvertLine(&dc,CPoint(m_nOldDivX,m_nDivTop),CPoint(m_nOldDivX,m_nDivBtm));
  344. //capture the mouse
  345. SetCapture();
  346. }
  347. else
  348. {
  349. m_bTracking = FALSE;
  350. CListBox::OnLButtonDown(nFlags, point);
  351. }
  352. }
  353. void CPropertyList::OnMouseMove(UINT nFlags, CPoint point) 
  354. {
  355. if (m_bTracking)
  356. {
  357. //move divider line to the mouse pos. if columns are
  358. //currently being resized
  359. CClientDC dc(this);
  360. //remove old divider line
  361. InvertLine(&dc,CPoint(m_nOldDivX,m_nDivTop),CPoint(m_nOldDivX,m_nDivBtm));
  362. //draw new divider line
  363. InvertLine(&dc,CPoint(point.x,m_nDivTop),CPoint(point.x,m_nDivBtm));
  364. m_nOldDivX = point.x;
  365. }
  366. else if ((point.x >= m_nDivider-5) && (point.x <= m_nDivider+5))
  367. //set the cursor to a sizing cursor if the cursor is over the row divider
  368. ::SetCursor(m_hCursorSize);
  369. else
  370. CListBox::OnMouseMove(nFlags, point);
  371. }
  372. void CPropertyList::InvertLine(CDC* pDC,CPoint ptFrom,CPoint ptTo)
  373. {
  374. int nOldMode = pDC->SetROP2(R2_NOT);
  375. pDC->MoveTo(ptFrom);
  376. pDC->LineTo(ptTo);
  377. pDC->SetROP2(nOldMode);
  378. }
  379. void CPropertyList::PreSubclassWindow() 
  380. {
  381. m_bDivIsSet = FALSE;
  382. m_nDivider = 0;
  383. m_bTracking = FALSE;
  384. m_curSel = 1;
  385. m_hCursorSize = AfxGetApp()->LoadStandardCursor(IDC_SIZEWE);
  386. m_hCursorArrow = AfxGetApp()->LoadStandardCursor(IDC_ARROW);
  387. m_SSerif8Font.CreatePointFont(80,_T("MS Sans Serif"));
  388. }