标签:from const array 规律 hwnd sleep fun 需要 标签
最近因为工作需要,需要写一个获取IE元素屏幕坐标的方法,用到了delphi2010自带的IHTMLElement2接口
实验了好多遍,虽然能获取到坐标,但是受到了每台机器屏幕分辨率的影响,
根据测试得到的规律,写出了不受分辨率影响的获取坐标的方法(第一步和第二步可以忽略,直接到第三步拿到坐标)
现在贴上代码:
首先第一步,获取浏览器窗口对象:
function SearchIEHTMLEx(const sWindowName: string; const iTime : Integer): HWND; var J: Integer; uThreadID: DWORD; begin Result := SearchIEHTML(sWindowName); if Result <> 0 then Exit; uThreadID := GetCurrentThreadId; J := 0; while (J <= iTime) and (not ScriptThreadStop(uThreadID)) do begin Inc(J); Sleep(1000); Result := SearchIEHTML(sWindowName); if Result <> 0 then Break; end; end;
第一个参数是窗口标题串 例如baidu.com的是:百度一下,你就知道
第二个参数是等待时间,超过等待时间还没找到就返回0
返回的就是浏览器窗口句柄
第二步:获取网页元素对象:
这里随便举个例子可以获取,比如根据 标签串和索引串 获取:
function GetObjectByIndexStr(const hParent: HWND; const tagNames,indexs: array of string): IHTMLElement; var P: IHTMLDocument2; uRst: {$ifdef DELPHI_2010_UP}DWORD_PTR{$ELSE}DWORD{$endif}; Item,Item2:IHTMLElement; I,J: Integer; begin Result := nil; if @FlpObjectFromLresult = nil then Exit; EnterCriticalSection(FcsBrowserLock); try SendMessageTimeOut(hParent, FuMsg, 0, 0, SMTO_ABORTIFHUNG, 1000, {$ifdef DELPHI_2010_UP}@{$endif}uRst); if FlpObjectFromLresult(uRst, IHTMLDocument2, 0, P) = S_OK then begin J := 0; Item := P.all.item(J, varEmpty) as IHTMLElement; if not Assigned(Item) then Exit; while Assigned(Item) and (not SameText(Item.tagName,‘html‘)) {(Pos(‘!‘,Item.tagName) > 0) or SameText(‘DOCTYPE‘,Item.tagName)} do //去除第一个标签是 <!.... begin Inc(J); Item := P.all.item(J, varEmpty) as IHTMLElement; end; if not Assigned(Item) then Exit; if not SameText(Item.tagName,tagNames[Low(tagNames)]) then Exit; I := Low(tagNames)+1; while I <= High(tagNames) do begin if SameText(Item.tagName,‘IFrame‘) or SameText(Item.tagName,‘Frame‘) then begin J := 0; Item2 := (Item as IHTMLFrameBase2).contentWindow.document.all.item(J, varEmpty) as IHTMLElement; while Assigned(Item2) and (not SameText(Item2.tagName,‘html‘)) do begin Inc(J); Item2 := (Item as IHTMLFrameBase2).contentWindow.document.all.item(J, varEmpty) as IHTMLElement; end; Item := Item2; end else begin J := StrToInt(indexs[I]); Item := GetChildElement(Item,tagNames[I],J); end; if Item = nil then break; Inc(I); end; Result := Item; end; finally LeaveCriticalSection(FcsBrowserLock); end; end;
参数3个 (窗口,标签串,索引串)
窗口:第一步获取的窗口句柄
标签串:从外到内 比如百度的输入框的标签串: [‘HTML‘,‘BODY‘,‘DIV‘,‘DIV‘,‘DIV‘,‘DIV‘,‘DIV‘,‘Form‘,‘SPAN‘,‘INPUT‘]
索引串:从0开始,例如百度的输入框的索引串:[‘0‘,‘1‘,‘1‘,‘1‘,‘0‘,‘0‘,‘0‘,‘3‘,‘8‘,‘0‘]
举例:
获取百度的输入框元素:
GetObjectByIndexStr(窗口, [‘HTML‘,‘BODY‘,‘DIV‘,‘DIV‘,‘DIV‘,‘DIV‘,‘DIV‘,‘Form‘,‘SPAN‘,‘INPUT‘],[‘0‘,‘1‘,‘1‘,‘1‘,‘0‘,‘0‘,‘0‘,‘3‘,‘8‘,‘0‘])
第三步:获取元素的坐标
function GetElementScreenXY(const obj: IHTMLElement; var X,Y: Integer): Boolean; begin Result := False; if obj = nil then Exit; // 屏幕坐标 X := (obj as IHTMLElement2).getBoundingClientRect.left; X := X + ((obj.document as IHTMLDocument2).parentWindow as IHTMLWindow3).screenLeft; Y := (obj as IHTMLElement2).getBoundingClientRect.top; Y := Y + ((obj.document as IHTMLDocument2).parentWindow as IHTMLWindow3).screenTop; // 全屏幕真实大小 / html获取的屏幕大小 * html获取的元素坐标 X := round(GetSystemMetrics(SM_CXSCREEN) / ((obj.document as IHTMLDocument2).parentWindow as IHTMLWindow2).Get_screen.width * X); Y := round(GetSystemMetrics(SM_CYSCREEN) / ((obj.document as IHTMLDocument2).parentWindow as IHTMLWindow2).Get_screen.height * Y); Result := True; end;
返回的X和Y是元素的实际坐标
第一个参数obj是IHTMLElement元素对象
可以通过第一步和第二步结合获取到元素对象
delphi使用IHTMLElement2获取IE元素屏幕坐标以及解决分辨率影响的坑
标签:from const array 规律 hwnd sleep fun 需要 标签
原文地址:https://www.cnblogs.com/ClaireWu/p/12470799.html