PictsViewer.cpp
上传用户:maryhy001
上传日期:2007-05-02
资源大小:2317k
文件大小:15k
源码类别:

网格计算

开发平台:

Visual C++

  1. // PictsViewer.cpp : implementation file
  2. #include "stdafx.h"
  3. #include "PictsViewer.h"
  4. #define MARGIN_LEFT 5
  5. #define MARGIN_TOP 5
  6. #define CX_EXPANDBTN 8
  7. #define CY_EXPANDBTN 4
  8. #define TIMER_ID_TRACKER 500
  9. //CPictsGroup class
  10. CPictsGroup::CPictsGroup()
  11. {
  12. this->m_pOwnerWnd = NULL;
  13. this->m_bOnlyShowCaption = FALSE;
  14. this->m_strCaption = "Picture Group";
  15. }
  16. CPictsGroup::~CPictsGroup()
  17. {
  18. this->m_imglstPicts.Detach();
  19. }
  20. void CPictsGroup::operator=(CPictsGroup &pgRight)
  21. {
  22. this->m_imglstPicts.Create(&pgRight.m_imglstPicts);
  23. this->m_strCaption  = pgRight.m_strCaption;
  24. this->m_pOwnerWnd = pgRight.m_pOwnerWnd;
  25. this->m_bOnlyShowCaption = pgRight.m_bOnlyShowCaption;
  26. }
  27. void CPictsGroup::SetOwnerWnd(CWnd *pOwnerWnd)
  28. {
  29. ASSERT(pOwnerWnd && ::IsWindow(pOwnerWnd->GetSafeHwnd()));
  30. this->m_pOwnerWnd = pOwnerWnd;
  31. }
  32. void CPictsGroup::SetCaption(LPCSTR strCaption)
  33. {
  34. this->m_strCaption = strCaption;
  35. }
  36. int  CPictsGroup::SetImageList(CImageList &ilImages)
  37. {
  38. this->m_imglstPicts.Detach();
  39. this->m_imglstPicts.Create(&ilImages);
  40. return this->m_imglstPicts.GetImageCount();
  41. }
  42. void CPictsGroup::SetOnlyShowCaption(BOOL bEnable)
  43. {
  44. this->m_bOnlyShowCaption = bEnable;
  45. if(this->m_pOwnerWnd)
  46. {
  47. this->m_pOwnerWnd->SendMessage(UWM_PICTSVIEWERREFRESH, 0, 0);
  48. }
  49. }
  50. int  CPictsGroup::InsertImage(CBitmap &bmp, COLORREF crMask)
  51. {
  52. this->m_imglstPicts.Add(&bmp, crMask);
  53. return this->m_imglstPicts.GetImageCount();
  54. }
  55. void CPictsGroup::DeleteImage(const int index)
  56. {
  57. int count = this->m_imglstPicts.GetImageCount();
  58. if(index > -1 && index < count)
  59. {
  60. this->m_imglstPicts.Remove(index);
  61. }
  62. }
  63. // CPictsViewer dialog
  64. CPictsViewer::CPictsViewer(CWnd* pParent /*=NULL*/)
  65. : CDialog(CPictsViewer::IDD, pParent)
  66. {
  67. this->m_wndParent = NULL;
  68. this->m_hcHand = NULL;
  69. this->m_uColsPreRow = 8;
  70. this->m_hOrgiWnd = NULL;
  71. this->m_bHoverControl = FALSE;
  72. this->m_bHoverGroupCaption = FALSE;
  73. this->m_nPictsGroupIndex = -1;
  74. this->m_nImageListIndex = -1;
  75. this->m_nHoverGroupCaptionIndex = -1;
  76. this->m_crBrdColor = RGB(0, 0, 160);
  77. this->m_crBkColor  = RGB(255, 255, 255);
  78. //{{AFX_DATA_INIT(CPictsViewer)
  79. //}}AFX_DATA_INIT
  80. }
  81. void CPictsViewer::DoDataExchange(CDataExchange* pDX)
  82. {
  83. CDialog::DoDataExchange(pDX);
  84. //{{AFX_DATA_MAP(CPictsViewer)
  85. //}}AFX_DATA_MAP
  86. }
  87. BEGIN_MESSAGE_MAP(CPictsViewer, CDialog)
  88. //{{AFX_MSG_MAP(CPictsViewer)
  89. ON_WM_PAINT()
  90. ON_WM_DESTROY()
  91. ON_WM_TIMER()
  92. ON_WM_ERASEBKGND()
  93. ON_WM_KILLFOCUS()
  94. ON_WM_MOUSEMOVE()
  95. ON_WM_SETCURSOR()
  96. ON_WM_LBUTTONDOWN()
  97. //}}AFX_MSG_MAP
  98. END_MESSAGE_MAP()
  99. // CPictsViewer message handlers
  100. BOOL CPictsViewer::Create(CWnd *pParent)
  101. {
  102. //if you want to create modeless window,
  103. //you must invoke CDialog::Create function.
  104. if(!CDialog::Create(CPictsViewer::IDD, pParent))
  105. {
  106. return FALSE;
  107. }
  108. this->m_wndParent = pParent;
  109. this->ModifyStyle(WS_CAPTION, WS_MINIMIZEBOX, SWP_DRAWFRAME);
  110. this->m_pnPen.CreatePen(PS_SOLID, 2, RGB(255, 0, 0));
  111. this->m_pnPen.GetLogPen(&m_logpen);
  112. this->m_ftFont.CreateFont(
  113. 16, // nHeight
  114. 0, // nWidth
  115. 0, // nEscapement
  116. 0, // nOrientation
  117. FW_BOLD, // nWeight
  118. FALSE, // bItalic
  119. FALSE, // bUnderline
  120. 0, // cStrikeOut
  121. ANSI_CHARSET, // nCharSet
  122. OUT_DEFAULT_PRECIS, // nOutPrecision
  123. CLIP_DEFAULT_PRECIS, // nClipPrecision
  124. DEFAULT_QUALITY, // nQuality
  125. DEFAULT_PITCH | FF_SWISS, // nPitchAndFamily
  126. "Arial");
  127. return TRUE;
  128. }
  129. void CPictsViewer::OnKillFocus(CWnd* pNewWnd) 
  130. {
  131. CDialog::OnKillFocus(pNewWnd);
  132. //close self windows.
  133. this->DestroyWindow();
  134. }
  135. void CPictsViewer::OnDestroy() 
  136. {
  137. CDialog::OnDestroy();
  138. if(NULL != m_hcHand)
  139. {
  140. ::DestroyCursor(this->m_hcHand);
  141. this->m_hcHand = NULL;
  142. }
  143. //delete GDI object.
  144. this->m_pnPen.DeleteObject();
  145. this->m_ftFont.DeleteObject();
  146. //free the memory.
  147. for(CPictsGroup *p = NULL; this->m_lstPictsGroups.GetCount() > 0; )
  148. {
  149. p = this->m_lstPictsGroups.GetHead();
  150. if(p) delete p;
  151. this->m_lstPictsGroups.RemoveHead();
  152. }
  153. this->FreeRcGralnkList();
  154. }
  155. void CPictsViewer::FreeRcGralnkList(void)
  156. {
  157. //1
  158. for(PRCLINKIMG prc = NULL; this->m_lstTxtRects.GetCount() > 0; )
  159. {
  160. prc = this->m_lstTxtRects.GetHead();
  161. if(prc) delete prc;
  162. this->m_lstTxtRects.RemoveHead();
  163. }
  164. this->m_lstTxtRects.RemoveAll();
  165. //2
  166. for(prc = NULL; this->m_lstGraphicRects.GetCount() > 0; )
  167. {
  168. prc = this->m_lstGraphicRects.GetHead();
  169. if(prc) delete prc;
  170. this->m_lstGraphicRects.RemoveHead();
  171. }
  172. this->m_lstGraphicRects.RemoveAll();
  173. //3
  174. for(prc = NULL; this->m_lstExpandBtnRects.GetCount() > 0; )
  175. {
  176. prc = this->m_lstExpandBtnRects.GetHead();
  177. if(prc) delete prc;
  178. this->m_lstExpandBtnRects.RemoveHead();
  179. }
  180. this->m_lstExpandBtnRects.RemoveAll();
  181. }
  182. int  CPictsViewer::InsertPictsGroup(CPictsGroup &pgPictsGroup)
  183. {
  184. CPictsGroup *p = new CPictsGroup;
  185. *p = pgPictsGroup;
  186. this->m_lstPictsGroups.AddTail(p);
  187. this->AdjustWindowRect();
  188. return this->m_lstPictsGroups.GetCount();
  189. }
  190. void CPictsViewer::DeletePictsGroup(const int index)
  191. {
  192. POSITION pos = this->m_lstPictsGroups.FindIndex(index);
  193. if(NULL != pos)
  194. {
  195. CPictsGroup *p = this->m_lstPictsGroups.GetAt(pos);
  196. if(p) delete p;
  197. this->m_lstPictsGroups.RemoveAt(pos);
  198. this->AdjustWindowRect();
  199. }
  200. }
  201. BOOL CPictsViewer::PreCreateWindow(CREATESTRUCT& cs) 
  202. {
  203. return CDialog::PreCreateWindow(cs);
  204. }
  205. void CPictsViewer::SetOrgWindow(HWND hwnd)
  206. {
  207. this->m_hOrgiWnd = hwnd;
  208. this->AdjustWindowRect();
  209. }
  210. void CPictsViewer::SetColsPreRow(const int nColsPreRow)
  211. {
  212. this->m_uColsPreRow = nColsPreRow;
  213. this->Invalidate();
  214. }
  215. void CPictsViewer::AdjustWindowRect(void)
  216. {
  217. CRect rcorgi;
  218. CDC *pDC = this->GetDC();
  219. int width = 0, height = 0;
  220. this->GetWindowRect(&rcorgi);
  221. width = rcorgi.Width(); height = rcorgi.Height();
  222. rcorgi.EqualRect(CRect(0, 0, 0, 0));
  223. if(NULL != this->m_hOrgiWnd)
  224. {
  225. ::GetWindowRect(this->m_hOrgiWnd, &rcorgi);
  226. }
  227. if(m_lstPictsGroups.GetCount() > 0)
  228. {
  229. CSize sizetxt;
  230. int cx = 0, 
  231. cy = 0,
  232. count = 0,
  233. txtheight  = 0,
  234. lineheight = 0;
  235. int nVisibleGroup = 0;
  236. width = height = 0;
  237. CPictsGroup *p = m_lstPictsGroups.GetHead();
  238. ImageList_GetIconSize(p->m_imglstPicts.GetSafeHandle(), &cx, &cy);
  239. for(POSITION pos = m_lstPictsGroups.GetHeadPosition(); pos != NULL; )
  240. {
  241. p = m_lstPictsGroups.GetNext(pos);
  242. if(!p->m_bOnlyShowCaption)
  243. {
  244. count += p->m_imglstPicts.GetImageCount();
  245. lineheight+= this->m_logpen.lopnWidth.x;
  246. nVisibleGroup++;
  247. }
  248. sizetxt = pDC->GetTextExtent(p->m_strCaption);
  249. txtheight += MARGIN_TOP + sizetxt.cy;
  250. }
  251. int rows = count / (this->m_uColsPreRow ? this->m_uColsPreRow : 1) + nVisibleGroup;
  252. width  = this->m_uColsPreRow * (MARGIN_LEFT + cx) + MARGIN_LEFT;
  253. height = rows * (cy + MARGIN_TOP) + MARGIN_TOP + (txtheight + lineheight + MARGIN_TOP);
  254. }
  255. if(width > 0 && height > 0)
  256. {
  257. this->SetWindowPos(NULL, rcorgi.left, rcorgi.bottom + 1, 
  258. width, height, SWP_SHOWWINDOW);
  259. this->Invalidate();
  260. }
  261. }
  262. BOOL CPictsViewer::OnEraseBkgnd(CDC* pDC)
  263. {
  264. return TRUE;
  265. }
  266. void CPictsViewer::OnPaint() 
  267. {
  268. //device context for painting.
  269. CPaintDC dc(this);
  270. CRect rcclt,
  271. rctxt,
  272. rcexpbtn;
  273. COLORREF crfntcolor;
  274. HPEN  hpen   = (HPEN)dc.SelectObject(m_pnPen.GetSafeHandle());
  275. HFONT hfont   = (HFONT)dc.SelectObject(m_ftFont.GetSafeHandle());
  276. int   nbkmode = dc.SetBkMode(TRANSPARENT);
  277. this->GetClientRect(&rcclt);
  278. //RGB(213, 227, 255)
  279. CBrush brush;
  280. brush.CreateSolidBrush(m_crBrdColor);
  281. dc.FillSolidRect(&rcclt, m_crBkColor);
  282. dc.FrameRect(&rcclt, &brush);
  283. if(m_lstPictsGroups.GetCount() > 0)
  284. {
  285. int cx = 0, cy = 0;
  286. int left = MARGIN_LEFT, top = MARGIN_TOP;
  287. //delete prior rect-graphices infos.
  288. this->FreeRcGralnkList();
  289. this->m_nPictsGroupIndex = m_nImageListIndex = -1;
  290. CPictsGroup *p = m_lstPictsGroups.GetHead();
  291. ImageList_GetIconSize(p->m_imglstPicts.GetSafeHandle(), &cx, &cy);
  292. POSITION pos = m_lstPictsGroups.GetHeadPosition();
  293. for(int j = 0; pos != NULL; ++j)
  294. {
  295. p = this->m_lstPictsGroups.GetAt(pos);
  296. //get the caption text drawing rect.
  297. CSize sizetxt = dc.GetTextExtent(p->m_strCaption);
  298. rctxt.left = CX_EXPANDBTN + 2*MARGIN_LEFT;
  299. rctxt.top  = top + MARGIN_TOP;
  300. rctxt.right  = rctxt.left + this->m_uColsPreRow * cx;
  301. rctxt.bottom = rctxt.top  + sizetxt.cy;
  302. //get the expanding button rect.
  303. rcexpbtn.left = MARGIN_LEFT;
  304. rcexpbtn.top  = top + MARGIN_TOP;
  305. rcexpbtn.right = rcexpbtn.left + CX_EXPANDBTN;
  306. rcexpbtn.bottom = max(rctxt.bottom, rcexpbtn.top + CY_EXPANDBTN);
  307. rctxt.bottom = rcexpbtn.bottom;
  308. //make the caption rect info and insert it into memory list.
  309. PRCLINKIMG prclnk = new RCLINKIMG;
  310. prclnk->rc = (RECT)rctxt;
  311. prclnk->lparam = j;
  312. this->m_lstTxtRects.AddTail(prclnk);
  313. //make expanding button rect.
  314. prclnk = new RCLINKIMG;
  315. prclnk->rc = (RECT)rcexpbtn;
  316. prclnk->lparam = j;
  317. this->m_lstExpandBtnRects.AddTail(prclnk);
  318. //draw expanding button.
  319. if(p->m_bOnlyShowCaption)
  320. {
  321. crfntcolor = dc.SetTextColor(RGB(155, 50, 0));
  322. dc.DrawText("+", &rcexpbtn, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  323. dc.SetTextColor(crfntcolor);
  324. }
  325. else
  326. {
  327. crfntcolor = dc.SetTextColor(RGB(0, 0, 0));
  328. dc.DrawText("-", &rcexpbtn, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  329. dc.SetTextColor(crfntcolor);
  330. }
  331. rcexpbtn.InflateRect(0, 1);
  332. dc.FrameRect(&rcexpbtn, &brush);
  333. //if current mouse is hovering on caption rect the change the caption text color.
  334. if(this->m_bHoverGroupCaption && j == this->m_nHoverGroupCaptionIndex)
  335. crfntcolor = dc.SetTextColor(RGB(0, 0, 255));
  336. else
  337. crfntcolor = dc.SetTextColor(RGB(0, 0, 0));
  338. dc.DrawText(p->m_strCaption, &rctxt, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
  339. dc.SetTextColor(crfntcolor);
  340. top = rctxt.bottom + MARGIN_TOP;
  341. //if user want to hide or show some pictures group then ...
  342. if(!p->m_bOnlyShowCaption)
  343. {
  344. //draw the line.
  345. dc.MoveTo(rctxt.left, rctxt.bottom + m_logpen.lopnWidth.x);
  346. dc.LineTo(rcclt.right - MARGIN_LEFT, rctxt.bottom + m_logpen.lopnWidth.x);
  347. //draw the imagelist elements and get every image's rect info.
  348. for(int i = 0; p && i < p->m_imglstPicts.GetImageCount(); ++i)
  349. {
  350. PRCLINKIMG prclnk = new RCLINKIMG;
  351. prclnk->rc = (RECT)CRect(left, top, left+cx, top+cy);
  352. prclnk->lparam = MAKELONG(i, j);
  353. this->m_lstGraphicRects.AddTail(prclnk);
  354. p->m_imglstPicts.DrawIndirect(&dc, i, CPoint(left, top),
  355. CSize(cx, cy), CPoint(0, 0), ILD_NORMAL, SRCCOPY);
  356. left += (cx + MARGIN_LEFT);
  357. if((i + 1) % (this->m_uColsPreRow ? this->m_uColsPreRow : 1) == 0)
  358. {
  359. left = MARGIN_LEFT;
  360. top += (cy + MARGIN_TOP);
  361. }
  362. }
  363. top  = top + (cy + MARGIN_TOP);
  364. }
  365. p = m_lstPictsGroups.GetNext(pos);
  366. left = MARGIN_LEFT;
  367. }
  368. }
  369. brush.DeleteObject();
  370. dc.SelectObject(hfont);
  371. dc.SelectObject(hpen);
  372. dc.SetBkMode(nbkmode);
  373. }
  374. BOOL CPictsViewer::PtInPictsExpandButtonRect(CPoint point, int &nGroupIndex, CRect &rcExpandButton)
  375. {
  376. if(!this->m_bHoverControl || !this->m_lstExpandBtnRects.GetCount()) return FALSE;
  377. POSITION pos = this->m_lstExpandBtnRects.GetHeadPosition();
  378. for(PRCLINKIMG prclnk = NULL; pos != NULL; )
  379. {
  380. prclnk = this->m_lstExpandBtnRects.GetNext(pos);
  381. if(prclnk && ::PtInRect(&prclnk->rc, (POINT)point))
  382. {
  383. nGroupIndex = prclnk->lparam;
  384. rcExpandButton = prclnk->rc;
  385. return TRUE;
  386. }
  387. }
  388. return FALSE;
  389. }
  390. BOOL CPictsViewer::PtInPictsGroupCaptionRect(CPoint point, int &nPictsGroupIndex, CRect &rcCaption)
  391. {
  392. if(!this->m_bHoverControl || !this->m_lstPictsGroups.GetCount()) return FALSE;
  393. nPictsGroupIndex = -1;
  394. POSITION pos = this->m_lstTxtRects.GetHeadPosition();
  395. for(PRCLINKIMG prclnk = NULL; pos != NULL; )
  396. {
  397. prclnk = this->m_lstTxtRects.GetNext(pos);
  398. if(prclnk && ::PtInRect(&prclnk->rc, (POINT)point))
  399. {
  400. nPictsGroupIndex = prclnk->lparam;
  401. rcCaption = prclnk->rc;
  402. return TRUE;
  403. }
  404. }
  405. return FALSE;
  406. }
  407. BOOL CPictsViewer::GetCellFromPoint(CPoint point, int &nGroupIndex, int &nImageIndex, CRect &rcGraphic)
  408. {
  409. if(!this->m_bHoverControl || !this->m_lstPictsGroups.GetCount()) return FALSE;
  410. nGroupIndex = nImageIndex = -1;
  411. POSITION pos = this->m_lstGraphicRects.GetHeadPosition();
  412. for(PRCLINKIMG prclnk = NULL; pos != NULL; )
  413. {
  414. prclnk = this->m_lstGraphicRects.GetNext(pos);
  415. if(prclnk && ::PtInRect(&prclnk->rc, (POINT)point))
  416. {
  417. rcGraphic = prclnk->rc;
  418. nGroupIndex = HIWORD(prclnk->lparam);
  419. nImageIndex = LOWORD(prclnk->lparam);
  420. return TRUE;
  421. }
  422. }
  423. return FALSE;
  424. }
  425. void CPictsViewer::OnMouseMove(UINT nFlags, CPoint point) 
  426. {
  427. if(!this->m_bHoverControl)
  428. {
  429. this->m_bHoverControl = TRUE;
  430. this->Invalidate();
  431. this->SetTimer(TIMER_ID_TRACKER, 100, NULL);
  432. }
  433. CRect rcCaption, rcGraphic;
  434. BOOL bInCaptionRect = PtInPictsGroupCaptionRect(point, m_nHoverGroupCaptionIndex, rcCaption);
  435. this->m_bHoverGroupCaption = bInCaptionRect;
  436. this->InvalidateRect(&rcCaption);
  437. this->GetCellFromPoint(point, m_nPictsGroupIndex, 
  438.   m_nImageListIndex, rcGraphic);
  439. CDialog::OnMouseMove(nFlags, point);
  440. }
  441. void CPictsViewer::OnTimer(UINT nIDEvent) 
  442. {
  443. CRect rcclt;
  444. CPoint ptcur;
  445. ::GetCursorPos(&ptcur);
  446. this->GetClientRect(&rcclt);
  447. this->ScreenToClient(&ptcur);
  448. if(!rcclt.PtInRect(ptcur))
  449. {
  450. this->m_bHoverControl = FALSE;
  451. this->KillTimer(TIMER_ID_TRACKER);
  452. this->Invalidate();
  453. }
  454. CDialog::OnTimer(nIDEvent);
  455. }
  456. BOOL CPictsViewer::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 
  457. {
  458. if(NULL == this->m_hcHand)
  459. {
  460. this->m_hcHand = GetSysHandCursor();
  461. if(NULL == this->m_hcHand) return FALSE;
  462. }
  463. ::SetCursor(this->m_hcHand);
  464. return TRUE;
  465. }
  466. void CPictsViewer::OnLButtonDown(UINT nFlags, CPoint point)
  467. {
  468. CRect rcExpanBtn,
  469. rcGraphic;
  470. POSITION pos;
  471. if(this->m_bHoverControl)
  472. {
  473. if(!this->m_bHoverGroupCaption)
  474. {
  475. if(this->GetCellFromPoint(point, m_nPictsGroupIndex, m_nImageListIndex, rcGraphic))
  476. {
  477. if(m_nPictsGroupIndex != -1 && m_nImageListIndex != -1)
  478. {
  479. if(this->m_wndParent) m_wndParent->SendMessage(UWM_PICTSVIEWERCLICKED, MAKEWORD(m_nImageListIndex, m_nPictsGroupIndex), NULL);
  480. }
  481. }
  482. else if(this->PtInPictsExpandButtonRect(point, m_nPictsGroupIndex, rcExpanBtn))
  483. {
  484. if(m_nPictsGroupIndex != -1)
  485. {
  486. m_nImageListIndex = -1;
  487. pos = this->m_lstPictsGroups.FindIndex(m_nPictsGroupIndex);
  488. if(pos != NULL)
  489. {
  490. CPictsGroup *p = this->m_lstPictsGroups.GetAt(pos);
  491. p->m_bOnlyShowCaption = !p->m_bOnlyShowCaption;
  492. this->AdjustWindowRect();
  493. this->Invalidate();
  494. }
  495. }
  496. }
  497. }
  498. else
  499. {
  500. //////////////////////////////////////////////////////////////////////////
  501. }
  502. }
  503. CDialog::OnLButtonDown(nFlags, point);
  504. }
  505. void CPictsViewer::OnRefreshMsg(WPARAM wparam, LPARAM lparam)
  506. {
  507. this->AdjustWindowRect();
  508. this->Invalidate();
  509. }