【问题标题】:Detecting CTRL+Wheel with CHtmlView使用 CHtmlView 检测 CTRL+Wheel
【发布时间】:2018-08-12 17:53:30
【问题描述】:

我知道如何为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;
}

我刚刚在包含此视图的主编辑器中引入了 CStatusBar,我的一位用户表示他们使用 CTRL + Wheel 来更改缩放因素。

我的菜单结构带有用户可以用来更改缩放的相关热键,因此我的状态栏窗格更新为他们选择的正确值。

但是当他们使用 CTRL + Wheel 更改缩放时,我的应用程序没有检测到这一点。所以他们放大或缩小到一个比例,我的状态栏窗格保持在原来的缩放系数。

使用 MFC 和 CHtmlView 网络浏览器控件,我如何检测他们何时使用 CTRL + Wheel 更改了缩放,以便我可以更新我的状态窗格?

【问题讨论】:

    标签: mfc webbrowser-control zooming mousewheel


    【解决方案1】:

    如果这是带有 Doc/View 结构的 CHtmlView,请使用 PreTranslateMessage 捕获消息。

    WM_MOUSEWHEEL 的文档建议使用几个宏来查找虚拟键和滚轮移动的状态:

    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 也有自己的CHtmlView::ExecWB 方法来设置和获取缩放值等。

    CHtmlView::OnUpdateUI 也应该发送更改通知。


    但浏览器可能不会在正确的时间发送信号。只需在检测到 CTRL+WHEEL 后设置一个计时器等待 1 秒。示例:

    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);
        }
    }
    

    【讨论】:

    • 好的。但我需要在处理完之后再使用它,这样我才能获得新的缩放因子值。
    • Tge 在我们处理它之前检测到鼠标滚轮。所以缩放系数还没有改变。
    • 浏览器处理消息需要时间。手动处理消息,或使用SetTimer/KillTimer 例程在读取缩放之前创建 1 秒延迟。 CHtmlView::OnUpdateUI 也应该收到通知,但它也可能不同步,具体取决于您的代码。
    • 查看编辑制作等待功能,这可能是最简单的方法了。
    • 还有更多控制缩放的快捷方式:Ctrl+PlusCtrl+MinusCtrl+0(至少我知道)
    猜你喜欢
    • 2018-09-10
    • 1970-01-01
    • 2011-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-13
    • 1970-01-01
    相关资源
    最近更新 更多