540 lines
19 KiB
C
540 lines
19 KiB
C
|
/*--------------------------------------------------------------------------*
|
||
|
*
|
||
|
* Microsoft Windows
|
||
|
* Copyright (C) Microsoft Corporation, 1999
|
||
|
*
|
||
|
* File: AxHostWindow2.h
|
||
|
*
|
||
|
* Contents: Header file for CAxHostWindow2T. Refer to MSJ, December 1999.
|
||
|
*
|
||
|
* History: 30-Nov-99 VivekJ Created
|
||
|
*
|
||
|
*--------------------------------------------------------------------------*/
|
||
|
|
||
|
#pragma once
|
||
|
#ifndef __AXHOSTWINDOW2_H_
|
||
|
#define __AXHOSTWINDOW2_H_
|
||
|
|
||
|
|
||
|
template <typename TFrameWindow> class CSimpleFrameSite;
|
||
|
//------------------------------------------------------------------------------------------------------------------
|
||
|
//
|
||
|
//
|
||
|
//------------------------------------------------------------------------------------------------------------------
|
||
|
|
||
|
template<typename TFrameWindow>
|
||
|
class ATL_NO_VTABLE CAxHostWindow2T : public CAxHostWindow/*,
|
||
|
public IPersistPropertyBagImpl<CAxHostWindow2T>,
|
||
|
public IPersistStreamInitImpl<CAxHostWindow2T>*/
|
||
|
{
|
||
|
public:
|
||
|
CAxHostWindow2T()
|
||
|
{
|
||
|
m_bUserMode = false;
|
||
|
m_bMessageReflect = false;
|
||
|
m_ContainerPages.cElems = 0;
|
||
|
m_ContainerPages.pElems = 0;
|
||
|
}
|
||
|
|
||
|
~CAxHostWindow2T()
|
||
|
{
|
||
|
if(m_ContainerPages.cElems >=1)
|
||
|
CoTaskMemFree(m_ContainerPages.pElems);
|
||
|
}
|
||
|
|
||
|
DECLARE_GET_CONTROLLING_UNKNOWN()
|
||
|
DECLARE_PROTECT_FINAL_CONSTRUCT()
|
||
|
|
||
|
typedef CAxHostWindow2T<TFrameWindow> thisClass;
|
||
|
typedef CSimpleFrameSite<TFrameWindow> simpleFrameClass;
|
||
|
BEGIN_COM_MAP(thisClass)
|
||
|
//COM_INTERFACE_ENTRY(IPersistPropertyBag)
|
||
|
//COM_INTERFACE_ENTRY(IPersistStreamInit)
|
||
|
COM_INTERFACE_ENTRY_CACHED_TEAR_OFF(IID_ISimpleFrameSite,simpleFrameClass, m_spUnkSimpleFrameSite.p)
|
||
|
COM_INTERFACE_ENTRY_NOINTERFACE(IOleContainer) //yes!!
|
||
|
COM_INTERFACE_ENTRY_CHAIN(CAxHostWindow)
|
||
|
END_COM_MAP()
|
||
|
|
||
|
public:
|
||
|
|
||
|
|
||
|
BEGIN_PROP_MAP(thisClass)
|
||
|
PROP_ENTRY("AllowWindowlessActivation" , 0x60020000, CLSID_NULL)
|
||
|
PROP_ENTRY("BackColor" , DISPID_AMBIENT_BACKCOLOR, CLSID_NULL)
|
||
|
PROP_ENTRY("ForeColor" , DISPID_AMBIENT_FORECOLOR, CLSID_NULL)
|
||
|
PROP_ENTRY("LocaleID" , DISPID_AMBIENT_LOCALEID, CLSID_NULL)
|
||
|
PROP_ENTRY("UserMode" , DISPID_AMBIENT_USERMODE, CLSID_NULL)
|
||
|
|
||
|
PROP_ENTRY("DisplayAsDefault" , DISPID_AMBIENT_DISPLAYASDEFAULT, CLSID_NULL)
|
||
|
PROP_ENTRY("Font" , DISPID_AMBIENT_FONT, CLSID_NULL)
|
||
|
PROP_ENTRY("MessageReflect" , DISPID_AMBIENT_MESSAGEREFLECT, CLSID_NULL)
|
||
|
PROP_ENTRY("ShowGrabHandles" , DISPID_AMBIENT_SHOWGRABHANDLES, CLSID_NULL)
|
||
|
PROP_ENTRY("ShowHatching" , DISPID_AMBIENT_SHOWHATCHING, CLSID_NULL)
|
||
|
|
||
|
PROP_ENTRY("DocHostFlags" , 0x60020012, CLSID_NULL)
|
||
|
PROP_ENTRY("DocHostDoubleClickFlags" , 0x60020014, CLSID_NULL)
|
||
|
PROP_ENTRY("AllowContextMenu" , 0x60020016, CLSID_NULL)
|
||
|
PROP_ENTRY("AllowShowUI" , 0x60020018, CLSID_NULL)
|
||
|
PROP_ENTRY("OptionKeyPath" , 0x6002001a, CLSID_NULL)
|
||
|
END_PROP_MAP()
|
||
|
public:
|
||
|
|
||
|
STDMETHOD(CreateControlEx)(LPCOLESTR lpszTricsData, HWND hWnd, IStream* pStream, IUnknown** ppUnk, REFIID iidAdvise, IUnknown* punkSink)
|
||
|
{
|
||
|
HRESULT hr = S_FALSE;
|
||
|
|
||
|
ReleaseAll();
|
||
|
|
||
|
if (m_hWnd != NULL)
|
||
|
{
|
||
|
RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE | RDW_INTERNALPAINT | RDW_FRAME);
|
||
|
ReleaseWindow();
|
||
|
}
|
||
|
|
||
|
if (::IsWindow(hWnd))
|
||
|
{
|
||
|
USES_CONVERSION;
|
||
|
SubclassWindow(hWnd);
|
||
|
if (m_clrBackground == NULL)
|
||
|
{
|
||
|
if (IsParentDialog())
|
||
|
m_clrBackground = GetSysColor(COLOR_BTNFACE);
|
||
|
else
|
||
|
m_clrBackground = GetSysColor(COLOR_WINDOW);
|
||
|
}
|
||
|
|
||
|
bool bWasHTML;
|
||
|
hr = CreateNormalizedObjectEx(lpszTricsData, IID_IUnknown, (void**)ppUnk, bWasHTML);
|
||
|
bool bInited = hr == S_FALSE;
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
hr = ActivateAx(*ppUnk, bInited, pStream);
|
||
|
|
||
|
|
||
|
//Try to hook up any sink the user might have given us.
|
||
|
m_iidSink = iidAdvise;
|
||
|
if(SUCCEEDED(hr) && *ppUnk && punkSink)
|
||
|
AtlAdvise(*ppUnk, punkSink, m_iidSink, &m_dwAdviseSink);
|
||
|
|
||
|
if (SUCCEEDED(hr) && bWasHTML && *ppUnk != NULL)
|
||
|
{
|
||
|
if ((GetStyle() & (WS_VSCROLL | WS_HSCROLL)) == 0)
|
||
|
m_dwDocHostFlags |= DOCHOSTUIFLAG_SCROLL_NO;
|
||
|
else
|
||
|
{
|
||
|
DWORD dwStyle = GetStyle();
|
||
|
SetWindowLong(GWL_STYLE, dwStyle & ~(WS_VSCROLL | WS_HSCROLL));
|
||
|
SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOSIZE | SWP_FRAMECHANGED | SWP_DRAWFRAME);
|
||
|
}
|
||
|
|
||
|
CComPtr<IUnknown> spUnk(*ppUnk);
|
||
|
// Is it just plain HTML?
|
||
|
USES_CONVERSION;
|
||
|
if ((lpszTricsData[0] == OLECHAR('M') || lpszTricsData[0] == OLECHAR('m')) &&
|
||
|
(lpszTricsData[1] == OLECHAR('S') || lpszTricsData[1] == OLECHAR('s')) &&
|
||
|
(lpszTricsData[2] == OLECHAR('H') || lpszTricsData[2] == OLECHAR('h')) &&
|
||
|
(lpszTricsData[3] == OLECHAR('T') || lpszTricsData[3] == OLECHAR('t')) &&
|
||
|
(lpszTricsData[4] == OLECHAR('M') || lpszTricsData[4] == OLECHAR('m')) &&
|
||
|
(lpszTricsData[5] == OLECHAR('L') || lpszTricsData[5] == OLECHAR('l')) &&
|
||
|
(lpszTricsData[6] == OLECHAR(':')))
|
||
|
{
|
||
|
// Just HTML, eh?
|
||
|
CComPtr<IPersistStreamInit> spPSI;
|
||
|
hr = spUnk->QueryInterface(IID_IPersistStreamInit, (void**)&spPSI);
|
||
|
spPSI->InitNew();
|
||
|
bInited = TRUE;
|
||
|
CComPtr<IHTMLDocument2> spHTMLDoc2;
|
||
|
hr = spUnk->QueryInterface(IID_IHTMLDocument2, (void**)&spHTMLDoc2);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
CComPtr<IHTMLElement> spHTMLBody;
|
||
|
hr = spHTMLDoc2->get_body(&spHTMLBody);
|
||
|
if (SUCCEEDED(hr))
|
||
|
hr = spHTMLBody->put_innerHTML(CComBSTR(lpszTricsData + 7));
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
CComPtr<IWebBrowser2> spBrowser;
|
||
|
spUnk->QueryInterface(IID_IWebBrowser2, (void**)&spBrowser);
|
||
|
if (spBrowser)
|
||
|
{
|
||
|
CComVariant ve;
|
||
|
CComVariant vurl(lpszTricsData);
|
||
|
#pragma warning(disable: 4310) // cast truncates constant value
|
||
|
spBrowser->put_Visible(VARIANT_TRUE);
|
||
|
#pragma warning(default: 4310) // cast truncates constant value
|
||
|
spBrowser->Navigate2(&vurl, &ve, &ve, &ve, &ve);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
if (FAILED(hr) || m_spUnknown == NULL)
|
||
|
{
|
||
|
// We don't have a control or something failed so release
|
||
|
ReleaseAll();
|
||
|
|
||
|
if (m_hWnd != NULL)
|
||
|
{
|
||
|
RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE | RDW_INTERNALPAINT | RDW_FRAME);
|
||
|
if (FAILED(hr))
|
||
|
ReleaseWindow();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return hr;
|
||
|
}
|
||
|
//We support licensing
|
||
|
virtual HRESULT CreateLicensedControl(REFCLSID clsid,REFIID riid, void** ppvObj,bool& bIsItLicensed)
|
||
|
{
|
||
|
CComPtr<IClassFactory2> spCF2;
|
||
|
bIsItLicensed = false;
|
||
|
HRESULT hr = CoGetClassObject(clsid,CLSCTX_SERVER,0,IID_IClassFactory2,(void**)&spCF2);
|
||
|
if(FAILED(hr)) return hr;
|
||
|
|
||
|
bIsItLicensed = true;
|
||
|
LICINFO licInfo;
|
||
|
licInfo.cbLicInfo = sizeof(LICINFO);
|
||
|
hr = spCF2->GetLicInfo(&licInfo);
|
||
|
|
||
|
if(FAILED(hr))
|
||
|
{
|
||
|
::MessageBox(NULL,_T("License Key for this component not found. You do not have the appropriate license to use this component in the design environment"),_T("Licensing Error"),MB_OK);
|
||
|
return hr;
|
||
|
}
|
||
|
BSTR strKey = 0;
|
||
|
if(licInfo.fRuntimeKeyAvail)
|
||
|
{
|
||
|
hr = spCF2->RequestLicKey(0,&strKey);
|
||
|
}
|
||
|
|
||
|
if(SUCCEEDED(hr) || licInfo.fLicVerified)
|
||
|
{
|
||
|
hr = spCF2->CreateInstanceLic(NULL,NULL,riid,strKey,ppvObj);
|
||
|
if(strKey) { ::SysFreeString(strKey); }
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
::MessageBox(NULL,_T("License Key for this component not found. You do not have the appropriate license to use this component in the design environment"),_T("Licensing Error"),MB_OK);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
virtual HRESULT CreateNormalizedObjectEx(LPCOLESTR lpszTricsData, REFIID riid, void** ppvObj, bool& bWasHTML)
|
||
|
{
|
||
|
ATLASSERT(ppvObj);
|
||
|
|
||
|
CLSID clsid;
|
||
|
HRESULT hr = E_FAIL;
|
||
|
bWasHTML = false;
|
||
|
*ppvObj = NULL;
|
||
|
|
||
|
if (lpszTricsData == NULL || lpszTricsData[0] == 0){ return S_OK; }
|
||
|
|
||
|
// Is it HTML ?
|
||
|
USES_CONVERSION;
|
||
|
if ((lpszTricsData[0] == OLECHAR('M') || lpszTricsData[0] == OLECHAR('m')) &&
|
||
|
(lpszTricsData[1] == OLECHAR('S') || lpszTricsData[1] == OLECHAR('s')) &&
|
||
|
(lpszTricsData[2] == OLECHAR('H') || lpszTricsData[2] == OLECHAR('h')) &&
|
||
|
(lpszTricsData[3] == OLECHAR('T') || lpszTricsData[3] == OLECHAR('t')) &&
|
||
|
(lpszTricsData[4] == OLECHAR('M') || lpszTricsData[4] == OLECHAR('m')) &&
|
||
|
(lpszTricsData[5] == OLECHAR('L') || lpszTricsData[5] == OLECHAR('l')) &&
|
||
|
(lpszTricsData[6] == OLECHAR(':')))
|
||
|
{
|
||
|
// It's HTML, so let's create mshtml
|
||
|
hr = CoCreateInstance(CLSID_HTMLDocument, NULL, CLSCTX_SERVER, riid, ppvObj);
|
||
|
bWasHTML = true;
|
||
|
}
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
// Can't be clsid, or progid if length is grater than 255
|
||
|
if (ocslen(lpszTricsData) < 255)
|
||
|
{
|
||
|
if (lpszTricsData[0] == '{') // Is it a CLSID?
|
||
|
hr = CLSIDFromString((LPOLESTR)lpszTricsData, &clsid);
|
||
|
else
|
||
|
hr = CLSIDFromProgID((LPOLESTR)lpszTricsData, &clsid); // How about a ProgID?
|
||
|
|
||
|
if (SUCCEEDED(hr)) // Aha, it was one of those two
|
||
|
{
|
||
|
//check if its a licensed control
|
||
|
//TODO: The usermode and binary persistence needs to act here
|
||
|
bool bLicensed = false;
|
||
|
hr = CreateLicensedControl(clsid,riid,ppvObj,bLicensed);
|
||
|
if(SUCCEEDED(hr) || ( bLicensed && FAILED(hr) ) )
|
||
|
return hr;
|
||
|
|
||
|
//create the control in a normal way - it does not support licensing
|
||
|
hr = CoCreateInstance(clsid, NULL, CLSCTX_SERVER, riid, ppvObj);
|
||
|
}
|
||
|
}
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
// Last guess - it must be either a URL so let's create shdocvw
|
||
|
hr = CoCreateInstance(CLSID_WebBrowser, NULL, CLSCTX_SERVER, riid, ppvObj);
|
||
|
bWasHTML = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
public:
|
||
|
virtual void OnFinalMessage(HWND hWnd)
|
||
|
{
|
||
|
FinalRelease();
|
||
|
GetControllingUnknown()->Release();
|
||
|
}
|
||
|
|
||
|
public: //modified methods
|
||
|
STDMETHOD(GetContainer)(IOleContainer** ppContainer)
|
||
|
{
|
||
|
if(!ppContainer) return E_POINTER;
|
||
|
if(m_spOleContainer)
|
||
|
return (*ppContainer = m_spOleContainer)->AddRef(), S_OK;
|
||
|
*ppContainer = 0;
|
||
|
return E_NOINTERFACE;
|
||
|
}
|
||
|
STDMETHOD(GetExtendedControl)(IDispatch** ppDisp)
|
||
|
{
|
||
|
if(!ppDisp) return E_POINTER;
|
||
|
if(m_spExtendedDispatch)
|
||
|
return (*ppDisp = m_spExtendedDispatch)->AddRef(), S_OK;
|
||
|
*ppDisp = 0;
|
||
|
return E_NOTIMPL;
|
||
|
}
|
||
|
|
||
|
STDMETHOD(GetWindowContext)(IOleInPlaceFrame** ppFrame, IOleInPlaceUIWindow** ppDoc, LPRECT lprcPosRect, LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO pFrameInfo)
|
||
|
{
|
||
|
if (ppFrame == NULL || ppDoc == NULL || lprcPosRect == NULL || lprcClipRect == NULL || !m_spInPlaceFrame || !m_spInPlaceUIWindow || !m_pContainerFrame)
|
||
|
{
|
||
|
return E_POINTER;
|
||
|
}
|
||
|
|
||
|
m_spInPlaceFrame.CopyTo(ppFrame);
|
||
|
m_spInPlaceUIWindow.CopyTo(ppDoc);
|
||
|
GetClientRect(lprcPosRect);
|
||
|
GetClientRect(lprcClipRect);
|
||
|
|
||
|
pFrameInfo = m_pContainerFrame->GetInPlaceFrameInfo();
|
||
|
return S_OK;
|
||
|
}
|
||
|
STDMETHOD(ShowPropertyFrame)()
|
||
|
{
|
||
|
HRESULT hr = E_FAIL;
|
||
|
if(m_ContainerPages.cElems <= 0) return hr;
|
||
|
|
||
|
CComPtr<ISpecifyPropertyPages> spSpecifyPages;
|
||
|
hr = QueryControl(IID_ISpecifyPropertyPages,(void**)&spSpecifyPages);
|
||
|
if(FAILED(hr)) return hr;
|
||
|
|
||
|
CAUUID pages;
|
||
|
hr = spSpecifyPages->GetPages(&pages);
|
||
|
if(FAILED(hr)) return hr;
|
||
|
|
||
|
CComQIPtr<IOleObject> spObj(spSpecifyPages);
|
||
|
CComPtr<IUnknown> spUnk = spSpecifyPages;
|
||
|
if(!spObj || !spUnk) return E_NOINTERFACE;
|
||
|
|
||
|
|
||
|
UINT nOldElems = pages.cElems;
|
||
|
pages.cElems += m_ContainerPages.cElems;
|
||
|
pages.pElems = (GUID *)::CoTaskMemRealloc(pages.pElems, pages.cElems * sizeof(CLSID));
|
||
|
|
||
|
for(UINT n = 0; n < m_ContainerPages.cElems; n++)
|
||
|
{
|
||
|
pages.pElems[nOldElems + n] = m_ContainerPages.pElems[n];
|
||
|
}
|
||
|
LPOLESTR szTitle = NULL;
|
||
|
|
||
|
spObj->GetUserType(USERCLASSTYPE_SHORT, &szTitle);
|
||
|
|
||
|
RECT rcPos;
|
||
|
::GetClientRect(m_hWnd,&rcPos);
|
||
|
|
||
|
m_pContainerFrame->SetDirty(true);
|
||
|
|
||
|
hr = OleCreatePropertyFrame(m_pContainerFrame->m_hWnd, rcPos.top, rcPos.left, szTitle,
|
||
|
1, &spUnk.p, pages.cElems, pages.pElems, LOCALE_USER_DEFAULT, 0, 0);
|
||
|
|
||
|
CoTaskMemFree(szTitle);
|
||
|
CoTaskMemFree(pages.pElems);
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
void ReleaseAll()
|
||
|
{
|
||
|
if (m_bReleaseAll)
|
||
|
return;
|
||
|
m_bReleaseAll = TRUE;
|
||
|
|
||
|
if (m_spViewObject != NULL)
|
||
|
m_spViewObject->SetAdvise(DVASPECT_CONTENT, 0, NULL);
|
||
|
|
||
|
if(m_dwAdviseSink != 0xCDCDCDCD)
|
||
|
{
|
||
|
AtlUnadvise(m_spUnknown, m_iidSink, m_dwAdviseSink);
|
||
|
m_dwAdviseSink = 0xCDCDCDCD;
|
||
|
}
|
||
|
|
||
|
if (m_spOleObject)
|
||
|
{
|
||
|
m_spOleObject->Unadvise(m_dwOleObject);
|
||
|
m_spOleObject->Close(OLECLOSE_NOSAVE);
|
||
|
m_spOleObject->SetClientSite(NULL);
|
||
|
}
|
||
|
|
||
|
if (m_spUnknown != NULL)
|
||
|
{
|
||
|
CComPtr<IObjectWithSite> spSite;
|
||
|
m_spUnknown->QueryInterface(IID_IObjectWithSite, (void**)&spSite);
|
||
|
if (spSite != NULL)
|
||
|
spSite->SetSite(NULL);
|
||
|
}
|
||
|
|
||
|
m_spViewObject.Release();
|
||
|
m_dwViewObjectType = 0;
|
||
|
|
||
|
m_spInPlaceObjectWindowless.Release();
|
||
|
m_spOleObject.Release();
|
||
|
m_spUnknown.Release();
|
||
|
|
||
|
m_bInPlaceActive = FALSE;
|
||
|
m_bWindowless = FALSE;
|
||
|
m_bInPlaceActive = FALSE;
|
||
|
m_bUIActive = FALSE;
|
||
|
m_bCapture = FALSE;
|
||
|
m_bReleaseAll = FALSE;
|
||
|
}
|
||
|
|
||
|
STDMETHOD(AttachControl)(IUnknown* pUnkControl, HWND hWnd)
|
||
|
{
|
||
|
HRESULT hr = S_FALSE;
|
||
|
|
||
|
ReleaseAll();
|
||
|
|
||
|
if (m_hWnd != NULL)
|
||
|
{
|
||
|
RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE | RDW_INTERNALPAINT | RDW_FRAME);
|
||
|
ReleaseWindow();
|
||
|
}
|
||
|
|
||
|
if (::IsWindow(hWnd))
|
||
|
{
|
||
|
SubclassWindow(hWnd);
|
||
|
|
||
|
hr = ActivateAx(pUnkControl, TRUE, NULL);
|
||
|
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
ReleaseAll();
|
||
|
|
||
|
if (m_hWnd != NULL)
|
||
|
{
|
||
|
RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE | RDW_INTERNALPAINT | RDW_FRAME);
|
||
|
ReleaseWindow();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
void FinalRelease()
|
||
|
{
|
||
|
CAxHostWindow::FinalRelease();
|
||
|
}
|
||
|
|
||
|
public:
|
||
|
unsigned m_bRequiresSave:1;
|
||
|
CComPtr<IUnknown> m_spUnkSimpleFrameSite;
|
||
|
CComPtr<IOleContainer> m_spOleContainer;
|
||
|
CComPtr<IDispatch> m_spExtendedDispatch;
|
||
|
CAUUID m_ContainerPages;
|
||
|
TFrameWindow *m_pContainerFrame;
|
||
|
};
|
||
|
|
||
|
//--------------------------------------------------------------------------------------------------------------------
|
||
|
//*Very Very* Simple SimpleFrameSite impl
|
||
|
//SimpleFrameSite tear-off atop the Site - very basic message routing
|
||
|
//one Known control that implements it for our test cases is(sad we cant use VB's intrinsic ones) - MS tabbed Dialog(Sheridan's)
|
||
|
//(not to be confused with MS tabstrip control)
|
||
|
//------------------------------------------------------------------------------------------------------------------
|
||
|
template <typename TFrameWindow>
|
||
|
class ATL_NO_VTABLE CSimpleFrameSite: public ISimpleFrameSite,
|
||
|
public CComTearOffObjectBase<CAxHostWindow2T<TFrameWindow> >
|
||
|
{
|
||
|
public:
|
||
|
CSimpleFrameSite(){}
|
||
|
~CSimpleFrameSite(){}
|
||
|
|
||
|
typedef CSimpleFrameSite<TFrameWindow> thisClass;
|
||
|
|
||
|
BEGIN_COM_MAP(thisClass)
|
||
|
COM_INTERFACE_ENTRY(ISimpleFrameSite)
|
||
|
END_COM_MAP()
|
||
|
|
||
|
DECLARE_PROTECT_FINAL_CONSTRUCT()
|
||
|
|
||
|
public:
|
||
|
//ISimpleFrameSite
|
||
|
STDMETHODIMP PreMessageFilter(/* [in] */ HWND hWnd,/* [in] */ UINT msg,/* [in] */ WPARAM wp,
|
||
|
/* [in] */ LPARAM lp,/* [out] */ LRESULT *plResult,
|
||
|
/* [out] */ DWORD *pdwCookie)
|
||
|
{
|
||
|
if(!plResult || !pdwCookie) { return E_POINTER; }
|
||
|
HWND hWndChild = GetAxWindow(hWnd);
|
||
|
|
||
|
if(hWndChild && ((msg == WM_PAINT)||(msg == WM_KEYDOWN)) )
|
||
|
{
|
||
|
ATLTRACE("\nPreMessageFilter called !!\n");
|
||
|
*plResult = 0;
|
||
|
::SendMessage(hWndChild,msg,wp,lp);
|
||
|
}
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
|
||
|
STDMETHODIMP PostMessageFilter(/* [in] */ HWND hWnd,/* [in] */ UINT msg,/* [in] */ WPARAM wp,
|
||
|
/* [in] */ LPARAM lp,/* [out] */ LRESULT *plResult,/* [in] */ DWORD dwCookie)
|
||
|
{
|
||
|
if(!plResult) { return E_POINTER; }
|
||
|
|
||
|
HWND hWndChild = GetAxWindow(hWnd);
|
||
|
if(hWndChild && ((msg == WM_PAINT)||(msg == WM_KEYDOWN)) )
|
||
|
{
|
||
|
ATLTRACE("\nPostMessageFilter called !!\n");
|
||
|
*plResult = 0;
|
||
|
}
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
protected:
|
||
|
HWND GetAxWindow(HWND& hWnd)
|
||
|
{
|
||
|
HWND hWndChild = GetWindow(hWnd,GW_CHILD);
|
||
|
|
||
|
TCHAR pszClassName[100];
|
||
|
if(hWndChild)
|
||
|
{
|
||
|
for(;;)
|
||
|
{
|
||
|
GetClassName(hWndChild,pszClassName,100);
|
||
|
if(lstrcmp(pszClassName, _T("AtlAxWinEx") ) ==0 )
|
||
|
{
|
||
|
return ::GetWindow(hWndChild,GW_CHILD);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return hWndChild;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
};
|
||
|
|
||
|
#endif
|
||
|
//--------------------------------------------------------------------------------------------------------------------
|