|
|
/*************************************************************************/ /* 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_
#ifdef _WMP
#include "wmp.h" // for wmp integration
#endif
const bool gcfGrayOut = false;
#define WM_USER_FOCUS (WM_USER + 0x10)
#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, IDC_ARROW, TRUE, 0, _T("") }; \ return wc; \ }/* end of function GetWndClassInfo */
/*************************************************************************/ /* 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
}/* end of function CMSMFCntrlUtils */
/*************************************************************************/ /* Function: ~CMSMFCntrlUtils */ /*************************************************************************/ virtual ~CMSMFCntrlUtils(){
if(NULL != m_hRes){
::FreeLibrary(m_hRes); // unload our resource library
}/* end of if statement */
m_hRes = NULL; }/* end of function ~CMSMFCntrlUtils */
/*************************************************************************/ /* Message Map */ /*************************************************************************/ typedef CMSMFCntrlUtils< T > thisClass;
BEGIN_MSG_MAP(thisClass) MESSAGE_HANDLER(WM_ERASEBKGND, CMSMFCntrlUtils::MFOnErase) 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: 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. */ /*************************************************************************/ STDMETHODIMP 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. */ /*************************************************************************/ STDMETHODIMP 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. */ /*************************************************************************/ STDMETHODIMP 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. */ /*************************************************************************/ STDMETHODIMP 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, TRUE); // Window based
} else if (pT->m_spInPlaceSite != NULL){
pT->m_spInPlaceSite->InvalidateRect(&pT->m_rcPos, TRUE); // 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 = ::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);
IOleClientSite *pClientSite; IOleContainer *pContainer; 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); pOleWindow->Release();
// 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 */ pClientSite->Release(); hrTemp = pContainer->QueryInterface(IID_IOleObject, (LPVOID*)&pObject); if(FAILED(hrTemp)){ return(hrTemp); }/* end of if statement */ pContainer->Release(); hrTemp = pObject->GetClientSite(&pClientSite); if(FAILED(hrTemp)){ return(hrTemp); }/* end of if statement */ } } while (FAILED(hr));
pClientSite->Release(); 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); #ifdef _DEBUG
if(bCapture){
ATLTRACE("SETTING mouse capture! \n"); } else {
ATLTRACE("RELEASING mouse capture! \n"); }/* end of if statement */
#endif
if(pT->m_bWndLess){
pT->m_spInPlaceSite->SetCapture(bCapture ? TRUE: FALSE); } else { 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
::ReleaseCapture(); }/* 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 */
// variables
protected: HINSTANCE m_hRes; CComBSTR m_strResDLL; TransparentBlitType m_blitType; bool m_fNoFocusGrab; // disable grabbing focus for windowed controls
}; #endif //__MSMFCSTUTILS_H_
/*************************************************************************/ /* End of file: CstUtils.h */ /*************************************************************************/
|