|
|
/*--------------------------------------------------------------------------*
* * Microsoft Windows * Copyright (C) Microsoft Corporation, 1992 - 1999 * * File: ocxview.cpp * * Contents: Implementation file for COCXHostView * * History: 12-Dec-97 JeffRo Created * * This class is required to host OCX controls to fix focus problems. * The MDI child frame window keeps track of its currently active view. * When we're hosting OCX controls without this view and the OCX get the * focus, the MDI child frame thinks the previously active view, usually * the scope tree, is still the active view. So if the user Alt-Tabs * away from MMC and back, for instance, the scope tree will get the focus * even though the OCX had the focus before. * * We need this view to represent the OCX, which isn't a view, to the MDI * child frame. * *--------------------------------------------------------------------------*/
#include "stdafx.h"
#include "amc.h"
#include "ocxview.h"
#include "amcview.h"
#ifdef DBG
CTraceTag tagOCXActivation (_T("OCX"), _T("Activation")); CTraceTag tagOCXTranslateAccel (_T("OCX"), _T("TranslateAccelerator")); #endif
/*+-------------------------------------------------------------------------*
* class COCXCtrlWrapper * * * PURPOSE: Maintains a pointer to a CMMCAxWindow as well as to the OCX in * the window. * *+-------------------------------------------------------------------------*/ class COCXCtrlWrapper : public CComObjectRoot, public IUnknown { typedef COCXCtrlWrapper ThisClass; public: COCXCtrlWrapper() : m_pOCXWindow(NULL) { }
~COCXCtrlWrapper() { if(m_pOCXWindow && m_pOCXWindow->IsWindow()) m_pOCXWindow->DestroyWindow();
delete m_pOCXWindow; }
BEGIN_COM_MAP(ThisClass) COM_INTERFACE_ENTRY(IUnknown) END_COM_MAP()
DECLARE_NOT_AGGREGATABLE(ThisClass);
SC ScInitialize(CMMCAxWindow *pWindowOCX, IUnknown *pUnkCtrl) // initialize with the window that hosts the control
{ DECLARE_SC(sc, TEXT("COCXCtrlWrapper::ScInitialize")); sc = ScCheckPointers(pWindowOCX, pUnkCtrl); if(sc) return sc;
m_pOCXWindow = pWindowOCX; m_spUnkCtrl = pUnkCtrl; return sc; }
SC ScGetControl(IUnknown **ppUnkCtrl) { DECLARE_SC(sc, TEXT("COCXCtrlWrapper::ScGetData")); sc = ScCheckPointers(ppUnkCtrl); if(sc) return sc;
*ppUnkCtrl = m_spUnkCtrl; if(*ppUnkCtrl) (*ppUnkCtrl)->AddRef(); return sc; }
CMMCAxWindow * GetAxWindow() {return m_pOCXWindow;}
private: CMMCAxWindow * m_pOCXWindow; // handle to the window.
CComPtr<IUnknown> m_spUnkCtrl; // the IUnknown of the control
};
/////////////////////////////////////////////////////////////////////////////
// COCXHostView
IMPLEMENT_DYNCREATE(COCXHostView, CView)
COCXHostView::COCXHostView() : m_pAMCView(NULL) { }
COCXHostView::~COCXHostView() { m_pAMCView = NULL; }
/*+-------------------------------------------------------------------------*
* * COCXHostView::PreCreateWindow * * PURPOSE: Adds the WS_CLIPCHILDREN bit. This prevents the host window * from overwriting the OCX. * * PARAMETERS: * CREATESTRUCT& cs : * * RETURNS: * BOOL * *+-------------------------------------------------------------------------*/ BOOL COCXHostView::PreCreateWindow(CREATESTRUCT& cs) { cs.style |= WS_CLIPCHILDREN; // give base class a chance to do own job
BOOL bOK = (CView::PreCreateWindow(cs));
// register view class
LPCTSTR pszViewClassName = g_szOCXViewWndClassName;
// try to register window class which does not cause the repaint
// on resizing (do it only once)
static bool bClassRegistered = false; if ( !bClassRegistered ) { WNDCLASS wc; if (::GetClassInfo(AfxGetInstanceHandle(), cs.lpszClass, &wc)) { // Clear the H and V REDRAW flags
wc.style &= ~(CS_HREDRAW | CS_VREDRAW); wc.lpszClassName = pszViewClassName; // Register this new class;
bClassRegistered = AfxRegisterClass(&wc); } }
// change window class to one which does not cause the repaint
// on resizing if we successfully registered such
if ( bClassRegistered ) cs.lpszClass = pszViewClassName;
return bOK; }
/*+-------------------------------------------------------------------------*
* * COCXHostView::GetAxWindow * * PURPOSE: Returns a pointer to the current AxWindow. * * RETURNS: * CMMCAxWindow * * *+-------------------------------------------------------------------------*/ CMMCAxWindow * COCXHostView::GetAxWindow() { COCXCtrlWrapper *pOCXCtrlWrapper = dynamic_cast<COCXCtrlWrapper *>(m_spUnkCtrlWrapper.GetInterfacePtr()); if(!pOCXCtrlWrapper) return (NULL);
return pOCXCtrlWrapper->GetAxWindow(); }
CAMCView * COCXHostView::GetAMCView() { return m_pAMCView; }
BEGIN_MESSAGE_MAP(COCXHostView, CView) //{{AFX_MSG_MAP(COCXHostView)
ON_WM_SIZE() ON_WM_SETFOCUS() ON_WM_MOUSEACTIVATE() ON_WM_SETTINGCHANGE() ON_WM_CREATE() ON_WM_DESTROY() //}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// COCXHostView drawing
void COCXHostView::OnDraw(CDC* pDC) { // this view should always be totally obscured by the OCX it is hosting
}
/////////////////////////////////////////////////////////////////////////////
// COCXHostView diagnostics
#ifdef _DEBUG
void COCXHostView::AssertValid() const { CView::AssertValid(); }
void COCXHostView::Dump(CDumpContext& dc) const { CView::Dump(dc); } #endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// COCXHostView message handlers
void COCXHostView::OnSize(UINT nType, int cx, int cy) { ASSERT_VALID (this); CView::OnSize(nType, cx, cy);
if (nType != SIZE_MINIMIZED) { if(GetAxWindow() != NULL) GetAxWindow()->MoveWindow (0, 0, cx, cy, FALSE /*bRepaint*/); }
}
void COCXHostView::OnSettingChange(UINT uFlags, LPCTSTR lpszSection) { SetAmbientFont (NULL);
CView::OnSettingChange(uFlags, lpszSection);
if(GetAxWindow() != NULL) GetAxWindow()->SendMessage (WM_SETTINGCHANGE, uFlags, (LPARAM) lpszSection); }
void COCXHostView::OnSetFocus(CWnd* pOldWnd) { DECLARE_SC(sc, TEXT("COCXHostView::OnSetFocus"));
ASSERT_VALID (this);
// delegate the focus to the control we're hosting, if we have one
if(GetAxWindow() != NULL) GetAxWindow()->SetFocus();
// check if someone cared to take the focus.
// default handling else.
if (this == GetFocus()) { CView::OnSetFocus (pOldWnd); } }
int COCXHostView::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message) { /*---------------------------------------------------------*/ /* this code came from CView::OnMouseActivate; we do it */ /* here to bypass sending WM_MOUSEACTIVATE on the the */ /* parent window, avoiding focus churn in the parent frame */ /*---------------------------------------------------------*/
CFrameWnd* pParentFrame = GetParentFrame(); if (pParentFrame != NULL) { // eat it if this will cause activation
ASSERT(pParentFrame == pDesktopWnd || pDesktopWnd->IsChild(pParentFrame));
// either re-activate the current view, or set this view to be active
CView* pView = pParentFrame->GetActiveView(); HWND hWndFocus = ::GetFocus(); if (pView == this && m_hWnd != hWndFocus && !::IsChild(m_hWnd, hWndFocus)) { // re-activate this view
OnActivateView(TRUE, this, this); } else { // activate this view
pParentFrame->SetActiveView(this); } } return (MA_ACTIVATE); }
BOOL COCXHostView::OnCmdMsg( UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo ) { // Do normal command routing
if (CView::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo)) return TRUE;
// if view didn't handle it, give parent view a chance
CWnd* pParentView = GetParent ();
if ((pParentView != NULL) && pParentView->IsKindOf (RUNTIME_CLASS (CAMCView)) && pParentView->OnCmdMsg (nID, nCode, pExtra, pHandlerInfo)) return (TRUE);
// not handled
return FALSE; }
void COCXHostView::OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView) { DECLARE_SC(sc, TEXT("COCXHostView::OnActivateView"));
CView::OnActivateView(bActivate,pActivateView,pDeactiveView);
// If pActivateView and pDeactiveView are same then this app has lost
// or gained focus without changing the active view within the app.
// So do nothing.
if (pActivateView == pDeactiveView) return;
if (bActivate) { sc = ScFireEvent(COCXHostActivationObserver::ScOnOCXHostActivated); if (sc) sc.TraceAndClear(); } else /*
* If this view's no longer active, then the in-place object should * no longer be UI active. This is important for the WebBrowser control * because if you move from one "Link to Web Address" node to another, or * from one taskpad to another, it won't allow tabbing to links on the * new hosted page if it's not deactivated and reactivated in the * appropriate sequence. */ { IOleInPlaceObjectPtr spOleIPObj = GetIUnknown();
/*
* app hack for SQL snapin. Do not UIDeactivate the DaVinci control. * See bugs 175586, 175756, 193673 & 258109. */ CAMCView *pAMCView = GetAMCView(); sc = ScCheckPointers(pAMCView, E_UNEXPECTED); if (sc) return;
SViewData *pViewData = pAMCView->GetViewData(); sc = ScCheckPointers(pViewData, E_UNEXPECTED); if (sc) return;
// If DaVinci control do not UIDeactivate.
LPCOLESTR lpszOCXClsid = pViewData->GetOCX(); if ( (_wcsicmp(lpszOCXClsid, L"{464EE255-FDC7-11D2-9743-00105A994F8D}") == 0) || (_wcsicmp(lpszOCXClsid, L"{97240642-F896-11D0-B255-006097C68E81}") == 0) ) return; /*
* app hack for SQL snapin ends here. */
if (spOleIPObj != NULL) { Trace (tagOCXActivation, _T("Deactivating in-place object")); spOleIPObj->UIDeactivate(); } else Trace (tagOCXActivation, _T("No in-place object to deactivate")); } }
int COCXHostView::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CView::OnCreate(lpCreateStruct) == -1) return -1;
// initialize the AxWin class just once.
static bool bIsAxWinInitialized = false; if(!bIsAxWinInitialized) { AtlAxWinInit(); bIsAxWinInitialized = true; }
// get a pointer to the AMCView.
m_pAMCView = dynamic_cast<CAMCView*>(GetParent());
return 0; }
LPUNKNOWN COCXHostView::GetIUnknown(void) { DECLARE_SC(sc, TEXT("COCXHostView::GetIUnknown"));
COCXCtrlWrapper *pOCXCtrlWrapper = dynamic_cast<COCXCtrlWrapper *>((IUnknown *)m_spUnkCtrlWrapper); if(!pOCXCtrlWrapper) { sc = E_UNEXPECTED; return NULL; }
IUnknownPtr spUnkCtrl; sc = pOCXCtrlWrapper->ScGetControl(&spUnkCtrl); if(sc) return NULL;
return (LPUNKNOWN)spUnkCtrl; }
/*+-------------------------------------------------------------------------*
* * COCXHostView::ScSetControl * * PURPOSE: Hosts the specified control in the OCX view. Delegates to one of * the two other overloaded versions of this function. * * PARAMETERS: * HNODE hNode : The node that owns the view. * CResultViewType& rvt: The result view information * INodeCallback * pNodeCallback : * * RETURNS: * SC * *+-------------------------------------------------------------------------*/ SC COCXHostView::ScSetControl(HNODE hNode, CResultViewType& rvt, INodeCallback *pNodeCallback) { DECLARE_SC(sc, TEXT("COCXHostView::ScSetControl")); USES_CONVERSION;
// make sure that we're trying to set up the right type of view.
if(rvt.GetType() != MMC_VIEW_TYPE_OCX) return E_UNEXPECTED;
// either BOTH rvt.IsPersistableViewDescriptionValid() and rvt.GetOCXUnknown() should be valid (the GetResultViewType2 case)
// or BOTH should be invalid and just GetOCX() should be valid.
if(rvt.IsPersistableViewDescriptionValid() && (rvt.GetOCXUnknown() != NULL) ) { // the GetResultViewType2 case
sc = ScSetControl1(hNode, rvt.GetOCXUnknown(), rvt.GetOCXOptions(), pNodeCallback); if(sc) return sc; } else if(rvt.GetOCX() != NULL) { sc = ScSetControl2(hNode, rvt.GetOCX(), rvt.GetOCXOptions(), pNodeCallback); if(sc) return sc; } else { // should never happen.
return (sc = E_UNEXPECTED); }
// must have a legal Ax Window at this point.
sc = ScCheckPointers(GetAxWindow()); if(sc) return sc;
// the OCX should fill the entirety of the OCX host view
CRect rectHost; GetClientRect (rectHost);
GetAxWindow()->SetWindowPos(HWND_TOP, rectHost.left, rectHost.top, rectHost.Width(), rectHost.Height(), SWP_NOACTIVATE | SWP_SHOWWINDOW);
return sc;
}
/*+-------------------------------------------------------------------------*
* * COCXHostView::ScSetControl1 * * PURPOSE: Hosts the control specified by pUnkCtrl in the OCX view. Takes * care of caching the control * * PARAMETERS: * HNODE hNode : * LPUNKNOWN pUnkCtrl : * DWORD dwOCXOptions : * INodeCallback * pNodeCallback : * * RETURNS: * SC * *+-------------------------------------------------------------------------*/ SC COCXHostView::ScSetControl1(HNODE hNode, LPUNKNOWN pUnkCtrl, DWORD dwOCXOptions, INodeCallback *pNodeCallback) { DECLARE_SC(sc, TEXT("COCXHostView::ScSetControl1"));
// validate parameters.
sc = ScCheckPointers((void *)hNode, pUnkCtrl, pNodeCallback); if(sc) return sc;
CComPtr<IUnknown> spUnkCtrl;
// 1. Hide existing window, if any.
sc = ScHideWindow(); if(sc) return sc;
// 2. Get a cached window if one exists - NOTE that in this overload we do not look at RVTI_OCX_OPTIONS_CACHE_OCX at this point.
sc = pNodeCallback->GetControl(hNode, pUnkCtrl, &m_spUnkCtrlWrapper); // the overloaded form of GetControl
if (sc) return sc;
// 3. if no cached window, create one.
if(m_spUnkCtrlWrapper == NULL) /*no cached window, create one*/ { CMMCAxWindow * pWndAx = NULL;
sc = ScCreateAxWindow(pWndAx); if(sc) return sc;
CComPtr<IUnknown> spUnkContainer;
// attach the container to the AxWindow
sc = pWndAx->AttachControl(pUnkCtrl, &spUnkContainer); if(sc) return sc;
// create a wrapper for the control
CComObject<COCXCtrlWrapper> *pOCXCtrlWrapper = NULL; sc = CComObject<COCXCtrlWrapper>::CreateInstance(&pOCXCtrlWrapper); if(sc) return sc;
spUnkCtrl = pUnkCtrl;
// initialize the wrapper.
// The pointer to the control and the CMMCAxWindow is now owned by the wrapper.
sc = pOCXCtrlWrapper->ScInitialize(pWndAx, spUnkCtrl); if(sc) return sc;
m_spUnkCtrlWrapper = pOCXCtrlWrapper; // does the addref.
// cache only if the snapin asked us to. NOTE that this logic is different from the other version of SetControl
if(dwOCXOptions & RVTI_OCX_OPTIONS_CACHE_OCX) { // This is cached by the static node and used for all nodes of the snapin.
sc = pNodeCallback->SetControl(hNode, pUnkCtrl, m_spUnkCtrlWrapper); // this call passes the wrapper
if(sc) return sc; }
// Do not send MMCN_INITOCX, the snapin created this control it should have initialized it.
} else { // The next call sets m_spUnkCtrlWrapper, which is used to get a pointer to the Ax window.
COCXCtrlWrapper *pOCXCtrlWrapper = dynamic_cast<COCXCtrlWrapper *>((IUnknown *)m_spUnkCtrlWrapper); if(!pOCXCtrlWrapper) return (sc = E_UNEXPECTED); // this should never happen.
sc = pOCXCtrlWrapper->ScGetControl(&spUnkCtrl); if(sc) return sc;
sc = ScCheckPointers(GetAxWindow(), (LPUNKNOWN)spUnkCtrl); if(sc) return sc;
// un-hide the window.
GetAxWindow()->ShowWindow(SW_SHOWNORMAL);
}
return sc; }
/*+-------------------------------------------------------------------------*
* * COCXHostView::ScSetControl2 * * PURPOSE: Hosts the specified control in the OCX view. This is the * OCX returned by GetResultViewType. Also takes care of * caching the control if needed and sending the MMCN_INITOCX * notification to snap-ins. The caching is done by hiding the * OCX window and passing nodemgr a COM object that holds a pointer * to the window as well as the control. The nodemgr side determines * whether or not to cache the control. If the control is not * cached, nodemgr merely releases the object passed to it. * * PARAMETERS: * HNODE hNode : * LPCWSTR szOCXClsid : * DWORD dwOCXOptions : * INodeCallback * pNodeCallback : * * RETURNS: * SC * *+-------------------------------------------------------------------------*/ SC COCXHostView::ScSetControl2(HNODE hNode, LPCWSTR szOCXClsid, DWORD dwOCXOptions, INodeCallback *pNodeCallback) { DECLARE_SC(sc, TEXT("COCXHostView::ScSetControl2"));
// validate parameters.
sc = ScCheckPointers((void *)hNode, szOCXClsid, pNodeCallback); if(sc) return sc;
// create the OCX if needed
CLSID clsid; sc = CLSIDFromString (const_cast<LPWSTR>(szOCXClsid), &clsid); if(sc) return sc;
CComPtr<IUnknown> spUnkCtrl;
sc = ScHideWindow(); if(sc) return sc;
// check whether there is a cached control for this node.
if (dwOCXOptions & RVTI_OCX_OPTIONS_CACHE_OCX) { sc = pNodeCallback->GetControl(hNode, clsid, &m_spUnkCtrlWrapper); if (sc) return sc; }
// nope, create a control and set this control for the node.
if (m_spUnkCtrlWrapper == NULL) { CMMCAxWindow * pWndAx = NULL;
sc = ScCreateAxWindow(pWndAx); if(sc) return sc;
sc = pWndAx->CreateControlEx(szOCXClsid, NULL /*pStream*/, NULL /*ppUnkContainer*/, &spUnkCtrl); if(sc) return sc;
// spUnkCtrl should be valid at this point.
sc = ScCheckPointers(spUnkCtrl); if(sc) return sc;
CComObject<COCXCtrlWrapper> *pOCXCtrlWrapper = NULL; sc = CComObject<COCXCtrlWrapper>::CreateInstance(&pOCXCtrlWrapper); if(sc) return sc;
sc = ScCheckPointers(pOCXCtrlWrapper); if(sc) return sc;
// initialize the wrapper.
// The pointer to the control and the CMMCAxWindow is now owned by the wrapper.
sc = pOCXCtrlWrapper->ScInitialize(pWndAx, spUnkCtrl); if(sc) return sc;
m_spUnkCtrlWrapper = pOCXCtrlWrapper; // does the addref.
// This is cached by the static node and used for all nodes of the snapin.
if (dwOCXOptions & RVTI_OCX_OPTIONS_CACHE_OCX) { sc = pNodeCallback->SetControl(hNode, clsid, m_spUnkCtrlWrapper); // this call passes the wrapper
if(sc) return sc; }
// send the MMCN_INITOCX notification.
sc = pNodeCallback->InitOCX(hNode, spUnkCtrl); // this passes the actual IUnknown of the control.
if(sc) return sc; } else { // The next call sets m_spUnkCtrlWrapper, which is used to get a pointer to the Ax window.
COCXCtrlWrapper *pOCXCtrlWrapper = dynamic_cast<COCXCtrlWrapper *>((IUnknown *)m_spUnkCtrlWrapper); if(!pOCXCtrlWrapper) return (sc = E_UNEXPECTED); // this should never happen.
sc = pOCXCtrlWrapper->ScGetControl(&spUnkCtrl); if(sc) return sc;
sc = ScCheckPointers(GetAxWindow(), (LPUNKNOWN)spUnkCtrl); if(sc) return sc;
// un-hide the window.
GetAxWindow()->ShowWindow(SW_SHOWNORMAL);
}
return sc; }
/*+-------------------------------------------------------------------------*
* * COCXHostView::ScHideWindow * * PURPOSE: Hides the existing window, if any. * * RETURNS: * SC * *+-------------------------------------------------------------------------*/ SC COCXHostView::ScHideWindow() { DECLARE_SC(sc, TEXT("COCXCtrlWrapper::ScHideWindow"));
// if there is an existing window, hide it.
if(GetAxWindow()) { GetAxWindow()->ShowWindow(SW_HIDE); m_spUnkCtrlWrapper.Release(); // this deletes the unneeded window if the reference count is zero.
}
return sc; }
/*+-------------------------------------------------------------------------*
* * COCXHostView::ScCreateAxWindow * * PURPOSE: Creates a new Ax window * * PARAMETERS: * PMMCAXWINDOW pWndAx : * * RETURNS: * SC * *+-------------------------------------------------------------------------*/ SC COCXHostView::ScCreateAxWindow(PMMCAXWINDOW &pWndAx) { DECLARE_SC(sc, TEXT("COCXHostView::ScCreateAxWindow"));
// create a new window
pWndAx = new CMMCAxWindow; if(!pWndAx) return (sc = E_OUTOFMEMORY);
// create the OCX host window
// BUG: 418921 always create the host window with (0,0,0,0) which is what used first time
// as client rect is not created.
// This fixes resize problem for some of the OCX (HP ManageX snapin).
HWND hwndAx = pWndAx->Create(m_hWnd, (RECT&)g_rectEmpty, _T(""), (WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS) );
if (hwndAx == NULL) { sc.FromLastError(); return (sc); }
/*
* Bug 451981: By default, the ATL OCX host window supports hosting * windowless controls. This differs from the MMC 1.2 implementation * of the OCX host window (which used MFC), which did not. Some controls * (e.g. Disk Defragmenter OCX) claim to support windowless instantiation * but do not. * * For compatibility, we must only instantiate result pane OCX's as * windowed controls. */ CComPtr<IAxWinAmbientDispatch> spHostDispatch; sc = pWndAx->QueryHost(IID_IAxWinAmbientDispatch, (void**)&spHostDispatch); if (sc) sc.Clear(); // ignore this failure
else { spHostDispatch->put_AllowWindowlessActivation (VARIANT_FALSE); // disallow windowless activation
SetAmbientFont (spHostDispatch); }
return sc; }
void COCXHostView::OnDestroy() { CView::OnDestroy();
if(GetAxWindow()) GetAxWindow()->DestroyWindow(); }
/*+-------------------------------------------------------------------------*
* COCXHostView::SetAmbientFont * * This function sets the font that any OCX that uses the DISPID_AMBIENT_FONT * ambient property will inherit. *--------------------------------------------------------------------------*/
void COCXHostView::SetAmbientFont (IAxWinAmbientDispatch* pHostDispatch) { DECLARE_SC (sc, _T("COCXHostView::SetAmbientFont")); CComPtr<IAxWinAmbientDispatch> spHostDispatch;
/*
* no host dispatch interface supplied? get it from the AxWindow */ if (pHostDispatch == NULL) { CMMCAxWindow* pWndAx = GetAxWindow(); if (pWndAx == NULL) return;
sc = pWndAx->QueryHost(IID_IAxWinAmbientDispatch, (void**)&spHostDispatch); if (sc) return;
pHostDispatch = spHostDispatch; sc = ScCheckPointers (pHostDispatch, E_UNEXPECTED); if (sc) return; }
/*
* get the icon title font */ LOGFONT lf; SystemParametersInfo (SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, false);
/*
* get the desktop resolution */ CWindowDC dcDesktop (CWnd::GetDesktopWindow()); int ppi = dcDesktop.GetDeviceCaps (LOGPIXELSY); long lfHeight = (lf.lfHeight >= 0) ? lf.lfHeight : -lf.lfHeight;
/*
* create an IFontDisp interface around the icon title font */ USES_CONVERSION; FONTDESC fd; fd.cbSizeofstruct = sizeof (fd); fd.lpstrName = T2OLE (lf.lfFaceName); fd.sWeight = (short) lf.lfWeight; fd.sCharset = lf.lfCharSet; fd.fItalic = lf.lfItalic; fd.fUnderline = lf.lfUnderline; fd.fStrikethrough = lf.lfStrikeOut; fd.cySize.Lo = lfHeight * 720000 / ppi; fd.cySize.Hi = 0;
CComPtr<IFontDisp> spFontDisp; sc = OleCreateFontIndirect (&fd, IID_IFontDisp, (void**) &spFontDisp); if (sc) return;
/*
* set the Font property on the AxHostWindow */ pHostDispatch->put_Font (spFontDisp); }
/*+-------------------------------------------------------------------------*
* * COCXHostView::PreTranslateMessage * * PURPOSE: Sends accelerator messages to the OCX. * * PARAMETERS: * MSG* pMsg : * * RETURNS: * BOOL * *+-------------------------------------------------------------------------*/ BOOL COCXHostView::PreTranslateMessage(MSG* pMsg) { DECLARE_SC(sc, TEXT("COCXHostView::PreTranslateMessage"));
if (pMsg->message >= WM_KEYFIRST && pMsg->message <= WM_KEYLAST) { IOleInPlaceActiveObjectPtr spOleIPAObj = GetIUnknown();
#ifdef DBG
TCHAR szTracePrefix[32];
sc = StringCchPrintf(szTracePrefix, countof(szTracePrefix), _T("msg=0x%04x, vkey=0x%04x:"), pMsg->message, pMsg->wParam); if (sc) sc.TraceAndClear(); // Ignore return;
#endif
if (spOleIPAObj != NULL) { bool fHandled = (spOleIPAObj->TranslateAccelerator(pMsg) == S_OK); Trace (tagOCXTranslateAccel, _T("%s %s handled"), szTracePrefix, fHandled ? _T(" ") : _T("not"));
if (fHandled) return TRUE; } else Trace (tagOCXTranslateAccel, _T("%s not handled (no IOleInPlaceActiveObject*)"), szTracePrefix); }
return BC::PreTranslateMessage(pMsg); }
|