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

图形图象

开发平台:

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 "UIStatusBar.h"
  19. #ifdef _DEBUG
  20. #define new DEBUG_NEW
  21. #undef THIS_FILE
  22. static char THIS_FILE[] = __FILE__;
  23. #endif
  24. ///////////////////////////////////
  25. //
  26. // IMStatusBar
  27. //
  28. ///////////////////////////////////
  29. IMPLEMENT_SERIAL(CUIStatusBar, CStatusBar, 0)
  30. IMPLEMENT_SERIAL(CStatusBarPane, CObject, 0)
  31. BEGIN_MESSAGE_MAP(CUIStatusBar, CStatusBar)
  32. //{{AFX_MSG_MAP(CUIStatusBar)
  33. ON_WM_CONTEXTMENU()
  34. ON_WM_LBUTTONDOWN()
  35. ON_WM_SETCURSOR()
  36. //}}AFX_MSG_MAP
  37. END_MESSAGE_MAP()
  38. LPCTSTR CUIStatusBar::szSection = _T("Settings\StatusBar");
  39. LPCTSTR CUIStatusBar::szPaneEntry = _T("Pane");
  40. CStatusBarPane::CStatusBarPane(const CStatusBarPane &rOther)
  41. {
  42. DoCopy(rOther);
  43. }
  44. CStatusBarPane &CStatusBarPane::operator=(const CStatusBarPane &rOther)
  45. {
  46. if (this == &rOther)
  47. return *this;
  48. DoCopy(rOther);
  49. return *this;
  50. }
  51. void CStatusBarPane::DoCopy(const CStatusBarPane &rOther)
  52. {
  53. m_nID = rOther.m_nID;
  54. m_nStyle = rOther.m_nStyle;
  55. m_bActive = rOther.m_bActive;
  56. // m_listImageIndex = rOther.m_listImageIndex;
  57. }
  58. void CStatusBarPane::Serialize(CArchive &ar)
  59. {
  60. if (ar.IsStoring())
  61. {
  62. ar << m_nID;
  63. ar << m_nStyle;
  64. ar << m_bActive;
  65. }
  66. else
  67. {
  68. ar >> m_nID;
  69. ar >> m_nStyle;
  70. ar >> m_bActive;
  71. }
  72. }
  73. void CUIStatusBar::OnContextMenu(CWnd *pWnd, CPoint point)
  74. {
  75. /*  CMenu Menu;
  76. // Build the popup menu
  77. Menu.CreatePopupMenu();
  78. CStatusBarPane *pPane = NULL;
  79. CString strText;
  80. for(POSITION pos = m_PaneList.GetTailPosition();pos != NULL;) 
  81. {
  82. pPane = m_PaneList.GetPrev(pos);
  83. if (pPane->GetCommandID() != ID_SEPARATOR && pPane->GetCommandID() != ID_INDICATOR_MAIN) 
  84. {
  85. strText.LoadString(pPane->GetCommandID());
  86. Menu.AppendMenu(MF_STRING,pPane->GetCommandID(),strText);
  87. }
  88. }
  89. // and display using main frame as message window
  90. Menu.TrackPopupMenu(TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_LEFTALIGN,point.x,point.y,theApp.m_pMainWnd);
  91. theApp.m_pMainWnd->SetFocus();
  92. */
  93. }
  94. ////////////////////////////////////////////////////////////
  95. CUIStatusBar::CUIStatusBar()
  96. {
  97. Init();
  98. }
  99. CUIStatusBar::~CUIStatusBar()
  100. {
  101. Clear();
  102. }
  103. void CUIStatusBar::Reset()
  104. {
  105. Clear();
  106. Init();
  107. }
  108. void CUIStatusBar::Init()
  109. {
  110. m_nStatusPane1Width = -1;
  111. m_nStatusPane1Style = SBPS_STRETCH;
  112. m_bMenuSelect = FALSE;
  113. m_nMinHeight = GetSystemMetrics(SM_CYSMICON)+4;
  114. m_pImageList = new CImageList;
  115. }
  116. void CUIStatusBar::Clear()
  117. {
  118. CStatusBarPane *pPane;
  119. while (!m_PaneList.IsEmpty()) 
  120. {
  121. pPane = m_PaneList.RemoveTail();
  122. delete pPane;
  123. }
  124. delete m_pImageList;
  125. m_pImageList = NULL;
  126. }
  127. CUIStatusBar &CUIStatusBar::operator=(const CUIStatusBar &rOther)
  128. {
  129. if (this == &rOther)
  130. return *this;
  131. for(POSITION pos=rOther.m_PaneList.GetHeadPosition();pos != NULL;) 
  132. {
  133. CStatusBarPane *pPane = new CStatusBarPane;
  134. *pPane = *rOther.m_PaneList.GetNext(pos);
  135. m_PaneList.AddTail(pPane);
  136. }
  137. m_nStatusPane1ID = rOther.m_nStatusPane1ID;
  138. m_nStatusPane1Style = rOther.m_nStatusPane1Style;
  139. m_nStatusPane1Width = rOther.m_nStatusPane1Width;
  140. m_bMenuSelect = rOther.m_bMenuSelect;
  141. return *this;
  142. }
  143. void CUIStatusBar::UpdatePane(int nIndex)
  144. {
  145. CRect rect;
  146. GetStatusBarCtrl().GetRect(nIndex,&rect);
  147. InvalidateRect(rect);
  148. UpdateWindow();
  149. }
  150. CStatusBarPane *CUIStatusBar::GetPane(UINT nPaneID) const
  151. {
  152. if (nPaneID == 0)
  153. {
  154. nPaneID = ((CUIStatusBar*)this)->GetPaneID(0);
  155. }
  156. CStatusBarPane *pPane = NULL;
  157. for (POSITION pos=m_PaneList.GetHeadPosition();pos != NULL;) 
  158. {
  159. pPane = m_PaneList.GetNext(pos);
  160. if (pPane->GetCommandID() == nPaneID)
  161. break;
  162. }
  163. return((pPane && nPaneID == pPane->GetCommandID()) ? pPane : NULL);
  164. }
  165. void CUIStatusBar::RemoveAllIcons(UINT nPaneID)
  166. {
  167. CStatusBarPane *pPane = GetPane(nPaneID);
  168. ASSERT(pPane);
  169. pPane->RemoveAllImages();
  170. UpdatePane(GetPaneIndex(nPaneID));
  171. }
  172. void CUIStatusBar::RemoveIcon(UINT nPaneID,UINT nImageID,bool bUpdate)
  173. {
  174. if (nPaneID == 0)
  175. {
  176. nPaneID = GetPaneID(0);
  177. }
  178. CStatusBarPane *pPane = GetPane(nPaneID);
  179. ASSERT(pPane);
  180. RemoveIcon(nImageID,pPane,bUpdate);
  181. }
  182. void CUIStatusBar::RemoveIcon(UINT nImageID,CStatusBarPane *pPane,bool bUpdate)
  183. {
  184. int nImageIndex=-1;
  185. if (m_mapImageIndex.Lookup(nImageID,nImageIndex))
  186. pPane->RemoveImage(nImageIndex);
  187. if (bUpdate)
  188. UpdatePane(nImageIndex);
  189. }
  190. void CUIStatusBar::AddIcon(UINT nPaneID,UINT nImageID,bool bUpdate)
  191. {
  192. int nIndex = -1;
  193. if (!m_mapImageIndex.Lookup(nImageID,nIndex))
  194. nIndex = AddIcon(nImageID);
  195. // Possibly wrong id using pane index 0
  196. if (nPaneID == 0)
  197. {
  198. nPaneID = GetPaneID(0);
  199. }
  200. AddImageIndex(nPaneID,nIndex,bUpdate);
  201. }
  202. // add an image to list of images that will be displayed
  203. // nIndex into the image list
  204. void CUIStatusBar::AddImageIndex(UINT nPaneID,int nImageIndex,bool bUpdate)
  205. {
  206. CStatusBarPane *pPane = GetPane(nPaneID);
  207. ASSERT(pPane);
  208. int nPaneIndex = GetPaneIndex(nPaneID);
  209. // Pane 0 can have only one icon
  210. if (nPaneIndex == 0)
  211. {
  212. pPane->RemoveAllImages();
  213. }
  214. if (!pPane->FindImage(nImageIndex))
  215. {
  216. pPane->AddImage(nImageIndex);
  217. }
  218. UINT nStyle;
  219. int nWidth;
  220. GetPaneInfo(nPaneIndex,nPaneID,nStyle,nWidth);
  221. // Make sure it's owner draw
  222. if (!(nStyle & SBT_OWNERDRAW))
  223. {
  224. nStyle |= SBT_OWNERDRAW;
  225. SetPaneInfo(nPaneIndex,nPaneID,nStyle,nWidth);
  226. pPane->SetStyle(nStyle);
  227. }
  228. if (bUpdate)
  229. UpdatePane(GetPaneIndex(nPaneID));
  230. }
  231. int CUIStatusBar::AddIcon(UINT nID)
  232. {
  233. if (m_pImageList->m_hImageList == NULL)
  234. CreateImageList();
  235. ASSERT(m_pImageList->m_hImageList);
  236. HICON hIcon = (HICON)::LoadImage(AfxGetInstanceHandle(),MAKEINTRESOURCE(nID),IMAGE_ICON,16,16,LR_DEFAULTCOLOR);
  237. if (hIcon)
  238. {
  239. int nIndex = m_pImageList->Add(hIcon);
  240. m_mapImageIndex[nID] = nIndex;
  241. return nIndex;
  242. }
  243. return -1;
  244. }
  245. // set image list from a bitmap id
  246. void CUIStatusBar::SetImageList(UINT nBitmapID)
  247. {
  248. delete m_pImageList;
  249. m_pImageList = NULL;
  250. m_pImageList = new CImageList;
  251. m_pImageList->Create(nBitmapID,::GetSystemMetrics(SM_CXSMICON),0,::GetSysColor(COLOR_BTNFACE));
  252. }
  253. void CUIStatusBar::CreateImageList()
  254. {
  255. delete m_pImageList;
  256. m_pImageList = new CImageList;
  257. m_pImageList->Create(::GetSystemMetrics(SM_CXSMICON),::GetSystemMetrics(SM_CYSMICON),ILC_MASK | ILC_COLOR16,0,1);
  258. m_pImageList->SetBkColor(CLR_NONE);
  259. }
  260. void CUIStatusBar::SetImageList(CImageList *pImageList)
  261. {
  262. CreateImageList();
  263. // if one passed in copy it
  264. if (pImageList)
  265. {
  266. int count = pImageList->GetImageCount();
  267. for(int i=0;i < count;i++)
  268. {
  269. HICON hIcon = pImageList->ExtractIcon(i);
  270. m_pImageList->Add(hIcon);
  271. }
  272. }
  273. }
  274. void CUIStatusBar::AddPane(UINT nID,BOOL bActive)
  275. {
  276. CStatusBarPane *pPane = new CStatusBarPane(nID,bActive);
  277. pPane->SetStyle(SBT_OWNERDRAW);
  278. m_PaneList.AddTail(pPane);
  279. }
  280. BOOL CUIStatusBar::SetPanes(BOOL bSave)
  281. {
  282. int nSize = 0;
  283. CStatusBarPane *pPane = NULL;
  284. for(POSITION pos = m_PaneList.GetTailPosition();pos != NULL;) 
  285. {
  286. pPane = m_PaneList.GetPrev(pos);
  287. nSize += pPane->IsPaneActive();
  288. }
  289. UINT *pIndicators = new UINT[nSize];
  290. int nIndex = 0;
  291. for(pos = m_PaneList.GetHeadPosition();pos != NULL;) 
  292. {
  293. pPane = m_PaneList.GetNext(pos);
  294. if (pPane->IsPaneActive()) 
  295. {
  296. pIndicators[nIndex++] = pPane->GetCommandID();
  297. }
  298. }
  299. BOOL ret = SetIndicators(pIndicators, nSize);
  300. delete[] pIndicators;
  301. UINT nID, nStyle;
  302. int nWidth;
  303. for(pos = m_PaneList.GetTailPosition();pos != NULL;) 
  304. {
  305. pPane = m_PaneList.GetPrev(pos);
  306. if (pPane->IsPaneActive() && pPane->GetCommandID() != ID_SEPARATOR) 
  307. {
  308. int nIndex = GetPaneIndex(pPane->GetCommandID());
  309. GetPaneInfo(nIndex,nID,nStyle,nWidth);
  310. SetPaneInfo(nIndex,pPane->GetCommandID(),nStyle | pPane->GetStyle(),nWidth);
  311. SetPaneText(nIndex,_T(""));
  312. }
  313. }
  314. GetPaneInfo(0,nID,nStyle,nWidth);
  315. // First pane has its own style
  316. SetPaneInfo(0,nID,m_nStatusPane1Style,nWidth);
  317. if (bSave) 
  318. {
  319. // save to registry
  320. Save();
  321. }
  322. return ret;
  323. }
  324. void CUIStatusBar::Load()
  325. {
  326. CWinApp *pApp = AfxGetApp();
  327. CString strPane;
  328. CStatusBarPane *pPane = NULL;
  329. int i=0;
  330. for(POSITION pos = m_PaneList.GetTailPosition();pos != NULL;i++) 
  331. {
  332. pPane = m_PaneList.GetPrev(pos);
  333. strPane.Format(_T("%s%d"),szPaneEntry,i);
  334. pPane->SetPaneActive(pApp->GetProfileInt(szSection,strPane,pPane->IsPaneActive()));      
  335. }
  336. }
  337. void CUIStatusBar::Save()
  338. {
  339. CWinApp *pApp = AfxGetApp();
  340. CString strPane;
  341. CStatusBarPane *pPane = NULL;
  342. int i=0;
  343. for(POSITION pos = m_PaneList.GetTailPosition();pos != NULL;i++) 
  344. {
  345. pPane = m_PaneList.GetPrev(pos);
  346. strPane.Format(_T("%s%d"),szPaneEntry,i);
  347. pApp->WriteProfileInt(szSection,strPane,pPane->IsPaneActive());
  348. }
  349. }
  350. void CUIStatusBar::TogglePane(UINT nID)
  351. {
  352. CStatusBarPane *pPane = GetPane(nID);
  353. if (pPane) 
  354. {
  355. pPane->SetPaneActive(!pPane->IsPaneActive());
  356. SetPanes(TRUE);
  357. }
  358. }
  359. void CUIStatusBar::SetText(UINT nPaneID,LPCTSTR szText,bool bUpdate)
  360. {
  361. const CStatusBarPane *pPane = GetPane(nPaneID);
  362. ASSERT(pPane);
  363. SetTextPane(pPane,szText,bUpdate);
  364. }
  365. void CUIStatusBar::SetTextPane(const CStatusBarPane *pPane,LPCTSTR szText,bool bUpdate)
  366. {
  367. if (!pPane->IsPaneActive())
  368. return;
  369. int nIndex = GetPaneIndex(pPane->GetCommandID());
  370. UINT nStyle;
  371. UINT nPaneID=pPane->GetCommandID();
  372. int nWidth;
  373. GetPaneInfo(nIndex, nPaneID, nStyle, nWidth);
  374. nStyle |= SBT_OWNERDRAW;
  375. if (nIndex != 0)
  376. {
  377. HGDIOBJ hOldFont = NULL;
  378. HFONT hFont = (HFONT)SendMessage(WM_GETFONT);
  379. CClientDC dc(NULL);
  380. if (hFont != NULL) 
  381. hOldFont = dc.SelectObject(hFont);
  382. CSize size = dc.GetTextExtent(szText);
  383. if (hOldFont != NULL) 
  384. dc.SelectObject(hOldFont);
  385. nWidth = size.cx;
  386. }
  387. SetPaneInfo(nIndex, nPaneID, nStyle, nWidth);
  388. SetPaneText(nIndex, szText, bUpdate);
  389. if (bUpdate)
  390. UpdateWindow();
  391. }
  392. void CUIStatusBar::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
  393. {
  394. CStatusBarPane *pPane = GetPane(GetPaneID(lpDrawItemStruct->itemID));
  395. if (pPane) 
  396. {
  397. // Get the pane rectangle and calculate text coordinates
  398. CRect rect(&lpDrawItemStruct->rcItem);
  399. CDC *pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
  400. COLORREF oldBkColor = pDC->SetBkColor(::GetSysColor(COLOR_BTNFACE));
  401. // draw the image
  402. CListImages &listImages = pPane->GetImageIndex();
  403. // make sure there is an image
  404. if (!listImages.IsEmpty()) 
  405. {
  406. for(POSITION pos=listImages.GetTailPosition();pos != NULL;)
  407. {
  408. m_pImageList->Draw(pDC,listImages.GetPrev(pos),CPoint(rect.left,rect.top),ILD_NORMAL);
  409. rect.left += ::GetSystemMetrics(SM_CXSMICON);
  410. rect.left += 5;
  411. }
  412. }
  413. // draw the text
  414. LPCTSTR pszText = (LPCTSTR)lpDrawItemStruct->itemData;
  415. // make sure there is text
  416. if (pszText)
  417. {
  418. UINT nFormat = DT_LEFT | DT_SINGLELINE | DT_EXPANDTABS | DT_NOPREFIX | DT_VCENTER;
  419. // if (pPane->GetStyle() & SBPS_POPOUT)
  420. // nFormat |= DT_VCENTER;
  421. // else
  422. // nFormat |= DT_BOTTOM;
  423. pDC->DrawText(pszText,lstrlen(pszText),rect,nFormat);
  424. }
  425. pDC->SetBkColor(oldBkColor);
  426. }
  427. }
  428. void CUIStatusBar::Serialize(CArchive &ar)
  429. {
  430. CStatusBar::Serialize(ar);
  431. m_PaneList.Serialize(ar);
  432. }
  433. template <> void AFXAPI SerializeElements <CStatusBarPane*> (CArchive& ar, CStatusBarPane **ppPane, int nCount)
  434. {
  435.     for (int i=0;i < nCount;i++,ppPane++)
  436.     {
  437. if (ar.IsLoading())
  438. {
  439. ar >> *ppPane;
  440. }
  441. else
  442. {
  443. ar << *ppPane;
  444. }
  445.     }
  446. }
  447. void CUIStatusBar::OnLButtonDown(UINT nFlags, CPoint point) 
  448. {
  449. // TODO: Add your message handler code here and/or call default
  450. CStatusBar::OnLButtonDown(nFlags, point);
  451. }
  452. BOOL CUIStatusBar::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 
  453. {
  454. // TODO: Add your message handler code here and/or call default
  455. /* if (theApp.IsLoading())
  456. {
  457. CPoint point;
  458. ::GetCursorPos(&point);
  459. ScreenToClient(&point);
  460. CRect rect;
  461. GetItemRect(4,&rect);
  462. if (rect.PtInRect(point))
  463. {
  464. SetCursor(::LoadCursor(NULL,IDC_CROSS));
  465. return TRUE;
  466. }
  467. }
  468. */
  469. return CStatusBar::OnSetCursor(pWnd, nHitTest, message);
  470. }
  471. ////////////////////////////////////////////////////////////////////////
  472. IMPLEMENT_DYNCREATE(CProgressBar, CProgressCtrl)
  473. BEGIN_MESSAGE_MAP(CProgressBar, CProgressCtrl)
  474. //{{AFX_MSG_MAP(CProgressBar)
  475. ON_WM_ERASEBKGND()
  476. //}}AFX_MSG_MAP
  477. END_MESSAGE_MAP()
  478. CProgressBar::CProgressBar() : m_nPaneIndex(-1), m_pStatusBar(NULL)
  479. {
  480. }
  481. CProgressBar::CProgressBar(int nPaneID, CUIStatusBar *pStatusBar, int MaxValue /* = 100 */)
  482. {
  483. Create(nPaneID, pStatusBar, MaxValue);
  484. }
  485. CProgressBar::~CProgressBar()
  486. {
  487. Clear();
  488. }
  489. // Create the CProgressCtrl as a child of the status bar 
  490. BOOL CProgressBar::Create(int nPaneID, CUIStatusBar *pStatusBar, int MaxValue)
  491. {
  492. m_pStatusBar = pStatusBar;
  493. m_nPaneIndex = pStatusBar->GetPaneIndex(nPaneID);
  494. if (m_nPaneIndex == -1)
  495. return FALSE;
  496. // Create the progress bar
  497. if (!CProgressCtrl::Create(WS_CHILD | WS_VISIBLE | PBS_SMOOTH, CRect(0,0,0,0), pStatusBar, 1))
  498. return FALSE;
  499. // Set range and step
  500. SetRange(0, MaxValue);
  501. SetStep(1);
  502. // Resize the control to its desired width
  503. Resize();
  504. return TRUE;
  505. }
  506. void CProgressBar::Clear()
  507. {
  508. }
  509. void CProgressBar::SetRange(int nLower, int nUpper, int nStep /* = 1 */)
  510. {
  511. CProgressCtrl::SetRange(nLower, nUpper);
  512. CProgressCtrl::SetStep(nStep);
  513. }
  514. int CProgressBar::SetPos(int nPos)  
  515. {
  516. if (m_hWnd == NULL)
  517. return -1;
  518. ModifyStyle(0,WS_VISIBLE);
  519. return CProgressCtrl::SetPos(nPos);
  520. }
  521. int  CProgressBar::OffsetPos(int nPos) 
  522. if (m_hWnd == NULL)
  523. return -1;
  524. ModifyStyle(0,WS_VISIBLE);
  525. return CProgressCtrl::OffsetPos(nPos);
  526. }
  527. int  CProgressBar::SetStep(int nStep)
  528. if (m_hWnd == NULL)
  529. return -1;
  530. ModifyStyle(0,WS_VISIBLE);
  531. return CProgressCtrl::SetStep(nStep);
  532. }
  533. int  CProgressBar::StepIt()  
  534. if (m_hWnd == NULL)
  535. return -1;
  536. ModifyStyle(0,WS_VISIBLE);
  537. return CProgressCtrl::StepIt();
  538. }
  539. void CProgressBar::Resize() 
  540. {
  541. ASSERT(m_pStatusBar);
  542. ASSERT(m_nPaneIndex != -1);
  543. if (!m_pStatusBar) 
  544. return;
  545. // Now get the rectangle in which we will draw the progress bar
  546. CRect rc;
  547. m_pStatusBar->GetItemRect (m_nPaneIndex, rc);
  548. // Resize the window
  549. if (::IsWindow(m_hWnd))
  550.     MoveWindow(&rc);
  551. }
  552. BOOL CProgressBar::OnEraseBkgnd(CDC* pDC) 
  553. {
  554. Resize();
  555. return CProgressCtrl::OnEraseBkgnd(pDC);
  556. }