Andrew Truckle
Andrew Truckle

Reputation: 19107

Detecting CTRL+Wheel with CHtmlView

I know how to set the zoom factor for a CHtmlView:

HRESULT CChristianLifeMinistryHtmlView::SetZoomFactor(long iZoom, bool bRefreshBrowser /*true*/)
{
    HRESULT hr = S_OK;
    VARIANT vZoom;

    m_lZoomFactor = iZoom;

    if (bRefreshBrowser)
    {
        vZoom.vt = VT_I4;
        vZoom.lVal = iZoom;

        hr = ExecWB(OLECMDID_OPTICAL_ZOOM, OLECMDEXECOPT_DONTPROMPTUSER, &vZoom, nullptr);
    }

    return hr;
}

HRESULT CChristianLifeMinistryHtmlView::ExecWB(OLECMDID cmdID, OLECMDEXECOPT cmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
{
    HRESULT hr;

    ASSERT(m_pBrowserApp != NULL);

    hr = m_pBrowserApp->ExecWB(cmdID, cmdexecopt, pvaIn, pvaOut);
    return hr;
}

I have just introduced a CStatusBar into the main editor that encompasses this view and one of my users has stated that they use CTRL + Wheel to change the zoom factor.

I have my menu structure with associated hotkeys that the user can use to change the zoom, thus my status bar pane is updated to the right value they selected.

But when they use the CTRL + Wheel to change the zoom my application is not detecting this. So they zoom in or out to a scale and my status bar pane is staying at the original zoom factor.

With MFC and the CHtmlView web browser control how to I detect when they have changed the zoom using CTRL + Wheel so I can update my status pane?

Upvotes: 3

Views: 457

Answers (1)

Barmak Shemirani
Barmak Shemirani

Reputation: 31599

If this is CHtmlView with Doc/View structure, use PreTranslateMessage to catch messages.

Documentation for WM_MOUSEWHEEL suggests several macros for finding the state of virtual keys and wheel movement:

BOOL CMyHtmlView::PreTranslateMessage(MSG* pmsg)
{
    if(pmsg->message == WM_MOUSEWHEEL)
    {
        int fwKeys = GET_KEYSTATE_WPARAM(pmsg->wParam);
        int zDelta = GET_WHEEL_DELTA_WPARAM(pmsg->wParam);
        if (fwKeys & MK_CONTROL)
        {
            //mousewheel + control key is down
            TRACE("%d %d\n", zDelta, zDelta / WHEEL_DELTA);

            //update statusbar, or return TRUE to handle this manually
        }
    }
    return CHtmlView::PreTranslateMessage(pmsg);
}

CHtmlView also has its own CHtmlView::ExecWB method to set and get the zoom value etc.

CHtmlView::OnUpdateUI should also send notification for the change.


But the browser may not send a signal at the right time. Just make a timer to wait 1 second after detecting CTRL+WHEEL. Example:

BEGIN_MESSAGE_MAP(CMyHtmlView, CHtmlView)
    ON_WM_TIMER()
END_MESSAGE_MAP()

const int ID_TIMER_ZOOM = 1;

BOOL CMyHtmlView::PreTranslateMessage(MSG* pmsg)
{
    if(pmsg->message == WM_MOUSEWHEEL)
        if (GET_KEYSTATE_WPARAM(pmsg->wParam) & MK_CONTROL)
            SetTimer(ID_TIMER_ZOOM, 1000, NULL); //start timer for detecting zoom
    return CHtmlView::PreTranslateMessage(pmsg);
}

void CMyHtmlView::OnTimer(UINT_PTR timer_id)
{
    if(timer_id == ID_TIMER_ZOOM)
    {
        //get the zoom value
        VARIANT vZoom;
        vZoom.vt = VT_I4;
        vZoom.lVal = 0;
        ExecWB(OLECMDID_OPTICAL_ZOOM, OLECMDEXECOPT_DONTPROMPTUSER, nullptr, &vZoom);
        TRACE("zoom %d\n", vZoom.lVal);

        //kill the timer
        KillTimer(timer_id);
    }
}

Upvotes: 4

Related Questions