SwitcherWnd.cpp
上传用户:sdpcwz
上传日期:2009-12-14
资源大小:1237k
文件大小:8k
源码类别:

书籍源码

开发平台:

Visual C++

  1. // SwitcherWnd.cpp
  2. //
  3. // Programmed by: JIMMY BRUSH (Kathy007@email.msn.com)
  4. // 
  5. // Legal:
  6. //
  7. // THIS CODE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND.
  8. // You may use and distribute this code provided that you do not
  9. // remove this title header and that you do not charge money for
  10. // it. If you want to update the code, feel free to do so, as long
  11. // as you *mark your changes* in code AND in the revision log below
  12. // (and send it to me ;)
  13. //
  14. //
  15. //
  16. // Version: 1.0 revision 1
  17. //
  18. // Revision Log:
  19. //
  20. // SUN MAR 14 1999 - JIMMY BRUSH -  Finished Writing version 1.0
  21. // MON MAR 15 1999 - JIMMY BRUSH -  Fixed RemoveButton to correctly decrement selected button
  22. // Added CMemDC by Keith Rule
  23. // Fixed up Animation a bit
  24. //
  25. //
  26. //
  27. // In the next version  Wish List:
  28. //
  29. // 1. Tool Tips in CSwitcherButton
  30. // 2. Support for more buttons than can display (with the up/down button at the right)
  31. #include "stdafx.h"
  32. #include "SwitcherButton.h"
  33. #include "SwitcherWnd.h"
  34. #ifdef _DEBUG
  35. #define new DEBUG_NEW
  36. #undef THIS_FILE
  37. static char THIS_FILE[] = __FILE__;
  38. #endif
  39. #define DEFAULTWIDTH 130
  40. #define DEFAULTHEIGHT 25
  41. #define MINWIDTH 24
  42. /////////////////////////////////////////////////////////////////////////////
  43. // CSwitcherWnd
  44. CSwitcherWnd::CSwitcherWnd()
  45. {
  46. m_iButtonWidth = DEFAULTWIDTH;
  47. m_iNextButtonStart = 0;
  48. m_iSelectedButton = -1;
  49. }
  50. CSwitcherWnd::~CSwitcherWnd()
  51. {
  52. }
  53. BEGIN_MESSAGE_MAP(CSwitcherWnd, CWnd)
  54. //{{AFX_MSG_MAP(CSwitcherWnd)
  55. ON_WM_DESTROY()
  56. ON_WM_PAINT()
  57. ON_WM_SIZE()
  58. ON_WM_LBUTTONUP()
  59. //}}AFX_MSG_MAP
  60. ON_MESSAGE(SWM_SELCHANGE, OnSelChange)
  61. ON_MESSAGE(SWM_UNSELECT, OnUnselect)
  62. END_MESSAGE_MAP()
  63. /////////////////////////////////////////////////////////////////////////////
  64. // CSwitcherWnd message handlers
  65. BOOL CSwitcherWnd::DoCreate(CWnd *parent, int x, int y, int cx, int cy, CString text)
  66. {
  67. m_wndParent = parent;
  68. WNDCLASS myclass;
  69. myclass.style = CS_HREDRAW|CS_VREDRAW|CS_PARENTDC;
  70. myclass.lpfnWndProc = AfxWndProc;
  71. myclass.cbClsExtra = 0;
  72. myclass.cbWndExtra = 0;
  73. myclass.hInstance = AfxGetInstanceHandle();
  74. myclass.hIcon = NULL;
  75. myclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  76. myclass.hbrBackground = NULL;
  77. myclass.lpszMenuName = NULL;
  78. myclass.lpszClassName = "SwitcherWndClass";
  79. AfxRegisterClass(&myclass);
  80. return Create("SwitcherWndClass", text, WS_CHILD|WS_VISIBLE, CRect(x,y,cx+x,cy+y), parent, 0);
  81. }
  82. BOOL CSwitcherWnd::AddButton(CString title, HICON icon)
  83. {
  84. CRect rect;
  85. GetClientRect(&rect);
  86. CSwitcherButton* newbutton = new CSwitcherButton();
  87. newbutton->m_iIcon = icon;
  88. newbutton->m_iID = m_Buttons.GetSize();
  89. if (!newbutton->DoCreate(this, m_iNextButtonStart, rect.top, m_iButtonWidth, DEFAULTHEIGHT, title))
  90. return FALSE;
  91. m_Buttons.Add((void*)newbutton);
  92. m_iNextButtonStart += m_iButtonWidth + 3;
  93. if (m_iNextButtonStart-3 > rect.Width())
  94. {
  95. // this loop makes a neat little animation
  96. int newsize = (rect.Width() / (m_Buttons.GetSize())) - 3;
  97. register int y;
  98. for (y = m_iButtonWidth; y >= newsize; y-=3)
  99. {
  100. ResizeButtons(y);
  101. Sleep(15);
  102. }
  103. if (y != newsize) ResizeButtons(newsize);
  104. if (m_iButtonWidth < MINWIDTH)
  105. {
  106. // the smallest allowable button size has been reached...
  107. // in this version, we can't handle this
  108. ASSERT(0);
  109. return FALSE;
  110. }
  111. }
  112. return TRUE;
  113. }
  114. void CSwitcherWnd::OnDestroy() 
  115. {
  116. RemoveAll();
  117. CWnd::OnDestroy();
  118. }
  119. void CSwitcherWnd::RemoveAll()
  120. {
  121. // remove the first button over and over
  122. int size = m_Buttons.GetSize();
  123. for (int x = 1; x <= size; x++)
  124. {
  125. CSwitcherButton* btn = (CSwitcherButton*)m_Buttons.GetAt(0);
  126. delete btn;
  127. m_Buttons.RemoveAt(0);
  128. }
  129. m_iNextButtonStart = 0;
  130. m_iButtonWidth = DEFAULTWIDTH;
  131. m_iSelectedButton = -1;
  132. }
  133. void CSwitcherWnd::ResizeButtons(int NewSize)
  134. {
  135. if (NewSize < MINWIDTH || NewSize > DEFAULTWIDTH)
  136. return;
  137. m_iButtonWidth = NewSize;
  138. m_iNextButtonStart = 0;
  139. for (register int x = 0; x < m_Buttons.GetSize(); x++)
  140. {
  141. CSwitcherButton* btn = (CSwitcherButton*)m_Buttons.GetAt(x);
  142. btn->SetWindowPos(NULL, m_iNextButtonStart, 0, m_iButtonWidth, DEFAULTHEIGHT, SWP_NOZORDER|SWP_NOCOPYBITS);
  143. m_iNextButtonStart += m_iButtonWidth + 3;
  144. }
  145. RedrawWindow();
  146. }
  147. void CSwitcherWnd::OnPaint() 
  148. {
  149. CPaintDC dc(this); // device context for painting
  150. // simply paint it the window bg color
  151. CRect rect;
  152. GetClientRect(&rect);
  153. CBrush brush;
  154. brush.CreateSolidBrush(::GetSysColor(COLOR_3DFACE));
  155. dc.FillRect(&rect, &brush);
  156. brush.DeleteObject();
  157. }
  158. void CSwitcherWnd::OnSize(UINT nType, int cx, int cy) 
  159. {
  160. CWnd::OnSize(nType, cx, cy);
  161. if (m_Buttons.GetSize() == 0)
  162. return;
  163. CRect rect;
  164. GetClientRect(&rect);
  165. int newsize = (rect.Width() / (m_Buttons.GetSize())) - 3;
  166. if (newsize <= DEFAULTWIDTH && m_iButtonWidth != newsize)
  167. ResizeButtons(newsize);
  168. }
  169. CSwitcherButton* CSwitcherWnd::GetButtonFromID(int id)
  170. {
  171. return (CSwitcherButton*)m_Buttons.GetAt(id);
  172. }
  173. LRESULT CSwitcherWnd::OnSelChange(WPARAM wp, LPARAM)
  174. {
  175. // sent when a button gets clicked
  176. CSwitcherButton* newsel = (CSwitcherButton*)wp;
  177. if (m_iSelectedButton > -1)
  178. GetButtonFromID(m_iSelectedButton)->Unselect();
  179. m_iSelectedButton = newsel->m_iID;
  180. return 1;
  181. }
  182. void CSwitcherWnd::OnLButtonUp(UINT nFlags, CPoint point) 
  183. {
  184. CWnd::OnLButtonUp(nFlags, point);
  185. if (m_iSelectedButton > -1)
  186. GetButtonFromID(m_iSelectedButton)->Unselect();
  187. m_iSelectedButton = -1;
  188. }
  189. LRESULT CSwitcherWnd::OnUnselect(WPARAM, LPARAM)
  190. {
  191. // sent when a button gets clicked when its selected
  192. // (which unselects it)
  193. m_iSelectedButton = -1;
  194. return 1;
  195. }
  196. BOOL CSwitcherWnd::RemoveButton(int index)
  197. {
  198. if (index >= m_Buttons.GetSize() || index < 0)
  199. {
  200. ASSERT(0); // out of range
  201. return FALSE;
  202. }
  203. if (m_iSelectedButton == index)
  204. m_iSelectedButton = -1;
  205. if (m_iSelectedButton > index)
  206. m_iSelectedButton -= 1;
  207. delete GetButtonFromID(index);
  208. m_Buttons.RemoveAt(index);
  209. for (register int x = index; x < m_Buttons.GetSize(); x++)
  210. GetButtonFromID(x)->m_iID -= 1;
  211. m_iNextButtonStart -= m_iButtonWidth + 3;
  212. if (m_iButtonWidth != DEFAULTWIDTH)
  213. {
  214. // do that funky animation thing
  215. CRect rect;
  216. GetClientRect(&rect);
  217. int newsize = (rect.Width() / (m_Buttons.GetSize())) - 3;
  218. if (newsize > DEFAULTWIDTH) newsize = DEFAULTWIDTH;
  219. if (newsize > m_iButtonWidth)
  220. {
  221. register int y;
  222. for (y = m_iButtonWidth; y <= newsize; y+=3)
  223. {
  224. ResizeButtons(y);
  225. Sleep(15);
  226. }
  227. if (y != newsize) ResizeButtons(newsize);
  228. }
  229. }
  230. ResizeButtons(m_iButtonWidth);
  231. return TRUE;
  232. }
  233. // icon can be NULL to not search the icons, just text
  234. int CSwitcherWnd::FindButton(CString text, HICON icon, int StartAt)
  235. {
  236. if (StartAt < 0 || StartAt >= m_Buttons.GetSize())
  237. {
  238. ASSERT(0); // out of range
  239. return -1;
  240. }
  241. for (register int x = StartAt; x < m_Buttons.GetSize(); x++)
  242. {
  243. CSwitcherButton* btn = GetButtonFromID(x);
  244. CString title;
  245. btn->GetWindowText(title);
  246. if (icon == NULL)
  247. {
  248. if (title == text)
  249. return x;
  250. }
  251. else
  252. {
  253. if (title == text && icon == btn->m_iIcon)
  254. return x;
  255. }
  256. }
  257. return -1;
  258. }
  259. int CSwitcherWnd::GetSel()
  260. {
  261. return m_iSelectedButton;
  262. }
  263. BOOL CSwitcherWnd::SetSel(int num)
  264. {
  265. if (num < 0 || num >= m_Buttons.GetSize())
  266. {
  267. ASSERT(0); // out of range
  268. return FALSE;
  269. }
  270. if (m_iSelectedButton > -1)
  271. GetButtonFromID(m_iSelectedButton)->Unselect();
  272. GetButtonFromID(num)->Select();
  273. m_iSelectedButton = num;
  274. return TRUE;
  275. }
  276. CString CSwitcherWnd::GetButtonText(int id)
  277. {
  278. if (id < 0 || id >= m_Buttons.GetSize())
  279. {
  280. ASSERT(0); // out of range
  281. return "";
  282. }
  283. CString retval = "";
  284. GetButtonFromID(id)->GetWindowText(retval);
  285. return retval;
  286. }
  287. HICON CSwitcherWnd::GetButtonIcon(int id)
  288. {
  289. if (id < 0 || id >= m_Buttons.GetSize())
  290. {
  291. ASSERT(0); // out of range
  292. return NULL;
  293. }
  294. return GetButtonFromID(id)->m_iIcon;
  295. }
  296. // note that this is 1 greater than the last button ID
  297. int CSwitcherWnd::GetNumButtons()
  298. {
  299. return m_Buttons.GetSize();
  300. }
  301. BOOL CSwitcherWnd::ModifyButton(int index, CString text, HICON icon)
  302. {
  303. if (index < 0 || index >= m_Buttons.GetSize())
  304. {
  305. ASSERT(0); // out of range
  306. return NULL;
  307. }
  308. CSwitcherButton* btn = GetButtonFromID(index);
  309. btn->SetWindowText(text);
  310. btn->m_iIcon = icon;
  311. btn->Refresh();
  312. return TRUE;
  313. }