IEMIMECTL.CPP
// IEMimeCtl.cpp : Implementation of CIEMimeCtl 
#include "stdafx.h" 
 
#include "IEMime.h" 
#include "IEMimeCtl.h" 
 
#include "dispids.h" 
 
///////////////////////////////////////////////////////////////////////////// 
// CIEMimeCtl 
 
 
HRESULT CIEMimeCtl::OnDraw(ATL_DRAWINFO& di) 
{ 
RECT& rc = *(RECT*)di.prcBounds; 
 
HDC hdc  = di.hdcDraw; 
HBRUSH    hOldBrush, hBrush; 
    HPEN      hOldPen, hPen; 
hPen = (HPEN)GetStockObject(BLACK_PEN); 
    hOldPen = (HPEN)SelectObject(hdc, hPen); 
    hBrush = (HBRUSH)GetStockObject(WHITE_BRUSH); 
    hOldBrush = (HBRUSH)SelectObject(hdc, hBrush); 
Rectangle(hdc, rc.left, rc.top, rc.right, rc.bottom); 
 
SetBkMode(di.hdcDraw,TRANSPARENT); 
SetTextColor(di.hdcDraw,RGB(0,0,255)); 
if (!m_bstrCFFormat) // Empty - don't draw text 
return S_OK; 
 
ATLTRACE(_T("    m_bstrCFFormat=%s\n"),(LPTSTR)m_bstrCFFormat); 
rc.left += 5; // small left margin 
DrawText(di.hdcDraw, m_bstrCFFormat, m_bstrCFFormat.length(), &rc,   
DT_LEFT | DT_WORD_ELLIPSIS | DT_SINGLELINE); 
 
SelectObject(hdc, hOldPen); 
    SelectObject(hdc, hOldBrush); 
 
return S_OK; 
} 
 
STDMETHODIMP CIEMimeCtl::get_URL(BSTR * pVal) 
{ 
//*pVal = m_bstrURL.copy(); 
// NOTE: _bstr_t::copy() has a BUG in VC5.0 that is fixed in VS5 SP1. See KB Q151491. 
*pVal = ::SysAllocString(static_cast<const wchar_t*>(m_bstrURL)); 
 
return S_OK; 
} 
 
STDMETHODIMP CIEMimeCtl::put_URL(BSTR newVal) 
{ 
m_bstrURL = newVal; 
 
FireOnChanged(DISPID_URL); 
 
if (!m_bstrURL) // NULL string 
return S_OK; 
 
if (READYSTATE_LOADING != m_nReadyState)  // Wait until control is done loading before 
Reload();  // firing off download 
 
    return S_OK; 
} 
 
STDMETHODIMP CIEMimeCtl::get_Media(BSTR * pVal) 
{ 
//*pVal = m_bstrMedia.copy(); 
// NOTE: _bstr_t::copy() has a BUG in VC5.0 that is fixed in VS5 SP1. See KB Q151491. 
*pVal = ::SysAllocString(static_cast<const wchar_t*>(m_bstrMedia)); 
 
return S_OK; 
} 
 
STDMETHODIMP CIEMimeCtl::put_Media(BSTR newVal) 
{ 
m_bstrMedia = newVal; 
 
FireOnChanged(DISPID_MEDIA); 
 
    return S_OK; 
} 
 
STDMETHODIMP CIEMimeCtl::get_Cfformat(BSTR * pVal) 
{ 
*pVal = m_bstrCFFormat.copy(); 
 
return S_OK; 
} 
 
STDMETHODIMP CIEMimeCtl::AboutBox() 
{ 
// The following is necessary to prepare the frame for showing a modal dialog box 
HRESULT hr; 
OLEINPLACEFRAMEINFO frameInfo; 
RECT rcPos, rcClip; 
CComPtr<IOleInPlaceFrame> spInPlaceFrame; 
CComPtr<IOleInPlaceUIWindow> spInPlaceUIWindow; 
frameInfo.cb = sizeof(OLEINPLACEFRAMEINFO); 
HWND hwndFrame = NULL; 
 
if (m_spInPlaceSite) 
{ 
m_spInPlaceSite->GetWindowContext(&spInPlaceFrame, 
&spInPlaceUIWindow, &rcPos, &rcClip, &frameInfo); 
if (spInPlaceFrame) 
{ 
spInPlaceFrame->GetWindow(&hwndFrame); 
hr = spInPlaceFrame->EnableModeless(FALSE); 
if (FAILED(hr)) 
return S_OK;  // Failed, but we don't want to send errors back to script 
} 
} 
// ------------------------------------------------------------------------------- 
 
    ::MessageBox(hwndFrame, _T("This is My Control"), _T("About iemim"), MB_OK | MB_TASKMODAL); 
 
// Tell frame our modal dialog box has gone away 
if (spInPlaceFrame) 
{ 
spInPlaceFrame->EnableModeless(TRUE); 
} 
// -------------------------------------------- 
 
return S_OK; 
} 
 
STDMETHODIMP CIEMimeCtl::Reload() 
{ 
if (!m_bstrURL) // NO OP 
return S_OK; 
else 
{ 
m_nReadyState = READYSTATE_INTERACTIVE; 
FireOnChanged(DISPID_READYSTATE); 
CBindStatusCallback2<CIEMimeCtl>::Download(this, OnData, m_bstrURL, m_spClientSite, FALSE); 
} 
 
return S_OK; 
} 
 
HRESULT CIEMimeCtl::PreBindMoniker(CComPtr<IBindCtx> pBindCtx, CComPtr<IMoniker> pMoniker) 
{ 
HRESULT hr = S_OK; 
 
if (!(m_bstrMedia)) // No MIME registration of our own, default 
return S_OK;    // will give us an accept-type of "*/*" 
 
LPSTR rgszTypes[1]; 
CLIPFORMAT cfFormats[1]; 
cfFormats[0] = CF_NULL; 
 
// Register m_bstrMedia as a media-type. This will either give us 
// the CLIPFORMAT of an existing media-type or create a new one for us. 
rgszTypes[0] = (LPSTR)(m_bstrMedia); 
if (SUCCEEDED(hr)) 
hr = RegisterMediaTypes(1, (LPSTR*)&rgszTypes, cfFormats); 
 
FORMATETC rgfmtetc[1] =  
{ {CF_NULL, NULL, DVASPECT_CONTENT, -1, TYMED_NULL} }; 
IEnumFORMATETC *pMyEtc = NULL; 
 
// Create and register a FORMATETC enumerator for our (potentially custom) 
// media type. Basically this has the equivalent effect of telling URLMON 
// to use this media type for the HTTP Accept-types header. 
// (this won't come into play for file://) 
rgfmtetc[0].cfFormat = cfFormats[0]; 
hr = CreateFormatEnumerator (1, rgfmtetc, &pMyEtc); 
if (SUCCEEDED(hr) && pMyEtc) 
{ 
hr = RegisterFormatEnumerator(pBindCtx, pMyEtc, 0); 
_ASSERTE(SUCCEEDED(hr)); 
} 
 
return hr; 
} 
 
void CIEMimeCtl::OnBindingFailure(HRESULT hr, LPCWSTR szError) 
{ 
if (NULL != szError && NULL != *szError) 
m_bstrCFFormat = szError; 
else 
{ 
// Convert HR to human-readable string 
if (INET_E_NO_VALID_MEDIA == hr) 
m_bstrCFFormat = _T("<Resource at URL does not match Media type>"); 
else 
m_bstrCFFormat = _T("<Failed to download>"); 
} 
 
m_nReadyState = READYSTATE_COMPLETE; 
FireOnChanged(DISPID_READYSTATE); 
FireViewChange(); 
 
} 
 
//OnData will be used as a callback functin by the CBindStatusCallback object. 
//OnData will be called periodically with data from the asynchronous transfer 
void CIEMimeCtl::OnData(CBindStatusCallback2<CIEMimeCtl>* pbsc, BYTE* pBytes, DWORD dwSize, 
DWORD grfBSCF, FORMATETC *pformatetc, STGMEDIUM *pstgmed) 
{ 
static TCHAR formatname[MAX_PATH]; 
 
GetClipboardFormatName(pformatetc->cfFormat, formatname, MAX_PATH); 
m_bstrCFFormat = formatname; 
 
FireOnChanged(DISPID_CFFORMAT); 
 
if (grfBSCF & BSCF_LASTDATANOTIFICATION) 
{ 
Fire_Complete(); // Fire the "Complete" event 
m_nReadyState = READYSTATE_COMPLETE; 
FireOnChanged(DISPID_READYSTATE); 
FireViewChange(); 
} 
 
} 
 
// From ATLCTL.H, line 842 
STDMETHODIMP CIEMimeCtl::FreezeEvents(BOOL bFreeze) 
{ 
ATLTRACE(_T("IOleControlImpl::FreezeEvents\n")); 
if (bFreeze) 
m_nFreezeEvents++; 
else 
{ 
m_nFreezeEvents--; 
// Modified this so that we wait until container is 
// set before downloading 
if (!m_nFreezeEvents) 
{ 
// Let's go! 
Reload(); 
} 
} 
 
return S_OK; 
}