You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1342 lines
40 KiB
1342 lines
40 KiB
/******************************************************************************
|
|
|
|
Copyright (c) 1999-2000 Microsoft Corporation
|
|
|
|
Module Name:
|
|
HtmlUtil.cpp
|
|
|
|
Abstract:
|
|
This file contains the implementation of various functions and classes
|
|
designed to help the handling of HTML elements.
|
|
|
|
Revision History:
|
|
Davide Massarenti (Dmassare) 07/11/2000
|
|
created
|
|
|
|
******************************************************************************/
|
|
|
|
#include "stdafx.h"
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
void MPC::HTML::QuoteEscape( /*[out]*/ MPC::wstring& strAppendTo ,
|
|
/*[in]*/ LPCWSTR szToEscape ,
|
|
/*[in]*/ WCHAR chQuote )
|
|
{
|
|
if(szToEscape)
|
|
{
|
|
WCHAR ch;
|
|
|
|
while((ch = *szToEscape++))
|
|
{
|
|
if(ch == chQuote || ch == '\\')
|
|
{
|
|
strAppendTo += '\\';
|
|
}
|
|
|
|
strAppendTo += ch;
|
|
}
|
|
}
|
|
}
|
|
|
|
void MPC::HTML::UrlUnescape( /*[out]*/ MPC::wstring& strAppendTo ,
|
|
/*[in]*/ LPCWSTR szToUnescape ,
|
|
/*[in]*/ bool fAsQueryString )
|
|
{
|
|
if(szToUnescape)
|
|
{
|
|
WCHAR ch;
|
|
|
|
while((ch = *szToUnescape++))
|
|
{
|
|
if(fAsQueryString && ch == '+')
|
|
{
|
|
strAppendTo += ' ';
|
|
}
|
|
else if(ch == '%')
|
|
{
|
|
int iLen = wcslen( szToUnescape );
|
|
bool fFourDigit = (szToUnescape[0] == 'u');
|
|
|
|
//
|
|
// Do we have enough characters??
|
|
//
|
|
if(iLen >= (fFourDigit ? 5 : 2))
|
|
{
|
|
if(fFourDigit)
|
|
{
|
|
ch = (HexToNum( szToUnescape[1] ) << 12) |
|
|
(HexToNum( szToUnescape[2] ) << 8) |
|
|
(HexToNum( szToUnescape[3] ) << 4) |
|
|
HexToNum( szToUnescape[4] );
|
|
|
|
szToUnescape += 5;
|
|
}
|
|
else
|
|
{
|
|
ch = (HexToNum( szToUnescape[0] ) << 4) |
|
|
HexToNum( szToUnescape[1] );
|
|
|
|
szToUnescape += 2;
|
|
}
|
|
}
|
|
|
|
if(ch) strAppendTo += ch;
|
|
}
|
|
else
|
|
{
|
|
strAppendTo += ch;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void MPC::HTML::UrlEscape( /*[out]*/ MPC::wstring& strAppendTo ,
|
|
/*[in]*/ LPCWSTR szToEscape ,
|
|
/*[in]*/ bool fAsQueryString )
|
|
{
|
|
// This is a bit field for the hex values: 00-29, 2C, 3A-3F, 5B-5E, 60, 7B-FF
|
|
// These are the values escape encodes using the default mask (or mask >= 4)
|
|
static const BYTE s_grfbitEscape[] =
|
|
{
|
|
0xFF, 0xFF, // 00 - 0F
|
|
0xFF, 0xFF, // 10 - 1F
|
|
0xFF, 0x13, // 20 - 2F
|
|
0x00, 0xFC, // 30 - 3F
|
|
0x00, 0x00, // 40 - 4F
|
|
0x00, 0x78, // 50 - 5F
|
|
0x01, 0x00, // 60 - 6F
|
|
0x00, 0xF8, // 70 - 7F
|
|
0xFF, 0xFF, // 80 - 8F
|
|
0xFF, 0xFF, // 90 - 9F
|
|
0xFF, 0xFF, // A0 - AF
|
|
0xFF, 0xFF, // B0 - BF
|
|
0xFF, 0xFF, // C0 - CF
|
|
0xFF, 0xFF, // D0 - DF
|
|
0xFF, 0xFF, // E0 - EF
|
|
0xFF, 0xFF, // F0 - FF
|
|
};
|
|
static const WCHAR s_rgchHex[] = L"0123456789ABCDEF";
|
|
|
|
////////////////////
|
|
|
|
if(szToEscape)
|
|
{
|
|
WCHAR ch;
|
|
|
|
while((ch = *szToEscape++))
|
|
{
|
|
if(fAsQueryString && ch == ' ')
|
|
{
|
|
strAppendTo += '+';
|
|
}
|
|
else if(0 != (ch & 0xFF00))
|
|
{
|
|
strAppendTo += L"%u";
|
|
strAppendTo += s_rgchHex[(ch >> 12) & 0x0F];
|
|
strAppendTo += s_rgchHex[(ch >> 8) & 0x0F];
|
|
strAppendTo += s_rgchHex[(ch >> 4) & 0x0F];
|
|
strAppendTo += s_rgchHex[ ch & 0x0F];
|
|
}
|
|
else if((s_grfbitEscape[ch >> 3] & (1 << (ch & 7))) || (fAsQueryString && ch == '+'))
|
|
{
|
|
strAppendTo += L"%";
|
|
strAppendTo += s_rgchHex[(ch >> 4) & 0x0F];
|
|
strAppendTo += s_rgchHex[ ch & 0x0F];
|
|
}
|
|
else
|
|
{
|
|
strAppendTo += ch;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void MPC::HTML::HTMLEscape( /*[out]*/ MPC::wstring& strAppendTo ,
|
|
/*[in]*/ LPCWSTR szToEscape )
|
|
{
|
|
if(szToEscape)
|
|
{
|
|
WCHAR ch;
|
|
|
|
while((ch = *szToEscape++))
|
|
{
|
|
switch(ch)
|
|
{
|
|
case '&': strAppendTo += L"&" ; break;
|
|
case '"': strAppendTo += L"""; break;
|
|
case '<': strAppendTo += L"<" ; break;
|
|
case '>': strAppendTo += L">" ; break;
|
|
default: strAppendTo += ch ; break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
HRESULT MPC::HTML::ConstructFullTag( /*[out]*/ MPC::wstring& strHTML ,
|
|
/*[in] */ LPCWSTR szTag ,
|
|
/*[in] */ bool fCloseTag ,
|
|
/*[in] */ const MPC::WStringLookup* pmapAttributes ,
|
|
/*[in] */ LPCWSTR szExtraAttributes ,
|
|
/*[in] */ LPCWSTR szBody ,
|
|
/*[in] */ bool fEscapeBody )
|
|
{
|
|
__MPC_FUNC_ENTRY( COMMONID, "MPC::HTML::ConstructFullTag" );
|
|
|
|
HRESULT hr;
|
|
size_t iLen = szBody ? wcslen( szBody ) : 0;
|
|
|
|
__MPC_PARAMCHECK_BEGIN(hr)
|
|
__MPC_PARAMCHECK_STRING_NOT_EMPTY(szTag);
|
|
__MPC_PARAMCHECK_END();
|
|
|
|
|
|
|
|
//
|
|
// Let's allocate enough storage for the common case, so we don't need to allocate at each append...
|
|
//
|
|
if(fEscapeBody) iLen *= 2;
|
|
strHTML.reserve( 1024 + iLen );
|
|
|
|
//
|
|
// Opening tag.
|
|
//
|
|
strHTML.erase(); // We use 'erase' instead of an assignment, because 'erase' just resets the end of string...
|
|
strHTML += L"<";
|
|
strHTML += szTag;
|
|
|
|
if(pmapAttributes)
|
|
{
|
|
MPC::WStringLookupIterConst it = pmapAttributes->begin();
|
|
MPC::WStringLookupIterConst itEnd = pmapAttributes->end ();
|
|
|
|
for(;it != itEnd; it++)
|
|
{
|
|
strHTML += L" ";
|
|
strHTML += it->first;
|
|
strHTML += L"=\"";
|
|
|
|
QuoteEscape( strHTML, it->second.c_str(), '\"' ); //"
|
|
|
|
strHTML += L"\"";
|
|
}
|
|
}
|
|
|
|
if(szExtraAttributes)
|
|
{
|
|
strHTML += L" ";
|
|
strHTML += szExtraAttributes;
|
|
}
|
|
|
|
strHTML += L">";
|
|
|
|
//
|
|
// Optional body.
|
|
//
|
|
if(szBody)
|
|
{
|
|
if(fEscapeBody)
|
|
{
|
|
HTMLEscape( strHTML, szBody );
|
|
}
|
|
else
|
|
{
|
|
strHTML += szBody;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Optional closing tag.
|
|
//
|
|
if(fCloseTag)
|
|
{
|
|
strHTML += L"</";
|
|
strHTML += szTag;
|
|
strHTML += L">";
|
|
}
|
|
|
|
////////////////////
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__MPC_FUNC_CLEANUP;
|
|
|
|
__MPC_FUNC_EXIT(hr);
|
|
}
|
|
|
|
void MPC::HTML::ParseHREF( /*[in] */ LPCWSTR szText ,
|
|
/*[out]*/ MPC::wstring& strBaseURL ,
|
|
/*[out]*/ MPC::WStringLookup& mapQuery )
|
|
{
|
|
LPCWSTR szEnd;
|
|
|
|
mapQuery.clear();
|
|
|
|
SANITIZEWSTR(szText);
|
|
|
|
szEnd = wcsrchr( szText, '?' );
|
|
if(szEnd)
|
|
{
|
|
MPC::wstring strRest( szEnd+1 );
|
|
MPC::wstring::size_type iLen = strRest.size();
|
|
|
|
//
|
|
// Cut before the question mark.
|
|
//
|
|
strBaseURL = MPC::wstring( szText, szEnd );
|
|
|
|
if(iLen)
|
|
{
|
|
MPC::wstring::size_type iStart = 0;
|
|
MPC::wstring::size_type iEnd = 0;
|
|
MPC::wstring::size_type iMid;
|
|
MPC::wstring nameESCAPED;
|
|
MPC::wstring valueESCAPED;
|
|
MPC::wstring name;
|
|
MPC::wstring value;
|
|
|
|
while(1)
|
|
{
|
|
iEnd = strRest.find( '&', iStart ); if(iEnd == strRest.npos) iEnd = iLen;
|
|
iMid = strRest.find( '=', iStart );
|
|
|
|
//
|
|
// If we have an equality sign, split the query part into a name and value part, unescaping the value
|
|
//
|
|
if(iMid != strRest.npos && iMid++ < iEnd)
|
|
{
|
|
nameESCAPED = strRest.substr( iStart, (iMid-1) - iStart );
|
|
valueESCAPED = strRest.substr( iMid , iEnd - iMid );
|
|
}
|
|
else
|
|
{
|
|
nameESCAPED = strRest.substr( iStart, iEnd - iStart );
|
|
valueESCAPED = L"";
|
|
}
|
|
|
|
//
|
|
// Unescape everything.
|
|
//
|
|
name = L""; UrlUnescape( name , nameESCAPED .c_str(), true );
|
|
value = L""; UrlUnescape( value, valueESCAPED.c_str(), true );
|
|
|
|
mapQuery[ name ] = value;
|
|
|
|
|
|
if(iEnd == iLen) break;
|
|
|
|
iStart = iEnd + 1;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
strBaseURL = szText;
|
|
}
|
|
}
|
|
|
|
void MPC::HTML::BuildHREF( /*[out]*/ MPC::wstring& strURL ,
|
|
/*[in ]*/ LPCWSTR szBaseURL ,
|
|
/*[in ]*/ const MPC::WStringLookup& mapQuery )
|
|
{
|
|
bool fFirst = true;
|
|
|
|
|
|
strURL = SAFEWSTR(szBaseURL);
|
|
|
|
for(WStringLookupIterConst it=mapQuery.begin(); it!=mapQuery.end(); it++)
|
|
{
|
|
strURL += fFirst ? L"?" : L"&"; UrlEscape( strURL, it->first .c_str(), true );
|
|
strURL += L"=" ; UrlEscape( strURL, it->second.c_str(), true );
|
|
|
|
fFirst = false;
|
|
}
|
|
}
|
|
|
|
void MPC::HTML::vBuildHREF( /*[out]*/ MPC::wstring& strURL ,
|
|
/*[in ]*/ LPCWSTR szBaseURL ,
|
|
/*[in ]*/ ... )
|
|
{
|
|
bool fFirst = true;
|
|
va_list arglist;
|
|
LPCWSTR szName;
|
|
LPCWSTR szValue;
|
|
|
|
|
|
strURL = SAFEWSTR(szBaseURL);
|
|
|
|
va_start( arglist, szBaseURL );
|
|
while((szName = va_arg(arglist,LPCWSTR)))
|
|
{
|
|
szValue = va_arg(arglist,LPCWSTR); if(!szValue) szValue = L"";
|
|
|
|
strURL += fFirst ? L"?" : L"&"; UrlEscape( strURL, szName , true );
|
|
strURL += L"=" ; UrlEscape( strURL, szValue, true );
|
|
|
|
fFirst = false;
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
HRESULT MPC::HTML::IDispatch_To_IHTMLDocument2( /*[out]*/ CComPtr<IHTMLDocument2>& doc ,
|
|
/*[in] */ IDispatch* pDisp )
|
|
{
|
|
__MPC_FUNC_ENTRY( COMMONID, "MPC::HTML::IDispatch_To_IHTMLDocument2" );
|
|
|
|
HRESULT hr;
|
|
|
|
doc.Release();
|
|
|
|
__MPC_PARAMCHECK_BEGIN(hr)
|
|
__MPC_PARAMCHECK_NOTNULL(pDisp);
|
|
__MPC_PARAMCHECK_END();
|
|
|
|
|
|
//
|
|
// The pointer passed as input can point to any of these things:
|
|
//
|
|
// 1) An IHTMLDocument2 itself.
|
|
// 2) An IWebBrowser2.
|
|
// 3) An IHTMLWindow2.
|
|
// 3) An IHTMLElement.
|
|
//
|
|
if(FAILED(pDisp->QueryInterface( IID_IHTMLDocument2, (LPVOID*)&doc )))
|
|
{
|
|
//
|
|
// Let's try IHTMLWindow2.
|
|
//
|
|
{
|
|
CComPtr<IHTMLWindow2> win;
|
|
|
|
if(SUCCEEDED(pDisp->QueryInterface( IID_IHTMLWindow2, (LPVOID*)&win )))
|
|
{
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, win->get_document( &doc ));
|
|
|
|
if(doc == NULL) __MPC_SET_ERROR_AND_EXIT(hr, E_FAIL);
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, S_OK);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Let's try IWebBrowser2 or IHTMLElement.
|
|
//
|
|
{
|
|
CComPtr<IWebBrowser2> wb;
|
|
CComPtr<IHTMLElement> elem;
|
|
CComPtr<IDispatch> docDisp;
|
|
|
|
if(SUCCEEDED(pDisp->QueryInterface( IID_IWebBrowser2, (LPVOID*)&wb )))
|
|
{
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, wb->get_Document( &docDisp ));
|
|
}
|
|
else if(SUCCEEDED(pDisp->QueryInterface( IID_IHTMLElement, (LPVOID*)&elem )))
|
|
{
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, elem->get_document( &docDisp ));
|
|
}
|
|
|
|
if(docDisp == NULL) __MPC_SET_ERROR_AND_EXIT(hr, E_FAIL);
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, docDisp->QueryInterface( IID_IHTMLDocument2, (LPVOID*)&doc ));
|
|
}
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__MPC_FUNC_CLEANUP;
|
|
|
|
__MPC_FUNC_EXIT(hr);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
HRESULT MPC::HTML::GetFramePath( /*[out]*/ CComBSTR& bstrFrame ,
|
|
/*[in] */ IDispatch* pDisp )
|
|
{
|
|
__MPC_FUNC_ENTRY( COMMONID, "MPC::HTML::GetFramePath" );
|
|
|
|
HRESULT hr;
|
|
CComPtr<IHTMLDocument2> pDoc;
|
|
CComPtr<IHTMLWindow2> pWin;
|
|
CComPtr<IHTMLWindow2> pTop;
|
|
|
|
|
|
//
|
|
// Get to the document and construct the recursive frame name.
|
|
//
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, IDispatch_To_IHTMLDocument2( pDoc, pDisp ));
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, pDoc->get_parentWindow( &pWin )); if(pWin == NULL) __MPC_SET_ERROR_AND_EXIT(hr, E_FAIL);
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, pWin->get_top ( &pTop )); if(pTop == NULL) __MPC_SET_ERROR_AND_EXIT(hr, E_FAIL);
|
|
|
|
while(pWin != pTop)
|
|
{
|
|
CComPtr<IHTMLWindow2> pParent;
|
|
CComBSTR bstrName;
|
|
|
|
pWin->get_name( &bstrName );
|
|
|
|
//
|
|
// Concatenate the frame names, backward.
|
|
//
|
|
if(bstrFrame.Length())
|
|
{
|
|
bstrName += L"/";
|
|
bstrName += bstrFrame;
|
|
}
|
|
bstrFrame = bstrName;
|
|
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, pWin->get_parent( &pParent ));
|
|
|
|
if(pParent == NULL) break;
|
|
|
|
pWin = pParent;
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__MPC_FUNC_CLEANUP;
|
|
|
|
__MPC_FUNC_EXIT(hr);
|
|
}
|
|
|
|
HRESULT MPC::HTML::AreAllTheFramesInTheCompleteState( /*[out]*/ bool& fDone ,
|
|
/*[in] */ IDispatch* pDisp )
|
|
{
|
|
__MPC_FUNC_ENTRY( COMMONID, "MPC::HTML::AreAllTheFramesInTheCompleteState" );
|
|
|
|
HRESULT hr;
|
|
CComPtr<IHTMLDocument2> pDoc;
|
|
CComPtr<IHTMLFramesCollection2> pFrames;
|
|
|
|
fDone = true;
|
|
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, IDispatch_To_IHTMLDocument2( pDoc, pDisp ));
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, pDoc->get_frames( &pFrames ));
|
|
if(pFrames)
|
|
{
|
|
long len;
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, pFrames->get_length( &len ));
|
|
|
|
for(int i=0; i<len; i++)
|
|
{
|
|
CComVariant vIndex = i;
|
|
CComVariant vValue;
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, pFrames->item( &vIndex, &vValue ));
|
|
|
|
if(vValue.vt == VT_DISPATCH)
|
|
{
|
|
CComQIPtr<IHTMLWindow2> fb = vValue.pdispVal;
|
|
if(fb)
|
|
{
|
|
CComPtr<IHTMLDocument2> pDoc2;
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, fb->get_document( &pDoc2 ));
|
|
if(pDoc2)
|
|
{
|
|
CComBSTR bstrReadyState;
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, pDoc2->get_readyState( &bstrReadyState ));
|
|
if(MPC::StrICmp( bstrReadyState, L"complete" ) != 0)
|
|
{
|
|
fDone = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
__MPC_FUNC_CLEANUP;
|
|
|
|
__MPC_FUNC_EXIT(hr);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
HRESULT MPC::HTML::LocateFrame( /*[out]*/ CComPtr<IHTMLWindow2>& win ,
|
|
/*[in]*/ IHTMLElement* pObj ,
|
|
/*[in]*/ LPCWSTR szName )
|
|
{
|
|
__MPC_FUNC_ENTRY( COMMONID, "MPC::HTML::LocateFrame" );
|
|
|
|
HRESULT hr;
|
|
CComPtr<IHTMLDocument2> doc;
|
|
|
|
win.Release();
|
|
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, IDispatch_To_IHTMLDocument2( doc, pObj ));
|
|
|
|
if(szName && szName[0])
|
|
{
|
|
if(!_wcsicmp( szName, L"_top" ))
|
|
{
|
|
CComPtr<IHTMLWindow2> winCurrent;
|
|
|
|
MPC_SCRIPTHELPER_GET__DIRECT__NOTNULL(winCurrent, doc , parentWindow);
|
|
MPC_SCRIPTHELPER_GET__DIRECT__NOTNULL(win , winCurrent, top );
|
|
}
|
|
else
|
|
{
|
|
CComPtr<IHTMLFramesCollection2> frames;
|
|
CComVariant vName( szName );
|
|
CComVariant vFrame;
|
|
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, doc->get_frames( &frames ));
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, frames->item( &vName, &vFrame ));
|
|
MPC_SCRIPTHELPER_FAIL_IF_NOT_AN_OBJECT(vFrame);
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, vFrame.pdispVal->QueryInterface( __uuidof(IHTMLWindow2), (LPVOID*)&win ));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
MPC_SCRIPTHELPER_GET__DIRECT__NOTNULL(win, doc, parentWindow);
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__MPC_FUNC_CLEANUP;
|
|
|
|
__MPC_FUNC_EXIT(hr);
|
|
}
|
|
|
|
HRESULT MPC::HTML::GetEventObject( /*[out]*/ CComPtr<IHTMLEventObj>& ev ,
|
|
/*[in] */ IHTMLElement* pObj )
|
|
{
|
|
__MPC_FUNC_ENTRY( COMMONID, "MPC::HTML::GetEventObject" );
|
|
|
|
HRESULT hr;
|
|
CComPtr<IHTMLDocument2> doc;
|
|
CComPtr<IHTMLWindow2> win;
|
|
|
|
ev.Release();
|
|
|
|
__MPC_PARAMCHECK_BEGIN(hr)
|
|
__MPC_PARAMCHECK_NOTNULL(pObj);
|
|
__MPC_PARAMCHECK_END();
|
|
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, IDispatch_To_IHTMLDocument2( doc, pObj ));
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, doc->get_parentWindow( &win )); if(win == NULL) __MPC_SET_ERROR_AND_EXIT(hr, E_FAIL);
|
|
|
|
MPC_SCRIPTHELPER_GET__DIRECT__NOTNULL(ev, win, event);
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__MPC_FUNC_CLEANUP;
|
|
|
|
__MPC_FUNC_EXIT(hr);
|
|
}
|
|
|
|
|
|
HRESULT MPC::HTML::GetUniqueID( /*[out]*/ CComBSTR& bstrID, /*[in]*/ IHTMLElement* pObj )
|
|
{
|
|
return MPC::COMUtil::GetPropertyByName( pObj, L"uniqueID", bstrID );
|
|
}
|
|
|
|
|
|
HRESULT MPC::HTML::FindFirstParentWithThisTag( /*[out]*/ CComPtr<IHTMLElement>& elem ,
|
|
/*[in] */ IHTMLElement* pObj ,
|
|
/*[in]*/ LPCWSTR szTag )
|
|
{
|
|
__MPC_FUNC_ENTRY( COMMONID, "MPC::HTML::FindFirstParentWithThisTag" );
|
|
|
|
HRESULT hr;
|
|
|
|
elem.Release();
|
|
|
|
__MPC_PARAMCHECK_BEGIN(hr)
|
|
__MPC_PARAMCHECK_STRING_NOT_EMPTY(szTag);
|
|
__MPC_PARAMCHECK_END();
|
|
|
|
|
|
elem = pObj;
|
|
while(elem)
|
|
{
|
|
CComBSTR bstrTag;
|
|
CComPtr<IHTMLElement> parent;
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, elem->get_tagName( &bstrTag ));
|
|
|
|
if(!MPC::StrICmp( bstrTag, szTag )) break;
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, elem->get_parentElement( &parent ));
|
|
elem = parent;
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__MPC_FUNC_CLEANUP;
|
|
|
|
__MPC_FUNC_EXIT(hr);
|
|
}
|
|
|
|
HRESULT MPC::HTML::FindFirstParentWithThisID( /*[out]*/ CComPtr<IHTMLElement>& elem ,
|
|
/*[in] */ IHTMLElement* pObj ,
|
|
/*[in]*/ LPCWSTR szID )
|
|
{
|
|
__MPC_FUNC_ENTRY( COMMONID, "MPC::HTML::FindFirstParentWithThisTag" );
|
|
|
|
HRESULT hr;
|
|
|
|
elem = pObj;
|
|
while(elem)
|
|
{
|
|
CComBSTR bstrID;
|
|
CComPtr<IHTMLElement> parent;
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, elem->get_id( &bstrID ));
|
|
|
|
if(bstrID)
|
|
{
|
|
if(szID == NULL || !_wcsicmp( bstrID, szID ))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, elem->get_parentElement( &parent ));
|
|
elem = parent;
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__MPC_FUNC_CLEANUP;
|
|
|
|
__MPC_FUNC_EXIT(hr);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
HRESULT MPC::HTML::FindElementInCollection( /*[out]*/ CComPtr<IHTMLElement>& elem ,
|
|
/*[in] */ IHTMLElementCollection* coll ,
|
|
/*[in] */ LPCWSTR szID ,
|
|
/*[in] */ int iPos )
|
|
{
|
|
__MPC_FUNC_ENTRY( COMMONID, "MPC::HTML::FindElementInCollection" );
|
|
|
|
HRESULT hr;
|
|
CComPtr<IDispatch> disp;
|
|
CComVariant vName;
|
|
CComVariant vIndex;
|
|
|
|
elem.Release();
|
|
|
|
__MPC_PARAMCHECK_BEGIN(hr)
|
|
__MPC_PARAMCHECK_NOTNULL(coll);
|
|
__MPC_PARAMCHECK_END();
|
|
|
|
|
|
if(szID)
|
|
{
|
|
vName = szID;
|
|
vIndex = iPos;
|
|
}
|
|
else
|
|
{
|
|
vName = iPos;
|
|
}
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, coll->item( vName, vIndex, &disp ));
|
|
if(disp)
|
|
{
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, disp.QueryInterface( &elem ));
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__MPC_FUNC_CLEANUP;
|
|
|
|
__MPC_FUNC_EXIT(hr);
|
|
}
|
|
|
|
HRESULT MPC::HTML::FindElement( /*[out]*/ CComPtr<IHTMLElement>& elem ,
|
|
/*[in] */ IHTMLElement* pObj ,
|
|
/*[in] */ LPCWSTR szID ,
|
|
/*[in] */ int iPos )
|
|
{
|
|
__MPC_FUNC_ENTRY( COMMONID, "MPC::HTML::FindElement" );
|
|
|
|
HRESULT hr;
|
|
CComPtr<IHTMLElementCollection> coll;
|
|
|
|
__MPC_PARAMCHECK_BEGIN(hr)
|
|
__MPC_PARAMCHECK_NOTNULL(pObj);
|
|
__MPC_PARAMCHECK_END();
|
|
|
|
|
|
MPC_SCRIPTHELPER_GET_OBJECT__NOTNULL(coll, pObj, all);
|
|
|
|
__MPC_SET_ERROR_AND_EXIT(hr, FindElementInCollection( elem, coll, szID, iPos ));
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__MPC_FUNC_CLEANUP;
|
|
|
|
__MPC_FUNC_EXIT(hr);
|
|
}
|
|
|
|
HRESULT MPC::HTML::FindChild( /*[out]*/ CComPtr<IHTMLElement>& elem ,
|
|
/*[in] */ IHTMLElement* pObj ,
|
|
/*[in] */ LPCWSTR szID ,
|
|
/*[in] */ int iPos )
|
|
{
|
|
__MPC_FUNC_ENTRY( COMMONID, "MPC::HTML::FindChild" );
|
|
|
|
HRESULT hr;
|
|
CComPtr<IHTMLElementCollection> coll;
|
|
|
|
__MPC_PARAMCHECK_BEGIN(hr)
|
|
__MPC_PARAMCHECK_NOTNULL(pObj);
|
|
__MPC_PARAMCHECK_END();
|
|
|
|
|
|
MPC_SCRIPTHELPER_GET_OBJECT__NOTNULL(coll, pObj, children);
|
|
|
|
__MPC_SET_ERROR_AND_EXIT(hr, FindElementInCollection( elem, coll, szID, iPos ));
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__MPC_FUNC_CLEANUP;
|
|
|
|
__MPC_FUNC_EXIT(hr);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
HRESULT MPC::HTML::EnumerateCollection( /*[out]*/ IHTMLElementList& lst ,
|
|
/*[in] */ IHTMLElementCollection* pColl ,
|
|
/*[in] */ LPCWSTR szFilterID )
|
|
{
|
|
__MPC_FUNC_ENTRY( COMMONID, "MPC::HTML::EnumerateCollection" );
|
|
|
|
HRESULT hr;
|
|
long lLen;
|
|
long lPos;
|
|
CComVariant vName;
|
|
CComVariant vIndex;
|
|
bool fFilterAsTag;
|
|
|
|
MPC::ReleaseAll( lst );
|
|
|
|
__MPC_PARAMCHECK_BEGIN(hr)
|
|
__MPC_PARAMCHECK_NOTNULL(pColl);
|
|
__MPC_PARAMCHECK_END();
|
|
|
|
|
|
if(szFilterID && szFilterID[0] == '<')
|
|
{
|
|
fFilterAsTag = true;
|
|
|
|
szFilterID++;
|
|
}
|
|
else
|
|
{
|
|
fFilterAsTag = false;
|
|
}
|
|
|
|
|
|
MPC_SCRIPTHELPER_GET__DIRECT(lLen, pColl, length);
|
|
|
|
for(lPos=0; lPos<lLen; lPos++)
|
|
{
|
|
CComPtr<IDispatch > disp;
|
|
CComPtr<IHTMLElement> elem;
|
|
|
|
vName = lPos;
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, pColl->item( vName, vIndex, &disp ));
|
|
if(disp == NULL) __MPC_SET_ERROR_AND_EXIT(hr, E_NOINTERFACE);
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, disp.QueryInterface( &elem ));
|
|
|
|
//
|
|
// If we receive a string as input, filter out all the tags not matching with the ID or TAG.
|
|
//
|
|
if(szFilterID)
|
|
{
|
|
CComBSTR bstr;
|
|
|
|
if(fFilterAsTag)
|
|
{
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, elem->get_tagName( &bstr ));
|
|
}
|
|
else
|
|
{
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, elem->get_id( &bstr ));
|
|
}
|
|
|
|
|
|
if(MPC::StrICmp( bstr, szFilterID )) continue;
|
|
}
|
|
|
|
|
|
lst.push_back( elem.Detach() );
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__MPC_FUNC_CLEANUP;
|
|
|
|
__MPC_FUNC_EXIT(hr);
|
|
}
|
|
|
|
HRESULT MPC::HTML::EnumerateElements( /*[out]*/ IHTMLElementList& lst ,
|
|
/*[in] */ IHTMLElement* pObj ,
|
|
/*[in] */ LPCWSTR szFilterID )
|
|
{
|
|
__MPC_FUNC_ENTRY( COMMONID, "MPC::HTML::EnumerateElements" );
|
|
|
|
HRESULT hr;
|
|
CComPtr<IHTMLElementCollection> coll;
|
|
|
|
__MPC_PARAMCHECK_BEGIN(hr)
|
|
__MPC_PARAMCHECK_NOTNULL(pObj);
|
|
__MPC_PARAMCHECK_END();
|
|
|
|
|
|
MPC_SCRIPTHELPER_GET_OBJECT__NOTNULL(coll, pObj, all);
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, EnumerateCollection( lst, coll, szFilterID ));
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__MPC_FUNC_CLEANUP;
|
|
|
|
__MPC_FUNC_EXIT(hr);
|
|
}
|
|
|
|
HRESULT MPC::HTML::EnumerateChildren( /*[out]*/ IHTMLElementList& lst ,
|
|
/*[in] */ IHTMLElement* pObj ,
|
|
/*[in] */ LPCWSTR szFilterID )
|
|
{
|
|
__MPC_FUNC_ENTRY( COMMONID, "MPC::HTML::EnumerateChildren" );
|
|
|
|
HRESULT hr;
|
|
CComPtr<IHTMLElementCollection> coll;
|
|
|
|
__MPC_PARAMCHECK_BEGIN(hr)
|
|
__MPC_PARAMCHECK_NOTNULL(pObj);
|
|
__MPC_PARAMCHECK_END();
|
|
|
|
|
|
MPC_SCRIPTHELPER_GET_OBJECT__NOTNULL(coll, pObj, children);
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, EnumerateCollection( lst, coll, szFilterID ));
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__MPC_FUNC_CLEANUP;
|
|
|
|
__MPC_FUNC_EXIT(hr);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
HRESULT MPC::HTML::FindStyle( /*[out]*/ CComPtr<IHTMLRuleStyle>& style ,
|
|
/*[in ]*/ IHTMLElement* pObj ,
|
|
/*[in ]*/ LPCWSTR szName )
|
|
{
|
|
__MPC_FUNC_ENTRY( COMMONID, "MPC::HTML::FindStyle" );
|
|
|
|
HRESULT hr;
|
|
CComPtr<IHTMLDocument2> doc;
|
|
CComPtr<IHTMLStyleSheetsCollection> styles;
|
|
VARIANT vIdx;
|
|
long lNumStyles;
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, IDispatch_To_IHTMLDocument2( doc, pObj ));
|
|
|
|
MPC_SCRIPTHELPER_GET__DIRECT__NOTNULL(styles , doc , styleSheets);
|
|
MPC_SCRIPTHELPER_GET__DIRECT (lNumStyles, styles, length );
|
|
|
|
vIdx.vt = VT_I4;
|
|
for(vIdx.iVal=0; vIdx.iVal<lNumStyles; vIdx.iVal++)
|
|
{
|
|
CComQIPtr<IHTMLStyleSheet> css;
|
|
CComVariant v;
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, styles->item( &vIdx, &v ));
|
|
if(v.vt == VT_DISPATCH && (css = v.pdispVal))
|
|
{
|
|
CComPtr<IHTMLStyleSheetRulesCollection> rules;
|
|
long lNumRules;
|
|
|
|
MPC_SCRIPTHELPER_GET__DIRECT__NOTNULL(rules , css , rules );
|
|
MPC_SCRIPTHELPER_GET__DIRECT (lNumRules, rules, length);
|
|
|
|
for(long l=0; l<lNumRules; l++)
|
|
{
|
|
CComPtr<IHTMLStyleSheetRule> rule;
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, rules->item( l, &rule ));
|
|
if(rule)
|
|
{
|
|
CComBSTR bstrName;
|
|
|
|
MPC_SCRIPTHELPER_GET__DIRECT(bstrName, rule, selectorText);
|
|
|
|
if(!MPC::StrICmp( bstrName, szName ))
|
|
{
|
|
__MPC_SET_ERROR_AND_EXIT(hr, rule->get_style( &style ));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__MPC_FUNC_CLEANUP;
|
|
|
|
__MPC_FUNC_EXIT(hr);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
HRESULT MPC::HTML::GetAttribute( /*[out]*/ CComPtr<IHTMLDOMAttribute>& attr ,
|
|
/*[in]*/ IHTMLElement* pObj ,
|
|
/*[in]*/ LPCWSTR szName )
|
|
{
|
|
__MPC_FUNC_ENTRY( COMMONID, "MPC::HTML::GetAttribute" );
|
|
|
|
HRESULT hr;
|
|
CComPtr<IHTMLDOMNode> dom;
|
|
CComPtr<IHTMLAttributeCollection> coll;
|
|
CComPtr<IDispatch> dispAttr;
|
|
CComVariant v( szName );
|
|
|
|
__MPC_PARAMCHECK_BEGIN(hr)
|
|
__MPC_PARAMCHECK_NOTNULL(pObj);
|
|
__MPC_PARAMCHECK_END();
|
|
|
|
|
|
attr.Release();
|
|
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, pObj->QueryInterface( IID_IHTMLDOMNode, (LPVOID *)&dom ));
|
|
|
|
MPC_SCRIPTHELPER_GET_OBJECT__NOTNULL(coll, dom, attributes);
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, coll->item( &v, &dispAttr ));
|
|
if(dispAttr)
|
|
{
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, dispAttr->QueryInterface( &attr ));
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__MPC_FUNC_CLEANUP;
|
|
|
|
__MPC_FUNC_EXIT(hr);
|
|
}
|
|
|
|
HRESULT MPC::HTML::GetAttribute( /*[out]*/ CComBSTR& value ,
|
|
/*[in]*/ IHTMLElement* pObj ,
|
|
/*[in]*/ LPCWSTR szName )
|
|
{
|
|
__MPC_FUNC_ENTRY( COMMONID, "MPC::HTML::GetAttribute" );
|
|
|
|
HRESULT hr;
|
|
CComPtr<IHTMLDOMAttribute> attr;
|
|
|
|
|
|
value.Empty();
|
|
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, GetAttribute( attr, pObj, szName ));
|
|
if(attr)
|
|
{
|
|
MPC_SCRIPTHELPER_GET_STRING__VARIANT(value, attr, nodeValue);
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__MPC_FUNC_CLEANUP;
|
|
|
|
__MPC_FUNC_EXIT(hr);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
typedef struct
|
|
{
|
|
const WCHAR* szName;
|
|
DWORD dwValue;
|
|
} COLORVALUE_PAIR;
|
|
|
|
static const COLORVALUE_PAIR c_rgColorNames[] =
|
|
{
|
|
{ L"aliceblue" , 0xfff8f0 },
|
|
{ L"antiquewhite" , 0xd7ebfa },
|
|
{ L"aqua" , 0xffff00 },
|
|
{ L"aquamarine" , 0xd4ff7f },
|
|
{ L"azure" , 0xfffff0 },
|
|
{ L"beige" , 0xdcf5f5 },
|
|
{ L"bisque" , 0xc4e4ff },
|
|
{ L"black" , 0x000000 },
|
|
{ L"blanchedalmond" , 0xcdebff },
|
|
{ L"blue" , 0xff0000 },
|
|
{ L"blueviolet" , 0xe22b8a },
|
|
{ L"brown" , 0x2a2aa5 },
|
|
{ L"burlywood" , 0x87b8de },
|
|
{ L"cadetblue" , 0xa09e5f },
|
|
{ L"chartreuse" , 0x00ff7f },
|
|
{ L"chocolate" , 0x1e69d2 },
|
|
{ L"coral" , 0x507fff },
|
|
{ L"cornflowerblue" , 0xed9564 },
|
|
{ L"cornsilk" , 0xdcf8ff },
|
|
{ L"crimson" , 0x3c14dc },
|
|
{ L"cyan" , 0xffff00 },
|
|
{ L"darkblue" , 0x8b0000 },
|
|
{ L"darkcyan" , 0x8b8b00 },
|
|
{ L"darkgoldenrod" , 0x0b86b8 },
|
|
{ L"darkgray" , 0xa9a9a9 },
|
|
{ L"darkgreen" , 0x006400 },
|
|
{ L"darkkhaki" , 0x6bb7bd },
|
|
{ L"darkmagenta" , 0x8b008b },
|
|
{ L"darkolivegreen" , 0x2f6b55 },
|
|
{ L"darkorange" , 0x008cff },
|
|
{ L"darkorchid" , 0xcc3299 },
|
|
{ L"darkred" , 0x00008b },
|
|
{ L"darksalmon" , 0x7a96e9 },
|
|
{ L"darkseagreen" , 0x8fbc8f },
|
|
{ L"darkslateblue" , 0x8b3d48 },
|
|
{ L"darkslategray" , 0x4f4f2f },
|
|
{ L"darkturquoise" , 0xd1ce00 },
|
|
{ L"darkviolet" , 0xd30094 },
|
|
{ L"deeppink" , 0x9314ff },
|
|
{ L"deepskyblue" , 0xffbf00 },
|
|
{ L"dimgray" , 0x696969 },
|
|
{ L"dodgerblue" , 0xff901e },
|
|
{ L"firebrick" , 0x2222b2 },
|
|
{ L"floralwhite" , 0xf0faff },
|
|
{ L"forestgreen" , 0x228b22 },
|
|
{ L"fuchsia" , 0xff00ff },
|
|
{ L"gainsboro" , 0xdcdcdc },
|
|
{ L"ghostwhite" , 0xfff8f8 },
|
|
{ L"gold" , 0x00d7ff },
|
|
{ L"goldenrod" , 0x20a5da },
|
|
{ L"gray" , 0x808080 },
|
|
{ L"green" , 0x008000 },
|
|
{ L"greenyellow" , 0x2fffad },
|
|
{ L"honeydew" , 0xf0fff0 },
|
|
{ L"hotpink" , 0xb469ff },
|
|
{ L"indianred" , 0x5c5ccd },
|
|
{ L"indigo" , 0x82004b },
|
|
{ L"ivory" , 0xf0ffff },
|
|
{ L"khaki" , 0x8ce6f0 },
|
|
{ L"lavender" , 0xfae6e6 },
|
|
{ L"lavenderblush" , 0xf5f0ff },
|
|
{ L"lawngreen" , 0x00fc7c },
|
|
{ L"lemonchiffon" , 0xcdfaff },
|
|
{ L"lightblue" , 0xe6d8ad },
|
|
{ L"lightcoral" , 0x8080f0 },
|
|
{ L"lightcyan" , 0xffffe0 },
|
|
{ L"lightgoldenrodyellow", 0xd2fafa },
|
|
{ L"lightgreen" , 0x90ee90 },
|
|
{ L"lightgrey" , 0xd3d3d3 },
|
|
{ L"lightpink" , 0xc1b6ff },
|
|
{ L"lightsalmon" , 0x7aa0ff },
|
|
{ L"lightseagreen" , 0xaab220 },
|
|
{ L"lightskyblue" , 0xface87 },
|
|
{ L"lightslategray" , 0x998877 },
|
|
{ L"lightsteelblue" , 0xdec4b0 },
|
|
{ L"lightyellow" , 0xe0ffff },
|
|
{ L"lime" , 0x00ff00 },
|
|
{ L"limegreen" , 0x32cd32 },
|
|
{ L"linen" , 0xe6f0fa },
|
|
{ L"magenta" , 0xff00ff },
|
|
{ L"maroon" , 0x000080 },
|
|
{ L"mediumaquamarine" , 0xaacd66 },
|
|
{ L"mediumblue" , 0xcd0000 },
|
|
{ L"mediumorchid" , 0xd355ba },
|
|
{ L"mediumpurple" , 0xdb7093 },
|
|
{ L"mediumseagreen" , 0x71b33c },
|
|
{ L"mediumslateblue" , 0xee687b },
|
|
{ L"mediumspringgreen" , 0x9afa00 },
|
|
{ L"mediumturquoise" , 0xccd148 },
|
|
{ L"mediumvioletred" , 0x8515c7 },
|
|
{ L"midnightblue" , 0x701919 },
|
|
{ L"mintcream" , 0xfafff5 },
|
|
{ L"mistyrose" , 0xe1e4ff },
|
|
{ L"moccasin" , 0xb5e4ff },
|
|
{ L"navajowhite" , 0xaddeff },
|
|
{ L"navy" , 0x800000 },
|
|
{ L"oldlace" , 0xe6f5fd },
|
|
{ L"olive" , 0x008080 },
|
|
{ L"olivedrab" , 0x238e6b },
|
|
{ L"orange" , 0x00a5ff },
|
|
{ L"orangered" , 0x0045ff },
|
|
{ L"orchid" , 0xd670da },
|
|
{ L"palegoldenrod" , 0xaae8ee },
|
|
{ L"palegreen" , 0x98fb98 },
|
|
{ L"paleturquoise" , 0xeeeeaf },
|
|
{ L"palevioletred" , 0x9370db },
|
|
{ L"papayawhip" , 0xd5efff },
|
|
{ L"peachpuff" , 0xb9daff },
|
|
{ L"peru" , 0x3f85cd },
|
|
{ L"pink" , 0xcbc0ff },
|
|
{ L"plum" , 0xdda0dd },
|
|
{ L"powderblue" , 0xe6e0b0 },
|
|
{ L"purple" , 0x800080 },
|
|
{ L"red" , 0x0000ff },
|
|
{ L"rosybrown" , 0x8f8fbc },
|
|
{ L"royalblue" , 0xe16941 },
|
|
{ L"saddlebrown" , 0x13458b },
|
|
{ L"salmon" , 0x7280fa },
|
|
{ L"sandybrown" , 0x60a4f4 },
|
|
{ L"seagreen" , 0x578b2e },
|
|
{ L"seashell" , 0xeef5ff },
|
|
{ L"sienna" , 0x2d52a0 },
|
|
{ L"silver" , 0xc0c0c0 },
|
|
{ L"skyblue" , 0xebce87 },
|
|
{ L"slateblue" , 0xcd5a6a },
|
|
{ L"slategray" , 0x908070 },
|
|
{ L"snow" , 0xfafaff },
|
|
{ L"springgreen" , 0x7fff00 },
|
|
{ L"steelblue" , 0xb48246 },
|
|
{ L"tan" , 0x8cb4d2 },
|
|
{ L"teal" , 0x808000 },
|
|
{ L"thistle" , 0xd8bfd8 },
|
|
{ L"tomato" , 0x4763ff },
|
|
{ L"turquoise" , 0xd0e040 },
|
|
{ L"violet" , 0xee82ee },
|
|
{ L"wheat" , 0xb3def5 },
|
|
{ L"white" , 0xffffff },
|
|
{ L"whitesmoke" , 0xf5f5f5 },
|
|
{ L"yellow" , 0x00ffff },
|
|
{ L"yellowgreen" , 0x32cd9a }
|
|
};
|
|
|
|
static const COLORVALUE_PAIR c_rgSystemColors[] =
|
|
{
|
|
{ L"activeborder" , COLOR_ACTIVEBORDER },
|
|
{ L"activecaption" , COLOR_ACTIVECAPTION },
|
|
{ L"appworkspace" , COLOR_APPWORKSPACE },
|
|
{ L"background" , COLOR_BACKGROUND },
|
|
{ L"buttonface" , COLOR_BTNFACE },
|
|
{ L"buttonhighlight" , COLOR_BTNHIGHLIGHT },
|
|
{ L"buttonshadow" , COLOR_BTNSHADOW },
|
|
{ L"buttontext" , COLOR_BTNTEXT },
|
|
{ L"captiontext" , COLOR_CAPTIONTEXT },
|
|
{ L"gradientactivecaption" , COLOR_GRADIENTACTIVECAPTION },
|
|
{ L"gradientinactivecaption", COLOR_GRADIENTINACTIVECAPTION },
|
|
{ L"graytext" , COLOR_GRAYTEXT },
|
|
{ L"highlight" , COLOR_HIGHLIGHT },
|
|
{ L"highlighttext" , COLOR_HIGHLIGHTTEXT },
|
|
{ L"hotlight" , COLOR_HOTLIGHT },
|
|
{ L"inactiveborder" , COLOR_INACTIVEBORDER },
|
|
{ L"inactivecaption" , COLOR_INACTIVECAPTION },
|
|
{ L"inactivecaptiontext" , COLOR_INACTIVECAPTIONTEXT },
|
|
{ L"infobackground" , COLOR_INFOBK },
|
|
{ L"infotext" , COLOR_INFOTEXT },
|
|
{ L"menu" , COLOR_MENU },
|
|
{ L"menutext" , COLOR_MENUTEXT },
|
|
{ L"scrollbar" , COLOR_SCROLLBAR },
|
|
{ L"threeddarkshadow" , COLOR_3DDKSHADOW },
|
|
{ L"threedface" , COLOR_3DFACE },
|
|
{ L"threedhighlight" , COLOR_3DHIGHLIGHT },
|
|
{ L"threedlightshadow" , COLOR_3DLIGHT },
|
|
{ L"threedshadow" , COLOR_3DSHADOW },
|
|
{ L"window" , COLOR_WINDOW },
|
|
{ L"windowframe" , COLOR_WINDOWFRAME },
|
|
{ L"windowtext" , COLOR_WINDOWTEXT },
|
|
};
|
|
|
|
static const COLORVALUE_PAIR* local_LookupName( /*[in]*/ const COLORVALUE_PAIR* tbl ,
|
|
/*[in]*/ int iSize ,
|
|
/*[in]*/ LPCWSTR szText )
|
|
{
|
|
while(iSize-- > 0)
|
|
{
|
|
if(!_wcsicmp( tbl->szName, szText )) return tbl;
|
|
|
|
tbl++;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
bool MPC::HTML::ConvertColor( /*[in]*/ VARIANT& v, /*[out]*/ COLORREF& color, /*[out]*/ bool& fSystem )
|
|
{
|
|
color = RGB(255,255,255);
|
|
fSystem = false;
|
|
|
|
if(v.vt == VT_I4)
|
|
{
|
|
color = (COLORREF)v.iVal;
|
|
|
|
return true;
|
|
}
|
|
|
|
if(v.vt == VT_BSTR && v.bstrVal)
|
|
{
|
|
const COLORVALUE_PAIR* ptr;
|
|
|
|
ptr = local_LookupName( c_rgColorNames, ARRAYSIZE(c_rgColorNames), v.bstrVal );
|
|
if(ptr)
|
|
{
|
|
color = (COLORREF)ptr->dwValue;
|
|
|
|
return true;
|
|
}
|
|
|
|
ptr = local_LookupName( c_rgSystemColors, ARRAYSIZE(c_rgSystemColors), v.bstrVal );
|
|
if(ptr)
|
|
{
|
|
color = (COLORREF)::GetSysColor( ptr->dwValue );
|
|
fSystem = true;
|
|
|
|
return true;
|
|
}
|
|
|
|
if(v.bstrVal[0] == '#')
|
|
{
|
|
int iRED;
|
|
int iGREEN;
|
|
int iBLUE;
|
|
|
|
if(swscanf( &v.bstrVal[1], L"%02x%02x%02x", &iRED, &iGREEN, &iBLUE ) == 3)
|
|
{
|
|
color = RGB( iRED, iGREEN, iBLUE );
|
|
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|