Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1273 lines
42 KiB

  1. /*************************************************************************/
  2. /* Copyright (C) 1999 Microsoft Corporation */
  3. /* File: MSMFBBtn.cpp */
  4. /* Description: Implementation of CMSMFBBtn Bitmap Button */
  5. /* Author: David Janecek */
  6. /*************************************************************************/
  7. #include "stdafx.h"
  8. #include "MSMFCnt.h"
  9. #include "MSMFBBtn.h"
  10. #include <commctrl.h>
  11. #include "ocidl.h" // Added by ClassView
  12. extern CComModule _Module;
  13. /////////////////////////////////////////////////////////////////////////////
  14. // CMSMFBBtn
  15. /*************************************************************************/
  16. /* Function: CMSMFBBtn */
  17. /*************************************************************************/
  18. CMSMFBBtn::CMSMFBBtn(){
  19. Init();
  20. for(INT i = 0; i < cgMaxBtnStates; i++){
  21. m_pBitmap[i] = new CBitmap;
  22. }/* end of for loop */
  23. }/* end of function CMSMFBBtn */
  24. /*************************************************************************/
  25. /* Function: Init */
  26. /* Description: Initializes variable states. */
  27. /*************************************************************************/
  28. void CMSMFBBtn::Init(){
  29. m_nEntry = BtnState::Static;
  30. m_hWndTip = NULL;
  31. m_nTTMaxWidth = 200;
  32. m_bTTCreated = FALSE;
  33. m_fDirty = true; // to refresh text property, font etc.
  34. m_uiFontSize = 10;
  35. m_bstrTextValue = L"";
  36. m_bstrFontFace = L"Arial";
  37. m_bstrFontStyle = L"Normal";
  38. m_clrBackColor = ::GetSysColor(COLOR_BTNFACE);
  39. m_clrColorActive = 0x00ff0000; // blue
  40. m_clrColorStatic = 0x00000000; // black
  41. m_clrColorHover = 0x00ff0000; // blue
  42. m_clrColorPush = 0x00ffffff; // white
  43. m_clrColorDisable = 0x00808080; // grey
  44. #if 0 // used for getting the windowed case working DJ
  45. m_bWindowOnly = TRUE;
  46. #endif
  47. }/* end of function Init */
  48. /*************************************************************************/
  49. /* Function: ~CMSMFBBtn */
  50. /* Description: Cleanup the bitmap and pallete arrays, unload resource */
  51. /* DLL. */
  52. /*************************************************************************/
  53. CMSMFBBtn::~CMSMFBBtn(){
  54. for(INT i = 0; i < cgMaxBtnStates; i++){
  55. if (m_pBitmap[i]){
  56. delete m_pBitmap[i];
  57. m_pBitmap[i] = NULL;
  58. }/* end of if statement */
  59. //CComBSTR m_bstrFilename[..] should get destructed on the stack
  60. }/* end of for loop */
  61. Init();
  62. }/* end of function ~CMSMFBBtn */
  63. /*************************************************************************/
  64. /* Function: OnDraw */
  65. /* Description: Does the basic drawing */
  66. /*************************************************************************/
  67. HRESULT CMSMFBBtn::OnDraw(ATL_DRAWINFO& di){
  68. USES_CONVERSION;
  69. RECT& rc = *(RECT*)di.prcBounds;
  70. HRESULT hr = S_OK;
  71. if (m_pBitmap[m_nEntry]){
  72. BOOL bRet;
  73. if (::IsWindow(m_hWnd) && m_blitType != DISABLE) {
  74. // TODO: Optimaze palette handling
  75. #if 0
  76. HPALETTE hNewPal = m_pBitmap[m_nEntry]->GetPal();
  77. if(hNewPal){
  78. HPALETTE hPal = ::SelectPalette(di.hdcDraw, hNewPal, TRUE);
  79. ::RealizePalette(di.hdcDraw);
  80. }/* end of if statement */
  81. #endif
  82. COLORREF clr;
  83. HPALETTE hNewPal = m_pBitmap[m_nEntry]->GetPal();
  84. ::OleTranslateColor (m_clrBackColor, hNewPal, &clr);
  85. // fill background of specific color
  86. HBRUSH hbrBack = ::CreateSolidBrush(clr);
  87. //::FillRect(hdc, &rcClient, hbrBack);
  88. ::FillRect(di.hdcDraw, (LPRECT)di.prcBounds, hbrBack);
  89. ::DeleteObject(hbrBack);
  90. }
  91. bRet = m_pBitmap[m_nEntry]->PaintTransparentDIB(di.hdcDraw, NULL,
  92. (LPRECT) di.prcBounds, m_blitType, FALSE, m_hWnd);
  93. if (m_fDirty)
  94. {
  95. SetTextProperties();
  96. }
  97. hr = m_cText.Write(di.hdcDraw, rc, m_bstrTextValue);
  98. hr = GetFocus();
  99. // THIS ASSUMES WE ARE REPAINTING THE WHOLE CONTROL
  100. // WHICH IS WHAT ATL AT THIS INCARNATION DOES
  101. if(S_OK == hr){
  102. ::DrawFocusRect(di.hdcDraw, (LPRECT)di.prcBounds);
  103. }/* end of if statement */
  104. if(!bRet){
  105. hr = E_UNEXPECTED;
  106. }/* end of if statement */
  107. }/* end of if statement */
  108. return (hr);
  109. }/* end of function OnDraw */
  110. /*************************************************************************/
  111. /* Function: SetTextProperties */
  112. /* Description: Set the properties for the CText object. */
  113. /*************************************************************************/
  114. HRESULT CMSMFBBtn::SetTextProperties()
  115. {
  116. HRESULT hr = S_OK;
  117. m_cText.SetFontFace(m_bstrFontFace);
  118. m_cText.SetFontSize(m_uiFontSize);
  119. m_cText.SetFontStyle(m_bstrFontStyle);
  120. m_cText.SetFixedSizeFont(true);
  121. // set the font color based on the current state
  122. OLE_COLOR clrColorCurrent = m_clrColorStatic;
  123. switch(m_nEntry)
  124. {
  125. case(BtnState::Static):
  126. clrColorCurrent = m_clrColorStatic;
  127. break;
  128. case(BtnState::Hover):
  129. clrColorCurrent = m_clrColorHover;
  130. break;
  131. case(BtnState::Active):
  132. clrColorCurrent = m_clrColorActive;
  133. break;
  134. case(BtnState::Push):
  135. clrColorCurrent = m_clrColorPush;
  136. break;
  137. case(BtnState::Disabled):
  138. clrColorCurrent = m_clrColorDisable;
  139. break;
  140. }
  141. // translate OLE_COLOR to COLORREF
  142. COLORREF crCurrentState;
  143. hr = OleTranslateColor(clrColorCurrent, NULL, &crCurrentState);
  144. if (FAILED(hr))
  145. {
  146. crCurrentState = GetSysColor(COLOR_WINDOWTEXT);
  147. }
  148. m_cText.SetTextColor(crCurrentState);
  149. m_fDirty = false;
  150. return hr;
  151. }
  152. STDMETHODIMP CMSMFBBtn::get_TextWidth(long *pVal)
  153. {
  154. // special case early return
  155. if (m_bstrTextValue.Length() == 0)
  156. {
  157. *pVal = 0;
  158. return S_OK;
  159. }
  160. // get the current window or the window of its parent
  161. HWND hwnd = GetWindow();
  162. HDC hdc = ::GetWindowDC(hwnd);
  163. // normalize to pixel coord as required by the container
  164. SetMapMode(hdc, MM_TEXT);
  165. if (m_fDirty)
  166. {
  167. SetTextProperties();
  168. }
  169. SIZE size;
  170. m_cText.GetTextWidth(hdc, m_bstrTextValue, &size);
  171. *pVal = size.cx;
  172. ::ReleaseDC(hwnd, hdc); // do not forget to free DC
  173. return S_OK;
  174. }
  175. STDMETHODIMP CMSMFBBtn::get_TextHeight(long *pVal)
  176. {
  177. // get the current window or the window of its parent
  178. HWND hwnd = GetWindow();
  179. HDC hdc = ::GetWindowDC(hwnd);
  180. // normalize to pixel coord as required by the container
  181. SetMapMode(hdc, MM_TEXT);
  182. if (m_fDirty)
  183. {
  184. SetTextProperties();
  185. }
  186. SIZE size;
  187. m_cText.GetTextWidth(hdc, m_bstrTextValue, &size);
  188. *pVal = size.cy;
  189. ::ReleaseDC(hwnd, hdc); // do not forget to free DC
  190. return S_OK;
  191. }
  192. /*************************************************************************/
  193. /* Function: get_ColorPush */
  194. /* Description: return the ColorPush property. */
  195. /*************************************************************************/
  196. STDMETHODIMP CMSMFBBtn::get_ColorPush(OLE_COLOR *pColor)
  197. {
  198. if (!pColor)
  199. {
  200. return E_POINTER;
  201. }
  202. *pColor = m_clrColorPush;
  203. return S_OK;
  204. }
  205. /*************************************************************************/
  206. /* Function: put_ColorPush */
  207. /* Description: set the ColorPush property. This is the color of text */
  208. /* in the Push state. */
  209. /*************************************************************************/
  210. STDMETHODIMP CMSMFBBtn::put_ColorPush(OLE_COLOR clrColor)
  211. {
  212. m_clrColorPush = clrColor;
  213. if (m_nEntry == BtnState::Push)
  214. {
  215. m_fDirty = true;
  216. }
  217. return S_OK;
  218. }
  219. /*************************************************************************/
  220. /* Function: get_ColorHover */
  221. /* Description: return the ColorHover property. */
  222. /*************************************************************************/
  223. STDMETHODIMP CMSMFBBtn::get_ColorHover(OLE_COLOR *pColor)
  224. {
  225. if (!pColor)
  226. {
  227. return E_POINTER;
  228. }
  229. *pColor = m_clrColorHover;
  230. return S_OK;
  231. }
  232. /*************************************************************************/
  233. /* Function: put_ColorHover */
  234. /* Description: set the ColorHover property. This is the color of text */
  235. /* in the Hover state. */
  236. /*************************************************************************/
  237. STDMETHODIMP CMSMFBBtn::put_ColorHover(OLE_COLOR clrColor)
  238. {
  239. m_clrColorHover = clrColor;
  240. if (m_nEntry == BtnState::Hover)
  241. {
  242. m_fDirty = true;
  243. }
  244. return S_OK;
  245. }
  246. /*************************************************************************/
  247. /* Function: get_ColorStatic */
  248. /* Description: return the ColorStatic property. */
  249. /*************************************************************************/
  250. STDMETHODIMP CMSMFBBtn::get_ColorStatic(OLE_COLOR *pColor)
  251. {
  252. if (!pColor)
  253. {
  254. return E_POINTER;
  255. }
  256. *pColor = m_clrColorStatic;
  257. return S_OK;
  258. }
  259. /*************************************************************************/
  260. /* Function: put_ColorPush */
  261. /* Description: set the ColorPush property. This is the color of text */
  262. /* in the Static (normal) state. */
  263. /*************************************************************************/
  264. STDMETHODIMP CMSMFBBtn::put_ColorStatic(OLE_COLOR clrColor)
  265. {
  266. m_clrColorStatic = clrColor;
  267. if (m_nEntry == BtnState::Static)
  268. {
  269. m_fDirty = true;
  270. }
  271. return S_OK;
  272. }
  273. /*************************************************************************/
  274. /* Function: get_ColorDisable */
  275. /* Description: return the ColorDisable property. */
  276. /*************************************************************************/
  277. STDMETHODIMP CMSMFBBtn::get_ColorDisable(OLE_COLOR *pColor)
  278. {
  279. if (!pColor)
  280. {
  281. return E_POINTER;
  282. }
  283. *pColor = m_clrColorDisable;
  284. return S_OK;
  285. }
  286. /*************************************************************************/
  287. /* Function: put_ColorDisable */
  288. /* Description: set the ColorDisable property. This is the color of text */
  289. /* in the Disabled state. */
  290. /*************************************************************************/
  291. STDMETHODIMP CMSMFBBtn::put_ColorDisable(OLE_COLOR clrColor)
  292. {
  293. m_clrColorDisable = clrColor;
  294. if (m_nEntry == BtnState::Disabled)
  295. {
  296. m_fDirty = true;
  297. }
  298. return S_OK;
  299. }
  300. /*************************************************************************/
  301. /* Function: get_ColorActive */
  302. /* Description: return the ColorActive property. */
  303. /*************************************************************************/
  304. STDMETHODIMP CMSMFBBtn::get_ColorActive(OLE_COLOR *pColor)
  305. {
  306. if (!pColor)
  307. {
  308. return E_POINTER;
  309. }
  310. *pColor = m_clrColorActive;
  311. return S_OK;
  312. }
  313. /*************************************************************************/
  314. /* Function: put_ColorActive */
  315. /* Description: set the ColorActive property. This is the color of text */
  316. /* in the Active state. */
  317. /*************************************************************************/
  318. STDMETHODIMP CMSMFBBtn::put_ColorActive(OLE_COLOR clrColor)
  319. {
  320. m_clrColorActive = clrColor;
  321. if (m_nEntry == BtnState::Active)
  322. {
  323. m_fDirty = true;
  324. }
  325. return S_OK;
  326. }
  327. /*************************************************************************/
  328. /* Function: get_FontSize */
  329. /* Description: return the FontSize property. */
  330. /*************************************************************************/
  331. STDMETHODIMP CMSMFBBtn::get_FontSize(long *pVal)
  332. {
  333. if (!pVal)
  334. {
  335. return E_POINTER;
  336. }
  337. *pVal = m_uiFontSize;
  338. return S_OK;
  339. }
  340. /*************************************************************************/
  341. /* Function: put_FontSize */
  342. /* Description: set the FontSize property, in pt. */
  343. /*************************************************************************/
  344. STDMETHODIMP CMSMFBBtn::put_FontSize(long lSize)
  345. {
  346. if ((UINT)lSize != m_uiFontSize)
  347. {
  348. m_uiFontSize = (UINT)lSize;
  349. m_fDirty = true;
  350. }
  351. return S_OK;
  352. }
  353. /*************************************************************************/
  354. /* Function: get_Text */
  355. /* Description: return the Text that is displayed in the control. */
  356. /*************************************************************************/
  357. STDMETHODIMP CMSMFBBtn::get_Text(BSTR *pText)
  358. {
  359. if (!pText)
  360. {
  361. return E_POINTER;
  362. }
  363. *pText = m_bstrTextValue.Copy();
  364. return S_OK;
  365. }
  366. /*************************************************************************/
  367. /* Function: put_Text */
  368. /* Description: set the text to be displayed in the control. */
  369. /*************************************************************************/
  370. STDMETHODIMP CMSMFBBtn::put_Text(BSTR wsText)
  371. {
  372. if (_wcsicmp(m_bstrTextValue, wsText) != 0)
  373. {
  374. m_bstrTextValue = wsText;
  375. FireViewChange();
  376. }
  377. return S_OK;
  378. }
  379. /*************************************************************************/
  380. /* Function: get_FontFace */
  381. /* Description: return the FontFace property. */
  382. /*************************************************************************/
  383. STDMETHODIMP CMSMFBBtn::get_FontFace(BSTR *pFontFace)
  384. {
  385. if (!pFontFace)
  386. {
  387. return E_POINTER;
  388. }
  389. *pFontFace = m_bstrFontFace.Copy();
  390. return S_OK;
  391. }
  392. /*************************************************************************/
  393. /* Function: put_FontFace */
  394. /* Description: set the FontFace property. */
  395. /*************************************************************************/
  396. STDMETHODIMP CMSMFBBtn::put_FontFace(BSTR wsFontFace)
  397. {
  398. if (_wcsicmp(m_bstrFontFace, wsFontFace) != 0)
  399. {
  400. m_bstrFontFace = wsFontFace;
  401. m_fDirty = true;
  402. }
  403. return S_OK;
  404. }
  405. /*************************************************************************/
  406. /* Function: get_FontStyle */
  407. /* Description: return the FontSize property. */
  408. /*************************************************************************/
  409. STDMETHODIMP CMSMFBBtn::get_FontStyle(BSTR *pFontStyle)
  410. {
  411. if (!pFontStyle)
  412. {
  413. return E_POINTER;
  414. }
  415. *pFontStyle = m_bstrFontStyle.Copy();
  416. return S_OK;
  417. }
  418. /*************************************************************************/
  419. /* Function: put_FontStyle */
  420. /* Description: set the FontStyle property. The style string should */
  421. /* contain either "Normal", or concatenation of one or more strings of: */
  422. /* "Bold", "Italic", "Underline", "Strikeout". Default is "Normal". */
  423. /*************************************************************************/
  424. STDMETHODIMP CMSMFBBtn::put_FontStyle(BSTR wsFontStyle)
  425. {
  426. if (_wcsicmp(m_bstrFontStyle, wsFontStyle) != 0)
  427. {
  428. m_bstrFontStyle = wsFontStyle;
  429. m_fDirty = true;
  430. }
  431. return S_OK;
  432. }
  433. /*************************************************************************/
  434. /* Function: get_ImageStatic */
  435. /*************************************************************************/
  436. STDMETHODIMP CMSMFBBtn::get_ImageStatic(BSTR *pstrFilename){
  437. *pstrFilename = m_bstrFilename[BtnState::Static].Copy();
  438. return S_OK;
  439. }/* end of function get_ImageStatic */
  440. /*************************************************************************/
  441. /* Function: put_ImageStatic */
  442. /*************************************************************************/
  443. STDMETHODIMP CMSMFBBtn::put_ImageStatic(BSTR strFilename){
  444. if (!m_bstrFilename[BtnState::Disabled])
  445. PutImage(strFilename, BtnState::Disabled);
  446. return (PutImage(strFilename, BtnState::Static));
  447. }/* end of function put_ImageStatic */
  448. /*************************************************************************/
  449. /* Function: get_ImageHover */
  450. /*************************************************************************/
  451. STDMETHODIMP CMSMFBBtn::get_ImageHover(BSTR *pstrFilename){
  452. *pstrFilename = m_bstrFilename[BtnState::Hover].Copy();
  453. return S_OK;
  454. }/* end of function get_ImageHover */
  455. /*************************************************************************/
  456. /* Function: put_ImageHover */
  457. /*************************************************************************/
  458. STDMETHODIMP CMSMFBBtn::put_ImageHover(BSTR strFilename){
  459. return (PutImage(strFilename, BtnState::Hover));
  460. }/* end of function put_ImageHover */
  461. /*************************************************************************/
  462. /* Function: get_ImagePush */
  463. /*************************************************************************/
  464. STDMETHODIMP CMSMFBBtn::get_ImagePush(BSTR *pstrFilename){
  465. *pstrFilename = m_bstrFilename[BtnState::Push].Copy();
  466. return S_OK;
  467. }/* end of function get_ImagePush */
  468. /*************************************************************************/
  469. /* Function: put_ImagePush */
  470. /*************************************************************************/
  471. STDMETHODIMP CMSMFBBtn::put_ImagePush(BSTR strFilename){
  472. return (PutImage(strFilename, BtnState::Push));
  473. }/* end of function put_ImagePush */
  474. /*************************************************************************/
  475. /* Function: get_ImageDisabled */
  476. /*************************************************************************/
  477. STDMETHODIMP CMSMFBBtn::get_ImageDisabled(BSTR *pstrFilename){
  478. *pstrFilename = m_bstrFilename[BtnState::Disabled].Copy();
  479. return S_OK;
  480. }/* end of function get_ImagePush */
  481. /*************************************************************************/
  482. /* Function: put_ImageDisabled */
  483. /*************************************************************************/
  484. STDMETHODIMP CMSMFBBtn::put_ImageDisabled(BSTR strFilename){
  485. return (PutImage(strFilename, BtnState::Disabled));
  486. }/* end of function put_ImagePush */
  487. /*************************************************************************/
  488. /* Function: get_ImageActive */
  489. /*************************************************************************/
  490. STDMETHODIMP CMSMFBBtn::get_ImageActive(BSTR *pstrFilename){
  491. *pstrFilename = m_bstrFilename[BtnState::Active].Copy();
  492. return S_OK;
  493. }/* end of function get_ImagePush */
  494. /*************************************************************************/
  495. /* Function: put_ImageActive */
  496. /*************************************************************************/
  497. STDMETHODIMP CMSMFBBtn::put_ImageActive(BSTR strFilename){
  498. return (PutImage(strFilename, BtnState::Active));
  499. }/* end of function put_ImagePush */
  500. /*************************************************************************/
  501. /* Function: PutImage */
  502. /* Description: Reads the DIB file (from file or resource) into a DIB, */
  503. /* updates palette and rects of the internal bitmap. */
  504. /* Also forces redraw if changing the active image. */
  505. /*************************************************************************/
  506. HRESULT CMSMFBBtn::PutImage(BSTR strFilename, int nEntry){
  507. USES_CONVERSION;
  508. HRESULT hr = S_OK;
  509. m_bstrFilename[nEntry] = strFilename;
  510. TCHAR strBuffer[MAX_PATH] = TEXT("\0");
  511. bool fGrayOut = false;
  512. if(BtnState::Disabled == nEntry){
  513. fGrayOut = gcfGrayOut;
  514. }/* end of if statement */
  515. hr = m_pBitmap[nEntry]->PutImage(strFilename, m_hRes, GetUnknown(),fGrayOut ,m_blitType);
  516. if(FAILED(hr)){
  517. return(hr);
  518. }/* end of if statement */
  519. if(nEntry == m_nEntry ){
  520. // we are updating image that is being used, refresh it
  521. ATLTRACE2(atlTraceWindowing, 20, TEXT("Redrawing the image\n"));
  522. InvalidateRgn(); // our helper function
  523. }/* end of if statement */
  524. return(hr);
  525. }/* end of function PutImage */
  526. /*************************************************************************/
  527. /* Function: OnButtonDown */
  528. /* Description: Handles when buttons is selected. Captures the mouse */
  529. /* movents (supported for windowless, via interfaces). */
  530. /*************************************************************************/
  531. LRESULT CMSMFBBtn::OnButtonDown(UINT, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
  532. if (m_nEntry == BtnState::Disabled){
  533. return 0;
  534. }/* end of if statement */
  535. LONG xPos = GET_X_LPARAM(lParam);
  536. LONG yPos = GET_Y_LPARAM(lParam);
  537. if(PtOnButton(xPos, yPos)){
  538. // we are really on the buttons bitmap and we pushed it
  539. if(BtnState::Hover != m_nEntry){
  540. // in hover case we already have captured the mouse, so do not do
  541. // that again
  542. SetCapture(true); // capture the mouse messages
  543. }/* end of if statement */
  544. SetButtonState(BtnState::Push);
  545. }/* end of if statement */
  546. return 0;
  547. }/* end of function OnButtonDown */
  548. /*************************************************************************/
  549. /* Function: OnButtonUp */
  550. /* Description: Releases the capture, updates the button visual state, */
  551. /* and if release on the buttons image fire the event. */
  552. /*************************************************************************/
  553. LRESULT CMSMFBBtn::OnButtonUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
  554. LONG lRes = 0;
  555. if (m_nEntry == BtnState::Disabled){
  556. ForwardWindowMessage(WM_USER_FOCUS, (WPARAM) m_hWnd, 0, lRes);
  557. return lRes;
  558. }/* end of if statement */
  559. LONG xPos = GET_X_LPARAM(lParam);
  560. LONG yPos = GET_Y_LPARAM(lParam);
  561. bool bOnButtonImage = PtOnButton(xPos, yPos);
  562. bool bFire = (m_nEntry == BtnState::Push);
  563. if(bOnButtonImage){
  564. SetButtonState(BtnState::Static); //change to static even
  565. SetCapture(false); // release the capture of the mouse messages
  566. }
  567. else {
  568. SetButtonState(BtnState::Static);
  569. // do it only when we do not hower, if we hower, then keep the capture
  570. SetCapture(false); // release the capture of the mouse messages
  571. }/* end of if statement */
  572. if (bFire){
  573. if(bOnButtonImage){
  574. Fire_OnClick();
  575. }/* end of if statement */
  576. }/* end of if statement */
  577. ForwardWindowMessage(WM_USER_FOCUS, (WPARAM) m_hWnd, 0, lRes);
  578. return lRes;
  579. }/* end of function OnButtonUp */
  580. /*************************************************************************/
  581. /* Function: OnMouseMove */
  582. /* Description: Check if we were captured/pushed the do not do much, */
  583. /* otherwise do the hit detection and see if we are in static or hower */
  584. /* state. */
  585. /*************************************************************************/
  586. LRESULT CMSMFBBtn::OnMouseMove(UINT, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
  587. if (m_nEntry == BtnState::Disabled)
  588. return 0;
  589. LONG xPos = GET_X_LPARAM(lParam);
  590. LONG yPos = GET_Y_LPARAM(lParam);
  591. if (m_nEntry != BtnState::Push){
  592. if(PtOnButton(xPos, yPos)){
  593. if(BtnState::Hover != m_nEntry || S_OK != GetCapture()){
  594. SetCapture(true); // capture the mouse messages
  595. SetButtonState(BtnState::Hover);
  596. }/* end of if statement */
  597. }
  598. else {
  599. if(BtnState::Static != m_nEntry){
  600. SetCapture(false); // release the capture of the mouse messages
  601. SetButtonState(BtnState::Static);
  602. }/* end of if statement */
  603. }/* end of if statement */
  604. }/* end of if statement */
  605. return 0;
  606. }/* end of function OnMouseMove */
  607. /*************************************************************************/
  608. /* Function: OnMouseToolTip */
  609. /* Description: Check if we were captured/pushed the do not do much, */
  610. /* otherwise do the hit detection and see if we are in static or hower */
  611. /* state. */
  612. /*************************************************************************/
  613. LRESULT CMSMFBBtn::OnMouseToolTip(UINT msg, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
  614. MSG mssg;
  615. mssg.hwnd = GetWindow();
  616. ATLASSERT(mssg.hwnd);
  617. mssg.message = msg;
  618. mssg.wParam = wParam;
  619. mssg.lParam = lParam;
  620. if (m_hWndTip)
  621. ::SendMessage(m_hWndTip, TTM_RELAYEVENT, 0, (LPARAM) &mssg);
  622. bHandled = FALSE;
  623. return 0;
  624. }/* end of function OnMouseToolTip */
  625. /*************************************************************************/
  626. /* Function: OnSetFocus */
  627. /* Description: If we are in disabled state SetFocus(false) */
  628. /*************************************************************************/
  629. LRESULT CMSMFBBtn::OnSetFocus(UINT msg, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
  630. if (m_nEntry == BtnState::Disabled){
  631. if(GetFocus() == S_OK){
  632. SetFocus(false);
  633. }/* end of if statement */
  634. FireViewChange();
  635. return(-1);
  636. }/* end of if statement */
  637. FireViewChange();
  638. return 0;
  639. }/* end of function OnSetFocus */
  640. /*************************************************************************/
  641. /* Function: OnKillFocus */
  642. /* Description: If we are in disabled state SetFocus(false) */
  643. /*************************************************************************/
  644. LRESULT CMSMFBBtn::OnKillFocus(UINT msg, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
  645. FireViewChange();
  646. return 0;
  647. }/* end of function OnKillFocus */
  648. /*************************************************************************/
  649. /* Function: PtOnButton */
  650. /* Description: Uses helper to do the same. */
  651. /*************************************************************************/
  652. bool CMSMFBBtn::PtOnButton(LONG x, LONG y){
  653. POINT pos = {x, y};
  654. return(PtOnButton(pos));
  655. }/* end of function PtOnButton */
  656. /*************************************************************************/
  657. /* Function: PtOnButton */
  658. /* Description: Determines if the point is located on the button. */
  659. /* TODO: Needs to be modified when we will handle transparent color. */
  660. /*************************************************************************/
  661. bool CMSMFBBtn::PtOnButton(POINT pos){
  662. RECT rc;
  663. bool bRet = false;
  664. if(m_bWndLess){
  665. rc = m_rcPos;
  666. }
  667. else {
  668. if(!::IsWindow(m_hWnd)){
  669. return(bRet);
  670. }/* end of if statement */
  671. ::GetClientRect(m_hWnd, &rc);
  672. }/* end of if statement */
  673. bRet = PtInRect(&rc, pos) ? true : false;
  674. //TODO: Add also if we are on bitmap itsels possibly
  675. #ifdef _DEBUG
  676. if(bRet)
  677. ATLTRACE2(atlTraceWindowing, 20, TEXT("Point x = %d y = %d in Rect left = %d top %d right %d bottom %d\n"),
  678. pos.x, pos.y, m_rcPos.left, m_rcPos.top, m_rcPos.right, m_rcPos.bottom);
  679. else
  680. ATLTRACE2(atlTraceWindowing, 20, TEXT("Point x = %d y = %d NOT ON RECT Rect left = %d top %d right %d bottom %d\n"),
  681. pos.x, pos.y, m_rcPos.left, m_rcPos.top, m_rcPos.right, m_rcPos.bottom);
  682. #endif
  683. return(bRet);
  684. }/* end of function PtOnButton */
  685. /*************************************************************************/
  686. /* Function: OnKeyDown */
  687. /* Description: Depresses the button. */
  688. /*************************************************************************/
  689. LRESULT CMSMFBBtn::OnKeyDown(UINT uMsg, WPARAM wParam, LPARAM lParam,
  690. BOOL& bHandled){
  691. bHandled = FALSE;
  692. LONG lRes = 0;
  693. if (m_nEntry == BtnState::Disabled){
  694. return 0;
  695. }/* end of if statement */
  696. switch(wParam){
  697. case VK_RETURN:
  698. case VK_SPACE:
  699. SetButtonState(BtnState::Push);
  700. break;
  701. }/* end of if statement */
  702. return(lRes);
  703. }/* end of function OnKeyDown */
  704. /*************************************************************************/
  705. /* Function: OnKeyUp */
  706. /* Description: Distrubutes the keyboard messages properly. */
  707. /*************************************************************************/
  708. LRESULT CMSMFBBtn::OnKeyUp(UINT uMsg, WPARAM wParam, LPARAM lParam,
  709. BOOL& bHandled){
  710. bHandled = FALSE;
  711. LONG lRes = 0;
  712. if (m_nEntry == BtnState::Disabled){
  713. return 0;
  714. }/* end of if statement */
  715. switch(wParam){
  716. case VK_RETURN:
  717. case VK_SPACE:
  718. Fire_OnClick();
  719. SetButtonState(BtnState::Static);
  720. break;
  721. }/* end of if statement */
  722. return(lRes);
  723. }/* end of function OnKeyUp */
  724. /*************************************************************************/
  725. /* Function: OnSize */
  726. /* Description: Invalidate region since size has changed */
  727. /*************************************************************************/
  728. LRESULT CMSMFBBtn::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam,
  729. BOOL& bHandled){
  730. bHandled = FALSE;
  731. InvalidateRgn();
  732. return 0;
  733. }
  734. /*************************************************************************/
  735. /* Function: SetButtonState */
  736. /* Description: Sets the button states forces redraw. */
  737. /*************************************************************************/
  738. HRESULT CMSMFBBtn::SetButtonState(BtnState btnState){
  739. HRESULT hr = S_OK;
  740. bool fRedraw = false;
  741. if(btnState != m_nEntry ){
  742. fRedraw = true;
  743. }/* end of if statement */
  744. m_nEntry = btnState;
  745. if(fRedraw){
  746. if (m_nEntry == BtnState::Disabled){
  747. SetFocus(false); // disable the focus
  748. SetCapture(false);
  749. }/* end of if statement */
  750. // we are updating image that is being used, refresh it
  751. ATLTRACE2(atlTraceWindowing, 20, TEXT("Redrawing the image\n"));
  752. m_fDirty = true; // to force an update of font color
  753. FireViewChange(); // update the display
  754. //InvalidateRgn(); // our helper function
  755. }/* end of if statement */
  756. return(hr);
  757. }/* end of function SetButtonState */
  758. /*************************************************************************/
  759. /* Function: About */
  760. /* Description: Displays the AboutBox */
  761. /*************************************************************************/
  762. STDMETHODIMP CMSMFBBtn::About(){
  763. HRESULT hr = S_OK;
  764. const INT ciMaxBuffSize = MAX_PATH; // enough for the text
  765. TCHAR strBuffer[ciMaxBuffSize];
  766. TCHAR strBufferAbout[ciMaxBuffSize];
  767. if(!::LoadString(_Module.m_hInstResource, IDS_BTN_ABOUT, strBuffer, ciMaxBuffSize)){
  768. hr = E_UNEXPECTED;
  769. return(hr);
  770. }/* end of if statement */
  771. if(!::LoadString(_Module.m_hInstResource, IDS_ABOUT, strBufferAbout, ciMaxBuffSize)){
  772. hr = E_UNEXPECTED;
  773. return(hr);
  774. }/* end of if statement */
  775. ::MessageBox(::GetFocus(), strBuffer, strBufferAbout, MB_OK);
  776. return (hr);
  777. }/* end of function About */
  778. /*************************************************************/
  779. /* Function: get_Disable */
  780. /* Description: Returns OLE-BOOL if disabled or enabled. */
  781. /*************************************************************/
  782. STDMETHODIMP CMSMFBBtn::get_Disable(VARIANT_BOOL *pVal){
  783. *pVal = BtnState::Disabled == m_nEntry ? VARIANT_TRUE : VARIANT_FALSE;
  784. return S_OK;
  785. }/* end of function get_Disable */
  786. /*************************************************************/
  787. /* Function: put_Disable */
  788. /* Description: Disable or enable the buttons (disabled */
  789. /* are greyed out and do not except mouse clicks). */
  790. /*************************************************************/
  791. STDMETHODIMP CMSMFBBtn::put_Disable(VARIANT_BOOL newVal){
  792. // TODO: Right Now We Get Restored Automatically into Static state
  793. // we could detect the mouse and see if we are in static
  794. // or hower state
  795. BtnState btnSt = VARIANT_FALSE == newVal ? BtnState::Static : BtnState::Disabled;
  796. HRESULT hr = SetButtonState(btnSt);
  797. return (hr);
  798. }/* end of function put_Disable */
  799. /*************************************************************/
  800. /* Function: get_BtnState */
  801. /* Description: Gets current button state. */
  802. /*************************************************************/
  803. STDMETHODIMP CMSMFBBtn::get_BtnState(long *pVal){
  804. *pVal = (long) m_nEntry;
  805. return S_OK;
  806. }/* end of function get_BtnState */
  807. /*************************************************************/
  808. /* Function: put_BtnState */
  809. /* Description: Sets the button state manually. */
  810. /*************************************************************/
  811. STDMETHODIMP CMSMFBBtn::put_BtnState(long newVal){
  812. HRESULT hr = SetButtonState((BtnState)newVal);
  813. return(hr);
  814. }/* end of function put_BtnState */
  815. /*************************************************************/
  816. /* Name: get_ToolTip */
  817. /* Description: create a tool tip for the button */
  818. /*************************************************************/
  819. STDMETHODIMP CMSMFBBtn::get_ToolTip(BSTR *pVal){
  820. *pVal = m_bstrToolTip.Copy();
  821. return 0;
  822. }/* end of function get_ToolTip */
  823. /*************************************************************/
  824. /* Name: put_ToolTip */
  825. /* Description: create a tool tip for the button */
  826. /* Cache the tooltip string if there is no window available */
  827. /*************************************************************/
  828. STDMETHODIMP CMSMFBBtn::put_ToolTip(BSTR newVal){
  829. m_bstrToolTip = newVal;
  830. return CreateToolTip();
  831. }
  832. /*************************************************************/
  833. /* Name: SetObjectRects */
  834. /* Description: Update tooltip rect object is being moved */
  835. /*************************************************************/
  836. STDMETHODIMP CMSMFBBtn::SetObjectRects(LPCRECT prcPos,LPCRECT prcClip){
  837. // Call the default method first
  838. IOleInPlaceObjectWindowlessImpl<CMSMFBBtn>::SetObjectRects(prcPos, prcClip);
  839. if (!m_hWndTip) return S_OK;
  840. HWND hwnd = GetWindow();
  841. if (!hwnd) return S_FALSE;
  842. TOOLINFO ti; // tool information
  843. ti.cbSize = sizeof(TOOLINFO);
  844. ti.uFlags = 0;
  845. ti.hwnd = hwnd;
  846. ti.hinst = _Module.GetModuleInstance();
  847. ti.uId = (UINT) 0;
  848. ti.rect = *prcPos; // new tooltip position
  849. if (!SendMessage(m_hWndTip, TTM_NEWTOOLRECT, 0,
  850. (LPARAM) (LPTOOLINFO) &ti))
  851. return S_FALSE;
  852. return S_OK;
  853. }/* end of function SetObjectRects */
  854. /*************************************************************/
  855. /* Name: OnPostVerbInPlaceActivate
  856. /* Description: Overwrite IOleObjectImp::OnPostVerbInPlaceActivate
  857. /* to actually create the tooltip for the button
  858. /*************************************************************/
  859. HRESULT CMSMFBBtn::OnPostVerbInPlaceActivate(){
  860. // Return if tooltip is already created
  861. if (m_bTTCreated) return S_OK;
  862. HRESULT hr = CreateToolTip();
  863. if (SUCCEEDED(hr))
  864. m_bTTCreated = TRUE;
  865. return hr;
  866. }/* end of function OnPostVerbInPlaceActivate */
  867. /*************************************************************/
  868. /* Name: CreateToolTip
  869. /* Description: create a tool tip for the button
  870. /*************************************************************/
  871. HRESULT CMSMFBBtn::CreateToolTip(void){
  872. HWND hwnd = GetWindow();
  873. if (!hwnd) return S_FALSE;
  874. USES_CONVERSION;
  875. // If tool tip is to be created for the first time
  876. if (m_hWndTip == (HWND) NULL) {
  877. // Ensure that the common control DLL is loaded, and create
  878. // a tooltip control.
  879. InitCommonControls();
  880. m_hWndTip = CreateWindow(TOOLTIPS_CLASS, (LPCTSTR) NULL, TTS_ALWAYSTIP,
  881. CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
  882. hwnd, (HMENU) NULL, _Module.GetModuleInstance(), NULL);
  883. }
  884. if (m_hWndTip == (HWND) NULL)
  885. return S_FALSE;
  886. TOOLINFO ti; // tool information
  887. ti.cbSize = sizeof(TOOLINFO);
  888. ti.uFlags = 0;
  889. ti.hwnd = hwnd;
  890. ti.hinst = _Module.GetModuleInstance();
  891. ti.uId = (UINT) 0;
  892. ti.lpszText = OLE2T(m_bstrToolTip);
  893. // if the button is a windowed control, the tool tip is added to
  894. // the button's own window, and the tool tip area should just be
  895. // the client rect of the window
  896. if (hwnd == m_hWnd)
  897. ::GetClientRect(hwnd, &ti.rect);
  898. // otherwise the tool tip is added to the closet windowed parent of
  899. // the button, and the tool tip area should be the relative postion
  900. // of the button in the parent window
  901. else {
  902. ti.rect.left = m_rcPos.left;
  903. ti.rect.top = m_rcPos.top;
  904. ti.rect.right = m_rcPos.right;
  905. ti.rect.bottom = m_rcPos.bottom;
  906. }
  907. if (!SendMessage(m_hWndTip, TTM_ADDTOOL, 0,
  908. (LPARAM) (LPTOOLINFO) &ti))
  909. return S_FALSE;
  910. // Set initial delay time
  911. put_ToolTipMaxWidth(m_nTTMaxWidth);
  912. SetDelayTime(TTDT_AUTOPOP, 10000);
  913. SetDelayTime(TTDT_INITIAL, 10);
  914. return S_OK;
  915. }/* end of function CreateToolTip */
  916. /*************************************************************/
  917. /* Name: GetDelayTime
  918. /* Description: Get the length of time a pointer must remain
  919. /* stationary within a tool's bounding rectangle before the
  920. /* tooltip window appears
  921. /* delayTypes: TTDT_RESHOW 1
  922. /* TTDT_AUTOPOP 2
  923. /* TTDT_INITIAL 3
  924. /*************************************************************/
  925. STDMETHODIMP CMSMFBBtn::GetDelayTime(long delayType, long *pVal){
  926. if (delayType>TTDT_INITIAL || delayType<TTDT_RESHOW)
  927. return S_FALSE;
  928. if (m_hWndTip)
  929. *pVal = SendMessage(m_hWndTip, TTM_GETDELAYTIME,
  930. (WPARAM) (DWORD) delayType, 0);
  931. return S_OK;
  932. }/* end of function GetDelayTime */
  933. /*************************************************************/
  934. /* Name: SetDelayTime
  935. /* Description: Set the length of time a pointer must remain
  936. /* stationary within a tool's bounding rectangle before the
  937. /* tooltip window appears
  938. /* delayTypes: TTDT_AUTOMATIC 0
  939. /* TTDT_RESHOW 1
  940. /* TTDT_AUTOPOP 2
  941. /* TTDT_INITIAL 3
  942. /*************************************************************/
  943. STDMETHODIMP CMSMFBBtn::SetDelayTime(long delayType, long newVal){
  944. if (delayType>TTDT_INITIAL || delayType<TTDT_AUTOMATIC)
  945. return S_FALSE;
  946. if (m_hWndTip) {
  947. if (!SendMessage(m_hWndTip, TTM_SETDELAYTIME,
  948. (WPARAM) (DWORD) delayType,
  949. (LPARAM) (INT) newVal))
  950. return S_FALSE;
  951. }
  952. return S_OK;
  953. }/* end of function SetDelayTime */
  954. /*************************************************************************/
  955. /* Function: get_ToolTipMaxWidth */
  956. /*************************************************************************/
  957. STDMETHODIMP CMSMFBBtn::get_ToolTipMaxWidth(long *pVal){
  958. if (m_hWndTip){
  959. *pVal = ::SendMessage(m_hWndTip, TTM_GETMAXTIPWIDTH, 0, 0);
  960. }/* end of if statement */
  961. return S_OK;
  962. }/* end of function get_ToolTipMaxWidth */
  963. /*************************************************************************/
  964. /* Function: put_ToolTipMaxWidth */
  965. /*************************************************************************/
  966. STDMETHODIMP CMSMFBBtn::put_ToolTipMaxWidth(long newVal){
  967. m_nTTMaxWidth = newVal;
  968. if (m_hWndTip){
  969. ::SendMessage(m_hWndTip, TTM_SETMAXTIPWIDTH, 0, (LPARAM)(INT) newVal);
  970. }/* end of if statement */
  971. return S_OK;
  972. }/* end of function put_ToolTipMaxWidth */
  973. /*************************************************************************/
  974. /* End of file: MSMFBBtn.cpp */
  975. /*************************************************************************/