IELNKCTL.CPP

// IELnkCtl.cpp : Implementation of CIELnkCtl 
#include "stdafx.h"
#include "IELnk.h"
#include "IELnkCtl.h"
#include <hlink.h>

/////////////////////////////////////////////////////////////////////////////
// CIELnkCtl
STDMETHODIMP CIELnkCtl::InterfaceSupportsErrorInfo(REFIID riid)
{
static const IID* arr[] =
{
&IID_IIELnkCtl,
};
for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
{
if (InlineIsEqualGUID(*arr[i],riid))
return S_OK;
}
return S_FALSE;
}


HRESULT CIELnkCtl::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);

#ifndef _UNICODE
if(m_pANSIHLink)
DrawText(hdc, m_pANSIHLink, -1, &rc, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
else
DrawText(hdc, "Unable to Display URL", -1, &rc, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
#else
DrawText(hdc, m_strHLink, -1, &rc, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
#endif

SelectObject(hdc, hOldPen);
SelectObject(hdc, hOldBrush);

return S_OK;
}

STDMETHODIMP CIELnkCtl::get_Flags(long * pVal)
{
*pVal = m_lFlags;

return S_OK;
}

STDMETHODIMP CIELnkCtl::put_Flags(long newVal)
{
if (newVal == 0 || newVal == 1)
{
m_lMode = newVal;

return S_OK;
}
else
return Error(_T("The navigation flag must be either 0 or 1."));
}

STDMETHODIMP CIELnkCtl::get_HLink(BSTR * pVal)
{
*pVal = m_strHLink;

return S_OK;
}

STDMETHODIMP CIELnkCtl::put_HLink(BSTR newVal)
{
m_strHLink = newVal;

#ifndef _UNICODE
unsigned int nURLLength = m_strHLink.Length();

if(m_pANSIHLink)
free(m_pANSIHLink);

// Adjust for the terminating NULL character when allocating space
m_pANSIHLink = (char *)calloc(nURLLength + 1, 1);

wcstombs(m_pANSIHLink, m_strHLink, nURLLength);
#endif

return S_OK;
}

STDMETHODIMP CIELnkCtl::get_Location(BSTR * pVal)
{
*pVal = m_strLocation;

return S_OK;
}

STDMETHODIMP CIELnkCtl::put_Location(BSTR newVal)
{
m_strLocation = newVal;

return S_OK;
}

STDMETHODIMP CIELnkCtl::get_Mode(long * pVal)
{
*pVal = m_lMode;

return S_OK;
}

STDMETHODIMP CIELnkCtl::put_Mode(long newVal)
{
if (newVal >= 0 && newVal <= 7)
{
m_lMode = newVal;

return S_OK;
}
else
return Error(_T("The Mode value must be in the range of 0 through 7."));
}

STDMETHODIMP CIELnkCtl::get_TargetFrame(BSTR * pVal)
{
*pVal = m_strTargetFrame;

return S_OK;
}

STDMETHODIMP CIELnkCtl::put_TargetFrame(BSTR newVal)
{
m_strTargetFrame = newVal;

return S_OK;
}

STDMETHODIMP CIELnkCtl::GetInterfaceSafetyOptions(REFIID riid, DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
{
ATLTRACE(_T("IObjectSafetyImpl::GetInterfaceSafetyOptions\n"));
if (pdwSupportedOptions == NULL || pdwEnabledOptions == NULL)
return E_POINTER;
HRESULT hr = S_OK;

if (riid == IID_IDispatch)
{
*pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER;
*pdwEnabledOptions = m_dwSafety & INTERFACESAFE_FOR_UNTRUSTED_CALLER;
}
else if (riid == IID_IPersistPropertyBag)
{
*pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA;
*pdwEnabledOptions = m_dwSafety & INTERFACESAFE_FOR_UNTRUSTED_DATA;
}
else
{
*pdwSupportedOptions = 0;
*pdwEnabledOptions = 0;
hr = E_NOINTERFACE;
}
return hr;
}

STDMETHODIMP CIELnkCtl::SetInterfaceSafetyOptions(REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions)
{
ATLTRACE(_T("IObjectSafetyImpl::SetInterfaceSafetyOptions\n"));

// If we're being asked to set our safe for scripting or
// safe for initialization options then oblige
if (riid == IID_IDispatch || riid == IID_IPersistPropertyBag)
{
// Store our current safety level to return in GetInterfaceSafetyOptions
m_dwSafety = dwEnabledOptions & dwOptionSetMask;
return S_OK;
}

return E_NOINTERFACE;
}

STDMETHODIMP CIELnkCtl::Go()
{
int nNavFlag;
HRESULT hr;

// m_lFlags values:
//
// 0 - Navigate in a new window
// 1 - Navigate in the current window

if( m_lFlags == 0 )
nNavFlag = HLNF_OPENINNEWWINDOW;
else if( m_lFlags == 1)
nNavFlag = HLNF_INTERNALJUMP;
else
return Error(_T("The navigation flag must be 0 or 1."));

switch (m_lMode)
{
case 0 :
hr = HlinkSimpleNavigateToString(
!m_strHLink ? NULL : (BSTR)m_strHLink,
!m_strLocation ? NULL : (BSTR)m_strLocation,
!m_strTargetFrame ? NULL : (BSTR)m_strTargetFrame,
GetUnknown(),
NULL,
NULL,
nNavFlag,
0);
break;

case 1 :
HlinkSimpleNavigateToString(
!m_strHLink ? NULL : (BSTR)m_strHLink,
!m_strLocation ? NULL : (BSTR)m_strLocation,
!m_strTargetFrame ? NULL : (BSTR)m_strTargetFrame,
NULL,
NULL,
NULL,
nNavFlag,
0);
break;

case 2 :
HlinkNavigateString(
GetUnknown(),
!m_strHLink ? NULL : (BSTR)m_strHLink);
break;

case 3 :
HlinkNavigateString(
NULL,
!m_strHLink ? NULL : (BSTR)m_strHLink);
break;

case 4 :
{
IMoniker *pmTarget;

::CreateURLMoniker(
0,
!m_strHLink ? NULL : (BSTR)m_strHLink,
&pmTarget);

HlinkSimpleNavigateToMoniker(
pmTarget,
!m_strLocation ? NULL : (BSTR)m_strLocation,
!m_strTargetFrame ? NULL : (BSTR)m_strTargetFrame,
GetUnknown(),
NULL,
NULL,
nNavFlag,
0);
}
break;

case 5 :
{
IMoniker *pmTarget;

::CreateURLMoniker(
0,
!m_strHLink ? NULL : (BSTR)m_strHLink,
&pmTarget);

HlinkSimpleNavigateToMoniker(
pmTarget,
!m_strLocation ? NULL : (BSTR)m_strLocation,
!m_strTargetFrame ? NULL : (BSTR)m_strTargetFrame,
NULL,
NULL,
NULL,
nNavFlag,
0);
}
break;

case 6 :
{
IMoniker *pmTarget;

::CreateURLMoniker(
0,
!m_strHLink ? NULL : (BSTR)m_strHLink,
&pmTarget);

HlinkNavigateMoniker(
GetUnknown(),
pmTarget);
}
break;

case 7 :
{
IMoniker *pmTarget;

::CreateURLMoniker(
0,
!m_strHLink ? NULL : (BSTR)m_strHLink,
&pmTarget);

HlinkNavigateMoniker(
NULL,
pmTarget);
}
break;

default:
return Error(_T("The Mode value must be in the range of 0 through 7."));
}

return S_OK;
}

STDMETHODIMP CIELnkCtl::Forward()
{
HlinkGoForward(GetUnknown());

return S_OK;
}

STDMETHODIMP CIELnkCtl::Back()
{
HlinkGoBack(GetUnknown());

return S_OK;
}