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.

1289 lines
40 KiB

  1. /*************************************************************************/
  2. /* Copyright (C) 1999 Microsoft Corporation */
  3. /* File: CstUtils.h */
  4. /* Description: Utilities that we can share across mutliple modules. */
  5. /* Author: David Janecek */
  6. /*************************************************************************/
  7. #ifndef __MSMFCSTUTILS_H_
  8. #define __MSMFCSTUTILS_H_
  9. #include <commctrl.h>
  10. #ifdef _WMP
  11. #include "wmp.h" // for wmp integration
  12. #endif
  13. const bool gcfGrayOut = false;
  14. #define WM_USER_FOCUS (WM_USER + 0x10)
  15. #define WM_USER_ENDHELP (WM_USER + 0x11)
  16. #define OCR_ARROW_DEFAULT 100
  17. #define USE_MF_OVERWRITES \
  18. HRESULT InvalidateRgn(bool fErase = false){return MFInvalidateRgn(fErase);} \
  19. HRESULT FireViewChange(){return MFFireViewChange();} \
  20. HRESULT InPlaceActivate(LONG iVerb, const RECT* prcPosRect){return MFInPlaceActivate(iVerb, prcPosRect);} \
  21. HRESULT SetCapture(bool bCapture){return MFSetCapture(bCapture);} \
  22. HRESULT SetFocus(bool bFocus){return MFSetFocus(bFocus);} \
  23. HWND GetWindow(){return MFGetWindow();} \
  24. HRESULT ForwardWindowMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, LONG& lRes,\
  25. bool fForwardInWndls = false){return MFForwardWindowMessage(uMsg, wParam, lParam, lRes, \
  26. fForwardInWndls);}
  27. #define USE_MF_RESOURCEDLL \
  28. STDMETHOD(get_ResourceDLL)(/*[out, retval]*/ BSTR *pVal){return get_MFResourceDLL(pVal);} \
  29. STDMETHOD(put_ResourceDLL)(/*[in]*/ BSTR newVal){return put_MFResourceDLL(newVal);}
  30. #define USE_MF_WINDOWLESS_ACTIVATION \
  31. STDMETHOD(get_Windowless)(VARIANT_BOOL *pVal){return get_MFWindowless(pVal);} \
  32. STDMETHOD(put_Windowless)(VARIANT_BOOL newVal){return put_MFWindowless(newVal);}
  33. #define USE_MF_TRANSPARENT_FLAG \
  34. STDMETHOD(get_TransparentBlit)(TransparentBlitType *pVal){return get_MFTransparentBlit(pVal);}\
  35. STDMETHOD(put_TransparentBlit)(TransparentBlitType newVal){return put_MFTransparentBlit(newVal);}
  36. #define USE_MF_CLASSSTYLE \
  37. static CWndClassInfo& GetWndClassInfo(){ \
  38. static HBRUSH wcBrush = ::CreateSolidBrush(RGB(0,0,0)); \
  39. static CWndClassInfo wc = {{ sizeof(WNDCLASSEX), 0 /*CS_OWNDC*/, StartWindowProc, \
  40. 0, 0, NULL, NULL, NULL, wcBrush /* (HBRUSH)(COLOR_WINDOW + 1) */, \
  41. NULL, TEXT("MSMFCtlClass"), NULL }, \
  42. NULL, NULL, MAKEINTRESOURCE(OCR_ARROW_DEFAULT), TRUE, 0, _T("") }; \
  43. return wc; \
  44. }/* end of function GetWndClassInfo */
  45. #define USE_MF_TOOLTIP \
  46. STDMETHOD(GetDelayTime)(long delayType, long *pVal) {return MFGetDelayTime(delayType, pVal); } \
  47. STDMETHOD(SetDelayTime)(long delayType, long newVal){return MFSetDelayTime(delayType, newVal); } \
  48. STDMETHOD(get_ToolTip)(BSTR *pVal) {return get_MFToolTip(pVal); } \
  49. STDMETHOD(put_ToolTip)(BSTR newVal) {put_MFToolTip(newVal); return CreateToolTip(m_hWnd, m_rcPos);} \
  50. STDMETHOD(get_ToolTipMaxWidth)(long *pVal) {return get_MFToolTipMaxWidth(pVal); } \
  51. STDMETHOD(put_ToolTipMaxWidth)(long newVal){return put_MFToolTipMaxWidth(newVal); } \
  52. STDMETHOD(get_ToolTipTracking)(VARIANT_BOOL *pVal) {return get_MFTooltipTracking(pVal); } \
  53. STDMETHOD(put_ToolTipTracking)(VARIANT_BOOL newVal) {put_MFTooltipTracking(newVal); return CreateToolTip(m_hWnd, m_rcPos);} \
  54. HRESULT OnPostVerbInPlaceActivate() { \
  55. /* Return if tooltip is already created */ \
  56. if (m_hWndTip) return S_OK; \
  57. return CreateToolTip(m_hWnd, m_rcPos); \
  58. } \
  59. /*************************************************************************/
  60. /* Defines */
  61. /* Could not find these under windows headers, so if there is a conflict */
  62. /* it is good idea to ifdef these out. */
  63. /*************************************************************************/
  64. #define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
  65. #define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
  66. template <class T>
  67. class ATL_NO_VTABLE CMSMFCntrlUtils{
  68. /*************************************************************************/
  69. /* PUBLIC MEMBER FUNCTIONS */
  70. /*************************************************************************/
  71. public:
  72. /*************************************************************************/
  73. /* Function: CMSMFCntrlUtils */
  74. /*************************************************************************/
  75. CMSMFCntrlUtils(){
  76. m_hRes = NULL;
  77. m_blitType = TRANSPARENT_TOP_LEFT; // DISABLE used to be the correct default TODO
  78. m_fNoFocusGrab = true; // to enable standalone "windowed" focus handeling please
  79. // make this flag a property
  80. m_hCursor = ::LoadCursor(NULL, MAKEINTRESOURCE(OCR_ARROW_DEFAULT));
  81. m_hWndTip = NULL;
  82. m_nTTMaxWidth = 200;
  83. m_bTTTracking = FALSE;
  84. m_bTrackingActivated = FALSE;
  85. m_dwTTInitalDelay = 10;
  86. m_dwTTReshowDelay = 2;
  87. m_dwTTAutopopDelay = 10000;
  88. ::ZeroMemory(&m_toolInfo, sizeof(TOOLINFO));
  89. }/* end of function CMSMFCntrlUtils */
  90. /*************************************************************************/
  91. /* Function: ~CMSMFCntrlUtils */
  92. /*************************************************************************/
  93. virtual ~CMSMFCntrlUtils(){
  94. if (m_hCursor != NULL) {
  95. ::DestroyCursor(m_hCursor);
  96. m_hCursor = NULL;
  97. }/* end of if statement */
  98. if(NULL != m_hRes){
  99. ::FreeLibrary(m_hRes); // unload our resource library
  100. m_hRes = NULL;
  101. }/* end of if statement */
  102. }/* end of function ~CMSMFCntrlUtils */
  103. /*************************************************************************/
  104. /* Message Map */
  105. /*************************************************************************/
  106. typedef CMSMFCntrlUtils< T > thisClass;
  107. BEGIN_MSG_MAP(thisClass)
  108. MESSAGE_HANDLER(WM_ERASEBKGND, CMSMFCntrlUtils::MFOnErase)
  109. MESSAGE_HANDLER(WM_SETCURSOR, CMSMFCntrlUtils::MFOnSetCursor)
  110. MESSAGE_HANDLER(WM_QUERYNEWPALETTE, CMSMFCntrlUtils::MFOnQueryNewPalette)
  111. MESSAGE_HANDLER(WM_PALETTECHANGED, CMSMFCntrlUtils::MFOnPaletteChanged)
  112. MESSAGE_RANGE_HANDLER(WM_MOUSEFIRST, WM_MOUSELAST, CMSMFCntrlUtils::MFOnMouseToolTip)
  113. END_MSG_MAP()
  114. /*************************************************************************/
  115. /* Function: MFOnErase */
  116. /* Description: Avoids erasing backround to avoid flashing. */
  117. /*************************************************************************/
  118. LRESULT MFOnErase(UINT, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
  119. bHandled = TRUE;
  120. return 0;
  121. }/* end of function MFOnErase */
  122. /*************************************************************************/
  123. /* Function: MFOnSetCursor */
  124. /* Description: Sets our cursor. */
  125. /*************************************************************************/
  126. LRESULT MFOnSetCursor(UINT, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
  127. bHandled = TRUE;
  128. ::SetCursor(m_hCursor);
  129. return(TRUE);
  130. }/* end of function MFOnSetCursor */
  131. /*************************************************************************/
  132. /* Function: MFOnQueryNewPalette */
  133. /* Description: Called when we are about to be instantiated. */
  134. /*************************************************************************/
  135. LRESULT MFOnQueryNewPalette(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
  136. T* pT = static_cast<T*>(this);
  137. if(NULL == ::IsWindow(pT->m_hWnd)){
  138. bHandled = FALSE;
  139. return FALSE;
  140. }/* end of if statement */
  141. HPALETTE hPal = CBitmap::GetSuperPal();
  142. if(NULL == hPal){
  143. //bHandled = FALSE;
  144. return FALSE;
  145. }/* end of if statement */
  146. HDC hdc = ::GetDC(pT->m_hWnd);
  147. if(NULL == hdc){
  148. return FALSE;
  149. }/* end of if statement */
  150. ::SelectPalette(hdc, hPal, FALSE);
  151. ::RealizePalette(hdc);
  152. ::InvalidateRect(pT->m_hWnd, NULL, FALSE);
  153. ::ReleaseDC(pT->m_hWnd, hdc);
  154. return TRUE;
  155. }/* end of function MFOnQueryNewPalette */
  156. /*************************************************************************/
  157. /* Function: MFOnPaletteChanged */
  158. /* Description: Called when palette is chaning. */
  159. /*************************************************************************/
  160. LRESULT MFOnPaletteChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
  161. T* pT = static_cast<T*>(this);
  162. if(NULL == ::IsWindow(pT->m_hWnd)){
  163. bHandled = FALSE;
  164. return FALSE;
  165. }/* end of if statement */
  166. if((HWND) wParam == pT->m_hWnd){
  167. bHandled = FALSE;
  168. return FALSE;
  169. }/* end of if statement */
  170. HPALETTE hPal = CBitmap::GetSuperPal();
  171. if(NULL == hPal){
  172. bHandled = FALSE;
  173. return FALSE;
  174. }/* end of if statement */
  175. HDC hdc = ::GetDC(pT->m_hWnd);
  176. if(NULL == hdc){
  177. return FALSE;
  178. }/* end of if statement */
  179. ::SelectPalette(hdc, hPal, FALSE);
  180. ::RealizePalette(hdc);
  181. ::UpdateColors(hdc);
  182. ::InvalidateRect(pT->m_hWnd, NULL, FALSE);
  183. ::ReleaseDC(pT->m_hWnd, hdc);
  184. bHandled = FALSE;
  185. return TRUE;
  186. }/* end of function MFOnPaletteChanged */
  187. /*************************************************************************/
  188. /* Function: get_MFResourceDLL */
  189. /* Description: Returns the string of the loaded resource DLL. */
  190. /*************************************************************************/
  191. STDMETHOD(get_MFResourceDLL)(BSTR *pVal){
  192. *pVal = m_strResDLL.Copy();
  193. return S_OK;
  194. }/* end of function get_MFResourceDLL */
  195. /*************************************************************************/
  196. /* Function: put_MFResourceDLL */
  197. /* Description: Loads the resource DLL. */
  198. /*************************************************************************/
  199. STDMETHOD(put_MFResourceDLL)(BSTR strFileName){
  200. HRESULT hr = LoadResourceDLL(strFileName);
  201. // see if we loaded it
  202. if(FAILED(hr)){
  203. return(hr);
  204. }/* end of if statement */
  205. // update the cached variable value
  206. m_strResDLL = strFileName;
  207. return(hr);
  208. }/* end of function put_MFResourceDLL */
  209. /*************************************************************************/
  210. /* Function: get_MFWindowless */
  211. /* Description: Gets if we we tried to be windowless activated or not. */
  212. /*************************************************************************/
  213. HRESULT get_MFWindowless(VARIANT_BOOL *pVal){
  214. HRESULT hr = S_OK;
  215. try {
  216. T* pT = static_cast<T*>(this);
  217. if(NULL == pVal){
  218. throw(E_POINTER);
  219. }/* end of if statement */
  220. *pVal = pT->m_bWindowOnly == FALSE ? VARIANT_FALSE: VARIANT_TRUE;
  221. }/* end of try statement */
  222. catch(HRESULT hrTmp){
  223. hr = hrTmp;
  224. }/* end of catch statement */
  225. catch(...){
  226. hr = E_UNEXPECTED;
  227. }/* end of catch statement */
  228. return(hr);
  229. }/* end of function get_MFWindowless */
  230. /*************************************************************************/
  231. /* Function: put_MFWindowless */
  232. /* Description: This sets the windowless mode, should be set from the */
  233. /* property bag. */
  234. /*************************************************************************/
  235. HRESULT put_MFWindowless(VARIANT_BOOL newVal){
  236. HRESULT hr = S_OK;
  237. try {
  238. T* pT = static_cast<T*>(this);
  239. if(VARIANT_FALSE == newVal){
  240. pT->m_bWindowOnly = TRUE;
  241. }
  242. else {
  243. pT->m_bWindowOnly = FALSE;
  244. }/* end of if statement */
  245. // TODO: This function should fail after we inplace activated !!
  246. }/* end of try statement */
  247. catch(HRESULT hrTmp){
  248. hr = hrTmp;
  249. }/* end of catch statement */
  250. catch(...){
  251. hr = E_UNEXPECTED;
  252. }/* end of catch statement */
  253. return(hr);
  254. }/* end of function put_MFWindowless */
  255. /*************************************************************************/
  256. /* Function: get_MFTransparentBlit */
  257. /* Description: Gets current state of the transperent blit. */
  258. /*************************************************************************/
  259. HRESULT get_MFTransparentBlit(TransparentBlitType *pVal){
  260. HRESULT hr = S_OK;
  261. try {
  262. T* pT = static_cast<T*>(this);
  263. *pVal = pT->m_blitType;
  264. }
  265. catch(HRESULT hrTmp){
  266. hr = hrTmp;
  267. }/* end of catch statement */
  268. catch(...){
  269. hr = E_UNEXPECTED;
  270. }/* end of catch statement */
  271. return(hr);
  272. }/* end of function get_MFTransparentBlit */
  273. /*************************************************************************/
  274. /* Function: put_MFTransparentBlit */
  275. /* Description: Sets the state of the transperent blit. */
  276. /*************************************************************************/
  277. HRESULT put_MFTransparentBlit(TransparentBlitType newVal){
  278. HRESULT hr = S_OK;
  279. try {
  280. T* pT = static_cast<T*>(this);
  281. pT->m_blitType = newVal;
  282. }
  283. catch(HRESULT hrTmp){
  284. hr = hrTmp;
  285. }/* end of catch statement */
  286. catch(...){
  287. hr = E_UNEXPECTED;
  288. }/* end of catch statement */
  289. return(hr);
  290. }/* end of function put_MFTransparentBlit */
  291. /*************************************************************************/
  292. /* Function: MFInvalidateRgn */
  293. /* Description: Invalidates the whole rect in case we need to repaint it.*/
  294. /*************************************************************************/
  295. HRESULT MFInvalidateRgn(bool fErase = false){
  296. HRESULT hr = S_OK;
  297. T* pT = static_cast<T*>(this);
  298. if(pT->m_bWndLess){
  299. pT->m_spInPlaceSite->InvalidateRgn(NULL ,fErase ? TRUE: FALSE);
  300. }
  301. else {
  302. if(NULL == pT->m_hWnd){
  303. hr = E_FAIL;
  304. return(hr);
  305. }/* end of if statement */
  306. if(::IsWindow(pT->m_hWnd)){
  307. ::InvalidateRgn(pT->m_hWnd, NULL, fErase ? TRUE: FALSE); // see if we can get by by not erasing..
  308. }
  309. else {
  310. hr = E_UNEXPECTED;
  311. }/* end of if statement */
  312. }/* end of if statement */
  313. return(hr);
  314. }/* end of function MFInvalidateRgn */
  315. /*************************************************************************/
  316. /* Function: MFFireViewChange */
  317. /* Description: Overloaded base function, which would try to repaint the */
  318. /* whole container. Just like to repaint the control area instead. */
  319. /*************************************************************************/
  320. inline HRESULT MFFireViewChange(){ // same as FireView change but optimized
  321. T* pT = static_cast<T*>(this);
  322. if (pT->m_bInPlaceActive){
  323. // Active
  324. if (pT->m_hWndCD != NULL){
  325. ::InvalidateRect(pT->m_hWndCD, NULL, FALSE); // Window based
  326. }
  327. else if (pT->m_spInPlaceSite != NULL){
  328. pT->m_spInPlaceSite->InvalidateRect(&pT->m_rcPos, FALSE); // Do not invalidate the whole container
  329. }/* end of if statement */
  330. }
  331. else {// Inactive
  332. pT->SendOnViewChange(DVASPECT_CONTENT);
  333. }/* end of if statement */
  334. return S_OK;
  335. }/* end of function MFFireViewChange */
  336. /*************************************************************************/
  337. /* Function: MFForwardWindowMessage */
  338. /* Description: Forward the message to the parent window. */
  339. /*************************************************************************/
  340. HRESULT MFForwardWindowMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, LONG& lRes,
  341. bool fForwardInWndls = false){
  342. HRESULT hr = S_OK;
  343. T* pT = static_cast<T*>(this);
  344. lRes = 0;
  345. if(false == fForwardInWndls){
  346. if(pT->m_bWndLess || (!::IsWindow(pT->m_hWnd))){
  347. hr = S_FALSE;
  348. return (hr);
  349. }/* end of if statement */
  350. }/* end of if statement */
  351. HWND hwnd = NULL;
  352. hr = GetParentHWND(&hwnd);
  353. if(FAILED(hr)){
  354. return(hr);
  355. }/* end of if statement */
  356. lRes = (LONG)::SendMessage(hwnd, uMsg, wParam, lParam);
  357. return(hr);
  358. }/* end of function MFForwardWindowMessage */
  359. /*************************************************************************/
  360. /* Function: InPlaceActivate */
  361. /* Description: Modified InPlaceActivate so WMP can startup. */
  362. /*************************************************************************/
  363. HRESULT MFInPlaceActivate(LONG iVerb, const RECT* /*prcPosRect*/){
  364. HRESULT hr;
  365. T* pT = static_cast<T*>(this);
  366. if (pT->m_spClientSite == NULL){
  367. return S_OK;
  368. }/* end of if statement */
  369. CComPtr<IOleInPlaceObject> pIPO;
  370. pT->ControlQueryInterface(IID_IOleInPlaceObject, (void**)&pIPO);
  371. ATLASSERT(pIPO != NULL);
  372. if (!pT->m_bNegotiatedWnd){
  373. if (!pT->m_bWindowOnly)
  374. // Try for windowless site
  375. hr = pT->m_spClientSite->QueryInterface(IID_IOleInPlaceSiteWindowless, (void **)&pT->m_spInPlaceSite);
  376. if (pT->m_spInPlaceSite){
  377. pT->m_bInPlaceSiteEx = TRUE;
  378. // CanWindowlessActivate returns S_OK or S_FALSE
  379. if ( pT->m_spInPlaceSite->CanWindowlessActivate() == S_OK ){
  380. pT->m_bWndLess = TRUE;
  381. pT->m_bWasOnceWindowless = TRUE;
  382. }
  383. else
  384. {
  385. pT->m_bWndLess = FALSE;
  386. }/* end of if statement */
  387. }
  388. else {
  389. pT->m_spClientSite->QueryInterface(IID_IOleInPlaceSiteEx, (void **)&pT->m_spInPlaceSite);
  390. if (pT->m_spInPlaceSite)
  391. pT->m_bInPlaceSiteEx = TRUE;
  392. else
  393. hr = pT->m_spClientSite->QueryInterface(IID_IOleInPlaceSite, (void **)&pT->m_spInPlaceSite);
  394. }/* end of if statement */
  395. }/* end of if statement */
  396. ATLASSERT(pT->m_spInPlaceSite);
  397. if (!pT->m_spInPlaceSite)
  398. return E_FAIL;
  399. pT->m_bNegotiatedWnd = TRUE;
  400. if (!pT->m_bInPlaceActive){
  401. BOOL bNoRedraw = FALSE;
  402. if (pT->m_bWndLess)
  403. pT->m_spInPlaceSite->OnInPlaceActivateEx(&bNoRedraw, ACTIVATE_WINDOWLESS);
  404. else {
  405. if (pT->m_bInPlaceSiteEx)
  406. pT->m_spInPlaceSite->OnInPlaceActivateEx(&bNoRedraw, 0);
  407. else {
  408. hr = pT->m_spInPlaceSite->CanInPlaceActivate();
  409. // CanInPlaceActivate returns S_FALSE or S_OK
  410. if (FAILED(hr))
  411. return hr;
  412. if ( hr != S_OK )
  413. {
  414. // CanInPlaceActivate returned S_FALSE.
  415. return( E_FAIL );
  416. }
  417. pT->m_spInPlaceSite->OnInPlaceActivate();
  418. }/* end of if statement */
  419. }/* end of if statement */
  420. }/* end of if statement */
  421. pT->m_bInPlaceActive = TRUE;
  422. // get location in the parent window,
  423. // as well as some information about the parent
  424. //
  425. OLEINPLACEFRAMEINFO frameInfo;
  426. RECT rcPos, rcClip;
  427. CComPtr<IOleInPlaceFrame> spInPlaceFrame;
  428. CComPtr<IOleInPlaceUIWindow> spInPlaceUIWindow;
  429. frameInfo.cb = sizeof(OLEINPLACEFRAMEINFO);
  430. HWND hwndParent;
  431. // DJ - GetParentHWND per MNnovak
  432. if (SUCCEEDED( GetParentHWND(&hwndParent) )){
  433. pT->m_spInPlaceSite->GetWindowContext(&spInPlaceFrame,
  434. &spInPlaceUIWindow, &rcPos, &rcClip, &frameInfo);
  435. if (!pT->m_bWndLess){
  436. if (pT->m_hWndCD){
  437. ::ShowWindow(pT->m_hWndCD, SW_SHOW);
  438. if (!::IsChild(pT->m_hWndCD, ::GetFocus()))
  439. ::SetFocus(pT->m_hWndCD);
  440. }
  441. else{
  442. HWND h = pT->CreateControlWindow(hwndParent, rcPos);
  443. ATLASSERT(h != NULL); // will assert if creation failed
  444. ATLASSERT(h == pT->m_hWndCD);
  445. h; // avoid unused warning
  446. }/* end of if statement */
  447. }/* end of if statement */
  448. pIPO->SetObjectRects(&rcPos, &rcClip);
  449. }/* end of if statement */
  450. CComPtr<IOleInPlaceActiveObject> spActiveObject;
  451. pT->ControlQueryInterface(IID_IOleInPlaceActiveObject, (void**)&spActiveObject);
  452. // Gone active by now, take care of UIACTIVATE
  453. if (pT->DoesVerbUIActivate(iVerb)){
  454. if (!pT->m_bUIActive){
  455. pT->m_bUIActive = TRUE;
  456. hr = pT->m_spInPlaceSite->OnUIActivate();
  457. if (FAILED(hr))
  458. return hr;
  459. pT->SetControlFocus(TRUE);
  460. // set ourselves up in the host.
  461. //
  462. if (spActiveObject)
  463. {
  464. if (spInPlaceFrame)
  465. spInPlaceFrame->SetActiveObject(spActiveObject, NULL);
  466. if (spInPlaceUIWindow)
  467. spInPlaceUIWindow->SetActiveObject(spActiveObject, NULL);
  468. }
  469. if (spInPlaceFrame)
  470. spInPlaceFrame->SetBorderSpace(NULL);
  471. if (spInPlaceUIWindow)
  472. spInPlaceUIWindow->SetBorderSpace(NULL);
  473. }/* end of if statement */
  474. }/* end of if statement */
  475. pT->m_spClientSite->ShowObject();
  476. return S_OK;
  477. }/* end of function MFInPlaceActivate */
  478. /*************************************************************************/
  479. /* PROTECTED MEMBER FUNCTIONS */
  480. /*************************************************************************/
  481. protected:
  482. /*************************************************************************/
  483. /* Function: MFGetWindow */
  484. /* Description: Gets the window. If we are windowless we pass */
  485. /* down the parent container window, which is really in a sense parent. */
  486. /*************************************************************************/
  487. HWND MFGetWindow(){
  488. HWND hwnd = NULL;
  489. T* pT = static_cast<T*>(this);
  490. if(pT->m_bWndLess){
  491. GetParentHWND(&hwnd);
  492. return(hwnd);
  493. }/* end of if statement */
  494. //ATLASSERT(::IsWindow(m_hWnd));
  495. return pT->m_hWnd;
  496. }/* end of function MFGetWindow */
  497. /*************************************************************************/
  498. /* Function: GetParentHWND */
  499. /* Description: Gets the parent window HWND where we are operating. */
  500. /*************************************************************************/
  501. HRESULT GetParentHWND(HWND* pWnd){
  502. HRESULT hr = S_OK;
  503. T* pT = static_cast<T*>(this);
  504. CComPtr<IOleClientSite> pClientSite;
  505. CComPtr<IOleContainer> pContainer;
  506. CComPtr<IOleObject> pObject;
  507. hr = pT->GetClientSite(&pClientSite);
  508. if(FAILED(hr)){
  509. return(hr);
  510. }/* end of if statement */
  511. IOleWindow *pOleWindow;
  512. do {
  513. hr = pClientSite->QueryInterface(IID_IOleWindow, (LPVOID *) &pOleWindow);
  514. if(FAILED(hr)){
  515. return(hr);
  516. }/* end of if statement */
  517. hr = pOleWindow->GetWindow(pWnd);
  518. // if pClientSite is windowless, go get its container
  519. if (FAILED(hr)) {
  520. HRESULT hrTemp = pClientSite->GetContainer(&pContainer);
  521. if(FAILED(hrTemp)){
  522. return(hrTemp);
  523. }/* end of if statement */
  524. hrTemp = pContainer->QueryInterface(IID_IOleObject, (LPVOID*)&pObject);
  525. if(FAILED(hrTemp)){
  526. return(hrTemp);
  527. }/* end of if statement */
  528. hrTemp = pObject->GetClientSite(&pClientSite);
  529. if(FAILED(hrTemp)){
  530. return(hrTemp);
  531. }/* end of if statement */
  532. }
  533. } while (FAILED(hr));
  534. return(hr);
  535. }/* end of function GetParentHWND */
  536. /*************************************************************************/
  537. /* Function: GetCapture */
  538. /* Description: Gets the capture state. S_FALSE no capture S_OK has */
  539. /* capture. */
  540. /*************************************************************************/
  541. HRESULT GetCapture(){
  542. HRESULT hr = E_UNEXPECTED;
  543. T* pT = static_cast<T*>(this);
  544. if(pT->m_bWndLess){
  545. hr = pT->m_spInPlaceSite->GetCapture();
  546. }
  547. else {
  548. if(NULL == pT->m_hWnd){
  549. hr = E_FAIL;
  550. return(hr);
  551. }/* end of if statement */
  552. if(::IsWindow(pT->m_hWnd)){
  553. HWND h = ::GetCapture();
  554. if(pT->m_hWnd == h){
  555. hr = S_OK;
  556. }
  557. else {
  558. hr = S_FALSE;
  559. }/* end of if statement */
  560. }
  561. else {
  562. hr = E_UNEXPECTED;
  563. }/* end of if statement */
  564. }/* end of if statement */
  565. return(hr);
  566. }/* end of function GetCapture */
  567. /*************************************************************************/
  568. /* Function: GetFocus */
  569. /* Description: Gets the focus state. S_FALSE no capture S_OK has */
  570. /* a focus. */
  571. /*************************************************************************/
  572. HRESULT GetFocus(){
  573. HRESULT hr = E_UNEXPECTED;
  574. T* pT = static_cast<T*>(this);
  575. if(pT->m_bWndLess || m_fNoFocusGrab){
  576. hr = pT->m_spInPlaceSite->GetFocus();
  577. }
  578. else {
  579. if(NULL == pT->m_hWnd){
  580. hr = E_FAIL;
  581. return(hr);
  582. }/* end of if statement */
  583. if(::IsWindow(pT->m_hWnd)){
  584. HWND h = ::GetFocus();
  585. if(pT->m_hWnd == h){
  586. hr = S_OK;
  587. }
  588. else {
  589. hr = S_FALSE;
  590. }/* end of if statement */
  591. }
  592. else {
  593. hr = E_UNEXPECTED;
  594. }/* end of if statement */
  595. }/* end of if statement */
  596. return(hr);
  597. }/* end of function GetFocus */
  598. /*************************************************************************/
  599. /* Function: MFSetFocus */
  600. /* Description: Sets the focus for the keyboard. */
  601. /*************************************************************************/
  602. HRESULT MFSetFocus(bool fFocus){
  603. HRESULT hr = S_OK;
  604. T* pT = static_cast<T*>(this);
  605. if(pT->m_bWndLess || m_fNoFocusGrab){
  606. pT->m_spInPlaceSite->SetFocus(fFocus ? TRUE: FALSE);
  607. }
  608. else {
  609. if(NULL == pT->m_hWnd){
  610. hr = E_FAIL;
  611. return(hr);
  612. }/* end of if statement */
  613. if(::IsWindow(pT->m_hWnd)){
  614. if(fFocus){
  615. ::SetFocus(pT->m_hWnd);
  616. }
  617. else {
  618. }/* end of if statement */
  619. }
  620. else {
  621. hr = E_UNEXPECTED;
  622. }/* end of if statement */
  623. }/* end of if statement */
  624. return(hr);
  625. }/* end of function MFSetFocus */
  626. /*************************************************************************/
  627. /* Function: MFSetCapture */
  628. /* Description: Sets the capture for the mouse. */
  629. /*************************************************************************/
  630. HRESULT MFSetCapture(bool bCapture){
  631. HRESULT hr = S_OK;
  632. T* pT = static_cast<T*>(this);
  633. if(pT->m_bWndLess){
  634. pT->m_spInPlaceSite->SetCapture(bCapture ? TRUE: FALSE);
  635. }
  636. else {
  637. #if 0
  638. if(bCapture){
  639. ATLTRACE("SETTING mouse capture! \n");
  640. }
  641. else {
  642. ATLTRACE("RELEASING mouse capture! \n");
  643. }/* end of if statement */
  644. #endif
  645. if(NULL == pT->m_hWnd){
  646. hr = E_FAIL;
  647. return(hr);
  648. }/* end of if statement */
  649. if(::IsWindow(pT->m_hWnd)){
  650. if(bCapture){
  651. ::SetCapture(pT->m_hWnd);
  652. }
  653. else {
  654. // note this might case problems if multiple ActiveX controls
  655. // in the container have a capture
  656. if(::GetCapture() == pT->m_hWnd){
  657. ::ReleaseCapture();
  658. }/* end of if statement */
  659. }/* end of if statement */
  660. }
  661. else {
  662. hr = E_UNEXPECTED;
  663. }/* end of if statement */
  664. }/* end of if statement */
  665. return(hr);
  666. }/* end of function MFSetCapture */
  667. /*************************************************************************/
  668. /* Function: LoadResourceDLL */
  669. /* Description: The path is relative to this module exe */
  670. /*************************************************************************/
  671. HRESULT LoadResourceDLL(BSTR strResDLLName){
  672. HRESULT hr = E_UNEXPECTED;
  673. if(NULL != m_hRes){
  674. ::FreeLibrary(m_hRes); // unload our resource library if we had some loaded
  675. }/* end of if statement */
  676. #if 0 // use relative path
  677. TCHAR szModule[_MAX_PATH+10];
  678. ::GetModuleFileName(_Module.m_hInstResource, szModule, _MAX_PATH);
  679. *( _tcsrchr( szModule, '\\' ) + 1 ) = TEXT('\0');
  680. // now attempt to load the library, since it is not ActiveX control
  681. USES_CONVERSION;
  682. _tcscat( szModule, OLE2T(strResDLLName));
  683. m_hRes = ::LoadLibrary(szModule);
  684. #else
  685. USES_CONVERSION;
  686. m_hRes = ::LoadLibrary(OLE2T(strResDLLName));
  687. #endif
  688. if (!m_hRes){
  689. hr = HRESULT_FROM_WIN32(::GetLastError());
  690. ATLTRACE(TEXT("Failed to load resource DLL\n"));
  691. }
  692. else {
  693. hr = S_OK;
  694. }/* end of if statement */
  695. return (hr);
  696. }/* end of function LoadResourceDLL */
  697. /*************************************************************/
  698. /* Name: get_ToolTip */
  699. /* Description: create a tool tip for the button */
  700. /*************************************************************/
  701. HRESULT get_MFToolTip(BSTR *pVal){
  702. if (!pVal) {
  703. return E_POINTER;
  704. }
  705. *pVal = m_bstrToolTip.Copy();
  706. return S_OK;
  707. }/* end of function get_ToolTip */
  708. /*************************************************************/
  709. /* Name: put_ToolTip */
  710. /* Description: create a tool tip for the button */
  711. /* Cache the tooltip string if there is no window available */
  712. /*************************************************************/
  713. HRESULT put_MFToolTip(BSTR newVal){
  714. m_bstrToolTip = newVal;
  715. return S_OK;
  716. }
  717. /*************************************************************/
  718. /* Name: get_MFTooltipTracking
  719. /* Description:
  720. /*************************************************************/
  721. HRESULT get_MFTooltipTracking(VARIANT_BOOL *pVal) {
  722. if (!pVal) {
  723. return E_POINTER;
  724. }
  725. *pVal = (m_bTTTracking==FALSE) ? VARIANT_FALSE:VARIANT_TRUE;
  726. return S_OK;
  727. }
  728. /*************************************************************/
  729. /* Name: put_MFTooltipTracking
  730. /* Description:
  731. /*************************************************************/
  732. HRESULT put_MFTooltipTracking(VARIANT_BOOL newVal) {
  733. BOOL bTemp = (newVal==VARIANT_FALSE) ? FALSE:TRUE;
  734. if (m_bTTTracking != bTemp) {
  735. m_bTTTracking = bTemp;
  736. ::DestroyWindow(m_hWndTip);
  737. m_hWndTip = NULL;
  738. }
  739. m_bTrackingActivated = FALSE;
  740. return S_OK;
  741. }
  742. /*************************************************************/
  743. /* Name: CreateToolTip
  744. /* Description: create a tool tip for the button
  745. /*************************************************************/
  746. HRESULT CreateToolTip(HWND parentWnd, RECT rc){
  747. HWND hwnd = MFGetWindow();
  748. if (!hwnd) return S_FALSE;
  749. if (m_bstrToolTip.Length() == 0)
  750. return S_FALSE;
  751. USES_CONVERSION;
  752. TOOLINFO ti; // tool information
  753. ti.cbSize = sizeof(TOOLINFO);
  754. ti.hwnd = hwnd;
  755. ti.hinst = _Module.GetModuleInstance();
  756. ti.lpszText = OLE2T(m_bstrToolTip);
  757. // if the button is a windowed control, the tool tip is added to
  758. // the button's own window, and the tool tip area should just be
  759. // the client rect of the window
  760. if (hwnd == parentWnd) {
  761. ::GetClientRect(hwnd, &ti.rect);
  762. ti.uId = (WPARAM) hwnd;
  763. ti.uFlags = TTF_IDISHWND;
  764. }
  765. // otherwise the tool tip is added to the closet windowed parent of
  766. // the button, and the tool tip area should be the relative postion
  767. // of the button in the parent window
  768. else {
  769. ti.rect.left = rc.left;
  770. ti.rect.top = rc.top;
  771. ti.rect.right = rc.right;
  772. ti.rect.bottom = rc.bottom;
  773. ti.uId = (UINT) 0;
  774. ti.uFlags = 0;
  775. }
  776. if (m_bTTTracking)
  777. ti.uFlags |= TTF_TRACK;
  778. // If tool tip is to be created for the first time
  779. if (m_hWndTip == (HWND) NULL) {
  780. // Ensure that the common control DLL is loaded, and create
  781. // a tooltip control.
  782. InitCommonControls();
  783. m_hWndTip = CreateWindow(TOOLTIPS_CLASS, (LPCTSTR) NULL, TTS_ALWAYSTIP,
  784. CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
  785. hwnd, (HMENU) NULL, _Module.GetModuleInstance(), NULL);
  786. ATLTRACE(TEXT("Tooltip %s CreateWindow\n"), OLE2T(m_bstrToolTip));
  787. if (m_hWndTip == (HWND) NULL)
  788. return S_FALSE;
  789. if (!::SendMessage(m_hWndTip, TTM_ADDTOOL, 0, (LPARAM)&ti)) {
  790. ::DestroyWindow(m_hWndTip);
  791. m_hWndTip = NULL;
  792. return S_FALSE;
  793. }
  794. }
  795. else {
  796. ::SendMessage(m_hWndTip, TTM_UPDATETIPTEXT, 0, (LPARAM)&ti);
  797. }
  798. // Save the tooltip info
  799. m_toolInfo = ti;
  800. // Set initial delay time
  801. put_MFToolTipMaxWidth(m_nTTMaxWidth);
  802. MFSetDelayTime(TTDT_AUTOPOP, m_dwTTAutopopDelay);
  803. MFSetDelayTime(TTDT_INITIAL, m_dwTTInitalDelay);
  804. MFSetDelayTime(TTDT_RESHOW, m_dwTTReshowDelay);
  805. return S_OK;
  806. }/* end of function CreateToolTip */
  807. /*************************************************************/
  808. /* Name: GetDelayTime
  809. /* Description: Get the length of time a pointer must remain
  810. /* stationary within a tool's bounding rectangle before the
  811. /* tooltip window appears
  812. /* delayTypes: TTDT_RESHOW 1
  813. /* TTDT_AUTOPOP 2
  814. /* TTDT_INITIAL 3
  815. /*************************************************************/
  816. HRESULT MFGetDelayTime(long delayType, long *pVal){
  817. if (!pVal) {
  818. return E_POINTER;
  819. }
  820. if (delayType>TTDT_INITIAL || delayType<TTDT_RESHOW) {
  821. return E_INVALIDARG;
  822. }
  823. // If tooltip has been created
  824. if (m_hWndTip) {
  825. *pVal = (long)::SendMessage(m_hWndTip, TTM_GETDELAYTIME,
  826. (WPARAM) (DWORD) delayType, 0);
  827. }
  828. // else return cached values
  829. else {
  830. switch (delayType) {
  831. case TTDT_AUTOPOP:
  832. *pVal = m_dwTTAutopopDelay;
  833. break;
  834. case TTDT_INITIAL:
  835. *pVal = m_dwTTInitalDelay;
  836. break;
  837. case TTDT_RESHOW:
  838. *pVal = m_dwTTReshowDelay;
  839. break;
  840. }
  841. }
  842. return S_OK;
  843. }/* end of function GetDelayTime */
  844. /*************************************************************/
  845. /* Name: SetDelayTime
  846. /* Description: Set the length of time a pointer must remain
  847. /* stationary within a tool's bounding rectangle before the
  848. /* tooltip window appears
  849. /* delayTypes: TTDT_AUTOMATIC 0
  850. /* TTDT_RESHOW 1
  851. /* TTDT_AUTOPOP 2
  852. /* TTDT_INITIAL 3
  853. /*************************************************************/
  854. HRESULT MFSetDelayTime(long delayType, long newVal){
  855. if (delayType>TTDT_INITIAL || delayType<TTDT_AUTOMATIC || newVal<0) {
  856. return E_INVALIDARG;
  857. }
  858. if (m_hWndTip) {
  859. if (!::SendMessage(m_hWndTip, TTM_SETDELAYTIME,
  860. (WPARAM) (DWORD) delayType,
  861. (LPARAM) (INT) newVal))
  862. return S_FALSE;
  863. }
  864. // cache these values
  865. switch (delayType) {
  866. case TTDT_AUTOPOP:
  867. m_dwTTAutopopDelay = newVal;
  868. break;
  869. case TTDT_INITIAL:
  870. m_dwTTInitalDelay = newVal;
  871. break;
  872. case TTDT_RESHOW:
  873. m_dwTTReshowDelay = newVal;
  874. break;
  875. case TTDT_AUTOMATIC:
  876. m_dwTTInitalDelay = newVal;
  877. m_dwTTAutopopDelay = newVal*10;
  878. m_dwTTReshowDelay = newVal/5;
  879. break;
  880. }
  881. return S_OK;
  882. }/* end of function SetDelayTime */
  883. /*************************************************************************/
  884. /* Function: get_ToolTipMaxWidth */
  885. /*************************************************************************/
  886. HRESULT get_MFToolTipMaxWidth(long *pVal){
  887. if (!pVal) {
  888. return E_POINTER;
  889. }
  890. if (m_hWndTip){
  891. *pVal = (long)::SendMessage(m_hWndTip, TTM_GETMAXTIPWIDTH, 0, 0);
  892. }/* end of if statement */
  893. return S_OK;
  894. }/* end of function get_ToolTipMaxWidth */
  895. /*************************************************************************/
  896. /* Function: put_ToolTipMaxWidth */
  897. /*************************************************************************/
  898. HRESULT put_MFToolTipMaxWidth(long newVal){
  899. if (newVal<0) {
  900. return E_INVALIDARG;
  901. }
  902. m_nTTMaxWidth = newVal;
  903. if (m_hWndTip){
  904. ::SendMessage(m_hWndTip, TTM_SETMAXTIPWIDTH, 0, (LPARAM)(INT) newVal);
  905. }/* end of if statement */
  906. return S_OK;
  907. }/* end of function put_ToolTipMaxWidth */
  908. /*************************************************************/
  909. /* Name: UpdateTooltipRect
  910. /* Description:
  911. /*************************************************************/
  912. HRESULT UpdateTooltipRect(LPCRECT prcPos) {
  913. if (!m_hWndTip) return S_OK;
  914. HWND hwnd = MFGetWindow();
  915. if (!hwnd) return S_FALSE;
  916. m_toolInfo.rect = *prcPos; // new tooltip position
  917. if (!::SendMessage(m_hWndTip, TTM_NEWTOOLRECT, 0,
  918. (LPARAM) (LPTOOLINFO) &m_toolInfo))
  919. return S_FALSE;
  920. return S_OK;
  921. } /* end of function UpdateTooltipRect */
  922. /*************************************************************************/
  923. /* Function: MFOnMouseToolTip */
  924. /* Description: Check if we were captured/pushed the do not do much, */
  925. /* otherwise do the hit detection and see if we are in static or hower */
  926. /* state. */
  927. /*************************************************************************/
  928. LRESULT MFOnMouseToolTip(UINT msg, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
  929. #define X_OFFSET 15
  930. #define Y_OFFSET X_OFFSET
  931. MSG mssg;
  932. mssg.hwnd = MFGetWindow();
  933. ATLASSERT(mssg.hwnd);
  934. mssg.message = msg;
  935. mssg.wParam = wParam;
  936. mssg.lParam = lParam;
  937. POINT pt;
  938. ::GetCursorPos(&pt);
  939. mssg.pt.x = pt.x;
  940. mssg.pt.y = pt.y;
  941. if (m_hWndTip)
  942. ::SendMessage(m_hWndTip, TTM_RELAYEVENT, 0, (LPARAM)&mssg);
  943. RECT rc = m_toolInfo.rect;
  944. ::MapWindowPoints(m_toolInfo.hwnd, ::GetDesktopWindow(), (LPPOINT)&rc, 2);
  945. if (::PtInRect(&rc, pt)) {
  946. if (m_hWndTip) {
  947. if (m_bTTTracking) {
  948. ::SendMessage(m_hWndTip, TTM_TRACKPOSITION, 0, (LPARAM)MAKELPARAM(X_OFFSET+pt.x, Y_OFFSET+pt.y));
  949. // Activate tracking if not yet
  950. if (!m_bTrackingActivated) {
  951. ::SendMessage(m_hWndTip, TTM_TRACKACTIVATE, TRUE, (LPARAM)&m_toolInfo);
  952. m_bTrackingActivated = TRUE;
  953. }
  954. }
  955. }
  956. }
  957. bHandled = FALSE;
  958. return 0;
  959. }/* end of function MFOnMouseToolTip */
  960. // variables
  961. protected:
  962. HINSTANCE m_hRes;
  963. HCURSOR m_hCursor;
  964. CComBSTR m_strResDLL;
  965. TransparentBlitType m_blitType;
  966. bool m_fNoFocusGrab; // disable grabbing focus for windowed controls
  967. HWND m_hWndTip; // Tooltip window
  968. TOOLINFO m_toolInfo; // Tooltip info
  969. LONG m_nTTMaxWidth; // Max tooltip width
  970. CComBSTR m_bstrToolTip; // Tooltip string
  971. BOOL m_bTTTracking; // Tracking or not
  972. BOOL m_bTrackingActivated; // Tracking activated or not
  973. DWORD m_dwTTReshowDelay;
  974. DWORD m_dwTTAutopopDelay;
  975. DWORD m_dwTTInitalDelay;
  976. };
  977. #endif //__MSMFCSTUTILS_H_
  978. /*************************************************************************/
  979. /* End of file: CstUtils.h */
  980. /*************************************************************************/