1313 lines
35 KiB
C++
1313 lines
35 KiB
C++
|
#include "priv.h"
|
||
|
#include <iehelpid.h>
|
||
|
#include <pstore.h>
|
||
|
#include "hlframe.h"
|
||
|
#include "shldisp.h"
|
||
|
#include "opsprof.h"
|
||
|
#include "resource.h"
|
||
|
#include <mluisupp.h>
|
||
|
#include "htmlstr.h"
|
||
|
#include "airesize.h"
|
||
|
#include "mshtmcid.h"
|
||
|
#include "util.h"
|
||
|
#include "winuser.h"
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// filename: airesize.cpp
|
||
|
//
|
||
|
// description: implements the autoimageresize feature
|
||
|
//
|
||
|
// notes:
|
||
|
//
|
||
|
// history: 03.07.2001 by jeffdav
|
||
|
//
|
||
|
//////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
extern HINSTANCE g_hinst;
|
||
|
|
||
|
#define TF_AIRESIZE TF_CUSTOM2
|
||
|
|
||
|
CAutoImageResizeEventSinkCallback::EventSinkEntry CAutoImageResizeEventSinkCallback::EventsToSink[] =
|
||
|
{
|
||
|
{ EVENT_MOUSEOVER, L"onmouseover", L"mouseover" },
|
||
|
{ EVENT_MOUSEOUT, L"onmouseout", L"mouseout" },
|
||
|
{ EVENT_SCROLL, L"onscroll", L"scroll" },
|
||
|
{ EVENT_RESIZE, L"onresize", L"resize" },
|
||
|
{ EVENT_BEFOREPRINT, L"onbeforeprint", L"beforeprint"},
|
||
|
{ EVENT_AFTERPRINT, L"onafterprint", L"afterprint" }
|
||
|
};
|
||
|
|
||
|
// autoimage resize states
|
||
|
enum
|
||
|
{
|
||
|
AIRSTATE_BOGUS = 0,
|
||
|
AIRSTATE_INIT,
|
||
|
AIRSTATE_NORMAL,
|
||
|
AIRSTATE_RESIZED,
|
||
|
AIRSTATE_WAITINGTORESIZE
|
||
|
};
|
||
|
|
||
|
// button states
|
||
|
enum
|
||
|
{
|
||
|
AIRBUTTONSTATE_BOGUS = 0,
|
||
|
AIRBUTTONSTATE_HIDDEN,
|
||
|
AIRBUTTONSTATE_VISIBLE,
|
||
|
AIRBUTTONSTATE_WAITINGTOSHOW,
|
||
|
AIRBUTTONSTATE_NOBUTTON
|
||
|
};
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
// QI, AddRef, Release:
|
||
|
|
||
|
STDMETHODIMP CAutoImageResize::QueryInterface(REFIID riid, void **ppv)
|
||
|
{
|
||
|
*ppv = NULL;
|
||
|
|
||
|
if ((IID_IPropertyNotifySink == riid) || (IID_IUnknown == riid))
|
||
|
{
|
||
|
*ppv = (IPropertyNotifySink *)this;
|
||
|
}
|
||
|
|
||
|
if (*ppv)
|
||
|
{
|
||
|
((IUnknown *)*ppv)->AddRef();
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
return E_NOINTERFACE;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP_(ULONG) CAutoImageResize::AddRef(void)
|
||
|
{
|
||
|
return ++m_cRef;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP_(ULONG) CAutoImageResize::Release(void)
|
||
|
{
|
||
|
if (--m_cRef == 0)
|
||
|
{
|
||
|
delete this;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
return m_cRef;
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
// Constructor, Destructor, Init, UnInit:
|
||
|
|
||
|
// constructor
|
||
|
CAutoImageResize::CAutoImageResize()
|
||
|
{
|
||
|
TraceMsg(TF_AIRESIZE, "+CAutoImageResize::CAutoImageResize");
|
||
|
|
||
|
m_airState = AIRSTATE_INIT;
|
||
|
m_airUsersLastChoice= AIRSTATE_BOGUS; // we don't care until the user clicks the button
|
||
|
m_hWndButton = NULL;
|
||
|
m_hWnd = NULL;
|
||
|
m_wndProcOld = NULL;
|
||
|
m_pDoc2 = NULL;
|
||
|
m_pEle2 = NULL;
|
||
|
m_pWin3 = NULL;
|
||
|
m_bWindowResizing = FALSE;
|
||
|
m_himlButtonShrink = NULL;
|
||
|
m_himlButtonExpand = NULL;
|
||
|
|
||
|
TraceMsg(TF_AIRESIZE, "-CAutoImageResize::CAutoImageResize");
|
||
|
}
|
||
|
|
||
|
// destructor
|
||
|
CAutoImageResize::~CAutoImageResize()
|
||
|
{
|
||
|
TraceMsg(TF_AIRESIZE, "+CAutoImageResize::~CAutoImageResize");
|
||
|
|
||
|
DestroyButton();
|
||
|
|
||
|
ATOMICRELEASE(m_pEle2);
|
||
|
ATOMICRELEASE(m_pDoc2);
|
||
|
|
||
|
TraceMsg(TF_AIRESIZE, "-CAutoImageResize::~CAutoImageResize");
|
||
|
}
|
||
|
|
||
|
HRESULT CAutoImageResize::Init(IHTMLDocument2 *pDoc2)
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
TraceMsg(TF_AIRESIZE, "+CAutoImageResize::Init");
|
||
|
|
||
|
ASSERT(pDoc2);
|
||
|
|
||
|
//sink things
|
||
|
IHTMLElement2 *pEle2 = NULL;
|
||
|
IHTMLElementCollection *pCollect = NULL;
|
||
|
IHTMLElementCollection *pSubCollect = NULL;
|
||
|
IDispatch *pDisp = NULL;
|
||
|
VARIANT TagName;
|
||
|
ULONG ulCount = 0;
|
||
|
VARIANTARG va1;
|
||
|
VARIANTARG va2;
|
||
|
IHTMLWindow3 *pWin3 = NULL;
|
||
|
IOleWindow *pOleWin = NULL;
|
||
|
|
||
|
// ...remember this...
|
||
|
m_pDoc2 = pDoc2;
|
||
|
pDoc2->AddRef();
|
||
|
|
||
|
// ...remember the hwnd also...
|
||
|
hr = m_pDoc2->QueryInterface(IID_IOleWindow,(void **)&pOleWin);
|
||
|
if (FAILED(hr))
|
||
|
goto Cleanup;
|
||
|
pOleWin->GetWindow(&m_hWnd);
|
||
|
|
||
|
// setup variant for finding all the IMG tags...
|
||
|
TagName.vt = VT_BSTR;
|
||
|
TagName.bstrVal = (BSTR)c_bstr_IMG;
|
||
|
|
||
|
//get all tags
|
||
|
hr = pDoc2->get_all(&pCollect);
|
||
|
if (FAILED(hr))
|
||
|
goto Cleanup;
|
||
|
|
||
|
//get all IMG tags
|
||
|
hr = pCollect->tags(TagName, &pDisp);
|
||
|
if (FAILED(hr))
|
||
|
goto Cleanup;
|
||
|
|
||
|
if (pDisp)
|
||
|
{
|
||
|
hr = pDisp->QueryInterface(IID_IHTMLElementCollection,(void **)&pSubCollect);
|
||
|
ATOMICRELEASE(pDisp);
|
||
|
}
|
||
|
if (FAILED(hr))
|
||
|
goto Cleanup;
|
||
|
|
||
|
//get IMG tag count
|
||
|
hr = pSubCollect->get_length((LONG *)&ulCount);
|
||
|
if (FAILED(hr))
|
||
|
goto Cleanup;
|
||
|
|
||
|
// highlander theorem: there can be only one!
|
||
|
// bt's corollary: there must be exactally one.
|
||
|
if (1 != ulCount)
|
||
|
goto Cleanup;
|
||
|
|
||
|
va1.vt = VT_I4;
|
||
|
va2.vt = VT_EMPTY;
|
||
|
|
||
|
pDisp = NULL;
|
||
|
va1.lVal = (LONG)0;
|
||
|
pSubCollect->item(va1, va2, &pDisp);
|
||
|
|
||
|
// create event sink for the image
|
||
|
if (!m_pSink && pDisp)
|
||
|
m_pSink = new CEventSink(this);
|
||
|
|
||
|
if (pDisp)
|
||
|
{
|
||
|
hr = pDisp->QueryInterface(IID_IHTMLElement2, (void **)&pEle2);
|
||
|
if (FAILED(hr))
|
||
|
goto Cleanup;
|
||
|
|
||
|
ASSERT(m_pSink);
|
||
|
|
||
|
if (m_pSink && pEle2)
|
||
|
{
|
||
|
EVENTS events[] = { EVENT_MOUSEOVER, EVENT_MOUSEOUT };
|
||
|
m_pSink->SinkEvents(pEle2, ARRAYSIZE(events), events);
|
||
|
m_pEle2=pEle2;
|
||
|
pEle2->AddRef();
|
||
|
}
|
||
|
ATOMICRELEASE(pEle2);
|
||
|
ATOMICRELEASE(pDisp);
|
||
|
}
|
||
|
|
||
|
// sink scroll event from the window, because it doesn't come from elements.
|
||
|
if (m_pSink)
|
||
|
{
|
||
|
Win3FromDoc2(m_pDoc2, &pWin3);
|
||
|
|
||
|
if (pWin3)
|
||
|
{
|
||
|
m_pWin3 = pWin3;
|
||
|
m_pWin3->AddRef();
|
||
|
|
||
|
EVENTS events[] = { EVENT_SCROLL, EVENT_RESIZE, EVENT_BEFOREPRINT, EVENT_AFTERPRINT };
|
||
|
m_pSink->SinkEvents(pWin3, ARRAYSIZE(events), events);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// end sinking things
|
||
|
|
||
|
// Init() gets called when onload fires, so the image *should* be ready
|
||
|
// to get adjusted, if need be...
|
||
|
DoAutoImageResize();
|
||
|
|
||
|
Cleanup:
|
||
|
|
||
|
ATOMICRELEASE(pCollect);
|
||
|
ATOMICRELEASE(pSubCollect);
|
||
|
ATOMICRELEASE(pWin3);
|
||
|
ATOMICRELEASE(pDisp);
|
||
|
ATOMICRELEASE(pEle2);
|
||
|
ATOMICRELEASE(pOleWin);
|
||
|
|
||
|
TraceMsg(TF_AIRESIZE, "-CAutoImageResize::Init");
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
HRESULT CAutoImageResize::UnInit()
|
||
|
{
|
||
|
// Unhook regular event sink
|
||
|
|
||
|
TraceMsg(TF_AIRESIZE, "+CAutoImageResize::UnInit");
|
||
|
|
||
|
DestroyButton();
|
||
|
|
||
|
if (m_pSink)
|
||
|
{
|
||
|
if (m_pWin3)
|
||
|
{
|
||
|
EVENTS events[] = { EVENT_SCROLL, EVENT_RESIZE, EVENT_BEFOREPRINT, EVENT_AFTERPRINT };
|
||
|
m_pSink->UnSinkEvents(m_pWin3, ARRAYSIZE(events), events);
|
||
|
SAFERELEASE(m_pWin3);
|
||
|
}
|
||
|
m_pSink->SetParent(NULL);
|
||
|
ATOMICRELEASE(m_pSink);
|
||
|
}
|
||
|
|
||
|
SAFERELEASE(m_pEle2);
|
||
|
SAFERELEASE(m_pDoc2);
|
||
|
|
||
|
TraceMsg(TF_AIRESIZE, "-CAutoImageResize::UnInit");
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
// AutoImageResize Functions:
|
||
|
|
||
|
HRESULT CAutoImageResize::DoAutoImageResize()
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
IHTMLImgElement *pImgEle = NULL;
|
||
|
LONG lHeight = 0;
|
||
|
LONG lWidth = 0;
|
||
|
LONG lNewHeight = 0;
|
||
|
LONG lNewWidth = 0;
|
||
|
LONG lScrHt = 0;
|
||
|
LONG lScrWd = 0;
|
||
|
RECT rcBrowserWnd;
|
||
|
|
||
|
ASSERT(m_pEle2);
|
||
|
|
||
|
// get an IHTMLImgElement from the IHTMLElement cached...
|
||
|
hr = m_pEle2->QueryInterface(IID_IHTMLImgElement, (void **)&pImgEle);
|
||
|
if (FAILED(hr) || !pImgEle)
|
||
|
goto Cleanup;
|
||
|
|
||
|
// get the current dimensions
|
||
|
if (FAILED(pImgEle->get_height(&lHeight)) || FAILED(pImgEle->get_width(&lWidth)))
|
||
|
goto Cleanup;
|
||
|
|
||
|
// if this is the first time through, we need to take care of some init stuff
|
||
|
if (AIRSTATE_INIT == m_airState)
|
||
|
{
|
||
|
// cache orig dimensions
|
||
|
m_airOrigSize.x = lWidth;
|
||
|
m_airOrigSize.y = lHeight;
|
||
|
|
||
|
// INIT done, promote to NORMAL
|
||
|
m_airState = AIRSTATE_NORMAL;
|
||
|
}
|
||
|
|
||
|
// check to see if we are being called because the user is resizing the window
|
||
|
// and then massage the state as necessary.
|
||
|
if (m_bWindowResizing)
|
||
|
{
|
||
|
m_airState = AIRSTATE_NORMAL;
|
||
|
}
|
||
|
|
||
|
switch (m_airState)
|
||
|
{
|
||
|
case AIRSTATE_NORMAL:
|
||
|
|
||
|
// how big is the window?
|
||
|
if (GetClientRect(m_hWnd, &rcBrowserWnd))
|
||
|
{
|
||
|
|
||
|
lScrHt = rcBrowserWnd.bottom - rcBrowserWnd.top;
|
||
|
lScrWd = rcBrowserWnd.right - rcBrowserWnd.left;
|
||
|
|
||
|
// is the image bigger then the window?
|
||
|
if (lScrWd < lWidth)
|
||
|
m_airState=AIRSTATE_WAITINGTORESIZE;
|
||
|
|
||
|
if (lScrHt < lHeight)
|
||
|
m_airState=AIRSTATE_WAITINGTORESIZE;
|
||
|
}
|
||
|
else
|
||
|
goto Cleanup;
|
||
|
|
||
|
// if the window is resizing, we may need to expand the image, so massage the state again...
|
||
|
// (there is a check later on to make sure we don't expand too far...)
|
||
|
if (m_bWindowResizing)
|
||
|
{
|
||
|
m_airState = AIRSTATE_WAITINGTORESIZE;
|
||
|
}
|
||
|
|
||
|
// image didn't fit, so we must resize now
|
||
|
if (AIRSTATE_WAITINGTORESIZE == m_airState)
|
||
|
{
|
||
|
// calculate new size:
|
||
|
if (MulDiv(lWidth,1000,lScrWd) < MulDiv(lHeight,1000,lScrHt))
|
||
|
{
|
||
|
lNewHeight = lScrHt-AIR_SCREEN_CONSTANTY;
|
||
|
lNewWidth = MulDiv(lNewHeight,m_airOrigSize.x,m_airOrigSize.y);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
lNewWidth = lScrWd-AIR_SCREEN_CONSTANTX;
|
||
|
lNewHeight = MulDiv(lNewWidth, m_airOrigSize.y, m_airOrigSize.x);
|
||
|
}
|
||
|
|
||
|
// we don't ever want to resize to be LARGER then the original...
|
||
|
if ((lNewHeight > m_airOrigSize.y) || (lNewWidth > m_airOrigSize.x))
|
||
|
{
|
||
|
if (m_bWindowResizing)
|
||
|
{
|
||
|
// restore orig size cause it should fit and turn off the button
|
||
|
lNewHeight = m_airOrigSize.y;
|
||
|
lNewWidth = m_airOrigSize.x;
|
||
|
m_airButtonState = AIRBUTTONSTATE_NOBUTTON;
|
||
|
}
|
||
|
else
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
|
||
|
if (FAILED(pImgEle->put_height(lNewHeight)) || FAILED(pImgEle->put_width(lNewWidth)))
|
||
|
{
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_airState=AIRSTATE_RESIZED;
|
||
|
if (AIRBUTTONSTATE_VISIBLE == m_airButtonState)
|
||
|
{
|
||
|
// reposition button
|
||
|
HideButton();
|
||
|
ShowButton();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// It fit in the browser window so we don't need to do any work yet...
|
||
|
// If they resize the window or something we need to check again...
|
||
|
m_airButtonState=AIRBUTTONSTATE_NOBUTTON;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
case AIRSTATE_RESIZED:
|
||
|
|
||
|
// restore the image to its normal size
|
||
|
if (FAILED(pImgEle->put_height(m_airOrigSize.y)) ||
|
||
|
FAILED(pImgEle->put_width (m_airOrigSize.x)))
|
||
|
{
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_airState=AIRSTATE_NORMAL;
|
||
|
if (AIRBUTTONSTATE_VISIBLE == m_airButtonState)
|
||
|
{
|
||
|
// reposition button
|
||
|
HideButton();
|
||
|
ShowButton();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
case AIRSTATE_WAITINGTORESIZE:
|
||
|
|
||
|
// we should never be in this state at this time!
|
||
|
ASSERT(m_airState!=AIRSTATE_WAITINGTORESIZE);
|
||
|
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
Cleanup:
|
||
|
|
||
|
ATOMICRELEASE(pImgEle);
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
// Timer Proc:
|
||
|
|
||
|
LRESULT CALLBACK CAutoImageResize::s_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||
|
{
|
||
|
CAutoImageResize* pThis = (CAutoImageResize*)GetWindowPtr(hWnd, GWLP_USERDATA);
|
||
|
|
||
|
TraceMsg(TF_AIRESIZE, "+CAutoImageResize::s_WndProc hWnd=%x, pThis=%p", hWnd, pThis);
|
||
|
|
||
|
HRESULT hr = S_OK;
|
||
|
IOleCommandTarget *pOleCommandTarget = NULL;
|
||
|
UINT iToolTip = NULL;
|
||
|
|
||
|
switch (uMsg)
|
||
|
{
|
||
|
case WM_SIZE:
|
||
|
|
||
|
if (!pThis)
|
||
|
break;
|
||
|
|
||
|
SetWindowPos(pThis->m_hWndButton, NULL, 0, 0, LOWORD(lParam), HIWORD(lParam), SWP_NOZORDER | SWP_NOACTIVATE);
|
||
|
break;
|
||
|
|
||
|
case WM_ERASEBKGND:
|
||
|
|
||
|
if (!pThis)
|
||
|
break;
|
||
|
|
||
|
{
|
||
|
RECT rc;
|
||
|
HBRUSH hb = GetSysColorBrush(COLOR_3DFACE);
|
||
|
|
||
|
GetClientRect(pThis->m_hWndButton, &rc);
|
||
|
FillRect((HDC)wParam, &rc, hb);
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
case WM_COMMAND:
|
||
|
|
||
|
if (!pThis)
|
||
|
break;
|
||
|
|
||
|
switch(LOWORD(wParam))
|
||
|
{
|
||
|
case IDM_AIR_BUTTON:
|
||
|
|
||
|
if (AIRSTATE_NORMAL == pThis->m_airState)
|
||
|
{
|
||
|
pThis->m_airUsersLastChoice = AIRSTATE_RESIZED;
|
||
|
}
|
||
|
else if (AIRSTATE_RESIZED == pThis->m_airState)
|
||
|
{
|
||
|
pThis->m_airUsersLastChoice = AIRSTATE_NORMAL;
|
||
|
}
|
||
|
|
||
|
pThis->DoAutoImageResize();
|
||
|
break;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case WM_NOTIFY: // tooltips...
|
||
|
|
||
|
if (!pThis)
|
||
|
break;
|
||
|
|
||
|
switch (((LPNMHDR)lParam)->code)
|
||
|
{
|
||
|
case TTN_NEEDTEXT:
|
||
|
{
|
||
|
if (AIRSTATE_NORMAL == pThis->m_airState)
|
||
|
{
|
||
|
iToolTip = IDS_AIR_SHRINK;
|
||
|
}
|
||
|
else if (AIRSTATE_RESIZED == pThis->m_airState)
|
||
|
{
|
||
|
iToolTip = IDS_AIR_EXPAND;
|
||
|
}
|
||
|
|
||
|
LPTOOLTIPTEXT lpToolTipText;
|
||
|
TCHAR szBuf[MAX_PATH];
|
||
|
lpToolTipText = (LPTOOLTIPTEXT)lParam;
|
||
|
hr = MLLoadString(iToolTip,
|
||
|
szBuf,
|
||
|
ARRAYSIZE(szBuf));
|
||
|
lpToolTipText->lpszText = szBuf;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case WM_SETTINGCHANGE:
|
||
|
{
|
||
|
pThis->DestroyButton(); // to stop wierd window distortion
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case WM_CONTEXTMENU:
|
||
|
{
|
||
|
// should we be consistant and have a turn-me-off/help context menu?
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
return(DefWindowProc(hWnd, uMsg, wParam, lParam));
|
||
|
}
|
||
|
|
||
|
|
||
|
TraceMsg(TF_AIRESIZE, "-CAutoImageResize::s_WndProc hWnd=%x, pThis=%p", hWnd, pThis);
|
||
|
|
||
|
return (hr);
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
// Timer Proc:
|
||
|
|
||
|
VOID CALLBACK CAutoImageResize::s_TimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
|
||
|
{
|
||
|
TraceMsg(TF_AIRESIZE, "+CAutoImageResize::TimerProc");
|
||
|
|
||
|
CAutoImageResize* pThis = (CAutoImageResize*)GetWindowPtr(hwnd, GWLP_USERDATA);
|
||
|
|
||
|
switch (uMsg)
|
||
|
{
|
||
|
case WM_TIMER:
|
||
|
KillTimer(hwnd, IDT_AIR_TIMER);
|
||
|
if (pThis && (AIRBUTTONSTATE_WAITINGTOSHOW == pThis->m_airButtonState))
|
||
|
{
|
||
|
// Our hover bar is waiting to be shown.
|
||
|
if (pThis->m_pEle2)
|
||
|
{
|
||
|
// We still have an element. Show it.
|
||
|
pThis->m_airButtonState = AIRBUTTONSTATE_VISIBLE;
|
||
|
|
||
|
pThis->ShowButton();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Our timer popped, but we don't have an element.
|
||
|
pThis->HideButton();
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
TraceMsg(TF_AIRESIZE, "-CAutoImageResize::TimerProc");
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
// Button Functions:
|
||
|
|
||
|
HRESULT CAutoImageResize::CreateButton()
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
SIZE size = {0,0};
|
||
|
|
||
|
TraceMsg(TF_AIRESIZE, "+CAutoImageResize::CreateHover, this=%p, m_airButtonState=%d", this, m_airButtonState);
|
||
|
|
||
|
InitCommonControls();
|
||
|
|
||
|
WNDCLASS wc = {0};
|
||
|
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||
|
wc.lpszClassName = TEXT("AutoImageResizeHost");
|
||
|
wc.lpfnWndProc = s_WndProc;
|
||
|
wc.hInstance = g_hinst;
|
||
|
wc.hbrBackground = HBRUSH(COLOR_BTNFACE);
|
||
|
RegisterClass(&wc);
|
||
|
|
||
|
if (!m_hWndButtonCont)
|
||
|
{
|
||
|
|
||
|
m_hWndButtonCont = CreateWindow(TEXT("AutoImageResizeHost"), TEXT(""), WS_DLGFRAME | WS_VISIBLE | WS_CHILD /*| WS_POPUP*/,
|
||
|
0, 0, 0, 0, m_hWnd, NULL, g_hinst, NULL);
|
||
|
|
||
|
if (!m_hWndButtonCont)
|
||
|
{
|
||
|
TraceMsg(TF_AIRESIZE | TF_WARNING, "CAutoImageResize::CreateButton, unable to create m_hWndButtonCont");
|
||
|
hr = E_FAIL;
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
|
||
|
// setup the window callback stuff...
|
||
|
ASSERT(m_wndProcOld == NULL);
|
||
|
m_wndProcOld = (WNDPROC)SetWindowLongPtr(m_hWndButtonCont, GWLP_WNDPROC, (LONG_PTR)s_WndProc);
|
||
|
|
||
|
// pass in the this pointer so the button can call member functions
|
||
|
ASSERT(GetWindowPtr(m_hWndButtonCont, GWLP_USERDATA) == NULL);
|
||
|
SetWindowPtr(m_hWndButtonCont, GWLP_USERDATA, this);
|
||
|
}
|
||
|
|
||
|
// create the button
|
||
|
if (!m_hWndButton)
|
||
|
{
|
||
|
|
||
|
m_hWndButton = CreateWindow(TOOLBARCLASSNAME, TEXT(""), TBSTYLE_TOOLTIPS | CCS_NODIVIDER | TBSTYLE_FLAT | WS_VISIBLE | WS_CHILD,
|
||
|
0,0,0,0, m_hWndButtonCont, NULL, g_hinst, NULL);
|
||
|
|
||
|
if (!m_hWndButton)
|
||
|
{
|
||
|
TraceMsg(TF_AIRESIZE | TF_WARNING, "CAutoImageResize::CreateButton, unable to create m_hWndButton");
|
||
|
hr = E_FAIL;
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
|
||
|
|
||
|
ASSERT(GetWindowPtr(m_hWndButton, GWLP_USERDATA) == NULL);
|
||
|
SetWindowPtr(m_hWndButton, GWLP_USERDATA, this);
|
||
|
|
||
|
// set cc version for this too, and the sizeof tbbutton struct...
|
||
|
SendMessage(m_hWndButton, CCM_SETVERSION, COMCTL32_VERSION, 0);
|
||
|
SendMessage(m_hWndButton, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
|
||
|
}
|
||
|
|
||
|
if (!m_himlButtonExpand)
|
||
|
{
|
||
|
m_himlButtonExpand = ImageList_LoadImage(HINST_THISDLL, MAKEINTRESOURCE(IDB_AIR_EXPAND), 32, 0, CLR_DEFAULT, IMAGE_BITMAP, LR_CREATEDIBSECTION);
|
||
|
if (!m_himlButtonExpand)
|
||
|
{
|
||
|
TraceMsg(TF_AIRESIZE | TF_WARNING, "CAutoImageResize::CreateButton, unable to create m_himlButtonExpand");
|
||
|
hr = E_FAIL;
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!m_himlButtonShrink)
|
||
|
{
|
||
|
m_himlButtonShrink = ImageList_LoadImage(HINST_THISDLL, MAKEINTRESOURCE(IDB_AIR_SHRINK), 32, 0, CLR_DEFAULT, IMAGE_BITMAP, LR_CREATEDIBSECTION);
|
||
|
if (!m_himlButtonShrink)
|
||
|
{
|
||
|
TraceMsg(TF_AIRESIZE | TF_WARNING, "CAutoImageResize::CreateButton, unable to create m_himlButtonShrink");
|
||
|
hr = E_FAIL;
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// set image list and hot image list
|
||
|
SendMessage(m_hWndButton, TB_SETIMAGELIST, 0, (LPARAM)m_himlButtonExpand);
|
||
|
SendMessage(m_hWndButton, TB_SETHOTIMAGELIST, 0, (LPARAM)m_himlButtonExpand);
|
||
|
|
||
|
// add the buttons
|
||
|
|
||
|
TBBUTTON tbAirButton;
|
||
|
|
||
|
tbAirButton.iBitmap = 0;
|
||
|
tbAirButton.idCommand = IDM_AIR_BUTTON;
|
||
|
tbAirButton.fsState = TBSTATE_ENABLED;
|
||
|
tbAirButton.fsStyle = TBSTYLE_BUTTON;
|
||
|
tbAirButton.dwData = 0;
|
||
|
tbAirButton.iString = 0;
|
||
|
|
||
|
SendMessage(m_hWndButton, TB_INSERTBUTTON, 0, (LPARAM)&tbAirButton);
|
||
|
|
||
|
Cleanup:
|
||
|
|
||
|
TraceMsg(TF_AIRESIZE, "-CAutoImageResize::CreateButton, this=%p, m_airButtonState=%d", this, m_airButtonState);
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
HRESULT CAutoImageResize::ShowButton()
|
||
|
{
|
||
|
HRESULT hr = E_FAIL;
|
||
|
IHTMLRect *pRect = NULL;
|
||
|
LONG lLeft = 0; // these are the screen coords
|
||
|
LONG lRight = 0; // we get right and bottom to det size of image
|
||
|
LONG lTop = 0;
|
||
|
LONG lBottom = 0;
|
||
|
DWORD dwOffset = MP_GetOffsetInfoFromRegistry();
|
||
|
RECT rcBrowserWnd;
|
||
|
WORD wImage = NULL;
|
||
|
|
||
|
DWORD dw;
|
||
|
SIZE sz;
|
||
|
RECT rc;
|
||
|
|
||
|
TraceMsg(TF_AIRESIZE, "+CAutoImageResize::ShowButton, this=%p, m_airButtonState=%d", this, m_airButtonState);
|
||
|
|
||
|
ASSERT(m_pEle2);
|
||
|
|
||
|
// get the coords of the image...
|
||
|
if (SUCCEEDED(m_pEle2->getBoundingClientRect(&pRect)) && pRect)
|
||
|
{
|
||
|
pRect->get_left(&lLeft);
|
||
|
pRect->get_right(&lRight);
|
||
|
pRect->get_top(&lTop);
|
||
|
pRect->get_bottom(&lBottom);
|
||
|
}
|
||
|
else
|
||
|
goto Cleanup;
|
||
|
|
||
|
// make sure we are inside the browser window...
|
||
|
if (GetClientRect(m_hWnd, &rcBrowserWnd))
|
||
|
{
|
||
|
// if the browser window is less then a certain min size, we
|
||
|
// don't display the button...
|
||
|
if ((rcBrowserWnd.right - rcBrowserWnd.left < AIR_MIN_BROWSER_SIZE) ||
|
||
|
(rcBrowserWnd.bottom - rcBrowserWnd.top < AIR_MIN_BROWSER_SIZE))
|
||
|
goto Cleanup;
|
||
|
|
||
|
// if the browser window is larger then the image, we don't display
|
||
|
// the button...
|
||
|
if ((AIRSTATE_NORMAL == m_airState) &&
|
||
|
(rcBrowserWnd.left < lLeft ) &&
|
||
|
(rcBrowserWnd.right > lRight ) &&
|
||
|
(rcBrowserWnd.top < lTop ) &&
|
||
|
(rcBrowserWnd.bottom > lBottom))
|
||
|
goto Cleanup;
|
||
|
|
||
|
|
||
|
// adjust for scrollbars
|
||
|
if (lRight > rcBrowserWnd.right - AIR_SCROLLBAR_SIZE_V)
|
||
|
{
|
||
|
lRight = rcBrowserWnd.right - AIR_SCROLLBAR_SIZE_V;
|
||
|
}
|
||
|
|
||
|
if (lBottom > rcBrowserWnd.bottom - AIR_SCROLLBAR_SIZE_H)
|
||
|
{
|
||
|
lBottom = rcBrowserWnd.bottom - AIR_SCROLLBAR_SIZE_H;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
goto Cleanup;
|
||
|
|
||
|
// someone tried to show the button, but it doesn't exist.
|
||
|
// this is ok, if we actually have an element, so fix it for them.
|
||
|
if (!m_hWndButtonCont && m_pEle2)
|
||
|
CreateButton();
|
||
|
|
||
|
// make sure the image list exists
|
||
|
if (!m_himlButtonShrink || !m_himlButtonExpand)
|
||
|
{
|
||
|
hr = E_FAIL;
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
|
||
|
if (AIRSTATE_NORMAL == m_airState)
|
||
|
{
|
||
|
SendMessage(m_hWndButton, TB_SETIMAGELIST, 0, (LPARAM)m_himlButtonShrink);
|
||
|
SendMessage(m_hWndButton, TB_SETHOTIMAGELIST, 0, (LPARAM)m_himlButtonShrink);
|
||
|
}
|
||
|
else if (AIRSTATE_RESIZED == m_airState)
|
||
|
{
|
||
|
SendMessage(m_hWndButton, TB_SETIMAGELIST, 0, (LPARAM)m_himlButtonExpand);
|
||
|
SendMessage(m_hWndButton, TB_SETHOTIMAGELIST, 0, (LPARAM)m_himlButtonExpand);
|
||
|
}
|
||
|
else if (AIRSTATE_INIT == m_airState || AIRSTATE_WAITINGTORESIZE == m_airState)
|
||
|
{
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
|
||
|
// do some calc to get window size and position...
|
||
|
dw = (DWORD)SendMessage(m_hWndButton, TB_GETBUTTONSIZE, 0, 0);
|
||
|
sz.cx = LOWORD(dw);
|
||
|
sz.cy = HIWORD(dw);
|
||
|
rc.left = rc.top = 0;
|
||
|
rc.right = sz.cx;
|
||
|
rc.bottom = sz.cy;
|
||
|
|
||
|
AdjustWindowRectEx(&rc, GetWindowLong(m_hWndButtonCont, GWL_STYLE), FALSE, GetWindowLong(m_hWndButtonCont, GWL_EXSTYLE));
|
||
|
|
||
|
// that should be all...
|
||
|
SetWindowPos(m_hWndButtonCont, NULL,
|
||
|
lRight -(rc.right-rc.left)-dwOffset, // left
|
||
|
lBottom-(rc.bottom-rc.top)-dwOffset, // right
|
||
|
rc.right -rc.left, // width
|
||
|
rc.bottom-rc.top, // height
|
||
|
SWP_NOZORDER | SWP_SHOWWINDOW); // show it
|
||
|
|
||
|
m_airButtonState = AIRBUTTONSTATE_VISIBLE;
|
||
|
|
||
|
hr = S_OK;
|
||
|
|
||
|
Cleanup:
|
||
|
|
||
|
ATOMICRELEASE(pRect);
|
||
|
|
||
|
TraceMsg(TF_AIRESIZE, "-CAutoImageResize::ShowButton, this=%p, m_airButtonState=%d", this, m_airButtonState);
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
HRESULT CAutoImageResize::HideButton()
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
if (m_hWndButton)
|
||
|
{
|
||
|
ShowWindow(m_hWndButtonCont, SW_HIDE);
|
||
|
m_airButtonState=AIRBUTTONSTATE_HIDDEN;
|
||
|
}
|
||
|
else
|
||
|
hr = E_FAIL;
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
HRESULT CAutoImageResize::DestroyButton()
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
TraceMsg(TF_AIRESIZE, "+CAutoImageResize::DestroyHover, this=%p, m_airButtonState=%d", this, m_airButtonState);
|
||
|
|
||
|
if (m_hWndButton)
|
||
|
{
|
||
|
// first destroy the toolbar
|
||
|
if (!DestroyWindow(m_hWndButton))
|
||
|
{
|
||
|
TraceMsg(TF_AIRESIZE, "In CAutoImageResize::DestroyHover, DestroyWindow(m_hWndButton) failed");
|
||
|
hr = E_FAIL;
|
||
|
}
|
||
|
m_hWndButton=NULL;
|
||
|
}
|
||
|
|
||
|
// If we have a container window...
|
||
|
if (m_hWndButtonCont)
|
||
|
{
|
||
|
if (m_wndProcOld)
|
||
|
{
|
||
|
// Unsubclass the window
|
||
|
SetWindowLongPtr(m_hWndButtonCont, GWLP_WNDPROC, (LONG_PTR)m_wndProcOld);
|
||
|
m_wndProcOld = NULL;
|
||
|
}
|
||
|
|
||
|
// Clear the window word
|
||
|
SetWindowPtr(m_hWndButtonCont, GWLP_USERDATA, NULL);
|
||
|
|
||
|
// then destroy the rebar
|
||
|
if (!DestroyWindow(m_hWndButtonCont))
|
||
|
{
|
||
|
hr = E_FAIL;
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
m_hWndButtonCont = NULL;
|
||
|
}
|
||
|
|
||
|
// and destroy the image lists...
|
||
|
if (m_himlButtonShrink)
|
||
|
{
|
||
|
ImageList_Destroy(m_himlButtonShrink);
|
||
|
m_himlButtonShrink = NULL;
|
||
|
}
|
||
|
|
||
|
if (m_himlButtonExpand)
|
||
|
{
|
||
|
ImageList_Destroy(m_himlButtonExpand);
|
||
|
m_himlButtonExpand = NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
Cleanup:
|
||
|
TraceMsg(TF_AIRESIZE, "-CAutoImageResize::DestroyHover, this=%p, hr=%x", this, hr);
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
// Event Handlers:
|
||
|
|
||
|
HRESULT CAutoImageResize::HandleMouseover()
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
if (AIRBUTTONSTATE_NOBUTTON == m_airButtonState)
|
||
|
{
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
if (!m_hWndButton)
|
||
|
{
|
||
|
hr = CreateButton();
|
||
|
}
|
||
|
|
||
|
if (m_hWndButton)
|
||
|
{
|
||
|
m_airButtonState = AIRBUTTONSTATE_WAITINGTOSHOW;
|
||
|
SetTimer(m_hWndButton, IDT_AIR_TIMER, AIR_TIMER, s_TimerProc);
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
HRESULT CAutoImageResize::HandleMouseout()
|
||
|
{
|
||
|
|
||
|
switch(m_airButtonState)
|
||
|
{
|
||
|
case AIRBUTTONSTATE_HIDDEN:
|
||
|
break;
|
||
|
|
||
|
case AIRBUTTONSTATE_VISIBLE:
|
||
|
HideButton();
|
||
|
break;
|
||
|
|
||
|
case AIRBUTTONSTATE_WAITINGTOSHOW:
|
||
|
m_airButtonState=AIRBUTTONSTATE_HIDDEN;
|
||
|
KillTimer(m_hWndButton, IDT_AIR_TIMER);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
HRESULT CAutoImageResize::HandleScroll()
|
||
|
{
|
||
|
RECT rect;
|
||
|
|
||
|
if (AIRBUTTONSTATE_VISIBLE == m_airButtonState)
|
||
|
{
|
||
|
ASSERT(m_hWndButtonCont);
|
||
|
ASSERT(m_pEle2);
|
||
|
|
||
|
GetWindowRect(m_hWndButtonCont, &rect);
|
||
|
|
||
|
HideButton();
|
||
|
ShowButton();
|
||
|
|
||
|
rect.top -= 3*AIR_MIN_CY;
|
||
|
rect.bottom += 2*AIR_MIN_CY;
|
||
|
rect.left -= 3*AIR_MIN_CX;
|
||
|
rect.right += 2*AIR_MIN_CX;
|
||
|
|
||
|
// redraw the button
|
||
|
RedrawWindow(m_hWnd, &rect, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
|
||
|
}
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
HRESULT CAutoImageResize::HandleResize()
|
||
|
{
|
||
|
|
||
|
// if the image previously fit in the window, but the user resized the window and now
|
||
|
// we have resized the image, we should reset the button state so the user actually gets
|
||
|
// a button...
|
||
|
if (AIRBUTTONSTATE_NOBUTTON == m_airButtonState)
|
||
|
{
|
||
|
m_airButtonState = AIRBUTTONSTATE_HIDDEN;
|
||
|
}
|
||
|
|
||
|
// if the users has decided they want the image expanded by clicking the button to expand it,
|
||
|
// we should honor that and not resize the image simply because the window changes size
|
||
|
if (AIRSTATE_NORMAL == m_airUsersLastChoice)
|
||
|
{
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
m_bWindowResizing = TRUE;
|
||
|
|
||
|
DoAutoImageResize();
|
||
|
|
||
|
m_bWindowResizing = FALSE;
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
HRESULT CAutoImageResize::HandleBeforePrint()
|
||
|
{
|
||
|
|
||
|
m_airBeforePrintState = m_airState;
|
||
|
|
||
|
if (AIRSTATE_RESIZED == m_airState)
|
||
|
{
|
||
|
DoAutoImageResize();
|
||
|
}
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
HRESULT CAutoImageResize::HandleAfterPrint()
|
||
|
{
|
||
|
if (AIRSTATE_RESIZED == m_airBeforePrintState &&
|
||
|
AIRSTATE_NORMAL == m_airState)
|
||
|
{
|
||
|
DoAutoImageResize();
|
||
|
}
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
HRESULT CAutoImageResize::HandleEvent(IHTMLElement *pEle, EVENTS Event, IHTMLEventObj *pEventObj)
|
||
|
{
|
||
|
TraceMsg(TF_AIRESIZE, "CAutoImageResize::HandleEvent Event=%ws", EventsToSink[Event].pwszEventName);
|
||
|
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
m_eventsCurr = Event;
|
||
|
|
||
|
switch(Event)
|
||
|
{
|
||
|
case EVENT_SCROLL:
|
||
|
HandleScroll();
|
||
|
break;
|
||
|
|
||
|
case EVENT_MOUSEOVER:
|
||
|
hr = HandleMouseover();
|
||
|
break;
|
||
|
|
||
|
case EVENT_MOUSEOUT:
|
||
|
hr = HandleMouseout();
|
||
|
break;
|
||
|
|
||
|
case EVENT_RESIZE:
|
||
|
hr = HandleResize();
|
||
|
break;
|
||
|
|
||
|
case EVENT_BEFOREPRINT:
|
||
|
hr = HandleBeforePrint();
|
||
|
break;
|
||
|
|
||
|
case EVENT_AFTERPRINT:
|
||
|
hr = HandleAfterPrint();
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
//do nothing?
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return (hr);
|
||
|
}
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
// this is stolen from iforms.cpp:
|
||
|
|
||
|
//=========================================================================
|
||
|
//
|
||
|
// Event sinking class
|
||
|
//
|
||
|
// We simply implement IDispatch and make a call into our parent when
|
||
|
// we receive a sinked event.
|
||
|
//
|
||
|
//=========================================================================
|
||
|
|
||
|
CAutoImageResize::CEventSink::CEventSink(CAutoImageResizeEventSinkCallback *pParent)
|
||
|
{
|
||
|
TraceMsg(TF_AIRESIZE, "CAutoImageResize::CEventSink::CEventSink");
|
||
|
DllAddRef();
|
||
|
m_cRef = 1;
|
||
|
m_pParent = pParent;
|
||
|
}
|
||
|
|
||
|
CAutoImageResize::CEventSink::~CEventSink()
|
||
|
{
|
||
|
TraceMsg(TF_AIRESIZE, "CAutoImageResize::CEventSink::~CEventSink");
|
||
|
ASSERT( m_cRef == 0 );
|
||
|
DllRelease();
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CAutoImageResize::CEventSink::QueryInterface(REFIID riid, void **ppv)
|
||
|
{
|
||
|
*ppv = NULL;
|
||
|
|
||
|
if ((IID_IDispatch == riid) ||
|
||
|
(IID_IUnknown == riid))
|
||
|
{
|
||
|
*ppv = (IDispatch *)this;
|
||
|
}
|
||
|
|
||
|
if (NULL != *ppv)
|
||
|
{
|
||
|
((IUnknown *)*ppv)->AddRef();
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
return E_NOINTERFACE;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP_(ULONG) CAutoImageResize::CEventSink::AddRef(void)
|
||
|
{
|
||
|
return ++m_cRef;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP_(ULONG) CAutoImageResize::CEventSink::Release(void)
|
||
|
{
|
||
|
if (--m_cRef == 0)
|
||
|
{
|
||
|
delete this;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
return m_cRef;
|
||
|
}
|
||
|
|
||
|
HRESULT CAutoImageResize::CEventSink::SinkEvents(IHTMLElement2 *pEle2, int iNum, EVENTS *pEvents)
|
||
|
{
|
||
|
VARIANT_BOOL bSuccess = VARIANT_TRUE;
|
||
|
|
||
|
for (int i=0; i<iNum; i++)
|
||
|
{
|
||
|
BSTR bstrEvent = SysAllocString(CAutoImageResizeEventSinkCallback::EventsToSink[(int)(pEvents[i])].pwszEventSubscribe);
|
||
|
|
||
|
if (bstrEvent)
|
||
|
{
|
||
|
pEle2->attachEvent(bstrEvent, (IDispatch *)this, &bSuccess);
|
||
|
|
||
|
SysFreeString(bstrEvent);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
bSuccess = VARIANT_FALSE;
|
||
|
}
|
||
|
|
||
|
if (!bSuccess)
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return (bSuccess) ? S_OK : E_FAIL;
|
||
|
}
|
||
|
|
||
|
HRESULT CAutoImageResize::CEventSink::SinkEvents(IHTMLWindow3 *pWin3, int iNum, EVENTS *pEvents)
|
||
|
{
|
||
|
VARIANT_BOOL bSuccess = VARIANT_TRUE;
|
||
|
|
||
|
for (int i=0; i<iNum; i++)
|
||
|
{
|
||
|
BSTR bstrEvent = SysAllocString(CAutoImageResizeEventSinkCallback::EventsToSink[(int)(pEvents[i])].pwszEventSubscribe);
|
||
|
|
||
|
if (bstrEvent)
|
||
|
{
|
||
|
pWin3->attachEvent(bstrEvent, (IDispatch *)this, &bSuccess);
|
||
|
|
||
|
SysFreeString(bstrEvent);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
bSuccess = VARIANT_FALSE;
|
||
|
}
|
||
|
|
||
|
if (!bSuccess)
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return (bSuccess) ? S_OK : E_FAIL;
|
||
|
}
|
||
|
|
||
|
|
||
|
HRESULT CAutoImageResize::CEventSink::UnSinkEvents(IHTMLElement2 *pEle2, int iNum, EVENTS *pEvents)
|
||
|
{
|
||
|
for (int i=0; i<iNum; i++)
|
||
|
{
|
||
|
BSTR bstrEvent = SysAllocString(CAutoImageResizeEventSinkCallback::EventsToSink[(int)(pEvents[i])].pwszEventSubscribe);
|
||
|
|
||
|
if (bstrEvent)
|
||
|
{
|
||
|
pEle2->detachEvent(bstrEvent, (IDispatch *)this);
|
||
|
|
||
|
SysFreeString(bstrEvent);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
HRESULT CAutoImageResize::CEventSink::UnSinkEvents(IHTMLWindow3 *pWin3, int iNum, EVENTS *pEvents)
|
||
|
{
|
||
|
for (int i=0; i<iNum; i++)
|
||
|
{
|
||
|
BSTR bstrEvent = SysAllocString(CAutoImageResizeEventSinkCallback::EventsToSink[(int)(pEvents[i])].pwszEventSubscribe);
|
||
|
|
||
|
if (bstrEvent)
|
||
|
{
|
||
|
pWin3->detachEvent(bstrEvent, (IDispatch *)this);
|
||
|
|
||
|
SysFreeString(bstrEvent);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
// IDispatch
|
||
|
STDMETHODIMP CAutoImageResize::CEventSink::GetTypeInfoCount(UINT* /*pctinfo*/)
|
||
|
{
|
||
|
return E_NOTIMPL;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CAutoImageResize::CEventSink::GetTypeInfo(/* [in] */ UINT /*iTInfo*/,
|
||
|
/* [in] */ LCID /*lcid*/,
|
||
|
/* [out] */ ITypeInfo** /*ppTInfo*/)
|
||
|
{
|
||
|
return E_NOTIMPL;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CAutoImageResize::CEventSink::GetIDsOfNames(
|
||
|
REFIID riid,
|
||
|
OLECHAR** rgszNames,
|
||
|
UINT cNames,
|
||
|
LCID lcid,
|
||
|
DISPID* rgDispId)
|
||
|
{
|
||
|
return E_NOTIMPL;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CAutoImageResize::CEventSink::Invoke(
|
||
|
DISPID dispIdMember,
|
||
|
REFIID, LCID,
|
||
|
WORD wFlags,
|
||
|
DISPPARAMS* pDispParams,
|
||
|
VARIANT* pVarResult,
|
||
|
EXCEPINFO*,
|
||
|
UINT* puArgErr)
|
||
|
{
|
||
|
if (m_pParent && pDispParams && pDispParams->cArgs>=1)
|
||
|
{
|
||
|
if (pDispParams->rgvarg[0].vt == VT_DISPATCH)
|
||
|
{
|
||
|
IHTMLEventObj *pObj=NULL;
|
||
|
|
||
|
if (SUCCEEDED(pDispParams->rgvarg[0].pdispVal->QueryInterface(IID_IHTMLEventObj, (void **)&pObj) && pObj))
|
||
|
{
|
||
|
EVENTS Event=EVENT_BOGUS;
|
||
|
BSTR bstrEvent=NULL;
|
||
|
|
||
|
pObj->get_type(&bstrEvent);
|
||
|
|
||
|
if (bstrEvent)
|
||
|
{
|
||
|
for (int i=0; i<ARRAYSIZE(CAutoImageResizeEventSinkCallback::EventsToSink); i++)
|
||
|
{
|
||
|
if (!StrCmpCW(bstrEvent, CAutoImageResizeEventSinkCallback::EventsToSink[i].pwszEventName))
|
||
|
{
|
||
|
Event = (EVENTS) i;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
SysFreeString(bstrEvent);
|
||
|
}
|
||
|
|
||
|
if (Event != EVENT_BOGUS)
|
||
|
{
|
||
|
IHTMLElement *pEle=NULL;
|
||
|
|
||
|
pObj->get_srcElement(&pEle);
|
||
|
|
||
|
// EVENT_SCROLL comes from our window so we won't have an
|
||
|
// element for it
|
||
|
if (pEle || (Event == EVENT_SCROLL) || (Event == EVENT_RESIZE) || (Event == EVENT_BEFOREPRINT) || (Event == EVENT_AFTERPRINT))
|
||
|
{
|
||
|
// Call the event handler here
|
||
|
m_pParent->HandleEvent(pEle, Event, pObj);
|
||
|
|
||
|
if (pEle)
|
||
|
{
|
||
|
pEle->Release();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pObj->Release();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
#undef TF_AIRESIZE
|