GdipButton.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692
  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(int dpiX, UINT id96, UINT id120, UINT id144, UINT id168, UINT id192, LPCTSTR pType)
  69. {
  70. BOOL ret = FALSE;
  71. if (dpiX >= 192)
  72. {
  73. ret = LoadStdImage(id192, pType);
  74. }
  75. else if (dpiX >= 168)
  76. {
  77. ret = LoadStdImage(id168, pType);
  78. }
  79. else if (dpiX >= 144)
  80. {
  81. ret = LoadStdImage(id144, pType);
  82. }
  83. else if (dpiX >= 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. delete m_pStdImage;
  121. m_pStdImage = NULL;
  122. delete m_pAltImage;
  123. m_pAltImage = NULL;
  124. delete m_pToolTip;
  125. m_pToolTip = NULL;
  126. m_bHaveBitmaps = FALSE;
  127. m_bHaveAltImage = FALSE;
  128. m_dcStd.DeleteDC();
  129. m_dcStdP.DeleteDC();
  130. m_dcStdH.DeleteDC();
  131. m_dcBk.DeleteDC();
  132. }
  133. void CGdipButton::Test(CString c)
  134. {
  135. m_pStdImage = new CGdiPlusBitmapResource;
  136. m_pStdImage->Loads(c);
  137. }
  138. //=============================================================================
  139. //
  140. // LoadAltImage()
  141. //
  142. // Purpose: The LoadAltImage() Loads the altername image for the button.
  143. // This function call is optional
  144. // Parameters:
  145. // [IN] id
  146. // resource id, one of the resources already imported with the
  147. // resource editor, usually begins with IDR_
  148. //
  149. // [IN] pType
  150. // pointer to string describing the resource type
  151. //
  152. // Returns: BOOL
  153. // Non zero if successful, otherwise zero
  154. //
  155. //=============================================================================
  156. BOOL CGdipButton::LoadAltImage(UINT id, LPCTSTR pType)
  157. {
  158. m_bHaveAltImage = TRUE;
  159. m_pAltImage = new CGdiPlusBitmapResource;
  160. return (m_pAltImage->Load(id, pType));
  161. }
  162. //=============================================================================
  163. //
  164. // The framework calls this member function when a child control is about to
  165. // be drawn. All the bitmaps are created here on the first call. Every thing
  166. // is done with a memory DC except the background, which get's it's information
  167. // from the parent. The background is needed for transparent portions of PNG
  168. // images. An always on top app (such as Task Manager) that is in the way can
  169. // cause it to get an incorrect background. To avoid this, the parent should
  170. // call the SetBkGnd function with a memory DC when it creates the background.
  171. //
  172. //=============================================================================
  173. HBRUSH CGdipButton::CtlColor(CDC* pScreenDC, UINT nCtlColor)
  174. {
  175. if(!m_bHaveBitmaps)
  176. {
  177. if(!m_pStdImage)
  178. {
  179. return NULL; // Load the standard image with LoadStdImage()
  180. }
  181. CBitmap bmp, *pOldBitmap;
  182. CRect rect;
  183. GetClientRect(rect);
  184. // do everything with mem dc
  185. CMemDCEx pDC(pScreenDC, rect);
  186. Gdiplus::Graphics graphics(pDC->m_hDC);
  187. // background
  188. if (m_dcBk.m_hDC == NULL)
  189. {
  190. CRect rect1;
  191. CClientDC clDC(GetParent());
  192. GetWindowRect(rect1);
  193. GetParent()->ScreenToClient(rect1);
  194. m_dcBk.CreateCompatibleDC(&clDC);
  195. bmp.CreateCompatibleBitmap(&clDC, rect.Width(), rect.Height());
  196. pOldBitmap = m_dcBk.SelectObject(&bmp);
  197. m_dcBk.BitBlt(0, 0, rect.Width(), rect.Height(), &clDC, rect1.left, rect1.top, SRCCOPY);
  198. bmp.DeleteObject();
  199. }
  200. // standard image
  201. if (m_dcStd.m_hDC == NULL)
  202. {
  203. PaintBk(pDC);
  204. /*graphics.DrawImage(*m_pStdImage, 0, 0);
  205. m_dcStd.CreateCompatibleDC(pDC);
  206. bmp.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());
  207. pOldBitmap = m_dcStd.SelectObject(&bmp);
  208. m_dcStd.BitBlt(0, 0, rect.Width(), rect.Height(), pDC, 0, 0, SRCCOPY);
  209. bmp.DeleteObject();*/
  210. float width = (float)m_pStdImage->m_pBitmap->GetWidth();
  211. float height = (float)m_pStdImage->m_pBitmap->GetHeight();
  212. RectF grect; grect.X = 0, grect.Y = 0; grect.Width = width; grect.Height = height;
  213. graphics.DrawImage(*m_pStdImage, grect, 0, 0, width, height, UnitPixel);
  214. m_dcStd.CreateCompatibleDC(pDC);
  215. bmp.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());
  216. pOldBitmap = m_dcStd.SelectObject(&bmp);
  217. m_dcStd.BitBlt(0, 0, rect.Width(), rect.Height(), pDC, 0, 0, SRCCOPY);
  218. bmp.DeleteObject();
  219. // standard image pressed
  220. if (m_dcStdP.m_hDC == NULL)
  221. {
  222. PaintBk(pDC);
  223. //graphics.DrawImage(*m_pStdImage, 1, 1);
  224. //m_dcStdP.CreateCompatibleDC(pDC);
  225. //bmp.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());
  226. //pOldBitmap = m_dcStdP.SelectObject(&bmp);
  227. //m_dcStdP.BitBlt(0, 0, rect.Width(), rect.Height(), pDC, 0, 0, SRCCOPY);
  228. //bmp.DeleteObject();
  229. float width = (float)m_pStdImage->m_pBitmap->GetWidth();
  230. float height = (float)m_pStdImage->m_pBitmap->GetHeight();
  231. RectF grect; grect.X = 0, grect.Y = 0; grect.Width = width; grect.Height = height;
  232. graphics.DrawImage(*m_pStdImage, grect, -1, -1, width, height, UnitPixel);
  233. m_dcStdP.CreateCompatibleDC(pDC);
  234. bmp.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());
  235. pOldBitmap = m_dcStdP.SelectObject(&bmp);
  236. m_dcStdP.BitBlt(0, 0, rect.Width(), rect.Height(), pDC, 0, 0, SRCCOPY);
  237. bmp.DeleteObject();
  238. }
  239. // standard image hot
  240. if(m_dcStdH.m_hDC == NULL)
  241. {
  242. PaintBk(pDC);
  243. ColorMatrix HotMat = { 1.05f, 0.00f, 0.00f, 0.00f, 0.00f,
  244. 0.00f, 1.05f, 0.00f, 0.00f, 0.00f,
  245. 0.00f, 0.00f, 1.05f, 0.00f, 0.00f,
  246. 0.00f, 0.00f, 0.00f, 1.00f, 0.00f,
  247. 0.05f, 0.05f, 0.05f, 0.00f, 1.00f };
  248. ImageAttributes ia;
  249. ia.SetColorMatrix(&HotMat);
  250. float width = (float)m_pStdImage->m_pBitmap->GetWidth();
  251. float height = (float)m_pStdImage->m_pBitmap->GetHeight();
  252. RectF grect; grect.X=0, grect.Y=0; grect.Width = width; grect.Height = height;
  253. graphics.DrawImage(*m_pStdImage, grect, 0, 0, width, height, UnitPixel, &ia);
  254. m_dcStdH.CreateCompatibleDC(pDC);
  255. bmp.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());
  256. pOldBitmap = m_dcStdH.SelectObject(&bmp);
  257. m_dcStdH.BitBlt(0, 0, rect.Width(), rect.Height(), pDC, 0, 0, SRCCOPY);
  258. bmp.DeleteObject();
  259. }
  260. // grayscale image
  261. if(m_dcGS.m_hDC == NULL)
  262. {
  263. PaintBk(pDC);
  264. ColorMatrix GrayMat = { 0.30f, 0.30f, 0.30f, 0.00f, 0.00f,
  265. 0.59f, 0.59f, 0.59f, 0.00f, 0.00f,
  266. 0.11f, 0.11f, 0.11f, 0.00f, 0.00f,
  267. 0.00f, 0.00f, 0.00f, 1.00f, 0.00f,
  268. 0.00f, 0.00f, 0.00f, 0.00f, 1.00f };
  269. ImageAttributes ia;
  270. ia.SetColorMatrix(&GrayMat);
  271. float width = (float)m_pStdImage->m_pBitmap->GetWidth();
  272. float height = (float)m_pStdImage->m_pBitmap->GetHeight();
  273. RectF grect; grect.X=0, grect.Y=0; grect.Width = width; grect.Height = height;
  274. graphics.DrawImage(*m_pStdImage, grect, 0, 0, width, height, UnitPixel, &ia);
  275. m_dcGS.CreateCompatibleDC(pDC);
  276. bmp.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());
  277. pOldBitmap = m_dcGS.SelectObject(&bmp);
  278. m_dcGS.BitBlt(0, 0, rect.Width(), rect.Height(), pDC, 0, 0, SRCCOPY);
  279. bmp.DeleteObject();
  280. }
  281. }
  282. // alternate image
  283. if( (m_dcAlt.m_hDC == NULL) && m_bHaveAltImage )
  284. {
  285. PaintBk(pDC);
  286. graphics.DrawImage(*m_pAltImage, 0, 0);
  287. m_dcAlt.CreateCompatibleDC(pDC);
  288. bmp.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());
  289. pOldBitmap = m_dcAlt.SelectObject(&bmp);
  290. m_dcAlt.BitBlt(0, 0, rect.Width(), rect.Height(), pDC, 0, 0, SRCCOPY);
  291. bmp.DeleteObject();
  292. // alternate image pressed
  293. if( (m_dcAltP.m_hDC == NULL) && m_bHaveAltImage )
  294. {
  295. PaintBk(pDC);
  296. graphics.DrawImage(*m_pAltImage, 1, 1);
  297. m_dcAltP.CreateCompatibleDC(pDC);
  298. bmp.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());
  299. pOldBitmap = m_dcAltP.SelectObject(&bmp);
  300. m_dcAltP.BitBlt(0, 0, rect.Width(), rect.Height(), pDC, 0, 0, SRCCOPY);
  301. bmp.DeleteObject();
  302. }
  303. // alternate image hot
  304. if(m_dcAltH.m_hDC == NULL)
  305. {
  306. PaintBk(pDC);
  307. ColorMatrix HotMat = { 1.05f, 0.00f, 0.00f, 0.00f, 0.00f,
  308. 0.00f, 1.05f, 0.00f, 0.00f, 0.00f,
  309. 0.00f, 0.00f, 1.05f, 0.00f, 0.00f,
  310. 0.00f, 0.00f, 0.00f, 1.00f, 0.00f,
  311. 0.05f, 0.05f, 0.05f, 0.00f, 1.00f };
  312. ImageAttributes ia;
  313. ia.SetColorMatrix(&HotMat);
  314. float width = (float)m_pStdImage->m_pBitmap->GetWidth();
  315. float height = (float)m_pStdImage->m_pBitmap->GetHeight();
  316. RectF grect; grect.X=0, grect.Y=0; grect.Width = width; grect.Height = height;
  317. graphics.DrawImage(*m_pAltImage, grect, 0, 0, width, height, UnitPixel, &ia);
  318. m_dcAltH.CreateCompatibleDC(pDC);
  319. bmp.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());
  320. pOldBitmap = m_dcAltH.SelectObject(&bmp);
  321. m_dcAltH.BitBlt(0, 0, rect.Width(), rect.Height(), pDC, 0, 0, SRCCOPY);
  322. bmp.DeleteObject();
  323. }
  324. }
  325. if(m_pCurBtn == NULL)
  326. {
  327. m_pCurBtn = &m_dcStd;
  328. }
  329. m_bHaveBitmaps = TRUE;
  330. }
  331. return NULL;
  332. }
  333. //=============================================================================
  334. // paint the background
  335. //=============================================================================
  336. void CGdipButton::PaintBk(CDC *pDC)
  337. {
  338. CRect rect;
  339. GetClientRect(rect);
  340. pDC->BitBlt(0, 0, rect.Width(), rect.Height(), &m_dcBk, 0, 0, SRCCOPY);
  341. }
  342. //=============================================================================
  343. // paint the bitmap currently pointed to with m_pCurBtn
  344. //=============================================================================
  345. void CGdipButton::PaintBtn(CDC *pDC)
  346. {
  347. CRect rect;
  348. GetClientRect(rect);
  349. pDC->BitBlt(0, 0, rect.Width(), rect.Height(), m_pCurBtn, 0, 0, SRCCOPY);
  350. }
  351. //=============================================================================
  352. // enables the toggle mode
  353. // returns if it doesn't have the alternate image
  354. //=============================================================================
  355. void CGdipButton::EnableToggle(BOOL bEnable)
  356. {
  357. if(!m_bHaveAltImage) return;
  358. m_bIsToggle = bEnable;
  359. // this actually makes it start in the std state since toggle is called before paint
  360. if(bEnable) m_pCurBtn = &m_dcAlt;
  361. else m_pCurBtn = &m_dcStd;
  362. }
  363. //=============================================================================
  364. // sets the image type and disabled state then repaints
  365. //=============================================================================
  366. void CGdipButton::SetImage(int type)
  367. {
  368. m_nCurType = type;
  369. (type == DIS_TYPE) ? m_bIsDisabled = TRUE : m_bIsDisabled = FALSE;
  370. Invalidate();
  371. }
  372. //=============================================================================
  373. // set the control to owner draw
  374. //=============================================================================
  375. void CGdipButton::PreSubclassWindow()
  376. {
  377. // Set control to owner draw
  378. ModifyStyle(0, BS_OWNERDRAW, SWP_FRAMECHANGED);
  379. CButton::PreSubclassWindow();
  380. }
  381. //=============================================================================
  382. // disable double click
  383. //=============================================================================
  384. BOOL CGdipButton::PreTranslateMessage(MSG* pMsg)
  385. {
  386. if (pMsg->message == WM_LBUTTONDBLCLK)
  387. pMsg->message = WM_LBUTTONDOWN;
  388. if (m_pToolTip != NULL)
  389. {
  390. if (::IsWindow(m_pToolTip->m_hWnd))
  391. {
  392. m_pToolTip->RelayEvent(pMsg);
  393. }
  394. }
  395. return CButton::PreTranslateMessage(pMsg);
  396. }
  397. //=============================================================================
  398. // overide the erase function
  399. //=============================================================================
  400. BOOL CGdipButton::OnEraseBkgnd(CDC* pDC)
  401. {
  402. return TRUE;
  403. }
  404. //=============================================================================
  405. // Paint the button depending on the state of the mouse
  406. //=============================================================================
  407. void CGdipButton::DrawItem(LPDRAWITEMSTRUCT lpDIS)
  408. {
  409. CDC* pDC = CDC::FromHandle(lpDIS->hDC);
  410. // handle disabled state
  411. if(m_bIsDisabled)
  412. {
  413. m_pCurBtn = &m_dcGS;
  414. PaintBtn(pDC);
  415. return;
  416. }
  417. BOOL bIsPressed = (lpDIS->itemState & ODS_SELECTED);
  418. // handle toggle button
  419. if(m_bIsToggle && bIsPressed)
  420. {
  421. (m_nCurType == STD_TYPE) ? m_nCurType = ALT_TYPE : m_nCurType = STD_TYPE;
  422. }
  423. if(bIsPressed)
  424. {
  425. if(m_nCurType == STD_TYPE)
  426. m_pCurBtn = &m_dcStdP;
  427. else
  428. m_pCurBtn = &m_dcAltP;
  429. }
  430. else if(m_bIsHovering)
  431. {
  432. if(m_nCurType == STD_TYPE)
  433. m_pCurBtn = &m_dcStdH;
  434. else
  435. m_pCurBtn = &m_dcAltH;
  436. }
  437. else
  438. {
  439. if(m_nCurType == STD_TYPE)
  440. m_pCurBtn = &m_dcStd;
  441. else
  442. m_pCurBtn = &m_dcAlt;
  443. }
  444. // paint the button
  445. PaintBtn(pDC);
  446. }
  447. //=============================================================================
  448. LRESULT CGdipButton::OnMouseHover(WPARAM wparam, LPARAM lparam)
  449. //=============================================================================
  450. {
  451. m_bIsHovering = TRUE;
  452. Invalidate();
  453. DeleteToolTip();
  454. // Create a new Tooltip with new Button Size and Location
  455. SetToolTipText(m_tooltext);
  456. if (m_pToolTip != NULL)
  457. {
  458. if (::IsWindow(m_pToolTip->m_hWnd))
  459. {
  460. //Display ToolTip
  461. m_pToolTip->Update();
  462. }
  463. }
  464. return 0;
  465. }
  466. //=============================================================================
  467. LRESULT CGdipButton::OnMouseLeave(WPARAM wparam, LPARAM lparam)
  468. //=============================================================================
  469. {
  470. m_bIsTracking = FALSE;
  471. m_bIsHovering = FALSE;
  472. Invalidate();
  473. return 0;
  474. }
  475. //=============================================================================
  476. void CGdipButton::OnMouseMove(UINT nFlags, CPoint point)
  477. //=============================================================================
  478. {
  479. if (!m_bIsTracking)
  480. {
  481. TRACKMOUSEEVENT tme;
  482. tme.cbSize = sizeof(tme);
  483. tme.hwndTrack = m_hWnd;
  484. tme.dwFlags = TME_LEAVE|TME_HOVER;
  485. tme.dwHoverTime = 1;
  486. m_bIsTracking = _TrackMouseEvent(&tme);
  487. }
  488. CButton::OnMouseMove(nFlags, point);
  489. }
  490. //=============================================================================
  491. //
  492. // Call this member function with a memory DC from the code that paints
  493. // the parents background. Passing the screen DC defeats the purpose of
  494. // using this function.
  495. //
  496. //=============================================================================
  497. void CGdipButton::SetBkGnd(CDC* pDC)
  498. {
  499. CRect rect, rectS;
  500. CBitmap bmp, *pOldBitmap;
  501. GetClientRect(rect);
  502. GetWindowRect(rectS);
  503. GetParent()->ScreenToClient(rectS);
  504. m_dcBk.DeleteDC();
  505. m_dcBk.CreateCompatibleDC(pDC);
  506. bmp.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());
  507. pOldBitmap = m_dcBk.SelectObject(&bmp);
  508. m_dcBk.BitBlt(0, 0, rect.Width(), rect.Height(), pDC, rectS.left, rectS.top, SRCCOPY);
  509. bmp.DeleteObject();
  510. }
  511. //=============================================================================
  512. // Set the tooltip with a string resource
  513. //=============================================================================
  514. void CGdipButton::SetToolTipText(UINT nId, BOOL bActivate)
  515. {
  516. // load string resource
  517. m_tooltext.LoadString(nId);
  518. // If string resource is not empty
  519. if (m_tooltext.IsEmpty() == FALSE)
  520. {
  521. SetToolTipText(m_tooltext, bActivate);
  522. }
  523. }
  524. //=============================================================================
  525. // Set the tooltip with a CString
  526. //=============================================================================
  527. void CGdipButton::SetToolTipText(CString spText, BOOL bActivate)
  528. {
  529. // We cannot accept NULL pointer
  530. if (spText.IsEmpty()) return;
  531. // Initialize ToolTip
  532. InitToolTip();
  533. m_tooltext = spText;
  534. // If there is no tooltip defined then add it
  535. if (m_pToolTip->GetToolCount() == 0)
  536. {
  537. CRect rectBtn;
  538. GetClientRect(rectBtn);
  539. m_pToolTip->AddTool(this, m_tooltext, rectBtn, 1);
  540. }
  541. // Set text for tooltip
  542. m_pToolTip->UpdateTipText(m_tooltext, this, 1);
  543. m_pToolTip->SetDelayTime(2000);
  544. m_pToolTip->Activate(bActivate);
  545. }
  546. //=============================================================================
  547. void CGdipButton::InitToolTip()
  548. //=============================================================================
  549. {
  550. if (m_pToolTip == NULL)
  551. {
  552. m_pToolTip = new CToolTipCtrl;
  553. // Create ToolTip control
  554. m_pToolTip->Create(this);
  555. m_pToolTip->Activate(TRUE);
  556. }
  557. }
  558. //=============================================================================
  559. void CGdipButton::DeleteToolTip()
  560. //=============================================================================
  561. {
  562. // Destroy Tooltip incase the size of the button has changed.
  563. if (m_pToolTip != NULL)
  564. {
  565. delete m_pToolTip;
  566. m_pToolTip = NULL;
  567. }
  568. }