tags:

views:

14

answers:

2

I am using IOleInPlaceSiteWindowless::AdjustRect to properly capture and release the mouse in a windowless ActiveX control hosted in IE:

LRESULT CD3DControl::OnMouseMove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
{
    CRect rc(CPoint(lParam), CSize(0, 0));
    HRESULT hr = m_spInPlaceSite->AdjustRect(rc);

    bool isInside = hr == S_OK;
    TRACE("AdjustRect 0x%X, isInside=%d %d %d %d %d\n", 
    hr, isInside, rc.top, rc.left, rc.bottom, rc.right);

    if (m_spInPlaceSite->GetCapture() == S_FALSE)
    {
        if (isInside)
        {
            hr = m_spInPlaceSite->SetCapture(TRUE);
            TRACE("SetCapture(TRUE) 0x%X\n", hr);
        }
    }
    else if (!isInside)
    {
        hr = m_spInPlaceSite->SetCapture(FALSE);
        TRACE("SetCapture(FALSE) 0x%X\n", hr);
    }
    return 0;
}

When the mouse enters my control's rect things work great and the control captures the mouse. However, when my mouse leaves the control's area, AdjustRect still returns S_OK. It also returns S_OK if the mouse hovers over a div that covers part of my control.

These results are not consistent with the AdjustRect documentation.

To debug this further, I re-wrote OnMouseMove:

LRESULT CD3DControl::OnMouseMove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
{
    CRect rc(0, 0, 2000, 2000);
    HRESULT hr = m_spInPlaceSite->AdjustRect(&rc);
    bool isInside = hr == S_OK;
    TRACE("AdjustRect 0x%X, isInside=%d %d %d %d %d\n", 
        hr, isInside, rc.top, rc.left, rc.bottom, rc.right);
    return 0;
}

In this case, AdjustRect also returns S_OK, but the rectangle isn't adjusted at all! It is still (0,0)x(2000,2000).

A: 

The amazing Igor Tandetnik answered my question here:

http://social.msdn.microsoft.com/Forums/en-US/ieextensiondevelopment/thread/b8586255-0321-450e-9c8a-090e47ce13c4/

Evidently the function simply isn't implemented. IE should return E_NOTIMPLEMENTED

-Erik

A: 

For OnMouseOut on windowless controls I'm usually using TrackMouseEvent on the container hwnd and monitor WM_MOUSELEAVE and WM_MOUSEMOVE.

Also, keep in mind when authoring windowless controls that some containers refuse windowless instantiation so your controls turn into full blown "windowful" controls there. Most notably MS Access is such a beast. In this case you never get a call on IOleInPlaceObjectWindowless::OnWindowMessage because you have you own hwnd.

wqw
Will TrackMouseEvent work for a windowless control? As you say, it will tell me when the mouse leaves the containing window, which is the entire Html page. I want to know when the mouse leaves my control, which may be partially obscured by overlapping divs and other Html elements.Yes, some containers require windowed execution. It's a lot easier to deal with those - Old tricks like TrackMouseEvent or SetCapture/Release work.