인터넷 익스플로러를 사용하면서 마우스가 위치한 곳의 링크나 문자열을 알아보고 싶을 때가 생긴다.
마우스가 위치한 곳의 단어나 링크를 알아보자.
[개발/MFC] 마우스가 위치한 곳의 정확한 단어를 얻기
마우스가 위치한 곳의 정확한 단어를 얻기
[출처] http://blog.naver.com/PostView.nhn?blogId=kkt3212&logNo=100052743892&parentCategoryNo=&categoryNo=&viewDate=&isShowPopularPosts=false&from=postView
마우스가 위치한 곳의 정확한 단어를 얻기
/**
모든 IHTMLDocument2 문서에 도규먼트 와처를 다는 것 보다는
클릭시 마우스아래의 태그가 무엇인지를 파악하는 것이 더 낫다..
*/
#include <Oleacc.h>
#pragma comment(lib,_T("Oleacc.lib"))
/**
문서의 좌측 상단을 기준으로 해당 Element가 Width, Height를 구하는데 부모 Element를 타고 올라가서
상대값을 각각 합친다.
*/
void GetOffsetParentRecursion(long &left, long&top, CComQIPtr<IHTMLElement> &pElem)
{
long x=0, y=0;
pElem->get_offsetLeft(&x);
pElem->get_offsetTop(&y) ;
left += x;
top += y;
CComQIPtr<IHTMLElement> pElemParent;
pElem->get_offsetParent(&pElemParent);
if( pElemParent)
GetOffsetParentRecursion(left, top, pElemParent);
}
/**
IHTMLElement가 있는 스크린 좌표의 left,top의 좌표 ,offsetHeight의 크기 좌표를 얻는다.
*/
bool GetHtmlElementScreenXY(long& Screenleft,
long& Screentop,
//long& offsetHeight,
long& clientLeft,
long& clientTop,
CComQIPtr<IHTMLDocument2> pDoc2 ,
CComQIPtr<IHTMLElement> pElem )
{
long nBodyClientLeft =0, nBodyClientTop=0;
CComPtr<IHTMLElement> pBodyElem;
pDoc2->get_body(&pBodyElem);
if(pBodyElem)
{
CComQIPtr<IHTMLElement2> pBody = pBodyElem;
if(pBody)
{
pBody->get_clientLeft(&nBodyClientLeft) ;
pBody->get_clientTop (&nBodyClientTop) ;
}
}
//문서 기준으로 해당 패스워드 필드가 존재하는 좌표를 구한다..
//부모 Element를 타고 올라가서 모든 offsetLeft와 offsetTop을 합친다.
long offsetLeftSum = 0, offsetTopSum = 0;
GetOffsetParentRecursion(offsetLeftSum, offsetTopSum, pElem);
//바디 클라이언트와 합쳐서 정확한 left, top을 구한다. IHTMLDocumnet2 기준이다.
int nDocumnetLeft = nBodyClientLeft + offsetLeftSum ;
int nDocumnetTop = nBodyClientTop + offsetTopSum;
CComPtr<IHTMLWindow2> pWin2 ;
pDoc2->get_parentWindow(&pWin2) ;
if(! pWin2)
return false;
CComQIPtr<IHTMLWindow3> pWin3 = pWin2;
if( ! pWin3 )
return false;
long nScreenLeft =0, nScreenTop = 0; //프레임 문서의 왼쪽 위 좌표인데, 스크린 기준이다.
pWin3->get_screenLeft(&nScreenLeft);
pWin3->get_screenTop(&nScreenTop);
//스크롤을 맨위로 맨왼쪽으로 옮겨야 해당 좌표기준이 맞게된다.
//pWin2->scroll(0,0);
Screenleft = nScreenLeft + nDocumnetLeft;
Screentop = nScreenTop + nDocumnetTop;
clientLeft = nDocumnetLeft;
clientTop = nDocumnetTop;
//pElem->get_offsetHeight(&offsetHeight);
return true;
}
void CBDBand::UserClick()
{
try
{
POINT ptScreen;
::GetCursorPos(&ptScreen);
CComPtr<IAccessible> pAccess;
CComVariant var;
HRESULT hr = AccessibleObjectFromPoint(ptScreen, &pAccess, &var) ;
if( FAILED(hr))
{
throw FALSE;
}
CComQIPtr<IServiceProvider > pSP = pAccess;
if(!pSP)
throw FALSE;
CComPtr<IHTMLElement> pElem;
pSP->QueryService(IID_IHTMLElement, IID_IHTMLElement, (void**)&pElem);
if(!pElem)
throw FALSE;
//Alt가 눌려져 있는가?
BOOL bSearchDic = (0x8000 & GetAsyncKeyState(VK_MENU)) == 0x8000;
if(bSearchDic)
{
CComPtr<IDispatch> pDocDisp;
pElem->get_document(&pDocDisp);
if( !pDocDisp)
throw FALSE;
CComQIPtr<IHTMLDocument2> pDoc2 = pDocDisp;
if( ! pDoc2)
throw FALSE;
CComPtr<IHTMLElement> pBodyElem;
pDoc2->get_body(&pBodyElem);
if( ! pBodyElem)
throw FALSE;
CComQIPtr<IHTMLBodyElement> pBody = pBodyElem;
if( ! pBody)
throw FALSE;
CComQIPtr<IHTMLTxtRange> spHTMLTxtRange;
pBody->createTextRange(&spHTMLTxtRange);
if( ! spHTMLTxtRange)
throw FALSE;
CComQIPtr<IHTMLElement> pElem2 = pElem;
if( !pElem2)
throw FALSE;
long ScreenLeft, ScreenTop, ClientLeft, ClientTop;
if( ! GetHtmlElementScreenXY(ScreenLeft, ScreenTop, ClientLeft, ClientTop, pDoc2, pElem2))
throw FALSE;
POINT pt;
GetCursorPos(&pt);
long dx = pt.x - ScreenLeft;
long dy = pt.y - ScreenTop;
long ClientX = ClientLeft + dx;
long ClientY = ClientTop + dy;
spHTMLTxtRange->moveToPoint(ClientX, ClientY);
CComBSTR bsText;
CComBSTR bsUnit(L"word");
VARIANT_BOOL bSuccess;
spHTMLTxtRange->expand(bsUnit, &bSuccess);
spHTMLTxtRange->get_text(&bsText);
CString sKeyword(bsText);
sKeyword.Replace(" ","");
m_strSearchDic = sKeyword;
if(m_strSearchDic.GetLength())
{
m_bUserClickedLink = TRUE;
m_wndToolBar.PostMessage(OCM_COMMAND, IDM_DIC_SEARCH, 0);
}
}else
{
CComBSTR bsTagName;
while(TRUE)
{
if(FAILED(pElem->get_tagName(&bsTagName)))
break;
bsTagName.ToUpper();
if (bsTagName == L"BODY")
break; // did not click a link
if (bsTagName == L"A" ||
bsTagName == L"AREA" ||
bsTagName == L"INPUT" ||
bsTagName == L"IMG")
{
m_bUserClickedLink=TRUE;
g_dwClickTime = GetTickCount();
break;
}
CComPtr<IHTMLElement> spParentElem;
hr = pElem->get_parentElement(&spParentElem);
if (FAILED(hr) || !spParentElem)
break;
pElem = spParentElem;
}
}
}catch(...)
{
m_bUserClickedLink=TRUE;
}
}
'IT-개발,DB' 카테고리의 다른 글
[개발/IE] 인터넷 익스플로러 새 탭 페이지 설정하는 방법 (0) | 2012.07.31 |
---|---|
[개발/MFC] 마우스가 위치한 곳의 IHTMLDocument2의 주소와 태그를 얻기 (0) | 2012.07.22 |
[개발/MFC] 실행중인 프로세스 강제 종료시키기 (0) | 2012.07.16 |
[개발/VC++] 탭 브라우저 윈도우 핸들 구하기 (0) | 2012.07.16 |
[IT/개발] DevOps, 개발과 운영의 새로운 문화 (0) | 2012.06.22 |
댓글