不知道有没有朋友用过搜索引擎中的关键字高亮显示(Highlight功能),这种功能的实现很简单,但是效果却是很惊人的。
首先,你要有一个IHTMLDocument2的接口指针,如果没有,你可以通过使用IWebBrowser2Ptr接口的get_Document方法得到一个IDispatch指针,然后通过它查询接口IID_IHTMLDocument2,就搞定了。(什么?你不知道怎么得到IWebBrowser2Ptr指针,OK,我也帮不了你了。)
然后,通过IHTMLDocument2接口指针,我们可以查询得到IID_IMarkupContainer和IID_IMarkupServices接口的指针,然后使用IMarkupServices接口指针生成两个关键的接口指针IMarkupPointer(注意,是两个,为什么是两个呢?在超文本里查找Element,就好像三明治一样,要用两个指针夹着去找)。
再然后,我们要把两个IMarkupPointer移到生成的IMarkupContainer上去,接着,我们就可以查找文本了,当然,之前,我们还要将文本生成适当的字符形式(稍后详细的代码中有说明),接着的事就简单了,生成一个Attribute的Element,然后利用IMarkupServices加到对象中去,再进行三明治的指针接力(后一个指针移到前一个指针的位置上去),查找下一段文本。
再然后呢?(重复了吧,汗......),没有然后了,已经给文本上色了.......慢,我们只提到了上色,怎样把上的色(Element)去掉?好,你能想到这一点,说明你一定的编程实践经验了。那么,我们还是刚才的那段代码,只要使用IMarkupPointer的CurrentScope方法和IMarkupServices的RemoveElement方法组合,就能删掉添加的Element了。
完了,这次是真的完了。
/******************************************************************* * MarkWords(): Logic of whether set highlight text or clear it * * parameter: sWord , the aid-Text for highlight * * return: TRUE if set success , else return FALSE * * DATE: 2002.3.5 * * TeddyWing * ********************************************************************/ BOOL CBiglobeToolBar::SetMyColor(CString sWord, BOOL mFlag) { IHTMLDocument2 * m_pHtmlDoc2; IMarkupServices * pMS; IMarkupContainer * pMarkup; IMarkupPointer * pPtr1, * pPtr2; unsigned short * mSet = L"COLOR=#0000ff STYLE=\"background-color:#ff009c\""; // Font attribute
if (0 == m_pBand->m_pIE) return FALSE;
LPDISPATCH lpDispatch; HRESULT hr = m_pBand->m_pIE->get_Document(&lpDispatch); ASSERT(lpDispatch); hr = lpDispatch->QueryInterface(IID_IHTMLDocument2, (void**)&m_pHtmlDoc2);
if (m_pHtmlDoc2) { hr = m_pHtmlDoc2->QueryInterface( IID_IMarkupContainer, (void **) & pMarkup ); hr = m_pHtmlDoc2->QueryInterface( IID_IMarkupServices, (void **) & pMS ); } else return FALSE;
hr = pMS->CreateMarkupPointer( & pPtr1 ); hr = pMS->CreateMarkupPointer( & pPtr2 );
hr = pPtr1->SetGravity( POINTER_GRAVITY_Right ); hr = pPtr2->SetGravity( POINTER_GRAVITY_Left ); hr = pPtr1->MoveToContainer( pMarkup, TRUE ); hr = pPtr2->MoveToContainer( pMarkup, FALSE );
int nFromLen = sWord.GetLength()+1; // Create aid-text OLECHAR * poSearchStr; poSearchStr = new OLECHAR[ nFromLen]; MultiByteToWideChar( CP_ACP, 0, sWord, -1, poSearchStr, nFromLen);
while(TRUE) { // Find text hr = pPtr1->FindText( poSearchStr, 0, pPtr2, NULL );
if (S_FALSE == hr) break;// did not find the text
IHTMLElement *pFontEl;
if (TRUE == mFlag){ hr = pMS->CreateElement(TAGID_FONT, mSet, &pFontEl); // create FONT element with attributes for selection hr = pMS->InsertElement( pFontEl, pPtr1, pPtr2); // Insert created element to context pPtr1->MoveToPointer(pPtr2); // Continue searching } else{ // Remove last created element in the context hr = pPtr1->CurrentScope( &pFontEl); hr = pMS->RemoveElement( pFontEl); pPtr1->MoveToPointer( pPtr2); // Continue searching } } delete poSearchStr;
return TRUE; } 
|