mpower Posted March 14, 2015 Share Posted March 14, 2015 (edited) I'm trying to intercept the Ctrl+F function in IE so that I can achieve a similar effect of words being highlighted via the input on my gui. To explain better here is my code. What I want is to basically be able to type stuff into the input box that follows the label "Quick find:" and for any data that partially matches input on the displayed html page to be highlighted as if I was using Ctrl+F search in IE. You can see the behaviour of Ctrl+F highlight by clicking into the IE object and then pressing Ctrl+F. I would also like for it to auto-scroll to the *best* match data. Essentially same as Ctrl+F in IE. Place all attachments - the tow PNG files and the HTML file in script folder to get the full effect. DaleHohm, DaleHohm, DaleHohm, <---- just trying to summon user DaleHohm who seems to have very good knowledge of IE expandcollapse popup#include-once #NoTrayIcon #AutoIt3Wrapper_Outfile=Example.exe #AutoIt3Wrapper_Compression=4 #AutoIt3Wrapper_UseUpx=n #AutoIt3Wrapper_UseX64=n #include <GDIPlus.au3> #include <WindowsConstants.au3> #include <GUIConstants.au3> #include <WinAPIEx.au3> #include <IE.au3> Global $bAero, $hidden = False, $tuck = False, $tucked = False, $untucked = False, $tucking = False, $untucking = False, $timer = 0, $tdiff = 0, _ $LAYERED_GUI = $WS_EX_LAYERED, $hGUI_child, $hGUI_height = 683 Global Const $hDwmApiDll = DllOpen("dwmapi.dll"), $sChkAero = DllStructCreate("int;") DllCall($hDwmApiDll, "int", "DwmIsCompositionEnabled", "ptr", DllStructGetPtr($sChkAero)) $bAero = DllStructGetData($sChkAero, 1) If Not $bAero Then $LAYERED_GUI = 0 $hGUI_height = $hGUI_height - 20 EndIf $hGUI = GUICreate("", 715, $hGUI_height, -1, 0, $WS_POPUP, $LAYERED_GUI + $WS_EX_TOPMOST, WinGetHandle(AutoItWinGetTitle())) $hIcon = _WinAPI_GetClassLongEx($hGUI, $GCL_HICON) _WinAPI_DestroyIcon($hIcon) _WinAPI_SetClassLongEx($hGUI, $GCL_HICON, 0) _WinAPI_SetClassLongEx($hGUI, $GCL_HICONSM, 0) If $bAero Then $hGUI_child = GUICreate("", 715-39, 683 - 26, 22, 3, $WS_POPUP, $WS_EX_MDICHILD + $WS_EX_TOPMOST, $hGUI) $hGUI_Font = $hGUI_child Else $hGUI_Font = $hGUI $hGUI_child = $hGUI EndIf GUISetBkColor(0xFFFFFF) GUISetFont(18, 100, Default, 'Segoe UI', $hGUI_Font, 5) GUICtrlCreateLabel('Quick find:', 10, 25) GUICtrlCreateInput('', 150, 20, 100, 35) $oIE = _IECreateEmbedded() $oIEobj = GUICtrlCreateObj($oIE, 10, 85, 650, 550) $oNav = _IENavigate($oIE, @ScriptDir & '/example.html', 0) $hGUI_child2 = GUICreate("", 112, 50, 280, 645, $WS_POPUP, $LAYERED_GUI + $WS_EX_MDICHILD + $WS_EX_TOPMOST, $hGUI_child) If Not $bAero Then GUISetBkColor(0xE0F2F7) $hGUI_Font = $hGUI_child2 GUISetFont(33, 100, Default, 'Segoe UI', $hGUI_Font, 5) GUICtrlCreateLabel(" = ", 0, 0, 112, 50, $SS_CENTER + $SS_CENTERIMAGE) EndIf GUISetCursor(0, 1, $hGUI_child2) If $bAero Then _GDIPlus_Startup() $hImage = _GDIPlus_ImageLoadFromFile(@ScriptDir & '\panel.png') SetBitmap($hGUI, $hImage) $hImage = _GDIPlus_ImageLoadFromFile(@ScriptDir & '\roundbn.png') SetBitmap($hGUI_child2, $hImage) _GDIPlus_Shutdown() EndIf GUIRegisterMsg($WM_MOUSEWHEEL, "WM_MOUSEWHEEL") GUISetState(@SW_SHOW, $hGUI) If $bAero Then GUISetState(@SW_SHOW, $hGUI_child) GUISetState(@SW_SHOW, $hGUI_child2) While 1 $mPos = MouseGetPos() If BitAnd($hidden, $mPos[1] = 0, $timer = 0) Then $timer = TimerInit() Sleep(10) ElseIf $mPos[1] <> 0 Then $timer = 0 $tdiff = 0 EndIf If $timer <> 0 Then $tdiff = TimerDiff($timer) If BitAND($hidden, Not $tucked, $mPos[1] <> 0, Not $tucking) Then $tuck = True $untucking = False $tucking = True AdlibRegister("TuckAway", 2500) ElseIf BitAND($hidden, $tucked, $mPos[1] = 0, Not $untucking, $tdiff > 450) Then $tuck = False $tucking = False $untucking = True AdlibRegister("TuckAway") ElseIf BitAND($hidden, Not $tucked, $mPos[1] = 0, $tucking) Then AdlibUnRegister("TuckAway") $tuck = False $tucking = False EndIf $msg = GUIGetMsg(1) Switch $msg[1] Case $hGUI Switch $msg[0] Case $GUI_EVENT_CLOSE, $GUI_EVENT_SECONDARYUP Exit EndSwitch Case $hGUI_child Switch $msg[0] Case $GUI_EVENT_CLOSE, $GUI_EVENT_SECONDARYUP Exit EndSwitch Case $hGUI_child2 Switch $msg[0] Case $GUI_EVENT_PRIMARYDOWN If Not $hidden Then HidePanel() Else HidePanel(False) EndIf EndSwitch EndSwitch WEnd Func WM_MOUSEWHEEL($hWnd, $iMsg, $wParam, $lParam) Switch $wParam Case 0x00780000 $oIE.document.parentwindow.scrollBy(0, -150) Case 0xFF880000 $oIE.document.parentwindow.scrollBy(0, 150) EndSwitch Return $GUI_RUNDEFMSG EndFunc Func HidePanel($hide = True) AdlibUnRegister("TuckAway") If $hide Then $tucked = False $untucked = True $hidden = True For $i = -1 to -663 Step - 1 WinMove($hGUI, "", Default, $i) Next Else $tucked = False $untucked = False $hidden = False For $i = -664 to -4 Step 1 WinMove($hGUI, "", Default, $i) Next EndIf EndFunc Func TuckAway() If $tuck Then $tucking = False $untucked = False $tucked = True For $i = 663 to 695 Step 1 WinMove($hGUI, "", Default, -$i) Sleep(10) Next Else $untucking = False $tucked = False For $i = 695 to 663 Step - 1 WinMove($hGUI, "", Default, -$i) Sleep(10) Next EndIf AdlibUnRegister("TuckAway") EndFunc Func SetBitmap($hGUI, $hImage, $iOpacity = 255) Local $hScrDC, $hMemDC, $hBitmap, $hOld, $pSize, $tSize, $pSource, $tSource, $pBlend, $tBlend $hScrDC = _WinAPI_GetDC(0) $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC) $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage) $hOld = _WinAPI_SelectObject($hMemDC, $hBitmap) $tSize = DllStructCreate($tagSIZE) $pSize = DllStructGetPtr($tSize) DllStructSetData($tSize, "X", _GDIPlus_ImageGetWidth($hImage)) DllStructSetData($tSize, "Y", _GDIPlus_ImageGetHeight($hImage)) $tSource = DllStructCreate($tagPOINT) $pSource = DllStructGetPtr($tSource) $tBlend = DllStructCreate($tagBLENDFUNCTION) $pBlend = DllStructGetPtr($tBlend) DllStructSetData($tBlend, "Alpha", $iOpacity) DllStructSetData($tBlend, "Format", 1) _WinAPI_UpdateLayeredWindow($hGUI, $hGUI, 0, $pSize, $hMemDC, $pSource, 0, $pBlend, $ULW_ALPHA) _WinAPI_ReleaseDC(0, $hScrDC) _WinAPI_SelectObject($hMemDC, $hOld) _WinAPI_DeleteObject($hBitmap) _WinAPI_DeleteDC($hMemDC) EndFunc example.html Edited March 15, 2015 by mpower Link to comment Share on other sites More sharing options...
mpower Posted March 15, 2015 Author Share Posted March 15, 2015 (edited) Okay so what I'm thinking is to have a WM_COMMAND function detect when my input has focus and then it can send Ctrl+F to the embedded IE object. I can then look at hiding IE's "Find" window and send any input from the GUI input to the "Find" window input. However the problem I have is that I can't seem to Send CTRL+F to the embedded IE object. I have searched the forums and found some working code to send keys to an embedded object however I found one peculiarity that ControlSend actions only seem to work if the GUI doesn't have focus. Here's the example code: #include <IE.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> $oIE = _IECreateEmbedded() $hGUI = GUICreate("myWindow", 800, 600, (@DesktopWidth - 640) / 2, (@DesktopHeight - 580) / 2, _ $WS_OVERLAPPEDWINDOW + $WS_VISIBLE + $WS_CLIPSIBLINGS) $GUIActiveX = GUICtrlCreateObj($oIE, 0, 0, 800, 600) GUISetState() _IENavigate($oIE, "http://www.autoitscript.com/forum/index.php") $hHandle = ControlGetHandle("", "", "[CLASS:Internet Explorer_Server; INSTANCE:1]") For $i = 1 To 10 ConsoleWrite("sending command:" & ControlSend($hHandle, 0, 0, "{DOWN}") & @CRLF) Sleep(1000) Next Notice that if you click out of the GUI the page scrolls down, however if you activate the GUI it does not. I wonder why... To see what I mean, run the above script and watch the Console. It should say "sending command:1" meaning that the sending of down key has succeeded. However the page will not be scrolling down. If, whilst the loop is running, you click outside of the main GUI you will notice that the page will start scrolling. Once the GUI is back in focus however the scrolling stops. Bizarre. How does one send keys (e.g. CTRL+F) to an embedded IE object without having to lose GUI focus? Edited March 15, 2015 by mpower Link to comment Share on other sites More sharing options...
mpower Posted March 15, 2015 Author Share Posted March 15, 2015 (edited) Okay I've totally re-thought the way I am approaching this and realised that I was overcomplicating things. Instead I am now using standard method .Find to find a match on the page, highlight a match and scroll the document view to the match location. Now - just have to figure out a way to highlight multiple results! Here's the code which can do single item searching/highlighting and scrolling to said item: GUIRegisterMsg($WM_COMMAND, "WM_COMMAND") Func WM_COMMAND($hWnd, $msg, $wParam, $lParam) Local $iCode = BitShift($wParam, 16) Local $nIDFrom = BitAND($wParam, 0xFFFF) Switch $hWnd Case $hGUI_child Switch $nIDFrom Case $qsInput Switch $iCode Case $EN_CHANGE _IESearchText($oIE, GUICtrlRead($qsInput)) EndSwitch EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc Func _IESearchText($oIE, $sFindText) $oRange = $oIE.document.body.createTextRange() If $oRange.FindText($sFindText) Then $oRange.Select() $oIE.scrollIntoView() Else $oIE.document.execCommand("Unselect") EndIf EndFunc Edited March 15, 2015 by mpower Digisoul 1 Link to comment Share on other sites More sharing options...
Solution mpower Posted March 15, 2015 Author Solution Share Posted March 15, 2015 (edited) Okay I think I'm satisfied with my code now - I can search for a single value but then press Enter to continue search to find the next value. This is good enough for me. Final sample code for those interested: expandcollapse popup#include-once #NoTrayIcon #AutoIt3Wrapper_Outfile=Example.exe #AutoIt3Wrapper_Compression=4 #AutoIt3Wrapper_UseUpx=n #AutoIt3Wrapper_UseX64=n #include <GDIPlus.au3> #include <WindowsConstants.au3> #include <GUIConstants.au3> #include <WinAPIEx.au3> #include <IE.au3> #include <Array.au3> Global $bAero, $hidden = False, $tuck = False, $tucked = False, $untucked = False, $tucking = False, $untucking = False, $timer = 0, $tdiff = 0, _ $LAYERED_GUI = $WS_EX_LAYERED, $hGUI_child, $hGUI_height = 683, $find = False, $qsInfocus = False Global Const $hDwmApiDll = DllOpen("dwmapi.dll"), $sChkAero = DllStructCreate("int;") DllCall($hDwmApiDll, "int", "DwmIsCompositionEnabled", "ptr", DllStructGetPtr($sChkAero)) $bAero = DllStructGetData($sChkAero, 1) If Not $bAero Then $LAYERED_GUI = 0 $hGUI_height = $hGUI_height - 20 EndIf $hGUI = GUICreate("", 715, $hGUI_height, -1, 0, $WS_POPUP, $LAYERED_GUI + $WS_EX_TOPMOST, WinGetHandle(AutoItWinGetTitle())) $hIcon = _WinAPI_GetClassLongEx($hGUI, $GCL_HICON) _WinAPI_DestroyIcon($hIcon) _WinAPI_SetClassLongEx($hGUI, $GCL_HICON, 0) _WinAPI_SetClassLongEx($hGUI, $GCL_HICONSM, 0) If $bAero Then $hGUI_child = GUICreate("", 715-39, 683 - 26, 22, 3, $WS_POPUP, $WS_EX_MDICHILD + $WS_EX_TOPMOST, $hGUI) $hGUI_Font = $hGUI_child Else $hGUI_Font = $hGUI $hGUI_child = $hGUI EndIf GUISetBkColor(0xFFFFFF) GUISetFont(18, 100, Default, 'Segoe UI', $hGUI_Font, 5) $qsLabel = GUICtrlCreateLabel('Quick find:', 10, 25) $qsInput = GUICtrlCreateInput('', 150, 20, 100, 35) $oIE = _IECreateEmbedded() $oIEobj = GUICtrlCreateObj($oIE, 10, 85, 650, 550) $oNav = _IENavigate($oIE, @ScriptDir & '/contactlist.html', 0) $hENTER = GUICtrlCreateDummy() Dim $AccelKeys[1][2]=[["{ENTER}", $hENTER]] GUISetAccelerators($AccelKeys) $hGUI_child2 = GUICreate("", 112, 50, 280, 645, $WS_POPUP, $LAYERED_GUI + $WS_EX_MDICHILD + $WS_EX_TOPMOST, $hGUI_child) If Not $bAero Then GUISetBkColor(0xE0F2F7) $hGUI_Font = $hGUI_child2 GUISetFont(33, 100, Default, 'Segoe UI', $hGUI_Font, 5) GUICtrlCreateLabel(" = ", 0, 0, 112, 50, $SS_CENTER + $SS_CENTERIMAGE) EndIf GUISetCursor(0, 1, $hGUI_child2) If $bAero Then _GDIPlus_Startup() $hImage = _GDIPlus_ImageLoadFromFile(@ScriptDir & '\panel.png') SetBitmap($hGUI, $hImage) $hImage = _GDIPlus_ImageLoadFromFile(@ScriptDir & '\roundbn.png') SetBitmap($hGUI_child2, $hImage) _GDIPlus_Shutdown() EndIf GUIRegisterMsg($WM_MOUSEWHEEL, "WM_MOUSEWHEEL") GUIRegisterMsg($WM_COMMAND, "WM_COMMAND") GUISetState(@SW_SHOW, $hGUI) If $bAero Then GUISetState(@SW_SHOW, $hGUI_child) GUISetState(@SW_SHOW, $hGUI_child2) While 1 $mPos = MouseGetPos() If BitAnd($hidden, $mPos[1] = 0, $timer = 0) Then $timer = TimerInit() Sleep(10) ElseIf $mPos[1] <> 0 Then $timer = 0 $tdiff = 0 EndIf If $timer <> 0 Then $tdiff = TimerDiff($timer) If BitAND($hidden, Not $tucked, $mPos[1] <> 0, Not $tucking) Then $tuck = True $untucking = False $tucking = True AdlibRegister("TuckAway", 2500) ElseIf BitAND($hidden, $tucked, $mPos[1] = 0, Not $untucking, $tdiff > 450) Then $tuck = False $tucking = False $untucking = True AdlibRegister("TuckAway") ElseIf BitAND($hidden, Not $tucked, $mPos[1] = 0, $tucking) Then AdlibUnRegister("TuckAway") $tuck = False $tucking = False EndIf $msg = GUIGetMsg(1) Switch $msg[1] Case $hGUI Switch $msg[0] Case $GUI_EVENT_CLOSE, $GUI_EVENT_SECONDARYUP Exit EndSwitch Case $hGUI_child Switch $msg[0] Case $GUI_EVENT_CLOSE, $GUI_EVENT_SECONDARYUP Exit Case $hENTER If $qsInfocus Then _IESearchText($oIE, GUICtrlRead($qsInput), 1) EndSwitch Case $hGUI_child2 Switch $msg[0] Case $GUI_EVENT_PRIMARYDOWN If Not $hidden Then HidePanel() Else HidePanel(False) EndIf EndSwitch EndSwitch WEnd Func WM_COMMAND($hWnd, $msg, $wParam, $lParam) Local $iCode = BitShift($wParam, 16) Local $nIDFrom = BitAND($wParam, 0xFFFF) Switch $hWnd Case $hGUI_child Switch $nIDFrom Case $qsInput Switch $iCode Case $EN_CHANGE _IESearchText($oIE, GUICtrlRead($qsInput), 0) Case $EN_SETFOCUS $qsInfocus = True Case $EN_KILLFOCUS $qsInfocus = False EndSwitch EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc Func _IESearchText($oIE, $sFindText, $fNext = 0) $docRange = $oIE.document.body.createTextRange() $docRange.execCommand("backColor", false, "#ffffff"); If $sFindText <> '' Then If $fNext = 0 Then Global $oRange = $oIE.document.body.createTextRange() Else $oRange.moveStart("character") EndIf If $oRange.FindText($sFindText) Then $oRange.execCommand("backColor", false, "fdee00"); $oRange.scrollIntoView() Else $oRange = $oIE.document.body.createTextRange() EndIf Else $oIE.document.parentwindow.scroll(0) EndIf EndFunc Func WM_MOUSEWHEEL($hWnd, $iMsg, $wParam, $lParam) Switch $wParam Case 0x00780000 $oIE.document.parentwindow.scrollBy(0, -150) Case 0xFF880000 $oIE.document.parentwindow.scrollBy(0, 150) EndSwitch Return $GUI_RUNDEFMSG EndFunc Func HidePanel($hide = True) AdlibUnRegister("TuckAway") If $hide Then $tucked = False $untucked = True $hidden = True For $i = -1 to -663 Step - 1 WinMove($hGUI, "", Default, $i) Next Else $tucked = False $untucked = False $hidden = False For $i = -664 to -4 Step 1 WinMove($hGUI, "", Default, $i) Next EndIf EndFunc Func TuckAway() If $tuck Then $tucking = False $untucked = False $tucked = True For $i = 663 to 695 Step 1 WinMove($hGUI, "", Default, -$i) Sleep(10) Next Else $untucking = False $tucked = False For $i = 695 to 663 Step - 1 WinMove($hGUI, "", Default, -$i) Sleep(10) Next EndIf AdlibUnRegister("TuckAway") EndFunc Func SetBitmap($hGUI, $hImage, $iOpacity = 255) Local $hScrDC, $hMemDC, $hBitmap, $hOld, $pSize, $tSize, $pSource, $tSource, $pBlend, $tBlend $hScrDC = _WinAPI_GetDC(0) $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC) $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage) $hOld = _WinAPI_SelectObject($hMemDC, $hBitmap) $tSize = DllStructCreate($tagSIZE) $pSize = DllStructGetPtr($tSize) DllStructSetData($tSize, "X", _GDIPlus_ImageGetWidth($hImage)) DllStructSetData($tSize, "Y", _GDIPlus_ImageGetHeight($hImage)) $tSource = DllStructCreate($tagPOINT) $pSource = DllStructGetPtr($tSource) $tBlend = DllStructCreate($tagBLENDFUNCTION) $pBlend = DllStructGetPtr($tBlend) DllStructSetData($tBlend, "Alpha", $iOpacity) DllStructSetData($tBlend, "Format", 1) _WinAPI_UpdateLayeredWindow($hGUI, $hGUI, 0, $pSize, $hMemDC, $pSource, 0, $pBlend, $ULW_ALPHA) _WinAPI_ReleaseDC(0, $hScrDC) _WinAPI_SelectObject($hMemDC, $hOld) _WinAPI_DeleteObject($hBitmap) _WinAPI_DeleteDC($hMemDC) EndFunc Edited March 15, 2015 by mpower Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now