GdipButton.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688
  1. //
  2. // GdipButton.cpp : Version 1.0 - see article at CodeProject.com
  3. //
  4. // Author: Darren Sessions
  5. //
  6. //
  7. // Description:
  8. // GdipButton is a CButton derived control that uses GDI+
  9. // to support alternate image formats
  10. //
  11. // History
  12. // Version 1.0 - 2008 June 10
  13. // - Initial public release
  14. //
  15. // License:
  16. // This software is released under the Code Project Open License (CPOL),
  17. // which may be found here: http://www.codeproject.com/info/eula.aspx
  18. // You are free to use this software in any way you like, except that you
  19. // may not sell this source code.
  20. //
  21. // This software is provided "as is" with no expressed or implied warranty.
  22. // I accept no liability for any damage or loss of business that this
  23. // software may cause.
  24. //
  25. ///////////////////////////////////////////////////////////////////////////////
  26. #include "stdafx.h"
  27. #include "GdipButton.h"
  28. #include "CGdiPlusBitmap.h"
  29. #include "MemDC.h"
  30. #include "CP_Main.h"
  31. #ifdef _DEBUG
  32. #define new DEBUG_NEW
  33. #undef THIS_FILE
  34. static char THIS_FILE[] = __FILE__;
  35. #endif
  36. /////////////////////////////////////////////////////////////////////////////
  37. // CGdipButton
  38. CGdipButton::CGdipButton()
  39. {
  40. m_pStdImage = NULL;
  41. m_pAltImage = NULL;
  42. m_bHaveBitmaps = FALSE;
  43. m_bHaveAltImage = FALSE;
  44. m_pCurBtn = NULL;
  45. m_bIsDisabled = FALSE;
  46. m_bIsToggle = FALSE;
  47. m_bIsHovering = FALSE;
  48. m_bIsTracking = FALSE;
  49. m_nCurType = STD_TYPE;
  50. m_pToolTip = NULL;
  51. }
  52. CGdipButton::~CGdipButton()
  53. {
  54. if(m_pStdImage) delete m_pStdImage;
  55. if(m_pAltImage) delete m_pAltImage;
  56. if(m_pToolTip) delete m_pToolTip;
  57. }
  58. BEGIN_MESSAGE_MAP(CGdipButton, CButton)
  59. //{{AFX_MSG_MAP(CGdipButton)
  60. ON_WM_DRAWITEM()
  61. ON_WM_ERASEBKGND()
  62. ON_WM_CTLCOLOR_REFLECT()
  63. ON_WM_MOUSEMOVE()
  64. ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
  65. ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover)
  66. //}}AFX_MSG_MAP
  67. END_MESSAGE_MAP()
  68. BOOL CGdipButton::LoadStdImageDPI(UINT id96, UINT id120, UINT id144, UINT id168, UINT id192, LPCTSTR pType)
  69. {
  70. BOOL ret = FALSE;
  71. if (theApp.m_metrics.GetDPIX() >= 192)
  72. {
  73. ret = LoadStdImage(id192, pType);
  74. }
  75. else if (theApp.m_metrics.GetDPIX() >= 168)
  76. {
  77. ret = LoadStdImage(id168, pType);
  78. }
  79. else if (theApp.m_metrics.GetDPIX() >= 144)
  80. {
  81. ret = LoadStdImage(id144, pType);
  82. }
  83. else if (theApp.m_metrics.GetDPIX() >= 120)
  84. {
  85. ret = LoadStdImage(id120, pType);
  86. }
  87. else
  88. {
  89. ret = LoadStdImage(id96, pType);
  90. }
  91. return ret;
  92. }
  93. //=============================================================================
  94. //
  95. // LoadStdImage()
  96. //
  97. // Purpose: The LoadStdImage() Loads the image for the button. This
  98. // function must be called at a minimum or the button wont do
  99. // anything.
  100. //
  101. // Parameters:
  102. // [IN] id
  103. // resource id, one of the resources already imported with the
  104. // resource editor, usually begins with IDR_
  105. //
  106. // [IN] pType
  107. // pointer to string describing the resource type
  108. //
  109. // Returns: BOOL
  110. // Non zero if successful, otherwise zero
  111. //
  112. //=============================================================================
  113. BOOL CGdipButton::LoadStdImage(UINT id, LPCTSTR pType)
  114. {
  115. m_pStdImage = new CGdiPlusBitmapResource;
  116. return m_pStdImage->Load(id, pType);
  117. }
  118. void CGdipButton::Reset()
  119. {
  120. /*if(m_pStdImage) delete m_pStdImage;
  121. if (m_pAltImage) delete m_pAltImage;
  122. if (m_pToolTip) delete m_pToolTip;*/
  123. m_bHaveBitmaps = FALSE;
  124. m_bHaveAltImage = FALSE;
  125. m_dcStd.DeleteDC();
  126. m_dcStdP.DeleteDC();
  127. m_dcStdH.DeleteDC();
  128. m_dcBk.DeleteDC();
  129. }
  130. void CGdipButton::Test(CString c)
  131. {
  132. m_pStdImage = new CGdiPlusBitmapResource;
  133. m_pStdImage->Loads(c);
  134. }
  135. //=============================================================================
  136. //
  137. // LoadAltImage()
  138. //
  139. // Purpose: The LoadAltImage() Loads the altername image for the button.
  140. // This function call is optional
  141. // Parameters:
  142. // [IN] id
  143. // resource id, one of the resources already imported with the
  144. // resource editor, usually begins with IDR_
  145. //
  146. // [IN] pType
  147. // pointer to string describing the resource type
  148. //
  149. // Returns: BOOL
  150. // Non zero if successful, otherwise zero
  151. //
  152. //=============================================================================
  153. BOOL CGdipButton::LoadAltImage(UINT id, LPCTSTR pType)
  154. {
  155. m_bHaveAltImage = TRUE;
  156. m_pAltImage = new CGdiPlusBitmapResource;
  157. return (m_pAltImage->Load(id, pType));
  158. }
  159. //=============================================================================
  160. //
  161. // The framework calls this member function when a child control is about to
  162. // be drawn. All the bitmaps are created here on the first call. Every thing
  163. // is done with a memory DC except the background, which get's it's information
  164. // from the parent. The background is needed for transparent portions of PNG
  165. // images. An always on top app (such as Task Manager) that is in the way can
  166. // cause it to get an incorrect background. To avoid this, the parent should
  167. // call the SetBkGnd function with a memory DC when it creates the background.
  168. //
  169. //=============================================================================
  170. HBRUSH CGdipButton::CtlColor(CDC* pScreenDC, UINT nCtlColor)
  171. {
  172. if(!m_bHaveBitmaps)
  173. {
  174. if(!m_pStdImage)
  175. {
  176. return NULL; // Load the standard image with LoadStdImage()
  177. }
  178. CBitmap bmp, *pOldBitmap;
  179. CRect rect;
  180. GetClientRect(rect);
  181. // do everything with mem dc
  182. CMemDCEx pDC(pScreenDC, rect);
  183. Gdiplus::Graphics graphics(pDC->m_hDC);
  184. // background
  185. if (m_dcBk.m_hDC == NULL)
  186. {
  187. CRect rect1;
  188. CClientDC clDC(GetParent());
  189. GetWindowRect(rect1);
  190. GetParent()->ScreenToClient(rect1);
  191. m_dcBk.CreateCompatibleDC(&clDC);
  192. bmp.CreateCompatibleBitmap(&clDC, rect.Width(), rect.Height());
  193. pOldBitmap = m_dcBk.SelectObject(&bmp);
  194. m_dcBk.BitBlt(0, 0, rect.Width(), rect.Height(), &clDC, rect1.left, rect1.top, SRCCOPY);
  195. bmp.DeleteObject();
  196. }
  197. // standard image
  198. if (m_dcStd.m_hDC == NULL)
  199. {
  200. PaintBk(pDC);
  201. /*graphics.DrawImage(*m_pStdImage, 0, 0);
  202. m_dcStd.CreateCompatibleDC(pDC);
  203. bmp.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());
  204. pOldBitmap = m_dcStd.SelectObject(&bmp);
  205. m_dcStd.BitBlt(0, 0, rect.Width(), rect.Height(), pDC, 0, 0, SRCCOPY);
  206. bmp.DeleteObject();*/
  207. float width = (float)m_pStdImage->m_pBitmap->GetWidth();
  208. float height = (float)m_pStdImage->m_pBitmap->GetHeight();
  209. RectF grect; grect.X = 0, grect.Y = 0; grect.Width = width; grect.Height = height;
  210. graphics.DrawImage(*m_pStdImage, grect, 0, 0, width, height, UnitPixel);
  211. m_dcStd.CreateCompatibleDC(pDC);
  212. bmp.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());
  213. pOldBitmap = m_dcStd.SelectObject(&bmp);
  214. m_dcStd.BitBlt(0, 0, rect.Width(), rect.Height(), pDC, 0, 0, SRCCOPY);
  215. bmp.DeleteObject();
  216. // standard image pressed
  217. if (m_dcStdP.m_hDC == NULL)
  218. {
  219. PaintBk(pDC);
  220. //graphics.DrawImage(*m_pStdImage, 1, 1);
  221. //m_dcStdP.CreateCompatibleDC(pDC);
  222. //bmp.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());
  223. //pOldBitmap = m_dcStdP.SelectObject(&bmp);
  224. //m_dcStdP.BitBlt(0, 0, rect.Width(), rect.Height(), pDC, 0, 0, SRCCOPY);
  225. //bmp.DeleteObject();
  226. float width = (float)m_pStdImage->m_pBitmap->GetWidth();
  227. float height = (float)m_pStdImage->m_pBitmap->GetHeight();
  228. RectF grect; grect.X = 0, grect.Y = 0; grect.Width = width; grect.Height = height;
  229. graphics.DrawImage(*m_pStdImage, grect, -1, -1, width, height, UnitPixel);
  230. m_dcStdP.CreateCompatibleDC(pDC);
  231. bmp.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());
  232. pOldBitmap = m_dcStdP.SelectObject(&bmp);
  233. m_dcStdP.BitBlt(0, 0, rect.Width(), rect.Height(), pDC, 0, 0, SRCCOPY);
  234. bmp.DeleteObject();
  235. }
  236. // standard image hot
  237. if(m_dcStdH.m_hDC == NULL)
  238. {
  239. PaintBk(pDC);
  240. ColorMatrix HotMat = { 1.05f, 0.00f, 0.00f, 0.00f, 0.00f,
  241. 0.00f, 1.05f, 0.00f, 0.00f, 0.00f,
  242. 0.00f, 0.00f, 1.05f, 0.00f, 0.00f,
  243. 0.00f, 0.00f, 0.00f, 1.00f, 0.00f,
  244. 0.05f, 0.05f, 0.05f, 0.00f, 1.00f };
  245. ImageAttributes ia;
  246. ia.SetColorMatrix(&HotMat);
  247. float width = (float)m_pStdImage->m_pBitmap->GetWidth();
  248. float height = (float)m_pStdImage->m_pBitmap->GetHeight();
  249. RectF grect; grect.X=0, grect.Y=0; grect.Width = width; grect.Height = height;
  250. graphics.DrawImage(*m_pStdImage, grect, 0, 0, width, height, UnitPixel, &ia);
  251. m_dcStdH.CreateCompatibleDC(pDC);
  252. bmp.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());
  253. pOldBitmap = m_dcStdH.SelectObject(&bmp);
  254. m_dcStdH.BitBlt(0, 0, rect.Width(), rect.Height(), pDC, 0, 0, SRCCOPY);
  255. bmp.DeleteObject();
  256. }
  257. // grayscale image
  258. if(m_dcGS.m_hDC == NULL)
  259. {
  260. PaintBk(pDC);
  261. ColorMatrix GrayMat = { 0.30f, 0.30f, 0.30f, 0.00f, 0.00f,
  262. 0.59f, 0.59f, 0.59f, 0.00f, 0.00f,
  263. 0.11f, 0.11f, 0.11f, 0.00f, 0.00f,
  264. 0.00f, 0.00f, 0.00f, 1.00f, 0.00f,
  265. 0.00f, 0.00f, 0.00f, 0.00f, 1.00f };
  266. ImageAttributes ia;
  267. ia.SetColorMatrix(&GrayMat);
  268. float width = (float)m_pStdImage->m_pBitmap->GetWidth();
  269. float height = (float)m_pStdImage->m_pBitmap->GetHeight();
  270. RectF grect; grect.X=0, grect.Y=0; grect.Width = width; grect.Height = height;
  271. graphics.DrawImage(*m_pStdImage, grect, 0, 0, width, height, UnitPixel, &ia);
  272. m_dcGS.CreateCompatibleDC(pDC);
  273. bmp.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());
  274. pOldBitmap = m_dcGS.SelectObject(&bmp);
  275. m_dcGS.BitBlt(0, 0, rect.Width(), rect.Height(), pDC, 0, 0, SRCCOPY);
  276. bmp.DeleteObject();
  277. }
  278. }
  279. // alternate image
  280. if( (m_dcAlt.m_hDC == NULL) && m_bHaveAltImage )
  281. {
  282. PaintBk(pDC);
  283. graphics.DrawImage(*m_pAltImage, 0, 0);
  284. m_dcAlt.CreateCompatibleDC(pDC);
  285. bmp.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());
  286. pOldBitmap = m_dcAlt.SelectObject(&bmp);
  287. m_dcAlt.BitBlt(0, 0, rect.Width(), rect.Height(), pDC, 0, 0, SRCCOPY);
  288. bmp.DeleteObject();
  289. // alternate image pressed
  290. if( (m_dcAltP.m_hDC == NULL) && m_bHaveAltImage )
  291. {
  292. PaintBk(pDC);
  293. graphics.DrawImage(*m_pAltImage, 1, 1);
  294. m_dcAltP.CreateCompatibleDC(pDC);
  295. bmp.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());
  296. pOldBitmap = m_dcAltP.SelectObject(&bmp);
  297. m_dcAltP.BitBlt(0, 0, rect.Width(), rect.Height(), pDC, 0, 0, SRCCOPY);
  298. bmp.DeleteObject();
  299. }
  300. // alternate image hot
  301. if(m_dcAltH.m_hDC == NULL)
  302. {
  303. PaintBk(pDC);
  304. ColorMatrix HotMat = { 1.05f, 0.00f, 0.00f, 0.00f, 0.00f,
  305. 0.00f, 1.05f, 0.00f, 0.00f, 0.00f,
  306. 0.00f, 0.00f, 1.05f, 0.00f, 0.00f,
  307. 0.00f, 0.00f, 0.00f, 1.00f, 0.00f,
  308. 0.05f, 0.05f, 0.05f, 0.00f, 1.00f };
  309. ImageAttributes ia;
  310. ia.SetColorMatrix(&HotMat);
  311. float width = (float)m_pStdImage->m_pBitmap->GetWidth();
  312. float height = (float)m_pStdImage->m_pBitmap->GetHeight();
  313. RectF grect; grect.X=0, grect.Y=0; grect.Width = width; grect.Height = height;
  314. graphics.DrawImage(*m_pAltImage, grect, 0, 0, width, height, UnitPixel, &ia);
  315. m_dcAltH.CreateCompatibleDC(pDC);
  316. bmp.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());
  317. pOldBitmap = m_dcAltH.SelectObject(&bmp);
  318. m_dcAltH.BitBlt(0, 0, rect.Width(), rect.Height(), pDC, 0, 0, SRCCOPY);
  319. bmp.DeleteObject();
  320. }
  321. }
  322. if(m_pCurBtn == NULL)
  323. {
  324. m_pCurBtn = &m_dcStd;
  325. }
  326. m_bHaveBitmaps = TRUE;
  327. }
  328. return NULL;
  329. }
  330. //=============================================================================
  331. // paint the background
  332. //=============================================================================
  333. void CGdipButton::PaintBk(CDC *pDC)
  334. {
  335. CRect rect;
  336. GetClientRect(rect);
  337. pDC->BitBlt(0, 0, rect.Width(), rect.Height(), &m_dcBk, 0, 0, SRCCOPY);
  338. }
  339. //=============================================================================
  340. // paint the bitmap currently pointed to with m_pCurBtn
  341. //=============================================================================
  342. void CGdipButton::PaintBtn(CDC *pDC)
  343. {
  344. CRect rect;
  345. GetClientRect(rect);
  346. pDC->BitBlt(0, 0, rect.Width(), rect.Height(), m_pCurBtn, 0, 0, SRCCOPY);
  347. }
  348. //=============================================================================
  349. // enables the toggle mode
  350. // returns if it doesn't have the alternate image
  351. //=============================================================================
  352. void CGdipButton::EnableToggle(BOOL bEnable)
  353. {
  354. if(!m_bHaveAltImage) return;
  355. m_bIsToggle = bEnable;
  356. // this actually makes it start in the std state since toggle is called before paint
  357. if(bEnable) m_pCurBtn = &m_dcAlt;
  358. else m_pCurBtn = &m_dcStd;
  359. }
  360. //=============================================================================
  361. // sets the image type and disabled state then repaints
  362. //=============================================================================
  363. void CGdipButton::SetImage(int type)
  364. {
  365. m_nCurType = type;
  366. (type == DIS_TYPE) ? m_bIsDisabled = TRUE : m_bIsDisabled = FALSE;
  367. Invalidate();
  368. }
  369. //=============================================================================
  370. // set the control to owner draw
  371. //=============================================================================
  372. void CGdipButton::PreSubclassWindow()
  373. {
  374. // Set control to owner draw
  375. ModifyStyle(0, BS_OWNERDRAW, SWP_FRAMECHANGED);
  376. CButton::PreSubclassWindow();
  377. }
  378. //=============================================================================
  379. // disable double click
  380. //=============================================================================
  381. BOOL CGdipButton::PreTranslateMessage(MSG* pMsg)
  382. {
  383. if (pMsg->message == WM_LBUTTONDBLCLK)
  384. pMsg->message = WM_LBUTTONDOWN;
  385. if (m_pToolTip != NULL)
  386. {
  387. if (::IsWindow(m_pToolTip->m_hWnd))
  388. {
  389. m_pToolTip->RelayEvent(pMsg);
  390. }
  391. }
  392. return CButton::PreTranslateMessage(pMsg);
  393. }
  394. //=============================================================================
  395. // overide the erase function
  396. //=============================================================================
  397. BOOL CGdipButton::OnEraseBkgnd(CDC* pDC)
  398. {
  399. return TRUE;
  400. }
  401. //=============================================================================
  402. // Paint the button depending on the state of the mouse
  403. //=============================================================================
  404. void CGdipButton::DrawItem(LPDRAWITEMSTRUCT lpDIS)
  405. {
  406. CDC* pDC = CDC::FromHandle(lpDIS->hDC);
  407. // handle disabled state
  408. if(m_bIsDisabled)
  409. {
  410. m_pCurBtn = &m_dcGS;
  411. PaintBtn(pDC);
  412. return;
  413. }
  414. BOOL bIsPressed = (lpDIS->itemState & ODS_SELECTED);
  415. // handle toggle button
  416. if(m_bIsToggle && bIsPressed)
  417. {
  418. (m_nCurType == STD_TYPE) ? m_nCurType = ALT_TYPE : m_nCurType = STD_TYPE;
  419. }
  420. if(bIsPressed)
  421. {
  422. if(m_nCurType == STD_TYPE)
  423. m_pCurBtn = &m_dcStdP;
  424. else
  425. m_pCurBtn = &m_dcAltP;
  426. }
  427. else if(m_bIsHovering)
  428. {
  429. if(m_nCurType == STD_TYPE)
  430. m_pCurBtn = &m_dcStdH;
  431. else
  432. m_pCurBtn = &m_dcAltH;
  433. }
  434. else
  435. {
  436. if(m_nCurType == STD_TYPE)
  437. m_pCurBtn = &m_dcStd;
  438. else
  439. m_pCurBtn = &m_dcAlt;
  440. }
  441. // paint the button
  442. PaintBtn(pDC);
  443. }
  444. //=============================================================================
  445. LRESULT CGdipButton::OnMouseHover(WPARAM wparam, LPARAM lparam)
  446. //=============================================================================
  447. {
  448. m_bIsHovering = TRUE;
  449. Invalidate();
  450. DeleteToolTip();
  451. // Create a new Tooltip with new Button Size and Location
  452. SetToolTipText(m_tooltext);
  453. if (m_pToolTip != NULL)
  454. {
  455. if (::IsWindow(m_pToolTip->m_hWnd))
  456. {
  457. //Display ToolTip
  458. m_pToolTip->Update();
  459. }
  460. }
  461. return 0;
  462. }
  463. //=============================================================================
  464. LRESULT CGdipButton::OnMouseLeave(WPARAM wparam, LPARAM lparam)
  465. //=============================================================================
  466. {
  467. m_bIsTracking = FALSE;
  468. m_bIsHovering = FALSE;
  469. Invalidate();
  470. return 0;
  471. }
  472. //=============================================================================
  473. void CGdipButton::OnMouseMove(UINT nFlags, CPoint point)
  474. //=============================================================================
  475. {
  476. if (!m_bIsTracking)
  477. {
  478. TRACKMOUSEEVENT tme;
  479. tme.cbSize = sizeof(tme);
  480. tme.hwndTrack = m_hWnd;
  481. tme.dwFlags = TME_LEAVE|TME_HOVER;
  482. tme.dwHoverTime = 1;
  483. m_bIsTracking = _TrackMouseEvent(&tme);
  484. }
  485. CButton::OnMouseMove(nFlags, point);
  486. }
  487. //=============================================================================
  488. //
  489. // Call this member function with a memory DC from the code that paints
  490. // the parents background. Passing the screen DC defeats the purpose of
  491. // using this function.
  492. //
  493. //=============================================================================
  494. void CGdipButton::SetBkGnd(CDC* pDC)
  495. {
  496. CRect rect, rectS;
  497. CBitmap bmp, *pOldBitmap;
  498. GetClientRect(rect);
  499. GetWindowRect(rectS);
  500. GetParent()->ScreenToClient(rectS);
  501. m_dcBk.DeleteDC();
  502. m_dcBk.CreateCompatibleDC(pDC);
  503. bmp.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());
  504. pOldBitmap = m_dcBk.SelectObject(&bmp);
  505. m_dcBk.BitBlt(0, 0, rect.Width(), rect.Height(), pDC, rectS.left, rectS.top, SRCCOPY);
  506. bmp.DeleteObject();
  507. }
  508. //=============================================================================
  509. // Set the tooltip with a string resource
  510. //=============================================================================
  511. void CGdipButton::SetToolTipText(UINT nId, BOOL bActivate)
  512. {
  513. // load string resource
  514. m_tooltext.LoadString(nId);
  515. // If string resource is not empty
  516. if (m_tooltext.IsEmpty() == FALSE)
  517. {
  518. SetToolTipText(m_tooltext, bActivate);
  519. }
  520. }
  521. //=============================================================================
  522. // Set the tooltip with a CString
  523. //=============================================================================
  524. void CGdipButton::SetToolTipText(CString spText, BOOL bActivate)
  525. {
  526. // We cannot accept NULL pointer
  527. if (spText.IsEmpty()) return;
  528. // Initialize ToolTip
  529. InitToolTip();
  530. m_tooltext = spText;
  531. // If there is no tooltip defined then add it
  532. if (m_pToolTip->GetToolCount() == 0)
  533. {
  534. CRect rectBtn;
  535. GetClientRect(rectBtn);
  536. m_pToolTip->AddTool(this, m_tooltext, rectBtn, 1);
  537. }
  538. // Set text for tooltip
  539. m_pToolTip->UpdateTipText(m_tooltext, this, 1);
  540. m_pToolTip->SetDelayTime(2000);
  541. m_pToolTip->Activate(bActivate);
  542. }
  543. //=============================================================================
  544. void CGdipButton::InitToolTip()
  545. //=============================================================================
  546. {
  547. if (m_pToolTip == NULL)
  548. {
  549. m_pToolTip = new CToolTipCtrl;
  550. // Create ToolTip control
  551. m_pToolTip->Create(this);
  552. m_pToolTip->Activate(TRUE);
  553. }
  554. }
  555. //=============================================================================
  556. void CGdipButton::DeleteToolTip()
  557. //=============================================================================
  558. {
  559. // Destroy Tooltip incase the size of the button has changed.
  560. if (m_pToolTip != NULL)
  561. {
  562. delete m_pToolTip;
  563. m_pToolTip = NULL;
  564. }
  565. }