Jump to content

GUIShow without taking focus


Recommended Posts

How do I show a child gui without having it take focus from its parant GUI?

#Include <GuiListBox.au3>
#include <GuiListView.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

Opt("GUIOnEventMode", 1)
Opt("GUIResizeMode", 1)
Global $__KM_Hook
Global $__KM_KB_Hook
Global $__KM_User32
Global $GUIMINWID = 463; Resizing / minimum width
Global $GUIMINHT = 278; Resizing / minimum hight
Global Const $WS_RESIZABLE = 0x00070000
Global $sPartialData, $asKeyWords[5], $iMatch_Count
Global $sCurr_Input = "", $sData = "|", $sChosen = "http://www.someplace.com/somedir/"
Global $iCurrIndex = -1
#region - GUI -
Global $BANEVADER = GUICreate("test", $GUIMINWID, $GUIMINHT, -1, -1, BitOR($WS_RESIZABLE, $WS_CAPTION, $WS_POPUP))
GUISetOnEvent(-3, "Terminate")
GUICtrlSetResizing(-1, 102)
GUICtrlCreateCheckbox("test",20,70,100,20)
Global $Input1 = GUICtrlCreateInput($sChosen, 4, 33, 385, 21)
GUICtrlSetResizing(-1, 512 + 32)
GUISetState(@SW_SHOW)
#region - HISTORY LIST -
Global $hUP = GUICtrlCreateDummy()
GUICtrlSetOnEvent(-1, "UP")
Global $hDOWN = GUICtrlCreateDummy()
GUICtrlSetOnEvent(-1, "DOWN")
Global $hENTER = GUICtrlCreateDummy()
GUICtrlSetOnEvent(-1, "ENTER")
Global $AccelKeys[3][2]=[["{UP}", $hUP], ["{DOWN}", $hDOWN], ["{ENTER}", $hENTER]]
GUISetAccelerators($AccelKeys)
Global $hlist_ui = GUICreate("Child", 385, 20, 3, 52, $WS_POPUP, $WS_EX_MDICHILD, $BANEVADER)
Global $hList = GUICtrlCreateList("", 0, 0, 385, 20, BitOR(0x00100000, 0x00200000))
GUICtrlSetOnEvent(-1, "SetListItem")
GUICtrlSetResizing($hList, 1)
Sleep(3000)
#endregion - HISTORY LIST -
#endregion - GUI -
Keywords()
_SetHooks(True)
Global $masterMask = CreateMasterMask();
AddToMask($masterMask,$hlist_ui,$hList);add button to mask
FitMask($masterMask,$hlist_ui);apply the mask to the window


Sleep(99999999999999)

Func CreateMasterMask()
    return DllCall("gdi32.dll", "long", "CreateRectRgn", "long", 0, "long", 0, "long", 0, "long", 0)
EndFunc
Func FitMask($aMask,$hWnd)
    DllCall("user32.dll", "long", "SetWindowRgn", "hwnd", $hWnd, "long", $aMask[0], "int", 1)
endfunc
Func AddToMask(ByRef $MM, $hWnd, $ID)
    Local $pp = ControlGetPos($hWnd,'',$ID)
    Local $Mask1 = DllCall("gdi32.dll", "long", "CreateRectRgn", "long", $pp[0], "long", $pp[1], "long", $pp[0] + $pp[2], "long",$pp[1] + $pp[3])
    DllCall("gdi32.dll", "long", "CombineRgn", "long", $MM[0], "long", $Mask1[0], "long", $MM[0],"int",2)
EndFunc
Func _KeyProcess($NCode, $WParam, $LParam)
    Local $aResult
    If $NCode < 0 Then
        $aResult = DllCall($__KM_User32, "lresult", "CallNextHookEx", "handle", $__KM_Hook, "int", $NCode, "wparam", $WParam, "lparam", $LParam)
        If @error Then Return SetError(@error, @extended, -1)
        Return $aResult[0]
    EndIf
    AdlibRegister("Monitor",100)
    $aResult = DllCall($__KM_User32, "lresult", "CallNextHookEx", "handle", $__KM_Hook, "int", $NCode, "wparam", $WParam, "lparam", $LParam)
    If @error Then Return SetError(@error, @extended, -1)
    Return $aResult[0]
EndFunc   ;==>_KeyProcess
Func SetListItem($Selected = 0)
    If Not IsDeclared("Selected") Then
        $sChosen = GUICtrlRead($hList)
    Else
        $sChosen = $Selected
    EndIf
    If $sChosen <> "" Then GUICtrlSetData($Input1, $sChosen)
    GUISetState(@SW_HIDE, $hlist_ui)
EndFunc
Func UP()
    $iCurrIndex -= 1
    If $iCurrIndex < 0 Then $iCurrIndex = 0
    _GUICtrlListBox_SetCurSel($hList, $iCurrIndex)
EndFunc
Func DOWN()
    Local $iTotal = _GUICtrlListBox_GetCount($hList)
    $iCurrIndex += 1
    If $iCurrIndex > $iTotal - 1 Then $iCurrIndex = $iTotal - 1
    _GUICtrlListBox_SetCurSel($hList, $iCurrIndex)
EndFunc
Func ENTER()
    If $iCurrIndex <> -1 Then
        Local $sText = _GUICtrlListBox_GetText($hList, $iCurrIndex)
        SetListItem($sText)
        $iCurrIndex = -1
        _GUICtrlListBox_SetCurSel($hList, $iCurrIndex)
        GUISetState(@SW_HIDE, $hlist_ui)
    EndIf
EndFunc
Func Monitor()
    If (GUICtrlRead($Input1) <> "") And (GUICtrlRead($Input1) <> $sChosen) And Not(BitAND(WinGetState($hlist_ui), 2)) And ($sData <> "|") Then
        GUISetState(@SW_SHOW, $hlist_ui)
        GUICtrlSetState($Input1, $GUI_FOCUS); <------ THIS RIGHT HERE
        ControlSend($BANEVADER, "", $Input1, "{END}"); <------ THIS RIGHT HERE
  ;I need another way of doing this above :(
    EndIf
    If GUICtrlRead($Input1) = "" Or Not($iMatch_Count) And BitAND(WinGetState($hlist_ui), 2) Then
        GUISetState(@SW_HIDE, $hlist_ui)
        $iCurrIndex = -1
    EndIf
    If GUICtrlRead($Input1) <> $sCurr_Input Then
        CheckInputText()
        $sCurr_Input = GUICtrlRead($Input1)
    EndIf
    AdlibUnRegister("Monitor")
EndFunc
Func CheckInputText()
    $sData = "|" ; Start with delimiter so new data always replaces aold
    Local $sInput = GUICtrlRead($Input1)
    $iMatch_Count = 0
    If $sInput <> "" Then
        For $i = 0 To UBound($asKeyWords) - 1
            If StringInStr($asKeyWords[$i], $sInput,2) Then
                $sData &= $asKeyWords[$i] & "|"
                $iMatch_Count += 1
            EndIf
        Next
        GUICtrlSetData($hList, $sData)
        ; Change size of child GUI
        Local $iList_Height = $iMatch_Count * (_GUICtrlListBox_GetItemHeight($hList)+1)
        If $iList_Height < 20 Then $iList_Height = 20
        If $iList_Height > 200 Then $iList_Height = 200
        ConsoleWrite($iList_Height & @CR)
        WinMove($hlist_ui, "", Default, Default, Default, $iList_Height)
        $masterMask = CreateMasterMask();
        AddToMask($masterMask,$hlist_ui,$hList);add button to mask
        FitMask($masterMask,$hlist_ui);apply the mask to the window
        $iCurrIndex = -1
    EndIf
EndFunc   ;==>CheckInputText
Func Keywords()
    Local $sData, $Count, $aKeyWords, $Rows, $Columns
    $asKeyWords[0] = "http://autoitscript.com"
    $asKeyWords[1] = "http://google.com"
    $asKeyWords[2] = "http://yahoo.com"
    $asKeyWords[3] = "http://ask.com"
    $asKeyWords[4] = "http://theworldisdying.com"
    For $I = 0 To 4
        $sData &= $asKeyWords[$i] & "|"
    Next

    GUICtrlSetData($hList, $sData)
    $iCurrIndex = -1
    _GUICtrlListBox_SetCurSel($hList, $iCurrIndex)
EndFunc   ;==>Keywords
Func _SetHooks($Type = False)
    Switch $Type
        Case True
            If Not ($__KM_User32) Then
                $__KM_User32 = DllOpen("User32.dll")
            EndIf
            $__KM_KB_Hook = DllCallbackRegister("_KeyProcess", "long", "int;wparam;lparam")
            If Not $__KM_KB_Hook Then Return SetError(1,0,False)
            Local $aResult = DllCall("kernel32.dll", "handle", "GetModuleHandleW", "ptr", 0)
            If @error Then Return SetError(2, @error, False)
            $aResult = DllCall($__KM_User32, "handle", "SetWindowsHookEx", _
                    "int", 13, _ ; WH_KEYBOARD_LL
                    "ptr", DllCallbackGetPtr($__KM_KB_Hook), _
                    "handle", $aResult[0], _
                    "dword", 0 _
            )
            If @error Then Return SetError(3, @error, False)
            $__KM_Hook = $aResult[0]
        Case False
            DllCall($__KM_User32, "bool", "UnhookWindowsHookEx", "handle", $__KM_Hook)
            DllCallbackFree($__KM_KB_Hook)
            DllClose($__KM_User32)
            $__KM_User32 = 0
    EndSwitch
    Return SetError(0,0,True)
EndFunc   ;==>_SetHooks
Func Terminate()
    Exit
EndFunc

Specifically it's this part of the script~

Func Monitor()
    If (GUICtrlRead($Input1) <> "") And (GUICtrlRead($Input1) <> $sChosen) And Not(BitAND(WinGetState($hlist_ui), 2)) And ($sData <> "|") Then
        GUISetState(@SW_SHOW, $hlist_ui)
        GUICtrlSetState($Input1, $GUI_FOCUS); <------ THIS RIGHT HERE
        ControlSend($BANEVADER, "", $Input1, "{END}"); <------ THIS RIGHT HERE
  ;I need another way of doing this above :(
    EndIf
    If GUICtrlRead($Input1) = "" Or Not($iMatch_Count) And BitAND(WinGetState($hlist_ui), 2) Then
        GUISetState(@SW_HIDE, $hlist_ui)
        $iCurrIndex = -1
    EndIf
    If GUICtrlRead($Input1) <> $sCurr_Input Then
        CheckInputText()
        $sCurr_Input = GUICtrlRead($Input1)
    EndIf
    AdlibUnRegister("Monitor")
EndFunc

I need an alternate method to keep focus on the parent GUI without having the child GUI take focus from the parents input control.

GUICtrlSetState($Input1, $GUI_FOCUS)
ControlSend($BANEVADER, "", $Input1, "{END}")

Using the above method will sometime cause sticky keys (or something) to activate when the user is typing really fast, and even sometimes during the small amount of time that the child took focus from the parent GUI, the imput box will highlight all the data in it and if the user presses a key at that instant, everything is gone...

I remember seeing some code that activated a window without it having focus, that's what I need :)

Edited by ApudAngelorum
Link to comment
Share on other sites

I was going to post that, but the "GUIShow", put me off, thought you were after something else.

Yeah, it's an example I found by melba23 (the drop down list and navigation), it's exactly what I was after except that using the method he was using to give back focus to the input control caused some hotkeys to take effect and I had to keep rebooting since I didn't know how to disable them.

Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...