|
|
/*************************************************************************/ /* Copyright (C) 1999 Microsoft Corporation */ /* File: CstUtils.h */ /* Description: Utilities that we can share across mutliple modules. */ /* Author: David Janecek */ /*************************************************************************/ #ifndef __MSMFCSTUTILS_H_
#define __MSMFCSTUTILS_H_
#include <commctrl.h>
#ifdef _WMP
#include "wmp.h" // for wmp integration
#endif
const bool gcfGrayOut = false;
#define WM_USER_FOCUS (WM_USER + 0x10)
#define WM_USER_ENDHELP (WM_USER + 0x11)
#define OCR_ARROW_DEFAULT 100
#define USE_MF_OVERWRITES \
HRESULT InvalidateRgn(bool fErase = false){return MFInvalidateRgn(fErase);} \ HRESULT FireViewChange(){return MFFireViewChange();} \ HRESULT InPlaceActivate(LONG iVerb, const RECT* prcPosRect){return MFInPlaceActivate(iVerb, prcPosRect);} \ HRESULT SetCapture(bool bCapture){return MFSetCapture(bCapture);} \ HRESULT SetFocus(bool bFocus){return MFSetFocus(bFocus);} \ HWND GetWindow(){return MFGetWindow();} \ HRESULT ForwardWindowMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, LONG& lRes,\ bool fForwardInWndls = false){return MFForwardWindowMessage(uMsg, wParam, lParam, lRes, \ fForwardInWndls);}
#define USE_MF_RESOURCEDLL \
STDMETHOD(get_ResourceDLL)(/*[out, retval]*/ BSTR *pVal){return get_MFResourceDLL(pVal);} \ STDMETHOD(put_ResourceDLL)(/*[in]*/ BSTR newVal){return put_MFResourceDLL(newVal);}
#define USE_MF_WINDOWLESS_ACTIVATION \
STDMETHOD(get_Windowless)(VARIANT_BOOL *pVal){return get_MFWindowless(pVal);} \ STDMETHOD(put_Windowless)(VARIANT_BOOL newVal){return put_MFWindowless(newVal);}
#define USE_MF_TRANSPARENT_FLAG \
STDMETHOD(get_TransparentBlit)(TransparentBlitType *pVal){return get_MFTransparentBlit(pVal);}\ STDMETHOD(put_TransparentBlit)(TransparentBlitType newVal){return put_MFTransparentBlit(newVal);}
#define USE_MF_CLASSSTYLE \
static CWndClassInfo& GetWndClassInfo(){ \ static HBRUSH wcBrush = ::CreateSolidBrush(RGB(0,0,0)); \ static CWndClassInfo wc = {{ sizeof(WNDCLASSEX), 0 /*CS_OWNDC*/, StartWindowProc, \ 0, 0, NULL, NULL, NULL, wcBrush /* (HBRUSH)(COLOR_WINDOW + 1) */, \ NULL, TEXT("MSMFCtlClass"), NULL }, \ NULL, NULL, MAKEINTRESOURCE(OCR_ARROW_DEFAULT), TRUE, 0, _T("") }; \ return wc; \ }/* end of function GetWndClassInfo */
#define USE_MF_TOOLTIP \
STDMETHOD(GetDelayTime)(long delayType, long *pVal) {return MFGetDelayTime(delayType, pVal); } \ STDMETHOD(SetDelayTime)(long delayType, long newVal){return MFSetDelayTime(delayType, newVal); } \ STDMETHOD(get_ToolTip)(BSTR *pVal) {return get_MFToolTip(pVal); } \ STDMETHOD(put_ToolTip)(BSTR newVal) {put_MFToolTip(newVal); return CreateToolTip(m_hWnd, m_rcPos);} \ STDMETHOD(get_ToolTipMaxWidth)(long *pVal) {return get_MFToolTipMaxWidth(pVal); } \ STDMETHOD(put_ToolTipMaxWidth)(long newVal){return put_MFToolTipMaxWidth(newVal); } \ STDMETHOD(get_ToolTipTracking)(VARIANT_BOOL *pVal) {return get_MFTooltipTracking(pVal); } \ STDMETHOD(put_ToolTipTracking)(VARIANT_BOOL newVal) {put_MFTooltipTracking(newVal); return CreateToolTip(m_hWnd, m_rcPos);} \ HRESULT OnPostVerbInPlaceActivate() { \ /* Return if tooltip is already created */ \ if (m_hWndTip) return S_OK; \ return CreateToolTip(m_hWnd, m_rcPos); \ } \
/*************************************************************************/ /* Defines */ /* Could not find these under windows headers, so if there is a conflict */ /* it is good idea to ifdef these out. */ /*************************************************************************/ #define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
#define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
template <class T> class ATL_NO_VTABLE CMSMFCntrlUtils{
/*************************************************************************/ /* PUBLIC MEMBER FUNCTIONS */ /*************************************************************************/ public:
/*************************************************************************/ /* Function: CMSMFCntrlUtils */ /*************************************************************************/ CMSMFCntrlUtils(){
m_hRes = NULL; m_blitType = TRANSPARENT_TOP_LEFT; // DISABLE used to be the correct default TODO
m_fNoFocusGrab = true; // to enable standalone "windowed" focus handeling please
// make this flag a property
m_hCursor = ::LoadCursor(NULL, MAKEINTRESOURCE(OCR_ARROW_DEFAULT));
m_hWndTip = NULL; m_nTTMaxWidth = 200; m_bTTTracking = FALSE; m_bTrackingActivated = FALSE; m_dwTTInitalDelay = 10; m_dwTTReshowDelay = 2; m_dwTTAutopopDelay = 10000; ::ZeroMemory(&m_toolInfo, sizeof(TOOLINFO));
}/* end of function CMSMFCntrlUtils */
/*************************************************************************/ /* Function: ~CMSMFCntrlUtils */ /*************************************************************************/ virtual ~CMSMFCntrlUtils(){
if (m_hCursor != NULL) {
::DestroyCursor(m_hCursor); m_hCursor = NULL; }/* end of if statement */
if(NULL != m_hRes){
::FreeLibrary(m_hRes); // unload our resource library
m_hRes = NULL; }/* end of if statement */ }/* end of function ~CMSMFCntrlUtils */
/*************************************************************************/ /* Message Map */ /*************************************************************************/ typedef CMSMFCntrlUtils< T > thisClass;
BEGIN_MSG_MAP(thisClass) MESSAGE_HANDLER(WM_ERASEBKGND, CMSMFCntrlUtils::MFOnErase) MESSAGE_HANDLER(WM_SETCURSOR, CMSMFCntrlUtils::MFOnSetCursor) MESSAGE_HANDLER(WM_QUERYNEWPALETTE, CMSMFCntrlUtils::MFOnQueryNewPalette) MESSAGE_HANDLER(WM_PALETTECHANGED, CMSMFCntrlUtils::MFOnPaletteChanged) MESSAGE_RANGE_HANDLER(WM_MOUSEFIRST, WM_MOUSELAST, CMSMFCntrlUtils::MFOnMouseToolTip) END_MSG_MAP()
/*************************************************************************/ /* Function: MFOnErase */ /* Description: Avoids erasing backround to avoid flashing. */ /*************************************************************************/ LRESULT MFOnErase(UINT, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
bHandled = TRUE; return 0; }/* end of function MFOnErase */
/*************************************************************************/ /* Function: MFOnSetCursor */ /* Description: Sets our cursor. */ /*************************************************************************/ LRESULT MFOnSetCursor(UINT, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
bHandled = TRUE; ::SetCursor(m_hCursor); return(TRUE); }/* end of function MFOnSetCursor */
/*************************************************************************/ /* Function: MFOnQueryNewPalette */ /* Description: Called when we are about to be instantiated. */ /*************************************************************************/ LRESULT MFOnQueryNewPalette(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
T* pT = static_cast<T*>(this);
if(NULL == ::IsWindow(pT->m_hWnd)){
bHandled = FALSE; return FALSE; }/* end of if statement */
HPALETTE hPal = CBitmap::GetSuperPal(); if(NULL == hPal){
//bHandled = FALSE;
return FALSE; }/* end of if statement */
HDC hdc = ::GetDC(pT->m_hWnd);
if(NULL == hdc){
return FALSE; }/* end of if statement */
::SelectPalette(hdc, hPal, FALSE); ::RealizePalette(hdc); ::InvalidateRect(pT->m_hWnd, NULL, FALSE);
::ReleaseDC(pT->m_hWnd, hdc); return TRUE; }/* end of function MFOnQueryNewPalette */
/*************************************************************************/ /* Function: MFOnPaletteChanged */ /* Description: Called when palette is chaning. */ /*************************************************************************/ LRESULT MFOnPaletteChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
T* pT = static_cast<T*>(this);
if(NULL == ::IsWindow(pT->m_hWnd)){
bHandled = FALSE; return FALSE; }/* end of if statement */
if((HWND) wParam == pT->m_hWnd){
bHandled = FALSE; return FALSE; }/* end of if statement */
HPALETTE hPal = CBitmap::GetSuperPal();
if(NULL == hPal){
bHandled = FALSE; return FALSE; }/* end of if statement */
HDC hdc = ::GetDC(pT->m_hWnd);
if(NULL == hdc){
return FALSE; }/* end of if statement */
::SelectPalette(hdc, hPal, FALSE); ::RealizePalette(hdc); ::UpdateColors(hdc);
::InvalidateRect(pT->m_hWnd, NULL, FALSE); ::ReleaseDC(pT->m_hWnd, hdc);
bHandled = FALSE; return TRUE; }/* end of function MFOnPaletteChanged */
/*************************************************************************/ /* Function: get_MFResourceDLL */ /* Description: Returns the string of the loaded resource DLL. */ /*************************************************************************/ STDMETHOD(get_MFResourceDLL)(BSTR *pVal){
*pVal = m_strResDLL.Copy(); return S_OK; }/* end of function get_MFResourceDLL */
/*************************************************************************/ /* Function: put_MFResourceDLL */ /* Description: Loads the resource DLL. */ /*************************************************************************/ STDMETHOD(put_MFResourceDLL)(BSTR strFileName){
HRESULT hr = LoadResourceDLL(strFileName);
// see if we loaded it
if(FAILED(hr)){
return(hr); }/* end of if statement */
// update the cached variable value
m_strResDLL = strFileName;
return(hr); }/* end of function put_MFResourceDLL */
/*************************************************************************/ /* Function: get_MFWindowless */ /* Description: Gets if we we tried to be windowless activated or not. */ /*************************************************************************/ HRESULT get_MFWindowless(VARIANT_BOOL *pVal){
HRESULT hr = S_OK;
try { T* pT = static_cast<T*>(this);
if(NULL == pVal){
throw(E_POINTER); }/* end of if statement */
*pVal = pT->m_bWindowOnly == FALSE ? VARIANT_FALSE: VARIANT_TRUE; }/* end of try statement */ catch(HRESULT hrTmp){ hr = hrTmp; }/* end of catch statement */ catch(...){ hr = E_UNEXPECTED; }/* end of catch statement */
return(hr); }/* end of function get_MFWindowless */
/*************************************************************************/ /* Function: put_MFWindowless */ /* Description: This sets the windowless mode, should be set from the */ /* property bag. */ /*************************************************************************/ HRESULT put_MFWindowless(VARIANT_BOOL newVal){
HRESULT hr = S_OK;
try { T* pT = static_cast<T*>(this);
if(VARIANT_FALSE == newVal){
pT->m_bWindowOnly = TRUE; } else {
pT->m_bWindowOnly = FALSE; }/* end of if statement */
// TODO: This function should fail after we inplace activated !!
}/* end of try statement */ catch(HRESULT hrTmp){ hr = hrTmp; }/* end of catch statement */ catch(...){ hr = E_UNEXPECTED; }/* end of catch statement */
return(hr); }/* end of function put_MFWindowless */
/*************************************************************************/ /* Function: get_MFTransparentBlit */ /* Description: Gets current state of the transperent blit. */ /*************************************************************************/ HRESULT get_MFTransparentBlit(TransparentBlitType *pVal){
HRESULT hr = S_OK;
try { T* pT = static_cast<T*>(this);
*pVal = pT->m_blitType; } catch(HRESULT hrTmp){ hr = hrTmp; }/* end of catch statement */ catch(...){ hr = E_UNEXPECTED; }/* end of catch statement */
return(hr); }/* end of function get_MFTransparentBlit */
/*************************************************************************/ /* Function: put_MFTransparentBlit */ /* Description: Sets the state of the transperent blit. */ /*************************************************************************/ HRESULT put_MFTransparentBlit(TransparentBlitType newVal){
HRESULT hr = S_OK;
try { T* pT = static_cast<T*>(this);
pT->m_blitType = newVal; } catch(HRESULT hrTmp){ hr = hrTmp; }/* end of catch statement */ catch(...){ hr = E_UNEXPECTED; }/* end of catch statement */
return(hr); }/* end of function put_MFTransparentBlit */
/*************************************************************************/ /* Function: MFInvalidateRgn */ /* Description: Invalidates the whole rect in case we need to repaint it.*/ /*************************************************************************/ HRESULT MFInvalidateRgn(bool fErase = false){
HRESULT hr = S_OK;
T* pT = static_cast<T*>(this);
if(pT->m_bWndLess){
pT->m_spInPlaceSite->InvalidateRgn(NULL ,fErase ? TRUE: FALSE); } else { if(NULL == pT->m_hWnd){
hr = E_FAIL; return(hr); }/* end of if statement */
if(::IsWindow(pT->m_hWnd)){
::InvalidateRgn(pT->m_hWnd, NULL, fErase ? TRUE: FALSE); // see if we can get by by not erasing..
} else { hr = E_UNEXPECTED; }/* end of if statement */
}/* end of if statement */
return(hr); }/* end of function MFInvalidateRgn */
/*************************************************************************/ /* Function: MFFireViewChange */ /* Description: Overloaded base function, which would try to repaint the */ /* whole container. Just like to repaint the control area instead. */ /*************************************************************************/ inline HRESULT MFFireViewChange(){ // same as FireView change but optimized
T* pT = static_cast<T*>(this);
if (pT->m_bInPlaceActive){ // Active
if (pT->m_hWndCD != NULL){
::InvalidateRect(pT->m_hWndCD, NULL, FALSE); // Window based
} else if (pT->m_spInPlaceSite != NULL){
pT->m_spInPlaceSite->InvalidateRect(&pT->m_rcPos, FALSE); // Do not invalidate the whole container
}/* end of if statement */ } else {// Inactive
pT->SendOnViewChange(DVASPECT_CONTENT); }/* end of if statement */
return S_OK; }/* end of function MFFireViewChange */
/*************************************************************************/ /* Function: MFForwardWindowMessage */ /* Description: Forward the message to the parent window. */ /*************************************************************************/ HRESULT MFForwardWindowMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, LONG& lRes, bool fForwardInWndls = false){
HRESULT hr = S_OK; T* pT = static_cast<T*>(this); lRes = 0;
if(false == fForwardInWndls){
if(pT->m_bWndLess || (!::IsWindow(pT->m_hWnd))){
hr = S_FALSE; return (hr); }/* end of if statement */
}/* end of if statement */
HWND hwnd = NULL;
hr = GetParentHWND(&hwnd);
if(FAILED(hr)){
return(hr); }/* end of if statement */
lRes = (LONG)::SendMessage(hwnd, uMsg, wParam, lParam);
return(hr); }/* end of function MFForwardWindowMessage */
/*************************************************************************/ /* Function: InPlaceActivate */ /* Description: Modified InPlaceActivate so WMP can startup. */ /*************************************************************************/ HRESULT MFInPlaceActivate(LONG iVerb, const RECT* /*prcPosRect*/){
HRESULT hr; T* pT = static_cast<T*>(this);
if (pT->m_spClientSite == NULL){
return S_OK; }/* end of if statement */
CComPtr<IOleInPlaceObject> pIPO; pT->ControlQueryInterface(IID_IOleInPlaceObject, (void**)&pIPO); ATLASSERT(pIPO != NULL);
if (!pT->m_bNegotiatedWnd){
if (!pT->m_bWindowOnly) // Try for windowless site
hr = pT->m_spClientSite->QueryInterface(IID_IOleInPlaceSiteWindowless, (void **)&pT->m_spInPlaceSite);
if (pT->m_spInPlaceSite){
pT->m_bInPlaceSiteEx = TRUE; // CanWindowlessActivate returns S_OK or S_FALSE
if ( pT->m_spInPlaceSite->CanWindowlessActivate() == S_OK ){
pT->m_bWndLess = TRUE; pT->m_bWasOnceWindowless = TRUE; } else { pT->m_bWndLess = FALSE; }/* end of if statement */ } else { pT->m_spClientSite->QueryInterface(IID_IOleInPlaceSiteEx, (void **)&pT->m_spInPlaceSite); if (pT->m_spInPlaceSite) pT->m_bInPlaceSiteEx = TRUE; else hr = pT->m_spClientSite->QueryInterface(IID_IOleInPlaceSite, (void **)&pT->m_spInPlaceSite); }/* end of if statement */ }/* end of if statement */
ATLASSERT(pT->m_spInPlaceSite); if (!pT->m_spInPlaceSite) return E_FAIL;
pT->m_bNegotiatedWnd = TRUE;
if (!pT->m_bInPlaceActive){
BOOL bNoRedraw = FALSE; if (pT->m_bWndLess) pT->m_spInPlaceSite->OnInPlaceActivateEx(&bNoRedraw, ACTIVATE_WINDOWLESS); else {
if (pT->m_bInPlaceSiteEx) pT->m_spInPlaceSite->OnInPlaceActivateEx(&bNoRedraw, 0); else { hr = pT->m_spInPlaceSite->CanInPlaceActivate(); // CanInPlaceActivate returns S_FALSE or S_OK
if (FAILED(hr)) return hr; if ( hr != S_OK ) { // CanInPlaceActivate returned S_FALSE.
return( E_FAIL ); } pT->m_spInPlaceSite->OnInPlaceActivate(); }/* end of if statement */ }/* end of if statement */ }/* end of if statement */
pT->m_bInPlaceActive = TRUE;
// get location in the parent window,
// as well as some information about the parent
//
OLEINPLACEFRAMEINFO frameInfo; RECT rcPos, rcClip; CComPtr<IOleInPlaceFrame> spInPlaceFrame; CComPtr<IOleInPlaceUIWindow> spInPlaceUIWindow; frameInfo.cb = sizeof(OLEINPLACEFRAMEINFO); HWND hwndParent;
// DJ - GetParentHWND per MNnovak
if (SUCCEEDED( GetParentHWND(&hwndParent) )){
pT->m_spInPlaceSite->GetWindowContext(&spInPlaceFrame, &spInPlaceUIWindow, &rcPos, &rcClip, &frameInfo);
if (!pT->m_bWndLess){
if (pT->m_hWndCD){
::ShowWindow(pT->m_hWndCD, SW_SHOW); if (!::IsChild(pT->m_hWndCD, ::GetFocus())) ::SetFocus(pT->m_hWndCD); } else{
HWND h = pT->CreateControlWindow(hwndParent, rcPos); ATLASSERT(h != NULL); // will assert if creation failed
ATLASSERT(h == pT->m_hWndCD); h; // avoid unused warning
}/* end of if statement */ }/* end of if statement */
pIPO->SetObjectRects(&rcPos, &rcClip); }/* end of if statement */
CComPtr<IOleInPlaceActiveObject> spActiveObject; pT->ControlQueryInterface(IID_IOleInPlaceActiveObject, (void**)&spActiveObject);
// Gone active by now, take care of UIACTIVATE
if (pT->DoesVerbUIActivate(iVerb)){
if (!pT->m_bUIActive){
pT->m_bUIActive = TRUE; hr = pT->m_spInPlaceSite->OnUIActivate(); if (FAILED(hr)) return hr;
pT->SetControlFocus(TRUE); // set ourselves up in the host.
//
if (spActiveObject) { if (spInPlaceFrame) spInPlaceFrame->SetActiveObject(spActiveObject, NULL); if (spInPlaceUIWindow) spInPlaceUIWindow->SetActiveObject(spActiveObject, NULL); }
if (spInPlaceFrame) spInPlaceFrame->SetBorderSpace(NULL); if (spInPlaceUIWindow) spInPlaceUIWindow->SetBorderSpace(NULL); }/* end of if statement */ }/* end of if statement */
pT->m_spClientSite->ShowObject();
return S_OK; }/* end of function MFInPlaceActivate */
/*************************************************************************/ /* PROTECTED MEMBER FUNCTIONS */ /*************************************************************************/ protected:
/*************************************************************************/ /* Function: MFGetWindow */ /* Description: Gets the window. If we are windowless we pass */ /* down the parent container window, which is really in a sense parent. */ /*************************************************************************/ HWND MFGetWindow(){
HWND hwnd = NULL;
T* pT = static_cast<T*>(this);
if(pT->m_bWndLess){
GetParentHWND(&hwnd); return(hwnd); }/* end of if statement */
//ATLASSERT(::IsWindow(m_hWnd));
return pT->m_hWnd; }/* end of function MFGetWindow */
/*************************************************************************/ /* Function: GetParentHWND */ /* Description: Gets the parent window HWND where we are operating. */ /*************************************************************************/ HRESULT GetParentHWND(HWND* pWnd){
HRESULT hr = S_OK;
T* pT = static_cast<T*>(this);
CComPtr<IOleClientSite> pClientSite; CComPtr<IOleContainer> pContainer; CComPtr<IOleObject> pObject;
hr = pT->GetClientSite(&pClientSite);
if(FAILED(hr)){
return(hr); }/* end of if statement */
IOleWindow *pOleWindow; do { hr = pClientSite->QueryInterface(IID_IOleWindow, (LPVOID *) &pOleWindow); if(FAILED(hr)){ return(hr); }/* end of if statement */ hr = pOleWindow->GetWindow(pWnd); // if pClientSite is windowless, go get its container
if (FAILED(hr)) { HRESULT hrTemp = pClientSite->GetContainer(&pContainer); if(FAILED(hrTemp)){ return(hrTemp); }/* end of if statement */ hrTemp = pContainer->QueryInterface(IID_IOleObject, (LPVOID*)&pObject); if(FAILED(hrTemp)){ return(hrTemp); }/* end of if statement */ hrTemp = pObject->GetClientSite(&pClientSite); if(FAILED(hrTemp)){ return(hrTemp); }/* end of if statement */ } } while (FAILED(hr)); return(hr); }/* end of function GetParentHWND */
/*************************************************************************/ /* Function: GetCapture */ /* Description: Gets the capture state. S_FALSE no capture S_OK has */ /* capture. */ /*************************************************************************/ HRESULT GetCapture(){
HRESULT hr = E_UNEXPECTED;
T* pT = static_cast<T*>(this);
if(pT->m_bWndLess){
hr = pT->m_spInPlaceSite->GetCapture(); } else { if(NULL == pT->m_hWnd){
hr = E_FAIL; return(hr); }/* end of if statement */
if(::IsWindow(pT->m_hWnd)){
HWND h = ::GetCapture();
if(pT->m_hWnd == h){
hr = S_OK; } else {
hr = S_FALSE; }/* end of if statement */ } else { hr = E_UNEXPECTED; }/* end of if statement */
}/* end of if statement */
return(hr); }/* end of function GetCapture */
/*************************************************************************/ /* Function: GetFocus */ /* Description: Gets the focus state. S_FALSE no capture S_OK has */ /* a focus. */ /*************************************************************************/ HRESULT GetFocus(){
HRESULT hr = E_UNEXPECTED;
T* pT = static_cast<T*>(this);
if(pT->m_bWndLess || m_fNoFocusGrab){
hr = pT->m_spInPlaceSite->GetFocus(); } else { if(NULL == pT->m_hWnd){
hr = E_FAIL; return(hr); }/* end of if statement */
if(::IsWindow(pT->m_hWnd)){
HWND h = ::GetFocus();
if(pT->m_hWnd == h){
hr = S_OK; } else {
hr = S_FALSE; }/* end of if statement */ } else { hr = E_UNEXPECTED; }/* end of if statement */
}/* end of if statement */
return(hr); }/* end of function GetFocus */
/*************************************************************************/ /* Function: MFSetFocus */ /* Description: Sets the focus for the keyboard. */ /*************************************************************************/ HRESULT MFSetFocus(bool fFocus){ HRESULT hr = S_OK;
T* pT = static_cast<T*>(this);
if(pT->m_bWndLess || m_fNoFocusGrab){
pT->m_spInPlaceSite->SetFocus(fFocus ? TRUE: FALSE); } else { if(NULL == pT->m_hWnd){
hr = E_FAIL; return(hr); }/* end of if statement */
if(::IsWindow(pT->m_hWnd)){
if(fFocus){
::SetFocus(pT->m_hWnd); } else { }/* end of if statement */ } else { hr = E_UNEXPECTED; }/* end of if statement */
}/* end of if statement */
return(hr); }/* end of function MFSetFocus */
/*************************************************************************/ /* Function: MFSetCapture */ /* Description: Sets the capture for the mouse. */ /*************************************************************************/ HRESULT MFSetCapture(bool bCapture){ HRESULT hr = S_OK;
T* pT = static_cast<T*>(this);
if(pT->m_bWndLess){
pT->m_spInPlaceSite->SetCapture(bCapture ? TRUE: FALSE); } else {
#if 0
if(bCapture){
ATLTRACE("SETTING mouse capture! \n"); } else {
ATLTRACE("RELEASING mouse capture! \n"); }/* end of if statement */
#endif
if(NULL == pT->m_hWnd){
hr = E_FAIL; return(hr); }/* end of if statement */
if(::IsWindow(pT->m_hWnd)){
if(bCapture){
::SetCapture(pT->m_hWnd); } else { // note this might case problems if multiple ActiveX controls
// in the container have a capture
if(::GetCapture() == pT->m_hWnd){
::ReleaseCapture(); }/* end of if statement */ }/* end of if statement */ } else { hr = E_UNEXPECTED; }/* end of if statement */
}/* end of if statement */
return(hr); }/* end of function MFSetCapture */
/*************************************************************************/ /* Function: LoadResourceDLL */ /* Description: The path is relative to this module exe */ /*************************************************************************/ HRESULT LoadResourceDLL(BSTR strResDLLName){ HRESULT hr = E_UNEXPECTED; if(NULL != m_hRes){
::FreeLibrary(m_hRes); // unload our resource library if we had some loaded
}/* end of if statement */
#if 0 // use relative path
TCHAR szModule[_MAX_PATH+10]; ::GetModuleFileName(_Module.m_hInstResource, szModule, _MAX_PATH); *( _tcsrchr( szModule, '\\' ) + 1 ) = TEXT('\0');
// now attempt to load the library, since it is not ActiveX control
USES_CONVERSION;
_tcscat( szModule, OLE2T(strResDLLName));
m_hRes = ::LoadLibrary(szModule); #else
USES_CONVERSION; m_hRes = ::LoadLibrary(OLE2T(strResDLLName)); #endif
if (!m_hRes){
hr = HRESULT_FROM_WIN32(::GetLastError()); ATLTRACE(TEXT("Failed to load resource DLL\n")); } else { hr = S_OK; }/* end of if statement */
return (hr); }/* end of function LoadResourceDLL */
/*************************************************************/ /* Name: get_ToolTip */ /* Description: create a tool tip for the button */ /*************************************************************/ HRESULT get_MFToolTip(BSTR *pVal){
if (!pVal) { return E_POINTER; }
*pVal = m_bstrToolTip.Copy(); return S_OK;
}/* end of function get_ToolTip */
/*************************************************************/ /* Name: put_ToolTip */ /* Description: create a tool tip for the button */ /* Cache the tooltip string if there is no window available */ /*************************************************************/ HRESULT put_MFToolTip(BSTR newVal){
m_bstrToolTip = newVal; return S_OK; }
/*************************************************************/ /* Name: get_MFTooltipTracking
/* Description:
/*************************************************************/ HRESULT get_MFTooltipTracking(VARIANT_BOOL *pVal) {
if (!pVal) { return E_POINTER; }
*pVal = (m_bTTTracking==FALSE) ? VARIANT_FALSE:VARIANT_TRUE; return S_OK; }
/*************************************************************/ /* Name: put_MFTooltipTracking
/* Description:
/*************************************************************/ HRESULT put_MFTooltipTracking(VARIANT_BOOL newVal) {
BOOL bTemp = (newVal==VARIANT_FALSE) ? FALSE:TRUE; if (m_bTTTracking != bTemp) { m_bTTTracking = bTemp; ::DestroyWindow(m_hWndTip); m_hWndTip = NULL; } m_bTrackingActivated = FALSE; return S_OK; }
/*************************************************************/ /* Name: CreateToolTip
/* Description: create a tool tip for the button
/*************************************************************/ HRESULT CreateToolTip(HWND parentWnd, RECT rc){
HWND hwnd = MFGetWindow(); if (!hwnd) return S_FALSE;
if (m_bstrToolTip.Length() == 0) return S_FALSE;
USES_CONVERSION; TOOLINFO ti; // tool information
ti.cbSize = sizeof(TOOLINFO); ti.hwnd = hwnd; ti.hinst = _Module.GetModuleInstance(); ti.lpszText = OLE2T(m_bstrToolTip); // if the button is a windowed control, the tool tip is added to
// the button's own window, and the tool tip area should just be
// the client rect of the window
if (hwnd == parentWnd) { ::GetClientRect(hwnd, &ti.rect); ti.uId = (WPARAM) hwnd; ti.uFlags = TTF_IDISHWND; }
// otherwise the tool tip is added to the closet windowed parent of
// the button, and the tool tip area should be the relative postion
// of the button in the parent window
else { ti.rect.left = rc.left; ti.rect.top = rc.top; ti.rect.right = rc.right; ti.rect.bottom = rc.bottom; ti.uId = (UINT) 0; ti.uFlags = 0; }
if (m_bTTTracking) ti.uFlags |= TTF_TRACK;
// If tool tip is to be created for the first time
if (m_hWndTip == (HWND) NULL) { // Ensure that the common control DLL is loaded, and create
// a tooltip control.
InitCommonControls(); m_hWndTip = CreateWindow(TOOLTIPS_CLASS, (LPCTSTR) NULL, TTS_ALWAYSTIP, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hwnd, (HMENU) NULL, _Module.GetModuleInstance(), NULL); ATLTRACE(TEXT("Tooltip %s CreateWindow\n"), OLE2T(m_bstrToolTip)); if (m_hWndTip == (HWND) NULL) return S_FALSE; if (!::SendMessage(m_hWndTip, TTM_ADDTOOL, 0, (LPARAM)&ti)) { ::DestroyWindow(m_hWndTip); m_hWndTip = NULL; return S_FALSE; } }
else { ::SendMessage(m_hWndTip, TTM_UPDATETIPTEXT, 0, (LPARAM)&ti); }
// Save the tooltip info
m_toolInfo = ti;
// Set initial delay time
put_MFToolTipMaxWidth(m_nTTMaxWidth); MFSetDelayTime(TTDT_AUTOPOP, m_dwTTAutopopDelay); MFSetDelayTime(TTDT_INITIAL, m_dwTTInitalDelay); MFSetDelayTime(TTDT_RESHOW, m_dwTTReshowDelay); return S_OK; }/* end of function CreateToolTip */
/*************************************************************/ /* Name: GetDelayTime
/* Description: Get the length of time a pointer must remain
/* stationary within a tool's bounding rectangle before the
/* tooltip window appears
/* delayTypes: TTDT_RESHOW 1
/* TTDT_AUTOPOP 2
/* TTDT_INITIAL 3
/*************************************************************/ HRESULT MFGetDelayTime(long delayType, long *pVal){
if (!pVal) { return E_POINTER; }
if (delayType>TTDT_INITIAL || delayType<TTDT_RESHOW) { return E_INVALIDARG; }
// If tooltip has been created
if (m_hWndTip) { *pVal = (long)::SendMessage(m_hWndTip, TTM_GETDELAYTIME, (WPARAM) (DWORD) delayType, 0); }
// else return cached values
else { switch (delayType) { case TTDT_AUTOPOP: *pVal = m_dwTTAutopopDelay; break; case TTDT_INITIAL: *pVal = m_dwTTInitalDelay; break; case TTDT_RESHOW: *pVal = m_dwTTReshowDelay; break; } }
return S_OK; }/* end of function GetDelayTime */
/*************************************************************/ /* Name: SetDelayTime
/* Description: Set the length of time a pointer must remain
/* stationary within a tool's bounding rectangle before the
/* tooltip window appears
/* delayTypes: TTDT_AUTOMATIC 0
/* TTDT_RESHOW 1
/* TTDT_AUTOPOP 2
/* TTDT_INITIAL 3
/*************************************************************/ HRESULT MFSetDelayTime(long delayType, long newVal){
if (delayType>TTDT_INITIAL || delayType<TTDT_AUTOMATIC || newVal<0) { return E_INVALIDARG; }
if (m_hWndTip) { if (!::SendMessage(m_hWndTip, TTM_SETDELAYTIME, (WPARAM) (DWORD) delayType, (LPARAM) (INT) newVal)) return S_FALSE; }
// cache these values
switch (delayType) { case TTDT_AUTOPOP: m_dwTTAutopopDelay = newVal; break; case TTDT_INITIAL: m_dwTTInitalDelay = newVal; break; case TTDT_RESHOW: m_dwTTReshowDelay = newVal; break; case TTDT_AUTOMATIC: m_dwTTInitalDelay = newVal; m_dwTTAutopopDelay = newVal*10; m_dwTTReshowDelay = newVal/5; break; } return S_OK; }/* end of function SetDelayTime */
/*************************************************************************/ /* Function: get_ToolTipMaxWidth */ /*************************************************************************/ HRESULT get_MFToolTipMaxWidth(long *pVal){
if (!pVal) { return E_POINTER; }
if (m_hWndTip){
*pVal = (long)::SendMessage(m_hWndTip, TTM_GETMAXTIPWIDTH, 0, 0); }/* end of if statement */
return S_OK; }/* end of function get_ToolTipMaxWidth */
/*************************************************************************/ /* Function: put_ToolTipMaxWidth */ /*************************************************************************/ HRESULT put_MFToolTipMaxWidth(long newVal){
if (newVal<0) { return E_INVALIDARG; }
m_nTTMaxWidth = newVal; if (m_hWndTip){
::SendMessage(m_hWndTip, TTM_SETMAXTIPWIDTH, 0, (LPARAM)(INT) newVal); }/* end of if statement */
return S_OK; }/* end of function put_ToolTipMaxWidth */
/*************************************************************/ /* Name: UpdateTooltipRect
/* Description:
/*************************************************************/ HRESULT UpdateTooltipRect(LPCRECT prcPos) {
if (!m_hWndTip) return S_OK;
HWND hwnd = MFGetWindow(); if (!hwnd) return S_FALSE;
m_toolInfo.rect = *prcPos; // new tooltip position
if (!::SendMessage(m_hWndTip, TTM_NEWTOOLRECT, 0, (LPARAM) (LPTOOLINFO) &m_toolInfo)) return S_FALSE; return S_OK; } /* end of function UpdateTooltipRect */
/*************************************************************************/ /* Function: MFOnMouseToolTip */ /* Description: Check if we were captured/pushed the do not do much, */ /* otherwise do the hit detection and see if we are in static or hower */ /* state. */ /*************************************************************************/ LRESULT MFOnMouseToolTip(UINT msg, WPARAM wParam, LPARAM lParam, BOOL& bHandled){
#define X_OFFSET 15
#define Y_OFFSET X_OFFSET
MSG mssg; mssg.hwnd = MFGetWindow(); ATLASSERT(mssg.hwnd); mssg.message = msg; mssg.wParam = wParam; mssg.lParam = lParam;
POINT pt; ::GetCursorPos(&pt); mssg.pt.x = pt.x; mssg.pt.y = pt.y; if (m_hWndTip) ::SendMessage(m_hWndTip, TTM_RELAYEVENT, 0, (LPARAM)&mssg);
RECT rc = m_toolInfo.rect; ::MapWindowPoints(m_toolInfo.hwnd, ::GetDesktopWindow(), (LPPOINT)&rc, 2); if (::PtInRect(&rc, pt)) { if (m_hWndTip) { if (m_bTTTracking) { ::SendMessage(m_hWndTip, TTM_TRACKPOSITION, 0, (LPARAM)MAKELPARAM(X_OFFSET+pt.x, Y_OFFSET+pt.y));
// Activate tracking if not yet
if (!m_bTrackingActivated) { ::SendMessage(m_hWndTip, TTM_TRACKACTIVATE, TRUE, (LPARAM)&m_toolInfo); m_bTrackingActivated = TRUE; } } } } bHandled = FALSE; return 0; }/* end of function MFOnMouseToolTip */
// variables
protected: HINSTANCE m_hRes; HCURSOR m_hCursor; CComBSTR m_strResDLL; TransparentBlitType m_blitType; bool m_fNoFocusGrab; // disable grabbing focus for windowed controls
HWND m_hWndTip; // Tooltip window
TOOLINFO m_toolInfo; // Tooltip info
LONG m_nTTMaxWidth; // Max tooltip width
CComBSTR m_bstrToolTip; // Tooltip string
BOOL m_bTTTracking; // Tracking or not
BOOL m_bTrackingActivated; // Tracking activated or not
DWORD m_dwTTReshowDelay; DWORD m_dwTTAutopopDelay; DWORD m_dwTTInitalDelay; };
#endif //__MSMFCSTUTILS_H_
/*************************************************************************/ /* End of file: CstUtils.h */ /*************************************************************************/
|