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